MediaWiki
REL1_23
|
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 }