SpecialVersion: Handle Closures in $wgHooks nicer
[lhc/web/wiklou.git] / includes / api / ApiResult.php
index 490b831..f0c7430 100644 (file)
@@ -140,8 +140,7 @@ class ApiResult implements ApiSerializable {
         */
        public function __construct( $maxSize ) {
                if ( $maxSize instanceof ApiMain ) {
-                       /// @todo: After fixing Wikidata unit tests, warn
-                       //wfDeprecated( 'Passing ApiMain to ' . __METHOD__ . ' is deprecated', '1.25' );
+                       wfDeprecated( 'ApiMain to ' . __METHOD__, '1.25' );
                        $this->errorFormatter = $maxSize->getErrorFormatter();
                        $this->mainForContinuation = $maxSize;
                        $maxSize = $maxSize->getConfig()->get( 'APIMaxResultSize' );
@@ -180,7 +179,9 @@ class ApiResult implements ApiSerializable {
         * Clear the current result data.
         */
        public function reset() {
-               $this->data = array();
+               $this->data = array(
+                       self::META_TYPE => 'assoc', // Usually what's desired
+               );
                $this->size = 0;
        }
 
@@ -275,6 +276,10 @@ class ApiResult implements ApiSerializable {
         * @param int $flags Zero or more OR-ed flags like OVERRIDE | ADD_ON_TOP.
         */
        public static function setValue( array &$arr, $name, $value, $flags = 0 ) {
+               if ( !( $flags & ApiResult::NO_VALIDATE ) ) {
+                       $value = self::validateValue( $value );
+               }
+
                if ( $name === null ) {
                        if ( $flags & ApiResult::ADD_ON_TOP ) {
                                array_unshift( $arr, $value );
@@ -284,10 +289,6 @@ class ApiResult implements ApiSerializable {
                        return;
                }
 
-               if ( !( $flags & ApiResult::NO_VALIDATE ) ) {
-                       $value = self::validateValue( $value );
-               }
-
                $exists = isset( $arr[$name] );
                if ( !$exists || ( $flags & ApiResult::OVERRIDE ) ) {
                        if ( !$exists && ( $flags & ApiResult::ADD_ON_TOP ) ) {
@@ -301,10 +302,14 @@ class ApiResult implements ApiSerializable {
                                $arr[$name] += $value;
                        } else {
                                $keys = join( ', ', array_keys( $conflicts ) );
-                               throw new RuntimeException( "Conflicting keys ($keys) when attempting to merge element $name" );
+                               throw new RuntimeException(
+                                       "Conflicting keys ($keys) when attempting to merge element $name"
+                               );
                        }
                } else {
-                       throw new RuntimeException( "Attempting to add element $name=$value, existing value is {$arr[$name]}" );
+                       throw new RuntimeException(
+                               "Attempting to add element $name=$value, existing value is {$arr[$name]}"
+                       );
                }
        }
 
@@ -702,7 +707,9 @@ class ApiResult implements ApiSerializable {
         * @param string $kvpKeyName See ApiResult::META_KVP_KEY_NAME
         */
        public static function setArrayType( array &$arr, $type, $kvpKeyName = null ) {
-               if ( !in_array( $type, array( 'default', 'array', 'assoc', 'kvp', 'BCarray', 'BCassoc', 'BCkvp' ), true ) ) {
+               if ( !in_array( $type, array(
+                               'default', 'array', 'assoc', 'kvp', 'BCarray', 'BCassoc', 'BCkvp'
+                               ), true ) ) {
                        throw new InvalidArgumentException( 'Bad type' );
                }
                $arr[self::META_TYPE] = $type;
@@ -831,11 +838,13 @@ class ApiResult implements ApiSerializable {
                                isset( $metadata[self::META_BC_SUBELEMENTS] )
                        ) {
                                foreach ( $metadata[self::META_BC_SUBELEMENTS] as $k ) {
-                                       $data[$k] = array(
-                                               '*' => $data[$k],
-                                               self::META_CONTENT => '*',
-                                               self::META_TYPE => 'assoc',
-                                       );
+                                       if ( isset( $data[$k] ) ) {
+                                               $data[$k] = array(
+                                                       '*' => $data[$k],
+                                                       self::META_CONTENT => '*',
+                                                       self::META_TYPE => 'assoc',
+                                               );
+                                       }
                                }
                        }
 
@@ -1032,7 +1041,8 @@ class ApiResult implements ApiSerializable {
        /**
         * Get the 'real' size of a result item. This means the strlen() of the item,
         * or the sum of the strlen()s of the elements if the item is an array.
-        * @note Once the deprecated public self::size is removed, we can rename this back to a less awkward name.
+        * @note Once the deprecated public self::size is removed, we can rename
+        *       this back to a less awkward name.
         * @param mixed $value
         * @return int
         */
@@ -1093,6 +1103,61 @@ class ApiResult implements ApiSerializable {
                return $ret;
        }
 
+       /**
+        * Add the correct metadata to an array of vars we want to export through
+        * the API.
+        *
+        * @param array $vars
+        * @param boolean $forceHash
+        * @return array
+        */
+       public static function addMetadataToResultVars( $vars, $forceHash = true ) {
+               // Process subarrays and determine if this is a JS [] or {}
+               $hash = $forceHash;
+               $maxKey = -1;
+               $bools = array();
+               foreach ( $vars as $k => $v ) {
+                       if ( is_array( $v ) || is_object( $v ) ) {
+                               $vars[$k] = ApiResult::addMetadataToResultVars( (array)$v, is_object( $v ) );
+                       } elseif ( is_bool( $v ) ) {
+                               // Better here to use real bools even in BC formats
+                               $bools[] = $k;
+                       }
+                       if ( is_string( $k ) ) {
+                               $hash = true;
+                       } elseif ( $k > $maxKey ) {
+                               $maxKey = $k;
+                       }
+               }
+               if ( !$hash && $maxKey !== count( $vars ) - 1 ) {
+                       $hash = true;
+               }
+
+               // Set metadata appropriately
+               if ( $hash ) {
+                       // Get the list of keys we actually care about. Unfortunately, we can't support
+                       // certain keys that conflict with ApiResult metadata.
+                       $keys = array_diff( array_keys( $vars ), array(
+                               ApiResult::META_TYPE, ApiResult::META_PRESERVE_KEYS, ApiResult::META_KVP_KEY_NAME,
+                               ApiResult::META_INDEXED_TAG_NAME, ApiResult::META_BC_BOOLS
+                       ) );
+
+                       return array(
+                               ApiResult::META_TYPE => 'kvp',
+                               ApiResult::META_KVP_KEY_NAME => 'key',
+                               ApiResult::META_PRESERVE_KEYS => $keys,
+                               ApiResult::META_BC_BOOLS => $bools,
+                               ApiResult::META_INDEXED_TAG_NAME => 'var',
+                       ) + $vars;
+               } else {
+                       return array(
+                               ApiResult::META_TYPE => 'array',
+                               ApiResult::META_BC_BOOLS => $bools,
+                               ApiResult::META_INDEXED_TAG_NAME => 'value',
+                       ) + $vars;
+               }
+       }
+
        /**@}*/
 
        /************************************************************************//**
@@ -1130,7 +1195,7 @@ class ApiResult implements ApiSerializable {
         * @return array
         */
        public function getData() {
-               /// @todo: Warn after fixing remaining callers: Wikibase, Gather
+               wfDeprecated( __METHOD__, '1.25' );
                return $this->getResultData( null, array(
                        'BC' => array(),
                        'Types' => array(),
@@ -1172,7 +1237,7 @@ class ApiResult implements ApiSerializable {
         *    new method signature.
         */
        public static function setElement( &$arr, $name, $value, $flags = 0 ) {
-               /// @todo: Warn after fixing remaining callers: Wikibase
+               wfDeprecated( __METHOD__, '1.25' );
                return self::setValue( $arr, $name, $value, $flags );
        }
 
@@ -1187,7 +1252,7 @@ class ApiResult implements ApiSerializable {
         *  format "<elem>text</elem>" without attributes.
         */
        public static function setContent( &$arr, $value, $subElemName = null ) {
-               /// @todo: Warn after fixing remaining callers: Wikibase
+               wfDeprecated( __METHOD__, '1.25' );
                if ( is_array( $value ) ) {
                        throw new InvalidArgumentException( __METHOD__ . ': Bad parameter' );
                }
@@ -1211,44 +1276,29 @@ class ApiResult implements ApiSerializable {
         * @param string $tag Tag name
         */
        public function setIndexedTagName_recursive( &$arr, $tag ) {
-               /// @todo: Warn after fixing remaining callers: Wikibase
+               wfDeprecated( __METHOD__, '1.25' );
                if ( !is_array( $arr ) ) {
                        return;
                }
-               self::setIndexedTagNameOnSubarrays( $arr, $tag );
-       }
-
-       /**
-        * Set indexed tag name on all subarrays of $arr
-        *
-        * Does not set the tag name for $arr itself.
-        *
-        * @since 1.25
-        * @deprecated For backwards compatibility, do not use
-        * @todo: Remove after updating callers to use self::setIndexedTagNameRecursive
-        * @param array &$arr
-        * @param string $tag Tag name
-        */
-       public static function setIndexedTagNameOnSubarrays( array &$arr, $tag ) {
                if ( !is_string( $tag ) ) {
                        throw new InvalidArgumentException( 'Bad tag name' );
                }
                foreach ( $arr as $k => &$v ) {
                        if ( !self::isMetadataKey( $k ) && is_array( $v ) ) {
                                $v[self::META_INDEXED_TAG_NAME] = $tag;
-                               self::setIndexedTagNameOnSubarrays( $v, $tag );
+                               $this->setIndexedTagName_recursive( $v, $tag );
                        }
                }
        }
 
        /**
-        * Alias for self::defineIndexedTagName()
+        * Alias for self::addIndexedTagName()
         * @deprecated since 1.25, use $this->addIndexedTagName() instead
         * @param array $path Path to the array, like addValue()'s $path
         * @param string $tag
         */
        public function setIndexedTagName_internal( $path, $tag ) {
-               /// @todo: Warn after fixing remaining callers: Wikibase, Gather
+               wfDeprecated( __METHOD__, '1.25' );
                $this->addIndexedTagName( $path, $tag );
        }
 
@@ -1288,7 +1338,7 @@ class ApiResult implements ApiSerializable {
        public function beginContinuation(
                $continue, array $allModules = array(), array $generatedModules = array()
        ) {
-               /// @todo: Warn after fixing remaining callers: Gather
+               wfDeprecated( __METHOD__, '1.25' );
                if ( $this->mainForContinuation->getContinuationManager() ) {
                        throw new UnexpectedValueException(
                                __METHOD__ . ': Continuation already in progress from ' .
@@ -1368,7 +1418,7 @@ class ApiResult implements ApiSerializable {
         *   the style used in 1.20 and earlier.
         */
        public function endContinuation( $style = 'standard' ) {
-               /// @todo: Warn after fixing remaining callers: Gather
+               wfDeprecated( __METHOD__, '1.25' );
                if ( !$this->mainForContinuation->getContinuationManager() ) {
                        return;
                }
@@ -1413,76 +1463,10 @@ class ApiResult implements ApiSerializable {
         * @return array
         */
        public function convertStatusToArray( $status, $errorType = 'error' ) {
-               /// @todo: Warn after fixing remaining callers: CentralAuth
+               wfDeprecated( __METHOD__, '1.25' );
                return $this->errorFormatter->arrayFromStatus( $status, $errorType );
        }
 
-       /**
-        * Alias for self::addIndexedTagName
-        *
-        * A bunch of extensions were updated for an earlier version of this
-        * extension which used this name.
-        * @deprecated For backwards compatibility, do not use
-        * @todo: Remove after updating callers to use self::addIndexedTagName
-        */
-       public function defineIndexedTagName( $path, $tag ) {
-               return $this->addIndexedTagName( $path, $tag );
-       }
-
-       /**
-        * Alias for self::stripMetadata
-        *
-        * A bunch of extensions were updated for an earlier version of this
-        * extension which used this name.
-        * @deprecated For backwards compatibility, do not use
-        * @todo: Remove after updating callers to use self::stripMetadata
-        */
-       public static function removeMetadata( $data ) {
-               return self::stripMetadata( $data );
-       }
-
-       /**
-        * Alias for self::stripMetadataNonRecursive
-        *
-        * A bunch of extensions were updated for an earlier version of this
-        * extension which used this name.
-        * @deprecated For backwards compatibility, do not use
-        * @todo: Remove after updating callers to use self::stripMetadataNonRecursive
-        */
-       public static function removeMetadataNonRecursive( $data, &$metadata = null ) {
-               return self::stripMetadataNonRecursive( $data, $metadata );
-       }
-
-       /**
-        * @deprecated For backwards compatibility, do not use
-        * @todo: Remove after updating callers
-        */
-       public static function transformForBC( array $data ) {
-               return self::applyTransformations( $data, array(
-                       'BC' => array(),
-               ) );
-       }
-
-       /**
-        * @deprecated For backwards compatibility, do not use
-        * @todo: Remove after updating callers
-        */
-       public static function transformForTypes( $data, $options = array() ) {
-               $transforms = array(
-                       'Types' => array(),
-               );
-               if ( isset( $options['assocAsObject'] ) ) {
-                       $transforms['Types']['AssocAsObject'] = $options['assocAsObject'];
-               }
-               if ( isset( $options['armorKVP'] ) ) {
-                       $transforms['Types']['ArmorKVP'] = $options['armorKVP'];
-               }
-               if ( !empty( $options['BC'] ) ) {
-                       $transforms['BC'] = array( 'nobool', 'no*', 'nosub' );
-               }
-               return self::applyTransformations( $data, $transforms );
-       }
-
        /**@}*/
 }