MediaWiki  REL1_23
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 
00086     public function setRawMode( $flag = true ) {
00087         $this->mIsRawMode = $flag;
00088     }
00089 
00094     public function getIsRawMode() {
00095         return $this->mIsRawMode;
00096     }
00097 
00102     public function getData() {
00103         return $this->mData;
00104     }
00105 
00112     public static function size( $value ) {
00113         $s = 0;
00114         if ( is_array( $value ) ) {
00115             foreach ( $value as $v ) {
00116                 $s += self::size( $v );
00117             }
00118         } elseif ( !is_object( $value ) ) {
00119             // Objects can't always be cast to string
00120             $s = strlen( $value );
00121         }
00122 
00123         return $s;
00124     }
00125 
00130     public function getSize() {
00131         return $this->mSize;
00132     }
00133 
00139     public function disableSizeCheck() {
00140         $this->mCheckingSize = false;
00141     }
00142 
00146     public function enableSizeCheck() {
00147         $this->mCheckingSize = true;
00148     }
00149 
00163     public static function setElement( &$arr, $name, $value, $flags = 0 ) {
00164         if ( $arr === null || $name === null || $value === null
00165             || !is_array( $arr ) || is_array( $name )
00166         ) {
00167             ApiBase::dieDebug( __METHOD__, 'Bad parameter' );
00168         }
00169 
00170         $exists = isset( $arr[$name] );
00171         if ( !$exists || ( $flags & ApiResult::OVERRIDE ) ) {
00172             if ( !$exists && ( $flags & ApiResult::ADD_ON_TOP ) ) {
00173                 $arr = array( $name => $value ) + $arr;
00174             } else {
00175                 $arr[$name] = $value;
00176             }
00177         } elseif ( is_array( $arr[$name] ) && is_array( $value ) ) {
00178             $merged = array_intersect_key( $arr[$name], $value );
00179             if ( !count( $merged ) ) {
00180                 $arr[$name] += $value;
00181             } else {
00182                 ApiBase::dieDebug( __METHOD__, "Attempting to merge element $name" );
00183             }
00184         } else {
00185             ApiBase::dieDebug(
00186                 __METHOD__,
00187                 "Attempting to add element $name=$value, existing value is {$arr[$name]}"
00188             );
00189         }
00190     }
00191 
00201     public static function setContent( &$arr, $value, $subElemName = null ) {
00202         if ( is_array( $value ) ) {
00203             ApiBase::dieDebug( __METHOD__, 'Bad parameter' );
00204         }
00205         if ( is_null( $subElemName ) ) {
00206             ApiResult::setElement( $arr, '*', $value );
00207         } else {
00208             if ( !isset( $arr[$subElemName] ) ) {
00209                 $arr[$subElemName] = array();
00210             }
00211             ApiResult::setElement( $arr[$subElemName], '*', $value );
00212         }
00213     }
00214 
00222     public function setIndexedTagName( &$arr, $tag ) {
00223         // In raw mode, add the '_element', otherwise just ignore
00224         if ( !$this->getIsRawMode() ) {
00225             return;
00226         }
00227         if ( $arr === null || $tag === null || !is_array( $arr ) || is_array( $tag ) ) {
00228             ApiBase::dieDebug( __METHOD__, 'Bad parameter' );
00229         }
00230         // Do not use setElement() as it is ok to call this more than once
00231         $arr['_element'] = $tag;
00232     }
00233 
00239     public function setIndexedTagName_recursive( &$arr, $tag ) {
00240         if ( !is_array( $arr ) ) {
00241             return;
00242         }
00243         foreach ( $arr as &$a ) {
00244             if ( !is_array( $a ) ) {
00245                 continue;
00246             }
00247             $this->setIndexedTagName( $a, $tag );
00248             $this->setIndexedTagName_recursive( $a, $tag );
00249         }
00250     }
00251 
00259     public function setIndexedTagName_internal( $path, $tag ) {
00260         $data = &$this->mData;
00261         foreach ( (array)$path as $p ) {
00262             if ( !isset( $data[$p] ) ) {
00263                 $data[$p] = array();
00264             }
00265             $data = &$data[$p];
00266         }
00267         if ( is_null( $data ) ) {
00268             return;
00269         }
00270         $this->setIndexedTagName( $data, $tag );
00271     }
00272 
00291     public function addValue( $path, $name, $value, $flags = 0 ) {
00292         global $wgAPIMaxResultSize;
00293 
00294         $data = &$this->mData;
00295         if ( $this->mCheckingSize ) {
00296             $newsize = $this->mSize + self::size( $value );
00297             if ( $newsize > $wgAPIMaxResultSize ) {
00298                 $this->setWarning(
00299                     "This result was truncated because it would otherwise be larger than the " .
00300                         "limit of {$wgAPIMaxResultSize} bytes" );
00301 
00302                 return false;
00303             }
00304             $this->mSize = $newsize;
00305         }
00306 
00307         $addOnTop = $flags & ApiResult::ADD_ON_TOP;
00308         if ( $path !== null ) {
00309             foreach ( (array)$path as $p ) {
00310                 if ( !isset( $data[$p] ) ) {
00311                     if ( $addOnTop ) {
00312                         $data = array( $p => array() ) + $data;
00313                         $addOnTop = false;
00314                     } else {
00315                         $data[$p] = array();
00316                     }
00317                 }
00318                 $data = &$data[$p];
00319             }
00320         }
00321 
00322         if ( !$name ) {
00323             // Add list element
00324             if ( $addOnTop ) {
00325                 // This element needs to be inserted in the beginning
00326                 // Numerical indexes will be renumbered
00327                 array_unshift( $data, $value );
00328             } else {
00329                 // Add new value at the end
00330                 $data[] = $value;
00331             }
00332         } else {
00333             // Add named element
00334             self::setElement( $data, $name, $value, $flags );
00335         }
00336 
00337         return true;
00338     }
00339 
00346     public function setParsedLimit( $moduleName, $limit ) {
00347         // Add value, allowing overwriting
00348         $this->addValue( 'limits', $moduleName, $limit, ApiResult::OVERRIDE );
00349     }
00350 
00358     public function unsetValue( $path, $name ) {
00359         $data = &$this->mData;
00360         if ( $path !== null ) {
00361             foreach ( (array)$path as $p ) {
00362                 if ( !isset( $data[$p] ) ) {
00363                     return;
00364                 }
00365                 $data = &$data[$p];
00366             }
00367         }
00368         $this->mSize -= self::size( $data[$name] );
00369         unset( $data[$name] );
00370     }
00371 
00375     public function cleanUpUTF8() {
00376         array_walk_recursive( $this->mData, array( 'ApiResult', 'cleanUp_helper' ) );
00377     }
00378 
00384     private static function cleanUp_helper( &$s ) {
00385         if ( !is_string( $s ) ) {
00386             return;
00387         }
00388         global $wgContLang;
00389         $s = $wgContLang->normalize( $s );
00390     }
00391 
00398     public function convertStatusToArray( $status, $errorType = 'error' ) {
00399         if ( $status->isGood() ) {
00400             return array();
00401         }
00402 
00403         $result = array();
00404         foreach ( $status->getErrorsByType( $errorType ) as $error ) {
00405             $this->setIndexedTagName( $error['params'], 'param' );
00406             $result[] = $error;
00407         }
00408         $this->setIndexedTagName( $result, $errorType );
00409 
00410         return $result;
00411     }
00412 
00413     public function execute() {
00414         ApiBase::dieDebug( __METHOD__, 'execute() is not supported on Result object' );
00415     }
00416 }