*/
/**
- * This abstract class implements many basic API functions, and is the base of all API classes.
+ * This abstract class implements many basic API functions, and is the base of
+ * all API classes.
* The class functions are divided into several areas of functionality:
*
- * Module parameters: Derived classes can define getAllowedParams() to specify which parameters to expect,
- * how to parse and validate them.
+ * Module parameters: Derived classes can define getAllowedParams() to specify
+ * which parameters to expect,h ow to parse and validate them.
*
- * Profiling: various methods to allow keeping tabs on various tasks and their time costs
+ * Profiling: various methods to allow keeping tabs on various tasks and their
+ * time costs
*
- * Self-documentation: code to allow api to document its own state.
+ * Self-documentation: code to allow the API to document its own state
*
* @ingroup API
*/
private $mMainModule, $mModuleName, $mModulePrefix;
/**
- * Constructor
- */
+ * Constructor
+ * @param $mainModule ApiMain object
+ * @param $moduleName string Name of this module
+ * @param $modulePrefix string Prefix to use for parameter names
+ */
public function __construct($mainModule, $moduleName, $modulePrefix = '') {
$this->mMainModule = $mainModule;
$this->mModuleName = $moduleName;
*****************************************************************************/
/**
- * Evaluates the parameters, performs the requested query, and sets up the
- * result. Concrete implementations of ApiBase must override this method to
- * provide whatever functionality their module offers. Implementations must
- * not produce any output on their own and are not expected to handle any
- * errors.
+ * Evaluates the parameters, performs the requested query, and sets up
+ * the result. Concrete implementations of ApiBase must override this
+ * method to provide whatever functionality their module offers.
+ * Implementations must not produce any output on their own and are not
+ * expected to handle any errors.
*
- * The execute method will be invoked directly by ApiMain immediately before
- * the result of the module is output. Aside from the constructor, implementations
- * should assume that no other methods will be called externally on the module
- * before the result is processed.
+ * The execute() method will be invoked directly by ApiMain immediately
+ * before the result of the module is output. Aside from the
+ * constructor, implementations should assume that no other methods
+ * will be called externally on the module before the result is
+ * processed.
*
- * The result data should be stored in the result object referred to by
- * "getResult()". Refer to ApiResult.php for details on populating a result
- * object.
+ * The result data should be stored in the ApiResult object available
+ * through getResult().
*/
public abstract function execute();
/**
- * Returns a String that identifies the version of the extending class. Typically
- * includes the class name, the svn revision, timestamp, and last author. May
- * be severely incorrect in many implementations!
+ * Returns a string that identifies the version of the extending class.
+ * Typically includes the class name, the svn revision, timestamp, and
+ * last author. Usually done with SVN's Id keyword
+ * @return string
*/
public abstract function getVersion();
/**
* Get the name of the module being executed by this instance
+ * @return string
*/
public function getModuleName() {
return $this->mModuleName;
/**
* Get parameter prefix (usually two letters or an empty string).
+ * @return string
*/
public function getModulePrefix() {
return $this->mModulePrefix;
/**
* Get the name of the module as shown in the profiler log
+ * @return string
*/
public function getModuleProfileName($db = false) {
if ($db)
}
/**
- * Get main module
+ * Get the main module
+ * @return ApiMain object
*/
public function getMain() {
return $this->mMainModule;
/**
* Returns true if this module is the main module ($this === $this->mMainModule),
* false otherwise.
+ * @return bool
*/
public function isMain() {
return $this === $this->mMainModule;
}
/**
- * Get the result object. Please refer to the documentation in ApiResult.php
- * for details on populating and accessing data in a result object.
+ * Get the result object
+ * @return ApiResult
*/
public function getResult() {
// Main module has getResult() method overriden
}
/**
- * Get the result data array
+ * Get the result data array (read-only)
+ * @return array
*/
public function getResultData() {
return $this->getResult()->getData();
}
/**
- * Set warning section for this module. Users should monitor this section to
- * notice any changes in API.
+ * Set warning section for this module. Users should monitor this
+ * section to notice any changes in API. Multiple calls to this
+ * function will result in the warning messages being separated by
+ * newlines
+ * @param $warning string Warning message
*/
public function setWarning($warning) {
$data = $this->getResult()->getData();
* If the module may only be used with a certain format module,
* it should override this method to return an instance of that formatter.
* A value of null means the default format will be used.
+ * @return mixed instance of a derived class of ApiFormatBase, or null
*/
public function getCustomPrinter() {
return null;
/**
* Generates help message for this module, or false if there is no description
+ * @return mixed string or false
*/
public function makeHelpMsg() {
/**
* Generates the parameter descriptions for this module, to be displayed in the
* module's help.
+ * @return string
*/
public function makeHelpMsgParameters() {
$params = $this->getFinalParams();
/**
* Returns the description string for this module
+ * @return mixed string or array of strings
*/
protected function getDescription() {
return false;
/**
* Returns usage examples for this module. Return null if no examples are available.
+ * @return mixed string or array of strings
*/
protected function getExamples() {
return false;
}
/**
- * Returns an array of allowed parameters (keys) => default value for that parameter.
- * Don't call this function directly: use getFinalParams() to allow hooks
- * to modify parameters as needed.
+ * Returns an array of allowed parameters (parameter name) => (default
+ * value) or (parameter name) => (array with PARAM_* constants as keys)
+ * Don't call this function directly: use getFinalParams() to allow
+ * hooks to modify parameters as needed.
+ * @return array
*/
protected function getAllowedParams() {
return false;
/**
* Returns an array of parameter descriptions.
- * Don't call this functon directly: use getFinalParamDescription() to allow
- * hooks to modify descriptions as needed.
+ * Don't call this functon directly: use getFinalParamDescription() to
+ * allow hooks to modify descriptions as needed.
+ * @return array
*/
protected function getParamDescription() {
return false;
}
/**
- * Get final list of parameters, after hooks have had
- * a chance to tweak it as needed.
+ * Get final list of parameters, after hooks have had a chance to
+ * tweak it as needed.
+ * @return array
*/
public function getFinalParams() {
$params = $this->getAllowedParams();
wfRunHooks('APIGetAllowedParams', array(&$this, &$params));
return $params;
}
-
-
+
+ /**
+ * Get final description, after hooks have had a chance to tweak it as
+ * needed.
+ * @return array
+ */
public function getFinalParamDescription() {
$desc = $this->getParamDescription();
wfRunHooks('APIGetParamDescription', array(&$this, &$desc));
/**
* This method mangles parameter name based on the prefix supplied to the constructor.
* Override this method to change parameter name during runtime
+ * @param $paramName string Parameter name
+ * @return string Prefixed parameter name
*/
public function encodeParamName($paramName) {
return $this->mModulePrefix . $paramName;
}
/**
- * Using getAllowedParams(), makes an array of the values provided by the user,
- * with key being the name of the variable, and value - validated value from user or default.
- * limit=max will not be parsed if $parseMaxLimit is set to false; use this
- * when the max limit is not definite, e.g. when getting revisions.
+ * Using getAllowedParams(), this function makes an array of the values
+ * provided by the user, with key being the name of the variable, and
+ * value - validated value from user or default. limit=max will not be
+ * parsed if $parseMaxLimit is set to false; use this when the max
+ * limit is not definitive yet, e.g. when getting revisions.
+ * @param $parseMaxLimit bool
+ * @return array
*/
public function extractRequestParams($parseMaxLimit = true) {
$params = $this->getFinalParams();
/**
* Get a value for the given parameter
+ * @param $paramName string Parameter name
+ * @param $parseMaxLimit bool see extractRequestParams()
+ * @return mixed Parameter value
*/
protected function getParameter($paramName, $parseMaxLimit = true) {
$params = $this->getFinalParams();
/**
* Die if none or more than one of a certain set of parameters is set
+ * @param $params array of parameter names
*/
public function requireOnlyOneParameter($params) {
$required = func_get_args();
/**
* Returns an array of the namespaces (by integer id) that exist on the
* wiki. Used primarily in help documentation.
+ * @return array
*/
public static function getValidNamespaces() {
static $mValidNamespaces = null;
* Using the settings determine the value for the given parameter
*
* @param $paramName String: parameter name
- * @param $paramSettings Mixed: default value or an array of settings using PARAM_* constants.
+ * @param $paramSettings Mixed: default value or an array of settings
+ * using PARAM_* constants.
* @param $parseMaxLimit Boolean: parse limit when max is given?
+ * @return mixed Parameter value
*/
protected function getParameterFromSettings($paramName, $paramSettings, $parseMaxLimit) {
* Return an array of values that were given in a 'a|b|c' notation,
* after it optionally validates them against the list allowed values.
*
- * @param valueName - The name of the parameter (for error reporting)
- * @param value - The value being parsed
- * @param allowMultiple - Can $value contain more than one value separated by '|'?
- * @param allowedValues - An array of values to check against. If null, all values are accepted.
- * @return (allowMultiple ? an_array_of_values : a_single_value)
+ * @param $valueName string The name of the parameter (for error
+ * reporting)
+ * @param $value mixed The value being parsed
+ * @param $allowMultiple bool Can $value contain more than one value
+ * separated by '|'?
+ * @param $allowedValues mixed An array of values to check against. If
+ * null, all values are accepted.
+ * @return mixed (allowMultiple ? an_array_of_values : a_single_value)
*/
protected function parseMultiValue($valueName, $value, $allowMultiple, $allowedValues) {
if( trim($value) === "" )
}
/**
- * Validate the value against the minimum and user/bot maximum limits. Prints usage info on failure.
- */
+ * Validate the value against the minimum and user/bot maximum limits.
+ * Prints usage info on failure.
+ * @param $paramName string Parameter name
+ * @param $value int Parameter value
+ * @param $min int Minimum value
+ * @param $max int Maximum value for users
+ * @param $botMax int Maximum value for sysops/bots
+ */
function validateLimit($paramName, $value, $min, $max, $botMax = null) {
if (!is_null($min) && $value < $min) {
$this->dieUsage($this->encodeParamName($paramName) . " may not be less than $min (set to $value)", $paramName);
}
/**
- * Call main module's error handler
+ * Call the main module's error handler
+ * @param $description string Error text
+ * @param $errorCode string Error code
+ * @param $httpRespCode int HTTP response code
*/
public function dieUsage($description, $errorCode, $httpRespCode = 0) {
wfProfileClose();
/**
* Output the error message related to a certain array
- * @param array $error Element of a getUserPermissionsErrors()-style array
+ * @param $error array Element of a getUserPermissionsErrors()-style array
*/
public function dieUsageMsg($error) {
$parsed = $this->parseMsg($error);
/**
* Return the error message related to a certain array
- * @param array $error Element of a getUserPermissionsErrors()-style array
+ * @param $error array Element of a getUserPermissionsErrors()-style array
* @return array('code' => code, 'info' => info)
*/
public function parseMsg($error) {
/**
* Internal code errors should be reported with this method
+ * @param $method string Method or function name
+ * @param $message string Error message
*/
protected static function dieDebug($method, $message) {
wfDebugDieBacktrace("Internal error in $method: $message");
}
/**
- * Indicates if API needs to check maxlag
+ * Indicates if this module needs maxlag to be checked
+ * @return bool
*/
public function shouldCheckMaxlag() {
return true;
/**
* Indicates if this module requires edit mode
+ * @return bool
*/
public function isEditMode() {
return false;
/**
* Indicates whether this module must be called with a POST request
+ * @return bool
*/
public function mustBePosted() {
return false;
/**
* Total time the module was executed
+ * @return float
*/
public function getProfileTime() {
if ($this->mTimeIn !== 0)
/**
* Total time the module used the database
+ * @return float
*/
public function getProfileDBTime() {
if ($this->mDBTimeIn !== 0)
return $this->mDBTime;
}
+ /**
+ * Debugging function that prints a value and an optional backtrace
+ * @param $value mixed Value to print
+ * @param $name string Description of the printed value
+ * @param $backtrace bool If true, print a backtrace
+ */
public static function debugPrint($value, $name = 'unknown', $backtrace = false) {
- print "\n\n<pre><b>Debuging value '$name':</b>\n\n";
+ print "\n\n<pre><b>Debugging value '$name':</b>\n\n";
var_export($value);
if ($backtrace)
print "\n" . wfBacktrace();
/**
- * Returns a String that identifies the version of this class.
+ * Returns a string that identifies the version of this class.
+ * @return string
*/
public static function getBaseVersion() {
return __CLASS__ . ': $Id$';
/**
* This class contains a list of pages that the client has requested.
- * Initially, when the client passes in titles=, pageids=, or revisions= parameter,
- * an instance of the ApiPageSet class will normalize titles,
- * determine if the pages/revisions exist, and prefetch any additional data page data requested.
+ * Initially, when the client passes in titles=, pageids=, or revisions=
+ * parameter, an instance of the ApiPageSet class will normalize titles,
+ * determine if the pages/revisions exist, and prefetch any additional page
+ * data requested.
*
- * When generator is used, the result of the generator will become the input for the
- * second instance of this class, and all subsequent actions will go use the second instance
- * for all their work.
+ * When a generator is used, the result of the generator will become the input
+ * for the second instance of this class, and all subsequent actions will use
+ * the second instance for all their work.
*
* @ingroup API
*/
private $mRequestedPageFields;
+ /**
+ * Constructor
+ * @param $query ApiQuery
+ * @param $resolveRedirects bool Whether redirects should be resolved
+ */
public function __construct($query, $resolveRedirects = false) {
parent :: __construct($query, 'query');
$this->mFakePageId = -1;
}
+ /**
+ * Check whether this PageSet is resolving redirects
+ * @return bool
+ */
public function isResolvingRedirects() {
return $this->mResolveRedirects;
}
+ /**
+ * Request an additional field from the page table. Must be called
+ * before execute()
+ * @param $fieldName string Field name
+ */
public function requestField($fieldName) {
$this->mRequestedPageFields[$fieldName] = null;
}
+ /**
+ * Get the value of a custom field previously requested through
+ * requestField()
+ * @param $fieldName string Field name
+ * @return mixed Field value
+ */
public function getCustomField($fieldName) {
return $this->mRequestedPageFields[$fieldName];
}
/**
- * Get fields that modules have requested from the page table
+ * Get the fields that have to be queried from the page table:
+ * the ones requested through requestField() and a few basic ones
+ * we always need
+ * @return array of field names
*/
public function getPageTableFields() {
// Ensure we get minimum required fields
'page_id' => null,
);
- // only store non-default fields
- $this->mRequestedPageFields = array_diff_key($this->mRequestedPageFields, $pageFlds);
-
if ($this->mResolveRedirects)
$pageFlds['page_is_redirect'] = null;
+ // only store non-default fields
+ $this->mRequestedPageFields = array_diff_key($this->mRequestedPageFields, $pageFlds);
+
$pageFlds = array_merge($pageFlds, $this->mRequestedPageFields);
return array_keys($pageFlds);
}
* Returns an array [ns][dbkey] => page_id for all requested titles.
* page_id is a unique negative number in case title was not found.
* Invalid titles will also have negative page IDs and will be in namespace 0
+ * @return array
*/
public function getAllTitlesByNamespace() {
return $this->mAllPages;
/**
* Returns the number of unique pages (not revisions) in the set.
+ * @return int
*/
public function getTitleCount() {
return count($this->mTitles);
/**
* Returns the number of found unique pages (not revisions) in the set.
+ * @return int
*/
public function getGoodTitleCount() {
return count($this->mGoodTitles);
}
/**
- * Get a list of redirects when doing redirect resolution
+ * Get a list of redirect resolutions - maps a title to its redirect
+ * target.
* @return array prefixed_title (string) => prefixed_title (string)
*/
public function getRedirectTitles() {
}
/**
- * Get a list of title normalizations - maps the title given
- * with its normalized version.
+ * Get a list of title normalizations - maps a title to its normalized
+ * version.
* @return array raw_prefixed_title (string) => prefixed_title (string)
*/
public function getNormalizedTitles() {
}
/**
- * Get a list of interwiki titles - maps the title given
- * with to the interwiki prefix.
+ * Get a list of interwiki titles - maps a title to its interwiki
+ * prefix.
* @return array raw_prefixed_title (string) => interwiki_prefix (string)
*/
public function getInterwikiTitles() {
}
/**
- * Get the list of revision IDs (requested with revids= parameter)
+ * Get the list of revision IDs (requested with the revids= parameter)
* @return array revID (int) => pageID (int)
*/
public function getRevisionIDs() {
}
/**
- * Returns the number of revisions (requested with revids= parameter)
+ * Returns the number of revisions (requested with revids= parameter)\
+ * @return int
*/
public function getRevisionCount() {
return count($this->getRevisionIDs());
}
/**
- * Populate from the request parameters
+ * Populate the PageSet from the request parameters.
*/
public function execute() {
$this->profileIn();
}
/**
- * Initialize PageSet from a list of Titles
+ * Populate this PageSet from a list of Titles
+ * @param $titles array of Title objects
*/
public function populateFromTitles($titles) {
$this->profileIn();
}
/**
- * Initialize PageSet from a list of Page IDs
+ * Populate this PageSet from a list of page IDs
+ * @param $pageIDs array of page IDs
*/
public function populateFromPageIDs($pageIDs) {
$this->profileIn();
}
/**
- * Initialize PageSet from a rowset returned from the database
+ * Populate this PageSet from a rowset returned from the database
+ * @param $db Database object
+ * @param $queryResult Query result object
*/
public function populateFromQueryResult($db, $queryResult) {
$this->profileIn();
}
/**
- * Initialize PageSet from a list of Revision IDs
+ * Populate this PageSet from a list of revision IDs
+ * @param $revIDs array of revision IDs
*/
public function populateFromRevisionIDs($revIDs) {
$this->profileIn();
- $revIDs = array_map('intval', $revIDs); // paranoia
$this->initFromRevIDs($revIDs);
$this->profileOut();
}
/**
* Extract all requested fields from the row received from the database
+ * @param $row Result row
*/
public function processDbRow($row) {
$fieldValues[$pageId] = $row-> $fieldName;
}
+ /**
+ * Resolve redirects, if applicable
+ */
public function finishPageSetGeneration() {
$this->profileIn();
$this->resolvePendingRedirects();
*
* Additionally, when resolving redirects:
* #3 If no more redirects left, stop.
- * #4 For each redirect, get its links from `pagelinks` table.
+ * #4 For each redirect, get its target from the `redirect` table.
* #5 Substitute the original LinkBatch object with the new list
* #6 Repeat from step #1
+ *
+ * @param $titles array of Title objects or strings
*/
private function initFromTitles($titles) {
// Get pageIDs data from the `page` table
$this->profileDBIn();
- $res = $db->select('page', $this->getPageTableFields(), $set, __METHOD__);
+ $res = $db->select('page', $this->getPageTableFields(), $set,
+ __METHOD__);
$this->profileDBOut();
// Hack: get the ns:titles stored in array(ns => array(titles)) format
$this->resolvePendingRedirects();
}
+ /**
+ * Does the same as initFromTitles(), but is based on page IDs instead
+ * @param $pageids array of page IDs
+ */
private function initFromPageIds($pageids) {
if(!count($pageids))
return;
$set = array (
'page_id' => $pageids
);
-
$db = $this->getDB();
// Get pageIDs data from the `page` table
$this->profileDBIn();
- $res = $db->select('page', $this->getPageTableFields(), $set, __METHOD__);
+ $res = $db->select('page', $this->getPageTableFields(), $set,
+ __METHOD__);
$this->profileDBOut();
$remaining = array_flip($pageids);
* and for each row create and store title object and save any extra fields requested.
* @param $db Database
* @param $res DB Query result
- * @param $remaining Array of either pageID or ns/title elements (optional).
+ * @param $remaining array of either pageID or ns/title elements (optional).
* If given, any missing items will go to $mMissingPageIDs and $mMissingTitles
* @param $processTitles bool Must be provided together with $remaining.
* If true, treat $remaining as an array of [ns][title]
* If false, treat it as an array of [pageIDs]
- * @return Array of redirect IDs (only when resolving redirects)
*/
private function initFromQueryResult($db, $res, &$remaining = null, $processTitles = null) {
if (!is_null($remaining) && is_null($processTitles))
}
}
+ /**
+ * Does the same as initFromTitles(), but is based on revision IDs
+ * instead
+ * @param $revids array of revision IDs
+ */
private function initFromRevIDs($revids) {
if(!count($revids))
return;
+ $revIDs = array_map('intval', $revIDs); // paranoia
$db = $this->getDB();
$pageids = array();
$remaining = array_flip($revids);
$tables = array('revision', 'page');
$fields = array('rev_id', 'rev_page');
$where = array('rev_id' => $revids, 'rev_page = page_id');
+ $options = array();
// Get pageIDs data from the `page` table
$this->profileDBIn();
- $res = $db->select( $tables, $fields, $where, __METHOD__ );
- while ( $row = $db->fetchObject( $res ) ) {
+ $res = $db->select($tables, $fields, $where, __METHOD__);
+ while ($row = $db->fetchObject($res)) {
$revid = intval($row->rev_id);
$pageid = intval($row->rev_page);
$this->mGoodRevIDs[$revid] = $pageid;
$pageids[$pageid] = '';
unset($remaining[$revid]);
}
- $db->freeResult( $res );
+ $db->freeResult($res);
$this->profileDBOut();
$this->mMissingRevIDs = array_keys($remaining);
$this->initFromPageIds(array_keys($pageids));
}
+ /**
+ * Resolve any redirects in the result if redirect resolution was
+ * requested. This function is called repeatedly until all redirects
+ * have been resolved.
+ */
private function resolvePendingRedirects() {
if($this->mResolveRedirects) {
break;
$set = $linkBatch->constructSet('page', $db);
- if(false === $set)
+ if($set === false)
break;
// Get pageIDs data from the `page` table
}
}
+ /**
+ * Get the targets of the pending redirects from the database
+ *
+ * Also creates entries in the redirect table for redirects that don't
+ * have one.
+ * @return LinkBatch
+ */
private function getRedirectTargets() {
$lb = new LinkBatch();
$db = $this->getDB();
* This method validates access rights for the title,
* and appends normalization values to the output.
*
- * @return LinkBatch of title objects.
+ * @param $titles array of Title objects or strings
+ * @return LinkBatch
*/
private function processTitlesArray($titles) {
$linkBatch->addObj($titleObj);
}
- // Make sure we remember the original title that was given to us
- // This way the caller can correlate new titles with the originally requested,
- // i.e. namespace is localized or capitalization is different
+ // Make sure we remember the original title that was
+ // given to us. This way the caller can correlate new
+ // titles with the originally requested when e.g. the
+ // namespace is localized or the capitalization is
+ // different
if (is_string($title) && $title !== $titleObj->getPrefixedText()) {
$this->mNormalizedTitles[$title] = $titleObj->getPrefixedText();
}
}
$count = 0;
+ ksort($titles); // Ensure they're always in the same order
foreach ( $titles as $pageid => $title ) {
$count++;
if(!is_null($params['continue']))
if(!is_null($params['continue']))
if($count < $params['continue'])
continue;
- $fit = true;
+ $r = array();
if(!is_null($params['token']))
{
$tokenFunctions = $this->getTokenFunctions();
if($val === false)
$this->setWarning("Action '$t' is not allowed for the current user");
else
- $fit = $result->addValue(
- array('query', 'pages', $pageid),
- $t . 'token', $val);
+ $r[$t . 'token'] = $val;
}
}
- if($fld_protection && $fit)
+ if($fld_protection)
{
// Apparently the XML formatting code doesn't like array(null)
// This is painful to fix, so we'll just work around it
else
$val = array();
$result->setIndexedTagName($val, 'pr');
- $fit = $result->addValue(
- array('query', 'pages', $pageid),
- 'protection', $val);
+ $r['protection'] = $val;
}
- if($fld_talkid && isset($talkids[$title->getNamespace()][$title->getDbKey()]) && $fit)
- $fit = $result->addValue(array('query', 'pages', $pageid), 'talkid',
- $talkids[$title->getNamespace()][$title->getDbKey()]);
- if($fld_subjectid && isset($subjectids[$title->getNamespace()][$title->getDbKey()]) && $fit)
- $fit = $result->addValue(array('query', 'pages', $pageid), 'subjectid',
- $subjectids[$title->getNamespace()][$title->getDbKey()]);
- if($fld_url && $fit) {
- $fit = $result->addValue(array('query', 'pages', $pageid), 'fullurl',
- $title->getFullURL());
- if($fit)
- $fit = $result->addValue(array('query', 'pages', $pageid), 'editurl',
- $title->getFullURL('action=edit'));
+ if($fld_talkid && isset($talkids[$title->getNamespace()][$title->getDbKey()]))
+ $r['talkid'] = $talkids[$title->getNamespace()][$title->getDbKey()];
+ if($fld_subjectid && isset($subjectids[$title->getNamespace()][$title->getDbKey()]))
+ $r['subjectid'] = $subjectids[$title->getNamespace()][$title->getDbKey()];
+ if($fld_url)
+ {
+ $r['fullurl'] = $title->getFullURL();
+ $r['editurl'] = $title->getFullURL('action=edit');
}
- if($fld_readable && $fit)
+ if($fld_readable)
if($title->userCanRead())
- $fit = $result->addValue(array('query', 'pages', $pageid), 'readable', '');
+ $r['readable'] = '';
+ $fit = $result->addValue(array('query', 'pages'), $pageid, $r);
if(!$fit)
{
$this->setContinueEnumParameter('continue', $count);
private $mData, $mIsRawMode, $mSize, $mCheckingSize;
/**
- * Constructor
- */
+ * Constructor
+ * @param $main ApiMain object
+ */
public function __construct($main) {
parent :: __construct($main, 'result');
$this->mIsRawMode = false;
}
/**
- * 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 the result's internal data array (read-only)
+ * @return array
*/
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 mixed $value
+ * @param $value mixed
* @return int
*/
public static function size($value) {
/**
* 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))
}
/**
- * 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))
/**
* 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
}
/**
- * 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)
{
* 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 array $path Path to the array, like addValue()'s path
- * @param string $tag
+ * @param $path array Path to the array, like addValue()'s $path
+ * @param $tag string
*/
public function setIndexedTagName_internal( $path, $tag ) {
$data = & $this->mData;
* 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;
{
array_walk_recursive($this->mData, array('ApiResult', 'cleanUp_helper'));
}
-
+
+ /**
+ * Callback function for cleanUpUTF8()
+ */
private static function cleanUp_helper(&$s)
{
if(!is_string($s))