diff options
Diffstat (limited to 'includes/api/ApiResult.php')
-rw-r--r-- | includes/api/ApiResult.php | 144 |
1 files changed, 128 insertions, 16 deletions
diff --git a/includes/api/ApiResult.php b/includes/api/ApiResult.php index 900953e0..3dbee08a 100644 --- a/includes/api/ApiResult.php +++ b/includes/api/ApiResult.php @@ -47,14 +47,16 @@ if (!defined('MEDIAWIKI')) { */ class ApiResult extends ApiBase { - private $mData, $mIsRawMode; + private $mData, $mIsRawMode, $mSize, $mCheckingSize; /** - * Constructor - */ + * Constructor + * @param $main ApiMain object + */ public function __construct($main) { parent :: __construct($main, 'result'); $this->mIsRawMode = false; + $this->mCheckingSize = true; $this->reset(); } @@ -63,6 +65,7 @@ class ApiResult extends ApiBase { */ public function reset() { $this->mData = array (); + $this->mSize = 0; } /** @@ -74,22 +77,68 @@ class ApiResult extends ApiBase { } /** - * Returns true if the result is being created for the formatter that requested raw data. + * Returns true whether the formatter requested raw data. + * @return bool */ public function getIsRawMode() { return $this->mIsRawMode; } /** - * Get result's internal data array + * Get the result's internal data array (read-only) + * @return array */ - public function & getData() { + public function getData() { return $this->mData; } + + /** + * 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. + * @param $value mixed + * @return int + */ + public static function size($value) { + $s = 0; + if(is_array($value)) + foreach($value as $v) + $s += self::size($v); + else if(!is_object($value)) + // Objects can't always be cast to string + $s = strlen($value); + return $s; + } + + /** + * Get the size of the result, i.e. the amount of bytes in it + * @return int + */ + public function getSize() { + return $this->mSize; + } + + /** + * Disable size checking in addValue(). Don't use this unless you + * REALLY know what you're doing. Values added while size checking + * was disabled will not be counted (ever) + */ + public function disableSizeCheck() { + $this->mCheckingSize = false; + } + + /** + * Re-enable size checking in addValue() + */ + public function enableSizeCheck() { + $this->mCheckingSize = true; + } /** * Add an output value to the array by name. * Verifies that value with the same name has not been added before. + * @param $arr array to add $value to + * @param $name string Index of $arr to add $value at + * @param $value mixed */ public static function setElement(& $arr, $name, $value) { if ($arr === null || $name === null || $value === null || !is_array($arr) || is_array($name)) @@ -109,10 +158,12 @@ class ApiResult extends ApiBase { } /** - * Adds the content element to the array. + * Adds a content element to an array. * Use this function instead of hardcoding the '*' element. - * @param string $subElemName when present, content element is created as a sub item of the arr. - * Use this parameter to create elements in format <elem>text</elem> without attributes + * @param $arr array to add the content element to + * @param $subElemName string when present, content element is created + * as a sub item of $arr. Use this parameter to create elements in + * format <elem>text</elem> without attributes */ public static function setContent(& $arr, $value, $subElemName = null) { if (is_array($value)) @@ -128,7 +179,10 @@ class ApiResult extends ApiBase { /** * In case the array contains indexed values (in addition to named), - * all indexed values will have the given tag name. + * give all indexed values the given tag name. This function MUST be + * called on every arrray that has numerical indexes. + * @param $arr array + * @param $tag string Tag name */ public function setIndexedTagName(& $arr, $tag) { // In raw mode, add the '_element', otherwise just ignore @@ -141,7 +195,9 @@ class ApiResult extends ApiBase { } /** - * Calls setIndexedTagName() on $arr and each sub-array + * Calls setIndexedTagName() on each sub-array of $arr + * @param $arr array + * @param $tag string Tag name */ public function setIndexedTagName_recursive(&$arr, $tag) { @@ -157,14 +213,41 @@ class ApiResult extends ApiBase { } /** + * Calls setIndexedTagName() on an array already in the result. + * Don't specify a path to a value that's not in the result, or + * you'll get nasty errors. + * @param $path array Path to the array, like addValue()'s $path + * @param $tag string + */ + public function setIndexedTagName_internal( $path, $tag ) { + $data = & $this->mData; + foreach((array)$path as $p) { + if ( !isset( $data[$p] ) ) { + $data[$p] = array(); + } + $data = & $data[$p]; + } + if(is_null($data)) + return; + $this->setIndexedTagName($data, $tag); + } + + /** * Add value to the output data at the given path. * Path is an indexed array, each element specifing the branch at which to add the new value * Setting $path to array('a','b','c') is equivalent to data['a']['b']['c'] = $value * If $name is empty, the $value is added as a next list element data[] = $value + * @return bool True if $value fits in the result, false if not */ public function addValue($path, $name, $value) { - - $data = & $this->getData(); + global $wgAPIMaxResultSize; + $data = & $this->mData; + if( $this->mCheckingSize ) { + $newsize = $this->mSize + self::size($value); + if($newsize > $wgAPIMaxResultSize) + return false; + $this->mSize = $newsize; + } if (!is_null($path)) { if (is_array($path)) { @@ -184,6 +267,26 @@ class ApiResult extends ApiBase { $data[] = $value; // Add list element else ApiResult :: setElement($data, $name, $value); // Add named element + return true; + } + + /** + * Unset a value previously added to the result set. + * Fails silently if the value isn't found. + * For parameters, see addValue() + * @param $path array + * @param $name string + */ + public function unsetValue($path, $name) { + $data = & $this->mData; + if(!is_null($path)) + foreach((array)$path as $p) { + if(!isset($data[$p])) + return; + $data = & $data[$p]; + } + $this->mSize -= self::size($data[$name]); + unset($data[$name]); } /** @@ -191,8 +294,17 @@ class ApiResult extends ApiBase { */ public function cleanUpUTF8() { - $data = & $this->getData(); - array_walk_recursive($data, array('UtfNormal', 'cleanUp')); + array_walk_recursive($this->mData, array('ApiResult', 'cleanUp_helper')); + } + + /** + * Callback function for cleanUpUTF8() + */ + private static function cleanUp_helper(&$s) + { + if(!is_string($s)) + return; + $s = UtfNormal::cleanUp($s); } public function execute() { @@ -200,7 +312,7 @@ class ApiResult extends ApiBase { } public function getVersion() { - return __CLASS__ . ': $Id: ApiResult.php 45752 2009-01-14 21:36:57Z catrope $'; + return __CLASS__ . ': $Id: ApiResult.php 47447 2009-02-18 12:41:28Z tstarling $'; } } |