Merge "Introduce new hook UploadVerifyUpload to allow preventing file uploads"
[lhc/web/wiklou.git] / includes / api / ApiUpload.php
index 326f8ba..cb8d938 100644 (file)
@@ -257,7 +257,7 @@ class ApiUpload extends ApiBase {
                                        'offset' => $this->mUpload->getOffset(),
                                ];
 
-                               $this->dieUsage( $status->getWikiText(), 'stashfailed', 0, $extradata );
+                               $this->dieUsage( $status->getWikiText( false, false, 'en' ), 'stashfailed', 0, $extradata );
                        }
                }
 
@@ -288,7 +288,7 @@ class ApiUpload extends ApiBase {
                                                $filekey,
                                                [ 'result' => 'Failure', 'stage' => 'assembling', 'status' => $status ]
                                        );
-                                       $this->dieUsage( $status->getWikiText(), 'stashfailed' );
+                                       $this->dieUsage( $status->getWikiText( false, false, 'en' ), 'stashfailed' );
                                }
 
                                // The fully concatenated file has a new filekey. So remove
@@ -347,12 +347,13 @@ class ApiUpload extends ApiBase {
         * Throw an error that the user can recover from by providing a better
         * value for $parameter
         *
-        * @param array $error Error array suitable for passing to dieUsageMsg()
+        * @param array|string|MessageSpecifier $error Error suitable for passing to dieUsageMsg()
         * @param string $parameter Parameter that needs revising
         * @param array $data Optional extra data to pass to the user
+        * @param string $code Error code to use if the error is unknown
         * @throws UsageException
         */
-       private function dieRecoverableError( $error, $parameter, $data = [] ) {
+       private function dieRecoverableError( $error, $parameter, $data = [], $code = 'unknownerror' ) {
                try {
                        $data['filekey'] = $this->performStash();
                        $data['sessionkey'] = $data['filekey'];
@@ -365,6 +366,9 @@ class ApiUpload extends ApiBase {
                if ( isset( $parsed['data'] ) ) {
                        $data = array_merge( $data, $parsed['data'] );
                }
+               if ( $parsed['code'] === 'unknownerror' ) {
+                       $parsed['code'] = $code;
+               }
 
                $this->dieUsage( $parsed['info'], $parsed['code'], 0, $data );
        }
@@ -391,7 +395,7 @@ class ApiUpload extends ApiBase {
                        if ( !$progress ) {
                                $this->dieUsage( 'No result in status data', 'missingresult' );
                        } elseif ( !$progress['status']->isGood() ) {
-                               $this->dieUsage( $progress['status']->getWikiText(), 'stashfailed' );
+                               $this->dieUsage( $progress['status']->getWikiText( false, false, 'en' ), 'stashfailed' );
                        }
                        if ( isset( $progress['status']->value['verification'] ) ) {
                                $this->checkVerification( $progress['status']->value['verification'] );
@@ -488,6 +492,16 @@ class ApiUpload extends ApiBase {
 
                        $this->dieUsageMsg( 'badaccess-groups' );
                }
+
+               // Check blocks
+               if ( $user->isBlocked() ) {
+                       $this->dieBlocked( $user->getBlock() );
+               }
+
+               // Global blocks
+               if ( $user->isBlockedGlobally() ) {
+                       $this->dieBlocked( $user->getGlobalBlock() );
+               }
        }
 
        /**
@@ -685,16 +699,19 @@ class ApiUpload extends ApiBase {
                /** @var $file File */
                $file = $this->mUpload->getLocalFile();
 
-               // For preferences mode, we want to watch if 'watchdefault' is set or
-               // if the *file* doesn't exist and 'watchcreations' is set. But
-               // getWatchlistValue()'s automatic handling checks if the *title*
-               // exists or not, so we need to check both prefs manually.
+               // For preferences mode, we want to watch if 'watchdefault' is set,
+               // or if the *file* doesn't exist, and either 'watchuploads' or
+               // 'watchcreations' is set. But getWatchlistValue()'s automatic
+               // handling checks if the *title* exists or not, so we need to check
+               // all three preferences manually.
                $watch = $this->getWatchlistValue(
                        $this->mParams['watchlist'], $file->getTitle(), 'watchdefault'
                );
+
                if ( !$watch && $this->mParams['watchlist'] == 'preferences' && !$file->exists() ) {
-                       $watch = $this->getWatchlistValue(
-                               $this->mParams['watchlist'], $file->getTitle(), 'watchcreations'
+                       $watch = (
+                               $this->getWatchlistValue( 'preferences', $file->getTitle(), 'watchuploads' ) ||
+                               $this->getWatchlistValue( 'preferences', $file->getTitle(), 'watchcreations' )
                        );
                }
 
@@ -741,9 +758,14 @@ class ApiUpload extends ApiBase {
                                $this->mParams['text'], $watch, $this->getUser(), $this->mParams['tags'] );
 
                        if ( !$status->isGood() ) {
-                               $error = $status->getErrorsArray();
-                               ApiResult::setIndexedTagName( $error, 'error' );
-                               $this->dieUsage( 'An internal error occurred', 'internal-error', 0, $error );
+                               // Is there really no better way to do this?
+                               $errors = $status->getErrorsByType( 'error' );
+                               $msg = array_merge( [ $errors[0]['message'] ], $errors[0]['params'] );
+                               $data = $status->getErrorsArray();
+                               ApiResult::setIndexedTagName( $data, 'error' );
+                               // For backwards-compatibility, we use the 'internal-error' fallback key and merge $data
+                               // into the root of the response (rather than something sane like [ 'details' => $data ]).
+                               $this->dieRecoverableError( $msg, null, $data, 'internal-error' );
                        }
                        $result['result'] = 'Success';
                }