);\r
\r
// Initialise common code\r
-require (dirname(__FILE__) . "/includes/WebStart.php");\r
+require (dirname(__FILE__) . '/includes/WebStart.php');\r
wfProfileIn('api.php');\r
\r
// Verify that the API has not been disabled\r
foreach ($apiAutoloadClasses as $className => $classFile)\r
$wgAutoloadClasses[$className] = $apiDirectory . $classFile;\r
}\r
-?>
\ No newline at end of file
+?>\r
// Main module has getResult() method overriden\r
// Safety - avoid infinite loop:\r
if ($this->isMain())\r
- $this->dieDebug(__METHOD__ .\r
+ ApiBase :: dieDebug(__METHOD__ .\r
' base method was called on main module. ');\r
return $this->getMain()->getResult();\r
}\r
\r
+ /**\r
+ * Get the result data array\r
+ */\r
+ public function & getResultData() {\r
+ return $this->getResult()->getData();\r
+ }\r
+\r
/**\r
* Generates help message for this module, or false if there is no description\r
*/\r
public function makeHelpMsgParameters() {\r
$params = $this->getAllowedParams();\r
if ($params !== false) {\r
- \r
+\r
$paramsDescription = $this->getParamDescription();\r
$msg = '';\r
foreach (array_keys($params) as $paramName) {\r
$msg .= sprintf(" %-14s - %s\n", $paramName, $desc);\r
}\r
return $msg;\r
- \r
- }\r
- else\r
- return false; \r
+\r
+ } else\r
+ return false;\r
}\r
\r
/**\r
return $results;\r
}\r
\r
- public function getParameter($paramName, $paramSettings){\r
+ public function getParameter($paramName, $paramSettings) {\r
global $wgRequest;\r
\r
if (!is_array($paramSettings)) {\r
if ($type == 'boolean') {\r
if (isset ($default) && $default !== false) {\r
// Having a default value of anything other than 'false' is pointless\r
- $this->dieDebug("Boolean param $paramName's default is set to '$default'");\r
+ ApiBase :: dieDebug("Boolean param $paramName's default is set to '$default'");\r
}\r
\r
- $value = $wgRequest->getCheck($paramName);\r
+ $value = $wgRequest->getCheck($paramName);\r
} else\r
- $value = $wgRequest->getVal($paramName, $default);\r
+ $value = $wgRequest->getVal($paramName, $default);\r
\r
if (isset ($value) && ($multi || is_array($type)))\r
$value = $this->parseMultiValue($paramName, $value, $multi, is_array($type) ? $type : null);\r
break;\r
case 'limit' :\r
if (!isset ($paramSettings[GN_ENUM_MAX1]) || !isset ($paramSettings[GN_ENUM_MAX2]))\r
- $this->dieDebug("MAX1 or MAX2 are not defined for the limit $paramName");\r
+ ApiBase :: dieDebug("MAX1 or MAX2 are not defined for the limit $paramName");\r
if ($multi)\r
- $this->dieDebug("Multi-values not supported for $paramName");\r
+ ApiBase :: dieDebug("Multi-values not supported for $paramName");\r
$min = isset ($paramSettings[GN_ENUM_MIN]) ? $paramSettings[GN_ENUM_MIN] : 0;\r
$value = intval($value);\r
$this->validateLimit($paramName, $value, $min, $paramSettings[GN_ENUM_MAX1], $paramSettings[GN_ENUM_MAX2]);\r
break;\r
case 'boolean' :\r
if ($multi)\r
- $this->dieDebug("Multi-values not supported for $paramName");\r
+ ApiBase :: dieDebug("Multi-values not supported for $paramName");\r
break;\r
case 'timestamp' :\r
if ($multi)\r
- $this->dieDebug("Multi-values not supported for $paramName");\r
+ ApiBase :: dieDebug("Multi-values not supported for $paramName");\r
$value = $this->prepareTimestamp($value); // Adds quotes around timestamp \r
break;\r
default :\r
- $this->dieDebug("Param $paramName's type is unknown - $type");\r
+ ApiBase :: dieDebug("Param $paramName's type is unknown - $type");\r
\r
}\r
}\r
\r
- return $value; \r
+ return $value;\r
}\r
- \r
+\r
/**\r
- * Return an array of values that were given in a "a|b|c" notation,\r
+ * Return an array of values that were given in a 'a|b|c' notation,\r
* after it optionally validates them against the list allowed values.\r
* \r
* @param valueName - The name of the parameter (for error reporting)\r
if (is_array($allowedValues)) {\r
$unknownValues = array_diff($valuesList, $allowedValues);\r
if ($unknownValues) {\r
- $this->dieUsage("Unrecognised value" . (count($unknownValues) > 1 ? "s '" : " '") . implode("', '", $unknownValues) . "' for parameter '$valueName'", "unknown_$valueName");\r
+ $this->dieUsage('Unrecognised value' . (count($unknownValues) > 1 ? "s '" : " '") . implode("', '", $unknownValues) . "' for parameter '$valueName'", "unknown_$valueName");\r
}\r
}\r
\r
/**\r
* Internal code errors should be reported with this method\r
*/\r
- protected function dieDebug($message) {\r
- wfDebugDieBacktrace("Internal error in '{get_class($this)}': $message");\r
+ protected static function dieDebug($message) {\r
+ wfDebugDieBacktrace("Internal error: $message");\r
}\r
- \r
+\r
/**\r
* Profiling: total module execution time\r
*/\r
- private $mTimeIn = 0, $mModuleTime = 0; \r
- \r
+ private $mTimeIn = 0, $mModuleTime = 0;\r
+\r
/**\r
* Start module profiling\r
*/\r
- public function profileIn()\r
- {\r
+ public function profileIn() {\r
if ($this->mTimeIn !== 0)\r
- $this->dieDebug(__FUNCTION__ . ' called twice without calling profileOut()');\r
+ ApiBase :: dieDebug(__FUNCTION__ . ' called twice without calling profileOut()');\r
$this->mTimeIn = microtime(true);\r
}\r
- \r
+\r
/**\r
* End module profiling\r
*/\r
- public function profileOut()\r
- {\r
+ public function profileOut() {\r
if ($this->mTimeIn === 0)\r
- $this->dieDebug(__FUNCTION__ . ' called without calling profileIn() first');\r
+ ApiBase :: dieDebug(__FUNCTION__ . ' called without calling profileIn() first');\r
if ($this->mDBTimeIn !== 0)\r
- $this->dieDebug(__FUNCTION__ . ' must be called after database profiling is done with profileDBOut()');\r
+ ApiBase :: dieDebug(__FUNCTION__ . ' must be called after database profiling is done with profileDBOut()');\r
\r
$this->mModuleTime += microtime(true) - $this->mTimeIn;\r
$this->mTimeIn = 0;\r
}\r
- \r
+\r
/**\r
* Total time the module was executed\r
*/\r
- public function getProfileTime()\r
- {\r
+ public function getProfileTime() {\r
if ($this->mTimeIn !== 0)\r
- $this->dieDebug(__FUNCTION__ . ' called without calling profileOut() first');\r
+ ApiBase :: dieDebug(__FUNCTION__ . ' called without calling profileOut() first');\r
return $this->mModuleTime;\r
}\r
- \r
+\r
/**\r
* Profiling: database execution time\r
*/\r
- private $mDBTimeIn = 0, $mDBTime = 0; \r
- \r
+ private $mDBTimeIn = 0, $mDBTime = 0;\r
+\r
/**\r
* Start module profiling\r
*/\r
- public function profileDBIn()\r
- {\r
+ public function profileDBIn() {\r
if ($this->mTimeIn === 0)\r
- $this->dieDebug(__FUNCTION__ . ' must be called while profiling the entire module with profileIn()');\r
+ ApiBase :: dieDebug(__FUNCTION__ . ' must be called while profiling the entire module with profileIn()');\r
if ($this->mDBTimeIn !== 0)\r
- $this->dieDebug(__FUNCTION__ . ' called twice without calling profileDBOut()');\r
+ ApiBase :: dieDebug(__FUNCTION__ . ' called twice without calling profileDBOut()');\r
$this->mDBTimeIn = microtime(true);\r
}\r
- \r
+\r
/**\r
* End database profiling\r
*/\r
- public function profileDBOut()\r
- {\r
+ public function profileDBOut() {\r
if ($this->mTimeIn === 0)\r
- $this->dieDebug(__FUNCTION__ . ' must be called while profiling the entire module with profileIn()');\r
+ ApiBase :: dieDebug(__FUNCTION__ . ' must be called while profiling the entire module with profileIn()');\r
if ($this->mDBTimeIn === 0)\r
- $this->dieDebug(__FUNCTION__ . ' called without calling profileDBIn() first');\r
+ ApiBase :: dieDebug(__FUNCTION__ . ' called without calling profileDBIn() first');\r
\r
$time = microtime(true) - $this->mDBTimeIn;\r
$this->mDBTimeIn = 0;\r
$this->mDBTime += $time;\r
$this->getMain()->mDBTime += $time;\r
}\r
- \r
+\r
/**\r
* Total time the module used the database\r
*/\r
- public function getProfileDBTime()\r
- {\r
+ public function getProfileDBTime() {\r
if ($this->mDBTimeIn !== 0)\r
- $this->dieDebug(__FUNCTION__ . ' called without calling profileDBOut() first');\r
+ ApiBase :: dieDebug(__FUNCTION__ . ' called without calling profileDBOut() first');\r
return $this->mDBTime;\r
}\r
}\r
if (!defined('MEDIAWIKI')) {
// Eclipse helper - will be ignored in production
- require_once ("ApiBase.php");
+ require_once ('ApiBase.php');
}
abstract class ApiFormatBase extends ApiBase {
<small>
This result is being shown in <?=$this->mFormat?> format,
which might not be suitable for your application.<br/>
- See <a href="api.php">API help</a> for more information.<br/>
+ See <a href='api.php'>API help</a> for more information.<br/>
</small>
<?php
/**
* Prety-print various elements in HTML format, such as xml tags and URLs.
- * This method also replaces any "<" with <
+ * This method also replaces any '<' with <
*/
protected function formatHTML($text) {
// encode all tags as safe blue strings
if (!defined('MEDIAWIKI')) {
// Eclipse helper - will be ignored in production
- require_once ("ApiFormatBase.php");
+ require_once ('ApiFormatBase.php');
}
class ApiFormatJson extends ApiFormatBase {
if (!defined('MEDIAWIKI')) {
// Eclipse helper - will be ignored in production
- require_once ("ApiFormatBase.php");
+ require_once ('ApiFormatBase.php');
}
class ApiFormatXml extends ApiFormatBase {
$xmlindent = null;
$this->printText('<?xml version="1.0" encoding="utf-8"?>');
- $this->recXmlPrint('api', $this->getResult()->getData(), $xmlindent);
+ $this->recXmlPrint('api', $this->getResultData(), $xmlindent);
}
/**
* This method takes an array and converts it into an xml.
* There are several noteworthy cases:
*
- * If array contains a key "_element", then the code assumes that ALL other keys are not important and replaces them with the value['_element'].
- * Example: name="root", value = array( "_element"=>"page", "x", "y", "z") creates <root> <page>x</page> <page>y</page> <page>z</page> </root>
+ * If array contains a key '_element', then the code assumes that ALL other keys are not important and replaces them with the value['_element'].
+ * Example: name='root', value = array( '_element'=>'page', 'x', 'y', 'z') creates <root> <page>x</page> <page>y</page> <page>z</page> </root>
*
- * If any of the array's element key is "*", then the code treats all other key->value pairs as attributes, and the value['*'] as the element's content.
- * Example: name="root", value = array( "*"=>"text", "lang"=>"en", "id"=>10) creates <root lang="en" id="10">text</root>
+ * If any of the array's element key is '*', then the code treats all other key->value pairs as attributes, and the value['*'] as the element's content.
+ * Example: name='root', value = array( '*'=>'text', 'lang'=>'en', 'id'=>10) creates <root lang='en' id='10'>text</root>
*
* If neither key is found, all keys become element names, and values become element content.
* The method is recursive, so the same rules apply to any sub-arrays.
*/
function recXmlPrint($elemName, $elemValue, $indent) {
- $indstr = "";
if (!is_null($indent)) {
$indent += 2;
$indstr = "\n" . str_repeat(" ", $indent);
+ } else {
+ $indstr = '';
}
switch (gettype($elemValue)) {
case 'array' :
- if (array_key_exists('*', $elemValue)) {
+
+ if (isset ($elemValue['*'])) {
$subElemContent = $elemValue['*'];
unset ($elemValue['*']);
- if (gettype($subElemContent) === 'array') {
- $this->printText($indstr . wfElement($elemName, $elemValue, null));
- $this->recXmlPrint($elemName, $subElemContent, $indent);
- $this->printText($indstr . "</$elemName>");
- } else {
- $this->printText($indstr . wfElement($elemName, $elemValue, $subElemContent));
- }
} else {
- $this->printText($indstr . wfElement($elemName, null, null));
- if (array_key_exists('_element', $elemValue)) {
- $subElemName = $elemValue['_element'];
- foreach ($elemValue as $subElemId => & $subElemValue) {
- if ($subElemId !== '_element') {
- $this->recXmlPrint($subElemName, $subElemValue, $indent);
- }
+ $subElemContent = null;
+ }
+
+ if (isset ($elemValue['_element'])) {
+ $subElemIndName = $elemValue['_element'];
+ unset ($elemValue['_element']);
+ } else {
+ $subElemIndName = null;
+ }
+
+ $indElements = array ();
+ $subElements = array ();
+ foreach ($elemValue as $subElemId => & $subElemValue) {
+ if (gettype($subElemId) === 'integer') {
+ if (!is_array($subElemValue))
+ ApiBase :: dieDebug(__FUNCTION__ . "($elemName, ...) has a scalar indexed value.");
+ $indElements[] = $subElemValue;
+ unset ($elemValue[$subElemId]);
+ } else
+ if (is_array($subElemValue)) {
+ $subElements[$subElemId] = $subElemValue;
+ unset ($elemValue[$subElemId]);
}
+ }
+
+ if (is_null($subElemIndName) && !empty ($indElements))
+ ApiBase :: dieDebug(__FUNCTION__ . "($elemName, ...) has integer keys without _element value");
+
+ if (!empty ($subElements) && !empty ($indElements) && !is_null($subElemContent))
+ ApiBase :: dieDebug(__FUNCTION__ . "($elemName, ...) has content and subelements");
+
+ if (!is_null($subElemContent)) {
+ $this->printText($indstr . wfElement($elemName, $elemValue, $subElemContent));
+ } else
+ if (empty ($indElements) && empty ($subElements)) {
+ $this->printText($indstr . wfElement($elemName, $elemValue));
} else {
- foreach ($elemValue as $subElemName => & $subElemValue) {
- $this->recXmlPrint($subElemName, $subElemValue, $indent);
- }
+ $this->printText($indstr . wfElement($elemName, $elemValue, null));
+
+ foreach ($subElements as $subElemId => & $subElemValue)
+ $this->recXmlPrint($subElemId, $subElemValue, $indent);
+
+ foreach ($indElements as $subElemId => & $subElemValue)
+ $this->recXmlPrint($subElemIndName, $subElemValue, $indent);
+
+ $this->printText($indstr . wfCloseElement($elemName));
}
- $this->printText($indstr . "</$elemName>");
- }
break;
case 'object' :
// ignore
if (!defined('MEDIAWIKI')) {
// Eclipse helper - will be ignored in production
- require_once ("ApiFormatBase.php");
+ require_once ('ApiFormatBase.php');
}
class ApiFormatYaml extends ApiFormatBase {
\r
if (!defined('MEDIAWIKI')) {\r
// Eclipse helper - will be ignored in production\r
- require_once ("ApiBase.php");\r
+ require_once ('ApiBase.php');\r
}\r
\r
class ApiHelp extends ApiBase {\r
if (!defined('MEDIAWIKI')) {
// Eclipse helper - will be ignored in production
- require_once ("ApiBase.php");
+ require_once ('ApiBase.php');
}
class ApiLogin extends ApiBase {
$result['result'] = 'AuthEmptyPass';
break;
default :
- $this->dieDebug("Unhandled case value");
+ $this->dieDebug('Unhandled case value');
}
- $this->getResult()->addMessage('login', null, $result);
+ $this->getResult()->addValue(null, 'login', $result);
}
protected function getAllowedParams() {
);
}
}
-?>
\ No newline at end of file
+?>
\r
if (!defined('MEDIAWIKI')) {\r
// Eclipse helper - will be ignored in production\r
- require_once ("ApiBase.php");\r
+ require_once ('ApiBase.php');\r
}\r
\r
class ApiMain extends ApiBase {\r
$this->mResult = new ApiResult($this);\r
}\r
\r
- public function getResult() {\r
+ public function & getResult() {\r
return $this->mResult;\r
}\r
\r
\r
public function mainDieUsage($description, $errorCode, $httpRespCode = 0) {\r
$this->mResult->Reset();\r
- $this->mResult->addMessage('error', null, $errorCode);\r
if ($httpRespCode === 0)\r
header($errorCode, true);\r
else\r
header($errorCode, true, $httpRespCode);\r
\r
- $this->mResult->addMessage('usage', null, $this->makeHelpMsg());\r
+ $data = array (\r
+ 'code' => $errorCode\r
+ );\r
+ ApiResult :: addContent($data, $this->makeHelpMsg());\r
+ $this->mResult->addValue(null, 'error', $data);\r
\r
throw new UsageException($description, $errorCode);\r
}\r
return "{$this->codestr}: {$this->message}";\r
}\r
}\r
-\r
?>
\ No newline at end of file
if (!defined('MEDIAWIKI')) {
// Eclipse helper - will be ignored in production
- require_once ("ApiQueryBase.php");
+ require_once ('ApiQueryBase.php');
}
class ApiPageSet extends ApiQueryBase {
public function getGoodTitleCount() {
return count($this->getGoodTitles());
}
-
+
/**
* Get the list of revision IDs (requested with revids= parameter)
*/
public function getRevisionIDs() {
- $this->dieUsage(__FUNCTION__ . " is not implemented", 'notimplemented');
+ $this->dieUsage(__FUNCTION__ . ' is not implemented', 'notimplemented');
}
-
+
/**
* Returns the number of revisions (requested with revids= parameter)
*/
* #6 Repeat from step #1
*/
private function populateTitles($titles, $redirects) {
-
+
$pageFlds = array (
'page_id',
'page_namespace',
}
private function populatePageIDs($pageids) {
- $this->dieUsage(__FUNCTION__ . " is not implemented", 'notimplemented');
+ $this->dieUsage(__FUNCTION__ . ' is not implemented', 'notimplemented');
}
public function execute() {
$titles = $pageids = $revids = $redirects = null;
extract($this->extractRequestParams());
-
+
// Only one of the titles/pageids/revids is allowed at the same time
$dataSource = null;
if (isset ($titles))
'redirects' => false
);
}
-
+
protected function getParamDescription() {
return array (
'titles' => 'A list of titles to work on',
\r
if (!defined('MEDIAWIKI')) {\r
// Eclipse helper - will be ignored in production\r
- require_once ("ApiBase.php");\r
+ require_once ('ApiBase.php');\r
}\r
\r
class ApiQuery extends ApiBase {\r
$modules[] = new $this->mQueryListModules[$moduleName] ($this, $moduleName);\r
\r
// Title normalizations\r
+ $normValues = array ();\r
foreach ($this->mData->getNormalizedTitles() as $rawTitleStr => $titleStr) {\r
- $this->getResult()->addMessage('query', 'normalized', array (\r
+ $normValues[] = array (\r
'from' => $rawTitleStr,\r
- 'to' => $titleStr,\r
- '*' => ''\r
- ), 'n');\r
+ 'to' => $titleStr\r
+ );\r
+ }\r
+\r
+ if (!empty ($normValues)) {\r
+ ApiResult :: setIndexedTagName($normValues, 'n');\r
+ $this->getResult()->addValue('query', 'normalized', $normValues);\r
}\r
\r
// Show redirect information\r
+ $redirValues = array ();\r
foreach ($this->mData->getRedirectTitles() as $titleStrFrom => $titleStrTo) {\r
- $this->getResult()->addMessage('query', 'redirects', array (\r
+ $redirValues[] = array (\r
'from' => $titleStrFrom,\r
- 'to' => $titleStrTo,\r
- '*' => ''\r
- ), 'r');\r
+ 'to' => $titleStrTo\r
+ );\r
+ }\r
+\r
+ if (!empty ($redirValues)) {\r
+ ApiResult :: setIndexedTagName($redirValues, 'r');\r
+ $this->getResult()->addValue('query', 'redirects', $redirValues);\r
}\r
\r
// Execute all requested modules.\r
$module->execute();\r
$module->profileOut();\r
}\r
+\r
+ // Ensure that pages are shown as '<page>' elements\r
+ $data = & $this->getResultData();\r
+ if (isset ($data['query']['pages'])) {\r
+ ApiResult :: setIndexedTagName($data['query']['pages'], 'page');\r
+ }\r
}\r
\r
protected function executeGenerator($generator) {\r
if (isset ($this->mQueryPropModules[$generator]))\r
$className = $this->mQueryPropModules[$generator];\r
else\r
- $this->dieDebug("Unknown generator=$generator");\r
+ ApiBase :: dieDebug("Unknown generator=$generator");\r
\r
$module = new $className ($this, $generator, true);\r
\r
// change $this->mData\r
\r
// TODO: implement\r
- $this->dieUsage("Generator execution has not been implemented", 'notimplemented');\r
+ $this->dieUsage('Generator execution has not been implemented', 'notimplemented');\r
}\r
\r
protected function getAllowedParams() {\r
// 'generator' => array (\r
// GN_ENUM_TYPE => $this->mAllowedGenerators\r
// ),\r
+\r
+ \r
);\r
}\r
\r
\r
/**\r
* Override to add extra parameters from PageSet\r
- */ \r
+ */\r
public function makeHelpMsgParameters() {\r
$module = new ApiPageSet($this);\r
return $module->makeHelpMsgParameters() . parent :: makeHelpMsgParameters();\r
}\r
- \r
\r
protected function getParamDescription() {\r
return array (\r
'prop' => 'Which properties to get for the titles/revisions/pageids',\r
'list' => 'Which lists to get',\r
'generator' => 'Use the output of a list as the input for other prop/list/meta items',\r
+\r
+ \r
);\r
}\r
\r
);\r
}\r
}\r
-?>
\ No newline at end of file
+?>\r
if (!defined('MEDIAWIKI')) {
// Eclipse helper - will be ignored in production
- require_once ("ApiQueryBase.php");
+ require_once ('ApiQueryBase.php');
}
class ApiQueryAllpages extends ApiQueryBase {
'ORDER BY' => 'page_namespace, page_title'
));
$this->profileDBOut();
-
+
$data = array ();
- $data['_element'] = 'p';
+ ApiResult :: setIndexedTagName($data, 'p');
$count = 0;
while ($row = $db->fetchObject($res)) {
if (++ $count > $aplimit) {
$msg = array (
'continue' => 'apfrom=' . ApiQueryBase :: keyToTitle($row->page_title
));
- $this->getResult()->addMessage('query-status', 'allpages', $msg);
+ $this->getResult()->addValue('query-status', 'allpages', $msg);
break;
}
if ($title->getNamespace() !== 0)
$pagedata['ns'] = $title->getNamespace();
$pagedata['title'] = $title->getPrefixedText();
- $pagedata['*'] = '';
$data[$id] = $pagedata;
}
}
$db->freeResult($res);
- $this->getResult()->addMessage('query', 'allpages', $data);
+ $this->getResult()->addValue('query', 'allpages', $data);
}
protected function getAllowedParams() {
\r
if (!defined('MEDIAWIKI')) {\r
// Eclipse helper - will be ignored in production\r
- require_once ("ApiBase.php");\r
+ require_once ('ApiBase.php');\r
}\r
\r
abstract class ApiQueryBase extends ApiBase {\r
if (!defined('MEDIAWIKI')) {
// Eclipse helper - will be ignored in production
- require_once ("ApiQueryBase.php");
+ require_once ('ApiQueryBase.php');
}
class ApiQueryInfo extends ApiQueryBase {
if (!defined('MEDIAWIKI')) {
// Eclipse helper - will be ignored in production
- require_once ("ApiQueryBase.php");
+ require_once ('ApiQueryBase.php');
}
class ApiQueryRevisions extends ApiQueryBase {
// true when ordered by timestamp from older to newer, false otherwise
$dirNewer = ($rvdir === 'newer');
- // If any of those parameters are used, work in "enumeration" mode.
+ // If any of those parameters are used, work in 'enumeration' mode.
// Enum mode can only be used when exactly one page is provided.
// Enumerating revisions on multiple pages make it extremelly
// difficult to manage continuations and require additional sql indexes
$pageCount = $data->getGoodTitleCount();
$revCount = $data->getRevisionCount();
+ // Optimization -- nothing to do
+ if ($revCount === 0 && $pageCount === 0)
+ return;
+
if ($revCount > 0 && $pageCount > 0)
- $this->dieUsage('The rvrevids= parameter may not be used with titles, pageids, and generator options.', 'rv_rvrevids');
+ $this->dieUsage('The revids= parameter may not be used with titles, pageids, or generator options.', 'rv_revids');
if ($revCount > 0 && $enumRevMode)
- $this->dieUsage('The rvrevids= parameter may not be used with the list options (rvlimit, rvstartid, rvendid, dirNewer, rvstart, rvend).', 'rv_rvrevids');
-
- if ($revCount === 0 && $pageCount === 0)
- $this->dieUsage('No pages were given. Please use titles, pageids or a generator to provide page(s) to work on.', 'rv_no_pages');
+ $this->dieUsage('The revids= parameter may not be used with the list options (rvlimit, rvstartid, rvendid, dirNewer, rvstart, rvend).', 'rv_revids');
if ($revCount === 0 && $pageCount > 1 && $enumRevMode)
$this->dieUsage('titles, pageids or a generator was used to supply multiple pages, but the rvlimit, rvstartid, rvendid, dirNewer, rvstart, and rvend parameters may only be used on a single page.', 'rv_multpages');
$showContent = true;
break;
default :
- $this->dieDebug("unknown rvprop $prop");
+ ApiBase :: dieDebug("unknown rvprop $prop");
}
}
}
$rvlimit = $revCount; // assumption testing -- we should never get more then $revCount rows.
} else
- $this->dieDebug('param validation?');
+ ApiBase :: dieDebug('param validation?');
$options['LIMIT'] = $rvlimit +1;
if (++ $count > $rvlimit) {
// We've reached the one extra which shows that there are additional pages to be had. Stop here...
if (!$enumRevMode)
- $this->dieDebug('Got more rows then expected'); // bug report
+ ApiBase :: dieDebug('Got more rows then expected'); // bug report
$startStr = 'rvstartid=' . $row->rev_id;
$msg = array (
'continue' => $startStr
);
- $this->getResult()->addMessage('query-status', 'revisions', $msg);
+ $this->getResult()->addValue('query-status', 'revisions', $msg);
break;
}
$vals['comment'] = $row->rev_comment;
if ($showContent) {
- $vals['xml:space'] = 'preserve';
- $vals['*'] = Revision :: getRevisionText($row);
- } else {
- $vals['*'] = ''; // Force all elements to be attributes
+ ApiResult :: addContent($vals, Revision :: getRevisionText($row));
}
- $data[$row->rev_page]['revisions']['_element'] = 'rv';
- $data[$row->rev_page]['revisions'][$row->rev_id] = $vals;
+ $this->getResult()->addValue(array (
+ 'query',
+ 'pages',
+ intval($row->rev_page
+ ), 'revisions'), intval($row->rev_id), $vals);
}
$db->freeResult($res);
- $this->getResult()->addMessage('query', 'allpages', $data);
+ // Ensure that all revisions are shown as '<r>' elements
+ $data = & $this->getResultData();
+ foreach ($data['query']['pages'] as & $page) {
+ if (isset ($page['revisions'])) {
+ ApiResult :: setIndexedTagName($page['revisions'], 'rev');
+ }
+ }
}
protected function getAllowedParams() {
return array (
- 'rvrevids' => array (
- GN_ENUM_ISMULTI => true,
- GN_ENUM_TYPE => 'integer'
- ),
'rvlimit' => array (
GN_ENUM_DFLT => 0,
GN_ENUM_TYPE => 'limit',
'Get revision information.',
'This module may be used in several ways:',
' 1) Get data about a set of pages (last revision), by setting titles or pageids parameter.',
- ' 2) Get revisions for one given page, by using titles/pageids with rvstart*/rvend*/rvlimit params.',
+ ' 2) Get revisions for one given page, by using titles/pageids with rvstart/rvend/rvlimit params.',
' 3) Get data about a set of revisions by setting their IDs with revids parameter.'
);
}
protected function getExamples() {
return array (
- 'api.php?action=query&prop=revisions&titles=ArticleA&rvprop=timestamp|user|comment|content'
+ 'api.php?action=query&prop=revisions&titles=Main%20Page&rvprop=timestamp|user|comment|content'
);
}
}
if (!defined('MEDIAWIKI')) {
// Eclipse helper - will be ignored in production
- require_once ("ApiQueryBase.php");
+ require_once ('ApiQueryBase.php');
}
class ApiQuerySiteinfo extends ApiQueryBase {
$data['base'] = $mainPage->getFullUrl();
$data['sitename'] = $wgSitename;
$data['generator'] = "MediaWiki $wgVersion";
- $data['case'] = $wgCapitalLinks ? 'first-letter' : 'case-sensitive'; // "case-insensitive" option is reserved for future
- $this->getResult()->addMessage('query', $prop, $data);
+ $data['case'] = $wgCapitalLinks ? 'first-letter' : 'case-sensitive'; // 'case-insensitive' option is reserved for future
+ $this->getResult()->addValue('query', $prop, $data);
break;
case 'namespaces' :
global $wgContLang;
$data = array ();
- $data['_element'] = 'ns';
- foreach ($wgContLang->getFormattedNamespaces() as $ns => $title)
+ foreach ($wgContLang->getFormattedNamespaces() as $ns => $title) {
$data[$ns] = array (
- 'id' => $ns,
- '*' => $title
+ 'id' => $ns
);
- $this->getResult()->addMessage('query', $prop, $data);
+ ApiResult :: addContent($data[$ns], $title);
+ }
+ ApiResult :: setIndexedTagName($data, 'ns');
+ $this->getResult()->addValue('query', $prop, $data);
break;
default :
- $this->dieDebug("Unknown siprop=$prop");
+ ApiBase :: dieDebug("Unknown siprop=$prop");
}
}
}
\r
if (!defined('MEDIAWIKI')) {\r
// Eclipse helper - will be ignored in production\r
- require_once ("ApiBase.php");\r
+ require_once ('ApiBase.php');\r
}\r
\r
class ApiResult extends ApiBase {\r
$this->mData = array ();\r
}\r
\r
- function getData() {\r
+ function & getData() {\r
return $this->mData;\r
}\r
\r
- function addMessage($mainSection, $subSection, $value, $multiitem = false, $preserveXmlSpacing = false) {\r
- if (!array_key_exists($mainSection, $this->mData)) {\r
- $this->mData[$mainSection] = array ();\r
- }\r
- if ($subSection !== null) {\r
- if (!array_key_exists($subSection, $this->mData[$mainSection])) {\r
- $this->mData[$mainSection][$subSection] = array ();\r
- }\r
- $element = & $this->mData[$mainSection][$subSection];\r
- } else {\r
- $element = & $this->mData[$mainSection];\r
- }\r
- if ($multiitem) {\r
- $element['_element'] = $multiitem;\r
- $element[] = $value;\r
- } else {\r
- if (is_array($value)) {\r
- $element = array_merge($element, $value);\r
- } else {\r
- if (array_key_exists('*', $element)) {\r
- $element['*'] .= $value;\r
- } else {\r
- $element['*'] = $value;\r
- }\r
- if ($preserveXmlSpacing) {\r
- $element['xml:space'] = 'preserve';\r
+ /**\r
+ * Add an output value to the array by name.\r
+ * Verifies that value with the same name has not been added before.\r
+ */\r
+ public static function addElement(& $arr, $name, $value) {\r
+ if ($arr === null || $name === null || $value === null || !is_array($arr) || is_array($name))\r
+ ApiBase :: dieDebug('Bad parameter for ' . __FUNCTION__);\r
+ if (isset ($arr[$name]))\r
+ ApiBase :: dieDebug("Attempting to add element $name=$value, existing value is {$arr[$name]}");\r
+ $arr[$name] = $value;\r
+ }\r
+\r
+ /**\r
+ * Adds the content element to the array.\r
+ * Use this function instead of hardcoding the '*' element.\r
+ */\r
+ public static function addContent(& $arr, $value) {\r
+ if (is_array($value))\r
+ ApiBase :: dieDebug('Bad parameter for ' . __FUNCTION__);\r
+ ApiResult :: addElement($arr, '*', $value);\r
+ }\r
+\r
+ // public static function makeContentElement($tag, $value) {\r
+ // $result = array();\r
+ // ApiResult::addContent($result, )\r
+ // }\r
+ //\r
+ /**\r
+ * In case the array contains indexed values (in addition to named),\r
+ * all indexed values will have the given tag name.\r
+ */\r
+ public static function setIndexedTagName(& $arr, $tag) {\r
+ // Do not use addElement() as it is ok to call this more than once\r
+ if ($arr === null || $tag === null || !is_array($arr) || is_array($tag))\r
+ ApiBase :: dieDebug('Bad parameter for ' . __FUNCTION__);\r
+ $arr['_element'] = $tag;\r
+ }\r
+\r
+ /**\r
+ * Add value to the output data at the given path.\r
+ * Path is an indexed array, each element specifing the branch at which to add the new value\r
+ * Setting $path to array('a','b','c') is equivalent to data['a']['b']['c'] = $value \r
+ */\r
+ public function addValue($path, $name, $value) {\r
+\r
+ $data = & $this->getData();\r
+\r
+ if (isset ($path)) {\r
+ if (is_array($path)) {\r
+ foreach ($path as $p) {\r
+ if (!isset ($data[$p]))\r
+ $data[$p] = array ();\r
+ $data = & $data[$p];\r
}\r
+ } else {\r
+ if (!isset ($data[$path]))\r
+ $data[$path] = array ();\r
+ $data = & $data[$path];\r
}\r
}\r
+\r
+ ApiResult :: addElement($data, $name, $value);\r
}\r
\r
/**\r
}\r
\r
public function execute() {\r
- $this->dieDebug("execute() is not supported on Result object");\r
+ $this->dieDebug('execute() is not supported on Result object');\r
}\r
}\r
?>\r