<?php
-
/*
* Created on Sep 4, 2006
*
* API for MediaWiki 1.8+
*
- * Copyright (C) 2006 Yuri Astrakhan <FirstnameLastname@gmail.com>
+ * Copyright (C) 2006 Yuri Astrakhan <Firstname><Lastname>@gmail.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
require_once ('ApiBase.php');
}
+/**
+ * This class represents the result of the API operations.
+ * It simply wraps a nested array() structure, adding some functions to simplify array's modifications.
+ * As various modules execute, they add different pieces of information to this result,
+ * structuring it as it will be given to the client.
+ *
+ * Each subarray may either be a dictionary - key-value pairs with unique keys,
+ * or lists, where the items are added using $data[] = $value notation.
+ *
+ * There are two special key values that change how XML output is generated:
+ * '_element' This key sets the tag name for the rest of the elements in the current array.
+ * It is only inserted if the formatter returned true for getNeedsRawData()
+ * '*' This key has special meaning only to the XML formatter, and is outputed as is
+ * for all others. In XML it becomes the content of the current element.
+ *
+ * @ingroup API
+ */
class ApiResult extends ApiBase {
- private $mData;
+ private $mData, $mIsRawMode;
/**
* Constructor
*/
public function __construct($main) {
- parent :: __construct($main);
- $this->Reset();
+ parent :: __construct($main, 'result');
+ $this->mIsRawMode = false;
+ $this->reset();
}
- public function Reset() {
+ /**
+ * Clear the current result data.
+ */
+ public function reset() {
$this->mData = array ();
}
- function & getData() {
+ /**
+ * Call this function when special elements such as '_element'
+ * are needed by the formatter, for example in XML printing.
+ */
+ public function setRawMode() {
+ $this->mIsRawMode = true;
+ }
+
+ /**
+ * Returns true if the result is being created for the formatter that requested raw data.
+ */
+ public function getIsRawMode() {
+ return $this->mIsRawMode;
+ }
+
+ /**
+ * Get result's internal data array
+ */
+ public function & getData() {
return $this->mData;
}
}
elseif (is_array($arr[$name]) && is_array($value)) {
$merged = array_intersect_key($arr[$name], $value);
- if (empty ($merged))
+ if (!count($merged))
$arr[$name] += $value;
else
ApiBase :: dieDebug(__METHOD__, "Attempting to merge element $name");
/**
* Adds the content element to the 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
*/
- public static function setContent(& $arr, $value) {
+ public static function setContent(& $arr, $value, $subElemName = null) {
if (is_array($value))
ApiBase :: dieDebug(__METHOD__, 'Bad parameter');
- ApiResult :: setElement($arr, '*', $value);
+ if (is_null($subElemName)) {
+ ApiResult :: setElement($arr, '*', $value);
+ } else {
+ if (!isset ($arr[$subElemName]))
+ $arr[$subElemName] = array ();
+ ApiResult :: setElement($arr[$subElemName], '*', $value);
+ }
}
- // public static function makeContentElement($tag, $value) {
- // $result = array();
- // ApiResult::setContent($result, )
- // }
- //
/**
* In case the array contains indexed values (in addition to named),
* all indexed values will have the given tag name.
*/
- public static function setIndexedTagName(& $arr, $tag) {
- // Do not use setElement() as it is ok to call this more than once
+ public function setIndexedTagName(& $arr, $tag) {
+ // In raw mode, add the '_element', otherwise just ignore
+ if (!$this->getIsRawMode())
+ return;
if ($arr === null || $tag === null || !is_array($arr) || is_array($tag))
ApiBase :: dieDebug(__METHOD__, 'Bad parameter');
+ // Do not use setElement() as it is ok to call this more than once
$arr['_element'] = $tag;
}
+ /**
+ * Calls setIndexedTagName() on $arr and each sub-array
+ */
+ public function setIndexedTagName_recursive(&$arr, $tag)
+ {
+ if(!is_array($arr))
+ return;
+ foreach($arr as &$a)
+ {
+ if(!is_array($a))
+ continue;
+ $this->setIndexedTagName($a, $tag);
+ $this->setIndexedTagName_recursive($a, $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
+ * 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
*/
public function addValue($path, $name, $value) {
$data = & $this->getData();
- if (isset ($path)) {
+ if (!is_null($path)) {
if (is_array($path)) {
foreach ($path as $p) {
if (!isset ($data[$p]))
}
}
- ApiResult :: setElement($data, $name, $value);
+ if (!$name)
+ $data[] = $value; // Add list element
+ else
+ ApiResult :: setElement($data, $name, $value); // Add named element
}
- /**
- * Recursivelly removes any elements from the array that begin with an '_'.
- * The content element '*' is the only special element that is left.
- * Use this method when the entire data object gets sent to the user.
- */
- public function SanitizeData() {
- ApiResult :: SanitizeDataInt($this->mData);
+ public function execute() {
+ ApiBase :: dieDebug(__METHOD__, 'execute() is not supported on Result object');
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id$';
}
+}
+
+/* For compatibility with PHP versions < 5.1.0, define our own array_intersect_key function. */
+if (!function_exists('array_intersect_key')) {
+ function array_intersect_key($isec, $keys) {
+ $argc = func_num_args();
+
+ if ($argc > 2) {
+ for ($i = 1; $isec && $i < $argc; $i++) {
+ $arr = func_get_arg($i);
- private static function SanitizeDataInt(& $data) {
- foreach ($data as $key => & $value) {
- if ($key[0] === '_') {
- unset ($data[$key]);
+ foreach (array_keys($isec) as $key) {
+ if (!isset($arr[$key]))
+ unset($isec[$key]);
+ }
}
- elseif (is_array($value)) {
- ApiResult :: SanitizeDataInt($value);
+
+ return $isec;
+ } else {
+ $res = array();
+ foreach (array_keys($isec) as $key) {
+ if (isset($keys[$key]))
+ $res[$key] = $isec[$key];
}
- }
- }
- public function execute() {
- ApiBase :: dieDebug(__METHOD__, 'execute() is not supported on Result object');
+ return $res;
+ }
}
}
-?>
\ No newline at end of file