Merge "Allow passing detailed permission errors data to API"
[lhc/web/wiklou.git] / includes / api / ApiBase.php
index 7743384..1227899 100644 (file)
@@ -986,6 +986,17 @@ abstract class ApiBase extends ContextSource {
                        // Set a warning if a deprecated parameter has been passed
                        if ( $deprecated && $value !== false ) {
                                $this->setWarning( "The $encParamName parameter has been deprecated." );
+
+                               $feature = $encParamName;
+                               $m = $this;
+                               while ( !$m->isMain() ) {
+                                       $p = $m->getParent();
+                                       $name = $m->getModuleName();
+                                       $param = $p->encodeParamName( $p->getModuleManager()->getModuleGroup( $name ) );
+                                       $feature = "{$param}={$name}&{$feature}";
+                                       $m = $p;
+                               }
+                               $this->logFeatureUsage( $feature );
                        }
                } elseif ( $required ) {
                        $this->dieUsageMsg( array( 'missingparam', $paramName ) );
@@ -1071,7 +1082,9 @@ abstract class ApiBase extends ContextSource {
         * @param int $botMax Maximum value for sysops/bots
         * @param bool $enforceLimits Whether to enforce (die) if value is outside limits
         */
-       protected function validateLimit( $paramName, &$value, $min, $max, $botMax = null, $enforceLimits = false ) {
+       protected function validateLimit( $paramName, &$value, $min, $max, $botMax = null,
+               $enforceLimits = false
+       ) {
                if ( !is_null( $min ) && $value < $min ) {
                        $msg = $this->encodeParamName( $paramName ) . " may not be less than $min (set to $value)";
                        $this->warnOrDie( $msg, $enforceLimits );
@@ -1356,8 +1369,8 @@ abstract class ApiBase extends ContextSource {
         * @param string $errorCode Brief, arbitrary, stable string to allow easy
         *   automated identification of the error, e.g., 'unknown_action'
         * @param int $httpRespCode HTTP response code
-        * @param array $extradata Data to add to the "<error>" element; array in ApiResult format
-        * @throws UsageException
+        * @param array|null $extradata Data to add to the "<error>" element; array in ApiResult format
+        * @throws UsageException always
         */
        public function dieUsage( $description, $errorCode, $httpRespCode = 0, $extradata = null ) {
                throw new UsageException(
@@ -1373,10 +1386,11 @@ abstract class ApiBase extends ContextSource {
         *
         * @since 1.23
         * @param Status $status
+        * @param array|null &$extraData Set if extra data from IApiMessage is available (since 1.27)
         * @return array Array of code and error string
         * @throws MWException
         */
-       public function getErrorFromStatus( $status ) {
+       public function getErrorFromStatus( $status, &$extraData = null ) {
                if ( $status->isGood() ) {
                        throw new MWException( 'Successful status passed to ApiBase::dieStatus' );
                }
@@ -1395,7 +1409,12 @@ abstract class ApiBase extends ContextSource {
                // error messages.
                if ( $errors[0] instanceof Message ) {
                        $msg = $errors[0];
-                       $code = $msg->getKey();
+                       if ( $msg instanceof IApiMessage ) {
+                               $extraData = $msg->getApiData();
+                               $code = $msg->getApiCode();
+                       } else {
+                               $code = $msg->getKey();
+                       }
                } else {
                        $code = array_shift( $errors[0] );
                        $msg = wfMessage( $code, $errors[0] );
@@ -1413,12 +1432,12 @@ abstract class ApiBase extends ContextSource {
         *
         * @since 1.22
         * @param Status $status
-        * @throws MWException
+        * @throws UsageException always
         */
        public function dieStatus( $status ) {
-
-               list( $code, $msg ) = $this->getErrorFromStatus( $status );
-               $this->dieUsage( $msg, $code );
+               $extraData = null;
+               list( $code, $msg ) = $this->getErrorFromStatus( $status, $extraData );
+               $this->dieUsage( $msg, $code, 0, $extraData );
        }
 
        // @codingStandardsIgnoreStart Allow long lines. Cannot split these.
@@ -1930,6 +1949,8 @@ abstract class ApiBase extends ContextSource {
 
        /**
         * Helper function for readonly errors
+        *
+        * @throws UsageException always
         */
        public function dieReadOnly() {
                $parsed = $this->parseMsg( array( 'readonlytext' ) );
@@ -1940,6 +1961,7 @@ abstract class ApiBase extends ContextSource {
        /**
         * Output the error message related to a certain array
         * @param array|string $error Element of a getUserPermissionsErrors()-style array
+        * @throws UsageException always
         */
        public function dieUsageMsg( $error ) {
                # most of the time we send a 1 element, so we might as well send it as
@@ -1948,13 +1970,15 @@ abstract class ApiBase extends ContextSource {
                        $error = array( $error );
                }
                $parsed = $this->parseMsg( $error );
-               $this->dieUsage( $parsed['info'], $parsed['code'] );
+               $extraData = isset( $parsed['data'] ) ? $parsed['data'] : null;
+               $this->dieUsage( $parsed['info'], $parsed['code'], 0, $extraData );
        }
 
        /**
         * Will only set a warning instead of failing if the global $wgDebugAPI
         * is set to true. Otherwise behaves exactly as dieUsageMsg().
         * @param array|string $error Element of a getUserPermissionsErrors()-style array
+        * @throws UsageException
         * @since 1.21
         */
        public function dieUsageMsgOrDebug( $error ) {
@@ -1973,6 +1997,7 @@ abstract class ApiBase extends ContextSource {
         * Die with the $prefix.'badcontinue' error. This call is common enough to
         * make it into the base method.
         * @param bool $condition Will only die if this value is true
+        * @throws UsageException
         * @since 1.21
         */
        protected function dieContinueUsageIf( $condition ) {
@@ -1999,6 +2024,14 @@ abstract class ApiBase extends ContextSource {
                        $key = array_shift( $error );
                }
 
+               if ( $key instanceof IApiMessage ) {
+                       return array(
+                               'code' => $key->getApiCode(),
+                               'info' => $key->inLanguage( 'en' )->useDatabase( false )->text(),
+                               'data' => $key->getApiData()
+                       );
+               }
+
                if ( isset( self::$messageMap[$key] ) ) {
                        return array(
                                'code' => wfMsgReplaceArgs( self::$messageMap[$key]['code'], $error ),
@@ -2014,7 +2047,7 @@ abstract class ApiBase extends ContextSource {
         * Internal code errors should be reported with this method
         * @param string $method Method or function name
         * @param string $message Error message
-        * @throws MWException
+        * @throws MWException always
         */
        protected static function dieDebug( $method, $message ) {
                throw new MWException( "Internal error in $method: $message" );
@@ -2672,14 +2705,14 @@ abstract class ApiBase extends ContextSource {
                                        $desc = implode( $paramPrefix, $desc );
                                }
 
-                               //handle shorthand
+                               // handle shorthand
                                if ( !is_array( $paramSettings ) ) {
                                        $paramSettings = array(
                                                self::PARAM_DFLT => $paramSettings,
                                        );
                                }
 
-                               //handle missing type
+                               // handle missing type
                                if ( !isset( $paramSettings[ApiBase::PARAM_TYPE] ) ) {
                                        $dflt = isset( $paramSettings[ApiBase::PARAM_DFLT] )
                                                ? $paramSettings[ApiBase::PARAM_DFLT]
@@ -2814,7 +2847,7 @@ abstract class ApiBase extends ContextSource {
 
        /**
         * @deprecated since 1.25, always returns empty string
-        * @param DatabaseBase|bool $db
+        * @param IDatabase|bool $db
         * @return string
         */
        public function getModuleProfileName( $db = false ) {