MediaWiki  REL1_22
ApiResult.php
Go to the documentation of this file.
00001 <?php
00044 class ApiResult extends ApiBase {
00045 
00050     const OVERRIDE = 1;
00051 
00057     const ADD_ON_TOP = 2;
00058 
00059     private $mData, $mIsRawMode, $mSize, $mCheckingSize;
00060 
00065     public function __construct( $main ) {
00066         parent::__construct( $main, 'result' );
00067         $this->mIsRawMode = false;
00068         $this->mCheckingSize = true;
00069         $this->reset();
00070     }
00071 
00075     public function reset() {
00076         $this->mData = array();
00077         $this->mSize = 0;
00078     }
00079 
00084     public function setRawMode() {
00085         $this->mIsRawMode = true;
00086     }
00087 
00092     public function getIsRawMode() {
00093         return $this->mIsRawMode;
00094     }
00095 
00100     public function getData() {
00101         return $this->mData;
00102     }
00103 
00110     public static function size( $value ) {
00111         $s = 0;
00112         if ( is_array( $value ) ) {
00113             foreach ( $value as $v ) {
00114                 $s += self::size( $v );
00115             }
00116         } elseif ( !is_object( $value ) ) {
00117             // Objects can't always be cast to string
00118             $s = strlen( $value );
00119         }
00120         return $s;
00121     }
00122 
00127     public function getSize() {
00128         return $this->mSize;
00129     }
00130 
00136     public function disableSizeCheck() {
00137         $this->mCheckingSize = false;
00138     }
00139 
00143     public function enableSizeCheck() {
00144         $this->mCheckingSize = true;
00145     }
00146 
00159     public static function setElement( &$arr, $name, $value, $flags = 0 ) {
00160         if ( $arr === null || $name === null || $value === null || !is_array( $arr ) || is_array( $name ) ) {
00161             ApiBase::dieDebug( __METHOD__, 'Bad parameter' );
00162         }
00163 
00164         $exists = isset( $arr[$name] );
00165         if ( !$exists || ( $flags & ApiResult::OVERRIDE ) ) {
00166             if ( !$exists && ( $flags & ApiResult::ADD_ON_TOP ) ) {
00167                 $arr = array( $name => $value ) + $arr;
00168             } else {
00169                 $arr[$name] = $value;
00170             }
00171         } elseif ( is_array( $arr[$name] ) && is_array( $value ) ) {
00172             $merged = array_intersect_key( $arr[$name], $value );
00173             if ( !count( $merged ) ) {
00174                 $arr[$name] += $value;
00175             } else {
00176                 ApiBase::dieDebug( __METHOD__, "Attempting to merge element $name" );
00177             }
00178         } else {
00179             ApiBase::dieDebug( __METHOD__, "Attempting to add element $name=$value, existing value is {$arr[$name]}" );
00180         }
00181     }
00182 
00192     public static function setContent( &$arr, $value, $subElemName = null ) {
00193         if ( is_array( $value ) ) {
00194             ApiBase::dieDebug( __METHOD__, 'Bad parameter' );
00195         }
00196         if ( is_null( $subElemName ) ) {
00197             ApiResult::setElement( $arr, '*', $value );
00198         } else {
00199             if ( !isset( $arr[$subElemName] ) ) {
00200                 $arr[$subElemName] = array();
00201             }
00202             ApiResult::setElement( $arr[$subElemName], '*', $value );
00203         }
00204     }
00205 
00213     public function setIndexedTagName( &$arr, $tag ) {
00214         // In raw mode, add the '_element', otherwise just ignore
00215         if ( !$this->getIsRawMode() ) {
00216             return;
00217         }
00218         if ( $arr === null || $tag === null || !is_array( $arr ) || is_array( $tag ) ) {
00219             ApiBase::dieDebug( __METHOD__, 'Bad parameter' );
00220         }
00221         // Do not use setElement() as it is ok to call this more than once
00222         $arr['_element'] = $tag;
00223     }
00224 
00230     public function setIndexedTagName_recursive( &$arr, $tag ) {
00231         if ( !is_array( $arr ) ) {
00232             return;
00233         }
00234         foreach ( $arr as &$a ) {
00235             if ( !is_array( $a ) ) {
00236                 continue;
00237             }
00238             $this->setIndexedTagName( $a, $tag );
00239             $this->setIndexedTagName_recursive( $a, $tag );
00240         }
00241     }
00242 
00250     public function setIndexedTagName_internal( $path, $tag ) {
00251         $data = &$this->mData;
00252         foreach ( (array)$path as $p ) {
00253             if ( !isset( $data[$p] ) ) {
00254                 $data[$p] = array();
00255             }
00256             $data = &$data[$p];
00257         }
00258         if ( is_null( $data ) ) {
00259             return;
00260         }
00261         $this->setIndexedTagName( $data, $tag );
00262     }
00263 
00281     public function addValue( $path, $name, $value, $flags = 0 ) {
00282         global $wgAPIMaxResultSize;
00283 
00284         $data = &$this->mData;
00285         if ( $this->mCheckingSize ) {
00286             $newsize = $this->mSize + self::size( $value );
00287             if ( $newsize > $wgAPIMaxResultSize ) {
00288                 $this->setWarning(
00289                     "This result was truncated because it would otherwise be larger than the " .
00290                             "limit of {$wgAPIMaxResultSize} bytes" );
00291                 return false;
00292             }
00293             $this->mSize = $newsize;
00294         }
00295 
00296         $addOnTop = $flags & ApiResult::ADD_ON_TOP;
00297         if ( $path !== null ) {
00298             foreach ( (array)$path as $p ) {
00299                 if ( !isset( $data[$p] ) ) {
00300                     if ( $addOnTop ) {
00301                         $data = array( $p => array() ) + $data;
00302                         $addOnTop = false;
00303                     } else {
00304                         $data[$p] = array();
00305                     }
00306                 }
00307                 $data = &$data[$p];
00308             }
00309         }
00310 
00311         if ( !$name ) {
00312             // Add list element
00313             if ( $addOnTop ) {
00314                 // This element needs to be inserted in the beginning
00315                 // Numerical indexes will be renumbered
00316                 array_unshift( $data, $value );
00317             } else {
00318                 // Add new value at the end
00319                 $data[] = $value;
00320             }
00321         } else {
00322             // Add named element
00323             self::setElement( $data, $name, $value, $flags );
00324         }
00325         return true;
00326     }
00327 
00334     public function setParsedLimit( $moduleName, $limit ) {
00335         // Add value, allowing overwriting
00336         $this->addValue( 'limits', $moduleName, $limit, ApiResult::OVERRIDE );
00337     }
00338 
00346     public function unsetValue( $path, $name ) {
00347         $data = &$this->mData;
00348         if ( $path !== null ) {
00349             foreach ( (array)$path as $p ) {
00350                 if ( !isset( $data[$p] ) ) {
00351                     return;
00352                 }
00353                 $data = &$data[$p];
00354             }
00355         }
00356         $this->mSize -= self::size( $data[$name] );
00357         unset( $data[$name] );
00358     }
00359 
00363     public function cleanUpUTF8() {
00364         array_walk_recursive( $this->mData, array( 'ApiResult', 'cleanUp_helper' ) );
00365     }
00366 
00372     private static function cleanUp_helper( &$s ) {
00373         if ( !is_string( $s ) ) {
00374             return;
00375         }
00376         global $wgContLang;
00377         $s = $wgContLang->normalize( $s );
00378     }
00379 
00386     public function convertStatusToArray( $status, $errorType = 'error' ) {
00387         if ( $status->isGood() ) {
00388             return array();
00389         }
00390 
00391         $result = array();
00392         foreach ( $status->getErrorsByType( $errorType ) as $error ) {
00393             $this->setIndexedTagName( $error['params'], 'param' );
00394             $result[] = $error;
00395         }
00396         $this->setIndexedTagName( $result, $errorType );
00397         return $result;
00398     }
00399 
00400     public function execute() {
00401         ApiBase::dieDebug( __METHOD__, 'execute() is not supported on Result object' );
00402     }
00403 }