ApiUpload: Better handle ApiMessage errors from UploadVerifyFile hook
authorBartosz Dziewoński <matma.rex@gmail.com>
Mon, 20 Jun 2016 21:55:43 +0000 (23:55 +0200)
committerBartosz Dziewoński <matma.rex@gmail.com>
Thu, 23 Jun 2016 04:39:02 +0000 (04:39 +0000)
The extra data is actually understood and output now.

Bug: T137961
Change-Id: Ifac8995a4d16d11840cee814177fc2808bc2072c

docs/hooks.txt
includes/api/ApiUpload.php
includes/upload/UploadBase.php

index 0e7c1c0..b9ed746 100644 (file)
@@ -3281,9 +3281,10 @@ in most cases over UploadVerification.
 $upload: (object) an instance of UploadBase, with all info about the upload
 $mime: (string) The uploaded file's MIME type, as detected by MediaWiki.
   Handlers will typically only apply for specific MIME types.
-&$error: (object) output: true if the file is valid. Otherwise, an indexed array
-  representing the problem with the file, where the first element is the message
-  key and the remaining elements are used as parameters to the message.
+&$error: (object) output: true if the file is valid. Otherwise, set this to the reason
+  in the form of array( messagename, param1, param2, ... ) or a MessageSpecifier
+  instance (you might want to use ApiMessage to provide machine-readable details
+  for the API).
 
 'UploadVerifyUpload': Upload verification, based on both file properties like
 MIME type (same as UploadVerifyFile) and the information entered by the user
index 3af0dff..6979746 100644 (file)
@@ -567,12 +567,28 @@ class ApiUpload extends ApiBase {
                                $this->dieUsage( $msg, 'filetype-banned', 0, $extradata );
                                break;
                        case UploadBase::VERIFICATION_ERROR:
-                               $params = $verification['details'];
-                               $key = array_shift( $params );
-                               $msg = $this->msg( $key, $params )->inLanguage( 'en' )->useDatabase( false )->text();
-                               ApiResult::setIndexedTagName( $verification['details'], 'detail' );
-                               $this->dieUsage( "This file did not pass file verification: $msg", 'verification-error',
-                                       0, [ 'details' => $verification['details'] ] );
+                               $parsed = $this->parseMsg( $verification['details'] );
+                               $info = "This file did not pass file verification: {$parsed['info']}";
+                               if ( $verification['details'][0] instanceof IApiMessage ) {
+                                       $code = $parsed['code'];
+                               } else {
+                                       // For backwards-compatibility, all of the errors from UploadBase::verifyFile() are
+                                       // reported as 'verification-error', and the real error code is reported in 'details'.
+                                       $code = 'verification-error';
+                               }
+                               if ( $verification['details'][0] instanceof IApiMessage ) {
+                                       $msg = $verification['details'][0];
+                                       $details = array_merge( [ $msg->getKey() ], $msg->getParams() );
+                               } else {
+                                       $details = $verification['details'];
+                               }
+                               ApiResult::setIndexedTagName( $details, 'detail' );
+                               $data = [ 'details' => $details ];
+                               if ( isset( $parsed['data'] ) ) {
+                                       $data = array_merge( $data, $parsed['data'] );
+                               }
+
+                               $this->dieUsage( $info, $code, 0, $data );
                                break;
                        case UploadBase::HOOK_ABORTED:
                                if ( is_array( $verification['error'] ) ) {
index 5d0bc13..9bc06a3 100644 (file)
@@ -467,9 +467,13 @@ abstract class UploadBase {
                        }
                }
 
-               Hooks::run( 'UploadVerifyFile', [ $this, $mime, &$status ] );
-               if ( $status !== true ) {
-                       return $status;
+               $error = true;
+               Hooks::run( 'UploadVerifyFile', [ $this, $mime, &$error ] );
+               if ( $error !== true ) {
+                       if ( !is_array( $error ) ) {
+                               $error = [ $error ];
+                       }
+                       return $error;
                }
 
                wfDebug( __METHOD__ . ": all clear; passing.\n" );