summaryrefslogtreecommitdiff
path: root/includes/api
diff options
context:
space:
mode:
Diffstat (limited to 'includes/api')
-rw-r--r--includes/api/ApiBase.php955
-rw-r--r--includes/api/ApiBlock.php105
-rw-r--r--includes/api/ApiDelete.php203
-rw-r--r--includes/api/ApiDisabled.php23
-rw-r--r--includes/api/ApiEditPage.php385
-rw-r--r--includes/api/ApiEmailUser.php34
-rw-r--r--includes/api/ApiExpandTemplates.php17
-rw-r--r--includes/api/ApiFeedWatchlist.php80
-rw-r--r--includes/api/ApiFormatBase.php115
-rw-r--r--includes/api/ApiFormatDbg.php18
-rw-r--r--includes/api/ApiFormatJson.php44
-rw-r--r--includes/api/ApiFormatJson_json.php861
-rw-r--r--includes/api/ApiFormatPhp.php12
-rw-r--r--includes/api/ApiFormatRaw.php28
-rw-r--r--includes/api/ApiFormatTxt.php18
-rw-r--r--includes/api/ApiFormatWddx.php77
-rw-r--r--includes/api/ApiFormatXml.php117
-rw-r--r--includes/api/ApiFormatYaml.php12
-rw-r--r--includes/api/ApiFormatYaml_spyc.php98
-rw-r--r--includes/api/ApiHelp.php12
-rw-r--r--includes/api/ApiImport.php98
-rw-r--r--includes/api/ApiLogin.php99
-rw-r--r--includes/api/ApiLogout.php12
-rw-r--r--includes/api/ApiMain.php347
-rw-r--r--includes/api/ApiMove.php159
-rw-r--r--includes/api/ApiOpenSearch.php38
-rw-r--r--includes/api/ApiPageSet.php257
-rw-r--r--includes/api/ApiParamInfo.php134
-rw-r--r--includes/api/ApiParse.php194
-rw-r--r--includes/api/ApiPatrol.php50
-rw-r--r--includes/api/ApiProtect.php146
-rw-r--r--includes/api/ApiPurge.php41
-rw-r--r--includes/api/ApiQuery.php243
-rw-r--r--includes/api/ApiQueryAllCategories.php92
-rw-r--r--includes/api/ApiQueryAllLinks.php135
-rw-r--r--includes/api/ApiQueryAllUsers.php148
-rw-r--r--includes/api/ApiQueryAllimages.php121
-rw-r--r--includes/api/ApiQueryAllmessages.php118
-rw-r--r--includes/api/ApiQueryAllpages.php162
-rw-r--r--includes/api/ApiQueryBacklinks.php338
-rw-r--r--includes/api/ApiQueryBase.php196
-rw-r--r--includes/api/ApiQueryBlocks.php205
-rw-r--r--includes/api/ApiQueryCategories.php179
-rw-r--r--includes/api/ApiQueryCategoryInfo.php66
-rw-r--r--includes/api/ApiQueryCategoryMembers.php186
-rw-r--r--includes/api/ApiQueryDeletedrevs.php257
-rw-r--r--includes/api/ApiQueryDisabled.php12
-rw-r--r--includes/api/ApiQueryDuplicateFiles.php97
-rw-r--r--includes/api/ApiQueryExtLinksUsage.php125
-rw-r--r--includes/api/ApiQueryExternalLinks.php50
-rw-r--r--includes/api/ApiQueryImageInfo.php229
-rw-r--r--includes/api/ApiQueryImages.php101
-rw-r--r--includes/api/ApiQueryInfo.php447
-rw-r--r--includes/api/ApiQueryLangLinks.php75
-rw-r--r--includes/api/ApiQueryLinks.php120
-rw-r--r--includes/api/ApiQueryLogEvents.php274
-rw-r--r--includes/api/ApiQueryProtectedTitles.php112
-rw-r--r--includes/api/ApiQueryRandom.php82
-rw-r--r--includes/api/ApiQueryRecentChanges.php383
-rw-r--r--includes/api/ApiQueryRevisions.php435
-rw-r--r--includes/api/ApiQuerySearch.php129
-rw-r--r--includes/api/ApiQuerySiteinfo.php198
-rw-r--r--includes/api/ApiQueryTags.php181
-rw-r--r--includes/api/ApiQueryUserContributions.php305
-rw-r--r--includes/api/ApiQueryUserInfo.php99
-rw-r--r--includes/api/ApiQueryUsers.php202
-rw-r--r--includes/api/ApiQueryWatchlist.php316
-rw-r--r--includes/api/ApiQueryWatchlistRaw.php118
-rw-r--r--includes/api/ApiResult.php168
-rw-r--r--includes/api/ApiRollback.php76
-rw-r--r--includes/api/ApiUnblock.php59
-rw-r--r--includes/api/ApiUndelete.php87
-rw-r--r--includes/api/ApiUpload.php325
-rw-r--r--includes/api/ApiUserrights.php128
-rw-r--r--includes/api/ApiWatch.php46
75 files changed, 6760 insertions, 5454 deletions
diff --git a/includes/api/ApiBase.php b/includes/api/ApiBase.php
index 8cf8c096..b703ab4f 100644
--- a/includes/api/ApiBase.php
+++ b/includes/api/ApiBase.php
@@ -1,11 +1,11 @@
<?php
-/*
+/**
* Created on Sep 5, 2006
*
* API for MediaWiki 1.8+
*
- * Copyright (C) 2006 Yuri Astrakhan <Firstname><Lastname>@gmail.com
+ * Copyright © 2006, 2010 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
@@ -49,6 +49,7 @@ abstract class ApiBase {
const PARAM_MAX2 = 4; // Max value allowed for a parameter for bots and sysops. Only applies if TYPE='integer'
const PARAM_MIN = 5; // Lowest value allowed for a parameter. Only applies if TYPE='integer'
const PARAM_ALLOW_DUPLICATES = 6; // Boolean, do we allow the same value to be set more than once when ISMULTI=true
+ const PARAM_DEPRECATED = 7; // Boolean, is the parameter deprecated (will show a warning)
const LIMIT_BIG1 = 500; // Fast query, std user limit
const LIMIT_BIG2 = 5000; // Fast query, bot/sysop limit
@@ -56,6 +57,7 @@ abstract class ApiBase {
const LIMIT_SML2 = 500; // Slow query, bot/sysop limit
private $mMainModule, $mModuleName, $mModulePrefix;
+ private $mParamCache = array();
/**
* Constructor
@@ -63,7 +65,7 @@ abstract class ApiBase {
* @param $moduleName string Name of this module
* @param $modulePrefix string Prefix to use for parameter names
*/
- public function __construct($mainModule, $moduleName, $modulePrefix = '') {
+ public function __construct( $mainModule, $moduleName, $modulePrefix = '' ) {
$this->mMainModule = $mainModule;
$this->mModuleName = $moduleName;
$this->mModulePrefix = $modulePrefix;
@@ -119,11 +121,12 @@ abstract class ApiBase {
* Get the name of the module as shown in the profiler log
* @return string
*/
- public function getModuleProfileName($db = false) {
- if ($db)
+ public function getModuleProfileName( $db = false ) {
+ if ( $db ) {
return 'API:' . $this->mModuleName . '-DB';
- else
+ } else {
return 'API:' . $this->mModuleName;
+ }
}
/**
@@ -150,8 +153,9 @@ abstract class ApiBase {
public function getResult() {
// Main module has getResult() method overriden
// Safety - avoid infinite loop:
- if ($this->isMain())
- ApiBase :: dieDebug(__METHOD__, 'base method was called on main module. ');
+ if ( $this->isMain() ) {
+ ApiBase::dieDebug( __METHOD__, 'base method was called on main module. ' );
+ }
return $this->getMain()->getResult();
}
@@ -170,23 +174,24 @@ abstract class ApiBase {
* newlines
* @param $warning string Warning message
*/
- public function setWarning($warning) {
+ public function setWarning( $warning ) {
$data = $this->getResult()->getData();
- if(isset($data['warnings'][$this->getModuleName()]))
- {
- # Don't add duplicate warnings
- $warn_regex = preg_quote($warning, '/');
- if(preg_match("/{$warn_regex}(\\n|$)/", $data['warnings'][$this->getModuleName()]['*']))
+ if ( isset( $data['warnings'][$this->getModuleName()] ) ) {
+ // Don't add duplicate warnings
+ $warn_regex = preg_quote( $warning, '/' );
+ if ( preg_match( "/{$warn_regex}(\\n|$)/", $data['warnings'][$this->getModuleName()]['*'] ) )
+ {
return;
+ }
$oldwarning = $data['warnings'][$this->getModuleName()]['*'];
- # If there is a warning already, append it to the existing one
+ // If there is a warning already, append it to the existing one
$warning = "$oldwarning\n$warning";
- $this->getResult()->unsetValue('warnings', $this->getModuleName());
+ $this->getResult()->unsetValue( 'warnings', $this->getModuleName() );
}
$msg = array();
- ApiResult :: setContent($msg, $warning);
+ ApiResult::setContent( $msg, $warning );
$this->getResult()->disableSizeCheck();
- $this->getResult()->addValue('warnings', $this->getModuleName(), $msg);
+ $this->getResult()->addValue( 'warnings', $this->getModuleName(), $msg );
$this->getResult()->enableSizeCheck();
}
@@ -205,58 +210,65 @@ abstract class ApiBase {
* @return mixed string or false
*/
public function makeHelpMsg() {
-
static $lnPrfx = "\n ";
$msg = $this->getDescription();
- if ($msg !== false) {
+ if ( $msg !== false ) {
- if (!is_array($msg))
- $msg = array (
+ if ( !is_array( $msg ) ) {
+ $msg = array(
$msg
);
- $msg = $lnPrfx . implode($lnPrfx, $msg) . "\n";
+ }
+ $msg = $lnPrfx . implode( $lnPrfx, $msg ) . "\n";
- if ($this->isReadMode())
+ if ( $this->isReadMode() ) {
$msg .= "\nThis module requires read rights.";
- if ($this->isWriteMode())
+ }
+ if ( $this->isWriteMode() ) {
$msg .= "\nThis module requires write rights.";
- if ($this->mustBePosted())
+ }
+ if ( $this->mustBePosted() ) {
$msg .= "\nThis module only accepts POST requests.";
- if ($this->isReadMode() || $this->isWriteMode() ||
- $this->mustBePosted())
+ }
+ if ( $this->isReadMode() || $this->isWriteMode() ||
+ $this->mustBePosted() )
+ {
$msg .= "\n";
+ }
// Parameters
$paramsMsg = $this->makeHelpMsgParameters();
- if ($paramsMsg !== false) {
+ if ( $paramsMsg !== false ) {
$msg .= "Parameters:\n$paramsMsg";
}
// Examples
$examples = $this->getExamples();
- if ($examples !== false) {
- if (!is_array($examples))
- $examples = array (
+ if ( $examples !== false ) {
+ if ( !is_array( $examples ) ) {
+ $examples = array(
$examples
);
- $msg .= 'Example' . (count($examples) > 1 ? 's' : '') . ":\n ";
- $msg .= implode($lnPrfx, $examples) . "\n";
+ }
+ $msg .= 'Example' . ( count( $examples ) > 1 ? 's' : '' ) . ":\n ";
+ $msg .= implode( $lnPrfx, $examples ) . "\n";
}
- if ($this->getMain()->getShowVersions()) {
+ if ( $this->getMain()->getShowVersions() ) {
$versions = $this->getVersion();
$pattern = '/(\$.*) ([0-9a-z_]+\.php) (.*\$)/i';
- $replacement = '\\0' . "\n " . 'http://svn.wikimedia.org/viewvc/mediawiki/trunk/phase3/includes/api/\\2';
+ $callback = array( $this, 'makeHelpMsg_callback' );
- if (is_array($versions)) {
- foreach ($versions as &$v)
- $v = preg_replace($pattern, $replacement, $v);
- $versions = implode("\n ", $versions);
+ if ( is_array( $versions ) ) {
+ foreach ( $versions as &$v ) {
+ $v = preg_replace_callback( $pattern, $callback, $v );
+ }
+ $versions = implode( "\n ", $versions );
+ } else {
+ $versions = preg_replace_callback( $pattern, $callback, $versions );
}
- else
- $versions = preg_replace($pattern, $replacement, $versions);
$msg .= "Version:\n $versions\n";
}
@@ -272,51 +284,61 @@ abstract class ApiBase {
*/
public function makeHelpMsgParameters() {
$params = $this->getFinalParams();
- if ($params !== false) {
+ if ( $params ) {
$paramsDescription = $this->getFinalParamDescription();
$msg = '';
- $paramPrefix = "\n" . str_repeat(' ', 19);
- foreach ($params as $paramName => $paramSettings) {
- $desc = isset ($paramsDescription[$paramName]) ? $paramsDescription[$paramName] : '';
- if (is_array($desc))
- $desc = implode($paramPrefix, $desc);
-
- $type = isset($paramSettings[self :: PARAM_TYPE])? $paramSettings[self :: PARAM_TYPE] : null;
- if (isset ($type)) {
- if (isset ($paramSettings[self :: PARAM_ISMULTI]))
+ $paramPrefix = "\n" . str_repeat( ' ', 19 );
+ foreach ( $params as $paramName => $paramSettings ) {
+ $desc = isset( $paramsDescription[$paramName] ) ? $paramsDescription[$paramName] : '';
+ if ( is_array( $desc ) ) {
+ $desc = implode( $paramPrefix, $desc );
+ }
+
+ $deprecated = isset( $paramSettings[self::PARAM_DEPRECATED] ) ?
+ $paramSettings[self::PARAM_DEPRECATED] : false;
+ if ( $deprecated ) {
+ $desc = "DEPRECATED! $desc";
+ }
+
+ $type = isset( $paramSettings[self::PARAM_TYPE] ) ? $paramSettings[self::PARAM_TYPE] : null;
+ if ( isset( $type ) ) {
+ if ( isset( $paramSettings[self::PARAM_ISMULTI] ) ) {
$prompt = 'Values (separate with \'|\'): ';
- else
+ } else {
$prompt = 'One value: ';
+ }
- if (is_array($type)) {
+ if ( is_array( $type ) ) {
$choices = array();
$nothingPrompt = false;
- foreach ($type as $t)
- if ($t === '')
+ foreach ( $type as $t )
+ if ( $t === '' ) {
$nothingPrompt = 'Can be empty, or ';
- else
+ } else {
$choices[] = $t;
- $desc .= $paramPrefix . $nothingPrompt . $prompt . implode(', ', $choices);
+ }
+ $desc .= $paramPrefix . $nothingPrompt . $prompt . implode( ', ', $choices );
} else {
- switch ($type) {
+ switch ( $type ) {
case 'namespace':
// Special handling because namespaces are type-limited, yet they are not given
- $desc .= $paramPrefix . $prompt . implode(', ', ApiBase :: getValidNamespaces());
+ $desc .= $paramPrefix . $prompt . implode( ', ', ApiBase::getValidNamespaces() );
break;
case 'limit':
- $desc .= $paramPrefix . "No more than {$paramSettings[self :: PARAM_MAX]} ({$paramSettings[self :: PARAM_MAX2]} for bots) allowed.";
+ $desc .= $paramPrefix . "No more than {$paramSettings[self :: PARAM_MAX]} ({$paramSettings[self::PARAM_MAX2]} for bots) allowed.";
break;
case 'integer':
- $hasMin = isset($paramSettings[self :: PARAM_MIN]);
- $hasMax = isset($paramSettings[self :: PARAM_MAX]);
- if ($hasMin || $hasMax) {
- if (!$hasMax)
- $intRangeStr = "The value must be no less than {$paramSettings[self :: PARAM_MIN]}";
- elseif (!$hasMin)
- $intRangeStr = "The value must be no more than {$paramSettings[self :: PARAM_MAX]}";
- else
- $intRangeStr = "The value must be between {$paramSettings[self :: PARAM_MIN]} and {$paramSettings[self :: PARAM_MAX]}";
+ $hasMin = isset( $paramSettings[self::PARAM_MIN] );
+ $hasMax = isset( $paramSettings[self::PARAM_MAX] );
+ if ( $hasMin || $hasMax ) {
+ if ( !$hasMax ) {
+ $intRangeStr = "The value must be no less than {$paramSettings[self::PARAM_MIN]}";
+ } elseif ( !$hasMin ) {
+ $intRangeStr = "The value must be no more than {$paramSettings[self::PARAM_MAX]}";
+ } else {
+ $intRangeStr = "The value must be between {$paramSettings[self::PARAM_MIN]} and {$paramSettings[self::PARAM_MAX]}";
+ }
$desc .= $paramPrefix . $intRangeStr;
}
@@ -325,16 +347,51 @@ abstract class ApiBase {
}
}
- $default = is_array($paramSettings) ? (isset ($paramSettings[self :: PARAM_DFLT]) ? $paramSettings[self :: PARAM_DFLT] : null) : $paramSettings;
- if (!is_null($default) && $default !== false)
+ $default = is_array( $paramSettings ) ? ( isset( $paramSettings[self::PARAM_DFLT] ) ? $paramSettings[self::PARAM_DFLT] : null ) : $paramSettings;
+ if ( !is_null( $default ) && $default !== false ) {
$desc .= $paramPrefix . "Default: $default";
+ }
- $msg .= sprintf(" %-14s - %s\n", $this->encodeParamName($paramName), $desc);
+ $msg .= sprintf( " %-14s - %s\n", $this->encodeParamName( $paramName ), $desc );
}
return $msg;
- } else
+ } else {
return false;
+ }
+ }
+
+ /**
+ * Callback for preg_replace_callback() call in makeHelpMsg().
+ * Replaces a source file name with a link to ViewVC
+ */
+ public function makeHelpMsg_callback( $matches ) {
+ global $wgAutoloadClasses, $wgAutoloadLocalClasses;
+ if ( isset( $wgAutoloadLocalClasses[get_class( $this )] ) ) {
+ $file = $wgAutoloadLocalClasses[get_class( $this )];
+ } elseif ( isset( $wgAutoloadClasses[get_class( $this )] ) ) {
+ $file = $wgAutoloadClasses[get_class( $this )];
+ }
+
+ // Do some guesswork here
+ $path = strstr( $file, 'includes/api/' );
+ if ( $path === false ) {
+ $path = strstr( $file, 'extensions/' );
+ } else {
+ $path = 'phase3/' . $path;
+ }
+
+ // Get the filename from $matches[2] instead of $file
+ // If they're not the same file, they're assumed to be in the
+ // same directory
+ // This is necessary to make stuff like ApiMain::getVersion()
+ // returning the version string for ApiBase work
+ if ( $path ) {
+ return "{$matches[0]}\n http://svn.wikimedia.org/" .
+ "viewvc/mediawiki/trunk/" . dirname( $path ) .
+ "/{$matches[2]}";
+ }
+ return $matches[0];
}
/**
@@ -373,7 +430,7 @@ abstract class ApiBase {
protected function getParamDescription() {
return false;
}
-
+
/**
* Get final list of parameters, after hooks have had a chance to
* tweak it as needed.
@@ -381,7 +438,7 @@ abstract class ApiBase {
*/
public function getFinalParams() {
$params = $this->getAllowedParams();
- wfRunHooks('APIGetAllowedParams', array(&$this, &$params));
+ wfRunHooks( 'APIGetAllowedParams', array( &$this, &$params ) );
return $params;
}
@@ -392,7 +449,7 @@ abstract class ApiBase {
*/
public function getFinalParamDescription() {
$desc = $this->getParamDescription();
- wfRunHooks('APIGetParamDescription', array(&$this, &$desc));
+ wfRunHooks( 'APIGetParamDescription', array( &$this, &$desc ) );
return $desc;
}
@@ -402,56 +459,63 @@ abstract class ApiBase {
* @param $paramName string Parameter name
* @return string Prefixed parameter name
*/
- public function encodeParamName($paramName) {
+ public function encodeParamName( $paramName ) {
return $this->mModulePrefix . $paramName;
}
/**
- * 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();
- $results = array ();
-
- foreach ($params as $paramName => $paramSettings)
- $results[$paramName] = $this->getParameterFromSettings($paramName, $paramSettings, $parseMaxLimit);
-
- return $results;
+ * 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. limits will not be
+ * parsed if $parseLimit is set to false; use this when the max
+ * limit is not definitive yet, e.g. when getting revisions.
+ * @param $parseLimit Boolean: true by default
+ * @return array
+ */
+ public function extractRequestParams( $parseLimit = true ) {
+ // Cache parameters, for performance and to avoid bug 24564.
+ if ( !isset( $this->mParamCache[$parseLimit] ) ) {
+ $params = $this->getFinalParams();
+ $results = array();
+
+ if ( $params ) { // getFinalParams() can return false
+ foreach ( $params as $paramName => $paramSettings ) {
+ $results[$paramName] = $this->getParameterFromSettings(
+ $paramName, $paramSettings, $parseLimit );
+ }
+ }
+ $this->mParamCache[$parseLimit] = $results;
+ }
+ return $this->mParamCache[$parseLimit];
}
/**
* Get a value for the given parameter
* @param $paramName string Parameter name
- * @param $parseMaxLimit bool see extractRequestParams()
+ * @param $parseLimit bool see extractRequestParams()
* @return mixed Parameter value
*/
- protected function getParameter($paramName, $parseMaxLimit = true) {
+ protected function getParameter( $paramName, $parseLimit = true ) {
$params = $this->getFinalParams();
$paramSettings = $params[$paramName];
- return $this->getParameterFromSettings($paramName, $paramSettings, $parseMaxLimit);
+ return $this->getParameterFromSettings( $paramName, $paramSettings, $parseLimit );
}
-
+
/**
- * Die if none or more than one of a certain set of parameters is set
+ * Die if none or more than one of a certain set of parameters is set and not false.
* @param $params array of parameter names
*/
- public function requireOnlyOneParameter($params) {
+ public function requireOnlyOneParameter( $params ) {
$required = func_get_args();
- array_shift($required);
-
- $intersection = array_intersect(array_keys(array_filter($params,
- create_function('$x', 'return !is_null($x);')
- )), $required);
- if (count($intersection) > 1) {
- $this->dieUsage('The parameters '.implode(', ', $intersection).' can not be used together', 'invalidparammix');
- } elseif (count($intersection) == 0) {
- $this->dieUsage('One of the parameters '.implode(', ', $required).' is required', 'missingparam');
+ array_shift( $required );
+
+ $intersection = array_intersect( array_keys( array_filter( $params,
+ create_function( '$x', 'return !is_null($x) && $x !== false;' )
+ ) ), $required );
+ if ( count( $intersection ) > 1 ) {
+ $this->dieUsage( 'The parameters ' . implode( ', ', $intersection ) . ' can not be used together', 'invalidparammix' );
+ } elseif ( count( $intersection ) == 0 ) {
+ $this->dieUsage( 'One of the parameters ' . implode( ', ', $required ) . ' is required', 'missingparam' );
}
}
@@ -462,15 +526,17 @@ abstract class ApiBase {
*/
public static function getValidNamespaces() {
static $mValidNamespaces = null;
- if (is_null($mValidNamespaces)) {
+ if ( is_null( $mValidNamespaces ) ) {
global $wgContLang;
- $mValidNamespaces = array ();
- foreach (array_keys($wgContLang->getNamespaces()) as $ns) {
- if ($ns >= 0)
+ $mValidNamespaces = array();
+ foreach ( array_keys( $wgContLang->getNamespaces() ) as $ns ) {
+ if ( $ns >= 0 ) {
$mValidNamespaces[] = $ns;
+ }
}
}
+
return $mValidNamespaces;
}
@@ -480,163 +546,183 @@ abstract class ApiBase {
* @param $paramName String: parameter name
* @param $paramSettings Mixed: default value or an array of settings
* using PARAM_* constants.
- * @param $parseMaxLimit Boolean: parse limit when max is given?
+ * @param $parseLimit Boolean: parse limit?
* @return mixed Parameter value
*/
- protected function getParameterFromSettings($paramName, $paramSettings, $parseMaxLimit) {
-
+ protected function getParameterFromSettings( $paramName, $paramSettings, $parseLimit ) {
// Some classes may decide to change parameter names
- $encParamName = $this->encodeParamName($paramName);
+ $encParamName = $this->encodeParamName( $paramName );
- if (!is_array($paramSettings)) {
+ if ( !is_array( $paramSettings ) ) {
$default = $paramSettings;
$multi = false;
- $type = gettype($paramSettings);
+ $type = gettype( $paramSettings );
$dupes = false;
+ $deprecated = false;
} else {
- $default = isset ($paramSettings[self :: PARAM_DFLT]) ? $paramSettings[self :: PARAM_DFLT] : null;
- $multi = isset ($paramSettings[self :: PARAM_ISMULTI]) ? $paramSettings[self :: PARAM_ISMULTI] : false;
- $type = isset ($paramSettings[self :: PARAM_TYPE]) ? $paramSettings[self :: PARAM_TYPE] : null;
- $dupes = isset ($paramSettings[self:: PARAM_ALLOW_DUPLICATES]) ? $paramSettings[self :: PARAM_ALLOW_DUPLICATES] : false;
+ $default = isset( $paramSettings[self::PARAM_DFLT] ) ? $paramSettings[self::PARAM_DFLT] : null;
+ $multi = isset( $paramSettings[self::PARAM_ISMULTI] ) ? $paramSettings[self::PARAM_ISMULTI] : false;
+ $type = isset( $paramSettings[self::PARAM_TYPE] ) ? $paramSettings[self::PARAM_TYPE] : null;
+ $dupes = isset( $paramSettings[self::PARAM_ALLOW_DUPLICATES] ) ? $paramSettings[self::PARAM_ALLOW_DUPLICATES] : false;
+ $deprecated = isset( $paramSettings[self::PARAM_DEPRECATED] ) ? $paramSettings[self::PARAM_DEPRECATED] : false;
// When type is not given, and no choices, the type is the same as $default
- if (!isset ($type)) {
- if (isset ($default))
- $type = gettype($default);
- else
+ if ( !isset( $type ) ) {
+ if ( isset( $default ) ) {
+ $type = gettype( $default );
+ } else {
$type = 'NULL'; // allow everything
+ }
}
}
- if ($type == 'boolean') {
- if (isset ($default) && $default !== false) {
+ if ( $type == 'boolean' ) {
+ if ( isset( $default ) && $default !== false ) {
// Having a default value of anything other than 'false' is pointless
- ApiBase :: dieDebug(__METHOD__, "Boolean param $encParamName's default is set to '$default'");
+ ApiBase::dieDebug( __METHOD__, "Boolean param $encParamName's default is set to '$default'" );
}
- $value = $this->getMain()->getRequest()->getCheck($encParamName);
+ $value = $this->getMain()->getRequest()->getCheck( $encParamName );
} else {
- $value = $this->getMain()->getRequest()->getVal($encParamName, $default);
+ $value = $this->getMain()->getRequest()->getVal( $encParamName, $default );
- if (isset ($value) && $type == 'namespace')
- $type = ApiBase :: getValidNamespaces();
+ if ( isset( $value ) && $type == 'namespace' ) {
+ $type = ApiBase::getValidNamespaces();
+ }
}
- if (isset ($value) && ($multi || is_array($type)))
- $value = $this->parseMultiValue($encParamName, $value, $multi, is_array($type) ? $type : null);
+ if ( isset( $value ) && ( $multi || is_array( $type ) ) ) {
+ $value = $this->parseMultiValue( $encParamName, $value, $multi, is_array( $type ) ? $type : null );
+ }
// More validation only when choices were not given
// choices were validated in parseMultiValue()
- if (isset ($value)) {
- if (!is_array($type)) {
- switch ($type) {
- case 'NULL' : // nothing to do
+ if ( isset( $value ) ) {
+ if ( !is_array( $type ) ) {
+ switch ( $type ) {
+ case 'NULL': // nothing to do
break;
- case 'string' : // nothing to do
+ case 'string': // nothing to do
break;
- case 'integer' : // Force everything using intval() and optionally validate limits
+ case 'integer': // Force everything using intval() and optionally validate limits
- $value = is_array($value) ? array_map('intval', $value) : intval($value);
- $min = isset ($paramSettings[self :: PARAM_MIN]) ? $paramSettings[self :: PARAM_MIN] : null;
- $max = isset ($paramSettings[self :: PARAM_MAX]) ? $paramSettings[self :: PARAM_MAX] : null;
+ $value = is_array( $value ) ? array_map( 'intval', $value ) : intval( $value );
+ $min = isset ( $paramSettings[self::PARAM_MIN] ) ? $paramSettings[self::PARAM_MIN] : null;
+ $max = isset ( $paramSettings[self::PARAM_MAX] ) ? $paramSettings[self::PARAM_MAX] : null;
- if (!is_null($min) || !is_null($max)) {
- $values = is_array($value) ? $value : array($value);
- foreach ($values as $v) {
- $this->validateLimit($paramName, $v, $min, $max);
+ if ( !is_null( $min ) || !is_null( $max ) ) {
+ $values = is_array( $value ) ? $value : array( $value );
+ foreach ( $values as &$v ) {
+ $this->validateLimit( $paramName, $v, $min, $max );
}
}
break;
- case 'limit' :
- if (!isset ($paramSettings[self :: PARAM_MAX]) || !isset ($paramSettings[self :: PARAM_MAX2]))
- ApiBase :: dieDebug(__METHOD__, "MAX1 or MAX2 are not defined for the limit $encParamName");
- if ($multi)
- ApiBase :: dieDebug(__METHOD__, "Multi-values not supported for $encParamName");
- $min = isset ($paramSettings[self :: PARAM_MIN]) ? $paramSettings[self :: PARAM_MIN] : 0;
- if( $value == 'max' ) {
- if( $parseMaxLimit ) {
- $value = $this->getMain()->canApiHighLimits() ? $paramSettings[self :: PARAM_MAX2] : $paramSettings[self :: PARAM_MAX];
- $this->getResult()->addValue( 'limits', $this->getModuleName(), $value );
- $this->validateLimit($paramName, $value, $min, $paramSettings[self :: PARAM_MAX], $paramSettings[self :: PARAM_MAX2]);
- }
+ case 'limit':
+ if ( !$parseLimit ) {
+ // Don't do any validation whatsoever
+ break;
+ }
+ if ( !isset( $paramSettings[self::PARAM_MAX] ) || !isset( $paramSettings[self::PARAM_MAX2] ) ) {
+ ApiBase::dieDebug( __METHOD__, "MAX1 or MAX2 are not defined for the limit $encParamName" );
}
- else {
- $value = intval($value);
- $this->validateLimit($paramName, $value, $min, $paramSettings[self :: PARAM_MAX], $paramSettings[self :: PARAM_MAX2]);
+ if ( $multi ) {
+ ApiBase::dieDebug( __METHOD__, "Multi-values not supported for $encParamName" );
+ }
+ $min = isset( $paramSettings[self::PARAM_MIN] ) ? $paramSettings[self::PARAM_MIN] : 0;
+ if ( $value == 'max' ) {
+ $value = $this->getMain()->canApiHighLimits() ? $paramSettings[self::PARAM_MAX2] : $paramSettings[self::PARAM_MAX];
+ $this->getResult()->addValue( 'limits', $this->getModuleName(), $value );
+ } else {
+ $value = intval( $value );
+ $this->validateLimit( $paramName, $value, $min, $paramSettings[self::PARAM_MAX], $paramSettings[self::PARAM_MAX2] );
}
break;
- case 'boolean' :
- if ($multi)
- ApiBase :: dieDebug(__METHOD__, "Multi-values not supported for $encParamName");
+ case 'boolean':
+ if ( $multi )
+ ApiBase::dieDebug( __METHOD__, "Multi-values not supported for $encParamName" );
break;
- case 'timestamp' :
- if ($multi)
- ApiBase :: dieDebug(__METHOD__, "Multi-values not supported for $encParamName");
- $value = wfTimestamp(TS_UNIX, $value);
- if ($value === 0)
- $this->dieUsage("Invalid value '$value' for timestamp parameter $encParamName", "badtimestamp_{$encParamName}");
- $value = wfTimestamp(TS_MW, $value);
+ case 'timestamp':
+ if ( $multi ) {
+ ApiBase::dieDebug( __METHOD__, "Multi-values not supported for $encParamName" );
+ }
+ $value = wfTimestamp( TS_UNIX, $value );
+ if ( $value === 0 ) {
+ $this->dieUsage( "Invalid value '$value' for timestamp parameter $encParamName", "badtimestamp_{$encParamName}" );
+ }
+ $value = wfTimestamp( TS_MW, $value );
break;
- case 'user' :
+ case 'user':
$title = Title::makeTitleSafe( NS_USER, $value );
- if ( is_null( $title ) )
- $this->dieUsage("Invalid value for user parameter $encParamName", "baduser_{$encParamName}");
+ if ( is_null( $title ) ) {
+ $this->dieUsage( "Invalid value for user parameter $encParamName", "baduser_{$encParamName}" );
+ }
$value = $title->getText();
break;
- default :
- ApiBase :: dieDebug(__METHOD__, "Param $encParamName's type is unknown - $type");
+ default:
+ ApiBase::dieDebug( __METHOD__, "Param $encParamName's type is unknown - $type" );
}
}
// Throw out duplicates if requested
- if (is_array($value) && !$dupes)
- $value = array_unique($value);
+ if ( is_array( $value ) && !$dupes ) {
+ $value = array_unique( $value );
+ }
+
+ // Set a warning if a deprecated parameter has been passed
+ if ( $deprecated && $value !== false ) {
+ $this->setWarning( "The $encParamName parameter has been deprecated." );
+ }
}
return $value;
}
/**
- * 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 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) === "" && $allowMultiple)
+ * 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 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 ) === '' && $allowMultiple ) {
return array();
- $sizeLimit = $this->mMainModule->canApiHighLimits() ? self::LIMIT_SML2 : self::LIMIT_SML1;
- $valuesList = explode('|', $value, $sizeLimit + 1);
- if( self::truncateArray($valuesList, $sizeLimit) ) {
- $this->setWarning("Too many values supplied for parameter '$valueName': the limit is $sizeLimit");
- }
- if (!$allowMultiple && count($valuesList) != 1) {
- $possibleValues = is_array($allowedValues) ? "of '" . implode("', '", $allowedValues) . "'" : '';
- $this->dieUsage("Only one $possibleValues is allowed for parameter '$valueName'", "multival_$valueName");
- }
- if (is_array($allowedValues)) {
- # Check for unknown values
- $unknown = array_diff($valuesList, $allowedValues);
- if(count($unknown))
- {
- if($allowMultiple)
- {
- $s = count($unknown) > 1 ? "s" : "";
- $vals = implode(", ", $unknown);
- $this->setWarning("Unrecognized value$s for parameter '$valueName': $vals");
+ }
+
+ // This is a bit awkward, but we want to avoid calling canApiHighLimits() because it unstubs $wgUser
+ $valuesList = explode( '|', $value, self::LIMIT_SML2 + 1 );
+ $sizeLimit = count( $valuesList ) > self::LIMIT_SML1 && $this->mMainModule->canApiHighLimits() ?
+ self::LIMIT_SML2 : self::LIMIT_SML1;
+
+ if ( self::truncateArray( $valuesList, $sizeLimit ) ) {
+ $this->setWarning( "Too many values supplied for parameter '$valueName': the limit is $sizeLimit" );
+ }
+
+ if ( !$allowMultiple && count( $valuesList ) != 1 ) {
+ $possibleValues = is_array( $allowedValues ) ? "of '" . implode( "', '", $allowedValues ) . "'" : '';
+ $this->dieUsage( "Only one $possibleValues is allowed for parameter '$valueName'", "multival_$valueName" );
+ }
+
+ if ( is_array( $allowedValues ) ) {
+ // Check for unknown values
+ $unknown = array_diff( $valuesList, $allowedValues );
+ if ( count( $unknown ) ) {
+ if ( $allowMultiple ) {
+ $s = count( $unknown ) > 1 ? 's' : '';
+ $vals = implode( ", ", $unknown );
+ $this->setWarning( "Unrecognized value$s for parameter '$valueName': $vals" );
+ } else {
+ $this->dieUsage( "Unrecognized value for parameter '$valueName': {$valuesList[0]}", "unknown_$valueName" );
}
- else
- $this->dieUsage("Unrecognized value for parameter '$valueName': {$valuesList[0]}", "unknown_$valueName");
}
- # Now throw them out
- $valuesList = array_intersect($valuesList, $allowedValues);
+ // Now throw them out
+ $valuesList = array_intersect( $valuesList, $allowedValues );
}
return $allowMultiple ? $valuesList : $valuesList[0];
@@ -651,54 +737,61 @@ abstract class ApiBase {
* @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);
+ function validateLimit( $paramName, &$value, $min, $max, $botMax = null ) {
+ if ( !is_null( $min ) && $value < $min ) {
+ $this->setWarning( $this->encodeParamName( $paramName ) . " may not be less than $min (set to $value)" );
+ $value = $min;
}
// Minimum is always validated, whereas maximum is checked only if not running in internal call mode
- if ($this->getMain()->isInternalMode())
+ if ( $this->getMain()->isInternalMode() ) {
return;
+ }
// Optimization: do not check user's bot status unless really needed -- skips db query
// assumes $botMax >= $max
- if (!is_null($max) && $value > $max) {
- if (!is_null($botMax) && $this->getMain()->canApiHighLimits()) {
- if ($value > $botMax) {
- $this->dieUsage($this->encodeParamName($paramName) . " may not be over $botMax (set to $value) for bots or sysops", $paramName);
+ if ( !is_null( $max ) && $value > $max ) {
+ if ( !is_null( $botMax ) && $this->getMain()->canApiHighLimits() ) {
+ if ( $value > $botMax ) {
+ $this->setWarning( $this->encodeParamName( $paramName ) . " may not be over $botMax (set to $value) for bots or sysops" );
+ $value = $botMax;
}
} else {
- $this->dieUsage($this->encodeParamName($paramName) . " may not be over $max (set to $value) for users", $paramName);
+ $this->setWarning( $this->encodeParamName( $paramName ) . " may not be over $max (set to $value) for users" );
+ $value = $max;
}
}
}
-
+
/**
* Truncate an array to a certain length.
* @param $arr array Array to truncate
* @param $limit int Maximum length
* @return bool True if the array was truncated, false otherwise
*/
- public static function truncateArray(&$arr, $limit)
- {
+ public static function truncateArray( &$arr, $limit ) {
$modified = false;
- while(count($arr) > $limit)
- {
- $junk = array_pop($arr);
+ while ( count( $arr ) > $limit ) {
+ $junk = array_pop( $arr );
$modified = true;
}
return $modified;
}
/**
- * Call the main module's error handler
- * @param $description string Error text
- * @param $errorCode string Error code
+ * Throw a UsageException, which will (if uncaught) call the main module's
+ * error handler and die with an error message.
+ *
+ * @param $description string One-line human-readable description of the
+ * error condition, e.g., "The API requires a valid action parameter"
+ * @param $errorCode string Brief, arbitrary, stable string to allow easy
+ * automated identification of the error, e.g., 'unknown_action'
* @param $httpRespCode int HTTP response code
+ * @param $extradata array Data to add to the <error> element; array in ApiResult format
*/
- public function dieUsage($description, $errorCode, $httpRespCode = 0) {
+ public function dieUsage( $description, $errorCode, $httpRespCode = 0, $extradata = null ) {
wfProfileClose();
- throw new UsageException($description, $this->encodeParamName($errorCode), $httpRespCode);
+ throw new UsageException( $description, $this->encodeParamName( $errorCode ), $httpRespCode, $extradata );
}
/**
@@ -706,145 +799,170 @@ abstract class ApiBase {
*/
public static $messageMap = array(
// This one MUST be present, or dieUsageMsg() will recurse infinitely
- 'unknownerror' => array('code' => 'unknownerror', 'info' => "Unknown error: ``\$1''"),
- 'unknownerror-nocode' => array('code' => 'unknownerror', 'info' => 'Unknown error'),
+ 'unknownerror' => array( 'code' => 'unknownerror', 'info' => "Unknown error: ``\$1''" ),
+ 'unknownerror-nocode' => array( 'code' => 'unknownerror', 'info' => 'Unknown error' ),
// Messages from Title::getUserPermissionsErrors()
- 'ns-specialprotected' => array('code' => 'unsupportednamespace', 'info' => "Pages in the Special namespace can't be edited"),
- 'protectedinterface' => array('code' => 'protectednamespace-interface', 'info' => "You're not allowed to edit interface messages"),
- 'namespaceprotected' => array('code' => 'protectednamespace', 'info' => "You're not allowed to edit pages in the ``\$1'' namespace"),
- 'customcssjsprotected' => array('code' => 'customcssjsprotected', 'info' => "You're not allowed to edit custom CSS and JavaScript pages"),
- 'cascadeprotected' => array('code' => 'cascadeprotected', 'info' =>"The page you're trying to edit is protected because it's included in a cascade-protected page"),
- 'protectedpagetext' => array('code' => 'protectedpage', 'info' => "The ``\$1'' right is required to edit this page"),
- 'protect-cantedit' => array('code' => 'cantedit', 'info' => "You can't protect this page because you can't edit it"),
- 'badaccess-group0' => array('code' => 'permissiondenied', 'info' => "Permission denied"), // Generic permission denied message
- 'badaccess-groups' => array('code' => 'permissiondenied', 'info' => "Permission denied"),
- 'titleprotected' => array('code' => 'protectedtitle', 'info' => "This title has been protected from creation"),
- 'nocreate-loggedin' => array('code' => 'cantcreate', 'info' => "You don't have permission to create new pages"),
- 'nocreatetext' => array('code' => 'cantcreate-anon', 'info' => "Anonymous users can't create new pages"),
- 'movenologintext' => array('code' => 'cantmove-anon', 'info' => "Anonymous users can't move pages"),
- 'movenotallowed' => array('code' => 'cantmove', 'info' => "You don't have permission to move pages"),
- 'confirmedittext' => array('code' => 'confirmemail', 'info' => "You must confirm your e-mail address before you can edit"),
- 'blockedtext' => array('code' => 'blocked', 'info' => "You have been blocked from editing"),
- 'autoblockedtext' => array('code' => 'autoblocked', 'info' => "Your IP address has been blocked automatically, because it was used by a blocked user"),
+ 'ns-specialprotected' => array( 'code' => 'unsupportednamespace', 'info' => "Pages in the Special namespace can't be edited" ),
+ 'protectedinterface' => array( 'code' => 'protectednamespace-interface', 'info' => "You're not allowed to edit interface messages" ),
+ 'namespaceprotected' => array( 'code' => 'protectednamespace', 'info' => "You're not allowed to edit pages in the ``\$1'' namespace" ),
+ 'customcssjsprotected' => array( 'code' => 'customcssjsprotected', 'info' => "You're not allowed to edit custom CSS and JavaScript pages" ),
+ 'cascadeprotected' => array( 'code' => 'cascadeprotected', 'info' => "The page you're trying to edit is protected because it's included in a cascade-protected page" ),
+ 'protectedpagetext' => array( 'code' => 'protectedpage', 'info' => "The ``\$1'' right is required to edit this page" ),
+ 'protect-cantedit' => array( 'code' => 'cantedit', 'info' => "You can't protect this page because you can't edit it" ),
+ 'badaccess-group0' => array( 'code' => 'permissiondenied', 'info' => "Permission denied" ), // Generic permission denied message
+ 'badaccess-groups' => array( 'code' => 'permissiondenied', 'info' => "Permission denied" ),
+ 'titleprotected' => array( 'code' => 'protectedtitle', 'info' => "This title has been protected from creation" ),
+ 'nocreate-loggedin' => array( 'code' => 'cantcreate', 'info' => "You don't have permission to create new pages" ),
+ 'nocreatetext' => array( 'code' => 'cantcreate-anon', 'info' => "Anonymous users can't create new pages" ),
+ 'movenologintext' => array( 'code' => 'cantmove-anon', 'info' => "Anonymous users can't move pages" ),
+ 'movenotallowed' => array( 'code' => 'cantmove', 'info' => "You don't have permission to move pages" ),
+ 'confirmedittext' => array( 'code' => 'confirmemail', 'info' => "You must confirm your e-mail address before you can edit" ),
+ 'blockedtext' => array( 'code' => 'blocked', 'info' => "You have been blocked from editing" ),
+ 'autoblockedtext' => array( 'code' => 'autoblocked', 'info' => "Your IP address has been blocked automatically, because it was used by a blocked user" ),
// Miscellaneous interface messages
- 'actionthrottledtext' => array('code' => 'ratelimited', 'info' => "You've exceeded your rate limit. Please wait some time and try again"),
- 'alreadyrolled' => array('code' => 'alreadyrolled', 'info' => "The page you tried to rollback was already rolled back"),
- 'cantrollback' => array('code' => 'onlyauthor', 'info' => "The page you tried to rollback only has one author"),
- 'readonlytext' => array('code' => 'readonly', 'info' => "The wiki is currently in read-only mode"),
- 'sessionfailure' => array('code' => 'badtoken', 'info' => "Invalid token"),
- 'cannotdelete' => array('code' => 'cantdelete', 'info' => "Couldn't delete ``\$1''. Maybe it was deleted already by someone else"),
- 'notanarticle' => array('code' => 'missingtitle', 'info' => "The page you requested doesn't exist"),
- 'selfmove' => array('code' => 'selfmove', 'info' => "Can't move a page to itself"),
- 'immobile_namespace' => array('code' => 'immobilenamespace', 'info' => "You tried to move pages from or to a namespace that is protected from moving"),
- 'articleexists' => array('code' => 'articleexists', 'info' => "The destination article already exists and is not a redirect to the source article"),
- 'protectedpage' => array('code' => 'protectedpage', 'info' => "You don't have permission to perform this move"),
- 'hookaborted' => array('code' => 'hookaborted', 'info' => "The modification you tried to make was aborted by an extension hook"),
- 'cantmove-titleprotected' => array('code' => 'protectedtitle', 'info' => "The destination article has been protected from creation"),
- 'imagenocrossnamespace' => array('code' => 'nonfilenamespace', 'info' => "Can't move a file to a non-file namespace"),
- 'imagetypemismatch' => array('code' => 'filetypemismatch', 'info' => "The new file extension doesn't match its type"),
+ 'actionthrottledtext' => array( 'code' => 'ratelimited', 'info' => "You've exceeded your rate limit. Please wait some time and try again" ),
+ 'alreadyrolled' => array( 'code' => 'alreadyrolled', 'info' => "The page you tried to rollback was already rolled back" ),
+ 'cantrollback' => array( 'code' => 'onlyauthor', 'info' => "The page you tried to rollback only has one author" ),
+ 'readonlytext' => array( 'code' => 'readonly', 'info' => "The wiki is currently in read-only mode" ),
+ 'sessionfailure' => array( 'code' => 'badtoken', 'info' => "Invalid token" ),
+ 'cannotdelete' => array( 'code' => 'cantdelete', 'info' => "Couldn't delete ``\$1''. Maybe it was deleted already by someone else" ),
+ 'notanarticle' => array( 'code' => 'missingtitle', 'info' => "The page you requested doesn't exist" ),
+ 'selfmove' => array( 'code' => 'selfmove', 'info' => "Can't move a page to itself" ),
+ 'immobile_namespace' => array( 'code' => 'immobilenamespace', 'info' => "You tried to move pages from or to a namespace that is protected from moving" ),
+ 'articleexists' => array( 'code' => 'articleexists', 'info' => "The destination article already exists and is not a redirect to the source article" ),
+ 'protectedpage' => array( 'code' => 'protectedpage', 'info' => "You don't have permission to perform this move" ),
+ 'hookaborted' => array( 'code' => 'hookaborted', 'info' => "The modification you tried to make was aborted by an extension hook" ),
+ 'cantmove-titleprotected' => array( 'code' => 'protectedtitle', 'info' => "The destination article has been protected from creation" ),
+ 'imagenocrossnamespace' => array( 'code' => 'nonfilenamespace', 'info' => "Can't move a file to a non-file namespace" ),
+ 'imagetypemismatch' => array( 'code' => 'filetypemismatch', 'info' => "The new file extension doesn't match its type" ),
// 'badarticleerror' => shouldn't happen
// 'badtitletext' => shouldn't happen
- 'ip_range_invalid' => array('code' => 'invalidrange', 'info' => "Invalid IP range"),
- 'range_block_disabled' => array('code' => 'rangedisabled', 'info' => "Blocking IP ranges has been disabled"),
- 'nosuchusershort' => array('code' => 'nosuchuser', 'info' => "The user you specified doesn't exist"),
- 'badipaddress' => array('code' => 'invalidip', 'info' => "Invalid IP address specified"),
- 'ipb_expiry_invalid' => array('code' => 'invalidexpiry', 'info' => "Invalid expiry time"),
- 'ipb_already_blocked' => array('code' => 'alreadyblocked', 'info' => "The user you tried to block was already blocked"),
- 'ipb_blocked_as_range' => array('code' => 'blockedasrange', 'info' => "IP address ``\$1'' was blocked as part of range ``\$2''. You can't unblock the IP invidually, but you can unblock the range as a whole."),
- 'ipb_cant_unblock' => array('code' => 'cantunblock', 'info' => "The block you specified was not found. It may have been unblocked already"),
- 'mailnologin' => array('code' => 'cantsend', 'info' => "You're not logged in or you don't have a confirmed e-mail address, so you can't send e-mail"),
- 'usermaildisabled' => array('code' => 'usermaildisabled', 'info' => "User email has been disabled"),
- 'blockedemailuser' => array('code' => 'blockedfrommail', 'info' => "You have been blocked from sending e-mail"),
- 'notarget' => array('code' => 'notarget', 'info' => "You have not specified a valid target for this action"),
- 'noemail' => array('code' => 'noemail', 'info' => "The user has not specified a valid e-mail address, or has chosen not to receive e-mail from other users"),
- 'rcpatroldisabled' => array('code' => 'patroldisabled', 'info' => "Patrolling is disabled on this wiki"),
- 'markedaspatrollederror-noautopatrol' => array('code' => 'noautopatrol', 'info' => "You don't have permission to patrol your own changes"),
- 'delete-toobig' => array('code' => 'bigdelete', 'info' => "You can't delete this page because it has more than \$1 revisions"),
- 'movenotallowedfile' => array('code' => 'cantmovefile', 'info' => "You don't have permission to move files"),
+ 'ip_range_invalid' => array( 'code' => 'invalidrange', 'info' => "Invalid IP range" ),
+ 'range_block_disabled' => array( 'code' => 'rangedisabled', 'info' => "Blocking IP ranges has been disabled" ),
+ 'nosuchusershort' => array( 'code' => 'nosuchuser', 'info' => "The user you specified doesn't exist" ),
+ 'badipaddress' => array( 'code' => 'invalidip', 'info' => "Invalid IP address specified" ),
+ 'ipb_expiry_invalid' => array( 'code' => 'invalidexpiry', 'info' => "Invalid expiry time" ),
+ 'ipb_already_blocked' => array( 'code' => 'alreadyblocked', 'info' => "The user you tried to block was already blocked" ),
+ 'ipb_blocked_as_range' => array( 'code' => 'blockedasrange', 'info' => "IP address ``\$1'' was blocked as part of range ``\$2''. You can't unblock the IP invidually, but you can unblock the range as a whole." ),
+ 'ipb_cant_unblock' => array( 'code' => 'cantunblock', 'info' => "The block you specified was not found. It may have been unblocked already" ),
+ 'mailnologin' => array( 'code' => 'cantsend', 'info' => "You are not logged in, you do not have a confirmed e-mail address, or you are not allowed to send e-mail to other users, so you cannot send e-mail" ),
+ 'usermaildisabled' => array( 'code' => 'usermaildisabled', 'info' => "User email has been disabled" ),
+ 'blockedemailuser' => array( 'code' => 'blockedfrommail', 'info' => "You have been blocked from sending e-mail" ),
+ 'notarget' => array( 'code' => 'notarget', 'info' => "You have not specified a valid target for this action" ),
+ 'noemail' => array( 'code' => 'noemail', 'info' => "The user has not specified a valid e-mail address, or has chosen not to receive e-mail from other users" ),
+ 'rcpatroldisabled' => array( 'code' => 'patroldisabled', 'info' => "Patrolling is disabled on this wiki" ),
+ 'markedaspatrollederror-noautopatrol' => array( 'code' => 'noautopatrol', 'info' => "You don't have permission to patrol your own changes" ),
+ 'delete-toobig' => array( 'code' => 'bigdelete', 'info' => "You can't delete this page because it has more than \$1 revisions" ),
+ 'movenotallowedfile' => array( 'code' => 'cantmovefile', 'info' => "You don't have permission to move files" ),
+ 'userrights-no-interwiki' => array( 'code' => 'nointerwikiuserrights', 'info' => "You don't have permission to change user rights on other wikis" ),
+ 'userrights-nodatabase' => array( 'code' => 'nosuchdatabase', 'info' => "Database ``\$1'' does not exist or is not local" ),
+ 'nouserspecified' => array( 'code' => 'invaliduser', 'info' => "Invalid username ``\$1''" ),
+ 'noname' => array( 'code' => 'invaliduser', 'info' => "Invalid username ``\$1''" ),
// API-specific messages
- 'readrequired' => array('code' => 'readapidenied', 'info' => "You need read permission to use this module"),
- 'writedisabled' => array('code' => 'noapiwrite', 'info' => "Editing of this wiki through the API is disabled. Make sure the \$wgEnableWriteAPI=true; statement is included in the wiki's LocalSettings.php file"),
- 'writerequired' => array('code' => 'writeapidenied', 'info' => "You're not allowed to edit this wiki through the API"),
- 'missingparam' => array('code' => 'no$1', 'info' => "The \$1 parameter must be set"),
- 'invalidtitle' => array('code' => 'invalidtitle', 'info' => "Bad title ``\$1''"),
- 'nosuchpageid' => array('code' => 'nosuchpageid', 'info' => "There is no page with ID \$1"),
- 'nosuchrevid' => array('code' => 'nosuchrevid', 'info' => "There is no revision with ID \$1"),
- 'invaliduser' => array('code' => 'invaliduser', 'info' => "Invalid username ``\$1''"),
- 'invalidexpiry' => array('code' => 'invalidexpiry', 'info' => "Invalid expiry time ``\$1''"),
- 'pastexpiry' => array('code' => 'pastexpiry', 'info' => "Expiry time ``\$1'' is in the past"),
- 'create-titleexists' => array('code' => 'create-titleexists', 'info' => "Existing titles can't be protected with 'create'"),
- 'missingtitle-createonly' => array('code' => 'missingtitle-createonly', 'info' => "Missing titles can only be protected with 'create'"),
- 'cantblock' => array('code' => 'cantblock', 'info' => "You don't have permission to block users"),
- 'canthide' => array('code' => 'canthide', 'info' => "You don't have permission to hide user names from the block log"),
- 'cantblock-email' => array('code' => 'cantblock-email', 'info' => "You don't have permission to block users from sending e-mail through the wiki"),
- 'unblock-notarget' => array('code' => 'notarget', 'info' => "Either the id or the user parameter must be set"),
- 'unblock-idanduser' => array('code' => 'idanduser', 'info' => "The id and user parameters can't be used together"),
- 'cantunblock' => array('code' => 'permissiondenied', 'info' => "You don't have permission to unblock users"),
- 'cannotundelete' => array('code' => 'cantundelete', 'info' => "Couldn't undelete: the requested revisions may not exist, or may have been undeleted already"),
- 'permdenied-undelete' => array('code' => 'permissiondenied', 'info' => "You don't have permission to restore deleted revisions"),
- 'createonly-exists' => array('code' => 'articleexists', 'info' => "The article you tried to create has been created already"),
- 'nocreate-missing' => array('code' => 'missingtitle', 'info' => "The article you tried to edit doesn't exist"),
- 'nosuchrcid' => array('code' => 'nosuchrcid', 'info' => "There is no change with rcid ``\$1''"),
- 'cantpurge' => array('code' => 'cantpurge', 'info' => "Only users with the 'purge' right can purge pages via the API"),
- 'protect-invalidaction' => array('code' => 'protect-invalidaction', 'info' => "Invalid protection type ``\$1''"),
- 'protect-invalidlevel' => array('code' => 'protect-invalidlevel', 'info' => "Invalid protection level ``\$1''"),
- 'toofewexpiries' => array('code' => 'toofewexpiries', 'info' => "\$1 expiry timestamps were provided where \$2 were needed"),
- 'cantimport' => array('code' => 'cantimport', 'info' => "You don't have permission to import pages"),
- 'cantimport-upload' => array('code' => 'cantimport-upload', 'info' => "You don't have permission to import uploaded pages"),
- 'importnofile' => array('code' => 'nofile', 'info' => "You didn't upload a file"),
- 'importuploaderrorsize' => array('code' => 'filetoobig', 'info' => 'The file you uploaded is bigger than the maximum upload size'),
- 'importuploaderrorpartial' => array('code' => 'partialupload', 'info' => 'The file was only partially uploaded'),
- 'importuploaderrortemp' => array('code' => 'notempdir', 'info' => 'The temporary upload directory is missing'),
- 'importcantopen' => array('code' => 'cantopenfile', 'info' => "Couldn't open the uploaded file"),
- 'import-noarticle' => array('code' => 'badinterwiki', 'info' => 'Invalid interwiki title specified'),
- 'importbadinterwiki' => array('code' => 'badinterwiki', 'info' => 'Invalid interwiki title specified'),
- 'import-unknownerror' => array('code' => 'import-unknownerror', 'info' => "Unknown error on import: ``\$1''"),
+ 'readrequired' => array( 'code' => 'readapidenied', 'info' => "You need read permission to use this module" ),
+ 'writedisabled' => array( 'code' => 'noapiwrite', 'info' => "Editing of this wiki through the API is disabled. Make sure the \$wgEnableWriteAPI=true; statement is included in the wiki's LocalSettings.php file" ),
+ 'writerequired' => array( 'code' => 'writeapidenied', 'info' => "You're not allowed to edit this wiki through the API" ),
+ 'missingparam' => array( 'code' => 'no$1', 'info' => "The \$1 parameter must be set" ),
+ 'invalidtitle' => array( 'code' => 'invalidtitle', 'info' => "Bad title ``\$1''" ),
+ 'nosuchpageid' => array( 'code' => 'nosuchpageid', 'info' => "There is no page with ID \$1" ),
+ 'nosuchrevid' => array( 'code' => 'nosuchrevid', 'info' => "There is no revision with ID \$1" ),
+ 'nosuchuser' => array( 'code' => 'nosuchuser', 'info' => "User ``\$1'' doesn't exist" ),
+ 'invaliduser' => array( 'code' => 'invaliduser', 'info' => "Invalid username ``\$1''" ),
+ 'invalidexpiry' => array( 'code' => 'invalidexpiry', 'info' => "Invalid expiry time ``\$1''" ),
+ 'pastexpiry' => array( 'code' => 'pastexpiry', 'info' => "Expiry time ``\$1'' is in the past" ),
+ 'create-titleexists' => array( 'code' => 'create-titleexists', 'info' => "Existing titles can't be protected with 'create'" ),
+ 'missingtitle-createonly' => array( 'code' => 'missingtitle-createonly', 'info' => "Missing titles can only be protected with 'create'" ),
+ 'cantblock' => array( 'code' => 'cantblock', 'info' => "You don't have permission to block users" ),
+ 'canthide' => array( 'code' => 'canthide', 'info' => "You don't have permission to hide user names from the block log" ),
+ 'cantblock-email' => array( 'code' => 'cantblock-email', 'info' => "You don't have permission to block users from sending e-mail through the wiki" ),
+ 'unblock-notarget' => array( 'code' => 'notarget', 'info' => "Either the id or the user parameter must be set" ),
+ 'unblock-idanduser' => array( 'code' => 'idanduser', 'info' => "The id and user parameters can't be used together" ),
+ 'cantunblock' => array( 'code' => 'permissiondenied', 'info' => "You don't have permission to unblock users" ),
+ 'cannotundelete' => array( 'code' => 'cantundelete', 'info' => "Couldn't undelete: the requested revisions may not exist, or may have been undeleted already" ),
+ 'permdenied-undelete' => array( 'code' => 'permissiondenied', 'info' => "You don't have permission to restore deleted revisions" ),
+ 'createonly-exists' => array( 'code' => 'articleexists', 'info' => "The article you tried to create has been created already" ),
+ 'nocreate-missing' => array( 'code' => 'missingtitle', 'info' => "The article you tried to edit doesn't exist" ),
+ 'nosuchrcid' => array( 'code' => 'nosuchrcid', 'info' => "There is no change with rcid ``\$1''" ),
+ 'cantpurge' => array( 'code' => 'cantpurge', 'info' => "Only users with the 'purge' right can purge pages via the API" ),
+ 'protect-invalidaction' => array( 'code' => 'protect-invalidaction', 'info' => "Invalid protection type ``\$1''" ),
+ 'protect-invalidlevel' => array( 'code' => 'protect-invalidlevel', 'info' => "Invalid protection level ``\$1''" ),
+ 'toofewexpiries' => array( 'code' => 'toofewexpiries', 'info' => "\$1 expiry timestamps were provided where \$2 were needed" ),
+ 'cantimport' => array( 'code' => 'cantimport', 'info' => "You don't have permission to import pages" ),
+ 'cantimport-upload' => array( 'code' => 'cantimport-upload', 'info' => "You don't have permission to import uploaded pages" ),
+ 'nouploadmodule' => array( 'code' => 'nomodule', 'info' => 'No upload module set' ),
+ 'importnofile' => array( 'code' => 'nofile', 'info' => "You didn't upload a file" ),
+ 'importuploaderrorsize' => array( 'code' => 'filetoobig', 'info' => 'The file you uploaded is bigger than the maximum upload size' ),
+ 'importuploaderrorpartial' => array( 'code' => 'partialupload', 'info' => 'The file was only partially uploaded' ),
+ 'importuploaderrortemp' => array( 'code' => 'notempdir', 'info' => 'The temporary upload directory is missing' ),
+ 'importcantopen' => array( 'code' => 'cantopenfile', 'info' => "Couldn't open the uploaded file" ),
+ 'import-noarticle' => array( 'code' => 'badinterwiki', 'info' => 'Invalid interwiki title specified' ),
+ 'importbadinterwiki' => array( 'code' => 'badinterwiki', 'info' => 'Invalid interwiki title specified' ),
+ 'import-unknownerror' => array( 'code' => 'import-unknownerror', 'info' => "Unknown error on import: ``\$1''" ),
+ 'cantoverwrite-sharedfile' => array( 'code' => 'cantoverwrite-sharedfile', 'info' => 'The target file exists on a shared repository and you do not have permission to override it' ),
+ 'sharedfile-exists' => array( 'code' => 'fileexists-sharedrepo-perm', 'info' => 'The target file exists on a shared repository. Use the ignorewarnings parameter to override it.' ),
+ 'mustbeposted' => array( 'code' => 'mustbeposted', 'info' => "The \$1 module requires a POST request" ),
+ 'show' => array( 'code' => 'show', 'info' => 'Incorrect parameter - mutually exclusive values may not be supplied' ),
// ApiEditPage messages
- 'noimageredirect-anon' => array('code' => 'noimageredirect-anon', 'info' => "Anonymous users can't create image redirects"),
- 'noimageredirect-logged' => array('code' => 'noimageredirect', 'info' => "You don't have permission to create image redirects"),
- 'spamdetected' => array('code' => 'spamdetected', 'info' => "Your edit was refused because it contained a spam fragment: ``\$1''"),
- 'filtered' => array('code' => 'filtered', 'info' => "The filter callback function refused your edit"),
- 'contenttoobig' => array('code' => 'contenttoobig', 'info' => "The content you supplied exceeds the article size limit of \$1 kilobytes"),
- 'noedit-anon' => array('code' => 'noedit-anon', 'info' => "Anonymous users can't edit pages"),
- 'noedit' => array('code' => 'noedit', 'info' => "You don't have permission to edit pages"),
- 'wasdeleted' => array('code' => 'pagedeleted', 'info' => "The page has been deleted since you fetched its timestamp"),
- 'blankpage' => array('code' => 'emptypage', 'info' => "Creating new, empty pages is not allowed"),
- 'editconflict' => array('code' => 'editconflict', 'info' => "Edit conflict detected"),
- 'hashcheckfailed' => array('code' => 'badmd5', 'info' => "The supplied MD5 hash was incorrect"),
- 'missingtext' => array('code' => 'notext', 'info' => "One of the text, appendtext, prependtext and undo parameters must be set"),
- 'emptynewsection' => array('code' => 'emptynewsection', 'info' => 'Creating empty new sections is not possible.'),
- 'revwrongpage' => array('code' => 'revwrongpage', 'info' => "r\$1 is not a revision of ``\$2''"),
- 'undo-failure' => array('code' => 'undofailure', 'info' => 'Undo failed due to conflicting intermediate edits'),
+ 'noimageredirect-anon' => array( 'code' => 'noimageredirect-anon', 'info' => "Anonymous users can't create image redirects" ),
+ 'noimageredirect-logged' => array( 'code' => 'noimageredirect', 'info' => "You don't have permission to create image redirects" ),
+ 'spamdetected' => array( 'code' => 'spamdetected', 'info' => "Your edit was refused because it contained a spam fragment: ``\$1''" ),
+ 'filtered' => array( 'code' => 'filtered', 'info' => "The filter callback function refused your edit" ),
+ 'contenttoobig' => array( 'code' => 'contenttoobig', 'info' => "The content you supplied exceeds the article size limit of \$1 kilobytes" ),
+ 'noedit-anon' => array( 'code' => 'noedit-anon', 'info' => "Anonymous users can't edit pages" ),
+ 'noedit' => array( 'code' => 'noedit', 'info' => "You don't have permission to edit pages" ),
+ 'wasdeleted' => array( 'code' => 'pagedeleted', 'info' => "The page has been deleted since you fetched its timestamp" ),
+ 'blankpage' => array( 'code' => 'emptypage', 'info' => "Creating new, empty pages is not allowed" ),
+ 'editconflict' => array( 'code' => 'editconflict', 'info' => "Edit conflict detected" ),
+ 'hashcheckfailed' => array( 'code' => 'badmd5', 'info' => "The supplied MD5 hash was incorrect" ),
+ 'missingtext' => array( 'code' => 'notext', 'info' => "One of the text, appendtext, prependtext and undo parameters must be set" ),
+ 'emptynewsection' => array( 'code' => 'emptynewsection', 'info' => 'Creating empty new sections is not possible.' ),
+ 'revwrongpage' => array( 'code' => 'revwrongpage', 'info' => "r\$1 is not a revision of ``\$2''" ),
+ 'undo-failure' => array( 'code' => 'undofailure', 'info' => 'Undo failed due to conflicting intermediate edits' ),
+
+ // uploadMsgs
+ 'invalid-session-key' => array( 'code' => 'invalid-session-key', 'info' => 'Not a valid session key' ),
+ 'nouploadmodule' => array( 'code' => 'nouploadmodule', 'info' => 'No upload module set' ),
+ 'uploaddisabled' => array( 'code' => 'uploaddisabled', 'info' => 'Uploads are not enabled. Make sure $wgEnableUploads is set to true in LocalSettings.php and the PHP ini setting file_uploads is true' ),
);
/**
+ * Helper function for readonly errors
+ */
+ public function dieReadOnly() {
+ $parsed = $this->parseMsg( array( 'readonlytext' ) );
+ $this->dieUsage( $parsed['info'], $parsed['code'], /* http error */ 0,
+ array( 'readonlyreason' => wfReadOnlyReason() ) );
+ }
+
+ /**
* Output the error message related to a certain array
* @param $error array Element of a getUserPermissionsErrors()-style array
*/
- public function dieUsageMsg($error) {
- $parsed = $this->parseMsg($error);
- $this->dieUsage($parsed['info'], $parsed['code']);
+ public function dieUsageMsg( $error ) {
+ $parsed = $this->parseMsg( $error );
+ $this->dieUsage( $parsed['info'], $parsed['code'] );
}
-
+
/**
* Return the error message related to a certain array
* @param $error array Element of a getUserPermissionsErrors()-style array
* @return array('code' => code, 'info' => info)
*/
- public function parseMsg($error) {
- $key = array_shift($error);
- if(isset(self::$messageMap[$key]))
- return array( 'code' =>
- wfMsgReplaceArgs(self::$messageMap[$key]['code'], $error),
+ public function parseMsg( $error ) {
+ $key = array_shift( $error );
+ if ( isset( self::$messageMap[$key] ) ) {
+ return array( 'code' =>
+ wfMsgReplaceArgs( self::$messageMap[$key]['code'], $error ),
'info' =>
- wfMsgReplaceArgs(self::$messageMap[$key]['info'], $error)
+ wfMsgReplaceArgs( self::$messageMap[$key]['info'], $error )
);
+ }
// If the key isn't present, throw an "unknown error"
- return $this->parseMsg(array('unknownerror', $key));
+ return $this->parseMsg( array( 'unknownerror', $key ) );
}
/**
@@ -852,8 +970,8 @@ abstract class ApiBase {
* @param $method string Method or function name
* @param $message string Error message
*/
- protected static function dieDebug($method, $message) {
- wfDebugDieBacktrace("Internal error in $method: $message");
+ protected static function dieDebug( $method, $message ) {
+ wfDebugDieBacktrace( "Internal error in $method: $message" );
}
/**
@@ -887,6 +1005,59 @@ abstract class ApiBase {
return false;
}
+ /**
+ * Returns the token salt if there is one, '' if the module doesn't require a salt, else false if the module doesn't need a token
+ * @returns bool
+ */
+ public function getTokenSalt() {
+ return false;
+ }
+
+ /**
+ * Returns a list of all possible errors returned by the module
+ * @return array in the format of array( key, param1, param2, ... ) or array( 'code' => ..., 'info' => ... )
+ */
+ public function getPossibleErrors() {
+ $ret = array();
+
+ if ( $this->mustBePosted() ) {
+ $ret[] = array( 'mustbeposted', $this->getModuleName() );
+ }
+
+ if ( $this->isReadMode() ) {
+ $ret[] = array( 'readrequired' );
+ }
+
+ if ( $this->isWriteMode() ) {
+ $ret[] = array( 'writerequired' );
+ $ret[] = array( 'writedisabled' );
+ }
+
+ if ( $this->getTokenSalt() !== false ) {
+ $ret[] = array( 'missingparam', 'token' );
+ $ret[] = array( 'sessionfailure' );
+ }
+
+ return $ret;
+ }
+
+ /**
+ * Parses a list of errors into a standardised format
+ * @param $errors array List of errors. Items can be in the for array( key, param1, param2, ... ) or array( 'code' => ..., 'info' => ... )
+ * @return array Parsed list of errors with items in the form array( 'code' => ..., 'info' => ... )
+ */
+ public function parseErrors( $errors ) {
+ $ret = array();
+
+ foreach ( $errors as $row ) {
+ if ( isset( $row['code'] ) && isset( $row['info'] ) ) {
+ $ret[] = $row;
+ } else {
+ $ret[] = $this->parseMsg( $row );
+ }
+ }
+ return $ret;
+ }
/**
* Profiling: total module execution time
@@ -897,24 +1068,27 @@ abstract class ApiBase {
* Start module profiling
*/
public function profileIn() {
- if ($this->mTimeIn !== 0)
- ApiBase :: dieDebug(__METHOD__, 'called twice without calling profileOut()');
- $this->mTimeIn = microtime(true);
- wfProfileIn($this->getModuleProfileName());
+ if ( $this->mTimeIn !== 0 ) {
+ ApiBase::dieDebug( __METHOD__, 'called twice without calling profileOut()' );
+ }
+ $this->mTimeIn = microtime( true );
+ wfProfileIn( $this->getModuleProfileName() );
}
/**
* End module profiling
*/
public function profileOut() {
- if ($this->mTimeIn === 0)
- ApiBase :: dieDebug(__METHOD__, 'called without calling profileIn() first');
- if ($this->mDBTimeIn !== 0)
- ApiBase :: dieDebug(__METHOD__, 'must be called after database profiling is done with profileDBOut()');
+ if ( $this->mTimeIn === 0 ) {
+ ApiBase::dieDebug( __METHOD__, 'called without calling profileIn() first' );
+ }
+ if ( $this->mDBTimeIn !== 0 ) {
+ ApiBase::dieDebug( __METHOD__, 'must be called after database profiling is done with profileDBOut()' );
+ }
- $this->mModuleTime += microtime(true) - $this->mTimeIn;
+ $this->mModuleTime += microtime( true ) - $this->mTimeIn;
$this->mTimeIn = 0;
- wfProfileOut($this->getModuleProfileName());
+ wfProfileOut( $this->getModuleProfileName() );
}
/**
@@ -922,9 +1096,10 @@ abstract class ApiBase {
* of the profiling state the module was in. This method does such cleanup.
*/
public function safeProfileOut() {
- if ($this->mTimeIn !== 0) {
- if ($this->mDBTimeIn !== 0)
+ if ( $this->mTimeIn !== 0 ) {
+ if ( $this->mDBTimeIn !== 0 ) {
$this->profileDBOut();
+ }
$this->profileOut();
}
}
@@ -934,8 +1109,9 @@ abstract class ApiBase {
* @return float
*/
public function getProfileTime() {
- if ($this->mTimeIn !== 0)
- ApiBase :: dieDebug(__METHOD__, 'called without calling profileOut() first');
+ if ( $this->mTimeIn !== 0 ) {
+ ApiBase::dieDebug( __METHOD__, 'called without calling profileOut() first' );
+ }
return $this->mModuleTime;
}
@@ -948,29 +1124,33 @@ abstract class ApiBase {
* Start module profiling
*/
public function profileDBIn() {
- if ($this->mTimeIn === 0)
- ApiBase :: dieDebug(__METHOD__, 'must be called while profiling the entire module with profileIn()');
- if ($this->mDBTimeIn !== 0)
- ApiBase :: dieDebug(__METHOD__, 'called twice without calling profileDBOut()');
- $this->mDBTimeIn = microtime(true);
- wfProfileIn($this->getModuleProfileName(true));
+ if ( $this->mTimeIn === 0 ) {
+ ApiBase::dieDebug( __METHOD__, 'must be called while profiling the entire module with profileIn()' );
+ }
+ if ( $this->mDBTimeIn !== 0 ) {
+ ApiBase::dieDebug( __METHOD__, 'called twice without calling profileDBOut()' );
+ }
+ $this->mDBTimeIn = microtime( true );
+ wfProfileIn( $this->getModuleProfileName( true ) );
}
/**
* End database profiling
*/
public function profileDBOut() {
- if ($this->mTimeIn === 0)
- ApiBase :: dieDebug(__METHOD__, 'must be called while profiling the entire module with profileIn()');
- if ($this->mDBTimeIn === 0)
- ApiBase :: dieDebug(__METHOD__, 'called without calling profileDBIn() first');
+ if ( $this->mTimeIn === 0 ) {
+ ApiBase::dieDebug( __METHOD__, 'must be called while profiling the entire module with profileIn()' );
+ }
+ if ( $this->mDBTimeIn === 0 ) {
+ ApiBase::dieDebug( __METHOD__, 'called without calling profileDBIn() first' );
+ }
- $time = microtime(true) - $this->mDBTimeIn;
+ $time = microtime( true ) - $this->mDBTimeIn;
$this->mDBTimeIn = 0;
$this->mDBTime += $time;
$this->getMain()->mDBTime += $time;
- wfProfileOut($this->getModuleProfileName(true));
+ wfProfileOut( $this->getModuleProfileName( true ) );
}
/**
@@ -978,8 +1158,9 @@ abstract class ApiBase {
* @return float
*/
public function getProfileDBTime() {
- if ($this->mDBTimeIn !== 0)
- ApiBase :: dieDebug(__METHOD__, 'called without calling profileDBOut() first');
+ if ( $this->mDBTimeIn !== 0 ) {
+ ApiBase::dieDebug( __METHOD__, 'called without calling profileDBOut() first' );
+ }
return $this->mDBTime;
}
@@ -989,20 +1170,20 @@ abstract class ApiBase {
* @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) {
+ public static function debugPrint( $value, $name = 'unknown', $backtrace = false ) {
print "\n\n<pre><b>Debugging value '$name':</b>\n\n";
- var_export($value);
- if ($backtrace)
+ var_export( $value );
+ if ( $backtrace ) {
print "\n" . wfBacktrace();
+ }
print "\n</pre>\n";
}
-
/**
* Returns a string that identifies the version of this class.
* @return string
*/
public static function getBaseVersion() {
- return __CLASS__ . ': $Id: ApiBase.php 50217 2009-05-05 13:12:16Z tstarling $';
+ return __CLASS__ . ': $Id: ApiBase.php 70066 2010-07-28 05:52:32Z tstarling $';
}
}
diff --git a/includes/api/ApiBlock.php b/includes/api/ApiBlock.php
index 1c0bd5ac..91bbaf6d 100644
--- a/includes/api/ApiBlock.php
+++ b/includes/api/ApiBlock.php
@@ -1,10 +1,10 @@
<?php
-/*
+/**
* Created on Sep 4, 2007
* API for MediaWiki 1.8+
*
- * Copyright (C) 2007 Roan Kattouw <Firstname>.<Lastname>@home.nl
+ * Copyright © 2007 Roan Kattouw <Firstname>.<Lastname>@home.nl
*
* 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
@@ -22,9 +22,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ("ApiBase.php");
+ require_once( "ApiBase.php" );
}
/**
@@ -38,8 +38,8 @@ class ApiBlock extends ApiBase {
/**
* Std ctor.
*/
- public function __construct($main, $action) {
- parent :: __construct($main, $action);
+ public function __construct( $main, $action ) {
+ parent::__construct( $main, $action );
}
/**
@@ -52,31 +52,30 @@ class ApiBlock extends ApiBase {
global $wgUser, $wgBlockAllowsUTEdit;
$params = $this->extractRequestParams();
- if($params['gettoken'])
- {
+ if ( $params['gettoken'] ) {
$res['blocktoken'] = $wgUser->editToken();
- $this->getResult()->addValue(null, $this->getModuleName(), $res);
+ $this->getResult()->addValue( null, $this->getModuleName(), $res );
return;
}
- if(is_null($params['user']))
- $this->dieUsageMsg(array('missingparam', 'user'));
- if(is_null($params['token']))
- $this->dieUsageMsg(array('missingparam', 'token'));
- if(!$wgUser->matchEditToken($params['token']))
- $this->dieUsageMsg(array('sessionfailure'));
- if(!$wgUser->isAllowed('block'))
- $this->dieUsageMsg(array('cantblock'));
- if($params['hidename'] && !$wgUser->isAllowed('hideuser'))
- $this->dieUsageMsg(array('canthide'));
- if($params['noemail'] && !$wgUser->isAllowed('blockemail'))
- $this->dieUsageMsg(array('cantblock-email'));
-
- $form = new IPBlockForm('');
+ if ( is_null( $params['user'] ) ) {
+ $this->dieUsageMsg( array( 'missingparam', 'user' ) );
+ }
+ if ( !$wgUser->isAllowed( 'block' ) ) {
+ $this->dieUsageMsg( array( 'cantblock' ) );
+ }
+ if ( $params['hidename'] && !$wgUser->isAllowed( 'hideuser' ) ) {
+ $this->dieUsageMsg( array( 'canthide' ) );
+ }
+ if ( $params['noemail'] && !IPBlockForm::canBlockEmail( $wgUser ) ) {
+ $this->dieUsageMsg( array( 'cantblock-email' ) );
+ }
+
+ $form = new IPBlockForm( '' );
$form->BlockAddress = $params['user'];
- $form->BlockReason = (is_null($params['reason']) ? '' : $params['reason']);
+ $form->BlockReason = ( is_null( $params['reason'] ) ? '' : $params['reason'] );
$form->BlockReasonList = 'other';
- $form->BlockExpiry = ($params['expiry'] == 'never' ? 'infinite' : $params['expiry']);
+ $form->BlockExpiry = ( $params['expiry'] == 'never' ? 'infinite' : $params['expiry'] );
$form->BlockOther = '';
$form->BlockAnonOnly = $params['anononly'];
$form->BlockCreateAccount = $params['nocreate'];
@@ -87,39 +86,48 @@ class ApiBlock extends ApiBase {
$form->BlockReblock = $params['reblock'];
$userID = $expiry = null;
- $retval = $form->doBlock($userID, $expiry);
- if(count($retval))
+ $retval = $form->doBlock( $userID, $expiry );
+ if ( count( $retval ) ) {
// We don't care about multiple errors, just report one of them
- $this->dieUsageMsg($retval);
+ $this->dieUsageMsg( $retval );
+ }
$res['user'] = $params['user'];
- $res['userID'] = intval($userID);
- $res['expiry'] = ($expiry == Block::infinity() ? 'infinite' : wfTimestamp(TS_ISO_8601, $expiry));
+ $res['userID'] = intval( $userID );
+ $res['expiry'] = ( $expiry == Block::infinity() ? 'infinite' : wfTimestamp( TS_ISO_8601, $expiry ) );
$res['reason'] = $params['reason'];
- if($params['anononly'])
+ if ( $params['anononly'] ) {
$res['anononly'] = '';
- if($params['nocreate'])
+ }
+ if ( $params['nocreate'] ) {
$res['nocreate'] = '';
- if($params['autoblock'])
+ }
+ if ( $params['autoblock'] ) {
$res['autoblock'] = '';
- if($params['noemail'])
+ }
+ if ( $params['noemail'] ) {
$res['noemail'] = '';
- if($params['hidename'])
+ }
+ if ( $params['hidename'] ) {
$res['hidename'] = '';
- if($params['allowusertalk'])
+ }
+ if ( $params['allowusertalk'] ) {
$res['allowusertalk'] = '';
+ }
- $this->getResult()->addValue(null, $this->getModuleName(), $res);
+ $this->getResult()->addValue( null, $this->getModuleName(), $res );
}
- public function mustBePosted() { return true; }
+ public function mustBePosted() {
+ return true;
+ }
public function isWriteMode() {
return true;
}
public function getAllowedParams() {
- return array (
+ return array(
'user' => null,
'token' => null,
'gettoken' => false,
@@ -136,7 +144,7 @@ class ApiBlock extends ApiBase {
}
public function getParamDescription() {
- return array (
+ return array(
'user' => 'Username, IP address or IP range you want to block',
'token' => 'A block token previously obtained through the gettoken parameter or prop=info',
'gettoken' => 'If set, a block token will be returned, and no other action will be taken',
@@ -157,15 +165,28 @@ class ApiBlock extends ApiBase {
'Block a user.'
);
}
+
+ public function getPossibleErrors() {
+ return array_merge( parent::getPossibleErrors(), array(
+ array( 'missingparam', 'user' ),
+ array( 'cantblock' ),
+ array( 'canthide' ),
+ array( 'cantblock-email' ),
+ ) );
+ }
+
+ public function getTokenSalt() {
+ return '';
+ }
protected function getExamples() {
- return array (
+ return array(
'api.php?action=block&user=123.5.5.12&expiry=3%20days&reason=First%20strike',
'api.php?action=block&user=Vandal&expiry=never&reason=Vandalism&nocreate&autoblock&noemail'
);
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiBlock.php 48091 2009-03-06 13:49:44Z catrope $';
+ return __CLASS__ . ': $Id: ApiBlock.php 62766 2010-02-21 12:32:46Z ashley $';
}
}
diff --git a/includes/api/ApiDelete.php b/includes/api/ApiDelete.php
index 9431ad78..2b349bd7 100644
--- a/includes/api/ApiDelete.php
+++ b/includes/api/ApiDelete.php
@@ -1,10 +1,10 @@
<?php
-/*
+/**
* Created on Jun 30, 2007
* API for MediaWiki 1.8+
*
- * Copyright (C) 2007 Roan Kattouw <Firstname>.<Lastname>@home.nl
+ * Copyright © 2007 Roan Kattouw <Firstname>.<Lastname>@home.nl
*
* 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
@@ -22,12 +22,11 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ("ApiBase.php");
+ require_once( "ApiBase.php" );
}
-
/**
* API module that facilitates deleting pages. The API eqivalent of action=delete.
* Requires API write mode to be enabled.
@@ -36,8 +35,8 @@ if (!defined('MEDIAWIKI')) {
*/
class ApiDelete extends ApiBase {
- public function __construct($main, $action) {
- parent :: __construct($main, $action);
+ public function __construct( $main, $action ) {
+ parent::__construct( $main, $action );
}
/**
@@ -49,65 +48,60 @@ class ApiDelete extends ApiBase {
*/
public function execute() {
global $wgUser;
+
$params = $this->extractRequestParams();
- $this->requireOnlyOneParameter($params, 'title', 'pageid');
- if(!isset($params['token']))
- $this->dieUsageMsg(array('missingparam', 'token'));
+ $this->requireOnlyOneParameter( $params, 'title', 'pageid' );
- if(isset($params['title']))
- {
- $titleObj = Title::newFromText($params['title']);
- if(!$titleObj)
- $this->dieUsageMsg(array('invalidtitle', $params['title']));
+ if ( isset( $params['title'] ) ) {
+ $titleObj = Title::newFromText( $params['title'] );
+ if ( !$titleObj ) {
+ $this->dieUsageMsg( array( 'invalidtitle', $params['title'] ) );
+ }
+ } elseif ( isset( $params['pageid'] ) ) {
+ $titleObj = Title::newFromID( $params['pageid'] );
+ if ( !$titleObj ) {
+ $this->dieUsageMsg( array( 'nosuchpageid', $params['pageid'] ) );
+ }
}
- else if(isset($params['pageid']))
- {
- $titleObj = Title::newFromID($params['pageid']);
- if(!$titleObj)
- $this->dieUsageMsg(array('nosuchpageid', $params['pageid']));
+ if ( !$titleObj->exists() ) {
+ $this->dieUsageMsg( array( 'notanarticle' ) );
}
- if(!$titleObj->exists())
- $this->dieUsageMsg(array('notanarticle'));
-
- $reason = (isset($params['reason']) ? $params['reason'] : NULL);
- if ($titleObj->getNamespace() == NS_FILE) {
- $retval = self::deleteFile($params['token'], $titleObj, $params['oldimage'], $reason, false);
- if(count($retval))
- // We don't care about multiple errors, just report one of them
- $this->dieUsageMsg(reset($retval));
+
+ $reason = ( isset( $params['reason'] ) ? $params['reason'] : null );
+ if ( $titleObj->getNamespace() == NS_FILE ) {
+ $retval = self::deleteFile( $params['token'], $titleObj, $params['oldimage'], $reason, false );
+ if ( count( $retval ) ) {
+ $this->dieUsageMsg( reset( $retval ) ); // We don't care about multiple errors, just report one of them
+ }
} else {
- $articleObj = new Article($titleObj);
- if($articleObj->isBigDeletion() && !$wgUser->isAllowed('bigdelete')) {
- global $wgDeleteRevisionsLimit;
- $this->dieUsageMsg(array('delete-toobig', $wgDeleteRevisionsLimit));
+ $articleObj = new Article( $titleObj );
+ $retval = self::delete( $articleObj, $params['token'], $reason );
+
+ if ( count( $retval ) ) {
+ $this->dieUsageMsg( reset( $retval ) ); // We don't care about multiple errors, just report one of them
}
- $retval = self::delete($articleObj, $params['token'], $reason);
-
- if(count($retval))
- // We don't care about multiple errors, just report one of them
- $this->dieUsageMsg(reset($retval));
-
- if($params['watch'] || $wgUser->getOption('watchdeletion'))
+
+ if ( $params['watch'] || $wgUser->getOption( 'watchdeletion' ) ) {
$articleObj->doWatch();
- else if($params['unwatch'])
+ } elseif ( $params['unwatch'] ) {
$articleObj->doUnwatch();
+ }
}
- $r = array('title' => $titleObj->getPrefixedText(), 'reason' => $reason);
- $this->getResult()->addValue(null, $this->getModuleName(), $r);
+ $r = array( 'title' => $titleObj->getPrefixedText(), 'reason' => $reason );
+ $this->getResult()->addValue( null, $this->getModuleName(), $r );
}
- private static function getPermissionsError(&$title, $token) {
+ private static function getPermissionsError( &$title, $token ) {
global $wgUser;
-
+
// Check permissions
- $errors = $title->getUserPermissionsErrors('delete', $wgUser);
- if (count($errors) > 0) return $errors;
-
- // Check token
- if(!$wgUser->matchEditToken($token))
- return array(array('sessionfailure'));
+ $errors = $title->getUserPermissionsErrors( 'delete', $wgUser );
+ if ( count( $errors ) > 0 ) {
+ return $errors;
+ }
+
return array();
}
@@ -119,70 +113,84 @@ class ApiDelete extends ApiBase {
* @param string $reason - Reason for the deletion. Autogenerated if NULL
* @return Title::getUserPermissionsErrors()-like array
*/
- public static function delete(&$article, $token, &$reason = NULL)
- {
+ public static function delete( &$article, $token, &$reason = null ) {
global $wgUser;
+ if ( $article->isBigDeletion() && !$wgUser->isAllowed( 'bigdelete' ) ) {
+ global $wgDeleteRevisionsLimit;
+ return array( array( 'delete-toobig', $wgDeleteRevisionsLimit ) );
+ }
$title = $article->getTitle();
- $errors = self::getPermissionsError($title, $token);
- if (count($errors)) return $errors;
+ $errors = self::getPermissionsError( $title, $token );
+ if ( count( $errors ) ) {
+ return $errors;
+ }
// Auto-generate a summary, if necessary
- if(is_null($reason))
- {
- # Need to pass a throwaway variable because generateReason expects
- # a reference
+ if ( is_null( $reason ) ) {
+ // Need to pass a throwaway variable because generateReason expects
+ // a reference
$hasHistory = false;
- $reason = $article->generateReason($hasHistory);
- if($reason === false)
- return array(array('cannotdelete'));
+ $reason = $article->generateReason( $hasHistory );
+ if ( $reason === false ) {
+ return array( array( 'cannotdelete' ) );
+ }
}
$error = '';
- if (!wfRunHooks('ArticleDelete', array(&$article, &$wgUser, &$reason, $error)))
- $this->dieUsageMsg(array('hookaborted', $error));
+ if ( !wfRunHooks( 'ArticleDelete', array( &$article, &$wgUser, &$reason, $error ) ) ) {
+ $this->dieUsageMsg( array( 'hookaborted', $error ) );
+ }
// Luckily, Article.php provides a reusable delete function that does the hard work for us
- if($article->doDeleteArticle($reason)) {
- wfRunHooks('ArticleDeleteComplete', array(&$article, &$wgUser, $reason, $article->getId()));
+ if ( $article->doDeleteArticle( $reason ) ) {
+ wfRunHooks( 'ArticleDeleteComplete', array( &$article, &$wgUser, $reason, $article->getId() ) );
return array();
}
- return array(array('cannotdelete', $article->mTitle->getPrefixedText()));
+ return array( array( 'cannotdelete', $article->mTitle->getPrefixedText() ) );
}
- public static function deleteFile($token, &$title, $oldimage, &$reason = NULL, $suppress = false)
- {
- $errors = self::getPermissionsError($title, $token);
- if (count($errors)) return $errors;
+ public static function deleteFile( $token, &$title, $oldimage, &$reason = null, $suppress = false ) {
+ $errors = self::getPermissionsError( $title, $token );
+ if ( count( $errors ) ) {
+ return $errors;
+ }
- if( $oldimage && !FileDeleteForm::isValidOldSpec($oldimage) )
- return array(array('invalidoldimage'));
+ if ( $oldimage && !FileDeleteForm::isValidOldSpec( $oldimage ) ) {
+ return array( array( 'invalidoldimage' ) );
+ }
- $file = wfFindFile($title, false, FileRepo::FIND_IGNORE_REDIRECT);
+ $file = wfFindFile( $title, array( 'ignoreRedirect' => true ) );
$oldfile = false;
-
- if( $oldimage )
+
+ if ( $oldimage ) {
$oldfile = RepoGroup::singleton()->getLocalRepo()->newFromArchiveName( $title, $oldimage );
-
- if( !FileDeleteForm::haveDeletableFile($file, $oldfile, $oldimage) )
- return array(array('nofile'));
- if (is_null($reason)) # Log and RC don't like null reasons
+ }
+
+ if ( !FileDeleteForm::haveDeletableFile( $file, $oldfile, $oldimage ) ) {
+ return self::delete( new Article( $title ), $token, $reason );
+ }
+ if ( is_null( $reason ) ) { // Log and RC don't like null reasons
$reason = '';
+ }
$status = FileDeleteForm::doDelete( $title, $file, $oldimage, $reason, $suppress );
-
- if( !$status->isGood() )
- return array(array('cannotdelete', $title->getPrefixedText()));
-
+
+ if ( !$status->isGood() ) {
+ return array( array( 'cannotdelete', $title->getPrefixedText() ) );
+ }
+
return array();
}
-
- public function mustBePosted() { return true; }
+
+ public function mustBePosted() {
+ return true;
+ }
public function isWriteMode() {
return true;
}
public function getAllowedParams() {
- return array (
+ return array(
'title' => null,
'pageid' => array(
ApiBase::PARAM_TYPE => 'integer'
@@ -196,7 +204,7 @@ class ApiDelete extends ApiBase {
}
public function getParamDescription() {
- return array (
+ return array(
'title' => 'Title of the page you want to delete. Cannot be used together with pageid',
'pageid' => 'Page ID of the page you want to delete. Cannot be used together with title',
'token' => 'A delete token previously retrieved through prop=info',
@@ -213,14 +221,27 @@ class ApiDelete extends ApiBase {
);
}
+ public function getPossibleErrors() {
+ return array_merge( parent::getPossibleErrors(), array(
+ array( 'invalidtitle', 'title' ),
+ array( 'nosuchpageid', 'pageid' ),
+ array( 'notanarticle' ),
+ array( 'hookaborted', 'error' ),
+ ) );
+ }
+
+ public function getTokenSalt() {
+ return '';
+ }
+
protected function getExamples() {
- return array (
+ return array(
'api.php?action=delete&title=Main%20Page&token=123ABC',
'api.php?action=delete&title=Main%20Page&token=123ABC&reason=Preparing%20for%20move'
);
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiDelete.php 48122 2009-03-07 12:58:41Z catrope $';
+ return __CLASS__ . ': $Id: ApiDelete.php 62703 2010-02-19 12:54:09Z ashley $';
}
-}
+} \ No newline at end of file
diff --git a/includes/api/ApiDisabled.php b/includes/api/ApiDisabled.php
index 9e0bf56e..60e0e7ee 100644
--- a/includes/api/ApiDisabled.php
+++ b/includes/api/ApiDisabled.php
@@ -1,10 +1,10 @@
<?php
-/*
+/**
* Created on Sep 25, 2008
* API for MediaWiki 1.8+
*
- * Copyright (C) 2008 Roan Kattouw <Firstname>.<Lastname>@home.nl
+ * Copyright © 2008 Roan Kattouw <Firstname>.<Lastname>@home.nl
*
* 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
@@ -22,12 +22,11 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ("ApiBase.php");
+ require_once( "ApiBase.php" );
}
-
/**
* API module that dies with an error immediately.
*
@@ -40,12 +39,12 @@ if (!defined('MEDIAWIKI')) {
*/
class ApiDisabled extends ApiBase {
- public function __construct($main, $action) {
- parent :: __construct($main, $action);
+ public function __construct( $main, $action ) {
+ parent::__construct( $main, $action );
}
public function execute() {
- $this->dieUsage("The ``{$this->getModuleName()}'' module has been disabled.", 'moduledisabled');
+ $this->dieUsage( "The ``{$this->getModuleName()}'' module has been disabled.", 'moduledisabled' );
}
public function isReadMode() {
@@ -53,11 +52,11 @@ class ApiDisabled extends ApiBase {
}
public function getAllowedParams() {
- return array ();
+ return array();
}
public function getParamDescription() {
- return array ();
+ return array();
}
public function getDescription() {
@@ -67,10 +66,10 @@ class ApiDisabled extends ApiBase {
}
protected function getExamples() {
- return array ();
+ return array();
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiDisabled.php 48091 2009-03-06 13:49:44Z catrope $';
+ return __CLASS__ . ': $Id: ApiDisabled.php 62783 2010-02-21 18:09:00Z ashley $';
}
}
diff --git a/includes/api/ApiEditPage.php b/includes/api/ApiEditPage.php
index d4a57b83..50a9836a 100644
--- a/includes/api/ApiEditPage.php
+++ b/includes/api/ApiEditPage.php
@@ -23,9 +23,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ("ApiBase.php");
+ require_once ( "ApiBase.php" );
}
/**
@@ -37,242 +37,295 @@ if (!defined('MEDIAWIKI')) {
*/
class ApiEditPage extends ApiBase {
- public function __construct($query, $moduleName) {
- parent :: __construct($query, $moduleName);
+ public function __construct( $query, $moduleName ) {
+ parent :: __construct( $query, $moduleName );
}
public function execute() {
global $wgUser;
$params = $this->extractRequestParams();
- if(is_null($params['title']))
- $this->dieUsageMsg(array('missingparam', 'title'));
- if(is_null($params['text']) && is_null($params['appendtext']) &&
- is_null($params['prependtext']) &&
- $params['undo'] == 0)
- $this->dieUsageMsg(array('missingtext'));
- if(is_null($params['token']))
- $this->dieUsageMsg(array('missingparam', 'token'));
- if(!$wgUser->matchEditToken($params['token']))
- $this->dieUsageMsg(array('sessionfailure'));
-
- $titleObj = Title::newFromText($params['title']);
- if(!$titleObj)
- $this->dieUsageMsg(array('invalidtitle', $params['title']));
+
+ if ( is_null( $params['title'] ) )
+ $this->dieUsageMsg( array( 'missingparam', 'title' ) );
+
+ if ( is_null( $params['text'] ) && is_null( $params['appendtext'] ) &&
+ is_null( $params['prependtext'] ) &&
+ $params['undo'] == 0 )
+ $this->dieUsageMsg( array( 'missingtext' ) );
+
+ $titleObj = Title::newFromText( $params['title'] );
+ if ( !$titleObj || $titleObj->isExternal() )
+ $this->dieUsageMsg( array( 'invalidtitle', $params['title'] ) );
+
// Some functions depend on $wgTitle == $ep->mTitle
global $wgTitle;
$wgTitle = $titleObj;
- if($params['createonly'] && $titleObj->exists())
- $this->dieUsageMsg(array('createonly-exists'));
- if($params['nocreate'] && !$titleObj->exists())
- $this->dieUsageMsg(array('nocreate-missing'));
+ if ( $params['createonly'] && $titleObj->exists() )
+ $this->dieUsageMsg( array( 'createonly-exists' ) );
+ if ( $params['nocreate'] && !$titleObj->exists() )
+ $this->dieUsageMsg( array( 'nocreate-missing' ) );
// Now let's check whether we're even allowed to do this
- $errors = $titleObj->getUserPermissionsErrors('edit', $wgUser);
- if(!$titleObj->exists())
- $errors = array_merge($errors, $titleObj->getUserPermissionsErrors('create', $wgUser));
- if(count($errors))
- $this->dieUsageMsg($errors[0]);
+ $errors = $titleObj->getUserPermissionsErrors( 'edit', $wgUser );
+ if ( !$titleObj->exists() )
+ $errors = array_merge( $errors, $titleObj->getUserPermissionsErrors( 'create', $wgUser ) );
+ if ( count( $errors ) )
+ $this->dieUsageMsg( $errors[0] );
- $articleObj = new Article($titleObj);
+ $articleObj = new Article( $titleObj );
$toMD5 = $params['text'];
- if(!is_null($params['appendtext']) || !is_null($params['prependtext']))
+ if ( !is_null( $params['appendtext'] ) || !is_null( $params['prependtext'] ) )
{
// For non-existent pages, Article::getContent()
// returns an interface message rather than ''
// We do want getContent()'s behavior for non-existent
// MediaWiki: pages, though
- if($articleObj->getID() == 0 && $titleObj->getNamespace() != NS_MEDIAWIKI)
+ if ( $articleObj->getID() == 0 && $titleObj->getNamespace() != NS_MEDIAWIKI )
$content = '';
else
$content = $articleObj->getContent();
+
+ if ( !is_null( $params['section'] ) )
+ {
+ // Process the content for section edits
+ global $wgParser;
+ $section = intval( $params['section'] );
+ $content = $wgParser->getSection( $content, $section, false );
+ if ( $content === false )
+ $this->dieUsage( "There is no section {$section}.", 'nosuchsection' );
+ }
$params['text'] = $params['prependtext'] . $content . $params['appendtext'];
$toMD5 = $params['prependtext'] . $params['appendtext'];
}
- if($params['undo'] > 0)
+ if ( $params['undo'] > 0 )
{
- if($params['undoafter'] > 0)
+ if ( $params['undoafter'] > 0 )
{
- if($params['undo'] < $params['undoafter'])
- list($params['undo'], $params['undoafter']) =
- array($params['undoafter'], $params['undo']);
- $undoafterRev = Revision::newFromID($params['undoafter']);
+ if ( $params['undo'] < $params['undoafter'] )
+ list( $params['undo'], $params['undoafter'] ) =
+ array( $params['undoafter'], $params['undo'] );
+ $undoafterRev = Revision::newFromID( $params['undoafter'] );
}
- $undoRev = Revision::newFromID($params['undo']);
- if(is_null($undoRev) || $undoRev->isDeleted(Revision::DELETED_TEXT))
- $this->dieUsageMsg(array('nosuchrevid', $params['undo']));
- if($params['undoafter'] == 0)
+ $undoRev = Revision::newFromID( $params['undo'] );
+ if ( is_null( $undoRev ) || $undoRev->isDeleted( Revision::DELETED_TEXT ) )
+ $this->dieUsageMsg( array( 'nosuchrevid', $params['undo'] ) );
+
+ if ( $params['undoafter'] == 0 )
$undoafterRev = $undoRev->getPrevious();
- if(is_null($undoafterRev) || $undoafterRev->isDeleted(Revision::DELETED_TEXT))
- $this->dieUsageMsg(array('nosuchrevid', $params['undoafter']));
- if($undoRev->getPage() != $articleObj->getID())
- $this->dieUsageMsg(array('revwrongpage', $undoRev->getID(), $titleObj->getPrefixedText()));
- if($undoafterRev->getPage() != $articleObj->getID())
- $this->dieUsageMsg(array('revwrongpage', $undoafterRev->getID(), $titleObj->getPrefixedText()));
- $newtext = $articleObj->getUndoText($undoRev, $undoafterRev);
- if($newtext === false)
- $this->dieUsageMsg(array('undo-failure'));
+ if ( is_null( $undoafterRev ) || $undoafterRev->isDeleted( Revision::DELETED_TEXT ) )
+ $this->dieUsageMsg( array( 'nosuchrevid', $params['undoafter'] ) );
+
+ if ( $undoRev->getPage() != $articleObj->getID() )
+ $this->dieUsageMsg( array( 'revwrongpage', $undoRev->getID(), $titleObj->getPrefixedText() ) );
+ if ( $undoafterRev->getPage() != $articleObj->getID() )
+ $this->dieUsageMsg( array( 'revwrongpage', $undoafterRev->getID(), $titleObj->getPrefixedText() ) );
+
+ $newtext = $articleObj->getUndoText( $undoRev, $undoafterRev );
+ if ( $newtext === false )
+ $this->dieUsageMsg( array( 'undo-failure' ) );
$params['text'] = $newtext;
// If no summary was given and we only undid one rev,
// use an autosummary
- if(is_null($params['summary']) && $titleObj->getNextRevisionID($undoafterRev->getID()) == $params['undo'])
- $params['summary'] = wfMsgForContent('undo-summary', $params['undo'], $undoRev->getUserText());
+ if ( is_null( $params['summary'] ) && $titleObj->getNextRevisionID( $undoafterRev->getID() ) == $params['undo'] )
+ $params['summary'] = wfMsgForContent( 'undo-summary', $params['undo'], $undoRev->getUserText() );
}
- # See if the MD5 hash checks out
- if(!is_null($params['md5']))
- if(md5($toMD5) !== $params['md5'])
- $this->dieUsageMsg(array('hashcheckfailed'));
+ // See if the MD5 hash checks out
+ if ( !is_null( $params['md5'] ) && md5( $toMD5 ) !== $params['md5'] )
+ $this->dieUsageMsg( array( 'hashcheckfailed' ) );
- $ep = new EditPage($articleObj);
+ $ep = new EditPage( $articleObj );
// EditPage wants to parse its stuff from a WebRequest
// That interface kind of sucks, but it's workable
- $reqArr = array('wpTextbox1' => $params['text'],
- 'wpEdittoken' => $params['token'],
+ $reqArr = array( 'wpTextbox1' => $params['text'],
+ 'wpEditToken' => $params['token'],
'wpIgnoreBlankSummary' => ''
);
- if(!is_null($params['summary']))
+
+ if ( !is_null( $params['summary'] ) )
$reqArr['wpSummary'] = $params['summary'];
- # Watch out for basetimestamp == ''
- # wfTimestamp() treats it as NOW, almost certainly causing an edit conflict
- if(!is_null($params['basetimestamp']) && $params['basetimestamp'] != '')
- $reqArr['wpEdittime'] = wfTimestamp(TS_MW, $params['basetimestamp']);
+
+ // Watch out for basetimestamp == ''
+ // wfTimestamp() treats it as NOW, almost certainly causing an edit conflict
+ if ( !is_null( $params['basetimestamp'] ) && $params['basetimestamp'] != '' )
+ $reqArr['wpEdittime'] = wfTimestamp( TS_MW, $params['basetimestamp'] );
else
$reqArr['wpEdittime'] = $articleObj->getTimestamp();
- if(!is_null($params['starttimestamp']) && $params['starttimestamp'] != '')
- $reqArr['wpStarttime'] = wfTimestamp(TS_MW, $params['starttimestamp']);
+
+ if ( !is_null( $params['starttimestamp'] ) && $params['starttimestamp'] != '' )
+ $reqArr['wpStarttime'] = wfTimestamp( TS_MW, $params['starttimestamp'] );
else
- # Fake wpStartime
- $reqArr['wpStarttime'] = $reqArr['wpEdittime'];
- if($params['minor'] || (!$params['notminor'] && $wgUser->getOption('minordefault')))
+ $reqArr['wpStarttime'] = $reqArr['wpEdittime']; // Fake wpStartime
+
+ if ( $params['minor'] || ( !$params['notminor'] && $wgUser->getOption( 'minordefault' ) ) )
$reqArr['wpMinoredit'] = '';
- if($params['recreate'])
+
+ if ( $params['recreate'] )
$reqArr['wpRecreate'] = '';
- if(!is_null($params['section']))
+
+ if ( !is_null( $params['section'] ) )
{
- $section = intval($params['section']);
- if($section == 0 && $params['section'] != '0' && $params['section'] != 'new')
- $this->dieUsage("The section parameter must be set to an integer or 'new'", "invalidsection");
+ $section = intval( $params['section'] );
+ if ( $section == 0 && $params['section'] != '0' && $params['section'] != 'new' )
+ $this->dieUsage( "The section parameter must be set to an integer or 'new'", "invalidsection" );
$reqArr['wpSection'] = $params['section'];
}
else
$reqArr['wpSection'] = '';
- if($params['watch'])
- $watch = true;
- else if($params['unwatch'])
- $watch = false;
- else if($titleObj->userIsWatching())
- $watch = true;
- else if($wgUser->getOption('watchdefault'))
- $watch = true;
- else if($wgUser->getOption('watchcreations') && !$titleObj->exists())
+ // Handle watchlist settings
+ switch ( $params['watchlist'] )
+ {
+ case 'watch':
+ $watch = true;
+ break;
+ case 'unwatch':
+ $watch = false;
+ break;
+ case 'preferences':
+ if ( $titleObj->exists() )
+ $watch = $wgUser->getOption( 'watchdefault' ) || $titleObj->userIsWatching();
+ else
+ $watch = $wgUser->getOption( 'watchcreations' );
+ break;
+ case 'nochange':
+ default:
+ $watch = $titleObj->userIsWatching();
+ }
+ // Deprecated parameters
+ if ( $params['watch'] )
$watch = true;
- else
+ elseif ( $params['unwatch'] )
$watch = false;
- if($watch)
+
+ if ( $watch )
$reqArr['wpWatchthis'] = '';
- $req = new FauxRequest($reqArr, true);
- $ep->importFormData($req);
+ $req = new FauxRequest( $reqArr, true );
+ $ep->importFormData( $req );
- # Run hooks
- # Handle CAPTCHA parameters
+ // Run hooks
+ // Handle CAPTCHA parameters
global $wgRequest;
- if(!is_null($params['captchaid']))
+ if ( !is_null( $params['captchaid'] ) )
$wgRequest->setVal( 'wpCaptchaId', $params['captchaid'] );
- if(!is_null($params['captchaword']))
+ if ( !is_null( $params['captchaword'] ) )
$wgRequest->setVal( 'wpCaptchaWord', $params['captchaword'] );
+
$r = array();
- if(!wfRunHooks('APIEditBeforeSave', array(&$ep, $ep->textbox1, &$r)))
+ if ( !wfRunHooks( 'APIEditBeforeSave', array( $ep, $ep->textbox1, &$r ) ) )
{
- if(count($r))
+ if ( count( $r ) )
{
$r['result'] = "Failure";
- $this->getResult()->addValue(null, $this->getModuleName(), $r);
+ $this->getResult()->addValue( null, $this->getModuleName(), $r );
return;
}
else
- $this->dieUsageMsg(array('hookaborted'));
+ $this->dieUsageMsg( array( 'hookaborted' ) );
}
- # Do the actual save
+ // Do the actual save
$oldRevId = $articleObj->getRevIdFetched();
$result = null;
- # Fake $wgRequest for some hooks inside EditPage
- # FIXME: This interface SUCKS
+ // Fake $wgRequest for some hooks inside EditPage
+ // FIXME: This interface SUCKS
$oldRequest = $wgRequest;
$wgRequest = $req;
- $retval = $ep->internalAttemptSave($result, $wgUser->isAllowed('bot') && $params['bot']);
+ $retval = $ep->internalAttemptSave( $result, $wgUser->isAllowed( 'bot' ) && $params['bot'] );
$wgRequest = $oldRequest;
- switch($retval)
+ switch( $retval )
{
case EditPage::AS_HOOK_ERROR:
case EditPage::AS_HOOK_ERROR_EXPECTED:
- $this->dieUsageMsg(array('hookaborted'));
+ $this->dieUsageMsg( array( 'hookaborted' ) );
+
case EditPage::AS_IMAGE_REDIRECT_ANON:
- $this->dieUsageMsg(array('noimageredirect-anon'));
+ $this->dieUsageMsg( array( 'noimageredirect-anon' ) );
+
case EditPage::AS_IMAGE_REDIRECT_LOGGED:
- $this->dieUsageMsg(array('noimageredirect-logged'));
+ $this->dieUsageMsg( array( 'noimageredirect-logged' ) );
+
case EditPage::AS_SPAM_ERROR:
- $this->dieUsageMsg(array('spamdetected', $result['spam']));
+ $this->dieUsageMsg( array( 'spamdetected', $result['spam'] ) );
+
case EditPage::AS_FILTERING:
- $this->dieUsageMsg(array('filtered'));
+ $this->dieUsageMsg( array( 'filtered' ) );
+
case EditPage::AS_BLOCKED_PAGE_FOR_USER:
- $this->dieUsageMsg(array('blockedtext'));
+ $this->dieUsageMsg( array( 'blockedtext' ) );
+
case EditPage::AS_MAX_ARTICLE_SIZE_EXCEEDED:
case EditPage::AS_CONTENT_TOO_BIG:
global $wgMaxArticleSize;
- $this->dieUsageMsg(array('contenttoobig', $wgMaxArticleSize));
+ $this->dieUsageMsg( array( 'contenttoobig', $wgMaxArticleSize ) );
+
case EditPage::AS_READ_ONLY_PAGE_ANON:
- $this->dieUsageMsg(array('noedit-anon'));
+ $this->dieUsageMsg( array( 'noedit-anon' ) );
+
case EditPage::AS_READ_ONLY_PAGE_LOGGED:
- $this->dieUsageMsg(array('noedit'));
+ $this->dieUsageMsg( array( 'noedit' ) );
+
case EditPage::AS_READ_ONLY_PAGE:
- $this->dieUsageMsg(array('readonlytext'));
+ $this->dieReadOnly();
+
case EditPage::AS_RATE_LIMITED:
- $this->dieUsageMsg(array('actionthrottledtext'));
+ $this->dieUsageMsg( array( 'actionthrottledtext' ) );
+
case EditPage::AS_ARTICLE_WAS_DELETED:
- $this->dieUsageMsg(array('wasdeleted'));
+ $this->dieUsageMsg( array( 'wasdeleted' ) );
+
case EditPage::AS_NO_CREATE_PERMISSION:
- $this->dieUsageMsg(array('nocreate-loggedin'));
+ $this->dieUsageMsg( array( 'nocreate-loggedin' ) );
+
case EditPage::AS_BLANK_ARTICLE:
- $this->dieUsageMsg(array('blankpage'));
+ $this->dieUsageMsg( array( 'blankpage' ) );
+
case EditPage::AS_CONFLICT_DETECTED:
- $this->dieUsageMsg(array('editconflict'));
- #case EditPage::AS_SUMMARY_NEEDED: Can't happen since we set wpIgnoreBlankSummary
+ $this->dieUsageMsg( array( 'editconflict' ) );
+
+ // case EditPage::AS_SUMMARY_NEEDED: Can't happen since we set wpIgnoreBlankSummary
case EditPage::AS_TEXTBOX_EMPTY:
- $this->dieUsageMsg(array('emptynewsection'));
- case EditPage::AS_END:
- # This usually means some kind of race condition
- # or DB weirdness occurred. Throw an unknown error here.
- $this->dieUsageMsg(array('unknownerror'));
+ $this->dieUsageMsg( array( 'emptynewsection' ) );
+
case EditPage::AS_SUCCESS_NEW_ARTICLE:
$r['new'] = '';
case EditPage::AS_SUCCESS_UPDATE:
$r['result'] = "Success";
- $r['pageid'] = intval($titleObj->getArticleID());
+ $r['pageid'] = intval( $titleObj->getArticleID() );
$r['title'] = $titleObj->getPrefixedText();
- # HACK: We create a new Article object here because getRevIdFetched()
- # refuses to be run twice, and because Title::getLatestRevId()
- # won't fetch from the master unless we select for update, which we
- # don't want to do.
- $newArticle = new Article($titleObj);
+ // HACK: We create a new Article object here because getRevIdFetched()
+ // refuses to be run twice, and because Title::getLatestRevId()
+ // won't fetch from the master unless we select for update, which we
+ // don't want to do.
+ $newArticle = new Article( $titleObj );
$newRevId = $newArticle->getRevIdFetched();
- if($newRevId == $oldRevId)
+ if ( $newRevId == $oldRevId )
$r['nochange'] = '';
else
{
- $r['oldrevid'] = intval($oldRevId);
- $r['newrevid'] = intval($newRevId);
+ $r['oldrevid'] = intval( $oldRevId );
+ $r['newrevid'] = intval( $newRevId );
+ $r['newtimestamp'] = wfTimestamp( TS_ISO_8601,
+ $newArticle->getTimestamp() );
}
break;
+
+ case EditPage::AS_END:
+ // This usually means some kind of race condition
+ // or DB weirdness occurred. Fall through to throw an unknown
+ // error.
+
+ // This needs fixing higher up, as Article::doEdit should be
+ // used rather than Article::updateArticle, so that specific
+ // error conditions can be returned
default:
- $this->dieUsageMsg(array('unknownerror', $retval));
+ $this->dieUsageMsg( array( 'unknownerror', $retval ) );
}
- $this->getResult()->addValue(null, $this->getModuleName(), $r);
+ $this->getResult()->addValue( null, $this->getModuleName(), $r );
}
public function mustBePosted() {
@@ -286,6 +339,41 @@ class ApiEditPage extends ApiBase {
protected function getDescription() {
return 'Create and edit pages.';
}
+
+ public function getPossibleErrors() {
+ global $wgMaxArticleSize;
+
+ return array_merge( parent::getPossibleErrors(), array(
+ array( 'missingparam', 'title' ),
+ array( 'missingtext' ),
+ array( 'invalidtitle', 'title' ),
+ array( 'createonly-exists' ),
+ array( 'nocreate-missing' ),
+ array( 'nosuchrevid', 'undo' ),
+ array( 'nosuchrevid', 'undoafter' ),
+ array( 'revwrongpage', 'id', 'text' ),
+ array( 'undo-failure' ),
+ array( 'hashcheckfailed' ),
+ array( 'hookaborted' ),
+ array( 'noimageredirect-anon' ),
+ array( 'noimageredirect-logged' ),
+ array( 'spamdetected', 'spam' ),
+ array( 'filtered' ),
+ array( 'blockedtext' ),
+ array( 'contenttoobig', $wgMaxArticleSize ),
+ array( 'noedit-anon' ),
+ array( 'noedit' ),
+ array( 'actionthrottledtext' ),
+ array( 'wasdeleted' ),
+ array( 'nocreate-loggedin' ),
+ array( 'blankpage' ),
+ array( 'editconflict' ),
+ array( 'emptynewsection' ),
+ array( 'unknownerror', 'retval' ),
+ array( 'code' => 'nosuchsection', 'info' => 'There is no section section.' ),
+ array( 'code' => 'invalidsection', 'info' => 'The section parameter must be set to an integer or \'new\'' ),
+ ) );
+ }
protected function getAllowedParams() {
return array (
@@ -304,8 +392,23 @@ class ApiEditPage extends ApiBase {
'nocreate' => false,
'captchaword' => null,
'captchaid' => null,
- 'watch' => false,
- 'unwatch' => false,
+ 'watch' => array(
+ ApiBase :: PARAM_DFLT => false,
+ ApiBase :: PARAM_DEPRECATED => true,
+ ),
+ 'unwatch' => array(
+ ApiBase :: PARAM_DFLT => false,
+ ApiBase :: PARAM_DEPRECATED => true,
+ ),
+ 'watchlist' => array(
+ ApiBase :: PARAM_DFLT => 'preferences',
+ ApiBase :: PARAM_TYPE => array(
+ 'watch',
+ 'unwatch',
+ 'preferences',
+ 'nochange'
+ ),
+ ),
'md5' => null,
'prependtext' => null,
'appendtext' => null,
@@ -328,10 +431,10 @@ class ApiEditPage extends ApiBase {
'minor' => 'Minor edit',
'notminor' => 'Non-minor edit',
'bot' => 'Mark this edit as bot',
- 'basetimestamp' => array('Timestamp of the base revision (gotten through prop=revisions&rvprop=timestamp).',
+ 'basetimestamp' => array( 'Timestamp of the base revision (gotten through prop=revisions&rvprop=timestamp).',
'Used to detect edit conflicts; leave unset to ignore conflicts.'
),
- 'starttimestamp' => array('Timestamp when you obtained the edit token.',
+ 'starttimestamp' => array( 'Timestamp when you obtained the edit token.',
'Used to detect edit conflicts; leave unset to ignore conflicts.'
),
'recreate' => 'Override any errors about the article having been deleted in the meantime',
@@ -339,17 +442,21 @@ class ApiEditPage extends ApiBase {
'nocreate' => 'Throw an error if the page doesn\'t exist',
'watch' => 'Add the page to your watchlist',
'unwatch' => 'Remove the page from your watchlist',
+ 'watchlist' => 'Unconditionally add or remove the page from your watchlist, use preferences or do not change watch',
'captchaid' => 'CAPTCHA ID from previous request',
'captchaword' => 'Answer to the CAPTCHA',
'md5' => array( 'The MD5 hash of the text parameter, or the prependtext and appendtext parameters concatenated.',
- 'If set, the edit won\'t be done unless the hash is correct'),
- 'prependtext' => array( 'Add this text to the beginning of the page. Overrides text.',
- 'Don\'t use together with section: that won\'t do what you expect.'),
+ 'If set, the edit won\'t be done unless the hash is correct' ),
+ 'prependtext' => 'Add this text to the beginning of the page. Overrides text.',
'appendtext' => 'Add this text to the end of the page. Overrides text',
'undo' => 'Undo this revision. Overrides text, prependtext and appendtext',
'undoafter' => 'Undo all revisions from undo to this one. If not set, just undo one revision',
);
}
+
+ public function getTokenSalt() {
+ return '';
+ }
protected function getExamples() {
return array (
@@ -363,6 +470,6 @@ class ApiEditPage extends ApiBase {
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiEditPage.php 50220 2009-05-05 14:07:59Z tstarling $';
+ return __CLASS__ . ': $Id: ApiEditPage.php 62600 2010-02-16 22:01:38Z reedy $';
}
}
diff --git a/includes/api/ApiEmailUser.php b/includes/api/ApiEmailUser.php
index 9bb504fb..912480ef 100644
--- a/includes/api/ApiEmailUser.php
+++ b/includes/api/ApiEmailUser.php
@@ -22,19 +22,18 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ("ApiBase.php");
+ require_once ( "ApiBase.php" );
}
-
/**
* @ingroup API
*/
class ApiEmailUser extends ApiBase {
- public function __construct($main, $action) {
- parent :: __construct($main, $action);
+ public function __construct( $main, $action ) {
+ parent :: __construct( $main, $action );
}
public function execute() {
@@ -49,8 +48,6 @@ class ApiEmailUser extends ApiBase {
$this->dieUsageMsg( array( 'missingparam', 'target' ) );
if ( !isset( $params['text'] ) )
$this->dieUsageMsg( array( 'missingparam', 'text' ) );
- if ( !isset( $params['token'] ) )
- $this->dieUsageMsg( array( 'missingparam', 'token' ) );
// Validate target
$targetUser = EmailUserForm::validateEmailTarget( $params['target'] );
@@ -61,8 +58,7 @@ class ApiEmailUser extends ApiBase {
$error = EmailUserForm::getPermissionsError( $wgUser, $params['token'] );
if ( $error )
$this->dieUsageMsg( array( $error ) );
-
-
+
$form = new EmailUserForm( $targetUser, $params['text'], $params['subject'], $params['ccme'] );
$retval = $form->doSubmit();
if ( is_null( $retval ) )
@@ -74,7 +70,9 @@ class ApiEmailUser extends ApiBase {
$this->getResult()->addValue( null, $this->getModuleName(), $result );
}
- public function mustBePosted() { return true; }
+ public function mustBePosted() {
+ return true;
+ }
public function isWriteMode() {
return true;
@@ -105,6 +103,18 @@ class ApiEmailUser extends ApiBase {
'Email a user.'
);
}
+
+ public function getPossibleErrors() {
+ return array_merge( parent::getPossibleErrors(), array(
+ array( 'usermaildisabled' ),
+ array( 'missingparam', 'target' ),
+ array( 'missingparam', 'text' ),
+ ) );
+ }
+
+ public function getTokenSalt() {
+ return '';
+ }
protected function getExamples() {
return array (
@@ -113,7 +123,7 @@ class ApiEmailUser extends ApiBase {
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiEmailUser.php 48091 2009-03-06 13:49:44Z catrope $';
+ return __CLASS__ . ': $Id: ApiEmailUser.php 62599 2010-02-16 21:59:16Z reedy $';
}
-}
+}
\ No newline at end of file
diff --git a/includes/api/ApiExpandTemplates.php b/includes/api/ApiExpandTemplates.php
index afb11402..d0c00db7 100644
--- a/includes/api/ApiExpandTemplates.php
+++ b/includes/api/ApiExpandTemplates.php
@@ -23,9 +23,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ("ApiBase.php");
+ require_once ( "ApiBase.php" );
}
/**
@@ -37,8 +37,8 @@ if (!defined('MEDIAWIKI')) {
*/
class ApiExpandTemplates extends ApiBase {
- public function __construct($main, $action) {
- parent :: __construct($main, $action);
+ public function __construct( $main, $action ) {
+ parent :: __construct( $main, $action );
}
public function execute() {
@@ -48,9 +48,9 @@ class ApiExpandTemplates extends ApiBase {
// Get parameters
$params = $this->extractRequestParams();
- //Create title for parser
+ // Create title for parser
$title_obj = Title :: newFromText( $params['title'] );
- if(!$title_obj)
+ if ( !$title_obj )
$title_obj = Title :: newFromText( "API" ); // default
$result = $this->getResult();
@@ -58,6 +58,7 @@ class ApiExpandTemplates extends ApiBase {
// Parse text
global $wgParser;
$options = new ParserOptions();
+
if ( $params['generatexml'] )
{
$wgParser->startExternalParse( $title_obj, $options, OT_PREPROCESS );
@@ -69,7 +70,7 @@ class ApiExpandTemplates extends ApiBase {
}
$xml_result = array();
$result->setContent( $xml_result, $xml );
- $result->addValue( null, 'parsetree', $xml_result);
+ $result->addValue( null, 'parsetree', $xml_result );
}
$retval = $wgParser->preprocess( $params['text'], $title_obj, $options );
@@ -108,6 +109,6 @@ class ApiExpandTemplates extends ApiBase {
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiExpandTemplates.php 69986 2010-07-27 03:57:39Z tstarling $';
+ return __CLASS__ . ': $Id: ApiExpandTemplates.php 69932 2010-07-26 08:03:21Z tstarling $';
}
}
diff --git a/includes/api/ApiFeedWatchlist.php b/includes/api/ApiFeedWatchlist.php
index 0859232e..03d12800 100644
--- a/includes/api/ApiFeedWatchlist.php
+++ b/includes/api/ApiFeedWatchlist.php
@@ -23,9 +23,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ("ApiBase.php");
+ require_once ( "ApiBase.php" );
}
/**
@@ -37,15 +37,15 @@ if (!defined('MEDIAWIKI')) {
*/
class ApiFeedWatchlist extends ApiBase {
- public function __construct($main, $action) {
- parent :: __construct($main, $action);
+ public function __construct( $main, $action ) {
+ parent :: __construct( $main, $action );
}
/**
* This module uses a custom feed wrapper printer.
*/
public function getCustomPrinter() {
- return new ApiFormatFeedWrapper($this->getMain());
+ return new ApiFormatFeedWrapper( $this->getMain() );
}
/**
@@ -60,7 +60,7 @@ class ApiFeedWatchlist extends ApiBase {
$params = $this->extractRequestParams();
// limit to the number of hours going from now back
- $endTime = wfTimestamp(TS_MW, time() - intval($params['hours'] * 60 * 60));
+ $endTime = wfTimestamp( TS_MW, time() - intval( $params['hours'] * 60 * 60 ) );
$dbr = wfGetDB( DB_SLAVE );
// Prepare parameters for nested request
@@ -71,48 +71,56 @@ class ApiFeedWatchlist extends ApiBase {
'list' => 'watchlist',
'wlprop' => 'title|user|comment|timestamp',
'wldir' => 'older', // reverse order - from newest to oldest
- 'wlend' => $dbr->timestamp($endTime), // stop at this time
- 'wllimit' => (50 > $wgFeedLimit) ? $wgFeedLimit : 50
+ 'wlend' => $dbr->timestamp( $endTime ), // stop at this time
+ 'wllimit' => ( 50 > $wgFeedLimit ) ? $wgFeedLimit : 50
);
+ if ( !is_null( $params['wlowner'] ) ) {
+ $fauxReqArr['wlowner'] = $params['wlowner'];
+ }
+ if ( !is_null( $params['wltoken'] ) ) {
+ $fauxReqArr['wltoken'] = $params['wltoken'];
+ }
+
// Check for 'allrev' parameter, and if found, show all revisions to each page on wl.
- if ( ! is_null ( $params['allrev'] ) ) $fauxReqArr['wlallrev'] = '';
+ if ( !is_null ( $params['allrev'] ) ) {
+ $fauxReqArr['wlallrev'] = '';
+ }
// Create the request
$fauxReq = new FauxRequest ( $fauxReqArr );
// Execute
- $module = new ApiMain($fauxReq);
+ $module = new ApiMain( $fauxReq );
$module->execute();
// Get data array
$data = $module->getResultData();
- $feedItems = array ();
- foreach ((array)$data['query']['watchlist'] as $info) {
- $feedItems[] = $this->createFeedItem($info);
+ $feedItems = array();
+ foreach ( (array)$data['query']['watchlist'] as $info ) {
+ $feedItems[] = $this->createFeedItem( $info );
}
- $feedTitle = $wgSitename . ' - ' . wfMsgForContent('watchlist') . ' [' . $wgContLanguageCode . ']';
+ $feedTitle = $wgSitename . ' - ' . wfMsgForContent( 'watchlist' ) . ' [' . $wgContLanguageCode . ']';
$feedUrl = SpecialPage::getTitleFor( 'Watchlist' )->getFullUrl();
- $feed = new $wgFeedClasses[$params['feedformat']] ($feedTitle, htmlspecialchars(wfMsgForContent('watchlist')), $feedUrl);
+ $feed = new $wgFeedClasses[$params['feedformat']] ( $feedTitle, htmlspecialchars( wfMsgForContent( 'watchlist' ) ), $feedUrl );
- ApiFormatFeedWrapper :: setResult($this->getResult(), $feed, $feedItems);
+ ApiFormatFeedWrapper :: setResult( $this->getResult(), $feed, $feedItems );
- } catch (Exception $e) {
+ } catch ( Exception $e ) {
// Error results should not be cached
- $this->getMain()->setCacheMaxAge(0);
+ $this->getMain()->setCacheMaxAge( 0 );
- $feedTitle = $wgSitename . ' - Error - ' . wfMsgForContent('watchlist') . ' [' . $wgContLanguageCode . ']';
+ $feedTitle = $wgSitename . ' - Error - ' . wfMsgForContent( 'watchlist' ) . ' [' . $wgContLanguageCode . ']';
$feedUrl = SpecialPage::getTitleFor( 'Watchlist' )->getFullUrl();
- $feedFormat = isset($params['feedformat']) ? $params['feedformat'] : 'rss';
- $feed = new $wgFeedClasses[$feedFormat] ($feedTitle, htmlspecialchars(wfMsgForContent('watchlist')), $feedUrl);
-
+ $feedFormat = isset( $params['feedformat'] ) ? $params['feedformat'] : 'rss';
+ $feed = new $wgFeedClasses[$feedFormat] ( $feedTitle, htmlspecialchars( wfMsgForContent( 'watchlist' ) ), $feedUrl );
- if ($e instanceof UsageException) {
+ if ( $e instanceof UsageException ) {
$errorCode = $e->getCodeString();
} else {
// Something is seriously wrong
@@ -120,14 +128,14 @@ class ApiFeedWatchlist extends ApiBase {
}
$errorText = $e->getMessage();
- $feedItems[] = new FeedItem("Error ($errorCode)", $errorText, "", "", "");
- ApiFormatFeedWrapper :: setResult($this->getResult(), $feed, $feedItems);
+ $feedItems[] = new FeedItem( "Error ($errorCode)", $errorText, "", "", "" );
+ ApiFormatFeedWrapper :: setResult( $this->getResult(), $feed, $feedItems );
}
}
- private function createFeedItem($info) {
+ private function createFeedItem( $info ) {
$titleStr = $info['title'];
- $title = Title :: newFromText($titleStr);
+ $title = Title :: newFromText( $titleStr );
$titleUrl = $title->getFullUrl();
$comment = isset( $info['comment'] ) ? $info['comment'] : null;
$timestamp = $info['timestamp'];
@@ -135,12 +143,12 @@ class ApiFeedWatchlist extends ApiBase {
$completeText = "$comment ($user)";
- return new FeedItem($titleStr, $completeText, $titleUrl, $timestamp, $user);
+ return new FeedItem( $titleStr, $completeText, $titleUrl, $timestamp, $user );
}
public function getAllowedParams() {
global $wgFeedClasses;
- $feedFormatNames = array_keys($wgFeedClasses);
+ $feedFormatNames = array_keys( $wgFeedClasses );
return array (
'feedformat' => array (
ApiBase :: PARAM_DFLT => 'rss',
@@ -152,7 +160,13 @@ class ApiFeedWatchlist extends ApiBase {
ApiBase :: PARAM_MIN => 1,
ApiBase :: PARAM_MAX => 72,
),
- 'allrev' => null
+ 'allrev' => null,
+ 'wlowner' => array (
+ ApiBase :: PARAM_TYPE => 'user'
+ ),
+ 'wltoken' => array (
+ ApiBase :: PARAM_TYPE => 'string'
+ )
);
}
@@ -160,7 +174,9 @@ class ApiFeedWatchlist extends ApiBase {
return array (
'feedformat' => 'The format of the feed',
'hours' => 'List pages modified within this many hours from now',
- 'allrev' => 'Include multiple revisions of the same page within given timeframe.'
+ 'allrev' => 'Include multiple revisions of the same page within given timeframe.',
+ 'wlowner' => "The user whose watchlist you want (must be accompanied by wltoken if it's not you)",
+ 'wltoken' => 'Security token that requested user set in their preferences'
);
}
@@ -175,6 +191,6 @@ class ApiFeedWatchlist extends ApiBase {
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiFeedWatchlist.php 46848 2009-02-05 15:31:06Z catrope $';
+ return __CLASS__ . ': $Id: ApiFeedWatchlist.php 69357 2010-07-14 22:39:23Z mah $';
}
}
diff --git a/includes/api/ApiFormatBase.php b/includes/api/ApiFormatBase.php
index cc7434c6..de211fe9 100644
--- a/includes/api/ApiFormatBase.php
+++ b/includes/api/ApiFormatBase.php
@@ -23,9 +23,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ('ApiBase.php');
+ require_once ( 'ApiBase.php' );
}
/**
@@ -36,6 +36,7 @@ if (!defined('MEDIAWIKI')) {
abstract class ApiFormatBase extends ApiBase {
private $mIsHtml, $mFormat, $mUnescapeAmps, $mHelp, $mCleared;
+ private $mBufferResult = false, $mBuffer;
/**
* Constructor
@@ -43,15 +44,15 @@ abstract class ApiFormatBase extends ApiBase {
* @param $main ApiMain
* @param $format string Format name
*/
- public function __construct($main, $format) {
- parent :: __construct($main, $format);
+ public function __construct( $main, $format ) {
+ parent :: __construct( $main, $format );
- $this->mIsHtml = (substr($format, -2, 2) === 'fm'); // ends with 'fm'
- if ($this->mIsHtml)
- $this->mFormat = substr($format, 0, -2); // remove ending 'fm'
+ $this->mIsHtml = ( substr( $format, - 2, 2 ) === 'fm' ); // ends with 'fm'
+ if ( $this->mIsHtml )
+ $this->mFormat = substr( $format, 0, - 2 ); // remove ending 'fm'
else
$this->mFormat = $format;
- $this->mFormat = strtoupper($this->mFormat);
+ $this->mFormat = strtoupper( $this->mFormat );
$this->mCleared = false;
}
@@ -102,29 +103,39 @@ abstract class ApiFormatBase extends ApiBase {
}
/**
+ * Whether this formatter can format the help message in a nice way.
+ * By default, this returns the same as getIsHtml().
+ * When action=help is set explicitly, the help will always be shown
+ * @return bool
+ */
+ public function getWantsHelp() {
+ return $this->getIsHtml();
+ }
+
+ /**
* Initialize the printer function and prepare the output headers, etc.
* This method must be the first outputing method during execution.
* A help screen's header is printed for the HTML-based output
* @param $isError bool Whether an error message is printed
*/
- function initPrinter($isError) {
+ function initPrinter( $isError ) {
$isHtml = $this->getIsHtml();
$mime = $isHtml ? 'text/html' : $this->getMimeType();
$script = wfScript( 'api' );
// Some printers (ex. Feed) do their own header settings,
// in which case $mime will be set to null
- if (is_null($mime))
+ if ( is_null( $mime ) )
return; // skip any initialization
- header("Content-Type: $mime; charset=utf-8");
+ header( "Content-Type: $mime; charset=utf-8" );
- if ($isHtml) {
+ if ( $isHtml ) {
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
-<?php if ($this->mUnescapeAmps) {
+<?php if ( $this->mUnescapeAmps ) {
?> <title>MediaWiki API</title>
<?php } else {
?> <title>MediaWiki API Result</title>
@@ -134,12 +145,12 @@ abstract class ApiFormatBase extends ApiBase {
<?php
- if( !$isError ) {
+ if ( !$isError ) {
?>
-<br/>
+<br />
<small>
-You are looking at the HTML representation of the <?php echo( $this->mFormat ); ?> format.<br/>
-HTML is good for debugging, but probably is not suitable for your application.<br/>
+You are looking at the HTML representation of the <?php echo( $this->mFormat ); ?> format.<br />
+HTML is good for debugging, but probably is not suitable for your application.<br />
See <a href='http://www.mediawiki.org/wiki/API'>complete documentation</a>, or
<a href='<?php echo( $script ); ?>'>API help</a> for more information.
</small>
@@ -159,7 +170,7 @@ See <a href='http://www.mediawiki.org/wiki/API'>complete documentation</a>, or
* Finish printing. Closes HTML tags.
*/
public function closePrinter() {
- if ($this->getIsHtml()) {
+ if ( $this->getIsHtml() ) {
?>
</pre>
@@ -177,15 +188,16 @@ See <a href='http://www.mediawiki.org/wiki/API'>complete documentation</a>, or
* when format name ends in 'fm'.
* @param $text string
*/
- public function printText($text) {
- if ($this->getIsHtml())
- echo $this->formatHTML($text);
- else
- {
+ public function printText( $text ) {
+ if ( $this->mBufferResult ) {
+ $this->mBuffer = $text;
+ } elseif ( $this->getIsHtml() ) {
+ echo $this->formatHTML( $text );
+ } else {
// For non-HTML output, clear all errors that might have been
// displayed if display_errors=On
// Do this only once, of course
- if(!$this->mCleared)
+ if ( !$this->mCleared )
{
ob_clean();
$this->mCleared = true;
@@ -195,6 +207,19 @@ See <a href='http://www.mediawiki.org/wiki/API'>complete documentation</a>, or
}
/**
+ * Get the contents of the buffer.
+ */
+ public function getBuffer() {
+ return $this->mBuffer;
+ }
+ /**
+ * Set the flag to buffer the result instead of printing it.
+ */
+ public function setBufferResult( $value ) {
+ $this->mBufferResult = $value;
+ }
+
+ /**
* Sets whether the pretty-printer should format *bold* and $italics$
* @param $help bool
*/
@@ -208,25 +233,25 @@ See <a href='http://www.mediawiki.org/wiki/API'>complete documentation</a>, or
* @param $text string
* @return string
*/
- protected function formatHTML($text) {
+ protected function formatHTML( $text ) {
global $wgUrlProtocols;
-
+
// Escape everything first for full coverage
- $text = htmlspecialchars($text);
+ $text = htmlspecialchars( $text );
// encode all comments or tags as safe blue strings
- $text = preg_replace('/\&lt;(!--.*?--|.*?)\&gt;/', '<span style="color:blue;">&lt;\1&gt;</span>', $text);
+ $text = preg_replace( '/\&lt;(!--.*?--|.*?)\&gt;/', '<span style="color:blue;">&lt;\1&gt;</span>', $text );
// identify URLs
- $protos = implode("|", $wgUrlProtocols);
- # This regex hacks around bug 13218 (&quot; included in the URL)
- $text = preg_replace("#(($protos).*?)(&quot;)?([ \\'\"<>\n]|&lt;|&gt;|&quot;)#", '<a href="\\1">\\1</a>\\3\\4', $text);
+ $protos = implode( "|", $wgUrlProtocols );
+ // This regex hacks around bug 13218 (&quot; included in the URL)
+ $text = preg_replace( "#(($protos).*?)(&quot;)?([ \\'\"<>\n]|&lt;|&gt;|&quot;)#", '<a href="\\1">\\1</a>\\3\\4', $text );
// identify requests to api.php
- $text = preg_replace("#api\\.php\\?[^ \\()<\n\t]+#", '<a href="\\0">\\0</a>', $text);
- if( $this->mHelp ) {
+ $text = preg_replace( "#api\\.php\\?[^ \\()<\n\t]+#", '<a href="\\0">\\0</a>', $text );
+ if ( $this->mHelp ) {
// make strings inside * bold
- $text = preg_replace("#\\*[^<>\n]+\\*#", '<b>\\0</b>', $text);
+ $text = preg_replace( "#\\*[^<>\n]+\\*#", '<b>\\0</b>', $text );
// make strings inside $ italic
- $text = preg_replace("#\\$[^<>\n]+\\$#", '<b><i>\\0</i></b>', $text);
+ $text = preg_replace( "#\\$[^<>\n]+\\$#", '<b><i>\\0</i></b>', $text );
}
/* Temporary fix for bad links in help messages. As a special case,
@@ -248,7 +273,7 @@ See <a href='http://www.mediawiki.org/wiki/API'>complete documentation</a>, or
}
public static function getBaseVersion() {
- return __CLASS__ . ': $Id: ApiFormatBase.php 48521 2009-03-18 19:25:29Z ialex $';
+ return __CLASS__ . ': $Id: ApiFormatBase.php 62367 2010-02-12 14:09:42Z siebrand $';
}
}
@@ -258,8 +283,8 @@ See <a href='http://www.mediawiki.org/wiki/API'>complete documentation</a>, or
*/
class ApiFormatFeedWrapper extends ApiFormatBase {
- public function __construct($main) {
- parent :: __construct($main, 'feed');
+ public function __construct( $main ) {
+ parent :: __construct( $main, 'feed' );
}
/**
@@ -268,15 +293,15 @@ class ApiFormatFeedWrapper extends ApiFormatBase {
* @param $feed object an instance of one of the $wgFeedClasses classes
* @param $feedItems array of FeedItem objects
*/
- public static function setResult($result, $feed, $feedItems) {
+ public static function setResult( $result, $feed, $feedItems ) {
// Store output in the Result data.
// This way we can check during execution if any error has occured
// Disable size checking for this because we can't continue
// cleanly; size checking would cause more problems than it'd
// solve
$result->disableSizeCheck();
- $result->addValue(null, '_feed', $feed);
- $result->addValue(null, '_feeditems', $feedItems);
+ $result->addValue( null, '_feed', $feed );
+ $result->addValue( null, '_feeditems', $feedItems );
$result->enableSizeCheck();
}
@@ -301,13 +326,13 @@ class ApiFormatFeedWrapper extends ApiFormatBase {
*/
public function execute() {
$data = $this->getResultData();
- if (isset ($data['_feed']) && isset ($data['_feeditems'])) {
+ if ( isset ( $data['_feed'] ) && isset ( $data['_feeditems'] ) ) {
$feed = $data['_feed'];
$items = $data['_feeditems'];
$feed->outHeader();
- foreach ($items as & $item)
- $feed->outItem($item);
+ foreach ( $items as & $item )
+ $feed->outItem( $item );
$feed->outFooter();
} else {
// Error has occured, print something useful
@@ -316,6 +341,6 @@ class ApiFormatFeedWrapper extends ApiFormatBase {
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiFormatBase.php 48521 2009-03-18 19:25:29Z ialex $';
+ return __CLASS__ . ': $Id: ApiFormatBase.php 62367 2010-02-12 14:09:42Z siebrand $';
}
} \ No newline at end of file
diff --git a/includes/api/ApiFormatDbg.php b/includes/api/ApiFormatDbg.php
index 254c140b..26afd329 100644
--- a/includes/api/ApiFormatDbg.php
+++ b/includes/api/ApiFormatDbg.php
@@ -23,9 +23,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ('ApiFormatBase.php');
+ require_once ( 'ApiFormatBase.php' );
}
/**
@@ -33,19 +33,19 @@ if (!defined('MEDIAWIKI')) {
*/
class ApiFormatDbg extends ApiFormatBase {
- public function __construct($main, $format) {
- parent :: __construct($main, $format);
+ public function __construct( $main, $format ) {
+ parent :: __construct( $main, $format );
}
public function getMimeType() {
- # This looks like it should be text/plain, but IE7 is so
- # brain-damaged it tries to parse text/plain as HTML if it
- # contains HTML tags. Using MIME text/text works around this bug
+ // This looks like it should be text/plain, but IE7 is so
+ // brain-damaged it tries to parse text/plain as HTML if it
+ // contains HTML tags. Using MIME text/text works around this bug
return 'text/text';
}
public function execute() {
- $this->printText(var_export($this->getResultData(), true));
+ $this->printText( var_export( $this->getResultData(), true ) );
}
public function getDescription() {
@@ -53,6 +53,6 @@ class ApiFormatDbg extends ApiFormatBase {
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiFormatDbg.php 35098 2008-05-20 17:13:28Z ialex $';
+ return __CLASS__ . ': $Id: ApiFormatDbg.php 61444 2010-01-23 22:52:40Z reedy $';
}
}
diff --git a/includes/api/ApiFormatJson.php b/includes/api/ApiFormatJson.php
index 7b5a02a4..69686bfb 100644
--- a/includes/api/ApiFormatJson.php
+++ b/includes/api/ApiFormatJson.php
@@ -23,9 +23,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ('ApiFormatBase.php');
+ require_once ( 'ApiFormatBase.php' );
}
/**
@@ -35,12 +35,17 @@ class ApiFormatJson extends ApiFormatBase {
private $mIsRaw;
- public function __construct($main, $format) {
- parent :: __construct($main, $format);
- $this->mIsRaw = ($format === 'rawfm');
+ public function __construct( $main, $format ) {
+ parent :: __construct( $main, $format );
+ $this->mIsRaw = ( $format === 'rawfm' );
}
public function getMimeType() {
+ $params = $this->extractRequestParams();
+ // callback:
+ if ( $params['callback'] ) {
+ return 'text/javascript';
+ }
return 'application/json';
}
@@ -48,30 +53,29 @@ class ApiFormatJson extends ApiFormatBase {
return $this->mIsRaw;
}
+ public function getWantsHelp() {
+ // Help is always ugly in JSON
+ return false;
+ }
+
public function execute() {
$prefix = $suffix = "";
$params = $this->extractRequestParams();
$callback = $params['callback'];
- if(!is_null($callback)) {
- $prefix = preg_replace("/[^][.\\'\\\"_A-Za-z0-9]/", "", $callback ) . "(";
+ if ( !is_null( $callback ) ) {
+ $prefix = preg_replace( "/[^][.\\'\\\"_A-Za-z0-9]/", "", $callback ) . "(";
$suffix = ")";
}
-
- // Some versions of PHP have a broken json_encode, see PHP bug
- // 46944. Test encoding an affected character (U+20000) to
- // avoid this.
- if (!function_exists('json_encode') || $this->getIsHtml() || strtolower(json_encode("\xf0\xa0\x80\x80")) != '"\ud840\udc00"') {
- $json = new Services_JSON();
- $this->printText($prefix . $json->encode($this->getResultData(), $this->getIsHtml()) . $suffix);
- } else {
- $this->printText($prefix . json_encode($this->getResultData()) . $suffix);
- }
+ $this->printText(
+ $prefix .
+ FormatJson::encode( $this->getResultData(), $this->getIsHtml() ) .
+ $suffix );
}
public function getAllowedParams() {
return array (
- 'callback' => null
+ 'callback' => null,
);
}
@@ -82,13 +86,13 @@ class ApiFormatJson extends ApiFormatBase {
}
public function getDescription() {
- if ($this->mIsRaw)
+ if ( $this->mIsRaw )
return 'Output data with the debuging elements in JSON format' . parent :: getDescription();
else
return 'Output data in JSON format' . parent :: getDescription();
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiFormatJson.php 48713 2009-03-23 19:58:07Z catrope $';
+ return __CLASS__ . ': $Id: ApiFormatJson.php 62354 2010-02-12 06:44:16Z mah $';
}
}
diff --git a/includes/api/ApiFormatJson_json.php b/includes/api/ApiFormatJson_json.php
deleted file mode 100644
index 8cb3606d..00000000
--- a/includes/api/ApiFormatJson_json.php
+++ /dev/null
@@ -1,861 +0,0 @@
-<?php
-/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
-
-/**
-* Converts to and from JSON format.
-*
-* JSON (JavaScript Object Notation) is a lightweight data-interchange
-* format. It is easy for humans to read and write. It is easy for machines
-* to parse and generate. It is based on a subset of the JavaScript
-* Programming Language, Standard ECMA-262 3rd Edition - December 1999.
-* This feature can also be found in Python. JSON is a text format that is
-* completely language independent but uses conventions that are familiar
-* to programmers of the C-family of languages, including C, C++, C#, Java,
-* JavaScript, Perl, TCL, and many others. These properties make JSON an
-* ideal data-interchange language.
-*
-* This package provides a simple encoder and decoder for JSON notation. It
-* is intended for use with client-side Javascript applications that make
-* use of HTTPRequest to perform server communication functions - data can
-* be encoded into JSON notation for use in a client-side javascript, or
-* decoded from incoming Javascript requests. JSON format is native to
-* Javascript, and can be directly eval()'ed with no further parsing
-* overhead
-*
-* All strings should be in ASCII or UTF-8 format!
-*
-* LICENSE: Redistribution and use in source and binary forms, with or
-* without modification, are permitted provided that the following
-* conditions are met: Redistributions of source code must retain the
-* above copyright notice, this list of conditions and the following
-* disclaimer. Redistributions in binary form must reproduce the above
-* copyright notice, this list of conditions and the following disclaimer
-* in the documentation and/or other materials provided with the
-* distribution.
-*
-* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
-* NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
-* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
-* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
-* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
-* DAMAGE.
-*
-* @ingroup API
-* @author Michal Migurski <mike-json@teczno.com>
-* @author Matt Knapp <mdknapp[at]gmail[dot]com>
-* @author Brett Stimmerman <brettstimmerman[at]gmail[dot]com>
-* @copyright 2005 Michal Migurski
-* @version CVS: $Id: ApiFormatJson_json.php 45765 2009-01-15 10:18:44Z catrope $
-* @license http://www.opensource.org/licenses/bsd-license.php
-* @see http://pear.php.net/pepr/pepr-proposal-show.php?id=198
-*/
-
-/**
-* Marker constant for Services_JSON::decode(), used to flag stack state
-*/
-define('SERVICES_JSON_SLICE', 1);
-
-/**
-* Marker constant for Services_JSON::decode(), used to flag stack state
-*/
-define('SERVICES_JSON_IN_STR', 2);
-
-/**
-* Marker constant for Services_JSON::decode(), used to flag stack state
-*/
-define('SERVICES_JSON_IN_ARR', 3);
-
-/**
-* Marker constant for Services_JSON::decode(), used to flag stack state
-*/
-define('SERVICES_JSON_IN_OBJ', 4);
-
-/**
-* Marker constant for Services_JSON::decode(), used to flag stack state
-*/
-define('SERVICES_JSON_IN_CMT', 5);
-
-/**
-* Behavior switch for Services_JSON::decode()
-*/
-define('SERVICES_JSON_LOOSE_TYPE', 16);
-
-/**
-* Behavior switch for Services_JSON::decode()
-*/
-define('SERVICES_JSON_SUPPRESS_ERRORS', 32);
-
-/**
- * Converts to and from JSON format.
- *
- * Brief example of use:
- *
- * <code>
- * // create a new instance of Services_JSON
- * $json = new Services_JSON();
- *
- * // convert a complexe value to JSON notation, and send it to the browser
- * $value = array('foo', 'bar', array(1, 2, 'baz'), array(3, array(4)));
- * $output = $json->encode($value);
- *
- * print($output);
- * // prints: ["foo","bar",[1,2,"baz"],[3,[4]]]
- *
- * // accept incoming POST data, assumed to be in JSON notation
- * $input = file_get_contents('php://input', 1000000);
- * $value = $json->decode($input);
- * </code>
- *
- * @ingroup API
- */
-class Services_JSON
-{
- /**
- * constructs a new JSON instance
- *
- * @param int $use object behavior flags; combine with boolean-OR
- *
- * possible values:
- * - SERVICES_JSON_LOOSE_TYPE: loose typing.
- * "{...}" syntax creates associative arrays
- * instead of objects in decode().
- * - SERVICES_JSON_SUPPRESS_ERRORS: error suppression.
- * Values which can't be encoded (e.g. resources)
- * appear as NULL instead of throwing errors.
- * By default, a deeply-nested resource will
- * bubble up with an error, so all return values
- * from encode() should be checked with isError()
- */
- function Services_JSON($use = 0)
- {
- $this->use = $use;
- }
-
- /**
- * convert a string from one UTF-16 char to one UTF-8 char
- *
- * Normally should be handled by mb_convert_encoding, but
- * provides a slower PHP-only method for installations
- * that lack the multibye string extension.
- *
- * @param string $utf16 UTF-16 character
- * @return string UTF-8 character
- * @access private
- */
- function utf162utf8($utf16)
- {
- // oh please oh please oh please oh please oh please
- if(function_exists('mb_convert_encoding')) {
- return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16');
- }
-
- $bytes = (ord($utf16{0}) << 8) | ord($utf16{1});
-
- switch(true) {
- case ((0x7F & $bytes) == $bytes):
- // this case should never be reached, because we are in ASCII range
- // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
- return chr(0x7F & $bytes);
-
- case (0x07FF & $bytes) == $bytes:
- // return a 2-byte UTF-8 character
- // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
- return chr(0xC0 | (($bytes >> 6) & 0x1F))
- . chr(0x80 | ($bytes & 0x3F));
-
- case (0xFC00 & $bytes) == 0xD800 && strlen($utf16) >= 4 && (0xFC & ord($utf16{2})) == 0xDC:
- // return a 4-byte UTF-8 character
- $char = ((($bytes & 0x03FF) << 10)
- | ((ord($utf16{2}) & 0x03) << 8)
- | ord($utf16{3}));
- $char += 0x10000;
- return chr(0xF0 | (($char >> 18) & 0x07))
- . chr(0x80 | (($char >> 12) & 0x3F))
- . chr(0x80 | (($char >> 6) & 0x3F))
- . chr(0x80 | ($char & 0x3F));
-
- case (0xFFFF & $bytes) == $bytes:
- // return a 3-byte UTF-8 character
- // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
- return chr(0xE0 | (($bytes >> 12) & 0x0F))
- . chr(0x80 | (($bytes >> 6) & 0x3F))
- . chr(0x80 | ($bytes & 0x3F));
- }
-
- // ignoring UTF-32 for now, sorry
- return '';
- }
-
- /**
- * convert a string from one UTF-8 char to one UTF-16 char
- *
- * Normally should be handled by mb_convert_encoding, but
- * provides a slower PHP-only method for installations
- * that lack the multibye string extension.
- *
- * @param string $utf8 UTF-8 character
- * @return string UTF-16 character
- * @access private
- */
- function utf82utf16($utf8)
- {
- // oh please oh please oh please oh please oh please
- if(function_exists('mb_convert_encoding')) {
- return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8');
- }
-
- switch(strlen($utf8)) {
- case 1:
- // this case should never be reached, because we are in ASCII range
- // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
- return $utf8;
-
- case 2:
- // return a UTF-16 character from a 2-byte UTF-8 char
- // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
- return chr(0x07 & (ord($utf8{0}) >> 2))
- . chr((0xC0 & (ord($utf8{0}) << 6))
- | (0x3F & ord($utf8{1})));
-
- case 3:
- // return a UTF-16 character from a 3-byte UTF-8 char
- // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
- return chr((0xF0 & (ord($utf8{0}) << 4))
- | (0x0F & (ord($utf8{1}) >> 2)))
- . chr((0xC0 & (ord($utf8{1}) << 6))
- | (0x7F & ord($utf8{2})));
-
- case 4:
- // return a UTF-16 surrogate pair from a 4-byte UTF-8 char
- if(ord($utf8{0}) > 0xF4) return ''; # invalid
- $char = ((0x1C0000 & (ord($utf8{0}) << 18))
- | (0x03F000 & (ord($utf8{1}) << 12))
- | (0x000FC0 & (ord($utf8{2}) << 6))
- | (0x00003F & ord($utf8{3})));
- if($char > 0x10FFFF) return ''; # invalid
- $char -= 0x10000;
- return chr(0xD8 | (($char >> 18) & 0x03))
- . chr(($char >> 10) & 0xFF)
- . chr(0xDC | (($char >> 8) & 0x03))
- . chr($char & 0xFF);
- }
-
- // ignoring UTF-32 for now, sorry
- return '';
- }
-
- /**
- * encodes an arbitrary variable into JSON format
- *
- * @param mixed $var any number, boolean, string, array, or object to be encoded.
- * see argument 1 to Services_JSON() above for array-parsing behavior.
- * if var is a strng, note that encode() always expects it
- * to be in ASCII or UTF-8 format!
- * @param bool $pretty pretty-print output with indents and newlines
- *
- * @return mixed JSON string representation of input var or an error if a problem occurs
- * @access public
- */
- function encode($var, $pretty=false)
- {
- $this->indent = 0;
- $this->pretty = $pretty;
- $this->nameValSeparator = $pretty ? ': ' : ':';
- return $this->encode2($var);
- }
-
- /**
- * encodes an arbitrary variable into JSON format
- *
- * @param mixed $var any number, boolean, string, array, or object to be encoded.
- * see argument 1 to Services_JSON() above for array-parsing behavior.
- * if var is a strng, note that encode() always expects it
- * to be in ASCII or UTF-8 format!
- *
- * @return mixed JSON string representation of input var or an error if a problem occurs
- * @access private
- */
- function encode2($var)
- {
- if ($this->pretty) {
- $close = "\n" . str_repeat("\t", $this->indent);
- $open = $close . "\t";
- $mid = ',' . $open;
- }
- else {
- $open = $close = '';
- $mid = ',';
- }
-
- switch (gettype($var)) {
- case 'boolean':
- return $var ? 'true' : 'false';
-
- case 'NULL':
- return 'null';
-
- case 'integer':
- return (int) $var;
-
- case 'double':
- case 'float':
- return (float) $var;
-
- case 'string':
- // STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT
- $ascii = '';
- $strlen_var = strlen($var);
-
- /*
- * Iterate over every character in the string,
- * escaping with a slash or encoding to UTF-8 where necessary
- */
- for ($c = 0; $c < $strlen_var; ++$c) {
-
- $ord_var_c = ord($var{$c});
-
- switch (true) {
- case $ord_var_c == 0x08:
- $ascii .= '\b';
- break;
- case $ord_var_c == 0x09:
- $ascii .= '\t';
- break;
- case $ord_var_c == 0x0A:
- $ascii .= '\n';
- break;
- case $ord_var_c == 0x0C:
- $ascii .= '\f';
- break;
- case $ord_var_c == 0x0D:
- $ascii .= '\r';
- break;
-
- case $ord_var_c == 0x22:
- case $ord_var_c == 0x2F:
- case $ord_var_c == 0x5C:
- // double quote, slash, slosh
- $ascii .= '\\'.$var{$c};
- break;
-
- case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)):
- // characters U-00000000 - U-0000007F (same as ASCII)
- $ascii .= $var{$c};
- break;
-
- case (($ord_var_c & 0xE0) == 0xC0):
- // characters U-00000080 - U-000007FF, mask 110XXXXX
- // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
- $char = pack('C*', $ord_var_c, ord($var{$c + 1}));
- $c += 1;
- $utf16 = $this->utf82utf16($char);
- $ascii .= sprintf('\u%04s', bin2hex($utf16));
- break;
-
- case (($ord_var_c & 0xF0) == 0xE0):
- // characters U-00000800 - U-0000FFFF, mask 1110XXXX
- // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
- $char = pack('C*', $ord_var_c,
- ord($var{$c + 1}),
- ord($var{$c + 2}));
- $c += 2;
- $utf16 = $this->utf82utf16($char);
- $ascii .= sprintf('\u%04s', bin2hex($utf16));
- break;
-
- case (($ord_var_c & 0xF8) == 0xF0):
- // characters U-00010000 - U-001FFFFF, mask 11110XXX
- // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
- // These will always return a surrogate pair
- $char = pack('C*', $ord_var_c,
- ord($var{$c + 1}),
- ord($var{$c + 2}),
- ord($var{$c + 3}));
- $c += 3;
- $utf16 = $this->utf82utf16($char);
- if($utf16 == '') {
- $ascii .= '\ufffd';
- } else {
- $utf16 = str_split($utf16, 2);
- $ascii .= sprintf('\u%04s\u%04s', bin2hex($utf16[0]), bin2hex($utf16[1]));
- }
- break;
- }
- }
-
- return '"'.$ascii.'"';
-
- case 'array':
- /*
- * As per JSON spec if any array key is not an integer
- * we must treat the the whole array as an object. We
- * also try to catch a sparsely populated associative
- * array with numeric keys here because some JS engines
- * will create an array with empty indexes up to
- * max_index which can cause memory issues and because
- * the keys, which may be relevant, will be remapped
- * otherwise.
- *
- * As per the ECMA and JSON specification an object may
- * have any string as a property. Unfortunately due to
- * a hole in the ECMA specification if the key is a
- * ECMA reserved word or starts with a digit the
- * parameter is only accessible using ECMAScript's
- * bracket notation.
- */
-
- // treat as a JSON object
- if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) {
- $this->indent++;
- $properties = array_map(array($this, 'name_value'),
- array_keys($var),
- array_values($var));
- $this->indent--;
-
- foreach($properties as $property) {
- if(Services_JSON::isError($property)) {
- return $property;
- }
- }
-
- return '{' . $open . join($mid, $properties) . $close . '}';
- }
-
- // treat it like a regular array
- $this->indent++;
- $elements = array_map(array($this, 'encode2'), $var);
- $this->indent--;
-
- foreach($elements as $element) {
- if(Services_JSON::isError($element)) {
- return $element;
- }
- }
-
- return '[' . $open . join($mid, $elements) . $close . ']';
-
- case 'object':
- $vars = get_object_vars($var);
-
- $this->indent++;
- $properties = array_map(array($this, 'name_value'),
- array_keys($vars),
- array_values($vars));
- $this->indent--;
-
- foreach($properties as $property) {
- if(Services_JSON::isError($property)) {
- return $property;
- }
- }
-
- return '{' . $open . join($mid, $properties) . $close . '}';
-
- default:
- return ($this->use & SERVICES_JSON_SUPPRESS_ERRORS)
- ? 'null'
- : new Services_JSON_Error(gettype($var)." can not be encoded as JSON string");
- }
- }
-
- /**
- * array-walking function for use in generating JSON-formatted name-value pairs
- *
- * @param string $name name of key to use
- * @param mixed $value reference to an array element to be encoded
- *
- * @return string JSON-formatted name-value pair, like '"name":value'
- * @access private
- */
- function name_value($name, $value)
- {
- $encoded_value = $this->encode2($value);
-
- if(Services_JSON::isError($encoded_value)) {
- return $encoded_value;
- }
-
- return $this->encode2(strval($name)) . $this->nameValSeparator . $encoded_value;
- }
-
- /**
- * reduce a string by removing leading and trailing comments and whitespace
- *
- * @param $str string string value to strip of comments and whitespace
- *
- * @return string string value stripped of comments and whitespace
- * @access private
- */
- function reduce_string($str)
- {
- $str = preg_replace(array(
-
- // eliminate single line comments in '// ...' form
- '#^\s*//(.+)$#m',
-
- // eliminate multi-line comments in '/* ... */' form, at start of string
- '#^\s*/\*(.+)\*/#Us',
-
- // eliminate multi-line comments in '/* ... */' form, at end of string
- '#/\*(.+)\*/\s*$#Us'
-
- ), '', $str);
-
- // eliminate extraneous space
- return trim($str);
- }
-
- /**
- * decodes a JSON string into appropriate variable
- *
- * @param string $str JSON-formatted string
- *
- * @return mixed number, boolean, string, array, or object
- * corresponding to given JSON input string.
- * See argument 1 to Services_JSON() above for object-output behavior.
- * Note that decode() always returns strings
- * in ASCII or UTF-8 format!
- * @access public
- */
- function decode($str)
- {
- $str = $this->reduce_string($str);
-
- switch (strtolower($str)) {
- case 'true':
- return true;
-
- case 'false':
- return false;
-
- case 'null':
- return null;
-
- default:
- $m = array();
-
- if (is_numeric($str)) {
- // Lookie-loo, it's a number
-
- // This would work on its own, but I'm trying to be
- // good about returning integers where appropriate:
- // return (float)$str;
-
- // Return float or int, as appropriate
- return ((float)$str == (integer)$str)
- ? (integer)$str
- : (float)$str;
-
- } elseif (preg_match('/^("|\').*(\1)$/s', $str, $m) && $m[1] == $m[2]) {
- // STRINGS RETURNED IN UTF-8 FORMAT
- $delim = substr($str, 0, 1);
- $chrs = substr($str, 1, -1);
- $utf8 = '';
- $strlen_chrs = strlen($chrs);
-
- for ($c = 0; $c < $strlen_chrs; ++$c) {
-
- $substr_chrs_c_2 = substr($chrs, $c, 2);
- $ord_chrs_c = ord($chrs{$c});
-
- switch (true) {
- case $substr_chrs_c_2 == '\b':
- $utf8 .= chr(0x08);
- ++$c;
- break;
- case $substr_chrs_c_2 == '\t':
- $utf8 .= chr(0x09);
- ++$c;
- break;
- case $substr_chrs_c_2 == '\n':
- $utf8 .= chr(0x0A);
- ++$c;
- break;
- case $substr_chrs_c_2 == '\f':
- $utf8 .= chr(0x0C);
- ++$c;
- break;
- case $substr_chrs_c_2 == '\r':
- $utf8 .= chr(0x0D);
- ++$c;
- break;
-
- case $substr_chrs_c_2 == '\\"':
- case $substr_chrs_c_2 == '\\\'':
- case $substr_chrs_c_2 == '\\\\':
- case $substr_chrs_c_2 == '\\/':
- if (($delim == '"' && $substr_chrs_c_2 != '\\\'') ||
- ($delim == "'" && $substr_chrs_c_2 != '\\"')) {
- $utf8 .= $chrs{++$c};
- }
- break;
-
- case preg_match('/\\\uD[89AB][0-9A-F]{2}\\\uD[C-F][0-9A-F]{2}/i', substr($chrs, $c, 12)):
- // escaped unicode surrogate pair
- $utf16 = chr(hexdec(substr($chrs, ($c + 2), 2)))
- . chr(hexdec(substr($chrs, ($c + 4), 2)))
- . chr(hexdec(substr($chrs, ($c + 8), 2)))
- . chr(hexdec(substr($chrs, ($c + 10), 2)));
- $utf8 .= $this->utf162utf8($utf16);
- $c += 11;
- break;
-
- case preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6)):
- // single, escaped unicode character
- $utf16 = chr(hexdec(substr($chrs, ($c + 2), 2)))
- . chr(hexdec(substr($chrs, ($c + 4), 2)));
- $utf8 .= $this->utf162utf8($utf16);
- $c += 5;
- break;
-
- case ($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F):
- $utf8 .= $chrs{$c};
- break;
-
- case ($ord_chrs_c & 0xE0) == 0xC0:
- // characters U-00000080 - U-000007FF, mask 110XXXXX
- //see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
- $utf8 .= substr($chrs, $c, 2);
- ++$c;
- break;
-
- case ($ord_chrs_c & 0xF0) == 0xE0:
- // characters U-00000800 - U-0000FFFF, mask 1110XXXX
- // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
- $utf8 .= substr($chrs, $c, 3);
- $c += 2;
- break;
-
- case ($ord_chrs_c & 0xF8) == 0xF0:
- // characters U-00010000 - U-001FFFFF, mask 11110XXX
- // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
- $utf8 .= substr($chrs, $c, 4);
- $c += 3;
- break;
-
- case ($ord_chrs_c & 0xFC) == 0xF8:
- // characters U-00200000 - U-03FFFFFF, mask 111110XX
- // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
- $utf8 .= substr($chrs, $c, 5);
- $c += 4;
- break;
-
- case ($ord_chrs_c & 0xFE) == 0xFC:
- // characters U-04000000 - U-7FFFFFFF, mask 1111110X
- // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
- $utf8 .= substr($chrs, $c, 6);
- $c += 5;
- break;
-
- }
-
- }
-
- return $utf8;
-
- } elseif (preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)) {
- // array, or object notation
-
- if ($str{0} == '[') {
- $stk = array(SERVICES_JSON_IN_ARR);
- $arr = array();
- } else {
- if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
- $stk = array(SERVICES_JSON_IN_OBJ);
- $obj = array();
- } else {
- $stk = array(SERVICES_JSON_IN_OBJ);
- $obj = new stdClass();
- }
- }
-
- array_push($stk, array( 'what' => SERVICES_JSON_SLICE,
- 'where' => 0,
- 'delim' => false));
-
- $chrs = substr($str, 1, -1);
- $chrs = $this->reduce_string($chrs);
-
- if ($chrs == '') {
- if (reset($stk) == SERVICES_JSON_IN_ARR) {
- return $arr;
-
- } else {
- return $obj;
-
- }
- }
-
- //print("\nparsing {$chrs}\n");
-
- $strlen_chrs = strlen($chrs);
-
- for ($c = 0; $c <= $strlen_chrs; ++$c) {
-
- $top = end($stk);
- $substr_chrs_c_2 = substr($chrs, $c, 2);
-
- if (($c == $strlen_chrs) || (($chrs{$c} == ',') && ($top['what'] == SERVICES_JSON_SLICE))) {
- // found a comma that is not inside a string, array, etc.,
- // OR we've reached the end of the character list
- $slice = substr($chrs, $top['where'], ($c - $top['where']));
- array_push($stk, array('what' => SERVICES_JSON_SLICE, 'where' => ($c + 1), 'delim' => false));
- //print("Found split at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
-
- if (reset($stk) == SERVICES_JSON_IN_ARR) {
- // we are in an array, so just push an element onto the stack
- array_push($arr, $this->decode($slice));
-
- } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) {
- // we are in an object, so figure
- // out the property name and set an
- // element in an associative array,
- // for now
- $parts = array();
-
- if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
- // "name":value pair
- $key = $this->decode($parts[1]);
- $val = $this->decode($parts[2]);
-
- if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
- $obj[$key] = $val;
- } else {
- $obj->$key = $val;
- }
- } elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
- // name:value pair, where name is unquoted
- $key = $parts[1];
- $val = $this->decode($parts[2]);
-
- if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
- $obj[$key] = $val;
- } else {
- $obj->$key = $val;
- }
- }
-
- }
-
- } elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != SERVICES_JSON_IN_STR)) {
- // found a quote, and we are not inside a string
- array_push($stk, array('what' => SERVICES_JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c}));
- //print("Found start of string at {$c}\n");
-
- } elseif (($chrs{$c} == $top['delim']) &&
- ($top['what'] == SERVICES_JSON_IN_STR) &&
- (($chrs{$c - 1} != '\\') ||
- ($chrs{$c - 1} == '\\' && $chrs{$c - 2} == '\\'))) {
- // found a quote, we're in a string, and it's not escaped
- array_pop($stk);
- //print("Found end of string at {$c}: ".substr($chrs, $top['where'], (1 + 1 + $c - $top['where']))."\n");
-
- } elseif (($chrs{$c} == '[') &&
- in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
- // found a left-bracket, and we are in an array, object, or slice
- array_push($stk, array('what' => SERVICES_JSON_IN_ARR, 'where' => $c, 'delim' => false));
- //print("Found start of array at {$c}\n");
-
- } elseif (($chrs{$c} == ']') && ($top['what'] == SERVICES_JSON_IN_ARR)) {
- // found a right-bracket, and we're in an array
- array_pop($stk);
- //print("Found end of array at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
-
- } elseif (($chrs{$c} == '{') &&
- in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
- // found a left-brace, and we are in an array, object, or slice
- array_push($stk, array('what' => SERVICES_JSON_IN_OBJ, 'where' => $c, 'delim' => false));
- //print("Found start of object at {$c}\n");
-
- } elseif (($chrs{$c} == '}') && ($top['what'] == SERVICES_JSON_IN_OBJ)) {
- // found a right-brace, and we're in an object
- array_pop($stk);
- //print("Found end of object at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
-
- } elseif (($substr_chrs_c_2 == '/*') &&
- in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
- // found a comment start, and we are in an array, object, or slice
- array_push($stk, array('what' => SERVICES_JSON_IN_CMT, 'where' => $c, 'delim' => false));
- $c++;
- //print("Found start of comment at {$c}\n");
-
- } elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == SERVICES_JSON_IN_CMT)) {
- // found a comment end, and we're in one now
- array_pop($stk);
- $c++;
-
- for ($i = $top['where']; $i <= $c; ++$i)
- $chrs = substr_replace($chrs, ' ', $i, 1);
-
- //print("Found end of comment at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
-
- }
-
- }
-
- if (reset($stk) == SERVICES_JSON_IN_ARR) {
- return $arr;
-
- } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) {
- return $obj;
-
- }
-
- }
- }
- }
-
- /**
- * @todo Ultimately, this should just call PEAR::isError()
- */
- function isError($data, $code = null)
- {
- if (class_exists('pear')) {
- return PEAR::isError($data, $code);
- } elseif (is_object($data) && (get_class($data) == 'services_json_error' ||
- is_subclass_of($data, 'services_json_error'))) {
- return true;
- }
-
- return false;
- }
-}
-
-
-// Hide the PEAR_Error variant from Doxygen
-/// @cond
-if (class_exists('PEAR_Error')) {
-
- /**
- * @ingroup API
- */
- class Services_JSON_Error extends PEAR_Error
- {
- function Services_JSON_Error($message = 'unknown error', $code = null,
- $mode = null, $options = null, $userinfo = null)
- {
- parent::PEAR_Error($message, $code, $mode, $options, $userinfo);
- }
- }
-
-} else {
-/// @endcond
-
- /**
- * @todo Ultimately, this class shall be descended from PEAR_Error
- * @ingroup API
- */
- class Services_JSON_Error
- {
- function Services_JSON_Error($message = 'unknown error', $code = null,
- $mode = null, $options = null, $userinfo = null)
- {
-
- }
- }
-}
diff --git a/includes/api/ApiFormatPhp.php b/includes/api/ApiFormatPhp.php
index 163d3028..dd03c300 100644
--- a/includes/api/ApiFormatPhp.php
+++ b/includes/api/ApiFormatPhp.php
@@ -23,9 +23,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ('ApiFormatBase.php');
+ require_once ( 'ApiFormatBase.php' );
}
/**
@@ -33,8 +33,8 @@ if (!defined('MEDIAWIKI')) {
*/
class ApiFormatPhp extends ApiFormatBase {
- public function __construct($main, $format) {
- parent :: __construct($main, $format);
+ public function __construct( $main, $format ) {
+ parent :: __construct( $main, $format );
}
public function getMimeType() {
@@ -42,7 +42,7 @@ class ApiFormatPhp extends ApiFormatBase {
}
public function execute() {
- $this->printText(serialize($this->getResultData()));
+ $this->printText( serialize( $this->getResultData() ) );
}
public function getDescription() {
@@ -50,6 +50,6 @@ class ApiFormatPhp extends ApiFormatBase {
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiFormatPhp.php 35098 2008-05-20 17:13:28Z ialex $';
+ return __CLASS__ . ': $Id: ApiFormatPhp.php 60930 2010-01-11 15:55:52Z simetrical $';
}
}
diff --git a/includes/api/ApiFormatRaw.php b/includes/api/ApiFormatRaw.php
index 51025448..8bb66aea 100644
--- a/includes/api/ApiFormatRaw.php
+++ b/includes/api/ApiFormatRaw.php
@@ -23,9 +23,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ('ApiFormatBase.php');
+ require_once ( 'ApiFormatBase.php' );
}
/**
@@ -39,33 +39,37 @@ class ApiFormatRaw extends ApiFormatBase {
* @param $main ApiMain object
* @param $errorFallback Formatter object to fall back on for errors
*/
- public function __construct($main, $errorFallback) {
- parent :: __construct($main, 'raw');
+ public function __construct( $main, $errorFallback ) {
+ parent :: __construct( $main, 'raw' );
$this->mErrorFallback = $errorFallback;
}
public function getMimeType() {
$data = $this->getResultData();
- if(isset($data['error']))
+
+ if ( isset( $data['error'] ) )
return $this->mErrorFallback->getMimeType();
- if(!isset($data['mime']))
- ApiBase::dieDebug(__METHOD__, "No MIME type set for raw formatter");
+
+ if ( !isset( $data['mime'] ) )
+ ApiBase::dieDebug( __METHOD__, "No MIME type set for raw formatter" );
+
return $data['mime'];
}
public function execute() {
$data = $this->getResultData();
- if(isset($data['error']))
+ if ( isset( $data['error'] ) )
{
$this->mErrorFallback->execute();
return;
}
- if(!isset($data['text']))
- ApiBase::dieDebug(__METHOD__, "No text given for raw formatter");
- $this->printText($data['text']);
+
+ if ( !isset( $data['text'] ) )
+ ApiBase::dieDebug( __METHOD__, "No text given for raw formatter" );
+ $this->printText( $data['text'] );
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiFormatRaw.php 48629 2009-03-20 11:40:54Z catrope $';
+ return __CLASS__ . ': $Id: ApiFormatRaw.php 61437 2010-01-23 22:26:40Z reedy $';
}
}
diff --git a/includes/api/ApiFormatTxt.php b/includes/api/ApiFormatTxt.php
index 5f608d5c..1627dde6 100644
--- a/includes/api/ApiFormatTxt.php
+++ b/includes/api/ApiFormatTxt.php
@@ -23,9 +23,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ('ApiFormatBase.php');
+ require_once ( 'ApiFormatBase.php' );
}
/**
@@ -33,19 +33,19 @@ if (!defined('MEDIAWIKI')) {
*/
class ApiFormatTxt extends ApiFormatBase {
- public function __construct($main, $format) {
- parent :: __construct($main, $format);
+ public function __construct( $main, $format ) {
+ parent :: __construct( $main, $format );
}
public function getMimeType() {
- # This looks like it should be text/plain, but IE7 is so
- # brain-damaged it tries to parse text/plain as HTML if it
- # contains HTML tags. Using MIME text/text works around this bug
+ // This looks like it should be text/plain, but IE7 is so
+ // brain-damaged it tries to parse text/plain as HTML if it
+ // contains HTML tags. Using MIME text/text works around this bug
return 'text/text';
}
public function execute() {
- $this->printText(print_r($this->getResultData(), true));
+ $this->printText( print_r( $this->getResultData(), true ) );
}
public function getDescription() {
@@ -53,6 +53,6 @@ class ApiFormatTxt extends ApiFormatBase {
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiFormatTxt.php 35098 2008-05-20 17:13:28Z ialex $';
+ return __CLASS__ . ': $Id: ApiFormatTxt.php 61444 2010-01-23 22:52:40Z reedy $';
}
}
diff --git a/includes/api/ApiFormatWddx.php b/includes/api/ApiFormatWddx.php
index a716373d..e95e540b 100644
--- a/includes/api/ApiFormatWddx.php
+++ b/includes/api/ApiFormatWddx.php
@@ -23,9 +23,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ('ApiFormatBase.php');
+ require_once ( 'ApiFormatBase.php' );
}
/**
@@ -33,8 +33,8 @@ if (!defined('MEDIAWIKI')) {
*/
class ApiFormatWddx extends ApiFormatBase {
- public function __construct($main, $format) {
- parent :: __construct($main, $format);
+ public function __construct( $main, $format ) {
+ parent :: __construct( $main, $format );
}
public function getMimeType() {
@@ -46,67 +46,66 @@ class ApiFormatWddx extends ApiFormatBase {
// PHP bug 45314. Test encoding an affected character (U+00A0)
// to avoid this.
$expected = "<wddxPacket version='1.0'><header/><data><string>\xc2\xa0</string></data></wddxPacket>";
- if (function_exists('wddx_serialize_value')
+ if ( function_exists( 'wddx_serialize_value' )
&& !$this->getIsHtml()
- && wddx_serialize_value("\xc2\xa0") == $expected) {
- $this->printText(wddx_serialize_value($this->getResultData()));
+ && wddx_serialize_value( "\xc2\xa0" ) == $expected ) {
+ $this->printText( wddx_serialize_value( $this->getResultData() ) );
} else {
// Don't do newlines and indentation if we weren't asked
// for pretty output
- $nl = ($this->getIsHtml() ? "" : "\n");
+ $nl = ( $this->getIsHtml() ? "" : "\n" );
$indstr = " ";
- $this->printText("<?xml version=\"1.0\"?>$nl");
- $this->printText("<wddxPacket version=\"1.0\">$nl");
- $this->printText("$indstr<header/>$nl");
- $this->printText("$indstr<data>$nl");
- $this->slowWddxPrinter($this->getResultData(), 4);
- $this->printText("$indstr</data>$nl");
- $this->printText("</wddxPacket>$nl");
+ $this->printText( "<?xml version=\"1.0\"?>$nl" );
+ $this->printText( "<wddxPacket version=\"1.0\">$nl" );
+ $this->printText( "$indstr<header/>$nl" );
+ $this->printText( "$indstr<data>$nl" );
+ $this->slowWddxPrinter( $this->getResultData(), 4 );
+ $this->printText( "$indstr</data>$nl" );
+ $this->printText( "</wddxPacket>$nl" );
}
}
/**
* Recursively go through the object and output its data in WDDX format.
*/
- function slowWddxPrinter($elemValue, $indent = 0) {
- $indstr = ($this->getIsHtml() ? "" : str_repeat(' ', $indent));
- $indstr2 = ($this->getIsHtml() ? "" : str_repeat(' ', $indent + 2));
- $nl = ($this->getIsHtml() ? "" : "\n");
- switch (gettype($elemValue)) {
+ function slowWddxPrinter( $elemValue, $indent = 0 ) {
+ $indstr = ( $this->getIsHtml() ? "" : str_repeat( ' ', $indent ) );
+ $indstr2 = ( $this->getIsHtml() ? "" : str_repeat( ' ', $indent + 2 ) );
+ $nl = ( $this->getIsHtml() ? "" : "\n" );
+ switch ( gettype( $elemValue ) ) {
case 'array' :
// Check whether we've got an associative array (<struct>)
// or a regular array (<array>)
- $cnt = count($elemValue);
- if($cnt == 0 || array_keys($elemValue) === range(0, $cnt - 1)) {
+ $cnt = count( $elemValue );
+ if ( $cnt == 0 || array_keys( $elemValue ) === range( 0, $cnt - 1 ) ) {
// Regular array
- $this->printText($indstr . Xml::element('array', array(
- 'length' => $cnt
- ), null) . $nl);
- foreach($elemValue as $subElemValue)
- $this->slowWddxPrinter($subElemValue, $indent + 2);
- $this->printText("$indstr</array>$nl");
+ $this->printText( $indstr . Xml::element( 'array', array(
+ 'length' => $cnt ), null ) . $nl );
+ foreach ( $elemValue as $subElemValue )
+ $this->slowWddxPrinter( $subElemValue, $indent + 2 );
+ $this->printText( "$indstr</array>$nl" );
} else {
// Associative array (<struct>)
- $this->printText("$indstr<struct>$nl");
- foreach($elemValue as $subElemName => $subElemValue) {
- $this->printText($indstr2 . Xml::element('var', array(
+ $this->printText( "$indstr<struct>$nl" );
+ foreach ( $elemValue as $subElemName => $subElemValue ) {
+ $this->printText( $indstr2 . Xml::element( 'var', array(
'name' => $subElemName
- ), null) . $nl);
- $this->slowWddxPrinter($subElemValue, $indent + 4);
- $this->printText("$indstr2</var>$nl");
+ ), null ) . $nl );
+ $this->slowWddxPrinter( $subElemValue, $indent + 4 );
+ $this->printText( "$indstr2</var>$nl" );
}
- $this->printText("$indstr</struct>$nl");
+ $this->printText( "$indstr</struct>$nl" );
}
break;
case 'integer' :
case 'double' :
- $this->printText($indstr . Xml::element('number', null, $elemValue) . $nl);
+ $this->printText( $indstr . Xml::element( 'number', null, $elemValue ) . $nl );
break;
case 'string' :
- $this->printText($indstr . Xml::element('string', null, $elemValue) . $nl);
+ $this->printText( $indstr . Xml::element( 'string', null, $elemValue ) . $nl );
break;
default :
- ApiBase :: dieDebug(__METHOD__, 'Unknown type ' . gettype($elemValue));
+ ApiBase :: dieDebug( __METHOD__, 'Unknown type ' . gettype( $elemValue ) );
}
}
@@ -115,6 +114,6 @@ class ApiFormatWddx extends ApiFormatBase {
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiFormatWddx.php 48716 2009-03-23 20:06:16Z catrope $';
+ return __CLASS__ . ': $Id: ApiFormatWddx.php 61437 2010-01-23 22:26:40Z reedy $';
}
}
diff --git a/includes/api/ApiFormatXml.php b/includes/api/ApiFormatXml.php
index 35b412c9..a3758a49 100644
--- a/includes/api/ApiFormatXml.php
+++ b/includes/api/ApiFormatXml.php
@@ -23,9 +23,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ('ApiFormatBase.php');
+ require_once ( 'ApiFormatBase.php' );
}
/**
@@ -35,9 +35,10 @@ class ApiFormatXml extends ApiFormatBase {
private $mRootElemName = 'api';
private $mDoubleQuote = false;
+ private $mXslt = null;
- public function __construct($main, $format) {
- parent :: __construct($main, $format);
+ public function __construct( $main, $format ) {
+ parent :: __construct( $main, $format );
}
public function getMimeType() {
@@ -48,16 +49,22 @@ class ApiFormatXml extends ApiFormatBase {
return true;
}
- public function setRootElement($rootElemName) {
+ public function setRootElement( $rootElemName ) {
$this->mRootElemName = $rootElemName;
}
public function execute() {
$params = $this->extractRequestParams();
$this->mDoubleQuote = $params['xmldoublequote'];
-
- $this->printText('<?xml version="1.0"?>');
- $this->recXmlPrint($this->mRootElemName, $this->getResultData(), $this->getIsHtml() ? -2 : null);
+ $this->mXslt = $params['xslt'];
+
+ $this->printText( '<?xml version="1.0"?>' );
+ if ( !is_null( $this->mXslt ) )
+ $this->addXslt();
+ $this->printText( self::recXmlPrint( $this->mRootElemName,
+ $this->getResultData(),
+ $this->getIsHtml() ? - 2 : null,
+ $this->mDoubleQuote ) );
}
/**
@@ -73,22 +80,23 @@ class ApiFormatXml extends ApiFormatBase {
* 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) {
- if (!is_null($indent)) {
+ public static function recXmlPrint( $elemName, $elemValue, $indent, $doublequote = false ) {
+ $retval = '';
+ if ( !is_null( $indent ) ) {
$indent += 2;
- $indstr = "\n" . str_repeat(" ", $indent);
+ $indstr = "\n" . str_repeat( " ", $indent );
} else {
$indstr = '';
}
- $elemName = str_replace(' ', '_', $elemName);
+ $elemName = str_replace( ' ', '_', $elemName );
- switch (gettype($elemValue)) {
+ switch ( gettype( $elemValue ) ) {
case 'array' :
- if (isset ($elemValue['*'])) {
+ if ( isset ( $elemValue['*'] ) ) {
$subElemContent = $elemValue['*'];
- if ($this->mDoubleQuote)
- $subElemContent = $this->doubleQuote($subElemContent);
- unset ($elemValue['*']);
+ if ( $doublequote )
+ $subElemContent = Sanitizer::encodeAttribute( $subElemContent );
+ unset ( $elemValue['*'] );
// Add xml:space="preserve" to the
// element so XML parsers will leave
@@ -98,80 +106,95 @@ class ApiFormatXml extends ApiFormatBase {
$subElemContent = null;
}
- if (isset ($elemValue['_element'])) {
+ if ( isset ( $elemValue['_element'] ) ) {
$subElemIndName = $elemValue['_element'];
- unset ($elemValue['_element']);
+ unset ( $elemValue['_element'] );
} else {
$subElemIndName = null;
}
$indElements = array ();
$subElements = array ();
- foreach ($elemValue as $subElemId => & $subElemValue) {
- if (is_string($subElemValue) && $this->mDoubleQuote)
- $subElemValue = $this->doubleQuote($subElemValue);
+ foreach ( $elemValue as $subElemId => & $subElemValue ) {
+ if ( is_string( $subElemValue ) && $doublequote )
+ $subElemValue = Sanitizer::encodeAttribute( $subElemValue );
- if (gettype($subElemId) === 'integer') {
+ if ( gettype( $subElemId ) === 'integer' ) {
$indElements[] = $subElemValue;
- unset ($elemValue[$subElemId]);
- } elseif (is_array($subElemValue)) {
+ unset ( $elemValue[$subElemId] );
+ } elseif ( is_array( $subElemValue ) ) {
$subElements[$subElemId] = $subElemValue;
- unset ($elemValue[$subElemId]);
+ unset ( $elemValue[$subElemId] );
}
}
- if (is_null($subElemIndName) && count($indElements))
- ApiBase :: dieDebug(__METHOD__, "($elemName, ...) has integer keys without _element value. Use ApiResult::setIndexedTagName().");
+ if ( is_null( $subElemIndName ) && count( $indElements ) )
+ ApiBase :: dieDebug( __METHOD__, "($elemName, ...) has integer keys without _element value. Use ApiResult::setIndexedTagName()." );
- if (count($subElements) && count($indElements) && !is_null($subElemContent))
- ApiBase :: dieDebug(__METHOD__, "($elemName, ...) has content and subelements");
+ if ( count( $subElements ) && count( $indElements ) && !is_null( $subElemContent ) )
+ ApiBase :: dieDebug( __METHOD__, "($elemName, ...) has content and subelements" );
- if (!is_null($subElemContent)) {
- $this->printText($indstr . Xml::element($elemName, $elemValue, $subElemContent));
- } elseif (!count($indElements) && !count($subElements)) {
- $this->printText($indstr . Xml::element($elemName, $elemValue));
+ if ( !is_null( $subElemContent ) ) {
+ $retval .= $indstr . Xml::element( $elemName, $elemValue, $subElemContent );
+ } elseif ( !count( $indElements ) && !count( $subElements ) ) {
+ $retval .= $indstr . Xml::element( $elemName, $elemValue );
} else {
- $this->printText($indstr . Xml::element($elemName, $elemValue, null));
+ $retval .= $indstr . Xml::element( $elemName, $elemValue, null );
- foreach ($subElements as $subElemId => & $subElemValue)
- $this->recXmlPrint($subElemId, $subElemValue, $indent);
+ foreach ( $subElements as $subElemId => & $subElemValue )
+ $retval .= self::recXmlPrint( $subElemId, $subElemValue, $indent );
- foreach ($indElements as $subElemId => & $subElemValue)
- $this->recXmlPrint($subElemIndName, $subElemValue, $indent);
+ foreach ( $indElements as $subElemId => & $subElemValue )
+ $retval .= self::recXmlPrint( $subElemIndName, $subElemValue, $indent );
- $this->printText($indstr . Xml::closeElement($elemName));
+ $retval .= $indstr . Xml::closeElement( $elemName );
}
break;
case 'object' :
// ignore
break;
default :
- $this->printText($indstr . Xml::element($elemName, null, $elemValue));
+ $retval .= $indstr . Xml::element( $elemName, null, $elemValue );
break;
}
+ return $retval;
}
- private function doubleQuote( $text ) {
- return Sanitizer::encodeAttribute( $text );
+ function addXslt() {
+ $nt = Title::newFromText( $this->mXslt );
+ if ( is_null( $nt ) || !$nt->exists() ) {
+ $this->setWarning( 'Invalid or non-existent stylesheet specified' );
+ return;
+ }
+ if ( $nt->getNamespace() != NS_MEDIAWIKI ) {
+ $this->setWarning( 'Stylesheet should be in the MediaWiki namespace.' );
+ return;
+ }
+ if ( substr( $nt->getText(), - 4 ) !== '.xsl' ) {
+ $this->setWarning( 'Stylesheet should have .xsl extension.' );
+ return;
+ }
+ $this->printText( '<?xml-stylesheet href="' . $nt->escapeLocalURL( 'action=raw' ) . '" type="text/xsl" ?>' );
}
-
+
public function getAllowedParams() {
return array (
- 'xmldoublequote' => false
+ 'xmldoublequote' => false,
+ 'xslt' => null,
);
}
public function getParamDescription() {
return array (
'xmldoublequote' => 'If specified, double quotes all attributes and content.',
+ 'xslt' => 'If specified, adds <xslt> as stylesheet',
);
}
-
public function getDescription() {
return 'Output data in XML format' . parent :: getDescription();
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiFormatXml.php 50217 2009-05-05 13:12:16Z tstarling $';
+ return __CLASS__ . ': $Id: ApiFormatXml.php 62402 2010-02-13 00:09:05Z reedy $';
}
}
diff --git a/includes/api/ApiFormatYaml.php b/includes/api/ApiFormatYaml.php
index cc255c63..39381b0f 100644
--- a/includes/api/ApiFormatYaml.php
+++ b/includes/api/ApiFormatYaml.php
@@ -23,9 +23,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ('ApiFormatBase.php');
+ require_once ( 'ApiFormatBase.php' );
}
/**
@@ -33,8 +33,8 @@ if (!defined('MEDIAWIKI')) {
*/
class ApiFormatYaml extends ApiFormatBase {
- public function __construct($main, $format) {
- parent :: __construct($main, $format);
+ public function __construct( $main, $format ) {
+ parent :: __construct( $main, $format );
}
public function getMimeType() {
@@ -42,7 +42,7 @@ class ApiFormatYaml extends ApiFormatBase {
}
public function execute() {
- $this->printText(Spyc :: YAMLDump($this->getResultData()));
+ $this->printText( Spyc :: YAMLDump( $this->getResultData() ) );
}
public function getDescription() {
@@ -50,6 +50,6 @@ class ApiFormatYaml extends ApiFormatBase {
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiFormatYaml.php 35098 2008-05-20 17:13:28Z ialex $';
+ return __CLASS__ . ': $Id: ApiFormatYaml.php 60930 2010-01-11 15:55:52Z simetrical $';
}
}
diff --git a/includes/api/ApiFormatYaml_spyc.php b/includes/api/ApiFormatYaml_spyc.php
index f16b2c8a..30f860dd 100644
--- a/includes/api/ApiFormatYaml_spyc.php
+++ b/includes/api/ApiFormatYaml_spyc.php
@@ -38,9 +38,9 @@ class Spyc {
* @param $indent Integer: Pass in false to use the default, which is 2
* @param $wordwrap Integer: Pass in 0 for no wordwrap, false for default (40)
*/
- public static function YAMLDump($array,$indent = false,$wordwrap = false) {
+ public static function YAMLDump( $array, $indent = false, $wordwrap = false ) {
$spyc = new Spyc;
- return $spyc->dump($array,$indent,$wordwrap);
+ return $spyc->dump( $array, $indent, $wordwrap );
}
/**
@@ -63,18 +63,18 @@ class Spyc {
* @param $indent Integer: Pass in false to use the default, which is 2
* @param $wordwrap Integer: Pass in 0 for no wordwrap, false for default (40)
*/
- function dump($array,$indent = false,$wordwrap = false) {
+ function dump( $array, $indent = false, $wordwrap = false ) {
// Dumps to some very clean YAML. We'll have to add some more features
// and options soon. And better support for folding.
// New features and options.
- if ($indent === false or !is_numeric($indent)) {
+ if ( $indent === false or !is_numeric( $indent ) ) {
$this->_dumpIndent = 2;
} else {
$this->_dumpIndent = $indent;
}
- if ($wordwrap === false or !is_numeric($wordwrap)) {
+ if ( $wordwrap === false or !is_numeric( $wordwrap ) ) {
$this->_dumpWordWrap = 40;
} else {
$this->_dumpWordWrap = $wordwrap;
@@ -84,8 +84,8 @@ class Spyc {
$string = "---\n";
// Start at the base of the array and move through it.
- foreach ($array as $key => $value) {
- $string .= $this->_yamlize($key,$value,0);
+ foreach ( $array as $key => $value ) {
+ $string .= $this->_yamlize( $key, $value, 0 );
}
return $string;
}
@@ -110,18 +110,18 @@ class Spyc {
* @param $value The value of the item
* @param $indent The indent of the current node
*/
- private function _yamlize($key,$value,$indent) {
- if (is_array($value)) {
+ private function _yamlize( $key, $value, $indent ) {
+ if ( is_array( $value ) ) {
// It has children. What to do?
// Make it the right kind of item
- $string = $this->_dumpNode($key,NULL,$indent);
+ $string = $this->_dumpNode( $key, null, $indent );
// Add the indent
$indent += $this->_dumpIndent;
// Yamlize the array
- $string .= $this->_yamlizeArray($value,$indent);
- } elseif (!is_array($value)) {
+ $string .= $this->_yamlizeArray( $value, $indent );
+ } elseif ( !is_array( $value ) ) {
// It doesn't have children. Yip.
- $string = $this->_dumpNode($key,$value,$indent);
+ $string = $this->_dumpNode( $key, $value, $indent );
}
return $string;
}
@@ -132,11 +132,11 @@ class Spyc {
* @param $array The array you want to convert
* @param $indent The indent of the current level
*/
- private function _yamlizeArray($array,$indent) {
- if (is_array($array)) {
+ private function _yamlizeArray( $array, $indent ) {
+ if ( is_array( $array ) ) {
$string = '';
- foreach ($array as $key => $value) {
- $string .= $this->_yamlize($key,$value,$indent);
+ foreach ( $array as $key => $value ) {
+ $string .= $this->_yamlize( $key, $value, $indent );
}
return $string;
} else {
@@ -150,16 +150,15 @@ class Spyc {
* @param $value The string to check
* @return bool
*/
- function _needLiteral($value) {
- # Check whether the string contains # or : or begins with any of:
- # [ - ? , [ ] { } ! * & | > ' " % @ ` ]
- # or is a number or contains newlines
- return (bool)(gettype($value) == "string" &&
- (is_numeric($value) ||
- strpos($value, "\n") ||
- preg_match("/[#:]/", $value) ||
- preg_match("/^[-?,[\]{}!*&|>'\"%@`]/", $value)));
-
+ function _needLiteral( $value ) {
+ // Check whether the string contains # or : or begins with any of:
+ // [ - ? , [ ] { } ! * & | > ' " % @ ` ]
+ // or is a number or contains newlines
+ return (bool)( gettype( $value ) == "string" &&
+ ( is_numeric( $value ) ||
+ strpos( $value, "\n" ) ||
+ preg_match( "/[#:]/", $value ) ||
+ preg_match( "/^[-?,[\]{}!*&|>'\"%@`]/", $value ) ) );
}
/**
@@ -169,25 +168,28 @@ class Spyc {
* @param $value The value of the item
* @param $indent The indent of the current node
*/
- private function _dumpNode($key,$value,$indent) {
+ private function _dumpNode( $key, $value, $indent ) {
// do some folding here, for blocks
- if ($this->_needLiteral($value)) {
- $value = $this->_doLiteralBlock($value,$indent);
+ if ( $this->_needLiteral( $value ) ) {
+ $value = $this->_doLiteralBlock( $value, $indent );
} else {
- $value = $this->_doFolding($value,$indent);
+ $value = $this->_doFolding( $value, $indent );
}
- $spaces = str_repeat(' ',$indent);
+ $spaces = str_repeat( ' ', $indent );
- if (is_int($key)) {
+ if ( is_int( $key ) ) {
// It's a sequence
- if ($value !== '' && !is_null($value))
- $string = $spaces.'- '.$value."\n";
+ if ( $value !== '' && !is_null( $value ) )
+ $string = $spaces . '- ' . $value . "\n";
else
$string = $spaces . "-\n";
} else {
+ if ($key == '*') //bug 21922 - Quote asterix used as keys
+ $key = "'*'";
+
// It's mapped
- if ($value !== '' && !is_null($value))
+ if ( $value !== '' && !is_null( $value ) )
$string = $spaces . $key . ': ' . $value . "\n";
else
$string = $spaces . $key . ":\n";
@@ -201,13 +203,13 @@ class Spyc {
* @param $value
* @param $indent int The value of the indent
*/
- private function _doLiteralBlock($value,$indent) {
- $exploded = explode("\n",$value);
- $newValue = '|';
+ private function _doLiteralBlock( $value, $indent ) {
+ $exploded = explode( "\n", $value );
+ $newValue = '|-';
$indent += $this->_dumpIndent;
- $spaces = str_repeat(' ',$indent);
- foreach ($exploded as $line) {
- $newValue .= "\n" . $spaces . trim($line);
+ $spaces = str_repeat( ' ', $indent );
+ foreach ( $exploded as $line ) {
+ $newValue .= "\n" . $spaces . trim( $line );
}
return $newValue;
}
@@ -217,17 +219,17 @@ class Spyc {
* @return string
* @param $value The string you wish to fold
*/
- private function _doFolding($value,$indent) {
+ private function _doFolding( $value, $indent ) {
// Don't do anything if wordwrap is set to 0
- if ($this->_dumpWordWrap === 0) {
+ if ( $this->_dumpWordWrap === 0 ) {
return $value;
}
- if (strlen($value) > $this->_dumpWordWrap) {
+ if ( strlen( $value ) > $this->_dumpWordWrap ) {
$indent += $this->_dumpIndent;
- $indent = str_repeat(' ',$indent);
- $wrapped = wordwrap($value,$this->_dumpWordWrap,"\n$indent");
- $value = ">\n".$indent.$wrapped;
+ $indent = str_repeat( ' ', $indent );
+ $wrapped = wordwrap( $value, $this->_dumpWordWrap, "\n$indent" );
+ $value = ">-\n" . $indent . $wrapped;
}
return $value;
}
diff --git a/includes/api/ApiHelp.php b/includes/api/ApiHelp.php
index c001a7dc..1f32e019 100644
--- a/includes/api/ApiHelp.php
+++ b/includes/api/ApiHelp.php
@@ -23,9 +23,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ('ApiBase.php');
+ require_once ( 'ApiBase.php' );
}
/**
@@ -35,15 +35,15 @@ if (!defined('MEDIAWIKI')) {
*/
class ApiHelp extends ApiBase {
- public function __construct($main, $action) {
- parent :: __construct($main, $action);
+ public function __construct( $main, $action ) {
+ parent :: __construct( $main, $action );
}
/**
* Stub module for displaying help when no parameters are given
*/
public function execute() {
- $this->dieUsage('', 'help');
+ $this->dieUsage( '', 'help' );
}
public function shouldCheckMaxlag() {
@@ -61,6 +61,6 @@ class ApiHelp extends ApiBase {
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiHelp.php 48091 2009-03-06 13:49:44Z catrope $';
+ return __CLASS__ . ': $Id: ApiHelp.php 60930 2010-01-11 15:55:52Z simetrical $';
}
}
diff --git a/includes/api/ApiImport.php b/includes/api/ApiImport.php
index 4b1518bb..032b684c 100644
--- a/includes/api/ApiImport.php
+++ b/includes/api/ApiImport.php
@@ -23,9 +23,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ('ApiBase.php');
+ require_once ( 'ApiBase.php' );
}
/**
@@ -35,70 +35,68 @@ if (!defined('MEDIAWIKI')) {
*/
class ApiImport extends ApiBase {
- public function __construct($main, $action) {
- parent :: __construct($main, $action);
+ public function __construct( $main, $action ) {
+ parent :: __construct( $main, $action );
}
public function execute() {
global $wgUser;
- if(!$wgUser->isAllowed('import'))
- $this->dieUsageMsg(array('cantimport'));
+ if ( !$wgUser->isAllowed( 'import' ) )
+ $this->dieUsageMsg( array( 'cantimport' ) );
$params = $this->extractRequestParams();
- if(!isset($params['token']))
- $this->dieUsageMsg(array('missingparam', 'token'));
- if(!$wgUser->matchEditToken($params['token']))
- $this->dieUsageMsg(array('sessionfailure'));
$source = null;
$isUpload = false;
- if(isset($params['interwikisource']))
+ if ( isset( $params['interwikisource'] ) )
{
- if(!isset($params['interwikipage']))
- $this->dieUsageMsg(array('missingparam', 'interwikipage'));
+ if ( !isset( $params['interwikipage'] ) )
+ $this->dieUsageMsg( array( 'missingparam', 'interwikipage' ) );
$source = ImportStreamSource::newFromInterwiki(
$params['interwikisource'],
$params['interwikipage'],
$params['fullhistory'],
- $params['templates']);
+ $params['templates'] );
}
else
{
$isUpload = true;
- if(!$wgUser->isAllowed('importupload'))
- $this->dieUsageMsg(array('cantimport-upload'));
- $source = ImportStreamSource::newFromUpload('xml');
+ if ( !$wgUser->isAllowed( 'importupload' ) )
+ $this->dieUsageMsg( array( 'cantimport-upload' ) );
+ $source = ImportStreamSource::newFromUpload( 'xml' );
}
- if($source instanceof WikiErrorMsg)
- $this->dieUsageMsg(array_merge(
- array($source->getMessageKey()),
- $source->getMessageArgs()));
- else if(WikiError::isError($source))
+ if ( $source instanceof WikiErrorMsg )
+ $this->dieUsageMsg( array_merge(
+ array( $source->getMessageKey() ),
+ $source->getMessageArgs() ) );
+ else if ( WikiError::isError( $source ) )
// This shouldn't happen
- $this->dieUsageMsg(array('import-unknownerror', $source->getMessage()));
+ $this->dieUsageMsg( array( 'import-unknownerror', $source->getMessage() ) );
- $importer = new WikiImporter($source);
- if(isset($params['namespace']))
- $importer->setTargetNamespace($params['namespace']);
- $reporter = new ApiImportReporter($importer, $isUpload,
+ $importer = new WikiImporter( $source );
+ if ( isset( $params['namespace'] ) )
+ $importer->setTargetNamespace( $params['namespace'] );
+ $reporter = new ApiImportReporter( $importer, $isUpload,
$params['interwikisource'],
- $params['summary']);
+ $params['summary'] );
$result = $importer->doImport();
- if($result instanceof WikiXmlError)
- $this->dieUsageMsg(array('import-xml-error',
+ if ( $result instanceof WikiXmlError )
+ $this->dieUsageMsg( array( 'import-xml-error',
$result->mLine,
$result->mColumn,
$result->mByte . $result->mContext,
- xml_error_string($result->mXmlError)));
- else if(WikiError::isError($result))
- // This shouldn't happen
- $this->dieUsageMsg(array('import-unknownerror', $result->getMessage()));
+ xml_error_string( $result->mXmlError ) ) );
+ else if ( WikiError::isError( $result ) )
+ $this->dieUsageMsg( array( 'import-unknownerror', $result->getMessage() ) ); // This shouldn't happen
+
$resultData = $reporter->getData();
- $this->getResult()->setIndexedTagName($resultData, 'page');
- $this->getResult()->addValue(null, $this->getModuleName(), $resultData);
+ $this->getResult()->setIndexedTagName( $resultData, 'page' );
+ $this->getResult()->addValue( null, $this->getModuleName(), $resultData );
}
- public function mustBePosted() { return true; }
+ public function mustBePosted() {
+ return true;
+ }
public function isWriteMode() {
return true;
@@ -140,6 +138,20 @@ class ApiImport extends ApiBase {
'Import a page from another wiki, or an XML file'
);
}
+
+ public function getPossibleErrors() {
+ return array_merge( parent::getPossibleErrors(), array(
+ array( 'cantimport' ),
+ array( 'missingparam', 'interwikipage' ),
+ array( 'cantimport-upload' ),
+ array( 'import-unknownerror', 'source' ),
+ array( 'import-unknownerror', 'result' ),
+ ) );
+ }
+
+ public function getTokenSalt() {
+ return '';
+ }
protected function getExamples() {
return array(
@@ -149,7 +161,7 @@ class ApiImport extends ApiBase {
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiImport.php 48091 2009-03-06 13:49:44Z catrope $';
+ return __CLASS__ . ': $Id: ApiImport.php 62599 2010-02-16 21:59:16Z reedy $';
}
}
@@ -160,20 +172,20 @@ class ApiImport extends ApiBase {
class ApiImportReporter extends ImportReporter {
private $mResultArr = array();
- function reportPage($title, $origTitle, $revisionCount, $successCount)
+ function reportPage( $title, $origTitle, $revisionCount, $successCount )
{
// Add a result entry
$r = array();
- ApiQueryBase::addTitleInfo($r, $title);
- $r['revisions'] = intval($successCount);
+ ApiQueryBase::addTitleInfo( $r, $title );
+ $r['revisions'] = intval( $successCount );
$this->mResultArr[] = $r;
// Piggyback on the parent to do the logging
- parent::reportPage($title, $origTitle, $revisionCount, $successCount);
+ parent::reportPage( $title, $origTitle, $revisionCount, $successCount );
}
function getData()
{
return $this->mResultArr;
}
-}
+} \ No newline at end of file
diff --git a/includes/api/ApiLogin.php b/includes/api/ApiLogin.php
index 8f1fb834..442bc44c 100644
--- a/includes/api/ApiLogin.php
+++ b/includes/api/ApiLogin.php
@@ -1,11 +1,11 @@
<?php
-/*
+/**
* Created on Sep 19, 2006
*
* API for MediaWiki 1.8+
*
- * Copyright (C) 2006-2007 Yuri Astrakhan <Firstname><Lastname>@gmail.com,
+ * Copyright © 2006-2007 Yuri Astrakhan <Firstname><Lastname>@gmail.com,
* Daniel Cannon (cannon dot danielc at gmail dot com)
*
* This program is free software; you can redistribute it and/or modify
@@ -24,9 +24,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ('ApiBase.php');
+ require_once( 'ApiBase.php' );
}
/**
@@ -36,8 +36,8 @@ if (!defined('MEDIAWIKI')) {
*/
class ApiLogin extends ApiBase {
- public function __construct($main, $action) {
- parent :: __construct($main, $action, 'lg');
+ public function __construct( $main, $action ) {
+ parent::__construct( $main, $action, 'lg' );
}
/**
@@ -48,42 +48,40 @@ class ApiLogin extends ApiBase {
* user, or any other reason, the host is cached with an expiry
* and no log-in attempts will be accepted until that expiry
* is reached. The expiry is $this->mLoginThrottle.
- *
- * @access public
*/
public function execute() {
$params = $this->extractRequestParams();
- $result = array ();
+ $result = array();
- $req = new FauxRequest(array (
+ $req = new FauxRequest( array(
'wpName' => $params['name'],
'wpPassword' => $params['password'],
'wpDomain' => $params['domain'],
'wpLoginToken' => $params['token'],
'wpRemember' => ''
- ));
+ ) );
// Init session if necessary
- if( session_id() == '' ) {
+ if ( session_id() == '' ) {
wfSetupSession();
}
- $loginForm = new LoginForm($req);
- switch ($authRes = $loginForm->authenticateUserData()) {
- case LoginForm :: SUCCESS :
+ $loginForm = new LoginForm( $req );
+ switch ( $authRes = $loginForm->authenticateUserData() ) {
+ case LoginForm::SUCCESS:
global $wgUser, $wgCookiePrefix;
- $wgUser->setOption('rememberpassword', 1);
+ $wgUser->setOption( 'rememberpassword', 1 );
$wgUser->setCookies();
// Run hooks. FIXME: split back and frontend from this hook.
// FIXME: This hook should be placed in the backend
$injected_html = '';
- wfRunHooks('UserLoginComplete', array(&$wgUser, &$injected_html));
+ wfRunHooks( 'UserLoginComplete', array( &$wgUser, &$injected_html ) );
$result['result'] = 'Success';
- $result['lguserid'] = intval($wgUser->getId());
+ $result['lguserid'] = intval( $wgUser->getId() );
$result['lgusername'] = $wgUser->getName();
$result['lgtoken'] = $wgUser->getToken();
$result['cookieprefix'] = $wgCookiePrefix;
@@ -102,48 +100,63 @@ class ApiLogin extends ApiBase {
$result['result'] = 'WrongToken';
break;
- case LoginForm :: NO_NAME :
+ case LoginForm::NO_NAME:
$result['result'] = 'NoName';
break;
- case LoginForm :: ILLEGAL :
+
+ case LoginForm::ILLEGAL:
$result['result'] = 'Illegal';
break;
- case LoginForm :: WRONG_PLUGIN_PASS :
+
+ case LoginForm::WRONG_PLUGIN_PASS:
$result['result'] = 'WrongPluginPass';
break;
- case LoginForm :: NOT_EXISTS :
+
+ case LoginForm::NOT_EXISTS:
$result['result'] = 'NotExists';
break;
- case LoginForm :: WRONG_PASS :
+
+ case LoginForm::RESET_PASS: // bug 20223 - Treat a temporary password as wrong. Per SpecialUserLogin - "The e-mailed temporary password should not be used for actual logins;"
+ case LoginForm::WRONG_PASS:
$result['result'] = 'WrongPass';
break;
- case LoginForm :: EMPTY_PASS :
+
+ case LoginForm::EMPTY_PASS:
$result['result'] = 'EmptyPass';
break;
- case LoginForm :: CREATE_BLOCKED :
+
+ case LoginForm::CREATE_BLOCKED:
$result['result'] = 'CreateBlocked';
$result['details'] = 'Your IP address is blocked from account creation';
break;
- case LoginForm :: THROTTLED :
+
+ case LoginForm::THROTTLED:
global $wgPasswordAttemptThrottle;
$result['result'] = 'Throttled';
- $result['wait'] = intval($wgPasswordAttemptThrottle['seconds']);
+ $result['wait'] = intval( $wgPasswordAttemptThrottle['seconds'] );
break;
- default :
- ApiBase :: dieDebug(__METHOD__, "Unhandled case value: {$authRes}");
+
+ case LoginForm::USER_BLOCKED:
+ $result['result'] = 'Blocked';
+ break;
+
+ default:
+ ApiBase::dieDebug( __METHOD__, "Unhandled case value: {$authRes}" );
}
- $this->getResult()->addValue(null, 'login', $result);
+ $this->getResult()->addValue( null, 'login', $result );
}
- public function mustBePosted() { return true; }
+ public function mustBePosted() {
+ return true;
+ }
public function isReadMode() {
return false;
}
public function getAllowedParams() {
- return array (
+ return array(
'name' => null,
'password' => null,
'domain' => null,
@@ -152,7 +165,7 @@ class ApiLogin extends ApiBase {
}
public function getParamDescription() {
- return array (
+ return array(
'name' => 'User Name',
'password' => 'Password',
'domain' => 'Domain (optional)',
@@ -161,7 +174,7 @@ class ApiLogin extends ApiBase {
}
public function getDescription() {
- return array (
+ return array(
'This module is used to login and get the authentication tokens. ',
'In the event of a successful log-in, a cookie will be attached',
'to your session. In the event of a failed log-in, you will not ',
@@ -170,6 +183,22 @@ class ApiLogin extends ApiBase {
);
}
+ public function getPossibleErrors() {
+ return array_merge( parent::getPossibleErrors(), array(
+ array( 'code' => 'NeedToken', 'info' => 'You need to resubmit your login with the specified token. See https://bugzilla.wikimedia.org/show_bug.cgi?id=23076' ),
+ array( 'code' => 'WrongToken', 'info' => 'You specified an invalid token' ),
+ array( 'code' => 'NoName', 'info' => 'You didn\'t set the lgname parameter' ),
+ array( 'code' => 'Illegal', 'info' => ' You provided an illegal username' ),
+ array( 'code' => 'NotExists', 'info' => ' The username you provided doesn\'t exist' ),
+ array( 'code' => 'EmptyPass', 'info' => ' You didn\'t set the lgpassword parameter or you left it empty' ),
+ array( 'code' => 'WrongPass', 'info' => ' The password you provided is incorrect' ),
+ array( 'code' => 'WrongPluginPass', 'info' => 'Same as `WrongPass", returned when an authentication plugin rather than MediaWiki itself rejected the password' ),
+ array( 'code' => 'CreateBlocked', 'info' => 'The wiki tried to automatically create a new account for you, but your IP address has been blocked from account creation' ),
+ array( 'code' => 'Throttled', 'info' => 'You\'ve logged in too many times in a short time' ),
+ array( 'code' => 'Blocked', 'info' => 'User is blocked' ),
+ ) );
+ }
+
protected function getExamples() {
return array(
'api.php?action=login&lgname=user&lgpassword=password'
@@ -177,6 +206,6 @@ class ApiLogin extends ApiBase {
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiLogin.php 69990 2010-07-27 08:44:08Z tstarling $';
+ return __CLASS__ . ': $Id: ApiLogin.php 64697 2010-04-07 09:05:05Z catrope $';
}
}
diff --git a/includes/api/ApiLogout.php b/includes/api/ApiLogout.php
index aa9f2829..6637ee09 100644
--- a/includes/api/ApiLogout.php
+++ b/includes/api/ApiLogout.php
@@ -23,9 +23,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ('ApiBase.php');
+ require_once ( 'ApiBase.php' );
}
/**
@@ -36,8 +36,8 @@ if (!defined('MEDIAWIKI')) {
*/
class ApiLogout extends ApiBase {
- public function __construct($main, $action) {
- parent :: __construct($main, $action);
+ public function __construct( $main, $action ) {
+ parent :: __construct( $main, $action );
}
public function execute() {
@@ -47,7 +47,7 @@ class ApiLogout extends ApiBase {
// Give extensions to do something after user logout
$injected_html = '';
- wfRunHooks( 'UserLogoutComplete', array(&$wgUser, &$injected_html, $oldName) );
+ wfRunHooks( 'UserLogoutComplete', array( &$wgUser, &$injected_html, $oldName ) );
}
public function isReadMode() {
@@ -75,6 +75,6 @@ class ApiLogout extends ApiBase {
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiLogout.php 69579 2010-07-20 02:49:55Z tstarling $';
+ return __CLASS__ . ': $Id: ApiLogout.php 69578 2010-07-20 02:46:20Z tstarling $';
}
}
diff --git a/includes/api/ApiMain.php b/includes/api/ApiMain.php
index 063e3574..fa6957b6 100644
--- a/includes/api/ApiMain.php
+++ b/includes/api/ApiMain.php
@@ -23,9 +23,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ('ApiBase.php');
+ require_once ( 'ApiBase.php' );
}
/**
@@ -76,10 +76,12 @@ class ApiMain extends ApiBase {
'unblock' => 'ApiUnblock',
'move' => 'ApiMove',
'edit' => 'ApiEditPage',
+ 'upload' => 'ApiUpload',
'emailuser' => 'ApiEmailUser',
'watch' => 'ApiWatch',
'patrol' => 'ApiPatrol',
'import' => 'ApiImport',
+ 'userrights' => 'ApiUserrights',
);
/**
@@ -102,26 +104,28 @@ class ApiMain extends ApiBase {
'dbg' => 'ApiFormatDbg',
'dbgfm' => 'ApiFormatDbg'
);
-
+
/**
* List of user roles that are specifically relevant to the API.
* array( 'right' => array ( 'msg' => 'Some message with a $1',
* 'params' => array ( $someVarToSubst ) ),
* );
*/
- private static $mRights = array('writeapi' => array(
+ private static $mRights = array( 'writeapi' => array(
'msg' => 'Use of the write API',
'params' => array()
),
'apihighlimits' => array(
'msg' => 'Use higher limits in API queries (Slow queries: $1 results; Fast queries: $2 results). The limits for slow queries also apply to multivalue parameters.',
- 'params' => array (ApiMain::LIMIT_SML2, ApiMain::LIMIT_BIG2)
+ 'params' => array ( ApiMain::LIMIT_SML2, ApiMain::LIMIT_BIG2 )
)
);
private $mPrinter, $mModules, $mModuleNames, $mFormats, $mFormatNames;
- private $mResult, $mAction, $mShowVersions, $mEnableWrite, $mRequest, $mInternalMode;
+ private $mResult, $mAction, $mShowVersions, $mEnableWrite, $mRequest;
+ private $mInternalMode, $mSquidMaxage, $mModule;
+
private $mCacheMode = 'private';
private $mCacheControl = array();
@@ -131,21 +135,21 @@ class ApiMain extends ApiBase {
* @param $request object - if this is an instance of FauxRequest, errors are thrown and no printing occurs
* @param $enableWrite bool should be set to true if the api may modify data
*/
- public function __construct($request, $enableWrite = false) {
+ public function __construct( $request, $enableWrite = false ) {
- $this->mInternalMode = ($request instanceof FauxRequest);
+ $this->mInternalMode = ( $request instanceof FauxRequest );
// Special handling for the main module: $parent === $this
- parent :: __construct($this, $this->mInternalMode ? 'main_int' : 'main');
+ parent :: __construct( $this, $this->mInternalMode ? 'main_int' : 'main' );
- if (!$this->mInternalMode) {
+ if ( !$this->mInternalMode ) {
// Impose module restrictions.
// If the current user cannot read,
// Remove all modules other than login
global $wgUser;
- if( $request->getVal( 'callback' ) !== null ) {
+ if ( $request->getVal( 'callback' ) !== null ) {
// JSON callback allows cross-site reads.
// For safety, strip user credentials.
wfDebug( "API: stripping user credentials for JSON callback\n" );
@@ -156,16 +160,17 @@ class ApiMain extends ApiBase {
global $wgAPIModules; // extension modules
$this->mModules = $wgAPIModules + self :: $Modules;
- $this->mModuleNames = array_keys($this->mModules);
+ $this->mModuleNames = array_keys( $this->mModules );
$this->mFormats = self :: $Formats;
- $this->mFormatNames = array_keys($this->mFormats);
+ $this->mFormatNames = array_keys( $this->mFormats );
- $this->mResult = new ApiResult($this);
+ $this->mResult = new ApiResult( $this );
$this->mShowVersions = false;
$this->mEnableWrite = $enableWrite;
$this->mRequest = & $request;
+ $this->mSquidMaxage = - 1; // flag for executeActionWithErrorHandling()
$this->mCommit = false;
}
@@ -184,27 +189,34 @@ class ApiMain extends ApiBase {
}
/**
- * Get the ApiResult object asscosiated with current request
+ * Get the ApiResult object associated with current request
*/
public function getResult() {
return $this->mResult;
}
/**
+ * Get the API module object. Only works after executeAction()
+ */
+ public function getModule() {
+ return $this->mModule;
+ }
+
+ /**
* Only kept for backwards compatibility
* @deprecated Use isWriteMode() instead
*/
public function requestWriteMode() {
- if (!$this->mEnableWrite)
- $this->dieUsageMsg(array('writedisabled'));
- if (wfReadOnly())
- $this->dieUsageMsg(array('readonlytext'));
+ if ( !$this->mEnableWrite )
+ $this->dieUsageMsg( array( 'writedisabled' ) );
+ if ( wfReadOnly() )
+ $this->dieUsageMsg( array( 'readonlytext' ) );
}
/**
* Set how long the response should be cached.
*/
- public function setCacheMaxAge($maxage) {
+ public function setCacheMaxAge( $maxage ) {
$this->setCacheControl( array(
'max-age' => $maxage,
's-maxage' => $maxage
@@ -293,10 +305,10 @@ class ApiMain extends ApiBase {
/**
* Create an instance of an output formatter by its name
*/
- public function createPrinterByName($format) {
- if( !isset( $this->mFormats[$format] ) )
+ public function createPrinterByName( $format ) {
+ if ( !isset( $this->mFormats[$format] ) )
$this->dieUsage( "Unrecognized format: {$format}", 'unknown_format' );
- return new $this->mFormats[$format] ($this, $format);
+ return new $this->mFormats[$format] ( $this, $format );
}
/**
@@ -304,11 +316,11 @@ class ApiMain extends ApiBase {
*/
public function execute() {
$this->profileIn();
- if ($this->mInternalMode)
+ if ( $this->mInternalMode )
$this->executeAction();
else
$this->executeActionWithErrorHandling();
-
+
$this->profileOut();
}
@@ -324,7 +336,7 @@ class ApiMain extends ApiBase {
try {
$this->executeAction();
- } catch (Exception $e) {
+ } catch ( Exception $e ) {
// Log it
if ( $e instanceof MWException ) {
wfDebugLog( 'exception', $e->getLogMessage() );
@@ -336,31 +348,32 @@ class ApiMain extends ApiBase {
// handler will process and log it.
//
- $errCode = $this->substituteResultWithError($e);
+ $errCode = $this->substituteResultWithError( $e );
// Error results should not be cached
$this->setCacheMode( 'private' );
$headerStr = 'MediaWiki-API-Error: ' . $errCode;
- if ($e->getCode() === 0)
- header($headerStr);
+ if ( $e->getCode() === 0 )
+ header( $headerStr );
else
- header($headerStr, true, $e->getCode());
+ header( $headerStr, true, $e->getCode() );
// Reset and print just the error message
ob_clean();
// If the error occured during printing, do a printer->profileOut()
$this->mPrinter->safeProfileOut();
- $this->printResult(true);
+ $this->printResult( true );
}
// Send cache headers after any code which might generate an error, to
// avoid sending public cache headers for errors.
$this->sendCacheHeaders();
- if($this->mPrinter->getIsHtml())
+ if ( $this->mPrinter->getIsHtml() ) {
echo wfReportTime();
+ }
ob_end_flush();
}
@@ -372,15 +385,22 @@ class ApiMain extends ApiBase {
}
if ( $this->mCacheMode == 'anon-public-user-private' ) {
- global $wgOut;
+ global $wgUseXVO, $wgOut;
header( 'Vary: Accept-Encoding, Cookie' );
- header( $wgOut->getXVO() );
- if ( session_id() != '' || $wgOut->haveCacheVaryCookies() ) {
- // Logged in, mark this request private
+ if ( $wgUseXVO ) {
+ header( $wgOut->getXVO() );
+ if ( $wgOut->haveCacheVaryCookies() ) {
+ // Logged in, mark this request private
+ header( 'Cache-Control: private' );
+ return;
+ }
+ // Logged out, send normal public headers below
+ } elseif ( session_id() != '' ) {
+ // Logged in or otherwise has session (e.g. anonymous users who have edited)
+ // Mark request private
header( 'Cache-Control: private' );
return;
- }
- // Logged out, send normal public headers below
+ } // else no XVO and anonymous, send public headers below
} else /* if public */ {
// Give a debugging message if the user object is unstubbed on a public request
global $wgUser;
@@ -396,7 +416,7 @@ class ApiMain extends ApiBase {
if ( !isset( $this->mCacheControl['max-age'] ) ) {
$this->mCacheControl['max-age'] = $this->getParameter( 'maxage' );
}
-
+
if ( !$this->mCacheControl['s-maxage'] && !$this->mCacheControl['max-age'] ) {
// Public cache not requested
// Sending a Vary header in this case is harmless, and protects us
@@ -426,7 +446,7 @@ class ApiMain extends ApiBase {
$separator = ', ';
}
}
-
+
header( "Cache-Control: $ccHeader" );
}
@@ -434,57 +454,55 @@ class ApiMain extends ApiBase {
* Replace the result data with the information about an exception.
* Returns the error code
*/
- protected function substituteResultWithError($e) {
+ protected function substituteResultWithError( $e ) {
- // Printer may not be initialized if the extractRequestParams() fails for the main module
- if (!isset ($this->mPrinter)) {
- // The printer has not been created yet. Try to manually get formatter value.
- $value = $this->getRequest()->getVal('format', self::API_DEFAULT_FORMAT);
- if (!in_array($value, $this->mFormatNames))
- $value = self::API_DEFAULT_FORMAT;
+ // Printer may not be initialized if the extractRequestParams() fails for the main module
+ if ( !isset ( $this->mPrinter ) ) {
+ // The printer has not been created yet. Try to manually get formatter value.
+ $value = $this->getRequest()->getVal( 'format', self::API_DEFAULT_FORMAT );
+ if ( !in_array( $value, $this->mFormatNames ) )
+ $value = self::API_DEFAULT_FORMAT;
- $this->mPrinter = $this->createPrinterByName($value);
- if ($this->mPrinter->getNeedsRawData())
- $this->getResult()->setRawMode();
- }
+ $this->mPrinter = $this->createPrinterByName( $value );
+ if ( $this->mPrinter->getNeedsRawData() )
+ $this->getResult()->setRawMode();
+ }
- if ($e instanceof UsageException) {
- //
- // User entered incorrect parameters - print usage screen
- //
- $errMessage = array (
- 'code' => $e->getCodeString(),
- 'info' => $e->getMessage());
+ if ( $e instanceof UsageException ) {
+ //
+ // User entered incorrect parameters - print usage screen
+ //
+ $errMessage = $e->getMessageArray();
- // Only print the help message when this is for the developer, not runtime
- if ($this->mPrinter->getIsHtml() || $this->mAction == 'help')
- ApiResult :: setContent($errMessage, $this->makeHelpMsg());
+ // Only print the help message when this is for the developer, not runtime
+ if ( $this->mPrinter->getWantsHelp() || $this->mAction == 'help' )
+ ApiResult :: setContent( $errMessage, $this->makeHelpMsg() );
+ } else {
+ global $wgShowSQLErrors, $wgShowExceptionDetails;
+ //
+ // Something is seriously wrong
+ //
+ if ( ( $e instanceof DBQueryError ) && !$wgShowSQLErrors ) {
+ $info = "Database query error";
} else {
- global $wgShowSQLErrors, $wgShowExceptionDetails;
- //
- // Something is seriously wrong
- //
- if ( ( $e instanceof DBQueryError ) && !$wgShowSQLErrors ) {
- $info = "Database query error";
- } else {
- $info = "Exception Caught: {$e->getMessage()}";
- }
-
- $errMessage = array (
- 'code' => 'internal_api_error_'. get_class($e),
- 'info' => $info,
- );
- ApiResult :: setContent($errMessage, $wgShowExceptionDetails ? "\n\n{$e->getTraceAsString()}\n\n" : "" );
+ $info = "Exception Caught: {$e->getMessage()}";
}
- $this->getResult()->reset();
- $this->getResult()->disableSizeCheck();
- // Re-add the id
- $requestid = $this->getParameter('requestid');
- if(!is_null($requestid))
- $this->getResult()->addValue(null, 'requestid', $requestid);
- $this->getResult()->addValue(null, 'error', $errMessage);
+ $errMessage = array (
+ 'code' => 'internal_api_error_' . get_class( $e ),
+ 'info' => $info,
+ );
+ ApiResult :: setContent( $errMessage, $wgShowExceptionDetails ? "\n\n{$e->getTraceAsString()}\n\n" : "" );
+ }
+
+ $this->getResult()->reset();
+ $this->getResult()->disableSizeCheck();
+ // Re-add the id
+ $requestid = $this->getParameter( 'requestid' );
+ if ( !is_null( $requestid ) )
+ $this->getResult()->addValue( null, 'requestid', $requestid );
+ $this->getResult()->addValue( null, 'error', $errMessage );
return $errMessage['code'];
}
@@ -494,23 +512,40 @@ class ApiMain extends ApiBase {
*/
protected function executeAction() {
// First add the id to the top element
- $requestid = $this->getParameter('requestid');
- if(!is_null($requestid))
- $this->getResult()->addValue(null, 'requestid', $requestid);
+ $requestid = $this->getParameter( 'requestid' );
+ if ( !is_null( $requestid ) )
+ $this->getResult()->addValue( null, 'requestid', $requestid );
$params = $this->extractRequestParams();
$this->mShowVersions = $params['version'];
$this->mAction = $params['action'];
- if( !is_string( $this->mAction ) ) {
+ if ( !is_string( $this->mAction ) ) {
$this->dieUsage( "The API requires a valid action parameter", 'unknown_action' );
}
-
+
// Instantiate the module requested by the user
- $module = new $this->mModules[$this->mAction] ($this, $this->mAction);
+ $module = new $this->mModules[$this->mAction] ( $this, $this->mAction );
+ $this->mModule = $module;
+
+ $moduleParams = $module->extractRequestParams();
+
+ // Die if token required, but not provided (unless there is a gettoken parameter)
+ $salt = $module->getTokenSalt();
+ if ( $salt !== false && !isset( $moduleParams['gettoken'] ) )
+ {
+ if ( !isset( $moduleParams['token'] ) ) {
+ $this->dieUsageMsg( array( 'missingparam', 'token' ) );
+ } else {
+ global $wgUser;
+ if ( !$wgUser->matchEditToken( $moduleParams['token'], $salt ) ) {
+ $this->dieUsageMsg( array( 'sessionfailure' ) );
+ }
+ }
+ }
- if( $module->shouldCheckMaxlag() && isset( $params['maxlag'] ) ) {
+ if ( $module->shouldCheckMaxlag() && isset( $params['maxlag'] ) ) {
// Check for maxlag
global $wgShowHostnames;
$maxLag = $params['maxlag'];
@@ -518,8 +553,7 @@ class ApiMain extends ApiBase {
if ( $lag > $maxLag ) {
header( 'Retry-After: ' . max( intval( $maxLag ), 5 ) );
header( 'X-Database-Lag: ' . intval( $lag ) );
- // XXX: should we return a 503 HTTP error code like wfMaxlagError() does?
- if( $wgShowHostnames ) {
+ if ( $wgShowHostnames ) {
$this->dieUsage( "Waiting for $host: $lag seconds lagged", 'maxlag' );
} else {
$this->dieUsage( "Waiting for a database server: $lag seconds lagged", 'maxlag' );
@@ -528,50 +562,50 @@ class ApiMain extends ApiBase {
}
}
- global $wgUser;
- if ($module->isReadMode() && !$wgUser->isAllowed('read'))
- $this->dieUsageMsg(array('readrequired'));
- if ($module->isWriteMode()) {
- if (!$this->mEnableWrite)
- $this->dieUsageMsg(array('writedisabled'));
- if (!$wgUser->isAllowed('writeapi'))
- $this->dieUsageMsg(array('writerequired'));
- if (wfReadOnly())
- $this->dieUsageMsg(array('readonlytext'));
+ global $wgUser, $wgGroupPermissions;
+ if ( $module->isReadMode() && !in_array( 'read', User::getGroupPermissions( array( '*' ) ), true ) && !$wgUser->isAllowed( 'read' ) )
+ $this->dieUsageMsg( array( 'readrequired' ) );
+ if ( $module->isWriteMode() ) {
+ if ( !$this->mEnableWrite )
+ $this->dieUsageMsg( array( 'writedisabled' ) );
+ if ( !$wgUser->isAllowed( 'writeapi' ) )
+ $this->dieUsageMsg( array( 'writerequired' ) );
+ if ( wfReadOnly() )
+ $this->dieReadOnly();
}
- if (!$this->mInternalMode) {
+ if ( !$this->mInternalMode ) {
// Ignore mustBePosted() for internal calls
- if($module->mustBePosted() && !$this->mRequest->wasPosted())
- $this->dieUsage("The {$this->mAction} module requires a POST request", 'mustbeposted');
+ if ( $module->mustBePosted() && !$this->mRequest->wasPosted() )
+ $this->dieUsageMsg( array ( 'mustbeposted', $this->mAction ) );
// See if custom printer is used
$this->mPrinter = $module->getCustomPrinter();
- if (is_null($this->mPrinter)) {
+ if ( is_null( $this->mPrinter ) ) {
// Create an appropriate printer
- $this->mPrinter = $this->createPrinterByName($params['format']);
+ $this->mPrinter = $this->createPrinterByName( $params['format'] );
}
- if ($this->mPrinter->getNeedsRawData())
+ if ( $this->mPrinter->getNeedsRawData() )
$this->getResult()->setRawMode();
}
// Execute
$module->profileIn();
$module->execute();
- wfRunHooks('APIAfterExecute', array(&$module));
+ wfRunHooks( 'APIAfterExecute', array( &$module ) );
$module->profileOut();
- if (!$this->mInternalMode) {
+ if ( !$this->mInternalMode ) {
// Print result data
- $this->printResult(false);
+ $this->printResult( false );
}
}
/**
* Print results using the current printer
*/
- protected function printResult($isError) {
+ protected function printResult( $isError ) {
$this->getResult()->cleanUpUTF8();
$printer = $this->mPrinter;
$printer->profileIn();
@@ -582,13 +616,13 @@ class ApiMain extends ApiBase {
$printer->setUnescapeAmps ( ( $this->mAction == 'help' || $isError )
&& $printer->getFormat() == 'XML' && $printer->getIsHtml() );
- $printer->initPrinter($isError);
+ $printer->initPrinter( $isError );
$printer->execute();
$printer->closePrinter();
$printer->profileOut();
}
-
+
public function isReadMode() {
return false;
}
@@ -668,6 +702,16 @@ class ApiMain extends ApiBase {
);
}
+ public function getPossibleErrors() {
+ return array_merge( parent::getPossibleErrors(), array(
+ array( 'readonlytext' ),
+ array( 'code' => 'unknown_format', 'info' => 'Unrecognized format: format' ),
+ array( 'code' => 'unknown_action', 'info' => 'The API requires a valid action parameter' ),
+ array( 'code' => 'maxlag', 'info' => 'Waiting for host: x seconds lagged' ),
+ array( 'code' => 'maxlag', 'info' => 'Waiting for a database server: x seconds lagged' ),
+ ) );
+ }
+
/**
* Returns an array of strings with credits for the API
*/
@@ -677,6 +721,7 @@ class ApiMain extends ApiBase {
' Roan Kattouw <Firstname>.<Lastname>@home.nl (lead developer Sep 2007-present)',
' Victor Vasiliev - vasilvv at gee mail dot com',
' Bryan Tong Minh - bryan . tongminh @ gmail . com',
+ ' Sam Reed - sam @ reedyboy . net',
' Yuri Astrakhan <Firstname><Lastname>@gmail.com (creator, lead developer Sep 2006-Sep 2007)',
'',
'Please send your comments, suggestions and questions to mediawiki-api@lists.wikimedia.org',
@@ -688,19 +733,37 @@ class ApiMain extends ApiBase {
* Override the parent to generate help messages for all available modules.
*/
public function makeHelpMsg() {
+ global $wgMemc, $wgAPICacheHelp, $wgAPICacheHelpTimeout;
+ $this->mPrinter->setHelp();
+ // Get help text from cache if present
+ $key = wfMemcKey( 'apihelp', $this->getModuleName(),
+ SpecialVersion::getVersion( 'nodb' ) .
+ $this->getMain()->getShowVersions() );
+ if ( $wgAPICacheHelp ) {
+ $cached = $wgMemc->get( $key );
+ if ( $cached )
+ return $cached;
+ }
+ $retval = $this->reallyMakeHelpMsg();
+ if ( $wgAPICacheHelp )
+ $wgMemc->set( $key, $retval, $wgAPICacheHelpTimeout );
+ return $retval;
+ }
+
+ public function reallyMakeHelpMsg() {
$this->mPrinter->setHelp();
// Use parent to make default message for the main module
$msg = parent :: makeHelpMsg();
- $astriks = str_repeat('*** ', 10);
+ $astriks = str_repeat( '*** ', 10 );
$msg .= "\n\n$astriks Modules $astriks\n\n";
- foreach( $this->mModules as $moduleName => $unused ) {
- $module = new $this->mModules[$moduleName] ($this, $moduleName);
- $msg .= self::makeHelpMsgHeader($module, 'action');
+ foreach ( $this->mModules as $moduleName => $unused ) {
+ $module = new $this->mModules[$moduleName] ( $this, $moduleName );
+ $msg .= self::makeHelpMsgHeader( $module, 'action' );
$msg2 = $module->makeHelpMsg();
- if ($msg2 !== false)
+ if ( $msg2 !== false )
$msg .= $msg2;
$msg .= "\n";
}
@@ -708,30 +771,30 @@ class ApiMain extends ApiBase {
$msg .= "\n$astriks Permissions $astriks\n\n";
foreach ( self :: $mRights as $right => $rightMsg ) {
$groups = User::getGroupsWithPermission( $right );
- $msg .= "* " . $right . " *\n " . wfMsgReplaceArgs( $rightMsg[ 'msg' ], $rightMsg[ 'params' ] ) .
+ $msg .= "* " . $right . " *\n " . wfMsgReplaceArgs( $rightMsg[ 'msg' ], $rightMsg[ 'params' ] ) .
"\nGranted to:\n " . str_replace( "*", "all", implode( ", ", $groups ) ) . "\n";
}
$msg .= "\n$astriks Formats $astriks\n\n";
- foreach( $this->mFormats as $formatName => $unused ) {
- $module = $this->createPrinterByName($formatName);
- $msg .= self::makeHelpMsgHeader($module, 'format');
+ foreach ( $this->mFormats as $formatName => $unused ) {
+ $module = $this->createPrinterByName( $formatName );
+ $msg .= self::makeHelpMsgHeader( $module, 'format' );
$msg2 = $module->makeHelpMsg();
- if ($msg2 !== false)
+ if ( $msg2 !== false )
$msg .= $msg2;
$msg .= "\n";
}
- $msg .= "\n*** Credits: ***\n " . implode("\n ", $this->getCredits()) . "\n";
+ $msg .= "\n*** Credits: ***\n " . implode( "\n ", $this->getCredits() ) . "\n";
return $msg;
}
- public static function makeHelpMsgHeader($module, $paramName) {
+ public static function makeHelpMsgHeader( $module, $paramName ) {
$modulePrefix = $module->getModulePrefix();
- if (strval($modulePrefix) !== '')
+ if ( strval( $modulePrefix ) !== '' )
$modulePrefix = "($modulePrefix) ";
return "* $paramName={$module->getModuleName()} $modulePrefix*";
@@ -746,9 +809,9 @@ class ApiMain extends ApiBase {
* OBSOLETE, use canApiHighLimits() instead
*/
public function isBot() {
- if (!isset ($this->mIsBot)) {
+ if ( !isset ( $this->mIsBot ) ) {
global $wgUser;
- $this->mIsBot = $wgUser->isAllowed('bot');
+ $this->mIsBot = $wgUser->isAllowed( 'bot' );
}
return $this->mIsBot;
}
@@ -759,9 +822,9 @@ class ApiMain extends ApiBase {
* OBSOLETE, use canApiHighLimits() instead
*/
public function isSysop() {
- if (!isset ($this->mIsSysop)) {
+ if ( !isset ( $this->mIsSysop ) ) {
global $wgUser;
- $this->mIsSysop = in_array( 'sysop', $wgUser->getGroups());
+ $this->mIsSysop = in_array( 'sysop', $wgUser->getGroups() );
}
return $this->mIsSysop;
@@ -772,9 +835,9 @@ class ApiMain extends ApiBase {
* @return bool
*/
public function canApiHighLimits() {
- if (!isset($this->mCanApiHighLimits)) {
+ if ( !isset( $this->mCanApiHighLimits ) ) {
global $wgUser;
- $this->mCanApiHighLimits = $wgUser->isAllowed('apihighlimits');
+ $this->mCanApiHighLimits = $wgUser->isAllowed( 'apihighlimits' );
}
return $this->mCanApiHighLimits;
@@ -795,11 +858,10 @@ class ApiMain extends ApiBase {
public function getVersion() {
$vers = array ();
$vers[] = 'MediaWiki: ' . SpecialVersion::getVersion() . "\n http://svn.wikimedia.org/viewvc/mediawiki/trunk/phase3/";
- $vers[] = __CLASS__ . ': $Id: ApiMain.php 69990 2010-07-27 08:44:08Z tstarling $';
+ $vers[] = __CLASS__ . ': $Id: ApiMain.php 70066 2010-07-28 05:52:32Z tstarling $';
$vers[] = ApiBase :: getBaseVersion();
$vers[] = ApiFormatBase :: getBaseVersion();
$vers[] = ApiQueryBase :: getBaseVersion();
- $vers[] = ApiFormatFeedWrapper :: getVersion(); // not accessible with format=xxx
return $vers;
}
@@ -845,14 +907,25 @@ class ApiMain extends ApiBase {
class UsageException extends Exception {
private $mCodestr;
+ private $mExtraData;
- public function __construct($message, $codestr, $code = 0) {
- parent :: __construct($message, $code);
+ public function __construct( $message, $codestr, $code = 0, $extradata = null ) {
+ parent :: __construct( $message, $code );
$this->mCodestr = $codestr;
+ $this->mExtraData = $extradata;
}
public function getCodeString() {
return $this->mCodestr;
}
+ public function getMessageArray() {
+ $result = array (
+ 'code' => $this->mCodestr,
+ 'info' => $this->getMessage()
+ );
+ if ( is_array( $this->mExtraData ) )
+ $result = array_merge( $result, $this->mExtraData );
+ return $result;
+ }
public function __toString() {
return "{$this->getCodeString()}: {$this->getMessage()}";
}
diff --git a/includes/api/ApiMove.php b/includes/api/ApiMove.php
index e22d0294..71010de7 100644
--- a/includes/api/ApiMove.php
+++ b/includes/api/ApiMove.php
@@ -22,9 +22,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ("ApiBase.php");
+ require_once ( "ApiBase.php" );
}
@@ -33,60 +33,68 @@ if (!defined('MEDIAWIKI')) {
*/
class ApiMove extends ApiBase {
- public function __construct($main, $action) {
- parent :: __construct($main, $action);
+ public function __construct( $main, $action ) {
+ parent :: __construct( $main, $action );
}
public function execute() {
global $wgUser;
$params = $this->extractRequestParams();
- if(is_null($params['reason']))
+ if ( is_null( $params['reason'] ) )
$params['reason'] = '';
- $this->requireOnlyOneParameter($params, 'from', 'fromid');
- if(!isset($params['to']))
- $this->dieUsageMsg(array('missingparam', 'to'));
- if(!isset($params['token']))
- $this->dieUsageMsg(array('missingparam', 'token'));
- if(!$wgUser->matchEditToken($params['token']))
- $this->dieUsageMsg(array('sessionfailure'));
+ $this->requireOnlyOneParameter( $params, 'from', 'fromid' );
+ if ( !isset( $params['to'] ) )
+ $this->dieUsageMsg( array( 'missingparam', 'to' ) );
- if(isset($params['from']))
+ if ( isset( $params['from'] ) )
{
- $fromTitle = Title::newFromText($params['from']);
- if(!$fromTitle)
- $this->dieUsageMsg(array('invalidtitle', $params['from']));
+ $fromTitle = Title::newFromText( $params['from'] );
+ if ( !$fromTitle )
+ $this->dieUsageMsg( array( 'invalidtitle', $params['from'] ) );
}
- else if(isset($params['fromid']))
+ else if ( isset( $params['fromid'] ) )
{
- $fromTitle = Title::newFromID($params['fromid']);
- if(!$fromTitle)
- $this->dieUsageMsg(array('nosuchpageid', $params['fromid']));
+ $fromTitle = Title::newFromID( $params['fromid'] );
+ if ( !$fromTitle )
+ $this->dieUsageMsg( array( 'nosuchpageid', $params['fromid'] ) );
}
- if(!$fromTitle->exists())
- $this->dieUsageMsg(array('notanarticle'));
+
+ if ( !$fromTitle->exists() )
+ $this->dieUsageMsg( array( 'notanarticle' ) );
$fromTalk = $fromTitle->getTalkPage();
- $toTitle = Title::newFromText($params['to']);
- if(!$toTitle)
- $this->dieUsageMsg(array('invalidtitle', $params['to']));
+ $toTitle = Title::newFromText( $params['to'] );
+ if ( !$toTitle )
+ $this->dieUsageMsg( array( 'invalidtitle', $params['to'] ) );
$toTalk = $toTitle->getTalkPage();
- # Move the page
+ if ( $toTitle->getNamespace() == NS_FILE
+ && !RepoGroup::singleton()->getLocalRepo()->findFile( $toTitle )
+ && wfFindFile( $toTitle ) )
+ {
+ if ( !$params['ignorewarnings'] && $wgUser->isAllowed( 'reupload-shared' ) ) {
+ $this->dieUsageMsg( array( 'sharedfile-exists' ) );
+ } elseif ( !$wgUser->isAllowed( 'reupload-shared' ) ) {
+ $this->dieUsageMsg( array( 'cantoverwrite-sharedfile' ) );
+ }
+ }
+
+ // Move the page
$hookErr = null;
- $retval = $fromTitle->moveTo($toTitle, true, $params['reason'], !$params['noredirect']);
- if($retval !== true)
- $this->dieUsageMsg(reset($retval));
+ $retval = $fromTitle->moveTo( $toTitle, true, $params['reason'], !$params['noredirect'] );
+ if ( $retval !== true )
+ $this->dieUsageMsg( reset( $retval ) );
- $r = array('from' => $fromTitle->getPrefixedText(), 'to' => $toTitle->getPrefixedText(), 'reason' => $params['reason']);
- if(!$params['noredirect'] || !$wgUser->isAllowed('suppressredirect'))
+ $r = array( 'from' => $fromTitle->getPrefixedText(), 'to' => $toTitle->getPrefixedText(), 'reason' => $params['reason'] );
+ if ( !$params['noredirect'] || !$wgUser->isAllowed( 'suppressredirect' ) )
$r['redirectcreated'] = '';
- # Move the talk page
- if($params['movetalk'] && $fromTalk->exists() && !$fromTitle->isTalkPage())
+ // Move the talk page
+ if ( $params['movetalk'] && $fromTalk->exists() && !$fromTitle->isTalkPage() )
{
- $retval = $fromTalk->moveTo($toTalk, true, $params['reason'], !$params['noredirect']);
- if($retval === true)
+ $retval = $fromTalk->moveTo( $toTalk, true, $params['reason'], !$params['noredirect'] );
+ if ( $retval === true )
{
$r['talkfrom'] = $fromTalk->getPrefixedText();
$r['talkto'] = $toTalk->getPrefixedText();
@@ -94,55 +102,55 @@ class ApiMove extends ApiBase {
// We're not gonna dieUsage() on failure, since we already changed something
else
{
- $parsed = $this->parseMsg(reset($retval));
+ $parsed = $this->parseMsg( reset( $retval ) );
$r['talkmove-error-code'] = $parsed['code'];
$r['talkmove-error-info'] = $parsed['info'];
}
}
- # Move subpages
- if($params['movesubpages'])
+ // Move subpages
+ if ( $params['movesubpages'] )
{
- $r['subpages'] = $this->moveSubpages($fromTitle, $toTitle,
- $params['reason'], $params['noredirect']);
- $this->getResult()->setIndexedTagName($r['subpages'], 'subpage');
- if($params['movetalk'])
+ $r['subpages'] = $this->moveSubpages( $fromTitle, $toTitle,
+ $params['reason'], $params['noredirect'] );
+ $this->getResult()->setIndexedTagName( $r['subpages'], 'subpage' );
+ if ( $params['movetalk'] )
{
- $r['subpages-talk'] = $this->moveSubpages($fromTalk, $toTalk,
- $params['reason'], $params['noredirect']);
- $this->getResult()->setIndexedTagName($r['subpages-talk'], 'subpage');
+ $r['subpages-talk'] = $this->moveSubpages( $fromTalk, $toTalk,
+ $params['reason'], $params['noredirect'] );
+ $this->getResult()->setIndexedTagName( $r['subpages-talk'], 'subpage' );
}
}
- # Watch pages
- if($params['watch'] || $wgUser->getOption('watchmoves'))
+ // Watch pages
+ if ( $params['watch'] || $wgUser->getOption( 'watchmoves' ) )
{
- $wgUser->addWatch($fromTitle);
- $wgUser->addWatch($toTitle);
+ $wgUser->addWatch( $fromTitle );
+ $wgUser->addWatch( $toTitle );
}
- else if($params['unwatch'])
+ else if ( $params['unwatch'] )
{
- $wgUser->removeWatch($fromTitle);
- $wgUser->removeWatch($toTitle);
+ $wgUser->removeWatch( $fromTitle );
+ $wgUser->removeWatch( $toTitle );
}
- $this->getResult()->addValue(null, $this->getModuleName(), $r);
+ $this->getResult()->addValue( null, $this->getModuleName(), $r );
}
-
- public function moveSubpages($fromTitle, $toTitle, $reason, $noredirect)
+
+ public function moveSubpages( $fromTitle, $toTitle, $reason, $noredirect )
{
$retval = array();
- $success = $fromTitle->moveSubpages($toTitle, true, $reason, !$noredirect);
- if(isset($success[0]))
- return array('error' => $this->parseMsg($success));
+ $success = $fromTitle->moveSubpages( $toTitle, true, $reason, !$noredirect );
+ if ( isset( $success[0] ) )
+ return array( 'error' => $this->parseMsg( $success ) );
else
{
// At least some pages could be moved
// Report each of them separately
- foreach($success as $oldTitle => $newTitle)
+ foreach ( $success as $oldTitle => $newTitle )
{
- $r = array('from' => $oldTitle);
- if(is_array($newTitle))
- $r['error'] = $this->parseMsg(reset($newTitle));
+ $r = array( 'from' => $oldTitle );
+ if ( is_array( $newTitle ) )
+ $r['error'] = $this->parseMsg( reset( $newTitle ) );
else
// Success
$r['to'] = $newTitle;
@@ -152,7 +160,9 @@ class ApiMove extends ApiBase {
return $retval;
}
- public function mustBePosted() { return true; }
+ public function mustBePosted() {
+ return true;
+ }
public function isWriteMode() {
return true;
@@ -171,7 +181,8 @@ class ApiMove extends ApiBase {
'movesubpages' => false,
'noredirect' => false,
'watch' => false,
- 'unwatch' => false
+ 'unwatch' => false,
+ 'ignorewarnings' => false
);
}
@@ -186,7 +197,8 @@ class ApiMove extends ApiBase {
'movesubpages' => 'Move subpages, if applicable',
'noredirect' => 'Don\'t create a redirect',
'watch' => 'Add the page and the redirect to your watchlist',
- 'unwatch' => 'Remove the page and the redirect from your watchlist'
+ 'unwatch' => 'Remove the page and the redirect from your watchlist',
+ 'ignorewarnings' => 'Ignore any warnings'
);
}
@@ -195,6 +207,21 @@ class ApiMove extends ApiBase {
'Move a page.'
);
}
+
+ public function getPossibleErrors() {
+ return array_merge( parent::getPossibleErrors(), array(
+ array( 'missingparam', 'to' ),
+ array( 'invalidtitle', 'from' ),
+ array( 'nosuchpageid', 'fromid' ),
+ array( 'notanarticle' ),
+ array( 'invalidtitle', 'to' ),
+ array( 'sharedfile-exists' ),
+ ) );
+ }
+
+ public function getTokenSalt() {
+ return '';
+ }
protected function getExamples() {
return array (
@@ -203,6 +230,6 @@ class ApiMove extends ApiBase {
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiMove.php 48091 2009-03-06 13:49:44Z catrope $';
+ return __CLASS__ . ': $Id: ApiMove.php 62810 2010-02-22 03:34:56Z mah $';
}
}
diff --git a/includes/api/ApiOpenSearch.php b/includes/api/ApiOpenSearch.php
index d2e6ea21..e145d80c 100644
--- a/includes/api/ApiOpenSearch.php
+++ b/includes/api/ApiOpenSearch.php
@@ -23,9 +23,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ("ApiBase.php");
+ require_once ( "ApiBase.php" );
}
/**
@@ -33,34 +33,38 @@ if (!defined('MEDIAWIKI')) {
*/
class ApiOpenSearch extends ApiBase {
- public function __construct($main, $action) {
- parent :: __construct($main, $action);
+ public function __construct( $main, $action ) {
+ parent :: __construct( $main, $action );
}
public function getCustomPrinter() {
- return $this->getMain()->createPrinterByName('json');
+ return $this->getMain()->createPrinterByName( 'json' );
}
public function execute() {
- global $wgEnableMWSuggest;
+ global $wgEnableOpenSearchSuggest, $wgSearchSuggestCacheExpiry;
$params = $this->extractRequestParams();
$search = $params['search'];
$limit = $params['limit'];
$namespaces = $params['namespace'];
$suggest = $params['suggest'];
- # $wgEnableMWSuggest hit incoming when $wgEnableMWSuggest is disabled
- if( $suggest && !$wgEnableMWSuggest ) return;
-
- // Open search results may be stored for a very long time
- $this->getMain()->setCacheMaxAge(1200);
- $this->getMain()->setCacheMode( 'public' );
- $srchres = PrefixSearch::titleSearch( $search, $limit, $namespaces );
+ // MWSuggest or similar hit
+ if ( $suggest && !$wgEnableOpenSearchSuggest )
+ $srchres = array();
+ else {
+ // Open search results may be stored for a very long
+ // time
+ $this->getMain()->setCacheMaxAge( $wgSearchSuggestCacheExpiry );
+ $this->getMain()->setCacheMode( 'public' );
+ $srchres = PrefixSearch::titleSearch( $search, $limit,
+ $namespaces );
+ }
// Set top level elements
$result = $this->getResult();
- $result->addValue(null, 0, $search);
- $result->addValue(null, 1, $srchres);
+ $result->addValue( null, 0, $search );
+ $result->addValue( null, 1, $srchres );
}
public function getAllowedParams() {
@@ -87,7 +91,7 @@ class ApiOpenSearch extends ApiBase {
'search' => 'Search string',
'limit' => 'Maximum amount of results to return',
'namespace' => 'Namespaces to search',
- 'suggest' => 'Do nothing if $wgEnableMWSuggest is false',
+ 'suggest' => 'Do nothing if $wgEnableOpenSearchSuggest is false',
);
}
@@ -102,6 +106,6 @@ class ApiOpenSearch extends ApiBase {
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiOpenSearch.php 69986 2010-07-27 03:57:39Z tstarling $';
+ return __CLASS__ . ': $Id: ApiOpenSearch.php 69932 2010-07-26 08:03:21Z tstarling $';
}
}
diff --git a/includes/api/ApiPageSet.php b/includes/api/ApiPageSet.php
index 6b9e90b8..361f1d8b 100644
--- a/includes/api/ApiPageSet.php
+++ b/includes/api/ApiPageSet.php
@@ -23,9 +23,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ('ApiQueryBase.php');
+ require_once ( 'ApiQueryBase.php' );
}
/**
@@ -58,8 +58,8 @@ class ApiPageSet extends ApiQueryBase {
* @param $query ApiQuery
* @param $resolveRedirects bool Whether redirects should be resolved
*/
- public function __construct($query, $resolveRedirects = false) {
- parent :: __construct($query, 'query');
+ public function __construct( $query, $resolveRedirects = false ) {
+ parent :: __construct( $query, 'query' );
$this->mAllPages = array ();
$this->mTitles = array();
@@ -75,10 +75,10 @@ class ApiPageSet extends ApiQueryBase {
$this->mRequestedPageFields = array ();
$this->mResolveRedirects = $resolveRedirects;
- if($resolveRedirects)
+ if ( $resolveRedirects )
$this->mPendingRedirectIDs = array();
- $this->mFakePageId = -1;
+ $this->mFakePageId = - 1;
}
/**
@@ -94,7 +94,7 @@ class ApiPageSet extends ApiQueryBase {
* before execute()
* @param $fieldName string Field name
*/
- public function requestField($fieldName) {
+ public function requestField( $fieldName ) {
$this->mRequestedPageFields[$fieldName] = null;
}
@@ -104,7 +104,7 @@ class ApiPageSet extends ApiQueryBase {
* @param $fieldName string Field name
* @return mixed Field value
*/
- public function getCustomField($fieldName) {
+ public function getCustomField( $fieldName ) {
return $this->mRequestedPageFields[$fieldName];
}
@@ -123,14 +123,14 @@ class ApiPageSet extends ApiQueryBase {
'page_id' => null,
);
- if ($this->mResolveRedirects)
+ if ( $this->mResolveRedirects )
$pageFlds['page_is_redirect'] = null;
// only store non-default fields
- $this->mRequestedPageFields = array_diff_key($this->mRequestedPageFields, $pageFlds);
+ $this->mRequestedPageFields = array_diff_key( $this->mRequestedPageFields, $pageFlds );
- $pageFlds = array_merge($pageFlds, $this->mRequestedPageFields);
- return array_keys($pageFlds);
+ $pageFlds = array_merge( $pageFlds, $this->mRequestedPageFields );
+ return array_keys( $pageFlds );
}
/**
@@ -156,7 +156,7 @@ class ApiPageSet extends ApiQueryBase {
* @return int
*/
public function getTitleCount() {
- return count($this->mTitles);
+ return count( $this->mTitles );
}
/**
@@ -172,7 +172,7 @@ class ApiPageSet extends ApiQueryBase {
* @return int
*/
public function getGoodTitleCount() {
- return count($this->mGoodTitles);
+ return count( $this->mGoodTitles );
}
/**
@@ -249,7 +249,7 @@ class ApiPageSet extends ApiQueryBase {
* @return int
*/
public function getRevisionCount() {
- return count($this->getRevisionIDs());
+ return count( $this->getRevisionIDs() );
}
/**
@@ -261,32 +261,32 @@ class ApiPageSet extends ApiQueryBase {
// Only one of the titles/pageids/revids is allowed at the same time
$dataSource = null;
- if (isset ($params['titles']))
+ if ( isset ( $params['titles'] ) )
$dataSource = 'titles';
- if (isset ($params['pageids'])) {
- if (isset ($dataSource))
- $this->dieUsage("Cannot use 'pageids' at the same time as '$dataSource'", 'multisource');
+ if ( isset ( $params['pageids'] ) ) {
+ if ( isset ( $dataSource ) )
+ $this->dieUsage( "Cannot use 'pageids' at the same time as '$dataSource'", 'multisource' );
$dataSource = 'pageids';
}
- if (isset ($params['revids'])) {
- if (isset ($dataSource))
- $this->dieUsage("Cannot use 'revids' at the same time as '$dataSource'", 'multisource');
+ if ( isset ( $params['revids'] ) ) {
+ if ( isset ( $dataSource ) )
+ $this->dieUsage( "Cannot use 'revids' at the same time as '$dataSource'", 'multisource' );
$dataSource = 'revids';
}
- switch ($dataSource) {
+ switch ( $dataSource ) {
case 'titles' :
- $this->initFromTitles($params['titles']);
+ $this->initFromTitles( $params['titles'] );
break;
case 'pageids' :
- $this->initFromPageIds($params['pageids']);
+ $this->initFromPageIds( $params['pageids'] );
break;
case 'revids' :
- if($this->mResolveRedirects)
- $this->setWarning('Redirect resolution cannot be used together with the revids= parameter. '.
- 'Any redirects the revids= point to have not been resolved.');
+ if ( $this->mResolveRedirects )
+ $this->setWarning( 'Redirect resolution cannot be used together with the revids= parameter. ' .
+ 'Any redirects the revids= point to have not been resolved.' );
$this->mResolveRedirects = false;
- $this->initFromRevIDs($params['revids']);
+ $this->initFromRevIDs( $params['revids'] );
break;
default :
// Do nothing - some queries do not need any of the data sources.
@@ -299,9 +299,9 @@ class ApiPageSet extends ApiQueryBase {
* Populate this PageSet from a list of Titles
* @param $titles array of Title objects
*/
- public function populateFromTitles($titles) {
+ public function populateFromTitles( $titles ) {
$this->profileIn();
- $this->initFromTitles($titles);
+ $this->initFromTitles( $titles );
$this->profileOut();
}
@@ -309,9 +309,9 @@ class ApiPageSet extends ApiQueryBase {
* Populate this PageSet from a list of page IDs
* @param $pageIDs array of page IDs
*/
- public function populateFromPageIDs($pageIDs) {
+ public function populateFromPageIDs( $pageIDs ) {
$this->profileIn();
- $this->initFromPageIds($pageIDs);
+ $this->initFromPageIds( $pageIDs );
$this->profileOut();
}
@@ -320,9 +320,9 @@ class ApiPageSet extends ApiQueryBase {
* @param $db Database object
* @param $queryResult Query result object
*/
- public function populateFromQueryResult($db, $queryResult) {
+ public function populateFromQueryResult( $db, $queryResult ) {
$this->profileIn();
- $this->initFromQueryResult($db, $queryResult);
+ $this->initFromQueryResult( $db, $queryResult );
$this->profileOut();
}
@@ -330,9 +330,9 @@ class ApiPageSet extends ApiQueryBase {
* Populate this PageSet from a list of revision IDs
* @param $revIDs array of revision IDs
*/
- public function populateFromRevisionIDs($revIDs) {
+ public function populateFromRevisionIDs( $revIDs ) {
$this->profileIn();
- $this->initFromRevIDs($revIDs);
+ $this->initFromRevIDs( $revIDs );
$this->profileOut();
}
@@ -340,22 +340,22 @@ class ApiPageSet extends ApiQueryBase {
* Extract all requested fields from the row received from the database
* @param $row Result row
*/
- public function processDbRow($row) {
+ public function processDbRow( $row ) {
// Store Title object in various data structures
- $title = Title :: makeTitle($row->page_namespace, $row->page_title);
+ $title = Title :: makeTitle( $row->page_namespace, $row->page_title );
- $pageId = intval($row->page_id);
+ $pageId = intval( $row->page_id );
$this->mAllPages[$row->page_namespace][$row->page_title] = $pageId;
$this->mTitles[] = $title;
- if ($this->mResolveRedirects && $row->page_is_redirect == '1') {
+ if ( $this->mResolveRedirects && $row->page_is_redirect == '1' ) {
$this->mPendingRedirectIDs[$pageId] = $title;
} else {
$this->mGoodTitles[$pageId] = $title;
}
- foreach ($this->mRequestedPageFields as $fieldName => & $fieldValues)
+ foreach ( $this->mRequestedPageFields as $fieldName => & $fieldValues )
$fieldValues[$pageId] = $row-> $fieldName;
}
@@ -384,24 +384,24 @@ class ApiPageSet extends ApiQueryBase {
*
* @param $titles array of Title objects or strings
*/
- private function initFromTitles($titles) {
+ private function initFromTitles( $titles ) {
// Get validated and normalized title objects
- $linkBatch = $this->processTitlesArray($titles);
- if($linkBatch->isEmpty())
+ $linkBatch = $this->processTitlesArray( $titles );
+ if ( $linkBatch->isEmpty() )
return;
$db = $this->getDB();
- $set = $linkBatch->constructSet('page', $db);
+ $set = $linkBatch->constructSet( 'page', $db );
// 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->initFromQueryResult($db, $res, $linkBatch->data, true); // process Titles
+ $this->initFromQueryResult( $db, $res, $linkBatch->data, true ); // process Titles
// Resolve any found redirects
$this->resolvePendingRedirects();
@@ -411,11 +411,11 @@ class ApiPageSet extends ApiQueryBase {
* 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))
+ private function initFromPageIds( $pageids ) {
+ if ( !count( $pageids ) )
return;
- $pageids = array_map('intval', $pageids); // paranoia
+ $pageids = array_map( 'intval', $pageids ); // paranoia
$set = array (
'page_id' => $pageids
);
@@ -423,12 +423,12 @@ class ApiPageSet extends ApiQueryBase {
// 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);
- $this->initFromQueryResult($db, $res, $remaining, false); // process PageIDs
+ $remaining = array_flip( $pageids );
+ $this->initFromQueryResult( $db, $res, $remaining, false ); // process PageIDs
// Resolve any found redirects
$this->resolvePendingRedirects();
@@ -445,34 +445,34 @@ class ApiPageSet extends ApiQueryBase {
* If true, treat $remaining as an array of [ns][title]
* If false, treat it as an array of [pageIDs]
*/
- private function initFromQueryResult($db, $res, &$remaining = null, $processTitles = null) {
- if (!is_null($remaining) && is_null($processTitles))
- ApiBase :: dieDebug(__METHOD__, 'Missing $processTitles parameter when $remaining is provided');
+ private function initFromQueryResult( $db, $res, &$remaining = null, $processTitles = null ) {
+ if ( !is_null( $remaining ) && is_null( $processTitles ) )
+ ApiBase :: dieDebug( __METHOD__, 'Missing $processTitles parameter when $remaining is provided' );
- while ($row = $db->fetchObject($res)) {
+ while ( $row = $db->fetchObject( $res ) ) {
- $pageId = intval($row->page_id);
+ $pageId = intval( $row->page_id );
// Remove found page from the list of remaining items
- if (isset($remaining)) {
- if ($processTitles)
- unset ($remaining[$row->page_namespace][$row->page_title]);
+ if ( isset( $remaining ) ) {
+ if ( $processTitles )
+ unset ( $remaining[$row->page_namespace][$row->page_title] );
else
- unset ($remaining[$pageId]);
+ unset ( $remaining[$pageId] );
}
// Store any extra fields requested by modules
- $this->processDbRow($row);
+ $this->processDbRow( $row );
}
- $db->freeResult($res);
+ $db->freeResult( $res );
- if(isset($remaining)) {
+ if ( isset( $remaining ) ) {
// Any items left in the $remaining list are added as missing
- if($processTitles) {
+ if ( $processTitles ) {
// The remaining titles in $remaining are non-existent pages
- foreach ($remaining as $ns => $dbkeys) {
+ foreach ( $remaining as $ns => $dbkeys ) {
foreach ( $dbkeys as $dbkey => $unused ) {
- $title = Title :: makeTitle($ns, $dbkey);
+ $title = Title :: makeTitle( $ns, $dbkey );
$this->mAllPages[$ns][$dbkey] = $this->mFakePageId;
$this->mMissingTitles[$this->mFakePageId] = $title;
$this->mFakePageId--;
@@ -483,10 +483,10 @@ class ApiPageSet extends ApiQueryBase {
else
{
// The remaining pageids do not exist
- if(!$this->mMissingPageIDs)
- $this->mMissingPageIDs = array_keys($remaining);
+ if ( !$this->mMissingPageIDs )
+ $this->mMissingPageIDs = array_keys( $remaining );
else
- $this->mMissingPageIDs = array_merge($this->mMissingPageIDs, array_keys($remaining));
+ $this->mMissingPageIDs = array_merge( $this->mMissingPageIDs, array_keys( $remaining ) );
}
}
}
@@ -496,37 +496,37 @@ class ApiPageSet extends ApiQueryBase {
* instead
* @param $revids array of revision IDs
*/
- private function initFromRevIDs($revids) {
+ private function initFromRevIDs( $revids ) {
- if(!count($revids))
+ if ( !count( $revids ) )
return;
- $revids = array_map('intval', $revids); // paranoia
+ $revids = array_map( 'intval', $revids ); // paranoia
$db = $this->getDB();
$pageids = array();
- $remaining = array_flip($revids);
+ $remaining = array_flip( $revids );
- $tables = array('revision', 'page');
- $fields = array('rev_id', 'rev_page');
- $where = array('rev_id' => $revids, 'rev_page = page_id');
+ $tables = array( 'revision', 'page' );
+ $fields = array( 'rev_id', 'rev_page' );
+ $where = array( 'rev_id' => $revids, 'rev_page = page_id' );
// Get pageIDs data from the `page` table
$this->profileDBIn();
- $res = $db->select($tables, $fields, $where, __METHOD__);
- while ($row = $db->fetchObject($res)) {
- $revid = intval($row->rev_id);
- $pageid = intval($row->rev_page);
+ $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]);
+ unset( $remaining[$revid] );
}
- $db->freeResult($res);
+ $db->freeResult( $res );
$this->profileDBOut();
- $this->mMissingRevIDs = array_keys($remaining);
+ $this->mMissingRevIDs = array_keys( $remaining );
// Populate all the page information
- $this->initFromPageIds(array_keys($pageids));
+ $this->initFromPageIds( array_keys( $pageids ) );
}
/**
@@ -536,32 +536,32 @@ class ApiPageSet extends ApiQueryBase {
*/
private function resolvePendingRedirects() {
- if($this->mResolveRedirects) {
+ if ( $this->mResolveRedirects ) {
$db = $this->getDB();
$pageFlds = $this->getPageTableFields();
// Repeat until all redirects have been resolved
// The infinite loop is prevented by keeping all known pages in $this->mAllPages
- while ($this->mPendingRedirectIDs) {
+ while ( $this->mPendingRedirectIDs ) {
// Resolve redirects by querying the pagelinks table, and repeat the process
// Create a new linkBatch object for the next pass
$linkBatch = $this->getRedirectTargets();
- if ($linkBatch->isEmpty())
+ if ( $linkBatch->isEmpty() )
break;
- $set = $linkBatch->constructSet('page', $db);
- if($set === false)
+ $set = $linkBatch->constructSet( 'page', $db );
+ if ( $set === false )
break;
// Get pageIDs data from the `page` table
$this->profileDBIn();
- $res = $db->select('page', $pageFlds, $set, __METHOD__);
+ $res = $db->select( 'page', $pageFlds, $set, __METHOD__ );
$this->profileDBOut();
// Hack: get the ns:titles stored in array(ns => array(titles)) format
- $this->initFromQueryResult($db, $res, $linkBatch->data, true);
+ $this->initFromQueryResult( $db, $res, $linkBatch->data, true );
}
}
}
@@ -578,40 +578,40 @@ class ApiPageSet extends ApiQueryBase {
$db = $this->getDB();
$this->profileDBIn();
- $res = $db->select('redirect', array(
+ $res = $db->select( 'redirect', array(
'rd_from',
'rd_namespace',
'rd_title'
- ), array('rd_from' => array_keys($this->mPendingRedirectIDs)),
+ ), array( 'rd_from' => array_keys( $this->mPendingRedirectIDs ) ),
__METHOD__
);
$this->profileDBOut();
- while($row = $db->fetchObject($res))
+ while ( $row = $db->fetchObject( $res ) )
{
- $rdfrom = intval($row->rd_from);
+ $rdfrom = intval( $row->rd_from );
$from = $this->mPendingRedirectIDs[$rdfrom]->getPrefixedText();
- $to = Title::makeTitle($row->rd_namespace, $row->rd_title)->getPrefixedText();
- unset($this->mPendingRedirectIDs[$rdfrom]);
- if(!isset($this->mAllPages[$row->rd_namespace][$row->rd_title]))
- $lb->add($row->rd_namespace, $row->rd_title);
+ $to = Title::makeTitle( $row->rd_namespace, $row->rd_title )->getPrefixedText();
+ unset( $this->mPendingRedirectIDs[$rdfrom] );
+ if ( !isset( $this->mAllPages[$row->rd_namespace][$row->rd_title] ) )
+ $lb->add( $row->rd_namespace, $row->rd_title );
$this->mRedirectTitles[$from] = $to;
}
- $db->freeResult($res);
- if($this->mPendingRedirectIDs)
+ $db->freeResult( $res );
+ if ( $this->mPendingRedirectIDs )
{
- # We found pages that aren't in the redirect table
- # Add them
- foreach($this->mPendingRedirectIDs as $id => $title)
+ // We found pages that aren't in the redirect table
+ // Add them
+ foreach ( $this->mPendingRedirectIDs as $id => $title )
{
- $article = new Article($title);
+ $article = new Article( $title );
$rt = $article->insertRedirect();
- if(!$rt)
- # What the hell. Let's just ignore this
+ if ( !$rt )
+ // What the hell. Let's just ignore this
continue;
- $lb->addObj($rt);
+ $lb->addObj( $rt );
$this->mRedirectTitles[$title->getPrefixedText()] = $rt->getPrefixedText();
- unset($this->mPendingRedirectIDs[$id]);
+ unset( $this->mPendingRedirectIDs[$id] );
}
}
return $lb;
@@ -626,32 +626,32 @@ class ApiPageSet extends ApiQueryBase {
* @param $titles array of Title objects or strings
* @return LinkBatch
*/
- private function processTitlesArray($titles) {
+ private function processTitlesArray( $titles ) {
$linkBatch = new LinkBatch();
- foreach ($titles as $title) {
+ foreach ( $titles as $title ) {
- $titleObj = is_string($title) ? Title :: newFromText($title) : $title;
- if (!$titleObj)
+ $titleObj = is_string( $title ) ? Title :: newFromText( $title ) : $title;
+ if ( !$titleObj )
{
- # Handle invalid titles gracefully
+ // Handle invalid titles gracefully
$this->mAllpages[0][$title] = $this->mFakePageId;
$this->mInvalidTitles[$this->mFakePageId] = $title;
$this->mFakePageId--;
continue; // There's nothing else we can do
}
$iw = $titleObj->getInterwiki();
- if (strval($iw) !== '') {
+ if ( strval( $iw ) !== '' ) {
// This title is an interwiki link.
$this->mInterwikiTitles[$titleObj->getPrefixedText()] = $iw;
} else {
// Validation
- if ($titleObj->getNamespace() < 0)
- $this->setWarning("No support for special pages has been implemented");
+ if ( $titleObj->getNamespace() < 0 )
+ $this->setWarning( "No support for special pages has been implemented" );
else
- $linkBatch->addObj($titleObj);
+ $linkBatch->addObj( $titleObj );
}
// Make sure we remember the original title that was
@@ -659,7 +659,7 @@ class ApiPageSet extends ApiQueryBase {
// titles with the originally requested when e.g. the
// namespace is localized or the capitalization is
// different
- if (is_string($title) && $title !== $titleObj->getPrefixedText()) {
+ if ( is_string( $title ) && $title !== $titleObj->getPrefixedText() ) {
$this->mNormalizedTitles[$title] = $titleObj->getPrefixedText();
}
}
@@ -691,7 +691,14 @@ class ApiPageSet extends ApiQueryBase {
);
}
+ public function getPossibleErrors() {
+ return array_merge( parent::getPossibleErrors(), array(
+ array( 'code' => 'multisource', 'info' => "Cannot use 'pageids' at the same time as 'dataSource'" ),
+ array( 'code' => 'multisource', 'info' => "Cannot use 'revids' at the same time as 'dataSource'" ),
+ ) );
+ }
+
public function getVersion() {
- return __CLASS__ . ': $Id: ApiPageSet.php 47424 2009-02-18 05:29:11Z werdna $';
+ return __CLASS__ . ': $Id: ApiPageSet.php 62410 2010-02-13 01:21:52Z reedy $';
}
}
diff --git a/includes/api/ApiParamInfo.php b/includes/api/ApiParamInfo.php
index d710c206..8fe2cad2 100644
--- a/includes/api/ApiParamInfo.php
+++ b/includes/api/ApiParamInfo.php
@@ -23,9 +23,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ("ApiBase.php");
+ require_once ( "ApiBase.php" );
}
/**
@@ -33,123 +33,149 @@ if (!defined('MEDIAWIKI')) {
*/
class ApiParamInfo extends ApiBase {
- public function __construct($main, $action) {
- parent :: __construct($main, $action);
+ public function __construct( $main, $action ) {
+ parent :: __construct( $main, $action );
}
public function execute() {
// Get parameters
$params = $this->extractRequestParams();
$result = $this->getResult();
- $queryObj = new ApiQuery($this->getMain(), 'query');
+ $queryObj = new ApiQuery( $this->getMain(), 'query' );
$r = array();
- if(is_array($params['modules']))
+ if ( is_array( $params['modules'] ) )
{
$modArr = $this->getMain()->getModules();
- foreach($params['modules'] as $m)
+ $r['modules'] = array();
+ foreach ( $params['modules'] as $m )
{
- if(!isset($modArr[$m]))
+ if ( !isset( $modArr[$m] ) )
{
- $r['modules'][] = array('name' => $m, 'missing' => '');
+ $r['modules'][] = array( 'name' => $m, 'missing' => '' );
continue;
}
- $obj = new $modArr[$m]($this->getMain(), $m);
- $a = $this->getClassInfo($obj);
+ $obj = new $modArr[$m]( $this->getMain(), $m );
+ $a = $this->getClassInfo( $obj );
$a['name'] = $m;
$r['modules'][] = $a;
}
- $result->setIndexedTagName($r['modules'], 'module');
+ $result->setIndexedTagName( $r['modules'], 'module' );
}
- if(is_array($params['querymodules']))
+ if ( is_array( $params['querymodules'] ) )
{
$qmodArr = $queryObj->getModules();
- foreach($params['querymodules'] as $qm)
+ $r['querymodules'] = array();
+ foreach ( $params['querymodules'] as $qm )
{
- if(!isset($qmodArr[$qm]))
+ if ( !isset( $qmodArr[$qm] ) )
{
- $r['querymodules'][] = array('name' => $qm, 'missing' => '');
+ $r['querymodules'][] = array( 'name' => $qm, 'missing' => '' );
continue;
}
- $obj = new $qmodArr[$qm]($this, $qm);
- $a = $this->getClassInfo($obj);
+ $obj = new $qmodArr[$qm]( $this, $qm );
+ $a = $this->getClassInfo( $obj );
$a['name'] = $qm;
$r['querymodules'][] = $a;
}
- $result->setIndexedTagName($r['querymodules'], 'module');
+ $result->setIndexedTagName( $r['querymodules'], 'module' );
}
- if($params['mainmodule'])
- $r['mainmodule'] = $this->getClassInfo($this->getMain());
- if($params['pagesetmodule'])
+ if ( $params['mainmodule'] )
+ $r['mainmodule'] = $this->getClassInfo( $this->getMain() );
+ if ( $params['pagesetmodule'] )
{
- $pageSet = new ApiPageSet($queryObj);
- $r['pagesetmodule'] = $this->getClassInfo($pageSet);
+ $pageSet = new ApiPageSet( $queryObj );
+ $r['pagesetmodule'] = $this->getClassInfo( $pageSet );
}
- $result->addValue(null, $this->getModuleName(), $r);
+ $result->addValue( null, $this->getModuleName(), $r );
}
- function getClassInfo($obj)
+ function getClassInfo( $obj )
{
$result = $this->getResult();
- $retval['classname'] = get_class($obj);
- $retval['description'] = (is_array($obj->getDescription()) ? implode("\n", $obj->getDescription()) : $obj->getDescription());
+ $retval['classname'] = get_class( $obj );
+ $retval['description'] = implode( "\n", (array)$obj->getDescription() );
+ $retval['version'] = implode( "\n", (array)$obj->getVersion() );
$retval['prefix'] = $obj->getModulePrefix();
- if($obj->isReadMode())
+
+ if ( $obj->isReadMode() )
$retval['readrights'] = '';
- if($obj->isWriteMode())
+ if ( $obj->isWriteMode() )
$retval['writerights'] = '';
- if($obj->mustBePosted())
+ if ( $obj->mustBePosted() )
$retval['mustbeposted'] = '';
+ if ( $obj instanceof ApiQueryGeneratorBase )
+ $retval['generator'] = '';
+
$allowedParams = $obj->getFinalParams();
- if(!is_array($allowedParams))
+ if ( !is_array( $allowedParams ) )
return $retval;
+
$retval['parameters'] = array();
$paramDesc = $obj->getFinalParamDescription();
- foreach($allowedParams as $n => $p)
+ foreach ( $allowedParams as $n => $p )
{
- $a = array('name' => $n);
- if(!is_array($p))
+ $a = array( 'name' => $n );
+ if ( isset( $paramDesc[$n] ) )
+ $a['description'] = implode( "\n", (array)$paramDesc[$n] );
+ if ( isset( $p[ApiBase::PARAM_DEPRECATED] ) && $p[ApiBase::PARAM_DEPRECATED] )
+ $a['deprecated'] = '';
+ if ( !is_array( $p ) )
{
- if(is_bool($p))
+ if ( is_bool( $p ) )
{
$a['type'] = 'bool';
- $a['default'] = ($p ? 'true' : 'false');
+ $a['default'] = ( $p ? 'true' : 'false' );
+ }
+ else if ( is_string( $p ) || is_null( $p ) )
+ {
+ $a['type'] = 'string';
+ $a['default'] = strval( $p );
+ }
+ else if ( is_int( $p ) )
+ {
+ $a['type'] = 'integer';
+ $a['default'] = intval( $p );
}
- if(is_string($p))
- $a['default'] = $p;
$retval['parameters'][] = $a;
continue;
}
- if(isset($p[ApiBase::PARAM_DFLT]))
+ if ( isset( $p[ApiBase::PARAM_DFLT] ) )
$a['default'] = $p[ApiBase::PARAM_DFLT];
- if(isset($p[ApiBase::PARAM_ISMULTI]))
- if($p[ApiBase::PARAM_ISMULTI])
+ if ( isset( $p[ApiBase::PARAM_ISMULTI] ) )
+ if ( $p[ApiBase::PARAM_ISMULTI] )
{
$a['multi'] = '';
$a['limit'] = $this->getMain()->canApiHighLimits() ?
ApiBase::LIMIT_SML2 :
ApiBase::LIMIT_SML1;
}
- if(isset($p[ApiBase::PARAM_ALLOW_DUPLICATES]))
- if($p[ApiBase::PARAM_ALLOW_DUPLICATES])
+
+ if ( isset( $p[ApiBase::PARAM_ALLOW_DUPLICATES] ) )
+ if ( $p[ApiBase::PARAM_ALLOW_DUPLICATES] )
$a['allowsduplicates'] = '';
- if(isset($p[ApiBase::PARAM_TYPE]))
+
+ if ( isset( $p[ApiBase::PARAM_TYPE] ) )
{
$a['type'] = $p[ApiBase::PARAM_TYPE];
- if(is_array($a['type']))
- $result->setIndexedTagName($a['type'], 't');
+ if ( is_array( $a['type'] ) )
+ $result->setIndexedTagName( $a['type'], 't' );
}
- if(isset($p[ApiBase::PARAM_MAX]))
+ if ( isset( $p[ApiBase::PARAM_MAX] ) )
$a['max'] = $p[ApiBase::PARAM_MAX];
- if(isset($p[ApiBase::PARAM_MAX2]))
+ if ( isset( $p[ApiBase::PARAM_MAX2] ) )
$a['highmax'] = $p[ApiBase::PARAM_MAX2];
- if(isset($p[ApiBase::PARAM_MIN]))
+ if ( isset( $p[ApiBase::PARAM_MIN] ) )
$a['min'] = $p[ApiBase::PARAM_MIN];
- if(isset($paramDesc[$n]))
- $a['description'] = (is_array($paramDesc[$n]) ? implode("\n", $paramDesc[$n]) : $paramDesc[$n]);
$retval['parameters'][] = $a;
}
- $result->setIndexedTagName($retval['parameters'], 'param');
+ $result->setIndexedTagName( $retval['parameters'], 'param' );
+
+ // Errors
+ $retval['errors'] = $this->parseErrors( $obj->getPossibleErrors() );
+
+ $result->setIndexedTagName( $retval['errors'], 'error' );
+
return $retval;
}
@@ -190,6 +216,6 @@ class ApiParamInfo extends ApiBase {
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiParamInfo.php 48091 2009-03-06 13:49:44Z catrope $';
+ return __CLASS__ . ': $Id: ApiParamInfo.php 62336 2010-02-11 22:22:20Z reedy $';
}
}
diff --git a/includes/api/ApiParse.php b/includes/api/ApiParse.php
index c8cd07fe..db389bdb 100644
--- a/includes/api/ApiParse.php
+++ b/includes/api/ApiParse.php
@@ -23,9 +23,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ("ApiBase.php");
+ require_once ( "ApiBase.php" );
}
/**
@@ -33,8 +33,8 @@ if (!defined('MEDIAWIKI')) {
*/
class ApiParse extends ApiBase {
- public function __construct($main, $action) {
- parent :: __construct($main, $action);
+ public function __construct( $main, $action ) {
+ parent :: __construct( $main, $action );
}
public function execute() {
@@ -47,119 +47,140 @@ class ApiParse extends ApiBase {
$title = $params['title'];
$page = $params['page'];
$oldid = $params['oldid'];
- if(!is_null($page) && (!is_null($text) || $title != "API"))
- $this->dieUsage("The page parameter cannot be used together with the text and title parameters", 'params');
- $prop = array_flip($params['prop']);
+ if ( !is_null( $page ) && ( !is_null( $text ) || $title != "API" ) )
+ $this->dieUsage( "The page parameter cannot be used together with the text and title parameters", 'params' );
+ $prop = array_flip( $params['prop'] );
$revid = false;
// The parser needs $wgTitle to be set, apparently the
// $title parameter in Parser::parse isn't enough *sigh*
- global $wgParser, $wgUser, $wgTitle;
+ global $wgParser, $wgUser, $wgTitle, $wgEnableParserCache;
$popts = new ParserOptions();
- $popts->setTidy(true);
+ $popts->setTidy( true );
$popts->enableLimitReport();
$redirValues = null;
- if(!is_null($oldid) || !is_null($page))
+ if ( !is_null( $oldid ) || !is_null( $page ) )
{
- if(!is_null($oldid))
+ if ( !is_null( $oldid ) )
{
- # Don't use the parser cache
- $rev = Revision::newFromID($oldid);
- if(!$rev)
- $this->dieUsage("There is no revision ID $oldid", 'missingrev');
- if(!$rev->userCan(Revision::DELETED_TEXT))
- $this->dieUsage("You don't have permission to view deleted revisions", 'permissiondenied');
+ // Don't use the parser cache
+ $rev = Revision::newFromID( $oldid );
+ if ( !$rev )
+ $this->dieUsage( "There is no revision ID $oldid", 'missingrev' );
+ if ( !$rev->userCan( Revision::DELETED_TEXT ) )
+ $this->dieUsage( "You don't have permission to view deleted revisions", 'permissiondenied' );
+
$text = $rev->getText( Revision::FOR_THIS_USER );
$titleObj = $rev->getTitle();
$wgTitle = $titleObj;
- $p_result = $wgParser->parse($text, $titleObj, $popts);
+ $p_result = $wgParser->parse( $text, $titleObj, $popts );
}
else
{
- if($params['redirects'])
+ if ( $params['redirects'] )
{
- $req = new FauxRequest(array(
+ $req = new FauxRequest( array(
'action' => 'query',
'redirects' => '',
'titles' => $page
- ));
- $main = new ApiMain($req);
+ ) );
+ $main = new ApiMain( $req );
$main->execute();
$data = $main->getResultData();
$redirValues = @$data['query']['redirects'];
$to = $page;
- foreach((array)$redirValues as $r)
+ foreach ( (array)$redirValues as $r )
$to = $r['to'];
}
else
- $to = $page;
- $titleObj = Title::newFromText($to);
- if(!$titleObj)
- $this->dieUsage("The page you specified doesn't exist", 'missingtitle');
+ $to = $page;
+ $titleObj = Title::newFromText( $to );
+ if ( !$titleObj )
+ $this->dieUsage( "The page you specified doesn't exist", 'missingtitle' );
- $articleObj = new Article($titleObj);
- if(isset($prop['revid']))
+ $articleObj = new Article( $titleObj );
+ if ( isset( $prop['revid'] ) )
$oldid = $articleObj->getRevIdFetched();
// Try the parser cache first
+ $p_result = false;
$pcache = ParserCache::singleton();
- $p_result = $pcache->get($articleObj, $wgUser);
- if(!$p_result)
+ if ( $wgEnableParserCache )
+ $p_result = $pcache->get( $articleObj, $wgUser );
+ if ( !$p_result )
{
- $p_result = $wgParser->parse($articleObj->getContent(), $titleObj, $popts);
- global $wgUseParserCache;
- if($wgUseParserCache)
- $pcache->save($p_result, $articleObj, $popts);
+ $p_result = $wgParser->parse( $articleObj->getContent(), $titleObj, $popts );
+
+ if ( $wgEnableParserCache )
+ $pcache->save( $p_result, $articleObj, $popts );
}
}
}
else
{
- $titleObj = Title::newFromText($title);
- if(!$titleObj)
- $titleObj = Title::newFromText("API");
+ $titleObj = Title::newFromText( $title );
+ if ( !$titleObj )
+ $titleObj = Title::newFromText( "API" );
$wgTitle = $titleObj;
- if($params['pst'] || $params['onlypst'])
- $text = $wgParser->preSaveTransform($text, $titleObj, $wgUser, $popts);
- if($params['onlypst'])
+ if ( $params['pst'] || $params['onlypst'] )
+ $text = $wgParser->preSaveTransform( $text, $titleObj, $wgUser, $popts );
+ if ( $params['onlypst'] )
{
// Build a result and bail out
$result_array['text'] = array();
- $this->getResult()->setContent($result_array['text'], $text);
- $this->getResult()->addValue(null, $this->getModuleName(), $result_array);
+ $this->getResult()->setContent( $result_array['text'], $text );
+ $this->getResult()->addValue( null, $this->getModuleName(), $result_array );
return;
}
- $p_result = $wgParser->parse($text, $titleObj, $popts);
+ $p_result = $wgParser->parse( $text, $titleObj, $popts );
}
// Return result
$result = $this->getResult();
$result_array = array();
- if($params['redirects'] && !is_null($redirValues))
+ if ( $params['redirects'] && !is_null( $redirValues ) )
$result_array['redirects'] = $redirValues;
- if(isset($prop['text'])) {
+
+ if ( isset( $prop['text'] ) ) {
$result_array['text'] = array();
- $result->setContent($result_array['text'], $p_result->getText());
+ $result->setContent( $result_array['text'], $p_result->getText() );
+ }
+
+ if ( !is_null( $params['summary'] ) ) {
+ $result_array['parsedsummary'] = array();
+ $result->setContent( $result_array['parsedsummary'], $wgUser->getSkin()->formatComment( $params['summary'], $titleObj ) );
}
- if(isset($prop['langlinks']))
- $result_array['langlinks'] = $this->formatLangLinks($p_result->getLanguageLinks());
- if(isset($prop['categories']))
- $result_array['categories'] = $this->formatCategoryLinks($p_result->getCategories());
- if(isset($prop['links']))
- $result_array['links'] = $this->formatLinks($p_result->getLinks());
- if(isset($prop['templates']))
- $result_array['templates'] = $this->formatLinks($p_result->getTemplates());
- if(isset($prop['images']))
- $result_array['images'] = array_keys($p_result->getImages());
- if(isset($prop['externallinks']))
- $result_array['externallinks'] = array_keys($p_result->getExternalLinks());
- if(isset($prop['sections']))
+
+ if ( isset( $prop['langlinks'] ) )
+ $result_array['langlinks'] = $this->formatLangLinks( $p_result->getLanguageLinks() );
+ if ( isset( $prop['categories'] ) )
+ $result_array['categories'] = $this->formatCategoryLinks( $p_result->getCategories() );
+ if ( isset( $prop['links'] ) )
+ $result_array['links'] = $this->formatLinks( $p_result->getLinks() );
+ if ( isset( $prop['templates'] ) )
+ $result_array['templates'] = $this->formatLinks( $p_result->getTemplates() );
+ if ( isset( $prop['images'] ) )
+ $result_array['images'] = array_keys( $p_result->getImages() );
+ if ( isset( $prop['externallinks'] ) )
+ $result_array['externallinks'] = array_keys( $p_result->getExternalLinks() );
+ if ( isset( $prop['sections'] ) )
$result_array['sections'] = $p_result->getSections();
- if(isset($prop['displaytitle']))
+ if ( isset( $prop['displaytitle'] ) )
$result_array['displaytitle'] = $p_result->getDisplayTitle() ?
$p_result->getDisplayTitle() :
$titleObj->getPrefixedText();
- if(!is_null($oldid))
- $result_array['revid'] = intval($oldid);
+
+ if ( isset( $prop['headitems'] ) )
+ $result_array['headitems'] = $this->formatHeadItems( $p_result->getHeadItems() );
+
+ if ( isset( $prop['headhtml'] ) ) {
+ $out = new OutputPage;
+ $out->addParserOutputNoText( $p_result );
+ $result_array['headhtml'] = array();
+ $result->setContent( $result_array['headhtml'], $out->headElement( $wgUser->getSkin() ) );
+ }
+
+ if ( !is_null( $oldid ) )
+ $result_array['revid'] = intval( $oldid );
$result_mapping = array(
'redirects' => 'r',
@@ -170,6 +191,7 @@ class ApiParse extends ApiBase {
'images' => 'img',
'externallinks' => 'el',
'sections' => 's',
+ 'headitems' => 'hi'
);
$this->setIndexedTagNames( $result_array, $result_mapping );
$result->addValue( null, $this->getModuleName(), $result_array );
@@ -177,9 +199,9 @@ class ApiParse extends ApiBase {
private function formatLangLinks( $links ) {
$result = array();
- foreach( $links as $link ) {
+ foreach ( $links as $link ) {
$entry = array();
- $bits = split( ':', $link, 2 );
+ $bits = explode( ':', $link, 2 );
$entry['lang'] = $bits[0];
$this->getResult()->setContent( $entry, $bits[1] );
$result[] = $entry;
@@ -189,7 +211,7 @@ class ApiParse extends ApiBase {
private function formatCategoryLinks( $links ) {
$result = array();
- foreach( $links as $link => $sortkey ) {
+ foreach ( $links as $link => $sortkey ) {
$entry = array();
$entry['sortkey'] = $sortkey;
$this->getResult()->setContent( $entry, $link );
@@ -200,12 +222,12 @@ class ApiParse extends ApiBase {
private function formatLinks( $links ) {
$result = array();
- foreach( $links as $ns => $nslinks ) {
- foreach( $nslinks as $title => $id ) {
+ foreach ( $links as $ns => $nslinks ) {
+ foreach ( $nslinks as $title => $id ) {
$entry = array();
$entry['ns'] = $ns;
$this->getResult()->setContent( $entry, Title::makeTitle( $ns, $title )->getFullText() );
- if( $id != 0 )
+ if ( $id != 0 )
$entry['exists'] = '';
$result[] = $entry;
}
@@ -213,9 +235,20 @@ class ApiParse extends ApiBase {
return $result;
}
+ private function formatHeadItems( $headItems ) {
+ $result = array();
+ foreach ( $headItems as $tag => $content ) {
+ $entry = array();
+ $entry['tag'] = $tag;
+ $this->getResult()->setContent( $entry, $content );
+ $result[] = $entry;
+ }
+ return $result;
+ }
+
private function setIndexedTagNames( &$array, $mapping ) {
- foreach( $mapping as $key => $name ) {
- if( isset( $array[$key] ) )
+ foreach ( $mapping as $key => $name ) {
+ if ( isset( $array[$key] ) )
$this->getResult()->setIndexedTagName( $array[$key], $name );
}
}
@@ -226,6 +259,7 @@ class ApiParse extends ApiBase {
ApiBase :: PARAM_DFLT => 'API',
),
'text' => null,
+ 'summary' => null,
'page' => null,
'redirects' => false,
'oldid' => null,
@@ -243,6 +277,8 @@ class ApiParse extends ApiBase {
'sections',
'revid',
'displaytitle',
+ 'headitems',
+ 'headhtml'
)
),
'pst' => false,
@@ -253,17 +289,18 @@ class ApiParse extends ApiBase {
public function getParamDescription() {
return array (
'text' => 'Wikitext to parse',
+ 'summary' => 'Summary to parse',
'redirects' => 'If the page parameter is set to a redirect, resolve it',
'title' => 'Title of page the text belongs to',
'page' => 'Parse the content of this page. Cannot be used together with text and title',
'oldid' => 'Parse the content of this revision. Overrides page',
- 'prop' => array('Which pieces of information to get.',
+ 'prop' => array( 'Which pieces of information to get.',
'NOTE: Section tree is only generated if there are more than 4 sections, or if the __TOC__ keyword is present'
),
'pst' => array( 'Do a pre-save transform on the input before parsing it.',
'Ignored if page or oldid is used.'
),
- 'onlypst' => array('Do a PST on the input, but don\'t parse it.',
+ 'onlypst' => array( 'Do a PST on the input, but don\'t parse it.',
'Returns PSTed wikitext. Ignored if page or oldid is used.'
),
);
@@ -272,6 +309,15 @@ class ApiParse extends ApiBase {
public function getDescription() {
return 'This module parses wikitext and returns parser output';
}
+
+ public function getPossibleErrors() {
+ return array_merge( parent::getPossibleErrors(), array(
+ array( 'code' => 'params', 'info' => 'The page parameter cannot be used together with the text and title parameters' ),
+ array( 'code' => 'missingrev', 'info' => 'There is no revision ID oldid' ),
+ array( 'code' => 'permissiondenied', 'info' => 'You don\'t have permission to view deleted revisions' ),
+ array( 'code' => 'missingtitle', 'info' => 'The page you specified doesn\'t exist' ),
+ ) );
+ }
protected function getExamples() {
return array (
@@ -280,6 +326,6 @@ class ApiParse extends ApiBase {
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiParse.php 69986 2010-07-27 03:57:39Z tstarling $';
+ return __CLASS__ . ': $Id: ApiParse.php 69932 2010-07-26 08:03:21Z tstarling $';
}
}
diff --git a/includes/api/ApiPatrol.php b/includes/api/ApiPatrol.php
index a6f25af2..3b2b2046 100644
--- a/includes/api/ApiPatrol.php
+++ b/includes/api/ApiPatrol.php
@@ -23,8 +23,8 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
- require_once ('ApiBase.php');
+if ( !defined( 'MEDIAWIKI' ) ) {
+ require_once ( 'ApiBase.php' );
}
/**
@@ -33,35 +33,30 @@ if (!defined('MEDIAWIKI')) {
*/
class ApiPatrol extends ApiBase {
- public function __construct($main, $action) {
- parent :: __construct($main, $action);
+ public function __construct( $main, $action ) {
+ parent :: __construct( $main, $action );
}
/**
* Patrols the article or provides the reason the patrol failed.
*/
public function execute() {
- global $wgUser, $wgUseRCPatrol, $wgUseNPPatrol;
$params = $this->extractRequestParams();
- if(!isset($params['token']))
- $this->dieUsageMsg(array('missingparam', 'token'));
- if(!isset($params['rcid']))
- $this->dieUsageMsg(array('missingparam', 'rcid'));
- if(!$wgUser->matchEditToken($params['token']))
- $this->dieUsageMsg(array('sessionfailure'));
+ if ( !isset( $params['rcid'] ) )
+ $this->dieUsageMsg( array( 'missingparam', 'rcid' ) );
- $rc = RecentChange::newFromID($params['rcid']);
- if(!$rc instanceof RecentChange)
- $this->dieUsageMsg(array('nosuchrcid', $params['rcid']));
- $retval = RecentChange::markPatrolled($params['rcid']);
+ $rc = RecentChange::newFromID( $params['rcid'] );
+ if ( !$rc instanceof RecentChange )
+ $this->dieUsageMsg( array( 'nosuchrcid', $params['rcid'] ) );
+ $retval = RecentChange::markPatrolled( $params['rcid'] );
- if($retval)
- $this->dieUsageMsg(reset($retval));
+ if ( $retval )
+ $this->dieUsageMsg( reset( $retval ) );
- $result = array('rcid' => intval($rc->getAttribute('rc_id')));
- ApiQueryBase::addTitleInfo($result, $rc->getTitle());
- $this->getResult()->addValue(null, $this->getModuleName(), $result);
+ $result = array( 'rcid' => intval( $rc->getAttribute( 'rc_id' ) ) );
+ ApiQueryBase::addTitleInfo( $result, $rc->getTitle() );
+ $this->getResult()->addValue( null, $this->getModuleName(), $result );
}
public function isWriteMode() {
@@ -89,6 +84,17 @@ class ApiPatrol extends ApiBase {
'Patrol a page or revision. '
);
}
+
+ public function getPossibleErrors() {
+ return array_merge( parent::getPossibleErrors(), array(
+ array( 'missingparam', 'rcid' ),
+ array( 'nosuchrcid', 'rcid' ),
+ ) );
+ }
+
+ public function getTokenSalt() {
+ return '';
+ }
protected function getExamples() {
return array(
@@ -97,6 +103,6 @@ class ApiPatrol extends ApiBase {
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiPatrol.php 69579 2010-07-20 02:49:55Z tstarling $';
+ return __CLASS__ . ': $Id: ApiPatrol.php 69578 2010-07-20 02:46:20Z tstarling $';
}
-}
+} \ No newline at end of file
diff --git a/includes/api/ApiProtect.php b/includes/api/ApiProtect.php
index aad37066..ca47c1b8 100644
--- a/includes/api/ApiProtect.php
+++ b/includes/api/ApiProtect.php
@@ -22,9 +22,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ("ApiBase.php");
+ require_once ( "ApiBase.php" );
}
/**
@@ -32,99 +32,100 @@ if (!defined('MEDIAWIKI')) {
*/
class ApiProtect extends ApiBase {
- public function __construct($main, $action) {
- parent :: __construct($main, $action);
+ public function __construct( $main, $action ) {
+ parent :: __construct( $main, $action );
}
public function execute() {
global $wgUser, $wgRestrictionTypes, $wgRestrictionLevels;
$params = $this->extractRequestParams();
- $titleObj = NULL;
- if(!isset($params['title']))
- $this->dieUsageMsg(array('missingparam', 'title'));
- if(!isset($params['token']))
- $this->dieUsageMsg(array('missingparam', 'token'));
- if(empty($params['protections']))
- $this->dieUsageMsg(array('missingparam', 'protections'));
+ $titleObj = null;
+ if ( !isset( $params['title'] ) )
+ $this->dieUsageMsg( array( 'missingparam', 'title' ) );
+ if ( empty( $params['protections'] ) )
+ $this->dieUsageMsg( array( 'missingparam', 'protections' ) );
- if(!$wgUser->matchEditToken($params['token']))
- $this->dieUsageMsg(array('sessionfailure'));
+ $titleObj = Title::newFromText( $params['title'] );
+ if ( !$titleObj )
+ $this->dieUsageMsg( array( 'invalidtitle', $params['title'] ) );
- $titleObj = Title::newFromText($params['title']);
- if(!$titleObj)
- $this->dieUsageMsg(array('invalidtitle', $params['title']));
-
- $errors = $titleObj->getUserPermissionsErrors('protect', $wgUser);
- if($errors)
+ $errors = $titleObj->getUserPermissionsErrors( 'protect', $wgUser );
+ if ( $errors )
// We don't care about multiple errors, just report one of them
- $this->dieUsageMsg(reset($errors));
+ $this->dieUsageMsg( reset( $errors ) );
$expiry = (array)$params['expiry'];
- if(count($expiry) != count($params['protections']))
+ if ( count( $expiry ) != count( $params['protections'] ) )
{
- if(count($expiry) == 1)
- $expiry = array_fill(0, count($params['protections']), $expiry[0]);
+ if ( count( $expiry ) == 1 )
+ $expiry = array_fill( 0, count( $params['protections'] ), $expiry[0] );
else
- $this->dieUsageMsg(array('toofewexpiries', count($expiry), count($params['protections'])));
+ $this->dieUsageMsg( array( 'toofewexpiries', count( $expiry ), count( $params['protections'] ) ) );
}
+
+ $restrictionTypes = $titleObj->getRestrictionTypes();
$protections = array();
$expiryarray = array();
$resultProtections = array();
- foreach($params['protections'] as $i => $prot)
+ foreach ( $params['protections'] as $i => $prot )
{
- $p = explode('=', $prot);
- $protections[$p[0]] = ($p[1] == 'all' ? '' : $p[1]);
- if($titleObj->exists() && $p[0] == 'create')
- $this->dieUsageMsg(array('create-titleexists'));
- if(!$titleObj->exists() && $p[0] != 'create')
- $this->dieUsageMsg(array('missingtitles-createonly'));
- if(!in_array($p[0], $wgRestrictionTypes) && $p[0] != 'create')
- $this->dieUsageMsg(array('protect-invalidaction', $p[0]));
- if(!in_array($p[1], $wgRestrictionLevels) && $p[1] != 'all')
- $this->dieUsageMsg(array('protect-invalidlevel', $p[1]));
-
- if(in_array($expiry[$i], array('infinite', 'indefinite', 'never')))
+ $p = explode( '=', $prot );
+ $protections[$p[0]] = ( $p[1] == 'all' ? '' : $p[1] );
+
+ if ( $titleObj->exists() && $p[0] == 'create' )
+ $this->dieUsageMsg( array( 'create-titleexists' ) );
+ if ( !$titleObj->exists() && $p[0] != 'create' )
+ $this->dieUsageMsg( array( 'missingtitle-createonly' ) );
+
+ if ( !in_array( $p[0], $restrictionTypes ) && $p[0] != 'create' )
+ $this->dieUsageMsg( array( 'protect-invalidaction', $p[0] ) );
+ if ( !in_array( $p[1], $wgRestrictionLevels ) && $p[1] != 'all' )
+ $this->dieUsageMsg( array( 'protect-invalidlevel', $p[1] ) );
+
+ if ( in_array( $expiry[$i], array( 'infinite', 'indefinite', 'never' ) ) )
$expiryarray[$p[0]] = Block::infinity();
else
{
- $exp = strtotime($expiry[$i]);
- if($exp < 0 || $exp == false)
- $this->dieUsageMsg(array('invalidexpiry', $expiry[$i]));
+ $exp = strtotime( $expiry[$i] );
+ if ( $exp < 0 || $exp == false )
+ $this->dieUsageMsg( array( 'invalidexpiry', $expiry[$i] ) );
- $exp = wfTimestamp(TS_MW, $exp);
- if($exp < wfTimestampNow())
- $this->dieUsageMsg(array('pastexpiry', $expiry[$i]));
+ $exp = wfTimestamp( TS_MW, $exp );
+ if ( $exp < wfTimestampNow() )
+ $this->dieUsageMsg( array( 'pastexpiry', $expiry[$i] ) );
$expiryarray[$p[0]] = $exp;
}
- $resultProtections[] = array($p[0] => $protections[$p[0]],
- 'expiry' => ($expiryarray[$p[0]] == Block::infinity() ?
+ $resultProtections[] = array( $p[0] => $protections[$p[0]],
+ 'expiry' => ( $expiryarray[$p[0]] == Block::infinity() ?
'infinite' :
- wfTimestamp(TS_ISO_8601, $expiryarray[$p[0]])));
+ wfTimestamp( TS_ISO_8601, $expiryarray[$p[0]] ) ) );
}
$cascade = $params['cascade'];
- $articleObj = new Article($titleObj);
- if($params['watch'])
+ $articleObj = new Article( $titleObj );
+ if ( $params['watch'] )
$articleObj->doWatch();
- if($titleObj->exists())
- $ok = $articleObj->updateRestrictions($protections, $params['reason'], $cascade, $expiryarray);
+ if ( $titleObj->exists() )
+ $ok = $articleObj->updateRestrictions( $protections, $params['reason'], $cascade, $expiryarray );
else
- $ok = $titleObj->updateTitleProtection($protections['create'], $params['reason'], $expiryarray['create']);
- if(!$ok)
+ $ok = $titleObj->updateTitleProtection( $protections['create'], $params['reason'], $expiryarray['create'] );
+ if ( !$ok )
// This is very weird. Maybe the article was deleted or the user was blocked/desysopped in the meantime?
// Just throw an unknown error in this case, as it's very likely to be a race condition
- $this->dieUsageMsg(array());
- $res = array('title' => $titleObj->getPrefixedText(), 'reason' => $params['reason']);
- if($cascade)
+ $this->dieUsageMsg( array() );
+ $res = array( 'title' => $titleObj->getPrefixedText(), 'reason' => $params['reason'] );
+ if ( $cascade )
$res['cascade'] = '';
$res['protections'] = $resultProtections;
- $this->getResult()->setIndexedTagName($res['protections'], 'protection');
- $this->getResult()->addValue(null, $this->getModuleName(), $res);
+ $this->getResult()->setIndexedTagName( $res['protections'], 'protection' );
+ $this->getResult()->addValue( null, $this->getModuleName(), $res );
}
- public function mustBePosted() { return true; }
+ public function mustBePosted() {
+ return true;
+ }
public function isWriteMode() {
return true;
@@ -153,11 +154,11 @@ class ApiProtect extends ApiBase {
'title' => 'Title of the page you want to (un)protect.',
'token' => 'A protect token previously retrieved through prop=info',
'protections' => 'Pipe-separated list of protection levels, formatted action=group (e.g. edit=sysop)',
- 'expiry' => array('Expiry timestamps. If only one timestamp is set, it\'ll be used for all protections.',
- 'Use \'infinite\', \'indefinite\' or \'never\', for a neverexpiring protection.'),
+ 'expiry' => array( 'Expiry timestamps. If only one timestamp is set, it\'ll be used for all protections.',
+ 'Use \'infinite\', \'indefinite\' or \'never\', for a neverexpiring protection.' ),
'reason' => 'Reason for (un)protecting (optional)',
- 'cascade' => array('Enable cascading protection (i.e. protect pages included in this page)',
- 'Ignored if not all protection levels are \'sysop\' or \'protect\''),
+ 'cascade' => array( 'Enable cascading protection (i.e. protect pages included in this page)',
+ 'Ignored if not all protection levels are \'sysop\' or \'protect\'' ),
'watch' => 'If set, add the page being (un)protected to your watchlist',
);
}
@@ -167,6 +168,25 @@ class ApiProtect extends ApiBase {
'Change the protection level of a page.'
);
}
+
+ public function getPossibleErrors() {
+ return array_merge( parent::getPossibleErrors(), array(
+ array( 'missingparam', 'title' ),
+ array( 'missingparam', 'protections' ),
+ array( 'invalidtitle', 'title' ),
+ array( 'toofewexpiries', 'noofexpiries', 'noofprotections' ),
+ array( 'create-titleexists' ),
+ array( 'missingtitle-createonly' ),
+ array( 'protect-invalidaction', 'action' ),
+ array( 'protect-invalidlevel', 'level' ),
+ array( 'invalidexpiry', 'expiry' ),
+ array( 'pastexpiry', 'expiry' ),
+ ) );
+ }
+
+ public function getTokenSalt() {
+ return null;
+ }
protected function getExamples() {
return array (
@@ -176,6 +196,6 @@ class ApiProtect extends ApiBase {
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiProtect.php 48122 2009-03-07 12:58:41Z catrope $';
+ return __CLASS__ . ': $Id: ApiProtect.php 62557 2010-02-15 23:53:43Z reedy $';
}
}
diff --git a/includes/api/ApiPurge.php b/includes/api/ApiPurge.php
index d1e6824d..76d45404 100644
--- a/includes/api/ApiPurge.php
+++ b/includes/api/ApiPurge.php
@@ -23,8 +23,8 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
- require_once ('ApiBase.php');
+if ( !defined( 'MEDIAWIKI' ) ) {
+ require_once ( 'ApiBase.php' );
}
/**
@@ -33,8 +33,8 @@ if (!defined('MEDIAWIKI')) {
*/
class ApiPurge extends ApiBase {
- public function __construct($main, $action) {
- parent :: __construct($main, $action);
+ public function __construct( $main, $action ) {
+ parent :: __construct( $main, $action );
}
/**
@@ -43,35 +43,35 @@ class ApiPurge extends ApiBase {
public function execute() {
global $wgUser;
$params = $this->extractRequestParams();
- if(!$wgUser->isAllowed('purge'))
- $this->dieUsageMsg(array('cantpurge'));
- if(!isset($params['titles']))
- $this->dieUsageMsg(array('missingparam', 'titles'));
+ if ( !$wgUser->isAllowed( 'purge' ) )
+ $this->dieUsageMsg( array( 'cantpurge' ) );
+ if ( !isset( $params['titles'] ) )
+ $this->dieUsageMsg( array( 'missingparam', 'titles' ) );
$result = array();
- foreach($params['titles'] as $t) {
+ foreach ( $params['titles'] as $t ) {
$r = array();
- $title = Title::newFromText($t);
- if(!$title instanceof Title)
+ $title = Title::newFromText( $t );
+ if ( !$title instanceof Title )
{
$r['title'] = $t;
$r['invalid'] = '';
$result[] = $r;
continue;
}
- ApiQueryBase::addTitleInfo($r, $title);
- if(!$title->exists())
+ ApiQueryBase::addTitleInfo( $r, $title );
+ if ( !$title->exists() )
{
$r['missing'] = '';
$result[] = $r;
continue;
}
- $article = new Article($title);
+ $article = Mediawiki::articleFromTitle( $title );
$article->doPurge(); // Directly purge and skip the UI part of purge().
$r['purged'] = '';
$result[] = $r;
}
- $this->getResult()->setIndexedTagName($result, 'page');
- $this->getResult()->addValue(null, $this->getModuleName(), $result);
+ $this->getResult()->setIndexedTagName( $result, 'page' );
+ $this->getResult()->addValue( null, $this->getModuleName(), $result );
}
public function mustBePosted() {
@@ -102,6 +102,13 @@ class ApiPurge extends ApiBase {
'Purge the cache for the given titles.'
);
}
+
+ public function getPossibleErrors() {
+ return array_merge( parent::getPossibleErrors(), array(
+ array( 'cantpurge' ),
+ array( 'missingparam', 'titles' ),
+ ) );
+ }
protected function getExamples() {
return array(
@@ -110,6 +117,6 @@ class ApiPurge extends ApiBase {
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiPurge.php 69579 2010-07-20 02:49:55Z tstarling $';
+ return __CLASS__ . ': $Id: ApiPurge.php 69578 2010-07-20 02:46:20Z tstarling $';
}
}
diff --git a/includes/api/ApiQuery.php b/includes/api/ApiQuery.php
index 49ddcdd3..8d3ef616 100644
--- a/includes/api/ApiQuery.php
+++ b/includes/api/ApiQuery.php
@@ -23,9 +23,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ('ApiBase.php');
+ require_once ( 'ApiBase.php' );
}
/**
@@ -74,6 +74,7 @@ class ApiQuery extends ApiBase {
'logevents' => 'ApiQueryLogEvents',
'recentchanges' => 'ApiQueryRecentChanges',
'search' => 'ApiQuerySearch',
+ 'tags' => 'ApiQueryTags',
'usercontribs' => 'ApiQueryContributions',
'watchlist' => 'ApiQueryWatchlist',
'watchlistraw' => 'ApiQueryWatchlistRaw',
@@ -92,22 +93,22 @@ class ApiQuery extends ApiBase {
private $mSlaveDB = null;
private $mNamedDB = array();
- public function __construct($main, $action) {
- parent :: __construct($main, $action);
+ public function __construct( $main, $action ) {
+ parent :: __construct( $main, $action );
// Allow custom modules to be added in LocalSettings.php
global $wgAPIPropModules, $wgAPIListModules, $wgAPIMetaModules;
- self :: appendUserModules($this->mQueryPropModules, $wgAPIPropModules);
- self :: appendUserModules($this->mQueryListModules, $wgAPIListModules);
- self :: appendUserModules($this->mQueryMetaModules, $wgAPIMetaModules);
+ self :: appendUserModules( $this->mQueryPropModules, $wgAPIPropModules );
+ self :: appendUserModules( $this->mQueryListModules, $wgAPIListModules );
+ self :: appendUserModules( $this->mQueryMetaModules, $wgAPIMetaModules );
- $this->mPropModuleNames = array_keys($this->mQueryPropModules);
- $this->mListModuleNames = array_keys($this->mQueryListModules);
- $this->mMetaModuleNames = array_keys($this->mQueryMetaModules);
+ $this->mPropModuleNames = array_keys( $this->mQueryPropModules );
+ $this->mListModuleNames = array_keys( $this->mQueryListModules );
+ $this->mMetaModuleNames = array_keys( $this->mQueryMetaModules );
// Allow the entire list of modules at first,
// but during module instantiation check if it can be used as a generator.
- $this->mAllowedGenerators = array_merge($this->mListModuleNames, $this->mPropModuleNames);
+ $this->mAllowedGenerators = array_merge( $this->mListModuleNames, $this->mPropModuleNames );
}
/**
@@ -115,9 +116,9 @@ class ApiQuery extends ApiBase {
* @param $modules array Module array
* @param $newModules array Module array to add to $modules
*/
- private static function appendUserModules(&$modules, $newModules) {
- if (is_array( $newModules )) {
- foreach ( $newModules as $moduleName => $moduleClass) {
+ private static function appendUserModules( &$modules, $newModules ) {
+ if ( is_array( $newModules ) ) {
+ foreach ( $newModules as $moduleName => $moduleClass ) {
$modules[$moduleName] = $moduleClass;
}
}
@@ -128,9 +129,9 @@ class ApiQuery extends ApiBase {
* @return Database
*/
public function getDB() {
- if (!isset ($this->mSlaveDB)) {
+ if ( !isset ( $this->mSlaveDB ) ) {
$this->profileDBIn();
- $this->mSlaveDB = wfGetDB(DB_SLAVE,'api');
+ $this->mSlaveDB = wfGetDB( DB_SLAVE, 'api' );
$this->profileDBOut();
}
return $this->mSlaveDB;
@@ -146,10 +147,10 @@ class ApiQuery extends ApiBase {
* @param $groups array Query groups
* @return Database
*/
- public function getNamedDB($name, $db, $groups) {
- if (!array_key_exists($name, $this->mNamedDB)) {
+ public function getNamedDB( $name, $db, $groups ) {
+ if ( !array_key_exists( $name, $this->mNamedDB ) ) {
$this->profileDBIn();
- $this->mNamedDB[$name] = wfGetDB($db, $groups);
+ $this->mNamedDB[$name] = wfGetDB( $db, $groups );
$this->profileDBOut();
}
return $this->mNamedDB[$name];
@@ -168,15 +169,15 @@ class ApiQuery extends ApiBase {
* @return array(modulename => classname)
*/
function getModules() {
- return array_merge($this->mQueryPropModules, $this->mQueryListModules, $this->mQueryMetaModules);
+ return array_merge( $this->mQueryPropModules, $this->mQueryListModules, $this->mQueryMetaModules );
}
-
+
public function getCustomPrinter() {
// If &exportnowrap is set, use the raw formatter
- if ($this->getParameter('export') &&
- $this->getParameter('exportnowrap'))
- return new ApiFormatRaw($this->getMain(),
- $this->getMain()->createPrinterByName('xml'));
+ if ( $this->getParameter( 'export' ) &&
+ $this->getParameter( 'exportnowrap' ) )
+ return new ApiFormatRaw( $this->getMain(),
+ $this->getMain()->createPrinterByName( 'xml' ) );
else
return null;
}
@@ -196,24 +197,18 @@ class ApiQuery extends ApiBase {
$this->params = $this->extractRequestParams();
$this->redirects = $this->params['redirects'];
- //
// Create PageSet
- //
- $this->mPageSet = new ApiPageSet($this, $this->redirects);
+ $this->mPageSet = new ApiPageSet( $this, $this->redirects );
- //
// Instantiate requested modules
- //
$modules = array ();
- $this->InstantiateModules($modules, 'prop', $this->mQueryPropModules);
- $this->InstantiateModules($modules, 'list', $this->mQueryListModules);
- $this->InstantiateModules($modules, 'meta', $this->mQueryMetaModules);
+ $this->InstantiateModules( $modules, 'prop', $this->mQueryPropModules );
+ $this->InstantiateModules( $modules, 'list', $this->mQueryListModules );
+ $this->InstantiateModules( $modules, 'meta', $this->mQueryMetaModules );
$cacheMode = 'public';
- //
// If given, execute generator to substitute user supplied data with generated data.
- //
if ( isset ( $this->params['generator'] ) ) {
$generator = $this->newGenerator( $this->params['generator'] );
$params = $generator->extractRequestParams();
@@ -222,25 +217,21 @@ class ApiQuery extends ApiBase {
$this->executeGeneratorModule( $generator, $modules );
} else {
// Append custom fields and populate page/revision information
- $this->addCustomFldsToPageSet($modules, $this->mPageSet);
+ $this->addCustomFldsToPageSet( $modules, $this->mPageSet );
$this->mPageSet->execute();
}
- //
// Record page information (title, namespace, if exists, etc)
- //
$this->outputGeneralPageInfo();
- //
// Execute all requested modules.
- //
- foreach ($modules as $module) {
+ foreach ( $modules as $module ) {
$params = $module->extractRequestParams();
$cacheMode = $this->mergeCacheMode(
$cacheMode, $module->getCacheMode( $params ) );
$module->profileIn();
$module->execute();
- wfRunHooks('APIQueryAfterExecute', array(&$module));
+ wfRunHooks( 'APIQueryAfterExecute', array( &$module ) );
$module->profileOut();
}
@@ -273,10 +264,10 @@ class ApiQuery extends ApiBase {
* @param $modules array of module objects
* @param $pageSet ApiPageSet
*/
- private function addCustomFldsToPageSet($modules, $pageSet) {
+ private function addCustomFldsToPageSet( $modules, $pageSet ) {
// Query all requested modules.
- foreach ($modules as $module) {
- $module->requestExtraData($pageSet);
+ foreach ( $modules as $module ) {
+ $module->requestExtraData( $pageSet );
}
}
@@ -286,11 +277,11 @@ class ApiQuery extends ApiBase {
* @param $param string Parameter name to read modules from
* @param $moduleList array(modulename => classname)
*/
- private function InstantiateModules(&$modules, $param, $moduleList) {
+ private function InstantiateModules( &$modules, $param, $moduleList ) {
$list = @$this->params[$param];
- if (!is_null ($list))
- foreach ($list as $moduleName)
- $modules[] = new $moduleList[$moduleName] ($this, $moduleName);
+ if ( !is_null ( $list ) )
+ foreach ( $list as $moduleName )
+ $modules[] = new $moduleList[$moduleName] ( $this, $moduleName );
}
/**
@@ -303,65 +294,65 @@ class ApiQuery extends ApiBase {
$pageSet = $this->getPageSet();
$result = $this->getResult();
- # We don't check for a full result set here because we can't be adding
- # more than 380K. The maximum revision size is in the megabyte range,
- # and the maximum result size must be even higher than that.
+ // We don't check for a full result set here because we can't be adding
+ // more than 380K. The maximum revision size is in the megabyte range,
+ // and the maximum result size must be even higher than that.
// Title normalizations
$normValues = array ();
- foreach ($pageSet->getNormalizedTitles() as $rawTitleStr => $titleStr) {
+ foreach ( $pageSet->getNormalizedTitles() as $rawTitleStr => $titleStr ) {
$normValues[] = array (
'from' => $rawTitleStr,
'to' => $titleStr
);
}
- if (count($normValues)) {
- $result->setIndexedTagName($normValues, 'n');
- $result->addValue('query', 'normalized', $normValues);
+ if ( count( $normValues ) ) {
+ $result->setIndexedTagName( $normValues, 'n' );
+ $result->addValue( 'query', 'normalized', $normValues );
}
// Interwiki titles
$intrwValues = array ();
- foreach ($pageSet->getInterwikiTitles() as $rawTitleStr => $interwikiStr) {
+ foreach ( $pageSet->getInterwikiTitles() as $rawTitleStr => $interwikiStr ) {
$intrwValues[] = array (
'title' => $rawTitleStr,
'iw' => $interwikiStr
);
}
- if (count($intrwValues)) {
- $result->setIndexedTagName($intrwValues, 'i');
- $result->addValue('query', 'interwiki', $intrwValues);
+ if ( count( $intrwValues ) ) {
+ $result->setIndexedTagName( $intrwValues, 'i' );
+ $result->addValue( 'query', 'interwiki', $intrwValues );
}
// Show redirect information
$redirValues = array ();
- foreach ($pageSet->getRedirectTitles() as $titleStrFrom => $titleStrTo) {
+ foreach ( $pageSet->getRedirectTitles() as $titleStrFrom => $titleStrTo ) {
$redirValues[] = array (
- 'from' => strval($titleStrFrom),
+ 'from' => strval( $titleStrFrom ),
'to' => $titleStrTo
);
}
- if (count($redirValues)) {
- $result->setIndexedTagName($redirValues, 'r');
- $result->addValue('query', 'redirects', $redirValues);
+ if ( count( $redirValues ) ) {
+ $result->setIndexedTagName( $redirValues, 'r' );
+ $result->addValue( 'query', 'redirects', $redirValues );
}
//
// Missing revision elements
//
$missingRevIDs = $pageSet->getMissingRevisionIDs();
- if (count($missingRevIDs)) {
+ if ( count( $missingRevIDs ) ) {
$revids = array ();
- foreach ($missingRevIDs as $revid) {
+ foreach ( $missingRevIDs as $revid ) {
$revids[$revid] = array (
'revid' => $revid
);
}
- $result->setIndexedTagName($revids, 'rev');
- $result->addValue('query', 'badrevids', $revids);
+ $result->setIndexedTagName( $revids, 'rev' );
+ $result->addValue( 'query', 'badrevids', $revids );
}
//
@@ -370,17 +361,17 @@ class ApiQuery extends ApiBase {
$pages = array ();
// Report any missing titles
- foreach ($pageSet->getMissingTitles() as $fakeId => $title) {
+ foreach ( $pageSet->getMissingTitles() as $fakeId => $title ) {
$vals = array();
- ApiQueryBase :: addTitleInfo($vals, $title);
+ ApiQueryBase :: addTitleInfo( $vals, $title );
$vals['missing'] = '';
$pages[$fakeId] = $vals;
}
// Report any invalid titles
- foreach ($pageSet->getInvalidTitles() as $fakeId => $title)
- $pages[$fakeId] = array('title' => $title, 'invalid' => '');
+ foreach ( $pageSet->getInvalidTitles() as $fakeId => $title )
+ $pages[$fakeId] = array( 'title' => $title, 'invalid' => '' );
// Report any missing page ids
- foreach ($pageSet->getMissingPageIDs() as $pageid) {
+ foreach ( $pageSet->getMissingPageIDs() as $pageid ) {
$pages[$pageid] = array (
'pageid' => $pageid,
'missing' => ''
@@ -388,51 +379,52 @@ class ApiQuery extends ApiBase {
}
// Output general page information for found titles
- foreach ($pageSet->getGoodTitles() as $pageid => $title) {
+ foreach ( $pageSet->getGoodTitles() as $pageid => $title ) {
$vals = array();
$vals['pageid'] = $pageid;
- ApiQueryBase :: addTitleInfo($vals, $title);
+ ApiQueryBase :: addTitleInfo( $vals, $title );
$pages[$pageid] = $vals;
}
- if (count($pages)) {
+ if ( count( $pages ) ) {
- if ($this->params['indexpageids']) {
- $pageIDs = array_keys($pages);
+ if ( $this->params['indexpageids'] ) {
+ $pageIDs = array_keys( $pages );
// json treats all map keys as strings - converting to match
- $pageIDs = array_map('strval', $pageIDs);
- $result->setIndexedTagName($pageIDs, 'id');
- $result->addValue('query', 'pageids', $pageIDs);
+ $pageIDs = array_map( 'strval', $pageIDs );
+ $result->setIndexedTagName( $pageIDs, 'id' );
+ $result->addValue( 'query', 'pageids', $pageIDs );
}
- $result->setIndexedTagName($pages, 'page');
- $result->addValue('query', 'pages', $pages);
+ $result->setIndexedTagName( $pages, 'page' );
+ $result->addValue( 'query', 'pages', $pages );
}
- if ($this->params['export']) {
- $exporter = new WikiExporter($this->getDB());
+ if ( $this->params['export'] ) {
+ $exporter = new WikiExporter( $this->getDB() );
// WikiExporter writes to stdout, so catch its
// output with an ob
ob_start();
$exporter->openStream();
- foreach (@$pageSet->getGoodTitles() as $title)
- if ($title->userCanRead())
- $exporter->pageByTitle($title);
+ foreach ( @$pageSet->getGoodTitles() as $title )
+ if ( $title->userCanRead() )
+ $exporter->pageByTitle( $title );
$exporter->closeStream();
$exportxml = ob_get_contents();
ob_end_clean();
+
// Don't check the size of exported stuff
// It's not continuable, so it would cause more
// problems than it'd solve
$result->disableSizeCheck();
- if ($this->params['exportnowrap']) {
+ if ( $this->params['exportnowrap'] ) {
$result->reset();
// Raw formatter will handle this
- $result->addValue(null, 'text', $exportxml);
- $result->addValue(null, 'mime', 'text/xml');
+ $result->addValue( null, 'text', $exportxml );
+ $result->addValue( null, 'mime', 'text/xml' );
} else {
$r = array();
- ApiResult::setContent($r, $exportxml);
- $result->addValue('query', 'export', $r);
+ ApiResult::setContent( $r, $exportxml );
+ $result->addValue( 'query', 'export', $r );
}
$result->enableSizeCheck();
}
@@ -442,22 +434,23 @@ class ApiQuery extends ApiBase {
* Create a generator object of the given type and return it
*/
public function newGenerator( $generatorName ) {
+
// Find class that implements requested generator
- if (isset ($this->mQueryListModules[$generatorName])) {
+ if ( isset ( $this->mQueryListModules[$generatorName] ) ) {
$className = $this->mQueryListModules[$generatorName];
- } elseif (isset ($this->mQueryPropModules[$generatorName])) {
+ } elseif ( isset ( $this->mQueryPropModules[$generatorName] ) ) {
$className = $this->mQueryPropModules[$generatorName];
} else {
- ApiBase :: dieDebug(__METHOD__, "Unknown generator=$generatorName");
+ ApiBase :: dieDebug( __METHOD__, "Unknown generator=$generatorName" );
}
// Generator results
- $resultPageSet = new ApiPageSet($this, $this->redirects);
+ $resultPageSet = new ApiPageSet( $this, $this->redirects );
// Create and execute the generator
- $generator = new $className ($this, $generatorName);
- if (!$generator instanceof ApiQueryGeneratorBase)
- $this->dieUsage("Module $generatorName cannot be used as a generator", "badgenerator");
+ $generator = new $className ( $this, $generatorName );
+ if ( !$generator instanceof ApiQueryGeneratorBase )
+ $this->dieUsage( "Module $generatorName cannot be used as a generator", "badgenerator" );
$generator->setGeneratorMode();
return $generator;
}
@@ -473,16 +466,16 @@ class ApiQuery extends ApiBase {
$resultPageSet = new ApiPageSet( $this, $this->redirects, $this->convertTitles );
// Add any additional fields modules may need
- $generator->requestExtraData($this->mPageSet);
- $this->addCustomFldsToPageSet($modules, $resultPageSet);
+ $generator->requestExtraData( $this->mPageSet );
+ $this->addCustomFldsToPageSet( $modules, $resultPageSet );
// Populate page information with the original user input
$this->mPageSet->execute();
// populate resultPageSet with the generator output
$generator->profileIn();
- $generator->executeGenerator($resultPageSet);
- wfRunHooks('APIQueryGeneratorAfterExecute', array(&$generator, &$resultPageSet));
+ $generator->executeGenerator( $resultPageSet );
+ wfRunHooks( 'APIQueryGeneratorAfterExecute', array( &$generator, &$resultPageSet ) );
$resultPageSet->finishPageSetGeneration();
$generator->profileOut();
@@ -527,14 +520,14 @@ class ApiQuery extends ApiBase {
$this->mPageSet = null;
$this->mAllowedGenerators = array(); // Will be repopulated
- $astriks = str_repeat('--- ', 8);
- $astriks2 = str_repeat('*** ', 10);
+ $astriks = str_repeat( '--- ', 8 );
+ $astriks2 = str_repeat( '*** ', 10 );
$msg .= "\n$astriks Query: Prop $astriks\n\n";
- $msg .= $this->makeHelpMsgHelper($this->mQueryPropModules, 'prop');
+ $msg .= $this->makeHelpMsgHelper( $this->mQueryPropModules, 'prop' );
$msg .= "\n$astriks Query: List $astriks\n\n";
- $msg .= $this->makeHelpMsgHelper($this->mQueryListModules, 'list');
+ $msg .= $this->makeHelpMsgHelper( $this->mQueryListModules, 'list' );
$msg .= "\n$astriks Query: Meta $astriks\n\n";
- $msg .= $this->makeHelpMsgHelper($this->mQueryMetaModules, 'meta');
+ $msg .= $this->makeHelpMsgHelper( $this->mQueryMetaModules, 'meta' );
$msg .= "\n\n$astriks2 Modules: continuation $astriks2\n\n";
// Perform the base call last because the $this->mAllowedGenerators
@@ -551,25 +544,25 @@ class ApiQuery extends ApiBase {
* @param $paramName string Parameter name
* @return string
*/
- private function makeHelpMsgHelper($moduleList, $paramName) {
+ private function makeHelpMsgHelper( $moduleList, $paramName ) {
$moduleDescriptions = array ();
- foreach ($moduleList as $moduleName => $moduleClass) {
- $module = new $moduleClass ($this, $moduleName, null);
+ foreach ( $moduleList as $moduleName => $moduleClass ) {
+ $module = new $moduleClass ( $this, $moduleName, null );
- $msg = ApiMain::makeHelpMsgHeader($module, $paramName);
+ $msg = ApiMain::makeHelpMsgHeader( $module, $paramName );
$msg2 = $module->makeHelpMsg();
- if ($msg2 !== false)
+ if ( $msg2 !== false )
$msg .= $msg2;
- if ($module instanceof ApiQueryGeneratorBase) {
+ if ( $module instanceof ApiQueryGeneratorBase ) {
$this->mAllowedGenerators[] = $moduleName;
$msg .= "Generator:\n This module may be used as a generator\n";
}
$moduleDescriptions[] = $msg;
}
- return implode("\n", $moduleDescriptions);
+ return implode( "\n", $moduleDescriptions );
}
/**
@@ -577,7 +570,7 @@ class ApiQuery extends ApiBase {
* @return string
*/
public function makeHelpMsgParameters() {
- $psModule = new ApiPageSet($this);
+ $psModule = new ApiPageSet( $this );
return $psModule->makeHelpMsgParameters() . parent :: makeHelpMsgParameters();
}
@@ -590,8 +583,8 @@ class ApiQuery extends ApiBase {
'prop' => 'Which properties to get for the titles/revisions/pageids',
'list' => 'Which lists to get',
'meta' => 'Which meta data to get about the site',
- 'generator' => array('Use the output of a list as the input for other prop/list/meta items',
- 'NOTE: generator parameter names must be prefixed with a \'g\', see examples.'),
+ 'generator' => array( 'Use the output of a list as the input for other prop/list/meta items',
+ 'NOTE: generator parameter names must be prefixed with a \'g\', see examples.' ),
'redirects' => 'Automatically resolve redirects',
'indexpageids' => 'Include an additional pageids section listing all returned page IDs.',
'export' => 'Export the current revisions of all given or generated pages',
@@ -606,6 +599,12 @@ class ApiQuery extends ApiBase {
'All data modifications will first have to use query to acquire a token to prevent abuse from malicious sites.'
);
}
+
+ public function getPossibleErrors() {
+ return array_merge( parent::getPossibleErrors(), array(
+ array( 'code' => 'badgenerator', 'info' => 'Module $generatorName cannot be used as a generator' ),
+ ) );
+ }
protected function getExamples() {
return array (
@@ -615,9 +614,9 @@ class ApiQuery extends ApiBase {
}
public function getVersion() {
- $psModule = new ApiPageSet($this);
+ $psModule = new ApiPageSet( $this );
$vers = array ();
- $vers[] = __CLASS__ . ': $Id: ApiQuery.php 69986 2010-07-27 03:57:39Z tstarling $';
+ $vers[] = __CLASS__ . ': $Id: ApiQuery.php 69932 2010-07-26 08:03:21Z tstarling $';
$vers[] = $psModule->getVersion();
return $vers;
}
diff --git a/includes/api/ApiQueryAllCategories.php b/includes/api/ApiQueryAllCategories.php
index fca92c4b..8f24fc7c 100644
--- a/includes/api/ApiQueryAllCategories.php
+++ b/includes/api/ApiQueryAllCategories.php
@@ -23,9 +23,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ('ApiQueryBase.php');
+ require_once ( 'ApiQueryBase.php' );
}
/**
@@ -36,8 +36,8 @@ if (!defined('MEDIAWIKI')) {
*/
class ApiQueryAllCategories extends ApiQueryGeneratorBase {
- public function __construct($query, $moduleName) {
- parent :: __construct($query, $moduleName, 'ac');
+ public function __construct( $query, $moduleName ) {
+ parent :: __construct( $query, $moduleName, 'ac' );
}
public function execute() {
@@ -48,86 +48,86 @@ class ApiQueryAllCategories extends ApiQueryGeneratorBase {
return 'public';
}
- public function executeGenerator($resultPageSet) {
- $this->run($resultPageSet);
+ public function executeGenerator( $resultPageSet ) {
+ $this->run( $resultPageSet );
}
- private function run($resultPageSet = null) {
+ private function run( $resultPageSet = null ) {
$db = $this->getDB();
$params = $this->extractRequestParams();
- $this->addTables('category');
- $this->addFields('cat_title');
+ $this->addTables( 'category' );
+ $this->addFields( 'cat_title' );
- $dir = ($params['dir'] == 'descending' ? 'older' : 'newer');
- $from = (is_null($params['from']) ? null : $this->titlePartToKey($params['from']));
- $this->addWhereRange('cat_title', $dir, $from, null);
- if (isset ($params['prefix']))
- $this->addWhere("cat_title LIKE '" . $db->escapeLike($this->titlePartToKey($params['prefix'])) . "%'");
+ $dir = ( $params['dir'] == 'descending' ? 'older' : 'newer' );
+ $from = ( is_null( $params['from'] ) ? null : $this->titlePartToKey( $params['from'] ) );
+ $this->addWhereRange( 'cat_title', $dir, $from, null );
+ if ( isset ( $params['prefix'] ) )
+ $this->addWhere( 'cat_title' . $db->buildLike( $this->titlePartToKey( $params['prefix'] ), $db->anyString() ) );
- $this->addOption('LIMIT', $params['limit']+1);
- $this->addOption('ORDER BY', 'cat_title' . ($params['dir'] == 'descending' ? ' DESC' : ''));
+ $this->addOption( 'LIMIT', $params['limit'] + 1 );
+ $this->addOption( 'ORDER BY', 'cat_title' . ( $params['dir'] == 'descending' ? ' DESC' : '' ) );
- $prop = array_flip($params['prop']);
- $this->addFieldsIf( array( 'cat_pages', 'cat_subcats', 'cat_files' ), isset($prop['size']) );
- if(isset($prop['hidden']))
+ $prop = array_flip( $params['prop'] );
+ $this->addFieldsIf( array( 'cat_pages', 'cat_subcats', 'cat_files' ), isset( $prop['size'] ) );
+ if ( isset( $prop['hidden'] ) )
{
- $this->addTables(array('page', 'page_props'));
- $this->addJoinConds(array(
- 'page' => array('LEFT JOIN', array(
+ $this->addTables( array( 'page', 'page_props' ) );
+ $this->addJoinConds( array(
+ 'page' => array( 'LEFT JOIN', array(
'page_namespace' => NS_CATEGORY,
- 'page_title=cat_title')),
- 'page_props' => array('LEFT JOIN', array(
+ 'page_title=cat_title' ) ),
+ 'page_props' => array( 'LEFT JOIN', array(
'pp_page=page_id',
- 'pp_propname' => 'hiddencat')),
- ));
- $this->addFields('pp_propname AS cat_hidden');
+ 'pp_propname' => 'hiddencat' ) ),
+ ) );
+ $this->addFields( 'pp_propname AS cat_hidden' );
}
- $res = $this->select(__METHOD__);
+ $res = $this->select( __METHOD__ );
$pages = array();
$categories = array();
$result = $this->getResult();
$count = 0;
- while ($row = $db->fetchObject($res)) {
- if (++ $count > $params['limit']) {
+ while ( $row = $db->fetchObject( $res ) ) {
+ if ( ++ $count > $params['limit'] ) {
// We've reached the one extra which shows that there are additional cats to be had. Stop here...
// TODO: Security issue - if the user has no right to view next title, it will still be shown
- $this->setContinueEnumParameter('from', $this->keyToTitle($row->cat_title));
+ $this->setContinueEnumParameter( 'from', $this->keyToTitle( $row->cat_title ) );
break;
}
// Normalize titles
- $titleObj = Title::makeTitle(NS_CATEGORY, $row->cat_title);
- if(!is_null($resultPageSet))
+ $titleObj = Title::makeTitle( NS_CATEGORY, $row->cat_title );
+ if ( !is_null( $resultPageSet ) )
$pages[] = $titleObj->getPrefixedText();
else {
$item = array();
$result->setContent( $item, $titleObj->getText() );
- if( isset( $prop['size'] ) ) {
- $item['size'] = intval($row->cat_pages);
+ if ( isset( $prop['size'] ) ) {
+ $item['size'] = intval( $row->cat_pages );
$item['pages'] = $row->cat_pages - $row->cat_subcats - $row->cat_files;
- $item['files'] = intval($row->cat_files);
- $item['subcats'] = intval($row->cat_subcats);
+ $item['files'] = intval( $row->cat_files );
+ $item['subcats'] = intval( $row->cat_subcats );
}
- if( isset( $prop['hidden'] ) && $row->cat_hidden )
+ if ( isset( $prop['hidden'] ) && $row->cat_hidden )
$item['hidden'] = '';
- $fit = $result->addValue(array('query', $this->getModuleName()), null, $item);
- if(!$fit)
+ $fit = $result->addValue( array( 'query', $this->getModuleName() ), null, $item );
+ if ( !$fit )
{
- $this->setContinueEnumParameter('from', $this->keyToTitle($row->cat_title));
+ $this->setContinueEnumParameter( 'from', $this->keyToTitle( $row->cat_title ) );
break;
}
}
}
- $db->freeResult($res);
+ $db->freeResult( $res );
- if (is_null($resultPageSet)) {
- $result->setIndexedTagName_internal(array('query', $this->getModuleName()), 'c');
+ if ( is_null( $resultPageSet ) ) {
+ $result->setIndexedTagName_internal( array( 'query', $this->getModuleName() ), 'c' );
} else {
- $resultPageSet->populateFromTitles($pages);
+ $resultPageSet->populateFromTitles( $pages );
}
}
@@ -179,6 +179,6 @@ class ApiQueryAllCategories extends ApiQueryGeneratorBase {
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiQueryAllCategories.php 69986 2010-07-27 03:57:39Z tstarling $';
+ return __CLASS__ . ': $Id: ApiQueryAllCategories.php 69932 2010-07-26 08:03:21Z tstarling $';
}
}
diff --git a/includes/api/ApiQueryAllLinks.php b/includes/api/ApiQueryAllLinks.php
index 73788aa6..6b6fc2c0 100644
--- a/includes/api/ApiQueryAllLinks.php
+++ b/includes/api/ApiQueryAllLinks.php
@@ -23,9 +23,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ('ApiQueryBase.php');
+ require_once ( 'ApiQueryBase.php' );
}
/**
@@ -35,8 +35,8 @@ if (!defined('MEDIAWIKI')) {
*/
class ApiQueryAllLinks extends ApiQueryGeneratorBase {
- public function __construct($query, $moduleName) {
- parent :: __construct($query, $moduleName, 'al');
+ public function __construct( $query, $moduleName ) {
+ parent :: __construct( $query, $moduleName, 'al' );
}
public function execute() {
@@ -47,105 +47,105 @@ class ApiQueryAllLinks extends ApiQueryGeneratorBase {
return 'public';
}
- public function executeGenerator($resultPageSet) {
- $this->run($resultPageSet);
+ public function executeGenerator( $resultPageSet ) {
+ $this->run( $resultPageSet );
}
- private function run($resultPageSet = null) {
+ private function run( $resultPageSet = null ) {
$db = $this->getDB();
$params = $this->extractRequestParams();
- $prop = array_flip($params['prop']);
- $fld_ids = isset($prop['ids']);
- $fld_title = isset($prop['title']);
+ $prop = array_flip( $params['prop'] );
+ $fld_ids = isset( $prop['ids'] );
+ $fld_title = isset( $prop['title'] );
- if ($params['unique']) {
- if (!is_null($resultPageSet))
- $this->dieUsage($this->getModuleName() . ' cannot be used as a generator in unique links mode', 'params');
- if ($fld_ids)
- $this->dieUsage($this->getModuleName() . ' cannot return corresponding page ids in unique links mode', 'params');
- $this->addOption('DISTINCT');
+ if ( $params['unique'] ) {
+ if ( !is_null( $resultPageSet ) )
+ $this->dieUsage( $this->getModuleName() . ' cannot be used as a generator in unique links mode', 'params' );
+ if ( $fld_ids )
+ $this->dieUsage( $this->getModuleName() . ' cannot return corresponding page ids in unique links mode', 'params' );
+ $this->addOption( 'DISTINCT' );
}
- $this->addTables('pagelinks');
- $this->addWhereFld('pl_namespace', $params['namespace']);
+ $this->addTables( 'pagelinks' );
+ $this->addWhereFld( 'pl_namespace', $params['namespace'] );
- if (!is_null($params['from']) && !is_null($params['continue']))
- $this->dieUsage('alcontinue and alfrom cannot be used together', 'params');
- if (!is_null($params['continue']))
+ if ( !is_null( $params['from'] ) && !is_null( $params['continue'] ) )
+ $this->dieUsage( 'alcontinue and alfrom cannot be used together', 'params' );
+ if ( !is_null( $params['continue'] ) )
{
- $arr = explode('|', $params['continue']);
- if(count($arr) != 2)
- $this->dieUsage("Invalid continue parameter", 'badcontinue');
- $from = $this->getDB()->strencode($this->titleToKey($arr[0]));
- $id = intval($arr[1]);
- $this->addWhere("pl_title > '$from' OR " .
+ $arr = explode( '|', $params['continue'] );
+ if ( count( $arr ) != 2 )
+ $this->dieUsage( "Invalid continue parameter", 'badcontinue' );
+ $from = $this->getDB()->strencode( $this->titleToKey( $arr[0] ) );
+ $id = intval( $arr[1] );
+ $this->addWhere( "pl_title > '$from' OR " .
"(pl_title = '$from' AND " .
- "pl_from > $id)");
- }
+ "pl_from > $id)" );
+ }
- if (!is_null($params['from']))
- $this->addWhere('pl_title>=' . $db->addQuotes($this->titlePartToKey($params['from'])));
- if (isset ($params['prefix']))
- $this->addWhere("pl_title LIKE '" . $db->escapeLike($this->titlePartToKey($params['prefix'])) . "%'");
+ if ( !is_null( $params['from'] ) )
+ $this->addWhere( 'pl_title>=' . $db->addQuotes( $this->titlePartToKey( $params['from'] ) ) );
+ if ( isset ( $params['prefix'] ) )
+ $this->addWhere( 'pl_title' . $db->buildLike( $this->titlePartToKey( $params['prefix'] ), $db->anyString() ) );
- $this->addFields(array (
+ $this->addFields( array (
'pl_title',
- ));
- $this->addFieldsIf('pl_from', !$params['unique']);
+ ) );
+ $this->addFieldsIf( 'pl_from', !$params['unique'] );
- $this->addOption('USE INDEX', 'pl_namespace');
+ $this->addOption( 'USE INDEX', 'pl_namespace' );
$limit = $params['limit'];
- $this->addOption('LIMIT', $limit+1);
- if($params['unique'])
- $this->addOption('ORDER BY', 'pl_title');
+ $this->addOption( 'LIMIT', $limit + 1 );
+ if ( $params['unique'] )
+ $this->addOption( 'ORDER BY', 'pl_title' );
else
- $this->addOption('ORDER BY', 'pl_title, pl_from');
+ $this->addOption( 'ORDER BY', 'pl_title, pl_from' );
- $res = $this->select(__METHOD__);
+ $res = $this->select( __METHOD__ );
$pageids = array ();
$count = 0;
$result = $this->getResult();
- while ($row = $db->fetchObject($res)) {
- if (++ $count > $limit) {
+ while ( $row = $db->fetchObject( $res ) ) {
+ if ( ++ $count > $limit ) {
// We've reached the one extra which shows that there are additional pages to be had. Stop here...
// TODO: Security issue - if the user has no right to view next title, it will still be shown
- if($params['unique'])
- $this->setContinueEnumParameter('from', $this->keyToTitle($row->pl_title));
+ if ( $params['unique'] )
+ $this->setContinueEnumParameter( 'from', $this->keyToTitle( $row->pl_title ) );
else
- $this->setContinueEnumParameter('continue', $this->keyToTitle($row->pl_title) . "|" . $row->pl_from);
+ $this->setContinueEnumParameter( 'continue', $this->keyToTitle( $row->pl_title ) . "|" . $row->pl_from );
break;
}
- if (is_null($resultPageSet)) {
+ if ( is_null( $resultPageSet ) ) {
$vals = array();
- if ($fld_ids)
- $vals['fromid'] = intval($row->pl_from);
- if ($fld_title) {
- $title = Title :: makeTitle($params['namespace'], $row->pl_title);
- ApiQueryBase::addTitleInfo($vals, $title);
+ if ( $fld_ids )
+ $vals['fromid'] = intval( $row->pl_from );
+ if ( $fld_title ) {
+ $title = Title :: makeTitle( $params['namespace'], $row->pl_title );
+ ApiQueryBase::addTitleInfo( $vals, $title );
}
- $fit = $result->addValue(array('query', $this->getModuleName()), null, $vals);
- if(!$fit)
+ $fit = $result->addValue( array( 'query', $this->getModuleName() ), null, $vals );
+ if ( !$fit )
{
- if($params['unique'])
- $this->setContinueEnumParameter('from', $this->keyToTitle($row->pl_title));
+ if ( $params['unique'] )
+ $this->setContinueEnumParameter( 'from', $this->keyToTitle( $row->pl_title ) );
else
- $this->setContinueEnumParameter('continue', $this->keyToTitle($row->pl_title) . "|" . $row->pl_from);
+ $this->setContinueEnumParameter( 'continue', $this->keyToTitle( $row->pl_title ) . "|" . $row->pl_from );
break;
}
} else {
$pageids[] = $row->pl_from;
}
}
- $db->freeResult($res);
+ $db->freeResult( $res );
- if (is_null($resultPageSet)) {
- $result->setIndexedTagName_internal(array('query', $this->getModuleName()), 'l');
+ if ( is_null( $resultPageSet ) ) {
+ $result->setIndexedTagName_internal( array( 'query', $this->getModuleName() ), 'l' );
} else {
- $resultPageSet->populateFromPageIDs($pageids);
+ $resultPageSet->populateFromPageIDs( $pageids );
}
}
@@ -192,6 +192,15 @@ class ApiQueryAllLinks extends ApiQueryGeneratorBase {
public function getDescription() {
return 'Enumerate all links that point to a given namespace';
}
+
+ public function getPossibleErrors() {
+ return array_merge( parent::getPossibleErrors(), array(
+ array( 'code' => 'params', 'info' => $this->getModuleName() . ' cannot be used as a generator in unique links mode' ),
+ array( 'code' => 'params', 'info' => $this->getModuleName() . ' cannot return corresponding page ids in unique links mode' ),
+ array( 'code' => 'params', 'info' => 'alcontinue and alfrom cannot be used together' ),
+ array( 'code' => 'badcontinue', 'info' => 'Invalid continue parameter' ),
+ ) );
+ }
protected function getExamples() {
return array (
@@ -200,6 +209,6 @@ class ApiQueryAllLinks extends ApiQueryGeneratorBase {
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiQueryAllLinks.php 69986 2010-07-27 03:57:39Z tstarling $';
+ return __CLASS__ . ': $Id: ApiQueryAllLinks.php 69932 2010-07-26 08:03:21Z tstarling $';
}
}
diff --git a/includes/api/ApiQueryAllUsers.php b/includes/api/ApiQueryAllUsers.php
index c18f6dd1..f8d475cc 100644
--- a/includes/api/ApiQueryAllUsers.php
+++ b/includes/api/ApiQueryAllUsers.php
@@ -23,9 +23,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ('ApiQueryBase.php');
+ require_once ( 'ApiQueryBase.php' );
}
/**
@@ -35,8 +35,8 @@ if (!defined('MEDIAWIKI')) {
*/
class ApiQueryAllUsers extends ApiQueryBase {
- public function __construct($query, $moduleName) {
- parent :: __construct($query, $moduleName, 'au');
+ public function __construct( $query, $moduleName ) {
+ parent :: __construct( $query, $moduleName, 'au' );
}
public function execute() {
@@ -44,67 +44,74 @@ class ApiQueryAllUsers extends ApiQueryBase {
$params = $this->extractRequestParams();
$prop = $params['prop'];
- if (!is_null($prop)) {
- $prop = array_flip($prop);
- $fld_blockinfo = isset($prop['blockinfo']);
- $fld_editcount = isset($prop['editcount']);
- $fld_groups = isset($prop['groups']);
- $fld_registration = isset($prop['registration']);
- } else {
+ if ( !is_null( $prop ) ) {
+ $prop = array_flip( $prop );
+ $fld_blockinfo = isset( $prop['blockinfo'] );
+ $fld_editcount = isset( $prop['editcount'] );
+ $fld_groups = isset( $prop['groups'] );
+ $fld_registration = isset( $prop['registration'] );
+ } else {
$fld_blockinfo = $fld_editcount = $fld_groups = $fld_registration = false;
}
$limit = $params['limit'];
- $this->addTables('user', 'u1');
+ $this->addTables( 'user', 'u1' );
+ $useIndex = true;
- if (!is_null($params['from']))
- $this->addWhere('u1.user_name >= ' . $db->addQuotes($this->keyToTitle($params['from'])));
+ if ( !is_null( $params['from'] ) )
+ $this->addWhere( 'u1.user_name >= ' . $db->addQuotes( $this->keyToTitle( $params['from'] ) ) );
- if (!is_null($params['prefix']))
- $this->addWhere('u1.user_name LIKE "' . $db->escapeLike($this->keyToTitle( $params['prefix'])) . '%"');
+ if ( !is_null( $params['prefix'] ) )
+ $this->addWhere( 'u1.user_name' . $db->buildLike( $this->keyToTitle( $params['prefix'] ), $db->anyString() ) );
- if (!is_null($params['group'])) {
+ if ( !is_null( $params['group'] ) ) {
+ $useIndex = false;
// Filter only users that belong to a given group
- $this->addTables('user_groups', 'ug1');
- $this->addWhere('ug1.ug_user=u1.user_id');
- $this->addWhereFld('ug1.ug_group', $params['group']);
+ $this->addTables( 'user_groups', 'ug1' );
+ $ug1 = $this->getAliasedName( 'user_groups', 'ug1' );
+ $this->addJoinConds( array( $ug1 => array( 'INNER JOIN', array( 'ug1.ug_user=u1.user_id',
+ 'ug1.ug_group' => $params['group'] ) ) ) );
}
- if ($params['witheditsonly'])
- $this->addWhere('u1.user_editcount > 0');
+ if ( $params['witheditsonly'] )
+ $this->addWhere( 'u1.user_editcount > 0' );
- if ($fld_groups) {
+ if ( $fld_groups ) {
// Show the groups the given users belong to
// request more than needed to avoid not getting all rows that belong to one user
- $groupCount = count(User::getAllGroups());
- $sqlLimit = $limit+$groupCount+1;
+ $groupCount = count( User::getAllGroups() );
+ $sqlLimit = $limit + $groupCount + 1;
- $this->addTables('user_groups', 'ug2');
- $tname = $this->getAliasedName('user_groups', 'ug2');
- $this->addJoinConds(array($tname => array('LEFT JOIN', 'ug2.ug_user=u1.user_id')));
- $this->addFields('ug2.ug_group ug_group2');
+ $this->addTables( 'user_groups', 'ug2' );
+ $tname = $this->getAliasedName( 'user_groups', 'ug2' );
+ $this->addJoinConds( array( $tname => array( 'LEFT JOIN', 'ug2.ug_user=u1.user_id' ) ) );
+ $this->addFields( 'ug2.ug_group ug_group2' );
} else {
- $sqlLimit = $limit+1;
+ $sqlLimit = $limit + 1;
}
- if ($fld_blockinfo) {
- $this->addTables('ipblocks');
- $this->addTables('user', 'u2');
- $u2 = $this->getAliasedName('user', 'u2');
- $this->addJoinConds(array(
- 'ipblocks' => array('LEFT JOIN', 'ipb_user=u1.user_id'),
- $u2 => array('LEFT JOIN', 'ipb_by=u2.user_id')));
- $this->addFields(array('ipb_reason', 'u2.user_name blocker_name'));
+ if ( $fld_blockinfo ) {
+ $this->addTables( 'ipblocks' );
+ $this->addTables( 'user', 'u2' );
+ $u2 = $this->getAliasedName( 'user', 'u2' );
+ $this->addJoinConds( array(
+ 'ipblocks' => array( 'LEFT JOIN', 'ipb_user=u1.user_id' ),
+ $u2 => array( 'LEFT JOIN', 'ipb_by=u2.user_id' ) ) );
+ $this->addFields( array( 'ipb_reason', 'u2.user_name AS blocker_name' ) );
}
- $this->addOption('LIMIT', $sqlLimit);
+ $this->addOption( 'LIMIT', $sqlLimit );
- $this->addFields('u1.user_name');
- $this->addFieldsIf('u1.user_editcount', $fld_editcount);
- $this->addFieldsIf('u1.user_registration', $fld_registration);
+ $this->addFields( 'u1.user_name' );
+ $this->addFieldsIf( 'u1.user_editcount', $fld_editcount );
+ $this->addFieldsIf( 'u1.user_registration', $fld_registration );
- $this->addOption('ORDER BY', 'u1.user_name');
+ $this->addOption( 'ORDER BY', 'u1.user_name' );
+ if ( $useIndex ) {
+ $u1 = $this->getAliasedName( 'user', 'u1' );
+ $this->addOption( 'USE INDEX', array( $u1 => 'user_name' ) );
+ }
- $res = $this->select(__METHOD__);
+ $res = $this->select( __METHOD__ );
$data = array ();
$count = 0;
@@ -119,66 +126,67 @@ class ApiQueryAllUsers extends ApiQueryBase {
// The setContinue... is more complex because of this, and takes into account the higher sql limit
// to make sure all rows that belong to the same user are received.
//
- while (true) {
+ while ( true ) {
- $row = $db->fetchObject($res);
+ $row = $db->fetchObject( $res );
$count++;
- if (!$row || $lastUser !== $row->user_name) {
+ if ( !$row || $lastUser !== $row->user_name ) {
// Save the last pass's user data
- if (is_array($lastUserData))
+ if ( is_array( $lastUserData ) )
{
- $fit = $result->addValue(array('query', $this->getModuleName()),
- null, $lastUserData);
- if(!$fit)
+ $fit = $result->addValue( array( 'query', $this->getModuleName() ),
+ null, $lastUserData );
+ if ( !$fit )
{
- $this->setContinueEnumParameter('from',
- $this->keyToTitle($lastUserData['name']));
+ $this->setContinueEnumParameter( 'from',
+ $this->keyToTitle( $lastUserData['name'] ) );
break;
}
}
// No more rows left
- if (!$row)
+ if ( !$row )
break;
- if ($count > $limit) {
+ if ( $count > $limit ) {
// We've reached the one extra which shows that there are additional pages to be had. Stop here...
- $this->setContinueEnumParameter('from', $this->keyToTitle($row->user_name));
+ $this->setContinueEnumParameter( 'from', $this->keyToTitle( $row->user_name ) );
break;
}
// Record new user's data
$lastUser = $row->user_name;
$lastUserData = array( 'name' => $lastUser );
- if ($fld_blockinfo) {
+ if ( $fld_blockinfo ) {
$lastUserData['blockedby'] = $row->blocker_name;
$lastUserData['blockreason'] = $row->ipb_reason;
}
- if ($fld_editcount)
- $lastUserData['editcount'] = intval($row->user_editcount);
- if ($fld_registration)
- $lastUserData['registration'] = wfTimestamp(TS_ISO_8601, $row->user_registration);
+ if ( $fld_editcount )
+ $lastUserData['editcount'] = intval( $row->user_editcount );
+ if ( $fld_registration )
+ $lastUserData['registration'] = $row->user_registration ?
+ wfTimestamp( TS_ISO_8601, $row->user_registration ) : '';
}
- if ($sqlLimit == $count) {
+ if ( $sqlLimit == $count ) {
// BUG! database contains group name that User::getAllGroups() does not return
// TODO: should handle this more gracefully
- ApiBase :: dieDebug(__METHOD__,
- 'MediaWiki configuration error: the database contains more user groups than known to User::getAllGroups() function');
+ ApiBase :: dieDebug( __METHOD__,
+ 'MediaWiki configuration error: the database contains more user groups than known to User::getAllGroups() function' );
}
// Add user's group info
- if ($fld_groups && !is_null($row->ug_group2)) {
+ if ( $fld_groups && !is_null( $row->ug_group2 ) ) {
$lastUserData['groups'][] = $row->ug_group2;
- $result->setIndexedTagName($lastUserData['groups'], 'g');
+ $result->setIndexedTagName( $lastUserData['groups'], 'g' );
}
}
- $db->freeResult($res);
+ $db->freeResult( $res );
- $result->setIndexedTagName_internal(array('query', $this->getModuleName()), 'u');
+ $result->setIndexedTagName_internal( array( 'query', $this->getModuleName() ), 'u' );
}
public function getCacheMode( $params ) {
@@ -219,7 +227,7 @@ class ApiQueryAllUsers extends ApiQueryBase {
'group' => 'Limit users to a given group name',
'prop' => array(
'What pieces of information to include.',
- '`groups` property uses more server resources and may return fewer results than the limit.'),
+ '`groups` property uses more server resources and may return fewer results than the limit.' ),
'limit' => 'How many total user names to return.',
'witheditsonly' => 'Only list users who have made edits',
);
@@ -236,6 +244,6 @@ class ApiQueryAllUsers extends ApiQueryBase {
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiQueryAllUsers.php 69986 2010-07-27 03:57:39Z tstarling $';
+ return __CLASS__ . ': $Id: ApiQueryAllUsers.php 69932 2010-07-26 08:03:21Z tstarling $';
}
}
diff --git a/includes/api/ApiQueryAllimages.php b/includes/api/ApiQueryAllimages.php
index 983c6469..0a745516 100644
--- a/includes/api/ApiQueryAllimages.php
+++ b/includes/api/ApiQueryAllimages.php
@@ -24,9 +24,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ('ApiQueryBase.php');
+ require_once ( 'ApiQueryBase.php' );
}
/**
@@ -36,8 +36,19 @@ if (!defined('MEDIAWIKI')) {
*/
class ApiQueryAllimages extends ApiQueryGeneratorBase {
- public function __construct($query, $moduleName) {
- parent :: __construct($query, $moduleName, 'ai');
+ public function __construct( $query, $moduleName ) {
+ parent :: __construct( $query, $moduleName, 'ai' );
+ $this->mRepo = RepoGroup::singleton()->getLocalRepo();
+ }
+
+ /**
+ * Overide parent method to make sure to make sure the repo's DB is used
+ * which may not necesarilly be the same as the local DB.
+ *
+ * TODO: allow querying non-local repos.
+ */
+ protected function getDB() {
+ return $this->mRepo->getSlaveDB();
}
public function execute() {
@@ -48,89 +59,89 @@ class ApiQueryAllimages extends ApiQueryGeneratorBase {
return 'public';
}
- public function executeGenerator($resultPageSet) {
- if ($resultPageSet->isResolvingRedirects())
- $this->dieUsage('Use "gaifilterredir=nonredirects" option instead of "redirects" when using allimages as a generator', 'params');
+ public function executeGenerator( $resultPageSet ) {
+ if ( $resultPageSet->isResolvingRedirects() )
+ $this->dieUsage( 'Use "gaifilterredir=nonredirects" option instead of "redirects" when using allimages as a generator', 'params' );
- $this->run($resultPageSet);
+ $this->run( $resultPageSet );
}
- private function run($resultPageSet = null) {
- $repo = RepoGroup::singleton()->getLocalRepo();
+ private function run( $resultPageSet = null ) {
+ $repo = $this->mRepo;
if ( !$repo instanceof LocalRepo )
- $this->dieUsage('Local file repository does not support querying all images', 'unsupportedrepo');
+ $this->dieUsage( 'Local file repository does not support querying all images', 'unsupportedrepo' );
$db = $this->getDB();
$params = $this->extractRequestParams();
// Image filters
- $dir = ($params['dir'] == 'descending' ? 'older' : 'newer');
- $from = (is_null($params['from']) ? null : $this->titlePartToKey($params['from']));
- $this->addWhereRange('img_name', $dir, $from, null);
- if (isset ($params['prefix']))
- $this->addWhere("img_name LIKE '" . $db->escapeLike($this->titlePartToKey($params['prefix'])) . "%'");
-
- if (isset ($params['minsize'])) {
- $this->addWhere('img_size>=' . intval($params['minsize']));
+ $dir = ( $params['dir'] == 'descending' ? 'older' : 'newer' );
+ $from = ( is_null( $params['from'] ) ? null : $this->titlePartToKey( $params['from'] ) );
+ $this->addWhereRange( 'img_name', $dir, $from, null );
+ if ( isset ( $params['prefix'] ) )
+ $this->addWhere( 'img_name' . $db->buildLike( $this->titlePartToKey( $params['prefix'] ), $db->anyString() ) );
+
+ if ( isset ( $params['minsize'] ) ) {
+ $this->addWhere( 'img_size>=' . intval( $params['minsize'] ) );
}
- if (isset ($params['maxsize'])) {
- $this->addWhere('img_size<=' . intval($params['maxsize']));
+ if ( isset ( $params['maxsize'] ) ) {
+ $this->addWhere( 'img_size<=' . intval( $params['maxsize'] ) );
}
$sha1 = false;
- if( isset( $params['sha1'] ) ) {
+ if ( isset( $params['sha1'] ) ) {
$sha1 = wfBaseConvert( $params['sha1'], 16, 36, 31 );
- } elseif( isset( $params['sha1base36'] ) ) {
+ } elseif ( isset( $params['sha1base36'] ) ) {
$sha1 = $params['sha1base36'];
}
- if( $sha1 ) {
+ if ( $sha1 ) {
$this->addWhere( 'img_sha1=' . $db->addQuotes( $sha1 ) );
}
- $this->addTables('image');
+ $this->addTables( 'image' );
- $prop = array_flip($params['prop']);
+ $prop = array_flip( $params['prop'] );
$this->addFields( LocalFile::selectFields() );
$limit = $params['limit'];
- $this->addOption('LIMIT', $limit+1);
- $this->addOption('ORDER BY', 'img_name' .
- ($params['dir'] == 'descending' ? ' DESC' : ''));
+ $this->addOption( 'LIMIT', $limit + 1 );
+ $this->addOption( 'ORDER BY', 'img_name' .
+ ( $params['dir'] == 'descending' ? ' DESC' : '' ) );
- $res = $this->select(__METHOD__);
+ $res = $this->select( __METHOD__ );
$titles = array();
$count = 0;
$result = $this->getResult();
- while ($row = $db->fetchObject($res)) {
- if (++ $count > $limit) {
+ while ( $row = $db->fetchObject( $res ) ) {
+ if ( ++ $count > $limit ) {
// We've reached the one extra which shows that there are additional pages to be had. Stop here...
// TODO: Security issue - if the user has no right to view next title, it will still be shown
- $this->setContinueEnumParameter('from', $this->keyToTitle($row->img_name));
+ $this->setContinueEnumParameter( 'from', $this->keyToTitle( $row->img_name ) );
break;
}
- if (is_null($resultPageSet)) {
+ if ( is_null( $resultPageSet ) ) {
$file = $repo->newFileFromRow( $row );
- $info = array_merge(array('name' => $row->img_name),
- ApiQueryImageInfo::getInfo($file, $prop, $result));
- $fit = $result->addValue(array('query', $this->getModuleName()), null, $info);
- if( !$fit ) {
- $this->setContinueEnumParameter('from', $this->keyToTitle($row->img_name));
+ $info = array_merge( array( 'name' => $row->img_name ),
+ ApiQueryImageInfo::getInfo( $file, $prop, $result ) );
+ $fit = $result->addValue( array( 'query', $this->getModuleName() ), null, $info );
+ if ( !$fit ) {
+ $this->setContinueEnumParameter( 'from', $this->keyToTitle( $row->img_name ) );
break;
}
} else {
- $titles[] = Title::makeTitle(NS_IMAGE, $row->img_name);
+ $titles[] = Title::makeTitle( NS_IMAGE, $row->img_name );
}
}
- $db->freeResult($res);
+ $db->freeResult( $res );
- if (is_null($resultPageSet)) {
- $result->setIndexedTagName_internal(array('query', $this->getModuleName()), 'img');
+ if ( is_null( $resultPageSet ) ) {
+ $result->setIndexedTagName_internal( array( 'query', $this->getModuleName() ), 'img' );
} else {
- $resultPageSet->populateFromTitles($titles);
+ $resultPageSet->populateFromTitles( $titles );
}
}
@@ -161,18 +172,7 @@ class ApiQueryAllimages extends ApiQueryGeneratorBase {
'sha1' => null,
'sha1base36' => null,
'prop' => array (
- ApiBase :: PARAM_TYPE => array(
- 'timestamp',
- 'user',
- 'comment',
- 'url',
- 'size',
- 'dimensions', // Obsolete
- 'mime',
- 'sha1',
- 'metadata',
- 'bitdepth',
- ),
+ ApiBase :: PARAM_TYPE => ApiQueryImageInfo::getPropertyNames(),
ApiBase :: PARAM_DFLT => 'timestamp|url',
ApiBase :: PARAM_ISMULTI => true
)
@@ -196,6 +196,13 @@ class ApiQueryAllimages extends ApiQueryGeneratorBase {
public function getDescription() {
return 'Enumerate all images sequentially';
}
+
+ public function getPossibleErrors() {
+ return array_merge( parent::getPossibleErrors(), array(
+ array( 'code' => 'params', 'info' => 'Use "gaifilterredir=nonredirects" option instead of "redirects" when using allimages as a generator' ),
+ array( 'code' => 'unsupportedrepo', 'info' => 'Local file repository does not support querying all images' ),
+ ) );
+ }
protected function getExamples() {
return array (
@@ -209,6 +216,6 @@ class ApiQueryAllimages extends ApiQueryGeneratorBase {
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiQueryAllimages.php 69986 2010-07-27 03:57:39Z tstarling $';
+ return __CLASS__ . ': $Id: ApiQueryAllimages.php 69932 2010-07-26 08:03:21Z tstarling $';
}
}
diff --git a/includes/api/ApiQueryAllmessages.php b/includes/api/ApiQueryAllmessages.php
index c615daf4..7dd9d874 100644
--- a/includes/api/ApiQueryAllmessages.php
+++ b/includes/api/ApiQueryAllmessages.php
@@ -23,9 +23,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ('ApiQueryBase.php');
+ require_once ( 'ApiQueryBase.php' );
}
/**
@@ -35,79 +35,98 @@ if (!defined('MEDIAWIKI')) {
*/
class ApiQueryAllmessages extends ApiQueryBase {
- public function __construct($query, $moduleName) {
- parent :: __construct($query, $moduleName, 'am');
+ public function __construct( $query, $moduleName ) {
+ parent :: __construct( $query, $moduleName, 'am' );
}
public function execute() {
- global $wgMessageCache;
$params = $this->extractRequestParams();
- if(!is_null($params['lang']))
+ if ( !is_null( $params['lang'] ) )
{
global $wgLang;
- $wgLang = Language::factory($params['lang']);
+ $wgLang = Language::factory( $params['lang'] );
}
+
+ $prop = array_flip( (array)$params['prop'] );
-
- //Determine which messages should we print
+ // Determine which messages should we print
$messages_target = array();
- if( $params['messages'] == '*' ) {
- $wgMessageCache->loadAllMessages();
- $message_names = array_keys( array_merge( Language::getMessagesFor( 'en' ), $wgMessageCache->getExtensionMessagesFor( 'en' ) ) );
+ if ( in_array( '*', $params['messages'] ) ) {
+ $message_names = array_keys( Language::getMessagesFor( 'en' ) );
sort( $message_names );
$messages_target = $message_names;
} else {
- $messages_target = explode( '|', $params['messages'] );
+ $messages_target = $params['messages'];
}
- //Filter messages
- if( isset( $params['filter'] ) ) {
+ // Filter messages
+ if ( isset( $params['filter'] ) ) {
$messages_filtered = array();
- foreach( $messages_target as $message ) {
- if( strpos( $message, $params['filter'] ) !== false ) { //!== is used because filter can be at the beginnig of the string
+ foreach ( $messages_target as $message ) {
+ if ( strpos( $message, $params['filter'] ) !== false ) { // !== is used because filter can be at the beginnig of the string
$messages_filtered[] = $message;
}
}
$messages_target = $messages_filtered;
}
- //Get all requested messages
+ // Get all requested messages and print the result
$messages = array();
- $skip = !is_null($params['from']);
- foreach( $messages_target as $message ) {
+ $skip = !is_null( $params['from'] );
+ $result = $this->getResult();
+ foreach ( $messages_target as $message ) {
// Skip all messages up to $params['from']
- if($skip && $message === $params['from'])
+ if ( $skip && $message === $params['from'] )
$skip = false;
- if(!$skip)
- $messages[$message] = wfMsg( $message );
- }
- //Print the result
- $result = $this->getResult();
- $messages_out = array();
- foreach( $messages as $name => $value ) {
- $message = array();
- $message['name'] = $name;
- if( wfEmptyMsg( $name, $value ) ) {
- $message['missing'] = '';
- } else {
- $result->setContent( $message, $value );
- }
- $fit = $result->addValue(array('query', $this->getModuleName()), null, $message);
- if(!$fit)
- {
- $this->setContinueEnumParameter('from', $name);
- break;
+ if ( !$skip ) {
+ $a = array( 'name' => $message );
+ $args = null;
+ if ( isset( $params['args'] ) && count( $params['args'] ) != 0 ) {
+ $args = $params['args'];
+ }
+ // Check if the parser is enabled:
+ if ( $params['enableparser'] ) {
+ $msg = wfMsgExt( $message, array( 'parsemag' ), $args );
+ } else if ( $args ) {
+ $msgString = wfMsgGetKey( $message, true, false, false );
+ $msg = wfMsgReplaceArgs( $msgString, $args );
+ } else {
+ $msg = wfMsgGetKey( $message, true, false, false );
+ }
+
+ if ( wfEmptyMsg( $message, $msg ) )
+ $a['missing'] = '';
+ else {
+ ApiResult::setContent( $a, $msg );
+ if ( isset( $prop['default'] ) ) {
+ $default = wfMsgGetKey( $message, false, false, false );
+ if ( $default !== $msg ) {
+ if ( wfEmptyMsg( $message, $default ) )
+ $a['defaultmissing'] = '';
+ else
+ $a['default'] = $default;
+ }
+ }
+ }
+ $fit = $result->addValue( array( 'query', $this->getModuleName() ), null, $a );
+ if ( !$fit ) {
+ $this->setContinueEnumParameter( 'from', $name );
+ break;
+ }
}
}
- $result->setIndexedTagName_internal(array('query', $this->getModuleName()), 'message');
+ $result->setIndexedTagName_internal( array( 'query', $this->getModuleName() ), 'message' );
}
public function getCacheMode( $params ) {
if ( is_null( $params['lang'] ) ) {
// Language not specified, will be fetched from preferences
return 'anon-public-user-private';
+ } elseif ( $params['enableparser'] ) {
+ // User-specific parser options will be used
+ return 'anon-public-user-private';
} else {
// OK to cache
return 'public';
@@ -118,6 +137,17 @@ class ApiQueryAllmessages extends ApiQueryBase {
return array (
'messages' => array (
ApiBase :: PARAM_DFLT => '*',
+ ApiBase :: PARAM_ISMULTI => true,
+ ),
+ 'prop' => array(
+ ApiBase :: PARAM_ISMULTI => true,
+ ApiBase :: PARAM_TYPE => array(
+ 'default'
+ )
+ ),
+ 'enableparser' => false,
+ 'args' => array(
+ ApiBase :: PARAM_ISMULTI => true
),
'filter' => array(),
'lang' => null,
@@ -128,6 +158,10 @@ class ApiQueryAllmessages extends ApiQueryBase {
public function getParamDescription() {
return array (
'messages' => 'Which messages to output. "*" means all messages',
+ 'prop' => 'Which properties to get',
+ 'enableparser' => array( 'Set to enable parser, will preprocess the wikitext of message',
+ 'Will substitute magic words, handle templates etc.' ),
+ 'args' => 'Arguments to be substituted into message',
'filter' => 'Return only messages that contain this string',
'lang' => 'Return messages in this language',
'from' => 'Return messages starting at this message',
@@ -146,6 +180,6 @@ class ApiQueryAllmessages extends ApiQueryBase {
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiQueryAllmessages.php 69986 2010-07-27 03:57:39Z tstarling $';
+ return __CLASS__ . ': $Id: ApiQueryAllmessages.php 69932 2010-07-26 08:03:21Z tstarling $';
}
}
diff --git a/includes/api/ApiQueryAllpages.php b/includes/api/ApiQueryAllpages.php
index e123e8fe..37f22ee2 100644
--- a/includes/api/ApiQueryAllpages.php
+++ b/includes/api/ApiQueryAllpages.php
@@ -23,9 +23,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ('ApiQueryBase.php');
+ require_once ( 'ApiQueryBase.php' );
}
/**
@@ -35,8 +35,8 @@ if (!defined('MEDIAWIKI')) {
*/
class ApiQueryAllpages extends ApiQueryGeneratorBase {
- public function __construct($query, $moduleName) {
- parent :: __construct($query, $moduleName, 'ap');
+ public function __construct( $query, $moduleName ) {
+ parent :: __construct( $query, $moduleName, 'ap' );
}
public function execute() {
@@ -47,31 +47,35 @@ class ApiQueryAllpages extends ApiQueryGeneratorBase {
return 'public';
}
- public function executeGenerator($resultPageSet) {
- if ($resultPageSet->isResolvingRedirects())
- $this->dieUsage('Use "gapfilterredir=nonredirects" option instead of "redirects" when using allpages as a generator', 'params');
+ public function executeGenerator( $resultPageSet ) {
+ if ( $resultPageSet->isResolvingRedirects() )
+ $this->dieUsage( 'Use "gapfilterredir=nonredirects" option instead of "redirects" when using allpages as a generator', 'params' );
- $this->run($resultPageSet);
+ $this->run( $resultPageSet );
}
- private function run($resultPageSet = null) {
-
+ private function run( $resultPageSet = null ) {
$db = $this->getDB();
$params = $this->extractRequestParams();
// Page filters
- $this->addTables('page');
- if (!$this->addWhereIf('page_is_redirect = 1', $params['filterredir'] === 'redirects'))
- $this->addWhereIf('page_is_redirect = 0', $params['filterredir'] === 'nonredirects');
- $this->addWhereFld('page_namespace', $params['namespace']);
- $dir = ($params['dir'] == 'descending' ? 'older' : 'newer');
- $from = (is_null($params['from']) ? null : $this->titlePartToKey($params['from']));
- $this->addWhereRange('page_title', $dir, $from, null);
- if (isset ($params['prefix']))
- $this->addWhere("page_title LIKE '" . $db->escapeLike($this->titlePartToKey($params['prefix'])) . "%'");
-
- if (is_null($resultPageSet)) {
+ $this->addTables( 'page' );
+
+ if ( $params['filterredir'] == 'redirects' )
+ $this->addWhereFld( 'page_is_redirect', 1 );
+ else if ( $params['filterredir'] == 'nonredirects' )
+ $this->addWhereFld( 'page_is_redirect', 0 );
+
+ $this->addWhereFld( 'page_namespace', $params['namespace'] );
+ $dir = ( $params['dir'] == 'descending' ? 'older' : 'newer' );
+ $from = ( is_null( $params['from'] ) ? null : $this->titlePartToKey( $params['from'] ) );
+ $this->addWhereRange( 'page_title', $dir, $from, null );
+
+ if ( isset ( $params['prefix'] ) )
+ $this->addWhere( 'page_title' . $db->buildLike( $this->titlePartToKey( $params['prefix'] ), $db->anyString() ) );
+
+ if ( is_null( $resultPageSet ) ) {
$selectFields = array (
'page_namespace',
'page_title',
@@ -80,95 +84,98 @@ class ApiQueryAllpages extends ApiQueryGeneratorBase {
} else {
$selectFields = $resultPageSet->getPageTableFields();
}
- $this->addFields($selectFields);
+
+ $this->addFields( $selectFields );
$forceNameTitleIndex = true;
- if (isset ($params['minsize'])) {
- $this->addWhere('page_len>=' . intval($params['minsize']));
+ if ( isset ( $params['minsize'] ) ) {
+ $this->addWhere( 'page_len>=' . intval( $params['minsize'] ) );
$forceNameTitleIndex = false;
}
- if (isset ($params['maxsize'])) {
- $this->addWhere('page_len<=' . intval($params['maxsize']));
+ if ( isset ( $params['maxsize'] ) ) {
+ $this->addWhere( 'page_len<=' . intval( $params['maxsize'] ) );
$forceNameTitleIndex = false;
}
// Page protection filtering
- if (!empty ($params['prtype'])) {
- $this->addTables('page_restrictions');
- $this->addWhere('page_id=pr_page');
- $this->addWhere('pr_expiry>' . $db->addQuotes($db->timestamp()));
- $this->addWhereFld('pr_type', $params['prtype']);
-
- // Remove the empty string and '*' from the prlevel array
- $prlevel = array_diff($params['prlevel'], array('', '*'));
- if (!empty($prlevel))
- $this->addWhereFld('pr_level', $prlevel);
- if ($params['prfiltercascade'] == 'cascading')
- $this->addWhereFld('pr_cascade', 1);
- if ($params['prfiltercascade'] == 'noncascading')
- $this->addWhereFld('pr_cascade', 0);
-
- $this->addOption('DISTINCT');
+ if ( !empty ( $params['prtype'] ) ) {
+ $this->addTables( 'page_restrictions' );
+ $this->addWhere( 'page_id=pr_page' );
+ $this->addWhere( 'pr_expiry>' . $db->addQuotes( $db->timestamp() ) );
+ $this->addWhereFld( 'pr_type', $params['prtype'] );
+
+ if ( isset ( $params['prlevel'] ) ) {
+ // Remove the empty string and '*' from the prlevel array
+ $prlevel = array_diff( $params['prlevel'], array( '', '*' ) );
+
+ if ( !empty( $prlevel ) )
+ $this->addWhereFld( 'pr_level', $prlevel );
+ }
+ if ( $params['prfiltercascade'] == 'cascading' )
+ $this->addWhereFld( 'pr_cascade', 1 );
+ else if ( $params['prfiltercascade'] == 'noncascading' )
+ $this->addWhereFld( 'pr_cascade', 0 );
+
+ $this->addOption( 'DISTINCT' );
$forceNameTitleIndex = false;
- } else if (isset ($params['prlevel'])) {
- $this->dieUsage('prlevel may not be used without prtype', 'params');
+ } else if ( isset ( $params['prlevel'] ) ) {
+ $this->dieUsage( 'prlevel may not be used without prtype', 'params' );
}
- if($params['filterlanglinks'] == 'withoutlanglinks') {
- $this->addTables('langlinks');
- $this->addJoinConds(array('langlinks' => array('LEFT JOIN', 'page_id=ll_from')));
- $this->addWhere('ll_from IS NULL');
+ if ( $params['filterlanglinks'] == 'withoutlanglinks' ) {
+ $this->addTables( 'langlinks' );
+ $this->addJoinConds( array( 'langlinks' => array( 'LEFT JOIN', 'page_id=ll_from' ) ) );
+ $this->addWhere( 'll_from IS NULL' );
$forceNameTitleIndex = false;
- } else if($params['filterlanglinks'] == 'withlanglinks') {
- $this->addTables('langlinks');
- $this->addWhere('page_id=ll_from');
- $this->addOption('STRAIGHT_JOIN');
+ } else if ( $params['filterlanglinks'] == 'withlanglinks' ) {
+ $this->addTables( 'langlinks' );
+ $this->addWhere( 'page_id=ll_from' );
+ $this->addOption( 'STRAIGHT_JOIN' );
// We have to GROUP BY all selected fields to stop
// PostgreSQL from whining
- $this->addOption('GROUP BY', implode(', ', $selectFields));
+ $this->addOption( 'GROUP BY', implode( ', ', $selectFields ) );
$forceNameTitleIndex = false;
}
- if ($forceNameTitleIndex)
- $this->addOption('USE INDEX', 'name_title');
-
+ if ( $forceNameTitleIndex )
+ $this->addOption( 'USE INDEX', 'name_title' );
$limit = $params['limit'];
- $this->addOption('LIMIT', $limit+1);
- $res = $this->select(__METHOD__);
+ $this->addOption( 'LIMIT', $limit + 1 );
+ $res = $this->select( __METHOD__ );
$count = 0;
$result = $this->getResult();
- while ($row = $db->fetchObject($res)) {
- if (++ $count > $limit) {
+ while ( $row = $db->fetchObject( $res ) ) {
+ if ( ++ $count > $limit ) {
// We've reached the one extra which shows that there are additional pages to be had. Stop here...
// TODO: Security issue - if the user has no right to view next title, it will still be shown
- $this->setContinueEnumParameter('from', $this->keyToTitle($row->page_title));
+ $this->setContinueEnumParameter( 'from', $this->keyToTitle( $row->page_title ) );
break;
}
- if (is_null($resultPageSet)) {
- $title = Title :: makeTitle($row->page_namespace, $row->page_title);
+ if ( is_null( $resultPageSet ) ) {
+ $title = Title :: makeTitle( $row->page_namespace, $row->page_title );
$vals = array(
- 'pageid' => intval($row->page_id),
- 'ns' => intval($title->getNamespace()),
- 'title' => $title->getPrefixedText());
- $fit = $result->addValue(array('query', $this->getModuleName()), null, $vals);
- if(!$fit)
+ 'pageid' => intval( $row->page_id ),
+ 'ns' => intval( $title->getNamespace() ),
+ 'title' => $title->getPrefixedText() );
+ $fit = $result->addValue( array( 'query', $this->getModuleName() ), null, $vals );
+ if ( !$fit )
{
- $this->setContinueEnumParameter('from', $this->keyToTitle($row->page_title));
+ $this->setContinueEnumParameter( 'from', $this->keyToTitle( $row->page_title ) );
break;
}
} else {
- $resultPageSet->processDbRow($row);
+ $resultPageSet->processDbRow( $row );
}
}
- $db->freeResult($res);
+ $db->freeResult( $res );
- if (is_null($resultPageSet)) {
- $result->setIndexedTagName_internal(array('query', $this->getModuleName()), 'p');
+ if ( is_null( $resultPageSet ) ) {
+ $result->setIndexedTagName_internal( array( 'query', $this->getModuleName() ), 'p' );
}
}
@@ -257,6 +264,13 @@ class ApiQueryAllpages extends ApiQueryGeneratorBase {
public function getDescription() {
return 'Enumerate all pages sequentially in a given namespace';
}
+
+ public function getPossibleErrors() {
+ return array_merge( parent::getPossibleErrors(), array(
+ array( 'code' => 'params', 'info' => 'Use "gapfilterredir=nonredirects" option instead of "redirects" when using allpages as a generator' ),
+ array( 'code' => 'params', 'info' => 'prlevel may not be used without prtype' ),
+ ) );
+ }
protected function getExamples() {
return array (
@@ -272,6 +286,6 @@ class ApiQueryAllpages extends ApiQueryGeneratorBase {
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiQueryAllpages.php 69986 2010-07-27 03:57:39Z tstarling $';
+ return __CLASS__ . ': $Id: ApiQueryAllpages.php 69932 2010-07-26 08:03:21Z tstarling $';
}
}
diff --git a/includes/api/ApiQueryBacklinks.php b/includes/api/ApiQueryBacklinks.php
index 1b1fe639..648da069 100644
--- a/includes/api/ApiQueryBacklinks.php
+++ b/includes/api/ApiQueryBacklinks.php
@@ -23,9 +23,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ("ApiQueryBase.php");
+ require_once ( "ApiQueryBase.php" );
}
/**
@@ -61,18 +61,18 @@ class ApiQueryBacklinks extends ApiQueryGeneratorBase {
)
);
- public function __construct($query, $moduleName) {
- extract($this->backlinksSettings[$moduleName]);
+ public function __construct( $query, $moduleName ) {
+ extract( $this->backlinksSettings[$moduleName] );
$this->resultArr = array();
- parent :: __construct($query, $moduleName, $code);
+ parent :: __construct( $query, $moduleName, $code );
$this->bl_ns = $prefix . '_namespace';
$this->bl_from = $prefix . '_from';
$this->bl_table = $linktbl;
$this->bl_code = $code;
$this->hasNS = $moduleName !== 'imageusage';
- if ($this->hasNS) {
+ if ( $this->hasNS ) {
$this->bl_title = $prefix . '_title';
$this->bl_sort = "{$this->bl_ns}, {$this->bl_title}, {$this->bl_from}";
$this->bl_fields = array (
@@ -96,210 +96,223 @@ class ApiQueryBacklinks extends ApiQueryGeneratorBase {
return 'public';
}
- public function executeGenerator($resultPageSet) {
- $this->run($resultPageSet);
+ public function executeGenerator( $resultPageSet ) {
+ $this->run( $resultPageSet );
}
- private function prepareFirstQuery($resultPageSet = null) {
+ private function prepareFirstQuery( $resultPageSet = null ) {
/* SELECT page_id, page_title, page_namespace, page_is_redirect
* FROM pagelinks, page WHERE pl_from=page_id
* AND pl_title='Foo' AND pl_namespace=0
* LIMIT 11 ORDER BY pl_from
*/
$db = $this->getDB();
- $this->addTables(array('page', $this->bl_table));
- $this->addWhere("{$this->bl_from}=page_id");
- if(is_null($resultPageSet))
- $this->addFields(array('page_id', 'page_title', 'page_namespace'));
+ $this->addTables( array( $this->bl_table, 'page' ) );
+ $this->addWhere( "{$this->bl_from}=page_id" );
+ if ( is_null( $resultPageSet ) )
+ $this->addFields( array( 'page_id', 'page_title', 'page_namespace' ) );
else
- $this->addFields($resultPageSet->getPageTableFields());
- $this->addFields('page_is_redirect');
- $this->addWhereFld($this->bl_title, $this->rootTitle->getDBKey());
- if($this->hasNS)
- $this->addWhereFld($this->bl_ns, $this->rootTitle->getNamespace());
- $this->addWhereFld('page_namespace', $this->params['namespace']);
- if(!is_null($this->contID))
- $this->addWhere("{$this->bl_from}>={$this->contID}");
- if($this->params['filterredir'] == 'redirects')
- $this->addWhereFld('page_is_redirect', 1);
- if($this->params['filterredir'] == 'nonredirects')
- $this->addWhereFld('page_is_redirect', 0);
- $this->addOption('LIMIT', $this->params['limit'] + 1);
- $this->addOption('ORDER BY', $this->bl_from);
+ $this->addFields( $resultPageSet->getPageTableFields() );
+
+ $this->addFields( 'page_is_redirect' );
+ $this->addWhereFld( $this->bl_title, $this->rootTitle->getDBkey() );
+
+ if ( $this->hasNS )
+ $this->addWhereFld( $this->bl_ns, $this->rootTitle->getNamespace() );
+ $this->addWhereFld( 'page_namespace', $this->params['namespace'] );
+
+ if ( !is_null( $this->contID ) )
+ $this->addWhere( "{$this->bl_from}>={$this->contID}" );
+
+ if ( $this->params['filterredir'] == 'redirects' )
+ $this->addWhereFld( 'page_is_redirect', 1 );
+ else if ( $this->params['filterredir'] == 'nonredirects' && !$this->redirect )
+ // bug 22245 - Check for !redirect, as filtering nonredirects, when getting what links to them is contradictory
+ $this->addWhereFld( 'page_is_redirect', 0 );
+
+ $this->addOption( 'LIMIT', $this->params['limit'] + 1 );
+ $this->addOption( 'ORDER BY', $this->bl_from );
+ $this->addOption( 'STRAIGHT_JOIN' );
}
- private function prepareSecondQuery($resultPageSet = null) {
+ private function prepareSecondQuery( $resultPageSet = null ) {
/* SELECT page_id, page_title, page_namespace, page_is_redirect, pl_title, pl_namespace
FROM pagelinks, page WHERE pl_from=page_id
AND (pl_title='Foo' AND pl_namespace=0) OR (pl_title='Bar' AND pl_namespace=1)
ORDER BY pl_namespace, pl_title, pl_from LIMIT 11
*/
$db = $this->getDB();
- $this->addTables(array('page', $this->bl_table));
- $this->addWhere("{$this->bl_from}=page_id");
- if(is_null($resultPageSet))
- $this->addFields(array('page_id', 'page_title', 'page_namespace', 'page_is_redirect'));
+ $this->addTables( array( 'page', $this->bl_table ) );
+ $this->addWhere( "{$this->bl_from}=page_id" );
+
+ if ( is_null( $resultPageSet ) )
+ $this->addFields( array( 'page_id', 'page_title', 'page_namespace', 'page_is_redirect' ) );
else
- $this->addFields($resultPageSet->getPageTableFields());
- $this->addFields($this->bl_title);
- if($this->hasNS)
- $this->addFields($this->bl_ns);
+ $this->addFields( $resultPageSet->getPageTableFields() );
+
+ $this->addFields( $this->bl_title );
+ if ( $this->hasNS )
+ $this->addFields( $this->bl_ns );
+
// We can't use LinkBatch here because $this->hasNS may be false
$titleWhere = array();
- foreach($this->redirTitles as $t)
- $titleWhere[] = "{$this->bl_title} = ".$db->addQuotes($t->getDBKey()).
- ($this->hasNS ? " AND {$this->bl_ns} = '{$t->getNamespace()}'" : "");
- $this->addWhere($db->makeList($titleWhere, LIST_OR));
- $this->addWhereFld('page_namespace', $this->params['namespace']);
- if(!is_null($this->redirID))
+ foreach ( $this->redirTitles as $t )
+ $titleWhere[] = "{$this->bl_title} = " . $db->addQuotes( $t->getDBkey() ) .
+ ( $this->hasNS ? " AND {$this->bl_ns} = '{$t->getNamespace()}'" : "" );
+ $this->addWhere( $db->makeList( $titleWhere, LIST_OR ) );
+ $this->addWhereFld( 'page_namespace', $this->params['namespace'] );
+
+ if ( !is_null( $this->redirID ) )
{
$first = $this->redirTitles[0];
- $title = $db->strencode($first->getDBKey());
+ $title = $db->strencode( $first->getDBkey() );
$ns = $first->getNamespace();
$from = $this->redirID;
- if($this->hasNS)
- $this->addWhere("{$this->bl_ns} > $ns OR ".
- "({$this->bl_ns} = $ns AND ".
- "({$this->bl_title} > '$title' OR ".
- "({$this->bl_title} = '$title' AND ".
- "{$this->bl_from} >= $from)))");
+ if ( $this->hasNS )
+ $this->addWhere( "{$this->bl_ns} > $ns OR " .
+ "({$this->bl_ns} = $ns AND " .
+ "({$this->bl_title} > '$title' OR " .
+ "({$this->bl_title} = '$title' AND " .
+ "{$this->bl_from} >= $from)))" );
else
- $this->addWhere("{$this->bl_title} > '$title' OR ".
- "({$this->bl_title} = '$title' AND ".
- "{$this->bl_from} >= $from)");
+ $this->addWhere( "{$this->bl_title} > '$title' OR " .
+ "({$this->bl_title} = '$title' AND " .
+ "{$this->bl_from} >= $from)" );
}
- if($this->params['filterredir'] == 'redirects')
- $this->addWhereFld('page_is_redirect', 1);
- if($this->params['filterredir'] == 'nonredirects')
- $this->addWhereFld('page_is_redirect', 0);
- $this->addOption('LIMIT', $this->params['limit'] + 1);
- $this->addOption('ORDER BY', $this->bl_sort);
- $this->addOption('USE INDEX', array('page' => 'PRIMARY'));
+ if ( $this->params['filterredir'] == 'redirects' )
+ $this->addWhereFld( 'page_is_redirect', 1 );
+ else if ( $this->params['filterredir'] == 'nonredirects' )
+ $this->addWhereFld( 'page_is_redirect', 0 );
+
+ $this->addOption( 'LIMIT', $this->params['limit'] + 1 );
+ $this->addOption( 'ORDER BY', $this->bl_sort );
+ $this->addOption( 'USE INDEX', array( 'page' => 'PRIMARY' ) );
}
- private function run($resultPageSet = null) {
- $this->params = $this->extractRequestParams(false);
- $this->redirect = isset($this->params['redirect']) && $this->params['redirect'];
- $userMax = ( $this->redirect ? ApiBase::LIMIT_BIG1/2 : ApiBase::LIMIT_BIG1 );
- $botMax = ( $this->redirect ? ApiBase::LIMIT_BIG2/2 : ApiBase::LIMIT_BIG2 );
- if( $this->params['limit'] == 'max' ) {
+ private function run( $resultPageSet = null ) {
+ $this->params = $this->extractRequestParams( false );
+ $this->redirect = isset( $this->params['redirect'] ) && $this->params['redirect'];
+ $userMax = ( $this->redirect ? ApiBase::LIMIT_BIG1 / 2 : ApiBase::LIMIT_BIG1 );
+ $botMax = ( $this->redirect ? ApiBase::LIMIT_BIG2 / 2 : ApiBase::LIMIT_BIG2 );
+ if ( $this->params['limit'] == 'max' ) {
$this->params['limit'] = $this->getMain()->canApiHighLimits() ? $botMax : $userMax;
$this->getResult()->addValue( 'limits', $this->getModuleName(), $this->params['limit'] );
}
$this->processContinue();
- $this->prepareFirstQuery($resultPageSet);
+ $this->prepareFirstQuery( $resultPageSet );
$db = $this->getDB();
- $res = $this->select(__METHOD__.'::firstQuery');
+ $res = $this->select( __METHOD__ . '::firstQuery' );
$count = 0;
$this->pageMap = array(); // Maps ns and title to pageid
$this->continueStr = null;
$this->redirTitles = array();
- while ($row = $db->fetchObject($res)) {
- if (++ $count > $this->params['limit']) {
+ while ( $row = $db->fetchObject( $res ) ) {
+ if ( ++ $count > $this->params['limit'] ) {
// We've reached the one extra which shows that there are additional pages to be had. Stop here...
// Continue string preserved in case the redirect query doesn't pass the limit
- $this->continueStr = $this->getContinueStr($row->page_id);
+ $this->continueStr = $this->getContinueStr( $row->page_id );
break;
}
- if (is_null($resultPageSet))
- $this->extractRowInfo($row);
+ if ( is_null( $resultPageSet ) )
+ $this->extractRowInfo( $row );
else
{
$this->pageMap[$row->page_namespace][$row->page_title] = $row->page_id;
- if($row->page_is_redirect)
- $this->redirTitles[] = Title::makeTitle($row->page_namespace, $row->page_title);
- $resultPageSet->processDbRow($row);
+ if ( $row->page_is_redirect )
+ $this->redirTitles[] = Title::makeTitle( $row->page_namespace, $row->page_title );
+
+ $resultPageSet->processDbRow( $row );
}
}
- $db->freeResult($res);
+ $db->freeResult( $res );
- if($this->redirect && count($this->redirTitles))
+ if ( $this->redirect && count( $this->redirTitles ) )
{
$this->resetQueryParams();
- $this->prepareSecondQuery($resultPageSet);
- $res = $this->select(__METHOD__.'::secondQuery');
+ $this->prepareSecondQuery( $resultPageSet );
+ $res = $this->select( __METHOD__ . '::secondQuery' );
$count = 0;
- while($row = $db->fetchObject($res))
+ while ( $row = $db->fetchObject( $res ) )
{
- if(++$count > $this->params['limit'])
+ if ( ++$count > $this->params['limit'] )
{
// We've reached the one extra which shows that there are additional pages to be had. Stop here...
// We need to keep the parent page of this redir in
- if($this->hasNS)
- $parentID = $this->pageMap[$row->{$this->bl_ns}][$row->{$this->bl_title}];
+ if ( $this->hasNS )
+ $parentID = $this->pageMap[$row-> { $this->bl_ns } ][$row-> { $this->bl_title } ];
else
- $parentID = $this->pageMap[NS_IMAGE][$row->{$this->bl_title}];
- $this->continueStr = $this->getContinueRedirStr($parentID, $row->page_id);
+ $parentID = $this->pageMap[NS_IMAGE][$row-> { $this->bl_title } ];
+ $this->continueStr = $this->getContinueRedirStr( $parentID, $row->page_id );
break;
}
- if(is_null($resultPageSet))
- $this->extractRedirRowInfo($row);
+ if ( is_null( $resultPageSet ) )
+ $this->extractRedirRowInfo( $row );
else
- $resultPageSet->processDbRow($row);
+ $resultPageSet->processDbRow( $row );
}
- $db->freeResult($res);
+ $db->freeResult( $res );
}
- if (is_null($resultPageSet)) {
+ if ( is_null( $resultPageSet ) ) {
// Try to add the result data in one go and pray that it fits
- $fit = $this->getResult()->addValue('query', $this->getModuleName(), array_values($this->resultArr));
- if(!$fit)
+ $fit = $this->getResult()->addValue( 'query', $this->getModuleName(), array_values( $this->resultArr ) );
+ if ( !$fit )
{
// It didn't fit. Add elements one by one until the
// result is full.
- foreach($this->resultArr as $pageID => $arr)
+ foreach ( $this->resultArr as $pageID => $arr )
{
// Add the basic entry without redirlinks first
$fit = $this->getResult()->addValue(
- array('query', $this->getModuleName()),
- null, array_diff_key($arr, array('redirlinks' => '')));
- if(!$fit)
+ array( 'query', $this->getModuleName() ),
+ null, array_diff_key( $arr, array( 'redirlinks' => '' ) ) );
+ if ( !$fit )
{
- $this->continueStr = $this->getContinueStr($pageID);
+ $this->continueStr = $this->getContinueStr( $pageID );
break;
}
$hasRedirs = false;
- foreach((array)@$arr['redirlinks'] as $key => $redir)
+ foreach ( (array)@$arr['redirlinks'] as $key => $redir )
{
$fit = $this->getResult()->addValue(
- array('query', $this->getModuleName(), $pageID, 'redirlinks'),
- $key, $redir);
- if(!$fit)
+ array( 'query', $this->getModuleName(), $pageID, 'redirlinks' ),
+ $key, $redir );
+ if ( !$fit )
{
- $this->continueStr = $this->getContinueRedirStr($pageID, $redir['pageid']);
+ $this->continueStr = $this->getContinueRedirStr( $pageID, $redir['pageid'] );
break;
}
$hasRedirs = true;
}
- if($hasRedirs)
+ if ( $hasRedirs )
$this->getResult()->setIndexedTagName_internal(
- array('query', $this->getModuleName(), $pageID, 'redirlinks'),
- $this->bl_code);
- if(!$fit)
+ array( 'query', $this->getModuleName(), $pageID, 'redirlinks' ),
+ $this->bl_code );
+ if ( !$fit )
break;
}
- }
+ }
$this->getResult()->setIndexedTagName_internal(
- array('query', $this->getModuleName()),
- $this->bl_code);
+ array( 'query', $this->getModuleName() ),
+ $this->bl_code );
}
- if(!is_null($this->continueStr))
- $this->setContinueEnumParameter('continue', $this->continueStr);
+ if ( !is_null( $this->continueStr ) )
+ $this->setContinueEnumParameter( 'continue', $this->continueStr );
}
- private function extractRowInfo($row) {
+ private function extractRowInfo( $row ) {
$this->pageMap[$row->page_namespace][$row->page_title] = $row->page_id;
- $t = Title::makeTitle($row->page_namespace, $row->page_title);
- $a = array('pageid' => intval($row->page_id));
- ApiQueryBase::addTitleInfo($a, $t);
- if($row->page_is_redirect)
+ $t = Title::makeTitle( $row->page_namespace, $row->page_title );
+ $a = array( 'pageid' => intval( $row->page_id ) );
+ ApiQueryBase::addTitleInfo( $a, $t );
+ if ( $row->page_is_redirect )
{
$a['redirect'] = '';
$this->redirTitles[] = $t;
@@ -308,42 +321,42 @@ class ApiQueryBacklinks extends ApiQueryGeneratorBase {
$this->resultArr[$a['pageid']] = $a;
}
- private function extractRedirRowInfo($row)
+ private function extractRedirRowInfo( $row )
{
- $a['pageid'] = intval($row->page_id);
- ApiQueryBase::addTitleInfo($a, Title::makeTitle($row->page_namespace, $row->page_title));
- if($row->page_is_redirect)
+ $a['pageid'] = intval( $row->page_id );
+ ApiQueryBase::addTitleInfo( $a, Title::makeTitle( $row->page_namespace, $row->page_title ) );
+ if ( $row->page_is_redirect )
$a['redirect'] = '';
- $ns = $this->hasNS ? $row->{$this->bl_ns} : NS_FILE;
- $parentID = $this->pageMap[$ns][$row->{$this->bl_title}];
+ $ns = $this->hasNS ? $row-> { $this->bl_ns } : NS_FILE;
+ $parentID = $this->pageMap[$ns][$row-> { $this->bl_title } ];
// Put all the results in an array first
$this->resultArr[$parentID]['redirlinks'][] = $a;
- $this->getResult()->setIndexedTagName($this->resultArr[$parentID]['redirlinks'], $this->bl_code);
+ $this->getResult()->setIndexedTagName( $this->resultArr[$parentID]['redirlinks'], $this->bl_code );
}
protected function processContinue() {
- if (!is_null($this->params['continue']))
+ if ( !is_null( $this->params['continue'] ) )
$this->parseContinueParam();
else {
if ( $this->params['title'] !== "" ) {
$title = Title::newFromText( $this->params['title'] );
if ( !$title ) {
- $this->dieUsageMsg(array('invalidtitle', $this->params['title']));
+ $this->dieUsageMsg( array( 'invalidtitle', $this->params['title'] ) );
} else {
$this->rootTitle = $title;
}
} else {
- $this->dieUsageMsg(array('missingparam', 'title'));
+ $this->dieUsageMsg( array( 'missingparam', 'title' ) );
}
}
// only image titles are allowed for the root in imageinfo mode
- if (!$this->hasNS && $this->rootTitle->getNamespace() !== NS_FILE)
- $this->dieUsage("The title for {$this->getModuleName()} query must be an image", 'bad_image_title');
+ if ( !$this->hasNS && $this->rootTitle->getNamespace() !== NS_FILE )
+ $this->dieUsage( "The title for {$this->getModuleName()} query must be an image", 'bad_image_title' );
}
protected function parseContinueParam() {
- $continueList = explode('|', $this->params['continue']);
+ $continueList = explode( '|', $this->params['continue'] );
// expected format:
// ns | key | id1 [| id2]
// ns+key: root title
@@ -352,33 +365,36 @@ class ApiQueryBacklinks extends ApiQueryGeneratorBase {
// null stuff out now so we know what's set and what isn't
$this->rootTitle = $this->contID = $this->redirID = null;
- $rootNs = intval($continueList[0]);
- if($rootNs === 0 && $continueList[0] !== '0')
+ $rootNs = intval( $continueList[0] );
+ if ( $rootNs === 0 && $continueList[0] !== '0' )
// Illegal continue parameter
- $this->dieUsage("Invalid continue param. You should pass the original value returned by the previous query", "_badcontinue");
- $this->rootTitle = Title::makeTitleSafe($rootNs, $continueList[1]);
- if(!$this->rootTitle)
- $this->dieUsage("Invalid continue param. You should pass the original value returned by the previous query", "_badcontinue");
- $contID = intval($continueList[2]);
- if($contID === 0 && $continueList[2] !== '0')
- $this->dieUsage("Invalid continue param. You should pass the original value returned by the previous query", "_badcontinue");
+ $this->dieUsage( "Invalid continue param. You should pass the original value returned by the previous query", "_badcontinue" );
+ $this->rootTitle = Title::makeTitleSafe( $rootNs, $continueList[1] );
+
+ if ( !$this->rootTitle )
+ $this->dieUsage( "Invalid continue param. You should pass the original value returned by the previous query", "_badcontinue" );
+ $contID = intval( $continueList[2] );
+
+ if ( $contID === 0 && $continueList[2] !== '0' )
+ $this->dieUsage( "Invalid continue param. You should pass the original value returned by the previous query", "_badcontinue" );
$this->contID = $contID;
- $redirID = intval(@$continueList[3]);
- if($redirID === 0 && @$continueList[3] !== '0')
+ $redirID = intval( @$continueList[3] );
+
+ if ( $redirID === 0 && @$continueList[3] !== '0' )
// This one isn't required
return;
$this->redirID = $redirID;
}
- protected function getContinueStr($lastPageID) {
+ protected function getContinueStr( $lastPageID ) {
return $this->rootTitle->getNamespace() .
'|' . $this->rootTitle->getDBkey() .
'|' . $lastPageID;
}
- protected function getContinueRedirStr($lastPageID, $lastRedirID) {
- return $this->getContinueStr($lastPageID) . '|' . $lastRedirID;
+ protected function getContinueRedirStr( $lastPageID, $lastRedirID ) {
+ return $this->getContinueStr( $lastPageID ) . '|' . $lastRedirID;
}
public function getAllowedParams() {
@@ -405,7 +421,7 @@ class ApiQueryBacklinks extends ApiQueryGeneratorBase {
ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2
)
);
- if($this->getModuleName() == 'embeddedin')
+ if ( $this->getModuleName() == 'embeddedin' )
return $retval;
$retval['redirect'] = false;
return $retval;
@@ -413,23 +429,24 @@ class ApiQueryBacklinks extends ApiQueryGeneratorBase {
public function getParamDescription() {
$retval = array (
- 'title' => 'Title to search. If null, titles= parameter will be used instead, but will be obsolete soon.',
+ 'title' => 'Title to search.',
'continue' => 'When more results are available, use this to continue.',
'namespace' => 'The namespace to enumerate.',
- 'filterredir' => 'How to filter for redirects'
);
- if($this->getModuleName() != 'embeddedin')
- return array_merge($retval, array(
+ if ( $this->getModuleName() != 'embeddedin' )
+ return array_merge( $retval, array(
'redirect' => 'If linking page is a redirect, find all pages that link to that redirect as well. Maximum limit is halved.',
- 'limit' => "How many total pages to return. If {$this->bl_code}redirect is enabled, limit applies to each level separately."
- ));
- return array_merge($retval, array(
- 'limit' => "How many total pages to return."
- ));
+ 'filterredir' => "How to filter for redirects. If set to nonredirects when {$this->bl_code}redirect is enabled, this is only applied to the second level",
+ 'limit' => "How many total pages to return. If {$this->bl_code}redirect is enabled, limit applies to each level separately (which means you may get up to 2 * limit results)."
+ ) );
+ return array_merge( $retval, array(
+ 'filterredir' => 'How to filter for redirects',
+ 'limit' => 'How many total pages to return.'
+ ) );
}
public function getDescription() {
- switch ($this->getModuleName()) {
+ switch ( $this->getModuleName() ) {
case 'backlinks' :
return 'Find all pages that link to the given page';
case 'embeddedin' :
@@ -437,9 +454,18 @@ class ApiQueryBacklinks extends ApiQueryGeneratorBase {
case 'imageusage' :
return 'Find all pages that use the given image title.';
default :
- ApiBase :: dieDebug(__METHOD__, 'Unknown module name');
+ ApiBase :: dieDebug( __METHOD__, 'Unknown module name' );
}
}
+
+ public function getPossibleErrors() {
+ return array_merge( parent::getPossibleErrors(), array(
+ array( 'invalidtitle', 'title' ),
+ array( 'missingparam', 'title' ),
+ array( 'code' => 'bad_image_title', 'info' => "The title for {$this->getModuleName()} query must be an image" ),
+ array( 'code' => '_badcontinue', 'info' => 'Invalid continue param. You should pass the original value returned by the previous query' ),
+ ) );
+ }
protected function getExamples() {
static $examples = array (
@@ -461,6 +487,6 @@ class ApiQueryBacklinks extends ApiQueryGeneratorBase {
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiQueryBacklinks.php 69986 2010-07-27 03:57:39Z tstarling $';
+ return __CLASS__ . ': $Id: ApiQueryBacklinks.php 69932 2010-07-26 08:03:21Z tstarling $';
}
}
diff --git a/includes/api/ApiQueryBase.php b/includes/api/ApiQueryBase.php
index 7e2b1d5e..893da566 100644
--- a/includes/api/ApiQueryBase.php
+++ b/includes/api/ApiQueryBase.php
@@ -23,9 +23,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ('ApiBase.php');
+ require_once ( 'ApiBase.php' );
}
/**
@@ -39,8 +39,8 @@ abstract class ApiQueryBase extends ApiBase {
private $mQueryModule, $mDb, $tables, $where, $fields, $options, $join_conds;
- public function __construct($query, $moduleName, $paramPrefix = '') {
- parent :: __construct($query->getMain(), $moduleName, $paramPrefix);
+ public function __construct( $query, $moduleName, $paramPrefix = '' ) {
+ parent :: __construct( $query->getMain(), $moduleName, $paramPrefix );
$this->mQueryModule = $query;
$this->mDb = null;
$this->resetQueryParams();
@@ -74,14 +74,14 @@ abstract class ApiQueryBase extends ApiBase {
* @param $alias mixed Table alias, or null for no alias. Cannot be
* used with multiple tables
*/
- protected function addTables($tables, $alias = null) {
- if (is_array($tables)) {
- if (!is_null($alias))
- ApiBase :: dieDebug(__METHOD__, 'Multiple table aliases not supported');
- $this->tables = array_merge($this->tables, $tables);
+ protected function addTables( $tables, $alias = null ) {
+ if ( is_array( $tables ) ) {
+ if ( !is_null( $alias ) )
+ ApiBase :: dieDebug( __METHOD__, 'Multiple table aliases not supported' );
+ $this->tables = array_merge( $this->tables, $tables );
} else {
- if (!is_null($alias))
- $tables = $this->getAliasedName($tables, $alias);
+ if ( !is_null( $alias ) )
+ $tables = $this->getAliasedName( $tables, $alias );
$this->tables[] = $tables;
}
}
@@ -92,8 +92,8 @@ abstract class ApiQueryBase extends ApiBase {
* @param $alias string Alias
* @return string SQL
*/
- protected function getAliasedName($table, $alias) {
- return $this->getDB()->tableName($table) . ' ' . $alias;
+ protected function getAliasedName( $table, $alias ) {
+ return $this->getDB()->tableName( $table ) . ' ' . $alias;
}
/**
@@ -105,19 +105,19 @@ abstract class ApiQueryBase extends ApiBase {
* addWhere()-style array
* @param $join_conds array JOIN conditions
*/
- protected function addJoinConds($join_conds) {
- if(!is_array($join_conds))
- ApiBase::dieDebug(__METHOD__, 'Join conditions have to be arrays');
- $this->join_conds = array_merge($this->join_conds, $join_conds);
+ protected function addJoinConds( $join_conds ) {
+ if ( !is_array( $join_conds ) )
+ ApiBase::dieDebug( __METHOD__, 'Join conditions have to be arrays' );
+ $this->join_conds = array_merge( $this->join_conds, $join_conds );
}
/**
* Add a set of fields to select to the internal array
* @param $value mixed Field name or array of field names
*/
- protected function addFields($value) {
- if (is_array($value))
- $this->fields = array_merge($this->fields, $value);
+ protected function addFields( $value ) {
+ if ( is_array( $value ) )
+ $this->fields = array_merge( $this->fields, $value );
else
$this->fields[] = $value;
}
@@ -128,9 +128,9 @@ abstract class ApiQueryBase extends ApiBase {
* @param $condition bool If false, do nothing
* @return bool $condition
*/
- protected function addFieldsIf($value, $condition) {
- if ($condition) {
- $this->addFields($value);
+ protected function addFieldsIf( $value, $condition ) {
+ if ( $condition ) {
+ $this->addFields( $value );
return true;
}
return false;
@@ -147,12 +147,12 @@ abstract class ApiQueryBase extends ApiBase {
* to "foo=bar AND baz='3' AND bla='foo'"
* @param $value mixed String or array
*/
- protected function addWhere($value) {
- if (is_array($value)) {
+ protected function addWhere( $value ) {
+ if ( is_array( $value ) ) {
// Sanity check: don't insert empty arrays,
// Database::makeList() chokes on them
if ( count( $value ) )
- $this->where = array_merge($this->where, $value);
+ $this->where = array_merge( $this->where, $value );
}
else
$this->where[] = $value;
@@ -164,9 +164,9 @@ abstract class ApiQueryBase extends ApiBase {
* @param $condition boolIf false, do nothing
* @return bool $condition
*/
- protected function addWhereIf($value, $condition) {
- if ($condition) {
- $this->addWhere($value);
+ protected function addWhereIf( $value, $condition ) {
+ if ( $condition ) {
+ $this->addWhere( $value );
return true;
}
return false;
@@ -177,7 +177,7 @@ abstract class ApiQueryBase extends ApiBase {
* @param $field string Field name
* @param $value string Value; ignored if null or empty array;
*/
- protected function addWhereFld($field, $value) {
+ protected function addWhereFld( $field, $value ) {
// Use count() to its full documented capabilities to simultaneously
// test for null, empty array or empty countable object
if ( count( $value ) )
@@ -196,24 +196,24 @@ abstract class ApiQueryBase extends ApiBase {
* is the upper boundary, otherwise it's the lower boundary
* @param $sort bool If false, don't add an ORDER BY clause
*/
- protected function addWhereRange($field, $dir, $start, $end, $sort = true) {
- $isDirNewer = ($dir === 'newer');
- $after = ($isDirNewer ? '>=' : '<=');
- $before = ($isDirNewer ? '<=' : '>=');
+ protected function addWhereRange( $field, $dir, $start, $end, $sort = true ) {
+ $isDirNewer = ( $dir === 'newer' );
+ $after = ( $isDirNewer ? '>=' : '<=' );
+ $before = ( $isDirNewer ? '<=' : '>=' );
$db = $this->getDB();
- if (!is_null($start))
- $this->addWhere($field . $after . $db->addQuotes($start));
+ if ( !is_null( $start ) )
+ $this->addWhere( $field . $after . $db->addQuotes( $start ) );
- if (!is_null($end))
- $this->addWhere($field . $before . $db->addQuotes($end));
+ if ( !is_null( $end ) )
+ $this->addWhere( $field . $before . $db->addQuotes( $end ) );
- if ($sort) {
- $order = $field . ($isDirNewer ? '' : ' DESC');
- if (!isset($this->options['ORDER BY']))
- $this->addOption('ORDER BY', $order);
+ if ( $sort ) {
+ $order = $field . ( $isDirNewer ? '' : ' DESC' );
+ if ( !isset( $this->options['ORDER BY'] ) )
+ $this->addOption( 'ORDER BY', $order );
else
- $this->addOption('ORDER BY', $this->options['ORDER BY'] . ', ' . $order);
+ $this->addOption( 'ORDER BY', $this->options['ORDER BY'] . ', ' . $order );
}
}
@@ -223,8 +223,8 @@ abstract class ApiQueryBase extends ApiBase {
* @param $name string Option name
* @param $value string Option value
*/
- protected function addOption($name, $value = null) {
- if (is_null($value))
+ protected function addOption( $name, $value = null ) {
+ if ( is_null( $value ) )
$this->options[] = $name;
else
$this->options[$name] = $value;
@@ -236,13 +236,12 @@ abstract class ApiQueryBase extends ApiBase {
* You should usually use __METHOD__ here
* @return ResultWrapper
*/
- protected function select($method) {
-
+ protected function select( $method ) {
// getDB has its own profileDBIn/Out calls
$db = $this->getDB();
$this->profileDBIn();
- $res = $db->select($this->tables, $this->fields, $this->where, $method, $this->options, $this->join_conds);
+ $res = $db->select( $this->tables, $this->fields, $this->where, $method, $this->options, $this->join_conds );
$this->profileDBOut();
return $res;
@@ -256,11 +255,11 @@ abstract class ApiQueryBase extends ApiBase {
protected function checkRowCount() {
$db = $this->getDB();
$this->profileDBIn();
- $rowcount = $db->estimateRowCount($this->tables, $this->fields, $this->where, __METHOD__, $this->options);
+ $rowcount = $db->estimateRowCount( $this->tables, $this->fields, $this->where, __METHOD__, $this->options );
$this->profileDBOut();
global $wgAPIMaxDBRows;
- if($rowcount > $wgAPIMaxDBRows)
+ if ( $rowcount > $wgAPIMaxDBRows )
return false;
return true;
}
@@ -272,8 +271,8 @@ abstract class ApiQueryBase extends ApiBase {
* @param $title Title
* @param $prefix string Module prefix
*/
- public static function addTitleInfo(&$arr, $title, $prefix='') {
- $arr[$prefix . 'ns'] = intval($title->getNamespace());
+ public static function addTitleInfo( &$arr, $title, $prefix = '' ) {
+ $arr[$prefix . 'ns'] = intval( $title->getNamespace() );
$arr[$prefix . 'title'] = $title->getPrefixedText();
}
@@ -282,7 +281,7 @@ abstract class ApiQueryBase extends ApiBase {
* using $pageSet->requestField('fieldName')
* @param $pageSet ApiPageSet
*/
- public function requestExtraData($pageSet) {
+ public function requestExtraData( $pageSet ) {
}
/**
@@ -299,12 +298,12 @@ abstract class ApiQueryBase extends ApiBase {
* @param $data array Data array à la ApiResult
* @return bool Whether the element fit in the result
*/
- protected function addPageSubItems($pageId, $data) {
+ protected function addPageSubItems( $pageId, $data ) {
$result = $this->getResult();
- $result->setIndexedTagName($data, $this->getModulePrefix());
- return $result->addValue(array('query', 'pages', intval($pageId)),
+ $result->setIndexedTagName( $data, $this->getModulePrefix() );
+ return $result->addValue( array( 'query', 'pages', intval( $pageId ) ),
$this->getModuleName(),
- $data);
+ $data );
}
/**
@@ -315,16 +314,16 @@ abstract class ApiQueryBase extends ApiBase {
* is used
* @return bool Whether the element fit in the result
*/
- protected function addPageSubItem($pageId, $item, $elemname = null) {
- if(is_null($elemname))
+ protected function addPageSubItem( $pageId, $item, $elemname = null ) {
+ if ( is_null( $elemname ) )
$elemname = $this->getModulePrefix();
$result = $this->getResult();
- $fit = $result->addValue(array('query', 'pages', $pageId,
- $this->getModuleName()), null, $item);
- if(!$fit)
+ $fit = $result->addValue( array( 'query', 'pages', $pageId,
+ $this->getModuleName() ), null, $item );
+ if ( !$fit )
return false;
- $result->setIndexedTagName_internal(array('query', 'pages', $pageId,
- $this->getModuleName()), $elemname);
+ $result->setIndexedTagName_internal( array( 'query', 'pages', $pageId,
+ $this->getModuleName() ), $elemname );
return true;
}
@@ -333,11 +332,11 @@ abstract class ApiQueryBase extends ApiBase {
* @param $paramName string Parameter name
* @param $paramValue string Parameter value
*/
- protected function setContinueEnumParameter($paramName, $paramValue) {
- $paramName = $this->encodeParamName($paramName);
+ protected function setContinueEnumParameter( $paramName, $paramValue ) {
+ $paramName = $this->encodeParamName( $paramName );
$msg = array( $paramName => $paramValue );
$this->getResult()->disableSizeCheck();
- $this->getResult()->addValue('query-continue', $this->getModuleName(), $msg);
+ $this->getResult()->addValue( 'query-continue', $this->getModuleName(), $msg );
$this->getResult()->enableSizeCheck();
}
@@ -346,7 +345,7 @@ abstract class ApiQueryBase extends ApiBase {
* @return Database
*/
protected function getDB() {
- if (is_null($this->mDb))
+ if ( is_null( $this->mDb ) )
$this->mDb = $this->getQuery()->getDB();
return $this->mDb;
}
@@ -359,8 +358,8 @@ abstract class ApiQueryBase extends ApiBase {
* @param $groups array Query groups
* @return Database
*/
- public function selectNamedDB($name, $db, $groups) {
- $this->mDb = $this->getQuery()->getNamedDB($name, $db, $groups);
+ public function selectNamedDB( $name, $db, $groups ) {
+ $this->mDb = $this->getQuery()->getNamedDB( $name, $db, $groups );
}
/**
@@ -376,13 +375,13 @@ abstract class ApiQueryBase extends ApiBase {
* @param $title string Page title with spaces
* @return string Page title with underscores
*/
- public function titleToKey($title) {
- # Don't throw an error if we got an empty string
- if(trim($title) == '')
+ public function titleToKey( $title ) {
+ // Don't throw an error if we got an empty string
+ if ( trim( $title ) == '' )
return '';
- $t = Title::newFromText($title);
- if(!$t)
- $this->dieUsageMsg(array('invalidtitle', $title));
+ $t = Title::newFromText( $title );
+ if ( !$t )
+ $this->dieUsageMsg( array( 'invalidtitle', $title ) );
return $t->getPrefixedDbKey();
}
@@ -391,14 +390,14 @@ abstract class ApiQueryBase extends ApiBase {
* @param $key string Page title with underscores
* @return string Page title with spaces
*/
- public function keyToTitle($key) {
- # Don't throw an error if we got an empty string
- if(trim($key) == '')
+ public function keyToTitle( $key ) {
+ // Don't throw an error if we got an empty string
+ if ( trim( $key ) == '' )
return '';
- $t = Title::newFromDbKey($key);
- # This really shouldn't happen but we gotta check anyway
- if(!$t)
- $this->dieUsageMsg(array('invalidtitle', $key));
+ $t = Title::newFromDbKey( $key );
+ // This really shouldn't happen but we gotta check anyway
+ if ( !$t )
+ $this->dieUsageMsg( array( 'invalidtitle', $key ) );
return $t->getPrefixedText();
}
@@ -407,8 +406,8 @@ abstract class ApiQueryBase extends ApiBase {
* @param $titlePart string Title part with spaces
* @return string Title part with underscores
*/
- public function titlePartToKey($titlePart) {
- return substr($this->titleToKey($titlePart . 'x'), 0, -1);
+ public function titlePartToKey( $titlePart ) {
+ return substr( $this->titleToKey( $titlePart . 'x' ), 0, - 1 );
}
/**
@@ -416,8 +415,15 @@ abstract class ApiQueryBase extends ApiBase {
* @param $keyPart string Key part with spaces
* @return string Key part with underscores
*/
- public function keyPartToTitle($keyPart) {
- return substr($this->keyToTitle($keyPart . 'x'), 0, -1);
+ public function keyPartToTitle( $keyPart ) {
+ return substr( $this->keyToTitle( $keyPart . 'x' ), 0, - 1 );
+ }
+
+ public function getPossibleErrors() {
+ return array_merge( parent::getPossibleErrors(), array(
+ array( 'invalidtitle', 'title' ),
+ array( 'invalidtitle', 'key' ),
+ ) );
}
/**
@@ -425,7 +431,7 @@ abstract class ApiQueryBase extends ApiBase {
* @return string
*/
public static function getBaseVersion() {
- return __CLASS__ . ': $Id: ApiQueryBase.php 69986 2010-07-27 03:57:39Z tstarling $';
+ return __CLASS__ . ': $Id: ApiQueryBase.php 69932 2010-07-26 08:03:21Z tstarling $';
}
}
@@ -436,8 +442,8 @@ abstract class ApiQueryGeneratorBase extends ApiQueryBase {
private $mIsGenerator;
- public function __construct($query, $moduleName, $paramPrefix = '') {
- parent :: __construct($query, $moduleName, $paramPrefix);
+ public function __construct( $query, $moduleName, $paramPrefix = '' ) {
+ parent :: __construct( $query, $moduleName, $paramPrefix );
$this->mIsGenerator = false;
}
@@ -454,11 +460,11 @@ abstract class ApiQueryGeneratorBase extends ApiQueryBase {
* @param $paramNames string Parameter name
* @return string Prefixed parameter name
*/
- public function encodeParamName($paramName) {
- if ($this->mIsGenerator)
- return 'g' . parent :: encodeParamName($paramName);
+ public function encodeParamName( $paramName ) {
+ if ( $this->mIsGenerator )
+ return 'g' . parent :: encodeParamName( $paramName );
else
- return parent :: encodeParamName($paramName);
+ return parent :: encodeParamName( $paramName );
}
/**
@@ -466,5 +472,5 @@ abstract class ApiQueryGeneratorBase extends ApiQueryBase {
* @param $resultPageSet ApiPageSet: All output should be appended to
* this object
*/
- public abstract function executeGenerator($resultPageSet);
+ public abstract function executeGenerator( $resultPageSet );
}
diff --git a/includes/api/ApiQueryBlocks.php b/includes/api/ApiQueryBlocks.php
index 64790037..8b321044 100644
--- a/includes/api/ApiQueryBlocks.php
+++ b/includes/api/ApiQueryBlocks.php
@@ -23,9 +23,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ('ApiQueryBase.php');
+ require_once ( 'ApiQueryBase.php' );
}
/**
@@ -37,157 +37,163 @@ class ApiQueryBlocks extends ApiQueryBase {
var $users;
- public function __construct($query, $moduleName) {
- parent :: __construct($query, $moduleName, 'bk');
+ public function __construct( $query, $moduleName ) {
+ parent :: __construct( $query, $moduleName, 'bk' );
}
public function execute() {
global $wgUser;
$params = $this->extractRequestParams();
- if(isset($params['users']) && isset($params['ip']))
- $this->dieUsage('bkusers and bkip cannot be used together', 'usersandip');
+ if ( isset( $params['users'] ) && isset( $params['ip'] ) )
+ $this->dieUsage( 'bkusers and bkip cannot be used together', 'usersandip' );
- $prop = array_flip($params['prop']);
- $fld_id = isset($prop['id']);
- $fld_user = isset($prop['user']);
- $fld_by = isset($prop['by']);
- $fld_timestamp = isset($prop['timestamp']);
- $fld_expiry = isset($prop['expiry']);
- $fld_reason = isset($prop['reason']);
- $fld_range = isset($prop['range']);
- $fld_flags = isset($prop['flags']);
+ $prop = array_flip( $params['prop'] );
+ $fld_id = isset( $prop['id'] );
+ $fld_user = isset( $prop['user'] );
+ $fld_by = isset( $prop['by'] );
+ $fld_timestamp = isset( $prop['timestamp'] );
+ $fld_expiry = isset( $prop['expiry'] );
+ $fld_reason = isset( $prop['reason'] );
+ $fld_range = isset( $prop['range'] );
+ $fld_flags = isset( $prop['flags'] );
$result = $this->getResult();
$pageSet = $this->getPageSet();
$titles = $pageSet->getTitles();
$data = array();
- $this->addTables('ipblocks');
- if($fld_id)
- $this->addFields('ipb_id');
- if($fld_user)
- $this->addFields(array('ipb_address', 'ipb_user', 'ipb_auto'));
- if($fld_by)
+ $this->addTables( 'ipblocks' );
+ $this->addFields( 'ipb_auto' );
+
+ if ( $fld_id )
+ $this->addFields( 'ipb_id' );
+ if ( $fld_user )
+ $this->addFields( array( 'ipb_address', 'ipb_user' ) );
+ if ( $fld_by )
{
- $this->addTables('user');
- $this->addFields(array('ipb_by', 'user_name'));
- $this->addWhere('user_id = ipb_by');
+ $this->addTables( 'user' );
+ $this->addFields( array( 'ipb_by', 'user_name' ) );
+ $this->addWhere( 'user_id = ipb_by' );
}
- if($fld_timestamp)
- $this->addFields('ipb_timestamp');
- if($fld_expiry)
- $this->addFields('ipb_expiry');
- if($fld_reason)
- $this->addFields('ipb_reason');
- if($fld_range)
- $this->addFields(array('ipb_range_start', 'ipb_range_end'));
- if($fld_flags)
- $this->addFields(array('ipb_auto', 'ipb_anon_only', 'ipb_create_account', 'ipb_enable_autoblock', 'ipb_block_email', 'ipb_deleted', 'ipb_allow_usertalk'));
+ if ( $fld_timestamp )
+ $this->addFields( 'ipb_timestamp' );
+ if ( $fld_expiry )
+ $this->addFields( 'ipb_expiry' );
+ if ( $fld_reason )
+ $this->addFields( 'ipb_reason' );
+ if ( $fld_range )
+ $this->addFields( array( 'ipb_range_start', 'ipb_range_end' ) );
+ if ( $fld_flags )
+ $this->addFields( array( 'ipb_anon_only', 'ipb_create_account', 'ipb_enable_autoblock', 'ipb_block_email', 'ipb_deleted', 'ipb_allow_usertalk' ) );
- $this->addOption('LIMIT', $params['limit'] + 1);
- $this->addWhereRange('ipb_timestamp', $params['dir'], $params['start'], $params['end']);
- if(isset($params['ids']))
- $this->addWhereFld('ipb_id', $params['ids']);
- if(isset($params['users']))
+ $this->addOption( 'LIMIT', $params['limit'] + 1 );
+ $this->addWhereRange( 'ipb_timestamp', $params['dir'], $params['start'], $params['end'] );
+ if ( isset( $params['ids'] ) )
+ $this->addWhereFld( 'ipb_id', $params['ids'] );
+ if ( isset( $params['users'] ) )
{
- foreach((array)$params['users'] as $u)
- $this->prepareUsername($u);
- $this->addWhereFld('ipb_address', $this->usernames);
+ foreach ( (array)$params['users'] as $u )
+ $this->prepareUsername( $u );
+ $this->addWhereFld( 'ipb_address', $this->usernames );
+ $this->addWhereFld( 'ipb_auto', 0 );
}
- if(isset($params['ip']))
+ if ( isset( $params['ip'] ) )
{
- list($ip, $range) = IP::parseCIDR($params['ip']);
- if($ip && $range)
+ list( $ip, $range ) = IP::parseCIDR( $params['ip'] );
+ if ( $ip && $range )
{
- # We got a CIDR range
- if($range < 16)
- $this->dieUsage('CIDR ranges broader than /16 are not accepted', 'cidrtoobroad');
- $lower = wfBaseConvert($ip, 10, 16, 8, false);
- $upper = wfBaseConvert($ip + pow(2, 32 - $range) - 1, 10, 16, 8, false);
+ // We got a CIDR range
+ if ( $range < 16 )
+ $this->dieUsage( 'CIDR ranges broader than /16 are not accepted', 'cidrtoobroad' );
+ $lower = wfBaseConvert( $ip, 10, 16, 8, false );
+ $upper = wfBaseConvert( $ip + pow( 2, 32 - $range ) - 1, 10, 16, 8, false );
}
else
- $lower = $upper = IP::toHex($params['ip']);
- $prefix = substr($lower, 0, 4);
- $this->addWhere(array(
- "ipb_range_start LIKE '$prefix%'",
+ $lower = $upper = IP::toHex( $params['ip'] );
+ $prefix = substr( $lower, 0, 4 );
+
+ $db = $this->getDB();
+ $this->addWhere( array(
+ 'ipb_range_start' . $db->buildLike( $prefix, $db->anyString() ),
"ipb_range_start <= '$lower'",
- "ipb_range_end >= '$upper'"
- ));
+ "ipb_range_end >= '$upper'",
+ 'ipb_auto' => 0
+ ) );
}
- if(!$wgUser->isAllowed('hideuser'))
- $this->addWhereFld('ipb_deleted', 0);
+ if ( !$wgUser->isAllowed( 'hideuser' ) )
+ $this->addWhereFld( 'ipb_deleted', 0 );
// Purge expired entries on one in every 10 queries
- if(!mt_rand(0, 10))
+ if ( !mt_rand( 0, 10 ) )
Block::purgeExpired();
- $res = $this->select(__METHOD__);
+ $res = $this->select( __METHOD__ );
$count = 0;
- while($row = $res->fetchObject())
+ while ( $row = $res->fetchObject() )
{
- if(++$count > $params['limit'])
+ if ( ++$count > $params['limit'] )
{
// We've had enough
- $this->setContinueEnumParameter('start', wfTimestamp(TS_ISO_8601, $row->ipb_timestamp));
+ $this->setContinueEnumParameter( 'start', wfTimestamp( TS_ISO_8601, $row->ipb_timestamp ) );
break;
}
$block = array();
- if($fld_id)
+ if ( $fld_id )
$block['id'] = $row->ipb_id;
- if($fld_user && !$row->ipb_auto)
+ if ( $fld_user && !$row->ipb_auto )
$block['user'] = $row->ipb_address;
- if($fld_by)
+ if ( $fld_by )
$block['by'] = $row->user_name;
- if($fld_timestamp)
- $block['timestamp'] = wfTimestamp(TS_ISO_8601, $row->ipb_timestamp);
- if($fld_expiry)
- $block['expiry'] = Block::decodeExpiry($row->ipb_expiry, TS_ISO_8601);
- if($fld_reason)
+ if ( $fld_timestamp )
+ $block['timestamp'] = wfTimestamp( TS_ISO_8601, $row->ipb_timestamp );
+ if ( $fld_expiry )
+ $block['expiry'] = Block::decodeExpiry( $row->ipb_expiry, TS_ISO_8601 );
+ if ( $fld_reason )
$block['reason'] = $row->ipb_reason;
- if($fld_range)
+ if ( $fld_range && !$row->ipb_auto )
{
- $block['rangestart'] = IP::hexToQuad($row->ipb_range_start);
- $block['rangeend'] = IP::hexToQuad($row->ipb_range_end);
+ $block['rangestart'] = IP::hexToQuad( $row->ipb_range_start );
+ $block['rangeend'] = IP::hexToQuad( $row->ipb_range_end );
}
- if($fld_flags)
+ if ( $fld_flags )
{
// For clarity, these flags use the same names as their action=block counterparts
- if($row->ipb_auto)
+ if ( $row->ipb_auto )
$block['automatic'] = '';
- if($row->ipb_anon_only)
+ if ( $row->ipb_anon_only )
$block['anononly'] = '';
- if($row->ipb_create_account)
+ if ( $row->ipb_create_account )
$block['nocreate'] = '';
- if($row->ipb_enable_autoblock)
+ if ( $row->ipb_enable_autoblock )
$block['autoblock'] = '';
- if($row->ipb_block_email)
+ if ( $row->ipb_block_email )
$block['noemail'] = '';
- if($row->ipb_deleted)
+ if ( $row->ipb_deleted )
$block['hidden'] = '';
- if($row->ipb_allow_usertalk)
+ if ( $row->ipb_allow_usertalk )
$block['allowusertalk'] = '';
}
- $fit = $result->addValue(array('query', $this->getModuleName()), null, $block);
- if(!$fit)
+ $fit = $result->addValue( array( 'query', $this->getModuleName() ), null, $block );
+ if ( !$fit )
{
- $this->setContinueEnumParameter('start', wfTimestamp(TS_ISO_8601, $row->ipb_timestamp));
+ $this->setContinueEnumParameter( 'start', wfTimestamp( TS_ISO_8601, $row->ipb_timestamp ) );
break;
}
}
- $result->setIndexedTagName_internal(array('query', $this->getModuleName()), 'block');
+ $result->setIndexedTagName_internal( array( 'query', $this->getModuleName() ), 'block' );
}
- protected function prepareUsername($user)
+ protected function prepareUsername( $user )
{
- if(!$user)
- $this->dieUsage('User parameter may not be empty', 'param_user');
- $name = User::isIP($user)
+ if ( !$user )
+ $this->dieUsage( 'User parameter may not be empty', 'param_user' );
+ $name = User::isIP( $user )
? $user
- : User::getCanonicalName($user, 'valid');
- if($name === false)
- $this->dieUsage("User name {$user} is not valid", 'param_user');
+ : User::getCanonicalName( $user, 'valid' );
+ if ( $name === false )
+ $this->dieUsage( "User name {$user} is not valid", 'param_user' );
$this->usernames[] = $name;
}
@@ -246,7 +252,7 @@ class ApiQueryBlocks extends ApiQueryBase {
'ids' => 'Pipe-separated list of block IDs to list (optional)',
'users' => 'Pipe-separated list of users to search for (optional)',
'ip' => array( 'Get all blocks applying to this IP or CIDR range, including range blocks.',
- 'Cannot be used together with bkusers. CIDR ranges broader than /16 are not accepted.'),
+ 'Cannot be used together with bkusers. CIDR ranges broader than /16 are not accepted.' ),
'limit' => 'The maximum amount of blocks to list',
'prop' => 'Which properties to get',
);
@@ -255,6 +261,15 @@ class ApiQueryBlocks extends ApiQueryBase {
public function getDescription() {
return 'List all blocked users and IP addresses.';
}
+
+ public function getPossibleErrors() {
+ return array_merge( parent::getPossibleErrors(), array(
+ array( 'code' => 'usersandip', 'info' => 'bkusers and bkip cannot be used together' ),
+ array( 'code' => 'cidrtoobroad', 'info' => 'CIDR ranges broader than /16 are not accepted' ),
+ array( 'code' => 'param_user', 'info' => 'User parameter may not be empty' ),
+ array( 'code' => 'param_user', 'info' => 'User name user is not valid' ),
+ ) );
+ }
protected function getExamples() {
return array ( 'api.php?action=query&list=blocks',
@@ -263,6 +278,6 @@ class ApiQueryBlocks extends ApiQueryBase {
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiQueryBlocks.php 69579 2010-07-20 02:49:55Z tstarling $';
+ return __CLASS__ . ': $Id: ApiQueryBlocks.php 69578 2010-07-20 02:46:20Z tstarling $';
}
} \ No newline at end of file
diff --git a/includes/api/ApiQueryCategories.php b/includes/api/ApiQueryCategories.php
index 15e1ce13..03135052 100644
--- a/includes/api/ApiQueryCategories.php
+++ b/includes/api/ApiQueryCategories.php
@@ -23,9 +23,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ("ApiQueryBase.php");
+ require_once ( "ApiQueryBase.php" );
}
/**
@@ -35,8 +35,8 @@ if (!defined('MEDIAWIKI')) {
*/
class ApiQueryCategories extends ApiQueryGeneratorBase {
- public function __construct($query, $moduleName) {
- parent :: __construct($query, $moduleName, 'cl');
+ public function __construct( $query, $moduleName ) {
+ parent :: __construct( $query, $moduleName, 'cl' );
}
public function execute() {
@@ -47,144 +47,134 @@ class ApiQueryCategories extends ApiQueryGeneratorBase {
return 'public';
}
- public function executeGenerator($resultPageSet) {
- $this->run($resultPageSet);
+ public function executeGenerator( $resultPageSet ) {
+ $this->run( $resultPageSet );
}
- private function run($resultPageSet = null) {
+ private function run( $resultPageSet = null ) {
- if ($this->getPageSet()->getGoodTitleCount() == 0)
+ if ( $this->getPageSet()->getGoodTitleCount() == 0 )
return; // nothing to do
$params = $this->extractRequestParams();
- $prop = $params['prop'];
- $show = array_flip((array)$params['show']);
+ $prop = array_flip( (array)$params['prop'] );
+ $show = array_flip( (array)$params['show'] );
- $this->addFields(array (
+ $this->addFields( array (
'cl_from',
'cl_to'
- ));
-
- $fld_sortkey = $fld_timestamp = false;
- if (!is_null($prop)) {
- foreach($prop as $p) {
- switch ($p) {
- case 'sortkey':
- $this->addFields('cl_sortkey');
- $fld_sortkey = true;
- break;
- case 'timestamp':
- $this->addFields('cl_timestamp');
- $fld_timestamp = true;
- break;
- default :
- ApiBase :: dieDebug(__METHOD__, "Unknown prop=$p");
- }
- }
- }
+ ) );
+
+ $this->addFieldsIf( 'cl_sortkey', isset( $prop['sortkey'] ) );
+ $this->addFieldsIf( 'cl_timestamp', isset( $prop['timestamp'] ) );
- $this->addTables('categorylinks');
- $this->addWhereFld('cl_from', array_keys($this->getPageSet()->getGoodTitles()));
- if(!is_null($params['categories']))
+ $this->addTables( 'categorylinks' );
+ $this->addWhereFld( 'cl_from', array_keys( $this->getPageSet()->getGoodTitles() ) );
+ if ( !is_null( $params['categories'] ) )
{
$cats = array();
- foreach($params['categories'] as $cat)
+ foreach ( $params['categories'] as $cat )
{
- $title = Title::newFromText($cat);
- if(!$title || $title->getNamespace() != NS_CATEGORY)
- $this->setWarning("``$cat'' is not a category");
+ $title = Title::newFromText( $cat );
+ if ( !$title || $title->getNamespace() != NS_CATEGORY )
+ $this->setWarning( "``$cat'' is not a category" );
else
$cats[] = $title->getDBkey();
}
- $this->addWhereFld('cl_to', $cats);
+ $this->addWhereFld( 'cl_to', $cats );
}
- if(!is_null($params['continue'])) {
- $cont = explode('|', $params['continue']);
- if(count($cont) != 2)
- $this->dieUsage("Invalid continue param. You should pass the " .
- "original value returned by the previous query", "_badcontinue");
- $clfrom = intval($cont[0]);
- $clto = $this->getDB()->strencode($this->titleToKey($cont[1]));
- $this->addWhere("cl_from > $clfrom OR ".
- "(cl_from = $clfrom AND ".
- "cl_to >= '$clto')");
+
+ if ( !is_null( $params['continue'] ) ) {
+ $cont = explode( '|', $params['continue'] );
+ if ( count( $cont ) != 2 )
+ $this->dieUsage( "Invalid continue param. You should pass the " .
+ "original value returned by the previous query", "_badcontinue" );
+ $clfrom = intval( $cont[0] );
+ $clto = $this->getDB()->strencode( $this->titleToKey( $cont[1] ) );
+ $this->addWhere( "cl_from > $clfrom OR " .
+ "(cl_from = $clfrom AND " .
+ "cl_to >= '$clto')" );
}
- if(isset($show['hidden']) && isset($show['!hidden']))
- $this->dieUsage("Incorrect parameter - mutually exclusive values may not be supplied", 'show');
- if(isset($show['hidden']) || isset($show['!hidden']))
+
+ if ( isset( $show['hidden'] ) && isset( $show['!hidden'] ) )
+ $this->dieUsageMsg( array( 'show' ) );
+ if ( isset( $show['hidden'] ) || isset( $show['!hidden'] ) || isset( $prop['hidden'] ) )
{
- $this->addOption('STRAIGHT_JOIN');
- $this->addTables(array('page', 'page_props'));
- $this->addJoinConds(array(
- 'page' => array('LEFT JOIN', array(
+ $this->addOption( 'STRAIGHT_JOIN' );
+ $this->addTables( array( 'page', 'page_props' ) );
+ $this->addFieldsIf( 'pp_propname', isset( $prop['hidden'] ) );
+ $this->addJoinConds( array(
+ 'page' => array( 'LEFT JOIN', array(
'page_namespace' => NS_CATEGORY,
- 'page_title = cl_to')),
- 'page_props' => array('LEFT JOIN', array(
+ 'page_title = cl_to' ) ),
+ 'page_props' => array( 'LEFT JOIN', array(
'pp_page=page_id',
- 'pp_propname' => 'hiddencat'))
- ));
- if(isset($show['hidden']))
- $this->addWhere(array('pp_propname IS NOT NULL'));
- else
- $this->addWhere(array('pp_propname IS NULL'));
+ 'pp_propname' => 'hiddencat' ) )
+ ) );
+ if ( isset( $show['hidden'] ) )
+ $this->addWhere( array( 'pp_propname IS NOT NULL' ) );
+ else if ( isset( $show['!hidden'] ) )
+ $this->addWhere( array( 'pp_propname IS NULL' ) );
}
- $this->addOption('USE INDEX', array('categorylinks' => 'cl_from'));
- # Don't order by cl_from if it's constant in the WHERE clause
- if(count($this->getPageSet()->getGoodTitles()) == 1)
- $this->addOption('ORDER BY', 'cl_to');
+ $this->addOption( 'USE INDEX', array( 'categorylinks' => 'cl_from' ) );
+ // Don't order by cl_from if it's constant in the WHERE clause
+ if ( count( $this->getPageSet()->getGoodTitles() ) == 1 )
+ $this->addOption( 'ORDER BY', 'cl_to' );
else
- $this->addOption('ORDER BY', "cl_from, cl_to");
+ $this->addOption( 'ORDER BY', "cl_from, cl_to" );
$db = $this->getDB();
- $res = $this->select(__METHOD__);
+ $res = $this->select( __METHOD__ );
- if (is_null($resultPageSet)) {
+ if ( is_null( $resultPageSet ) ) {
$count = 0;
- while ($row = $db->fetchObject($res)) {
- if (++$count > $params['limit']) {
+ while ( $row = $db->fetchObject( $res ) ) {
+ if ( ++$count > $params['limit'] ) {
// We've reached the one extra which shows that
// there are additional pages to be had. Stop here...
- $this->setContinueEnumParameter('continue', $row->cl_from .
- '|' . $this->keyToTitle($row->cl_to));
+ $this->setContinueEnumParameter( 'continue', $row->cl_from .
+ '|' . $this->keyToTitle( $row->cl_to ) );
break;
}
- $title = Title :: makeTitle(NS_CATEGORY, $row->cl_to);
+ $title = Title :: makeTitle( NS_CATEGORY, $row->cl_to );
$vals = array();
- ApiQueryBase :: addTitleInfo($vals, $title);
- if ($fld_sortkey)
+ ApiQueryBase :: addTitleInfo( $vals, $title );
+ if ( isset( $prop['sortkey'] ) )
$vals['sortkey'] = $row->cl_sortkey;
- if ($fld_timestamp)
- $vals['timestamp'] = wfTimestamp(TS_ISO_8601, $row->cl_timestamp);
+ if ( isset( $prop['timestamp'] ) )
+ $vals['timestamp'] = wfTimestamp( TS_ISO_8601, $row->cl_timestamp );
+ if ( isset( $prop['hidden'] ) && !is_null( $row->pp_propname ) )
+ $vals['hidden'] = '';
- $fit = $this->addPageSubItem($row->cl_from, $vals);
- if(!$fit)
+ $fit = $this->addPageSubItem( $row->cl_from, $vals );
+ if ( !$fit )
{
- $this->setContinueEnumParameter('continue', $row->cl_from .
- '|' . $this->keyToTitle($row->cl_to));
+ $this->setContinueEnumParameter( 'continue', $row->cl_from .
+ '|' . $this->keyToTitle( $row->cl_to ) );
break;
}
}
} else {
$titles = array();
- while ($row = $db->fetchObject($res)) {
- if (++$count > $params['limit']) {
+ while ( $row = $db->fetchObject( $res ) ) {
+ if ( ++$count > $params['limit'] ) {
// We've reached the one extra which shows that
// there are additional pages to be had. Stop here...
- $this->setContinueEnumParameter('continue', $row->cl_from .
- '|' . $this->keyToTitle($row->cl_to));
+ $this->setContinueEnumParameter( 'continue', $row->cl_from .
+ '|' . $this->keyToTitle( $row->cl_to ) );
break;
}
- $titles[] = Title :: makeTitle(NS_CATEGORY, $row->cl_to);
+ $titles[] = Title :: makeTitle( NS_CATEGORY, $row->cl_to );
}
- $resultPageSet->populateFromTitles($titles);
+ $resultPageSet->populateFromTitles( $titles );
}
- $db->freeResult($res);
+ $db->freeResult( $res );
}
public function getAllowedParams() {
@@ -194,6 +184,7 @@ class ApiQueryCategories extends ApiQueryGeneratorBase {
ApiBase :: PARAM_TYPE => array (
'sortkey',
'timestamp',
+ 'hidden',
)
),
'show' => array(
@@ -230,6 +221,12 @@ class ApiQueryCategories extends ApiQueryGeneratorBase {
public function getDescription() {
return 'List all categories the page(s) belong to';
}
+
+ public function getPossibleErrors() {
+ return array_merge( parent::getPossibleErrors(), array(
+ array( 'show' ),
+ ) );
+ }
protected function getExamples() {
return array (
@@ -241,6 +238,6 @@ class ApiQueryCategories extends ApiQueryGeneratorBase {
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiQueryCategories.php 69986 2010-07-27 03:57:39Z tstarling $';
+ return __CLASS__ . ': $Id: ApiQueryCategories.php 69932 2010-07-26 08:03:21Z tstarling $';
}
}
diff --git a/includes/api/ApiQueryCategoryInfo.php b/includes/api/ApiQueryCategoryInfo.php
index f3d45ccf..4df2f181 100644
--- a/includes/api/ApiQueryCategoryInfo.php
+++ b/includes/api/ApiQueryCategoryInfo.php
@@ -23,9 +23,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ("ApiQueryBase.php");
+ require_once ( "ApiQueryBase.php" );
}
/**
@@ -35,8 +35,8 @@ if (!defined('MEDIAWIKI')) {
*/
class ApiQueryCategoryInfo extends ApiQueryBase {
- public function __construct($query, $moduleName) {
- parent :: __construct($query, $moduleName, 'ci');
+ public function __construct( $query, $moduleName ) {
+ parent :: __construct( $query, $moduleName, 'ci' );
}
public function execute() {
@@ -50,51 +50,53 @@ class ApiQueryCategoryInfo extends ApiQueryBase {
$titles = $this->getPageSet()->getGoodTitles() +
$this->getPageSet()->getMissingTitles();
$cattitles = array();
- foreach($categories as $c)
+ foreach ( $categories as $c )
{
$t = $titles[$c];
- $cattitles[$c] = $t->getDBKey();
+ $cattitles[$c] = $t->getDBkey();
}
- $this->addTables(array('category', 'page', 'page_props'));
- $this->addJoinConds(array(
- 'page' => array('LEFT JOIN', array(
+ $this->addTables( array( 'category', 'page', 'page_props' ) );
+ $this->addJoinConds( array(
+ 'page' => array( 'LEFT JOIN', array(
'page_namespace' => NS_CATEGORY,
- 'page_title=cat_title')),
- 'page_props' => array('LEFT JOIN', array(
+ 'page_title=cat_title' ) ),
+ 'page_props' => array( 'LEFT JOIN', array(
'pp_page=page_id',
- 'pp_propname' => 'hiddencat')),
- ));
- $this->addFields(array('cat_title', 'cat_pages', 'cat_subcats', 'cat_files', 'pp_propname AS cat_hidden'));
- $this->addWhere(array('cat_title' => $cattitles));
- if(!is_null($params['continue']))
+ 'pp_propname' => 'hiddencat' ) ),
+ ) );
+
+ $this->addFields( array( 'cat_title', 'cat_pages', 'cat_subcats', 'cat_files', 'pp_propname AS cat_hidden' ) );
+ $this->addWhere( array( 'cat_title' => $cattitles ) );
+
+ if ( !is_null( $params['continue'] ) )
{
- $title = $this->getDB()->addQuotes($params['continue']);
- $this->addWhere("cat_title >= $title");
- }
- $this->addOption('ORDER BY', 'cat_title');
+ $title = $this->getDB()->addQuotes( $params['continue'] );
+ $this->addWhere( "cat_title >= $title" );
+ }
+ $this->addOption( 'ORDER BY', 'cat_title' );
$db = $this->getDB();
- $res = $this->select(__METHOD__);
+ $res = $this->select( __METHOD__ );
- $catids = array_flip($cattitles);
- while($row = $db->fetchObject($res))
+ $catids = array_flip( $cattitles );
+ while ( $row = $db->fetchObject( $res ) )
{
$vals = array();
- $vals['size'] = intval($row->cat_pages);
+ $vals['size'] = intval( $row->cat_pages );
$vals['pages'] = $row->cat_pages - $row->cat_subcats - $row->cat_files;
- $vals['files'] = intval($row->cat_files);
- $vals['subcats'] = intval($row->cat_subcats);
- if($row->cat_hidden)
+ $vals['files'] = intval( $row->cat_files );
+ $vals['subcats'] = intval( $row->cat_subcats );
+ if ( $row->cat_hidden )
$vals['hidden'] = '';
- $fit = $this->addPageSubItems($catids[$row->cat_title], $vals);
- if(!$fit)
+ $fit = $this->addPageSubItems( $catids[$row->cat_title], $vals );
+ if ( !$fit )
{
- $this->setContinueEnumParameter('continue', $row->cat_title);
+ $this->setContinueEnumParameter( 'continue', $row->cat_title );
break;
}
}
- $db->freeResult($res);
+ $db->freeResult( $res );
}
public function getCacheMode( $params ) {
@@ -122,6 +124,6 @@ class ApiQueryCategoryInfo extends ApiQueryBase {
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiQueryCategoryInfo.php 69986 2010-07-27 03:57:39Z tstarling $';
+ return __CLASS__ . ': $Id: ApiQueryCategoryInfo.php 69932 2010-07-26 08:03:21Z tstarling $';
}
}
diff --git a/includes/api/ApiQueryCategoryMembers.php b/includes/api/ApiQueryCategoryMembers.php
index 45461abd..107f5049 100644
--- a/includes/api/ApiQueryCategoryMembers.php
+++ b/includes/api/ApiQueryCategoryMembers.php
@@ -23,9 +23,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ("ApiQueryBase.php");
+ require_once ( "ApiQueryBase.php" );
}
/**
@@ -35,8 +35,8 @@ if (!defined('MEDIAWIKI')) {
*/
class ApiQueryCategoryMembers extends ApiQueryGeneratorBase {
- public function __construct($query, $moduleName) {
- parent :: __construct($query, $moduleName, 'cm');
+ public function __construct( $query, $moduleName ) {
+ parent :: __construct( $query, $moduleName, 'cm' );
}
public function execute() {
@@ -47,113 +47,128 @@ class ApiQueryCategoryMembers extends ApiQueryGeneratorBase {
return 'public';
}
- public function executeGenerator($resultPageSet) {
- $this->run($resultPageSet);
+ public function executeGenerator( $resultPageSet ) {
+ $this->run( $resultPageSet );
}
- private function run($resultPageSet = null) {
+ private function run( $resultPageSet = null ) {
$params = $this->extractRequestParams();
- if ( !isset($params['title']) || is_null($params['title']) )
- $this->dieUsage("The cmtitle parameter is required", 'notitle');
- $categoryTitle = Title::newFromText($params['title']);
+ if ( !isset( $params['title'] ) || is_null( $params['title'] ) )
+ $this->dieUsage( "The cmtitle parameter is required", 'notitle' );
+ $categoryTitle = Title::newFromText( $params['title'] );
if ( is_null( $categoryTitle ) || $categoryTitle->getNamespace() != NS_CATEGORY )
- $this->dieUsage("The category name you entered is not valid", 'invalidcategory');
+ $this->dieUsage( "The category name you entered is not valid", 'invalidcategory' );
- $prop = array_flip($params['prop']);
- $fld_ids = isset($prop['ids']);
- $fld_title = isset($prop['title']);
- $fld_sortkey = isset($prop['sortkey']);
- $fld_timestamp = isset($prop['timestamp']);
+ $prop = array_flip( $params['prop'] );
+ $fld_ids = isset( $prop['ids'] );
+ $fld_title = isset( $prop['title'] );
+ $fld_sortkey = isset( $prop['sortkey'] );
+ $fld_timestamp = isset( $prop['timestamp'] );
- if (is_null($resultPageSet)) {
- $this->addFields(array('cl_from', 'cl_sortkey', 'page_namespace', 'page_title'));
- $this->addFieldsIf('page_id', $fld_ids);
+ if ( is_null( $resultPageSet ) ) {
+ $this->addFields( array( 'cl_from', 'cl_sortkey', 'page_namespace', 'page_title' ) );
+ $this->addFieldsIf( 'page_id', $fld_ids );
} else {
- $this->addFields($resultPageSet->getPageTableFields()); // will include page_ id, ns, title
- $this->addFields(array('cl_from', 'cl_sortkey'));
+ $this->addFields( $resultPageSet->getPageTableFields() ); // will include page_ id, ns, title
+ $this->addFields( array( 'cl_from', 'cl_sortkey' ) );
}
- $this->addFieldsIf('cl_timestamp', $fld_timestamp || $params['sort'] == 'timestamp');
- $this->addTables(array('page','categorylinks')); // must be in this order for 'USE INDEX'
+ $this->addFieldsIf( 'cl_timestamp', $fld_timestamp || $params['sort'] == 'timestamp' );
+ $this->addTables( array( 'page', 'categorylinks' ) ); // must be in this order for 'USE INDEX'
// Not needed after bug 10280 is applied to servers
- if($params['sort'] == 'timestamp')
- $this->addOption('USE INDEX', 'cl_timestamp');
+ if ( $params['sort'] == 'timestamp' )
+ $this->addOption( 'USE INDEX', 'cl_timestamp' );
else
- $this->addOption('USE INDEX', 'cl_sortkey');
-
- $this->addWhere('cl_from=page_id');
- $this->setContinuation($params['continue'], $params['dir']);
- $this->addWhereFld('cl_to', $categoryTitle->getDBkey());
- $this->addWhereFld('page_namespace', $params['namespace']);
- if($params['sort'] == 'timestamp')
- $this->addWhereRange('cl_timestamp', ($params['dir'] == 'asc' ? 'newer' : 'older'), $params['start'], $params['end']);
+ $this->addOption( 'USE INDEX', 'cl_sortkey' );
+
+ $this->addWhere( 'cl_from=page_id' );
+ $this->setContinuation( $params['continue'], $params['dir'] );
+ $this->addWhereFld( 'cl_to', $categoryTitle->getDBkey() );
+ // Scanning large datasets for rare categories sucks, and I already told
+ // how to have efficient subcategory access :-) ~~~~ (oh well, domas)
+ global $wgMiserMode;
+ $miser_ns = array();
+ if ( $wgMiserMode ) {
+ $miser_ns = $params['namespace'];
+ } else {
+ $this->addWhereFld( 'page_namespace', $params['namespace'] );
+ }
+ if ( $params['sort'] == 'timestamp' )
+ $this->addWhereRange( 'cl_timestamp', ( $params['dir'] == 'asc' ? 'newer' : 'older' ), $params['start'], $params['end'] );
else
{
- $this->addWhereRange('cl_sortkey', ($params['dir'] == 'asc' ? 'newer' : 'older'), $params['startsortkey'], $params['endsortkey']);
- $this->addWhereRange('cl_from', ($params['dir'] == 'asc' ? 'newer' : 'older'), null, null);
+ $this->addWhereRange( 'cl_sortkey', ( $params['dir'] == 'asc' ? 'newer' : 'older' ), $params['startsortkey'], $params['endsortkey'] );
+ $this->addWhereRange( 'cl_from', ( $params['dir'] == 'asc' ? 'newer' : 'older' ), null, null );
}
$limit = $params['limit'];
- $this->addOption('LIMIT', $limit +1);
+ $this->addOption( 'LIMIT', $limit + 1 );
$db = $this->getDB();
$data = array ();
$count = 0;
$lastSortKey = null;
- $res = $this->select(__METHOD__);
- while ($row = $db->fetchObject($res)) {
- if (++ $count > $limit) {
+ $res = $this->select( __METHOD__ );
+ while ( $row = $db->fetchObject( $res ) ) {
+ if ( ++ $count > $limit ) {
// We've reached the one extra which shows that there are additional pages to be had. Stop here...
// TODO: Security issue - if the user has no right to view next title, it will still be shown
- if ($params['sort'] == 'timestamp')
- $this->setContinueEnumParameter('start', wfTimestamp(TS_ISO_8601, $row->cl_timestamp));
+ if ( $params['sort'] == 'timestamp' )
+ $this->setContinueEnumParameter( 'start', wfTimestamp( TS_ISO_8601, $row->cl_timestamp ) );
else
- $this->setContinueEnumParameter('continue', $this->getContinueStr($row, $lastSortKey));
+ $this->setContinueEnumParameter( 'continue', $this->getContinueStr( $row, $lastSortKey ) );
break;
}
- if (is_null($resultPageSet)) {
+ // Since domas won't tell anyone what he told long ago, apply
+ // cmnamespace here. This means the query may return 0 actual
+ // results, but on the other hand it could save returning 5000
+ // useless results to the client. ~~~~
+ if ( count( $miser_ns ) && !in_array( $row->page_namespace, $miser_ns ) )
+ continue;
+
+ if ( is_null( $resultPageSet ) ) {
$vals = array();
- if ($fld_ids)
- $vals['pageid'] = intval($row->page_id);
- if ($fld_title) {
- $title = Title :: makeTitle($row->page_namespace, $row->page_title);
- ApiQueryBase::addTitleInfo($vals, $title);
+ if ( $fld_ids )
+ $vals['pageid'] = intval( $row->page_id );
+ if ( $fld_title ) {
+ $title = Title :: makeTitle( $row->page_namespace, $row->page_title );
+ ApiQueryBase::addTitleInfo( $vals, $title );
}
- if ($fld_sortkey)
+ if ( $fld_sortkey )
$vals['sortkey'] = $row->cl_sortkey;
- if ($fld_timestamp)
- $vals['timestamp'] = wfTimestamp(TS_ISO_8601, $row->cl_timestamp);
- $fit = $this->getResult()->addValue(array('query', $this->getModuleName()),
- null, $vals);
- if(!$fit)
+ if ( $fld_timestamp )
+ $vals['timestamp'] = wfTimestamp( TS_ISO_8601, $row->cl_timestamp );
+ $fit = $this->getResult()->addValue( array( 'query', $this->getModuleName() ),
+ null, $vals );
+ if ( !$fit )
{
- if ($params['sort'] == 'timestamp')
- $this->setContinueEnumParameter('start', wfTimestamp(TS_ISO_8601, $row->cl_timestamp));
+ if ( $params['sort'] == 'timestamp' )
+ $this->setContinueEnumParameter( 'start', wfTimestamp( TS_ISO_8601, $row->cl_timestamp ) );
else
- $this->setContinueEnumParameter('continue', $this->getContinueStr($row, $lastSortKey));
+ $this->setContinueEnumParameter( 'continue', $this->getContinueStr( $row, $lastSortKey ) );
break;
}
} else {
- $resultPageSet->processDbRow($row);
+ $resultPageSet->processDbRow( $row );
}
$lastSortKey = $row->cl_sortkey; // detect duplicate sortkeys
}
- $db->freeResult($res);
+ $db->freeResult( $res );
- if (is_null($resultPageSet)) {
+ if ( is_null( $resultPageSet ) ) {
$this->getResult()->setIndexedTagName_internal(
- array('query', $this->getModuleName()), 'cm');
+ array( 'query', $this->getModuleName() ), 'cm' );
}
}
- private function getContinueStr($row, $lastSortKey) {
+ private function getContinueStr( $row, $lastSortKey ) {
$ret = $row->cl_sortkey . '|';
- if ($row->cl_sortkey == $lastSortKey) // duplicate sort key, add cl_from
+ if ( $row->cl_sortkey == $lastSortKey ) // duplicate sort key, add cl_from
$ret .= $row->cl_from;
return $ret;
}
@@ -161,24 +176,24 @@ class ApiQueryCategoryMembers extends ApiQueryGeneratorBase {
/**
* Add DB WHERE clause to continue previous query based on 'continue' parameter
*/
- private function setContinuation($continue, $dir) {
- if (is_null($continue))
+ private function setContinuation( $continue, $dir ) {
+ if ( is_null( $continue ) )
return; // This is not a continuation request
- $pos = strrpos($continue, '|');
- $sortkey = substr($continue, 0, $pos);
- $fromstr = substr($continue, $pos + 1);
- $from = intval($fromstr);
+ $pos = strrpos( $continue, '|' );
+ $sortkey = substr( $continue, 0, $pos );
+ $fromstr = substr( $continue, $pos + 1 );
+ $from = intval( $fromstr );
- if ($from == 0 && strlen($fromstr) > 0)
- $this->dieUsage("Invalid continue param. You should pass the original value returned by the previous query", "badcontinue");
+ if ( $from == 0 && strlen( $fromstr ) > 0 )
+ $this->dieUsage( "Invalid continue param. You should pass the original value returned by the previous query", "badcontinue" );
- $encSortKey = $this->getDB()->addQuotes($sortkey);
- $encFrom = $this->getDB()->addQuotes($from);
+ $encSortKey = $this->getDB()->addQuotes( $sortkey );
+ $encFrom = $this->getDB()->addQuotes( $from );
- $op = ($dir == 'desc' ? '<' : '>');
+ $op = ( $dir == 'desc' ? '<' : '>' );
- if ($from != 0) {
+ if ( $from != 0 ) {
// Duplicate sort key continue
$this->addWhere( "cl_sortkey$op$encSortKey OR (cl_sortkey=$encSortKey AND cl_from$op=$encFrom)" );
} else {
@@ -237,7 +252,8 @@ class ApiQueryCategoryMembers extends ApiQueryGeneratorBase {
}
public function getParamDescription() {
- return array (
+ global $wgMiserMode;
+ $desc = array (
'title' => 'Which category to enumerate (required). Must include Category: prefix',
'prop' => 'What pieces of information to include',
'namespace' => 'Only include pages in these namespaces',
@@ -250,11 +266,27 @@ class ApiQueryCategoryMembers extends ApiQueryGeneratorBase {
'continue' => 'For large categories, give the value retured from previous query',
'limit' => 'The maximum number of pages to return.',
);
+ if ( $wgMiserMode ) {
+ $desc['namespace'] = array(
+ $desc['namespace'],
+ 'NOTE: Due to $wgMiserMode, using this may result in fewer than "limit" results',
+ 'returned before continuing; in extreme cases, zero results may be returned.',
+ );
+ }
+ return $desc;
}
public function getDescription() {
return 'List all pages in a given category';
}
+
+ public function getPossibleErrors() {
+ return array_merge( parent::getPossibleErrors(), array(
+ array( 'code' => 'notitle', 'info' => 'The cmtitle parameter is required' ),
+ array( 'code' => 'invalidcategory', 'info' => 'The category name you entered is not valid' ),
+ array( 'code' => 'badcontinue', 'info' => 'Invalid continue param. You should pass the original value returned by the previous query' ),
+ ) );
+ }
protected function getExamples() {
return array (
@@ -266,6 +298,6 @@ class ApiQueryCategoryMembers extends ApiQueryGeneratorBase {
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiQueryCategoryMembers.php 69986 2010-07-27 03:57:39Z tstarling $';
+ return __CLASS__ . ': $Id: ApiQueryCategoryMembers.php 69932 2010-07-26 08:03:21Z tstarling $';
}
}
diff --git a/includes/api/ApiQueryDeletedrevs.php b/includes/api/ApiQueryDeletedrevs.php
index bd767b1b..b26c7051 100644
--- a/includes/api/ApiQueryDeletedrevs.php
+++ b/includes/api/ApiQueryDeletedrevs.php
@@ -23,9 +23,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ('ApiQueryBase.php');
+ require_once ( 'ApiQueryBase.php' );
}
/**
@@ -35,27 +35,28 @@ if (!defined('MEDIAWIKI')) {
*/
class ApiQueryDeletedrevs extends ApiQueryBase {
- public function __construct($query, $moduleName) {
- parent :: __construct($query, $moduleName, 'dr');
+ public function __construct( $query, $moduleName ) {
+ parent :: __construct( $query, $moduleName, 'dr' );
}
public function execute() {
global $wgUser;
// Before doing anything at all, let's check permissions
- if(!$wgUser->isAllowed('deletedhistory'))
- $this->dieUsage('You don\'t have permission to view deleted revision information', 'permissiondenied');
+ if ( !$wgUser->isAllowed( 'deletedhistory' ) )
+ $this->dieUsage( 'You don\'t have permission to view deleted revision information', 'permissiondenied' );
$db = $this->getDB();
- $params = $this->extractRequestParams(false);
- $prop = array_flip($params['prop']);
- $fld_revid = isset($prop['revid']);
- $fld_user = isset($prop['user']);
- $fld_comment = isset($prop['comment']);
- $fld_minor = isset($prop['minor']);
- $fld_len = isset($prop['len']);
- $fld_content = isset($prop['content']);
- $fld_token = isset($prop['token']);
+ $params = $this->extractRequestParams( false );
+ $prop = array_flip( $params['prop'] );
+ $fld_revid = isset( $prop['revid'] );
+ $fld_user = isset( $prop['user'] );
+ $fld_comment = isset( $prop['comment'] );
+ $fld_parsedcomment = isset ( $prop['parsedcomment'] );
+ $fld_minor = isset( $prop['minor'] );
+ $fld_len = isset( $prop['len'] );
+ $fld_content = isset( $prop['content'] );
+ $fld_token = isset( $prop['token'] );
$result = $this->getResult();
$pageSet = $this->getPageSet();
@@ -67,36 +68,35 @@ class ApiQueryDeletedrevs extends ApiQueryBase {
// 'user': List deleted revs by a certain user
// 'all': List all deleted revs
$mode = 'all';
- if(count($titles) > 0)
+ if ( count( $titles ) > 0 )
$mode = 'revs';
- else if(!is_null($params['user']))
+ else if ( !is_null( $params['user'] ) )
$mode = 'user';
- if(!is_null($params['user']) && !is_null($params['excludeuser']))
- $this->dieUsage('user and excludeuser cannot be used together', 'badparams');
+ if ( !is_null( $params['user'] ) && !is_null( $params['excludeuser'] ) )
+ $this->dieUsage( 'user and excludeuser cannot be used together', 'badparams' );
- $this->addTables('archive');
- $this->addWhere('ar_deleted = 0');
- $this->addFields(array('ar_title', 'ar_namespace', 'ar_timestamp'));
- if($fld_revid)
- $this->addFields('ar_rev_id');
- if($fld_user)
- $this->addFields('ar_user_text');
- if($fld_comment)
- $this->addFields('ar_comment');
- if($fld_minor)
- $this->addFields('ar_minor_edit');
- if($fld_len)
- $this->addFields('ar_len');
- if($fld_content)
- {
- $this->addTables('text');
- $this->addFields(array('ar_text', 'ar_text_id', 'old_text', 'old_flags'));
- $this->addWhere('ar_text_id = old_id');
+ $this->addTables( 'archive' );
+ $this->addWhere( 'ar_deleted = 0' );
+ $this->addFields( array( 'ar_title', 'ar_namespace', 'ar_timestamp' ) );
+ if ( $fld_revid )
+ $this->addFields( 'ar_rev_id' );
+ if ( $fld_user )
+ $this->addFields( 'ar_user_text' );
+ if ( $fld_comment || $fld_parsedcomment )
+ $this->addFields( 'ar_comment' );
+ if ( $fld_minor )
+ $this->addFields( 'ar_minor_edit' );
+ if ( $fld_len )
+ $this->addFields( 'ar_len' );
+ if ( $fld_content ) {
+ $this->addTables( 'text' );
+ $this->addFields( array( 'ar_text', 'ar_text_id', 'old_text', 'old_flags' ) );
+ $this->addWhere( 'ar_text_id = old_id' );
// This also means stricter restrictions
- if(!$wgUser->isAllowed('undelete'))
- $this->dieUsage('You don\'t have permission to view deleted revision content', 'permissiondenied');
+ if ( !$wgUser->isAllowed( 'undelete' ) )
+ $this->dieUsage( 'You don\'t have permission to view deleted revision content', 'permissiondenied' );
}
// Check limits
$userMax = $fld_content ? ApiBase :: LIMIT_SML1 : ApiBase :: LIMIT_BIG1;
@@ -104,143 +104,136 @@ class ApiQueryDeletedrevs extends ApiQueryBase {
$limit = $params['limit'];
- if( $limit == 'max' ) {
+ if ( $limit == 'max' ) {
$limit = $this->getMain()->canApiHighLimits() ? $botMax : $userMax;
$this->getResult()->addValue( 'limits', $this->getModuleName(), $limit );
}
- $this->validateLimit('limit', $limit, 1, $userMax, $botMax);
+ $this->validateLimit( 'limit', $limit, 1, $userMax, $botMax );
- if($fld_token)
+ if ( $fld_token )
// Undelete tokens are identical for all pages, so we cache one here
$token = $wgUser->editToken();
// We need a custom WHERE clause that matches all titles.
- if($mode == 'revs')
- {
- $lb = new LinkBatch($titles);
- $where = $lb->constructSet('ar', $db);
- $this->addWhere($where);
- }
- elseif($mode == 'all')
- {
- $this->addWhereFld('ar_namespace', $params['namespace']);
- if(!is_null($params['from']))
+ if ( $mode == 'revs' ) {
+ $lb = new LinkBatch( $titles );
+ $where = $lb->constructSet( 'ar', $db );
+ $this->addWhere( $where );
+ } elseif ( $mode == 'all' ) {
+ $this->addWhereFld( 'ar_namespace', $params['namespace'] );
+ if ( !is_null( $params['from'] ) )
{
- $from = $this->getDB()->strencode($this->titleToKey($params['from']));
- $this->addWhere("ar_title >= '$from'");
+ $from = $this->getDB()->strencode( $this->titleToKey( $params['from'] ) );
+ $this->addWhere( "ar_title >= '$from'" );
}
}
- if(!is_null($params['user'])) {
- $this->addWhereFld('ar_user_text', $params['user']);
- } elseif(!is_null($params['excludeuser'])) {
- $this->addWhere('ar_user_text != ' .
- $this->getDB()->addQuotes($params['excludeuser']));
+ if ( !is_null( $params['user'] ) ) {
+ $this->addWhereFld( 'ar_user_text', $params['user'] );
+ } elseif ( !is_null( $params['excludeuser'] ) ) {
+ $this->addWhere( 'ar_user_text != ' .
+ $this->getDB()->addQuotes( $params['excludeuser'] ) );
}
- if(!is_null($params['continue']) && ($mode == 'all' || $mode == 'revs'))
+ if ( !is_null( $params['continue'] ) && ( $mode == 'all' || $mode == 'revs' ) )
{
- $cont = explode('|', $params['continue']);
- if(count($cont) != 3)
- $this->dieUsage("Invalid continue param. You should pass the original value returned by the previous query", "badcontinue");
- $ns = intval($cont[0]);
- $title = $this->getDB()->strencode($this->titleToKey($cont[1]));
- $ts = $this->getDB()->strencode($cont[2]);
- $op = ($params['dir'] == 'newer' ? '>' : '<');
- $this->addWhere("ar_namespace $op $ns OR " .
+ $cont = explode( '|', $params['continue'] );
+ if ( count( $cont ) != 3 )
+ $this->dieUsage( "Invalid continue param. You should pass the original value returned by the previous query", "badcontinue" );
+ $ns = intval( $cont[0] );
+ $title = $this->getDB()->strencode( $this->titleToKey( $cont[1] ) );
+ $ts = $this->getDB()->strencode( $cont[2] );
+ $op = ( $params['dir'] == 'newer' ? '>' : '<' );
+ $this->addWhere( "ar_namespace $op $ns OR " .
"(ar_namespace = $ns AND " .
"(ar_title $op '$title' OR " .
"(ar_title = '$title' AND " .
- "ar_timestamp = '$ts')))");
+ "ar_timestamp $op= '$ts')))" );
}
- $this->addOption('LIMIT', $limit + 1);
- $this->addOption('USE INDEX', array('archive' => ($mode == 'user' ? 'usertext_timestamp' : 'name_title_timestamp')));
- if($mode == 'all')
- {
- if($params['unique'])
+ $this->addOption( 'LIMIT', $limit + 1 );
+ $this->addOption( 'USE INDEX', array( 'archive' => ( $mode == 'user' ? 'usertext_timestamp' : 'name_title_timestamp' ) ) );
+ if ( $mode == 'all' ) {
+ if ( $params['unique'] )
{
- $this->addOption('GROUP BY', 'ar_title');
- $this->addOption('ORDER BY', 'ar_title');
- }
- else
- $this->addOption('ORDER BY', 'ar_title, ar_timestamp');
- }
- else
- {
- if($mode == 'revs')
+ $this->addOption( 'GROUP BY', 'ar_title' );
+ $this->addOption( 'ORDER BY', 'ar_title' );
+ } else
+ $this->addOption( 'ORDER BY', 'ar_title, ar_timestamp' );
+ } else {
+ if ( $mode == 'revs' )
{
// Sort by ns and title in the same order as timestamp for efficiency
- $this->addWhereRange('ar_namespace', $params['dir'], null, null);
- $this->addWhereRange('ar_title', $params['dir'], null, null);
+ $this->addWhereRange( 'ar_namespace', $params['dir'], null, null );
+ $this->addWhereRange( 'ar_title', $params['dir'], null, null );
}
- $this->addWhereRange('ar_timestamp', $params['dir'], $params['start'], $params['end']);
+ $this->addWhereRange( 'ar_timestamp', $params['dir'], $params['start'], $params['end'] );
}
- $res = $this->select(__METHOD__);
+ $res = $this->select( __METHOD__ );
$pageMap = array(); // Maps ns&title to (fake) pageid
$count = 0;
$newPageID = 0;
- while($row = $db->fetchObject($res))
+ while ( $row = $db->fetchObject( $res ) )
{
- if(++$count > $limit)
- {
+ if ( ++$count > $limit ) {
// We've had enough
- if($mode == 'all' || $mode == 'revs')
- $this->setContinueEnumParameter('continue', intval($row->ar_namespace) . '|' .
- $this->keyToTitle($row->ar_title) . '|' . $row->ar_timestamp);
+ if ( $mode == 'all' || $mode == 'revs' )
+ $this->setContinueEnumParameter( 'continue', intval( $row->ar_namespace ) . '|' .
+ $this->keyToTitle( $row->ar_title ) . '|' . $row->ar_timestamp );
else
- $this->setContinueEnumParameter('start', wfTimestamp(TS_ISO_8601, $row->ar_timestamp));
+ $this->setContinueEnumParameter( 'start', wfTimestamp( TS_ISO_8601, $row->ar_timestamp ) );
break;
}
$rev = array();
- $rev['timestamp'] = wfTimestamp(TS_ISO_8601, $row->ar_timestamp);
- if($fld_revid)
- $rev['revid'] = intval($row->ar_rev_id);
- if($fld_user)
+ $rev['timestamp'] = wfTimestamp( TS_ISO_8601, $row->ar_timestamp );
+ if ( $fld_revid )
+ $rev['revid'] = intval( $row->ar_rev_id );
+ if ( $fld_user )
$rev['user'] = $row->ar_user_text;
- if($fld_comment)
+ if ( $fld_comment )
$rev['comment'] = $row->ar_comment;
- if($fld_minor)
- if($row->ar_minor_edit == 1)
- $rev['minor'] = '';
- if($fld_len)
+
+ $title = Title::makeTitle( $row->ar_namespace, $row->ar_title );
+
+ if ( $fld_parsedcomment ) {
+ global $wgUser;
+ $rev['parsedcomment'] = $wgUser->getSkin()->formatComment( $row->ar_comment, $title );
+ }
+ if ( $fld_minor && $row->ar_minor_edit == 1 )
+ $rev['minor'] = '';
+ if ( $fld_len )
$rev['len'] = $row->ar_len;
- if($fld_content)
- ApiResult::setContent($rev, Revision::getRevisionText($row));
+ if ( $fld_content )
+ ApiResult::setContent( $rev, Revision::getRevisionText( $row ) );
- if(!isset($pageMap[$row->ar_namespace][$row->ar_title]))
- {
+ if ( !isset( $pageMap[$row->ar_namespace][$row->ar_title] ) ) {
$pageID = $newPageID++;
$pageMap[$row->ar_namespace][$row->ar_title] = $pageID;
- $t = Title::makeTitle($row->ar_namespace, $row->ar_title);
- $a['revisions'] = array($rev);
- $result->setIndexedTagName($a['revisions'], 'rev');
- ApiQueryBase::addTitleInfo($a, $t);
- if($fld_token)
+ $a['revisions'] = array( $rev );
+ $result->setIndexedTagName( $a['revisions'], 'rev' );
+ ApiQueryBase::addTitleInfo( $a, $title );
+ if ( $fld_token )
$a['token'] = $token;
- $fit = $result->addValue(array('query', $this->getModuleName()), $pageID, $a);
- }
- else
- {
+ $fit = $result->addValue( array( 'query', $this->getModuleName() ), $pageID, $a );
+ } else {
$pageID = $pageMap[$row->ar_namespace][$row->ar_title];
$fit = $result->addValue(
- array('query', $this->getModuleName(), $pageID, 'revisions'),
- null, $rev);
+ array( 'query', $this->getModuleName(), $pageID, 'revisions' ),
+ null, $rev );
}
- if(!$fit)
- {
- if($mode == 'all' || $mode == 'revs')
- $this->setContinueEnumParameter('continue', intval($row->ar_namespace) . '|' .
- $this->keyToTitle($row->ar_title) . '|' . $row->ar_timestamp);
+ if ( !$fit ) {
+ if ( $mode == 'all' || $mode == 'revs' )
+ $this->setContinueEnumParameter( 'continue', intval( $row->ar_namespace ) . '|' .
+ $this->keyToTitle( $row->ar_title ) . '|' . $row->ar_timestamp );
else
- $this->setContinueEnumParameter('start', wfTimestamp(TS_ISO_8601, $row->ar_timestamp));
+ $this->setContinueEnumParameter( 'start', wfTimestamp( TS_ISO_8601, $row->ar_timestamp ) );
break;
}
}
- $db->freeResult($res);
- $result->setIndexedTagName_internal(array('query', $this->getModuleName()), 'page');
+ $db->freeResult( $res );
+ $result->setIndexedTagName_internal( array( 'query', $this->getModuleName() ), 'page' );
}
public function getAllowedParams() {
@@ -284,6 +277,7 @@ class ApiQueryDeletedrevs extends ApiQueryBase {
'revid',
'user',
'comment',
+ 'parsedcomment',
'minor',
'len',
'content',
@@ -320,6 +314,15 @@ class ApiQueryDeletedrevs extends ApiQueryBase {
'For instance, a parameter marked (1) only applies to mode 1 and is ignored in modes 2 and 3.',
);
}
+
+ public function getPossibleErrors() {
+ return array_merge( parent::getPossibleErrors(), array(
+ array( 'code' => 'permissiondenied', 'info' => 'You don\'t have permission to view deleted revision information' ),
+ array( 'code' => 'badparams', 'info' => 'user and excludeuser cannot be used together' ),
+ array( 'code' => 'permissiondenied', 'info' => 'You don\'t have permission to view deleted revision content' ),
+ array( 'code' => 'badcontinue', 'info' => 'Invalid continue param. You should pass the original value returned by the previous query' ),
+ ) );
+ }
protected function getExamples() {
return array (
@@ -335,6 +338,6 @@ class ApiQueryDeletedrevs extends ApiQueryBase {
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiQueryDeletedrevs.php 69579 2010-07-20 02:49:55Z tstarling $';
+ return __CLASS__ . ': $Id: ApiQueryDeletedrevs.php 69578 2010-07-20 02:46:20Z tstarling $';
}
} \ No newline at end of file
diff --git a/includes/api/ApiQueryDisabled.php b/includes/api/ApiQueryDisabled.php
index 50825464..4bd3f5fd 100644
--- a/includes/api/ApiQueryDisabled.php
+++ b/includes/api/ApiQueryDisabled.php
@@ -22,9 +22,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ("ApiBase.php");
+ require_once ( "ApiBase.php" );
}
@@ -40,12 +40,12 @@ if (!defined('MEDIAWIKI')) {
*/
class ApiQueryDisabled extends ApiQueryBase {
- public function __construct($main, $action) {
- parent :: __construct($main, $action);
+ public function __construct( $main, $action ) {
+ parent :: __construct( $main, $action );
}
public function execute() {
- $this->setWarning("The ``{$this->getModuleName()}'' module has been disabled.");
+ $this->setWarning( "The ``{$this->getModuleName()}'' module has been disabled." );
}
public function getAllowedParams() {
@@ -67,6 +67,6 @@ class ApiQueryDisabled extends ApiQueryBase {
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiQueryDisabled.php 41268 2008-09-25 20:50:50Z catrope $';
+ return __CLASS__ . ': $Id: ApiQueryDisabled.php 60930 2010-01-11 15:55:52Z simetrical $';
}
}
diff --git a/includes/api/ApiQueryDuplicateFiles.php b/includes/api/ApiQueryDuplicateFiles.php
index a59ee356..ed070069 100644
--- a/includes/api/ApiQueryDuplicateFiles.php
+++ b/includes/api/ApiQueryDuplicateFiles.php
@@ -23,9 +23,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ("ApiQueryBase.php");
+ require_once ( "ApiQueryBase.php" );
}
/**
@@ -35,8 +35,8 @@ if (!defined('MEDIAWIKI')) {
*/
class ApiQueryDuplicateFiles extends ApiQueryGeneratorBase {
- public function __construct($query, $moduleName) {
- parent :: __construct($query, $moduleName, 'df');
+ public function __construct( $query, $moduleName ) {
+ parent :: __construct( $query, $moduleName, 'df' );
}
public function execute() {
@@ -47,11 +47,11 @@ class ApiQueryDuplicateFiles extends ApiQueryGeneratorBase {
return 'public';
}
- public function executeGenerator($resultPageSet) {
- $this->run($resultPageSet);
+ public function executeGenerator( $resultPageSet ) {
+ $this->run( $resultPageSet );
}
- private function run($resultPageSet = null) {
+ private function run( $resultPageSet = null ) {
$params = $this->extractRequestParams();
$namespaces = $this->getPageSet()->getAllTitlesByNamespace();
if ( empty( $namespaces[NS_FILE] ) ) {
@@ -59,71 +59,74 @@ class ApiQueryDuplicateFiles extends ApiQueryGeneratorBase {
}
$images = $namespaces[NS_FILE];
- $this->addTables('image', 'i1');
- $this->addTables('image', 'i2');
- $this->addFields(array(
+ $this->addTables( 'image', 'i1' );
+ $this->addTables( 'image', 'i2' );
+ $this->addFields( array(
'i1.img_name AS orig_name',
'i2.img_name AS dup_name',
'i2.img_user_text AS dup_user_text',
'i2.img_timestamp AS dup_timestamp'
- ));
- $this->addWhere(array(
- 'i1.img_name' => array_keys($images),
+ ) );
+
+ $this->addWhere( array(
+ 'i1.img_name' => array_keys( $images ),
'i1.img_sha1 = i2.img_sha1',
'i1.img_name != i2.img_name',
- ));
- if(isset($params['continue']))
+ ) );
+
+ if ( isset( $params['continue'] ) )
{
- $cont = explode('|', $params['continue']);
- if(count($cont) != 2)
- $this->dieUsage("Invalid continue param. You should pass the " .
- "original value returned by the previous query", "_badcontinue");
- $orig = $this->getDB()->strencode($this->titleTokey($cont[0]));
- $dup = $this->getDB()->strencode($this->titleToKey($cont[1]));
- $this->addWhere("i1.img_name > '$orig' OR ".
- "(i1.img_name = '$orig' AND ".
- "i2.img_name >= '$dup')");
+ $cont = explode( '|', $params['continue'] );
+ if ( count( $cont ) != 2 )
+ $this->dieUsage( "Invalid continue param. You should pass the " .
+ "original value returned by the previous query", "_badcontinue" );
+ $orig = $this->getDB()->strencode( $this->titleTokey( $cont[0] ) );
+ $dup = $this->getDB()->strencode( $this->titleToKey( $cont[1] ) );
+ $this->addWhere( "i1.img_name > '$orig' OR " .
+ "(i1.img_name = '$orig' AND " .
+ "i2.img_name >= '$dup')" );
}
- $this->addOption('ORDER BY', 'i1.img_name');
- $this->addOption('LIMIT', $params['limit'] + 1);
- $res = $this->select(__METHOD__);
+ $this->addOption( 'ORDER BY', 'i1.img_name' );
+ $this->addOption( 'LIMIT', $params['limit'] + 1 );
+
+ $res = $this->select( __METHOD__ );
$db = $this->getDB();
$count = 0;
$titles = array();
- while($row = $db->fetchObject($res))
+ while ( $row = $db->fetchObject( $res ) )
{
- if(++$count > $params['limit'])
+ if ( ++$count > $params['limit'] )
{
// We've reached the one extra which shows that
// there are additional pages to be had. Stop here...
- $this->setContinueEnumParameter('continue',
- $this->keyToTitle($row->orig_name) . '|' .
- $this->keyToTitle($row->dup_name));
+ $this->setContinueEnumParameter( 'continue',
+ $this->keyToTitle( $row->orig_name ) . '|' .
+ $this->keyToTitle( $row->dup_name ) );
break;
}
- if(!is_null($resultPageSet))
- $titles[] = Title::makeTitle(NS_FILE, $row->dup_name);
+ if ( !is_null( $resultPageSet ) )
+ $titles[] = Title::makeTitle( NS_FILE, $row->dup_name );
else
{
$r = array(
'name' => $row->dup_name,
'user' => $row->dup_user_text,
- 'timestamp' => wfTimestamp(TS_ISO_8601, $row->dup_timestamp)
+ 'timestamp' => wfTimestamp( TS_ISO_8601, $row->dup_timestamp )
);
- $fit = $this->addPageSubItem($images[$row->orig_name], $r);
- if(!$fit)
+ $fit = $this->addPageSubItem( $images[$row->orig_name], $r );
+ if ( !$fit )
{
- $this->setContinueEnumParameter('continue',
- $this->keyToTitle($row->orig_name) . '|' .
- $this->keyToTitle($row->dup_name));
+ $this->setContinueEnumParameter( 'continue',
+ $this->keyToTitle( $row->orig_name ) . '|' .
+ $this->keyToTitle( $row->dup_name ) );
break;
}
}
}
- if(!is_null($resultPageSet))
- $resultPageSet->populateFromTitles($titles);
- $db->freeResult($res);
+ if ( !is_null( $resultPageSet ) )
+ $resultPageSet->populateFromTitles( $titles );
+ $db->freeResult( $res );
}
public function getAllowedParams() {
@@ -149,6 +152,12 @@ class ApiQueryDuplicateFiles extends ApiQueryGeneratorBase {
public function getDescription() {
return 'List all files that are duplicates of the given file(s).';
}
+
+ public function getPossibleErrors() {
+ return array_merge( parent::getPossibleErrors(), array(
+ array( 'code' => '_badcontinue', 'info' => 'Invalid continue param. You should pass the original value returned by the previous query' ),
+ ) );
+ }
protected function getExamples() {
return array ( 'api.php?action=query&titles=File:Albert_Einstein_Head.jpg&prop=duplicatefiles',
@@ -157,6 +166,6 @@ class ApiQueryDuplicateFiles extends ApiQueryGeneratorBase {
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiQueryDuplicateFiles.php 69986 2010-07-27 03:57:39Z tstarling $';
+ return __CLASS__ . ': $Id: ApiQueryDuplicateFiles.php 69932 2010-07-26 08:03:21Z tstarling $';
}
}
diff --git a/includes/api/ApiQueryExtLinksUsage.php b/includes/api/ApiQueryExtLinksUsage.php
index 08f6ab1f..0e171e44 100644
--- a/includes/api/ApiQueryExtLinksUsage.php
+++ b/includes/api/ApiQueryExtLinksUsage.php
@@ -23,9 +23,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ('ApiQueryBase.php');
+ require_once ( 'ApiQueryBase.php' );
}
/**
@@ -33,8 +33,8 @@ if (!defined('MEDIAWIKI')) {
*/
class ApiQueryExtLinksUsage extends ApiQueryGeneratorBase {
- public function __construct($query, $moduleName) {
- parent :: __construct($query, $moduleName, 'eu');
+ public function __construct( $query, $moduleName ) {
+ parent :: __construct( $query, $moduleName, 'eu' );
}
public function execute() {
@@ -45,11 +45,11 @@ class ApiQueryExtLinksUsage extends ApiQueryGeneratorBase {
return 'public';
}
- public function executeGenerator($resultPageSet) {
- $this->run($resultPageSet);
+ public function executeGenerator( $resultPageSet ) {
+ $this->run( $resultPageSet );
}
- private function run($resultPageSet = null) {
+ private function run( $resultPageSet = null ) {
$params = $this->extractRequestParams();
@@ -58,10 +58,10 @@ class ApiQueryExtLinksUsage extends ApiQueryGeneratorBase {
// Find the right prefix
global $wgUrlProtocols;
- if($protocol && !in_array($protocol, $wgUrlProtocols))
+ if ( $protocol && !in_array( $protocol, $wgUrlProtocols ) )
{
- foreach ($wgUrlProtocols as $p) {
- if( substr( $p, 0, strlen( $protocol ) ) === $protocol ) {
+ foreach ( $wgUrlProtocols as $p ) {
+ if ( substr( $p, 0, strlen( $protocol ) ) === $protocol ) {
$protocol = $p;
break;
}
@@ -71,91 +71,92 @@ class ApiQueryExtLinksUsage extends ApiQueryGeneratorBase {
$protocol = null;
$db = $this->getDB();
- $this->addTables(array('page','externallinks')); // must be in this order for 'USE INDEX'
- $this->addOption('USE INDEX', 'el_index');
- $this->addWhere('page_id=el_from');
- $this->addWhereFld('page_namespace', $params['namespace']);
+ $this->addTables( array( 'page', 'externallinks' ) ); // must be in this order for 'USE INDEX'
+ $this->addOption( 'USE INDEX', 'el_index' );
+ $this->addWhere( 'page_id=el_from' );
+ $this->addWhereFld( 'page_namespace', $params['namespace'] );
- if(!is_null($query) || $query != '')
+ if ( !is_null( $query ) || $query != '' )
{
- if(is_null($protocol))
+ if ( is_null( $protocol ) )
$protocol = 'http://';
- $likeQuery = LinkFilter::makeLike($query, $protocol);
- if (!$likeQuery)
- $this->dieUsage('Invalid query', 'bad_query');
- $likeQuery = substr($likeQuery, 0, strpos($likeQuery,'%')+1);
- $this->addWhere('el_index LIKE ' . $db->addQuotes( $likeQuery ));
+ $likeQuery = LinkFilter::makeLikeArray( $query, $protocol );
+ if ( !$likeQuery )
+ $this->dieUsage( 'Invalid query', 'bad_query' );
+
+ $likeQuery = LinkFilter::keepOneWildcard( $likeQuery );
+ $this->addWhere( 'el_index ' . $db->buildLike( $likeQuery ) );
}
- else if(!is_null($protocol))
- $this->addWhere('el_index LIKE ' . $db->addQuotes( "$protocol%" ));
+ else if ( !is_null( $protocol ) )
+ $this->addWhere( 'el_index ' . $db->buildLike( "$protocol", $db->anyString() ) );
- $prop = array_flip($params['prop']);
- $fld_ids = isset($prop['ids']);
- $fld_title = isset($prop['title']);
- $fld_url = isset($prop['url']);
+ $prop = array_flip( $params['prop'] );
+ $fld_ids = isset( $prop['ids'] );
+ $fld_title = isset( $prop['title'] );
+ $fld_url = isset( $prop['url'] );
- if (is_null($resultPageSet)) {
- $this->addFields(array (
+ if ( is_null( $resultPageSet ) ) {
+ $this->addFields( array (
'page_id',
'page_namespace',
'page_title'
- ));
- $this->addFieldsIf('el_to', $fld_url);
+ ) );
+ $this->addFieldsIf( 'el_to', $fld_url );
} else {
- $this->addFields($resultPageSet->getPageTableFields());
+ $this->addFields( $resultPageSet->getPageTableFields() );
}
$limit = $params['limit'];
$offset = $params['offset'];
- $this->addOption('LIMIT', $limit +1);
- if (isset ($offset))
- $this->addOption('OFFSET', $offset);
+ $this->addOption( 'LIMIT', $limit + 1 );
+ if ( isset ( $offset ) )
+ $this->addOption( 'OFFSET', $offset );
- $res = $this->select(__METHOD__);
+ $res = $this->select( __METHOD__ );
$result = $this->getResult();
$count = 0;
- while ($row = $db->fetchObject($res)) {
- if (++ $count > $limit) {
+ while ( $row = $db->fetchObject( $res ) ) {
+ if ( ++ $count > $limit ) {
// We've reached the one extra which shows that there are additional pages to be had. Stop here...
- $this->setContinueEnumParameter('offset', $offset+$limit);
+ $this->setContinueEnumParameter( 'offset', $offset + $limit );
break;
}
- if (is_null($resultPageSet)) {
+ if ( is_null( $resultPageSet ) ) {
$vals = array();
- if ($fld_ids)
- $vals['pageid'] = intval($row->page_id);
- if ($fld_title) {
- $title = Title :: makeTitle($row->page_namespace, $row->page_title);
- ApiQueryBase::addTitleInfo($vals, $title);
+ if ( $fld_ids )
+ $vals['pageid'] = intval( $row->page_id );
+ if ( $fld_title ) {
+ $title = Title :: makeTitle( $row->page_namespace, $row->page_title );
+ ApiQueryBase::addTitleInfo( $vals, $title );
}
- if ($fld_url)
+ if ( $fld_url )
$vals['url'] = $row->el_to;
- $fit = $result->addValue(array('query', $this->getModuleName()), null, $vals);
- if(!$fit)
+ $fit = $result->addValue( array( 'query', $this->getModuleName() ), null, $vals );
+ if ( !$fit )
{
- $this->setContinueEnumParameter('offset', $offset + $count - 1);
+ $this->setContinueEnumParameter( 'offset', $offset + $count - 1 );
break;
}
} else {
- $resultPageSet->processDbRow($row);
+ $resultPageSet->processDbRow( $row );
}
}
- $db->freeResult($res);
+ $db->freeResult( $res );
- if (is_null($resultPageSet)) {
- $result->setIndexedTagName_internal(array('query', $this->getModuleName()),
- $this->getModulePrefix());
+ if ( is_null( $resultPageSet ) ) {
+ $result->setIndexedTagName_internal( array( 'query', $this->getModuleName() ),
+ $this->getModulePrefix() );
}
}
public function getAllowedParams() {
global $wgUrlProtocols;
- $protocols = array('');
- foreach ($wgUrlProtocols as $p) {
- $protocols[] = substr($p, 0, strpos($p,':'));
+ $protocols = array( '' );
+ foreach ( $wgUrlProtocols as $p ) {
+ $protocols[] = substr( $p, 0, strpos( $p, ':' ) );
}
return array (
@@ -195,7 +196,7 @@ class ApiQueryExtLinksUsage extends ApiQueryGeneratorBase {
'prop' => 'What pieces of information to include',
'offset' => 'Used for paging. Use the value returned for "continue"',
'protocol' => array( 'Protocol of the url. If empty and euquery set, the protocol is http.',
- 'Leave both this and euquery empty to list all external links'),
+ 'Leave both this and euquery empty to list all external links' ),
'query' => 'Search string without protocol. See [[Special:LinkSearch]]. Leave empty to list all external links',
'namespace' => 'The page namespace(s) to enumerate.',
'limit' => 'How many pages to return.'
@@ -205,6 +206,12 @@ class ApiQueryExtLinksUsage extends ApiQueryGeneratorBase {
public function getDescription() {
return 'Enumerate pages that contain a given URL';
}
+
+ public function getPossibleErrors() {
+ return array_merge( parent::getPossibleErrors(), array(
+ array( 'code' => 'bad_query', 'info' => 'Invalid query' ),
+ ) );
+ }
protected function getExamples() {
return array (
@@ -213,6 +220,6 @@ class ApiQueryExtLinksUsage extends ApiQueryGeneratorBase {
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiQueryExtLinksUsage.php 69986 2010-07-27 03:57:39Z tstarling $';
+ return __CLASS__ . ': $Id: ApiQueryExtLinksUsage.php 69932 2010-07-26 08:03:21Z tstarling $';
}
}
diff --git a/includes/api/ApiQueryExternalLinks.php b/includes/api/ApiQueryExternalLinks.php
index 0bddd6df..a748e036 100644
--- a/includes/api/ApiQueryExternalLinks.php
+++ b/includes/api/ApiQueryExternalLinks.php
@@ -23,9 +23,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ("ApiQueryBase.php");
+ require_once ( "ApiQueryBase.php" );
}
/**
@@ -35,8 +35,8 @@ if (!defined('MEDIAWIKI')) {
*/
class ApiQueryExternalLinks extends ApiQueryBase {
- public function __construct($query, $moduleName) {
- parent :: __construct($query, $moduleName, 'el');
+ public function __construct( $query, $moduleName ) {
+ parent :: __construct( $query, $moduleName, 'el' );
}
public function execute() {
@@ -44,41 +44,43 @@ class ApiQueryExternalLinks extends ApiQueryBase {
return;
$params = $this->extractRequestParams();
- $this->addFields(array (
+ $this->addFields( array (
'el_from',
'el_to'
- ));
+ ) );
- $this->addTables('externallinks');
- $this->addWhereFld('el_from', array_keys($this->getPageSet()->getGoodTitles()));
- # Don't order by el_from if it's constant in the WHERE clause
- if(count($this->getPageSet()->getGoodTitles()) != 1)
- $this->addOption('ORDER BY', 'el_from');
- $this->addOption('LIMIT', $params['limit'] + 1);
- if(!is_null($params['offset']))
- $this->addOption('OFFSET', $params['offset']);
+ $this->addTables( 'externallinks' );
+ $this->addWhereFld( 'el_from', array_keys( $this->getPageSet()->getGoodTitles() ) );
+
+ // Don't order by el_from if it's constant in the WHERE clause
+ if ( count( $this->getPageSet()->getGoodTitles() ) != 1 )
+ $this->addOption( 'ORDER BY', 'el_from' );
+
+ $this->addOption( 'LIMIT', $params['limit'] + 1 );
+ if ( !is_null( $params['offset'] ) )
+ $this->addOption( 'OFFSET', $params['offset'] );
$db = $this->getDB();
- $res = $this->select(__METHOD__);
+ $res = $this->select( __METHOD__ );
$count = 0;
- while ($row = $db->fetchObject($res)) {
- if (++$count > $params['limit']) {
+ while ( $row = $db->fetchObject( $res ) ) {
+ if ( ++$count > $params['limit'] ) {
// We've reached the one extra which shows that
// there are additional pages to be had. Stop here...
- $this->setContinueEnumParameter('offset', @$params['offset'] + $params['limit']);
+ $this->setContinueEnumParameter( 'offset', @$params['offset'] + $params['limit'] );
break;
}
$entry = array();
- ApiResult :: setContent($entry, $row->el_to);
- $fit = $this->addPageSubItem($row->el_from, $entry);
- if(!$fit)
+ ApiResult :: setContent( $entry, $row->el_to );
+ $fit = $this->addPageSubItem( $row->el_from, $entry );
+ if ( !$fit )
{
- $this->setContinueEnumParameter('offset', @$params['offset'] + $count - 1);
+ $this->setContinueEnumParameter( 'offset', @$params['offset'] + $count - 1 );
break;
}
}
- $db->freeResult($res);
+ $db->freeResult( $res );
}
public function getCacheMode( $params ) {
@@ -117,6 +119,6 @@ class ApiQueryExternalLinks extends ApiQueryBase {
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiQueryExternalLinks.php 69986 2010-07-27 03:57:39Z tstarling $';
+ return __CLASS__ . ': $Id: ApiQueryExternalLinks.php 69932 2010-07-26 08:03:21Z tstarling $';
}
}
diff --git a/includes/api/ApiQueryImageInfo.php b/includes/api/ApiQueryImageInfo.php
index c4c71075..3704710a 100644
--- a/includes/api/ApiQueryImageInfo.php
+++ b/includes/api/ApiQueryImageInfo.php
@@ -23,9 +23,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ('ApiQueryBase.php');
+ require_once ( 'ApiQueryBase.php' );
}
/**
@@ -35,19 +35,19 @@ if (!defined('MEDIAWIKI')) {
*/
class ApiQueryImageInfo extends ApiQueryBase {
- public function __construct($query, $moduleName) {
- parent :: __construct($query, $moduleName, 'ii');
+ public function __construct( $query, $moduleName ) {
+ parent :: __construct( $query, $moduleName, 'ii' );
}
public function execute() {
$params = $this->extractRequestParams();
- $prop = array_flip($params['prop']);
+ $prop = array_flip( $params['prop'] );
- if($params['urlheight'] != -1 && $params['urlwidth'] == -1)
- $this->dieUsage("iiurlheight cannot be used without iiurlwidth", 'iiurlwidth');
+ if ( $params['urlheight'] != - 1 && $params['urlwidth'] == - 1 )
+ $this->dieUsage( "iiurlheight cannot be used without iiurlwidth", 'iiurlwidth' );
- if ( $params['urlwidth'] != -1 ) {
+ if ( $params['urlwidth'] != - 1 ) {
$scale = array();
$scale['width'] = $params['urlwidth'];
$scale['height'] = $params['urlheight'];
@@ -57,23 +57,23 @@ class ApiQueryImageInfo extends ApiQueryBase {
$pageIds = $this->getPageSet()->getAllTitlesByNamespace();
if ( !empty( $pageIds[NS_FILE] ) ) {
- $titles = array_keys($pageIds[NS_FILE]);
- asort($titles); // Ensure the order is always the same
+ $titles = array_keys( $pageIds[NS_FILE] );
+ asort( $titles ); // Ensure the order is always the same
$skip = false;
- if(!is_null($params['continue']))
+ if ( !is_null( $params['continue'] ) )
{
$skip = true;
- $cont = explode('|', $params['continue']);
- if(count($cont) != 2)
- $this->dieUsage("Invalid continue param. You should pass the original " .
- "value returned by the previous query", "_badcontinue");
- $fromTitle = strval($cont[0]);
+ $cont = explode( '|', $params['continue'] );
+ if ( count( $cont ) != 2 )
+ $this->dieUsage( "Invalid continue param. You should pass the original " .
+ "value returned by the previous query", "_badcontinue" );
+ $fromTitle = strval( $cont[0] );
$fromTimestamp = $cont[1];
// Filter out any titles before $fromTitle
- foreach($titles as $key => $title)
- if($title < $fromTitle)
- unset($titles[$key]);
+ foreach ( $titles as $key => $title )
+ if ( $title < $fromTitle )
+ unset( $titles[$key] );
else
break;
}
@@ -81,90 +81,95 @@ class ApiQueryImageInfo extends ApiQueryBase {
$result = $this->getResult();
$images = RepoGroup::singleton()->findFiles( $titles );
foreach ( $images as $img ) {
+ // Skip redirects
+ if ( $img->getOriginalTitle()->isRedirect() )
+ continue;
+
$start = $skip ? $fromTimestamp : $params['start'];
$pageId = $pageIds[NS_IMAGE][ $img->getOriginalTitle()->getDBkey() ];
$fit = $result->addValue(
- array('query', 'pages', intval($pageId)),
+ array( 'query', 'pages', intval( $pageId ) ),
'imagerepository', $img->getRepoName()
);
- if(!$fit)
+ if ( !$fit )
{
- if(count($pageIds[NS_IMAGE]) == 1)
- # The user is screwed. imageinfo can't be solely
- # responsible for exceeding the limit in this case,
- # so set a query-continue that just returns the same
- # thing again. When the violating queries have been
- # out-continued, the result will get through
- $this->setContinueEnumParameter('start',
- wfTimestamp(TS_ISO_8601, $img->getTimestamp()));
+ if ( count( $pageIds[NS_IMAGE] ) == 1 )
+ // The user is screwed. imageinfo can't be solely
+ // responsible for exceeding the limit in this case,
+ // so set a query-continue that just returns the same
+ // thing again. When the violating queries have been
+ // out-continued, the result will get through
+ $this->setContinueEnumParameter( 'start',
+ wfTimestamp( TS_ISO_8601, $img->getTimestamp() ) );
else
- $this->setContinueEnumParameter('continue',
- $this->getContinueStr($img));
+ $this->setContinueEnumParameter( 'continue',
+ $this->getContinueStr( $img ) );
break;
}
// Get information about the current version first
// Check that the current version is within the start-end boundaries
$gotOne = false;
- if((is_null($start) || $img->getTimestamp() <= $start) &&
- (is_null($params['end']) || $img->getTimestamp() >= $params['end'])) {
+ if ( ( is_null( $start ) || $img->getTimestamp() <= $start ) &&
+ ( is_null( $params['end'] ) || $img->getTimestamp() >= $params['end'] ) ) {
$gotOne = true;
- $fit = $this->addPageSubItem($pageId,
- self::getInfo( $img, $prop, $result, $scale));
- if(!$fit)
+ $fit = $this->addPageSubItem( $pageId,
+ self::getInfo( $img, $prop, $result, $scale ) );
+ if ( !$fit )
{
- if(count($pageIds[NS_IMAGE]) == 1)
- # See the 'the user is screwed' comment above
- $this->setContinueEnumParameter('start',
- wfTimestamp(TS_ISO_8601, $img->getTimestamp()));
+ if ( count( $pageIds[NS_IMAGE] ) == 1 )
+ // See the 'the user is screwed' comment above
+ $this->setContinueEnumParameter( 'start',
+ wfTimestamp( TS_ISO_8601, $img->getTimestamp() ) );
else
- $this->setContinueEnumParameter('continue',
- $this->getContinueStr($img));
+ $this->setContinueEnumParameter( 'continue',
+ $this->getContinueStr( $img ) );
break;
}
}
// Now get the old revisions
// Get one more to facilitate query-continue functionality
- $count = ($gotOne ? 1 : 0);
- $oldies = $img->getHistory($params['limit'] - $count + 1, $start, $params['end']);
- foreach($oldies as $oldie) {
- if(++$count > $params['limit']) {
+ $count = ( $gotOne ? 1 : 0 );
+ $oldies = $img->getHistory( $params['limit'] - $count + 1, $start, $params['end'] );
+ foreach ( $oldies as $oldie ) {
+ if ( ++$count > $params['limit'] ) {
// We've reached the extra one which shows that there are additional pages to be had. Stop here...
// Only set a query-continue if there was only one title
- if(count($pageIds[NS_FILE]) == 1)
+ if ( count( $pageIds[NS_FILE] ) == 1 )
{
- $this->setContinueEnumParameter('start',
- wfTimestamp(TS_ISO_8601, $oldie->getTimestamp()));
+ $this->setContinueEnumParameter( 'start',
+ wfTimestamp( TS_ISO_8601, $oldie->getTimestamp() ) );
}
break;
}
- $fit = $this->addPageSubItem($pageId,
- self::getInfo($oldie, $prop, $result));
- if(!$fit)
+ $fit = $this->addPageSubItem( $pageId,
+ self::getInfo( $oldie, $prop, $result ) );
+ if ( !$fit )
{
- if(count($pageIds[NS_IMAGE]) == 1)
- $this->setContinueEnumParameter('start',
- wfTimestamp(TS_ISO_8601, $oldie->getTimestamp()));
+ if ( count( $pageIds[NS_IMAGE] ) == 1 )
+ $this->setContinueEnumParameter( 'start',
+ wfTimestamp( TS_ISO_8601, $oldie->getTimestamp() ) );
else
- $this->setContinueEnumParameter('continue',
- $this->getContinueStr($oldie));
+ $this->setContinueEnumParameter( 'continue',
+ $this->getContinueStr( $oldie ) );
break;
}
}
- if(!$fit)
+ if ( !$fit )
break;
$skip = false;
}
- $missing = array_diff( array_keys( $pageIds[NS_FILE] ), array_keys( $images ) );
- foreach ($missing as $title) {
- $result->addValue(
- array('query', 'pages', intval($pageIds[NS_FILE][$title])),
- 'imagerepository', ''
- );
- // The above can't fail because it doesn't increase the result size
+ $data = $this->getResultData();
+ foreach ( $data['query']['pages'] as $pageid => $arr ) {
+ if ( !isset( $arr['imagerepository'] ) )
+ $result->addValue(
+ array( 'query', 'pages', $pageid ),
+ 'imagerepository', ''
+ );
+ // The above can't fail because it doesn't increase the result size
}
}
}
@@ -174,26 +179,26 @@ class ApiQueryImageInfo extends ApiQueryBase {
* @param File f The image
* @return array Result array
*/
- static function getInfo($file, $prop, $result, $scale = null) {
+ static function getInfo( $file, $prop, $result, $scale = null ) {
$vals = array();
- if( isset( $prop['timestamp'] ) )
- $vals['timestamp'] = wfTimestamp(TS_ISO_8601, $file->getTimestamp());
- if( isset( $prop['user'] ) ) {
+ if ( isset( $prop['timestamp'] ) )
+ $vals['timestamp'] = wfTimestamp( TS_ISO_8601, $file->getTimestamp() );
+ if ( isset( $prop['user'] ) ) {
$vals['user'] = $file->getUser();
- if( !$file->getUser( 'id' ) )
+ if ( !$file->getUser( 'id' ) )
$vals['anon'] = '';
}
- if( isset( $prop['size'] ) || isset( $prop['dimensions'] ) ) {
+ if ( isset( $prop['size'] ) || isset( $prop['dimensions'] ) ) {
$vals['size'] = intval( $file->getSize() );
$vals['width'] = intval( $file->getWidth() );
$vals['height'] = intval( $file->getHeight() );
}
- if( isset( $prop['url'] ) ) {
- if( !is_null( $scale ) && !$file->isOld() ) {
+ if ( isset( $prop['url'] ) ) {
+ if ( !is_null( $scale ) && !$file->isOld() ) {
$mto = $file->transform( array( 'width' => $scale['width'], 'height' => $scale['height'] ) );
- if( $mto && !$mto->isError() )
+ if ( $mto && !$mto->isError() )
{
- $vals['thumburl'] = $mto->getUrl();
+ $vals['thumburl'] = wfExpandUrl( $mto->getUrl() );
$vals['thumbwidth'] = intval( $mto->getWidth() );
$vals['thumbheight'] = intval( $mto->getHeight() );
}
@@ -201,41 +206,41 @@ class ApiQueryImageInfo extends ApiQueryBase {
$vals['url'] = $file->getFullURL();
$vals['descriptionurl'] = wfExpandUrl( $file->getDescriptionUrl() );
}
- if( isset( $prop['comment'] ) )
+ if ( isset( $prop['comment'] ) )
$vals['comment'] = $file->getDescription();
- if( isset( $prop['sha1'] ) )
+ if ( isset( $prop['sha1'] ) )
$vals['sha1'] = wfBaseConvert( $file->getSha1(), 36, 16, 40 );
- if( isset( $prop['metadata'] ) ) {
+ if ( isset( $prop['metadata'] ) ) {
$metadata = $file->getMetadata();
$vals['metadata'] = $metadata ? self::processMetaData( unserialize( $metadata ), $result ) : null;
}
- if( isset( $prop['mime'] ) )
+ if ( isset( $prop['mime'] ) )
$vals['mime'] = $file->getMimeType();
- if( isset( $prop['archivename'] ) && $file->isOld() )
+ if ( isset( $prop['archivename'] ) && $file->isOld() )
$vals['archivename'] = $file->getArchiveName();
- if( isset( $prop['bitdepth'] ) )
+ if ( isset( $prop['bitdepth'] ) )
$vals['bitdepth'] = $file->getBitDepth();
return $vals;
}
- public static function processMetaData($metadata, $result)
+ public static function processMetaData( $metadata, $result )
{
$retval = array();
if ( is_array( $metadata ) ) {
- foreach($metadata as $key => $value)
+ foreach ( $metadata as $key => $value )
{
- $r = array('name' => $key);
- if(is_array($value))
- $r['value'] = self::processMetaData($value, $result);
+ $r = array( 'name' => $key );
+ if ( is_array( $value ) )
+ $r['value'] = self::processMetaData( $value, $result );
else
$r['value'] = $value;
$retval[] = $r;
}
}
- $result->setIndexedTagName($retval, 'metadata');
+ $result->setIndexedTagName( $retval, 'metadata' );
return $retval;
}
@@ -243,7 +248,7 @@ class ApiQueryImageInfo extends ApiQueryBase {
return 'public';
}
- private function getContinueStr($img)
+ private function getContinueStr( $img )
{
return $img->getOriginalTitle()->getText() .
'|' . $img->getTimestamp();
@@ -254,18 +259,7 @@ class ApiQueryImageInfo extends ApiQueryBase {
'prop' => array (
ApiBase :: PARAM_ISMULTI => true,
ApiBase :: PARAM_DFLT => 'timestamp|user',
- ApiBase :: PARAM_TYPE => array (
- 'timestamp',
- 'user',
- 'comment',
- 'url',
- 'size',
- 'sha1',
- 'mime',
- 'metadata',
- 'archivename',
- 'bitdepth',
- )
+ ApiBase :: PARAM_TYPE => self::getPropertyNames()
),
'limit' => array(
ApiBase :: PARAM_TYPE => 'limit',
@@ -282,15 +276,34 @@ class ApiQueryImageInfo extends ApiQueryBase {
),
'urlwidth' => array(
ApiBase :: PARAM_TYPE => 'integer',
- ApiBase :: PARAM_DFLT => -1
+ ApiBase :: PARAM_DFLT => - 1
),
'urlheight' => array(
ApiBase :: PARAM_TYPE => 'integer',
- ApiBase :: PARAM_DFLT => -1
+ ApiBase :: PARAM_DFLT => - 1
),
'continue' => null,
);
}
+
+ /**
+ * Returns all possible parameters to iiprop
+ */
+ public static function getPropertyNames() {
+ return array (
+ 'timestamp',
+ 'user',
+ 'comment',
+ 'url',
+ 'size',
+ 'dimensions', // For backwards compatibility with Allimages
+ 'sha1',
+ 'mime',
+ 'metadata',
+ 'archivename',
+ 'bitdepth',
+ );
+ }
public function getParamDescription() {
return array (
@@ -298,8 +311,8 @@ class ApiQueryImageInfo extends ApiQueryBase {
'limit' => 'How many image revisions to return',
'start' => 'Timestamp to start listing from',
'end' => 'Timestamp to stop listing at',
- 'urlwidth' => array('If iiprop=url is set, a URL to an image scaled to this width will be returned.',
- 'Only the current version of the image can be scaled.'),
+ 'urlwidth' => array( 'If iiprop=url is set, a URL to an image scaled to this width will be returned.',
+ 'Only the current version of the image can be scaled.' ),
'urlheight' => 'Similar to iiurlwidth. Cannot be used without iiurlwidth',
'continue' => 'When more results are available, use this to continue',
);
@@ -310,6 +323,12 @@ class ApiQueryImageInfo extends ApiQueryBase {
'Returns image information and upload history'
);
}
+
+ public function getPossibleErrors() {
+ return array_merge( parent::getPossibleErrors(), array(
+ array( 'code' => 'iiurlwidth', 'info' => 'iiurlheight cannot be used without iiurlwidth' ),
+ ) );
+ }
protected function getExamples() {
return array (
@@ -319,6 +338,6 @@ class ApiQueryImageInfo extends ApiQueryBase {
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiQueryImageInfo.php 69986 2010-07-27 03:57:39Z tstarling $';
+ return __CLASS__ . ': $Id: ApiQueryImageInfo.php 69932 2010-07-26 08:03:21Z tstarling $';
}
}
diff --git a/includes/api/ApiQueryImages.php b/includes/api/ApiQueryImages.php
index 9dbe08a6..65df94dc 100644
--- a/includes/api/ApiQueryImages.php
+++ b/includes/api/ApiQueryImages.php
@@ -23,9 +23,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ("ApiQueryBase.php");
+ require_once ( "ApiQueryBase.php" );
}
/**
@@ -35,69 +35,70 @@ if (!defined('MEDIAWIKI')) {
*/
class ApiQueryImages extends ApiQueryGeneratorBase {
- public function __construct($query, $moduleName) {
- parent :: __construct($query, $moduleName, 'im');
+ public function __construct( $query, $moduleName ) {
+ parent :: __construct( $query, $moduleName, 'im' );
}
public function execute() {
$this->run();
}
- public function executeGenerator($resultPageSet) {
- $this->run($resultPageSet);
+ public function executeGenerator( $resultPageSet ) {
+ $this->run( $resultPageSet );
}
- private function run($resultPageSet = null) {
+ private function run( $resultPageSet = null ) {
- if ($this->getPageSet()->getGoodTitleCount() == 0)
+ if ( $this->getPageSet()->getGoodTitleCount() == 0 )
return; // nothing to do
$params = $this->extractRequestParams();
- $this->addFields(array (
+ $this->addFields( array (
'il_from',
'il_to'
- ));
-
- $this->addTables('imagelinks');
- $this->addWhereFld('il_from', array_keys($this->getPageSet()->getGoodTitles()));
- if(!is_null($params['continue'])) {
- $cont = explode('|', $params['continue']);
- if(count($cont) != 2)
- $this->dieUsage("Invalid continue param. You should pass the " .
- "original value returned by the previous query", "_badcontinue");
- $ilfrom = intval($cont[0]);
- $ilto = $this->getDB()->strencode($this->titleToKey($cont[1]));
- $this->addWhere("il_from > $ilfrom OR ".
- "(il_from = $ilfrom AND ".
- "il_to >= '$ilto')");
+ ) );
+
+ $this->addTables( 'imagelinks' );
+ $this->addWhereFld( 'il_from', array_keys( $this->getPageSet()->getGoodTitles() ) );
+ if ( !is_null( $params['continue'] ) ) {
+ $cont = explode( '|', $params['continue'] );
+ if ( count( $cont ) != 2 )
+ $this->dieUsage( "Invalid continue param. You should pass the " .
+ "original value returned by the previous query", "_badcontinue" );
+ $ilfrom = intval( $cont[0] );
+ $ilto = $this->getDB()->strencode( $this->titleToKey( $cont[1] ) );
+ $this->addWhere( "il_from > $ilfrom OR " .
+ "(il_from = $ilfrom AND " .
+ "il_to >= '$ilto')" );
}
- # Don't order by il_from if it's constant in the WHERE clause
- if(count($this->getPageSet()->getGoodTitles()) == 1)
- $this->addOption('ORDER BY', 'il_to');
+
+ // Don't order by il_from if it's constant in the WHERE clause
+ if ( count( $this->getPageSet()->getGoodTitles() ) == 1 )
+ $this->addOption( 'ORDER BY', 'il_to' );
else
- $this->addOption('ORDER BY', 'il_from, il_to');
- $this->addOption('LIMIT', $params['limit'] + 1);
+ $this->addOption( 'ORDER BY', 'il_from, il_to' );
+ $this->addOption( 'LIMIT', $params['limit'] + 1 );
$db = $this->getDB();
- $res = $this->select(__METHOD__);
+ $res = $this->select( __METHOD__ );
- if (is_null($resultPageSet)) {
+ if ( is_null( $resultPageSet ) ) {
$count = 0;
- while ($row = $db->fetchObject($res)) {
- if (++$count > $params['limit']) {
+ while ( $row = $db->fetchObject( $res ) ) {
+ if ( ++$count > $params['limit'] ) {
// We've reached the one extra which shows that
// there are additional pages to be had. Stop here...
- $this->setContinueEnumParameter('continue', $row->il_from .
- '|' . $this->keyToTitle($row->il_to));
+ $this->setContinueEnumParameter( 'continue', $row->il_from .
+ '|' . $this->keyToTitle( $row->il_to ) );
break;
}
$vals = array();
- ApiQueryBase :: addTitleInfo($vals, Title :: makeTitle(NS_FILE, $row->il_to));
- $fit = $this->addPageSubItem($row->il_from, $vals);
- if(!$fit)
+ ApiQueryBase :: addTitleInfo( $vals, Title :: makeTitle( NS_FILE, $row->il_to ) );
+ $fit = $this->addPageSubItem( $row->il_from, $vals );
+ if ( !$fit )
{
- $this->setContinueEnumParameter('continue', $row->il_from .
- '|' . $this->keyToTitle($row->il_to));
+ $this->setContinueEnumParameter( 'continue', $row->il_from .
+ '|' . $this->keyToTitle( $row->il_to ) );
break;
}
}
@@ -105,20 +106,20 @@ class ApiQueryImages extends ApiQueryGeneratorBase {
$titles = array();
$count = 0;
- while ($row = $db->fetchObject($res)) {
- if (++$count > $params['limit']) {
+ while ( $row = $db->fetchObject( $res ) ) {
+ if ( ++$count > $params['limit'] ) {
// We've reached the one extra which shows that
// there are additional pages to be had. Stop here...
- $this->setContinueEnumParameter('continue', $row->il_from .
- '|' . $this->keyToTitle($row->il_to));
+ $this->setContinueEnumParameter( 'continue', $row->il_from .
+ '|' . $this->keyToTitle( $row->il_to ) );
break;
}
- $titles[] = Title :: makeTitle(NS_FILE, $row->il_to);
+ $titles[] = Title :: makeTitle( NS_FILE, $row->il_to );
}
- $resultPageSet->populateFromTitles($titles);
+ $resultPageSet->populateFromTitles( $titles );
}
- $db->freeResult($res);
+ $db->freeResult( $res );
}
public function getCacheMode( $params ) {
@@ -148,6 +149,12 @@ class ApiQueryImages extends ApiQueryGeneratorBase {
public function getDescription() {
return 'Returns all images contained on the given page(s)';
}
+
+ public function getPossibleErrors() {
+ return array_merge( parent::getPossibleErrors(), array(
+ array( 'code' => '_badcontinue', 'info' => 'Invalid continue param. You should pass the original value returned by the previous query' ),
+ ) );
+ }
protected function getExamples() {
return array (
@@ -159,6 +166,6 @@ class ApiQueryImages extends ApiQueryGeneratorBase {
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiQueryImages.php 69986 2010-07-27 03:57:39Z tstarling $';
+ return __CLASS__ . ': $Id: ApiQueryImages.php 69932 2010-07-26 08:03:21Z tstarling $';
}
}
diff --git a/includes/api/ApiQueryInfo.php b/includes/api/ApiQueryInfo.php
index f78450b7..b1c2963c 100644
--- a/includes/api/ApiQueryInfo.php
+++ b/includes/api/ApiQueryInfo.php
@@ -23,9 +23,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ('ApiQueryBase.php');
+ require_once ( 'ApiQueryBase.php' );
}
/**
@@ -34,23 +34,24 @@ if (!defined('MEDIAWIKI')) {
* @ingroup API
*/
class ApiQueryInfo extends ApiQueryBase {
-
+
private $fld_protection = false, $fld_talkid = false,
$fld_subjectid = false, $fld_url = false,
- $fld_readable = false;
+ $fld_readable = false, $fld_watched = false,
+ $fld_preload = false;
- public function __construct($query, $moduleName) {
- parent :: __construct($query, $moduleName, 'in');
+ public function __construct( $query, $moduleName ) {
+ parent :: __construct( $query, $moduleName, 'in' );
}
- public function requestExtraData($pageSet) {
- $pageSet->requestField('page_restrictions');
- $pageSet->requestField('page_is_redirect');
- $pageSet->requestField('page_is_new');
- $pageSet->requestField('page_counter');
- $pageSet->requestField('page_touched');
- $pageSet->requestField('page_latest');
- $pageSet->requestField('page_len');
+ public function requestExtraData( $pageSet ) {
+ $pageSet->requestField( 'page_restrictions' );
+ $pageSet->requestField( 'page_is_redirect' );
+ $pageSet->requestField( 'page_is_new' );
+ $pageSet->requestField( 'page_counter' );
+ $pageSet->requestField( 'page_touched' );
+ $pageSet->requestField( 'page_latest' );
+ $pageSet->requestField( 'page_len' );
}
/**
@@ -61,11 +62,11 @@ class ApiQueryInfo extends ApiQueryBase {
*/
protected function getTokenFunctions() {
// Don't call the hooks twice
- if(isset($this->tokenFunctions))
+ if ( isset( $this->tokenFunctions ) )
return $this->tokenFunctions;
// If we're in JSON callback mode, no tokens can be obtained
- if(!is_null($this->getMain()->getRequest()->getVal('callback')))
+ if ( !is_null( $this->getMain()->getRequest()->getVal( 'callback' ) ) )
return array();
$this->tokenFunctions = array(
@@ -78,112 +79,112 @@ class ApiQueryInfo extends ApiQueryBase {
'email' => array( 'ApiQueryInfo', 'getEmailToken' ),
'import' => array( 'ApiQueryInfo', 'getImportToken' ),
);
- wfRunHooks('APIQueryInfoTokens', array(&$this->tokenFunctions));
+ wfRunHooks( 'APIQueryInfoTokens', array( &$this->tokenFunctions ) );
return $this->tokenFunctions;
}
- public static function getEditToken($pageid, $title)
+ public static function getEditToken( $pageid, $title )
{
// We could check for $title->userCan('edit') here,
// but that's too expensive for this purpose
// and would break caching
global $wgUser;
- if(!$wgUser->isAllowed('edit'))
+ if ( !$wgUser->isAllowed( 'edit' ) )
return false;
-
+
// The edit token is always the same, let's exploit that
static $cachedEditToken = null;
- if(!is_null($cachedEditToken))
+ if ( !is_null( $cachedEditToken ) )
return $cachedEditToken;
$cachedEditToken = $wgUser->editToken();
return $cachedEditToken;
}
-
- public static function getDeleteToken($pageid, $title)
+
+ public static function getDeleteToken( $pageid, $title )
{
global $wgUser;
- if(!$wgUser->isAllowed('delete'))
- return false;
+ if ( !$wgUser->isAllowed( 'delete' ) )
+ return false;
static $cachedDeleteToken = null;
- if(!is_null($cachedDeleteToken))
+ if ( !is_null( $cachedDeleteToken ) )
return $cachedDeleteToken;
$cachedDeleteToken = $wgUser->editToken();
return $cachedDeleteToken;
}
- public static function getProtectToken($pageid, $title)
+ public static function getProtectToken( $pageid, $title )
{
global $wgUser;
- if(!$wgUser->isAllowed('protect'))
+ if ( !$wgUser->isAllowed( 'protect' ) )
return false;
static $cachedProtectToken = null;
- if(!is_null($cachedProtectToken))
+ if ( !is_null( $cachedProtectToken ) )
return $cachedProtectToken;
$cachedProtectToken = $wgUser->editToken();
return $cachedProtectToken;
}
- public static function getMoveToken($pageid, $title)
+ public static function getMoveToken( $pageid, $title )
{
global $wgUser;
- if(!$wgUser->isAllowed('move'))
+ if ( !$wgUser->isAllowed( 'move' ) )
return false;
static $cachedMoveToken = null;
- if(!is_null($cachedMoveToken))
+ if ( !is_null( $cachedMoveToken ) )
return $cachedMoveToken;
$cachedMoveToken = $wgUser->editToken();
return $cachedMoveToken;
}
- public static function getBlockToken($pageid, $title)
+ public static function getBlockToken( $pageid, $title )
{
global $wgUser;
- if(!$wgUser->isAllowed('block'))
+ if ( !$wgUser->isAllowed( 'block' ) )
return false;
static $cachedBlockToken = null;
- if(!is_null($cachedBlockToken))
+ if ( !is_null( $cachedBlockToken ) )
return $cachedBlockToken;
$cachedBlockToken = $wgUser->editToken();
return $cachedBlockToken;
}
- public static function getUnblockToken($pageid, $title)
+ public static function getUnblockToken( $pageid, $title )
{
// Currently, this is exactly the same as the block token
- return self::getBlockToken($pageid, $title);
+ return self::getBlockToken( $pageid, $title );
}
- public static function getEmailToken($pageid, $title)
+ public static function getEmailToken( $pageid, $title )
{
global $wgUser;
- if(!$wgUser->canSendEmail() || $wgUser->isBlockedFromEmailUser())
+ if ( !$wgUser->canSendEmail() || $wgUser->isBlockedFromEmailUser() )
return false;
static $cachedEmailToken = null;
- if(!is_null($cachedEmailToken))
+ if ( !is_null( $cachedEmailToken ) )
return $cachedEmailToken;
$cachedEmailToken = $wgUser->editToken();
return $cachedEmailToken;
}
-
- public static function getImportToken($pageid, $title)
+
+ public static function getImportToken( $pageid, $title )
{
global $wgUser;
- if(!$wgUser->isAllowed('import'))
+ if ( !$wgUser->isAllowed( 'import' ) )
return false;
static $cachedImportToken = null;
- if(!is_null($cachedImportToken))
+ if ( !is_null( $cachedImportToken ) )
return $cachedImportToken;
$cachedImportToken = $wgUser->editToken();
@@ -192,13 +193,15 @@ class ApiQueryInfo extends ApiQueryBase {
public function execute() {
$this->params = $this->extractRequestParams();
- if(!is_null($this->params['prop'])) {
- $prop = array_flip($this->params['prop']);
- $this->fld_protection = isset($prop['protection']);
- $this->fld_talkid = isset($prop['talkid']);
- $this->fld_subjectid = isset($prop['subjectid']);
- $this->fld_url = isset($prop['url']);
- $this->fld_readable = isset($prop['readable']);
+ if ( !is_null( $this->params['prop'] ) ) {
+ $prop = array_flip( $this->params['prop'] );
+ $this->fld_protection = isset( $prop['protection'] );
+ $this->fld_watched = isset( $prop['watched'] );
+ $this->fld_talkid = isset( $prop['talkid'] );
+ $this->fld_subjectid = isset( $prop['subjectid'] );
+ $this->fld_url = isset( $prop['url'] );
+ $this->fld_readable = isset( $prop['readable'] );
+ $this->fld_preload = isset ( $prop['preload'] );
}
$pageSet = $this->getPageSet();
@@ -207,54 +210,57 @@ class ApiQueryInfo extends ApiQueryBase {
$this->everything = $this->titles + $this->missing;
$result = $this->getResult();
- uasort($this->everything, array('Title', 'compare'));
- if(!is_null($this->params['continue']))
+ uasort( $this->everything, array( 'Title', 'compare' ) );
+ if ( !is_null( $this->params['continue'] ) )
{
// Throw away any titles we're gonna skip so they don't
// clutter queries
- $cont = explode('|', $this->params['continue']);
- if(count($cont) != 2)
- $this->dieUsage("Invalid continue param. You should pass the original " .
- "value returned by the previous query", "_badcontinue");
- $conttitle = Title::makeTitleSafe($cont[0], $cont[1]);
- foreach($this->everything as $pageid => $title)
+ $cont = explode( '|', $this->params['continue'] );
+ if ( count( $cont ) != 2 )
+ $this->dieUsage( "Invalid continue param. You should pass the original " .
+ "value returned by the previous query", "_badcontinue" );
+ $conttitle = Title::makeTitleSafe( $cont[0], $cont[1] );
+ foreach ( $this->everything as $pageid => $title )
{
- if(Title::compare($title, $conttitle) >= 0)
+ if ( Title::compare( $title, $conttitle ) >= 0 )
break;
- unset($this->titles[$pageid]);
- unset($this->missing[$pageid]);
- unset($this->everything[$pageid]);
+ unset( $this->titles[$pageid] );
+ unset( $this->missing[$pageid] );
+ unset( $this->everything[$pageid] );
}
}
- $this->pageRestrictions = $pageSet->getCustomField('page_restrictions');
- $this->pageIsRedir = $pageSet->getCustomField('page_is_redirect');
- $this->pageIsNew = $pageSet->getCustomField('page_is_new');
- $this->pageCounter = $pageSet->getCustomField('page_counter');
- $this->pageTouched = $pageSet->getCustomField('page_touched');
- $this->pageLatest = $pageSet->getCustomField('page_latest');
- $this->pageLength = $pageSet->getCustomField('page_len');
+ $this->pageRestrictions = $pageSet->getCustomField( 'page_restrictions' );
+ $this->pageIsRedir = $pageSet->getCustomField( 'page_is_redirect' );
+ $this->pageIsNew = $pageSet->getCustomField( 'page_is_new' );
+ $this->pageCounter = $pageSet->getCustomField( 'page_counter' );
+ $this->pageTouched = $pageSet->getCustomField( 'page_touched' );
+ $this->pageLatest = $pageSet->getCustomField( 'page_latest' );
+ $this->pageLength = $pageSet->getCustomField( 'page_len' );
$db = $this->getDB();
// Get protection info if requested
- if ($this->fld_protection)
+ if ( $this->fld_protection )
$this->getProtectionInfo();
+ if ( $this->fld_watched )
+ $this->getWatchedInfo();
+
// Run the talkid/subjectid query if requested
- if($this->fld_talkid || $this->fld_subjectid)
+ if ( $this->fld_talkid || $this->fld_subjectid )
$this->getTSIDs();
- foreach($this->everything as $pageid => $title) {
- $pageInfo = $this->extractPageInfo($pageid, $title);
- $fit = $result->addValue(array (
+ foreach ( $this->everything as $pageid => $title ) {
+ $pageInfo = $this->extractPageInfo( $pageid, $title );
+ $fit = $result->addValue( array (
'query',
'pages'
- ), $pageid, $pageInfo);
- if(!$fit)
+ ), $pageid, $pageInfo );
+ if ( !$fit )
{
- $this->setContinueEnumParameter('continue',
+ $this->setContinueEnumParameter( 'continue',
$title->getNamespace() . '|' .
- $title->getText());
+ $title->getText() );
break;
}
}
@@ -266,52 +272,67 @@ class ApiQueryInfo extends ApiQueryBase {
* @param $title Title object
* @return array
*/
- private function extractPageInfo($pageid, $title)
+ private function extractPageInfo( $pageid, $title )
{
$pageInfo = array();
- if($title->exists())
+ if ( $title->exists() )
{
- $pageInfo['touched'] = wfTimestamp(TS_ISO_8601, $this->pageTouched[$pageid]);
- $pageInfo['lastrevid'] = intval($this->pageLatest[$pageid]);
- $pageInfo['counter'] = intval($this->pageCounter[$pageid]);
- $pageInfo['length'] = intval($this->pageLength[$pageid]);
- if ($this->pageIsRedir[$pageid])
+ $pageInfo['touched'] = wfTimestamp( TS_ISO_8601, $this->pageTouched[$pageid] );
+ $pageInfo['lastrevid'] = intval( $this->pageLatest[$pageid] );
+ $pageInfo['counter'] = intval( $this->pageCounter[$pageid] );
+ $pageInfo['length'] = intval( $this->pageLength[$pageid] );
+ if ( $this->pageIsRedir[$pageid] )
$pageInfo['redirect'] = '';
- if ($this->pageIsNew[$pageid])
+ if ( $this->pageIsNew[$pageid] )
$pageInfo['new'] = '';
}
- if (!is_null($this->params['token'])) {
+ if ( !is_null( $this->params['token'] ) ) {
$tokenFunctions = $this->getTokenFunctions();
- $pageInfo['starttimestamp'] = wfTimestamp(TS_ISO_8601, time());
- foreach($this->params['token'] as $t)
+ $pageInfo['starttimestamp'] = wfTimestamp( TS_ISO_8601, time() );
+ foreach ( $this->params['token'] as $t )
{
- $val = call_user_func($tokenFunctions[$t], $pageid, $title);
- if($val === false)
- $this->setWarning("Action '$t' is not allowed for the current user");
+ $val = call_user_func( $tokenFunctions[$t], $pageid, $title );
+ if ( $val === false )
+ $this->setWarning( "Action '$t' is not allowed for the current user" );
else
$pageInfo[$t . 'token'] = $val;
}
}
- if($this->fld_protection) {
+ if ( $this->fld_protection ) {
$pageInfo['protection'] = array();
- if (isset($this->protections[$title->getNamespace()][$title->getDBkey()]))
+ if ( isset( $this->protections[$title->getNamespace()][$title->getDBkey()] ) )
$pageInfo['protection'] =
$this->protections[$title->getNamespace()][$title->getDBkey()];
- $this->getResult()->setIndexedTagName($pageInfo['protection'], 'pr');
+ $this->getResult()->setIndexedTagName( $pageInfo['protection'], 'pr' );
}
- if($this->fld_talkid && isset($this->talkids[$title->getNamespace()][$title->getDBKey()]))
- $pageInfo['talkid'] = $this->talkids[$title->getNamespace()][$title->getDBKey()];
- if($this->fld_subjectid && isset($this->subjectids[$title->getNamespace()][$title->getDBKey()]))
- $pageInfo['subjectid'] = $this->subjectids[$title->getNamespace()][$title->getDBKey()];
- if($this->fld_url) {
+
+ if ( $this->fld_watched && isset( $this->watched[$title->getNamespace()][$title->getDBkey()] ) )
+ $pageInfo['watched'] = '';
+
+ if ( $this->fld_talkid && isset( $this->talkids[$title->getNamespace()][$title->getDBkey()] ) )
+ $pageInfo['talkid'] = $this->talkids[$title->getNamespace()][$title->getDBkey()];
+
+ if ( $this->fld_subjectid && isset( $this->subjectids[$title->getNamespace()][$title->getDBkey()] ) )
+ $pageInfo['subjectid'] = $this->subjectids[$title->getNamespace()][$title->getDBkey()];
+
+ if ( $this->fld_url ) {
$pageInfo['fullurl'] = $title->getFullURL();
- $pageInfo['editurl'] = $title->getFullURL('action=edit');
+ $pageInfo['editurl'] = $title->getFullURL( 'action=edit' );
+ }
+ if ( $this->fld_readable && $title->userCanRead() )
+ $pageInfo['readable'] = '';
+
+ if ( $this->fld_preload ) {
+ if ( $title->exists() )
+ $pageInfo['preload'] = '';
+ else {
+ wfRunHooks( 'EditFormPreloadText', array( &$text, &$title ) );
+
+ $pageInfo['preload'] = $text;
+ }
}
- if($this->fld_readable)
- if($title->userCanRead())
- $pageInfo['readable'] = '';
return $pageInfo;
}
@@ -324,36 +345,37 @@ class ApiQueryInfo extends ApiQueryBase {
$db = $this->getDB();
// Get normal protections for existing titles
- if(count($this->titles))
+ if ( count( $this->titles ) )
{
- $this->addTables(array('page_restrictions', 'page'));
- $this->addWhere('page_id=pr_page');
- $this->addFields(array('pr_page', 'pr_type', 'pr_level',
+ $this->resetQueryParams();
+ $this->addTables( array( 'page_restrictions', 'page' ) );
+ $this->addWhere( 'page_id=pr_page' );
+ $this->addFields( array( 'pr_page', 'pr_type', 'pr_level',
'pr_expiry', 'pr_cascade', 'page_namespace',
- 'page_title'));
- $this->addWhereFld('pr_page', array_keys($this->titles));
+ 'page_title' ) );
+ $this->addWhereFld( 'pr_page', array_keys( $this->titles ) );
- $res = $this->select(__METHOD__);
- while($row = $db->fetchObject($res)) {
+ $res = $this->select( __METHOD__ );
+ while ( $row = $db->fetchObject( $res ) ) {
$a = array(
'type' => $row->pr_type,
'level' => $row->pr_level,
- 'expiry' => Block::decodeExpiry($row->pr_expiry, TS_ISO_8601)
+ 'expiry' => Block::decodeExpiry( $row->pr_expiry, TS_ISO_8601 )
);
- if($row->pr_cascade)
+ if ( $row->pr_cascade )
$a['cascade'] = '';
$this->protections[$row->page_namespace][$row->page_title][] = $a;
- # Also check old restrictions
- if($this->pageRestrictions[$row->pr_page]) {
- $restrictions = explode(':', trim($this->pageRestrictions[$row->pr_page]));
- foreach($restrictions as $restrict) {
- $temp = explode('=', trim($restrict));
- if(count($temp) == 1) {
+ // Also check old restrictions
+ if ( $this->pageRestrictions[$row->pr_page] ) {
+ $restrictions = explode( ':', trim( $this->pageRestrictions[$row->pr_page] ) );
+ foreach ( $restrictions as $restrict ) {
+ $temp = explode( '=', trim( $restrict ) );
+ if ( count( $temp ) == 1 ) {
// old old format should be treated as edit/move restriction
- $restriction = trim($temp[0]);
+ $restriction = trim( $temp[0] );
- if($restriction == '')
+ if ( $restriction == '' )
continue;
$this->protections[$row->page_namespace][$row->page_title][] = array(
'type' => 'edit',
@@ -366,8 +388,8 @@ class ApiQueryInfo extends ApiQueryBase {
'expiry' => 'infinity',
);
} else {
- $restriction = trim($temp[1]);
- if($restriction == '')
+ $restriction = trim( $temp[1] );
+ if ( $restriction == '' )
continue;
$this->protections[$row->page_namespace][$row->page_title][] = array(
'type' => $temp[0],
@@ -378,84 +400,84 @@ class ApiQueryInfo extends ApiQueryBase {
}
}
}
- $db->freeResult($res);
+ $db->freeResult( $res );
}
// Get protections for missing titles
- if(count($this->missing))
+ if ( count( $this->missing ) )
{
$this->resetQueryParams();
- $lb = new LinkBatch($this->missing);
- $this->addTables('protected_titles');
- $this->addFields(array('pt_title', 'pt_namespace', 'pt_create_perm', 'pt_expiry'));
- $this->addWhere($lb->constructSet('pt', $db));
- $res = $this->select(__METHOD__);
- while($row = $db->fetchObject($res)) {
+ $lb = new LinkBatch( $this->missing );
+ $this->addTables( 'protected_titles' );
+ $this->addFields( array( 'pt_title', 'pt_namespace', 'pt_create_perm', 'pt_expiry' ) );
+ $this->addWhere( $lb->constructSet( 'pt', $db ) );
+ $res = $this->select( __METHOD__ );
+ while ( $row = $db->fetchObject( $res ) ) {
$this->protections[$row->pt_namespace][$row->pt_title][] = array(
'type' => 'create',
'level' => $row->pt_create_perm,
- 'expiry' => Block::decodeExpiry($row->pt_expiry, TS_ISO_8601)
+ 'expiry' => Block::decodeExpiry( $row->pt_expiry, TS_ISO_8601 )
);
}
- $db->freeResult($res);
+ $db->freeResult( $res );
}
// Cascading protections
$images = $others = array();
- foreach ($this->everything as $title)
- if ($title->getNamespace() == NS_FILE)
- $images[] = $title->getDBKey();
+ foreach ( $this->everything as $title )
+ if ( $title->getNamespace() == NS_FILE )
+ $images[] = $title->getDBkey();
else
$others[] = $title;
- if (count($others)) {
+ if ( count( $others ) ) {
// Non-images: check templatelinks
- $lb = new LinkBatch($others);
+ $lb = new LinkBatch( $others );
$this->resetQueryParams();
- $this->addTables(array('page_restrictions', 'page', 'templatelinks'));
- $this->addFields(array('pr_type', 'pr_level', 'pr_expiry',
+ $this->addTables( array( 'page_restrictions', 'page', 'templatelinks' ) );
+ $this->addFields( array( 'pr_type', 'pr_level', 'pr_expiry',
'page_title', 'page_namespace',
- 'tl_title', 'tl_namespace'));
- $this->addWhere($lb->constructSet('tl', $db));
- $this->addWhere('pr_page = page_id');
- $this->addWhere('pr_page = tl_from');
- $this->addWhereFld('pr_cascade', 1);
-
- $res = $this->select(__METHOD__);
- while($row = $db->fetchObject($res)) {
- $source = Title::makeTitle($row->page_namespace, $row->page_title);
+ 'tl_title', 'tl_namespace' ) );
+ $this->addWhere( $lb->constructSet( 'tl', $db ) );
+ $this->addWhere( 'pr_page = page_id' );
+ $this->addWhere( 'pr_page = tl_from' );
+ $this->addWhereFld( 'pr_cascade', 1 );
+
+ $res = $this->select( __METHOD__ );
+ while ( $row = $db->fetchObject( $res ) ) {
+ $source = Title::makeTitle( $row->page_namespace, $row->page_title );
$this->protections[$row->tl_namespace][$row->tl_title][] = array(
'type' => $row->pr_type,
'level' => $row->pr_level,
- 'expiry' => Block::decodeExpiry($row->pr_expiry, TS_ISO_8601),
+ 'expiry' => Block::decodeExpiry( $row->pr_expiry, TS_ISO_8601 ),
'source' => $source->getPrefixedText()
);
}
- $db->freeResult($res);
+ $db->freeResult( $res );
}
- if (count($images)) {
+ if ( count( $images ) ) {
// Images: check imagelinks
$this->resetQueryParams();
- $this->addTables(array('page_restrictions', 'page', 'imagelinks'));
- $this->addFields(array('pr_type', 'pr_level', 'pr_expiry',
- 'page_title', 'page_namespace', 'il_to'));
- $this->addWhere('pr_page = page_id');
- $this->addWhere('pr_page = il_from');
- $this->addWhereFld('pr_cascade', 1);
- $this->addWhereFld('il_to', $images);
-
- $res = $this->select(__METHOD__);
- while($row = $db->fetchObject($res)) {
- $source = Title::makeTitle($row->page_namespace, $row->page_title);
+ $this->addTables( array( 'page_restrictions', 'page', 'imagelinks' ) );
+ $this->addFields( array( 'pr_type', 'pr_level', 'pr_expiry',
+ 'page_title', 'page_namespace', 'il_to' ) );
+ $this->addWhere( 'pr_page = page_id' );
+ $this->addWhere( 'pr_page = il_from' );
+ $this->addWhereFld( 'pr_cascade', 1 );
+ $this->addWhereFld( 'il_to', $images );
+
+ $res = $this->select( __METHOD__ );
+ while ( $row = $db->fetchObject( $res ) ) {
+ $source = Title::makeTitle( $row->page_namespace, $row->page_title );
$this->protections[NS_FILE][$row->il_to][] = array(
'type' => $row->pr_type,
'level' => $row->pr_level,
- 'expiry' => Block::decodeExpiry($row->pr_expiry, TS_ISO_8601),
+ 'expiry' => Block::decodeExpiry( $row->pr_expiry, TS_ISO_8601 ),
'source' => $source->getPrefixedText()
);
}
- $db->freeResult($res);
+ $db->freeResult( $res );
}
}
@@ -467,35 +489,67 @@ class ApiQueryInfo extends ApiQueryBase {
{
$getTitles = $this->talkids = $this->subjectids = array();
$db = $this->getDB();
- foreach($this->everything as $t)
+ foreach ( $this->everything as $t )
{
- if(MWNamespace::isTalk($t->getNamespace()))
+ if ( MWNamespace::isTalk( $t->getNamespace() ) )
{
- if($this->fld_subjectid)
+ if ( $this->fld_subjectid )
$getTitles[] = $t->getSubjectPage();
}
- else if($this->fld_talkid)
+ else if ( $this->fld_talkid )
$getTitles[] = $t->getTalkPage();
}
- if(!count($getTitles))
+ if ( !count( $getTitles ) )
return;
-
+
// Construct a custom WHERE clause that matches
// all titles in $getTitles
- $lb = new LinkBatch($getTitles);
+ $lb = new LinkBatch( $getTitles );
$this->resetQueryParams();
- $this->addTables('page');
- $this->addFields(array('page_title', 'page_namespace', 'page_id'));
- $this->addWhere($lb->constructSet('page', $db));
- $res = $this->select(__METHOD__);
- while($row = $db->fetchObject($res))
+ $this->addTables( 'page' );
+ $this->addFields( array( 'page_title', 'page_namespace', 'page_id' ) );
+ $this->addWhere( $lb->constructSet( 'page', $db ) );
+ $res = $this->select( __METHOD__ );
+ while ( $row = $db->fetchObject( $res ) )
{
- if(MWNamespace::isTalk($row->page_namespace))
- $this->talkids[MWNamespace::getSubject($row->page_namespace)][$row->page_title] =
- intval($row->page_id);
+ if ( MWNamespace::isTalk( $row->page_namespace ) )
+ $this->talkids[MWNamespace::getSubject( $row->page_namespace )][$row->page_title] =
+ intval( $row->page_id );
else
- $this->subjectids[MWNamespace::getTalk($row->page_namespace)][$row->page_title] =
- intval($row->page_id);
+ $this->subjectids[MWNamespace::getTalk( $row->page_namespace )][$row->page_title] =
+ intval( $row->page_id );
+ }
+ }
+
+ /**
+ * Get information about watched status and put it in $this->watched
+ */
+ private function getWatchedInfo()
+ {
+ global $wgUser;
+
+ if ( $wgUser->isAnon() || count( $this->titles ) == 0 )
+ return;
+
+ $this->watched = array();
+ $db = $this->getDB();
+
+ $lb = new LinkBatch( $this->titles );
+
+ $this->resetQueryParams();
+ $this->addTables( array( 'page', 'watchlist' ) );
+ $this->addFields( array( 'page_title', 'page_namespace' ) );
+ $this->addWhere( array(
+ $lb->constructSet( 'page', $db ),
+ 'wl_namespace=page_namespace',
+ 'wl_title=page_title',
+ 'wl_user' => $wgUser->getID()
+ ) );
+
+ $res = $this->select( __METHOD__ );
+
+ while ( $row = $db->fetchObject( $res ) ) {
+ $this->watched[$row->page_namespace][$row->page_title] = true;
}
}
@@ -505,6 +559,7 @@ class ApiQueryInfo extends ApiQueryBase {
'talkid',
'subjectid',
'url',
+ 'preload',
);
if ( !is_null( $params['prop'] ) ) {
foreach ( $params['prop'] as $prop ) {
@@ -522,21 +577,23 @@ class ApiQueryInfo extends ApiQueryBase {
public function getAllowedParams() {
return array (
'prop' => array (
- ApiBase :: PARAM_DFLT => NULL,
+ ApiBase :: PARAM_DFLT => null,
ApiBase :: PARAM_ISMULTI => true,
ApiBase :: PARAM_TYPE => array (
'protection',
'talkid',
+ 'watched', # private
'subjectid',
'url',
'readable', # private
+ 'preload'
// If you add more properties here, please consider whether they
// need to be added to getCacheMode()
- )),
+ ) ),
'token' => array (
- ApiBase :: PARAM_DFLT => NULL,
+ ApiBase :: PARAM_DFLT => null,
ApiBase :: PARAM_ISMULTI => true,
- ApiBase :: PARAM_TYPE => array_keys($this->getTokenFunctions())
+ ApiBase :: PARAM_TYPE => array_keys( $this->getTokenFunctions() )
),
'continue' => null,
);
@@ -548,7 +605,11 @@ class ApiQueryInfo extends ApiQueryBase {
'Which additional properties to get:',
' protection - List the protection level of each page',
' talkid - The page ID of the talk page for each non-talk page',
- ' subjectid - The page ID of the parent page for each talk page'
+ ' watched - List the watched status of each page',
+ ' subjectid - The page ID of the parent page for each talk page',
+ ' url - Gives a full URL to the page, and also an edit URL',
+ ' readable - Whether the user can read this page',
+ ' preload - Gives the text returned by EditFormPreloadText'
),
'token' => 'Request a token to perform a data-modifying action on a page',
'continue' => 'When more results are available, use this to continue',
@@ -558,6 +619,12 @@ class ApiQueryInfo extends ApiQueryBase {
public function getDescription() {
return 'Get basic page information such as namespace, title, last touched date, ...';
}
+
+ public function getPossibleErrors() {
+ return array_merge( parent::getPossibleErrors(), array(
+ array( 'code' => '_badcontinue', 'info' => 'Invalid continue param. You should pass the original value returned by the previous query' ),
+ ) );
+ }
protected function getExamples() {
return array (
@@ -567,6 +634,6 @@ class ApiQueryInfo extends ApiQueryBase {
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiQueryInfo.php 69986 2010-07-27 03:57:39Z tstarling $';
+ return __CLASS__ . ': $Id: ApiQueryInfo.php 69932 2010-07-26 08:03:21Z tstarling $';
}
}
diff --git a/includes/api/ApiQueryLangLinks.php b/includes/api/ApiQueryLangLinks.php
index 35f7e67c..9330e380 100644
--- a/includes/api/ApiQueryLangLinks.php
+++ b/includes/api/ApiQueryLangLinks.php
@@ -23,9 +23,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ("ApiQueryBase.php");
+ require_once ( "ApiQueryBase.php" );
}
/**
@@ -35,8 +35,8 @@ if (!defined('MEDIAWIKI')) {
*/
class ApiQueryLangLinks extends ApiQueryBase {
- public function __construct($query, $moduleName) {
- parent :: __construct($query, $moduleName, 'll');
+ public function __construct( $query, $moduleName ) {
+ parent :: __construct( $query, $moduleName, 'll' );
}
public function execute() {
@@ -44,52 +44,53 @@ class ApiQueryLangLinks extends ApiQueryBase {
return;
$params = $this->extractRequestParams();
- $this->addFields(array (
+ $this->addFields( array (
'll_from',
'll_lang',
'll_title'
- ));
+ ) );
- $this->addTables('langlinks');
- $this->addWhereFld('ll_from', array_keys($this->getPageSet()->getGoodTitles()));
- if(!is_null($params['continue'])) {
- $cont = explode('|', $params['continue']);
- if(count($cont) != 2)
- $this->dieUsage("Invalid continue param. You should pass the " .
- "original value returned by the previous query", "_badcontinue");
- $llfrom = intval($cont[0]);
- $lllang = $this->getDB()->strencode($cont[1]);
- $this->addWhere("ll_from > $llfrom OR ".
- "(ll_from = $llfrom AND ".
- "ll_lang >= '$lllang')");
+ $this->addTables( 'langlinks' );
+ $this->addWhereFld( 'll_from', array_keys( $this->getPageSet()->getGoodTitles() ) );
+ if ( !is_null( $params['continue'] ) ) {
+ $cont = explode( '|', $params['continue'] );
+ if ( count( $cont ) != 2 )
+ $this->dieUsage( "Invalid continue param. You should pass the " .
+ "original value returned by the previous query", "_badcontinue" );
+ $llfrom = intval( $cont[0] );
+ $lllang = $this->getDB()->strencode( $cont[1] );
+ $this->addWhere( "ll_from > $llfrom OR " .
+ "(ll_from = $llfrom AND " .
+ "ll_lang >= '$lllang')" );
}
- # Don't order by ll_from if it's constant in the WHERE clause
- if(count($this->getPageSet()->getGoodTitles()) == 1)
- $this->addOption('ORDER BY', 'll_lang');
+
+ // Don't order by ll_from if it's constant in the WHERE clause
+ if ( count( $this->getPageSet()->getGoodTitles() ) == 1 )
+ $this->addOption( 'ORDER BY', 'll_lang' );
else
- $this->addOption('ORDER BY', 'll_from, ll_lang');
- $this->addOption('LIMIT', $params['limit'] + 1);
- $res = $this->select(__METHOD__);
+ $this->addOption( 'ORDER BY', 'll_from, ll_lang' );
+ $this->addOption( 'LIMIT', $params['limit'] + 1 );
+ $res = $this->select( __METHOD__ );
$count = 0;
$db = $this->getDB();
- while ($row = $db->fetchObject($res)) {
- if (++$count > $params['limit']) {
+ while ( $row = $db->fetchObject( $res ) ) {
+ if ( ++$count > $params['limit'] ) {
// We've reached the one extra which shows that
// there are additional pages to be had. Stop here...
- $this->setContinueEnumParameter('continue', "{$row->ll_from}|{$row->ll_lang}");
+ $this->setContinueEnumParameter( 'continue', "{$row->ll_from}|{$row->ll_lang}" );
break;
}
- $entry = array('lang' => $row->ll_lang);
- ApiResult :: setContent($entry, $row->ll_title);
- $fit = $this->addPageSubItem($row->ll_from, $entry);
- if(!$fit)
+ $entry = array( 'lang' => $row->ll_lang );
+ ApiResult :: setContent( $entry, $row->ll_title );
+ $fit = $this->addPageSubItem( $row->ll_from, $entry );
+ if ( !$fit )
{
- $this->setContinueEnumParameter('continue', "{$row->ll_from}|{$row->ll_lang}");
+ $this->setContinueEnumParameter( 'continue', "{$row->ll_from}|{$row->ll_lang}" );
break;
}
}
- $db->freeResult($res);
+ $db->freeResult( $res );
}
public function getCacheMode( $params ) {
@@ -119,6 +120,12 @@ class ApiQueryLangLinks extends ApiQueryBase {
public function getDescription() {
return 'Returns all interlanguage links from the given page(s)';
}
+
+ public function getPossibleErrors() {
+ return array_merge( parent::getPossibleErrors(), array(
+ array( 'code' => '_badcontinue', 'info' => 'Invalid continue param. You should pass the original value returned by the previous query' ),
+ ) );
+ }
protected function getExamples() {
return array (
@@ -128,6 +135,6 @@ class ApiQueryLangLinks extends ApiQueryBase {
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiQueryLangLinks.php 69986 2010-07-27 03:57:39Z tstarling $';
+ return __CLASS__ . ': $Id: ApiQueryLangLinks.php 69932 2010-07-26 08:03:21Z tstarling $';
}
}
diff --git a/includes/api/ApiQueryLinks.php b/includes/api/ApiQueryLinks.php
index 94b7980c..52dfd591 100644
--- a/includes/api/ApiQueryLinks.php
+++ b/includes/api/ApiQueryLinks.php
@@ -23,9 +23,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ("ApiQueryBase.php");
+ require_once ( "ApiQueryBase.php" );
}
/**
@@ -40,9 +40,9 @@ class ApiQueryLinks extends ApiQueryGeneratorBase {
private $table, $prefix, $description;
- public function __construct($query, $moduleName) {
+ public function __construct( $query, $moduleName ) {
- switch ($moduleName) {
+ switch ( $moduleName ) {
case self::LINKS :
$this->table = 'pagelinks';
$this->prefix = 'pl';
@@ -54,10 +54,10 @@ class ApiQueryLinks extends ApiQueryGeneratorBase {
$this->description = 'template';
break;
default :
- ApiBase :: dieDebug(__METHOD__, 'Unknown module name');
+ ApiBase :: dieDebug( __METHOD__, 'Unknown module name' );
}
- parent :: __construct($query, $moduleName, $this->prefix);
+ parent :: __construct( $query, $moduleName, $this->prefix );
}
public function execute() {
@@ -68,101 +68,101 @@ class ApiQueryLinks extends ApiQueryGeneratorBase {
return 'public';
}
- public function executeGenerator($resultPageSet) {
- $this->run($resultPageSet);
+ public function executeGenerator( $resultPageSet ) {
+ $this->run( $resultPageSet );
}
- private function run($resultPageSet = null) {
+ private function run( $resultPageSet = null ) {
- if ($this->getPageSet()->getGoodTitleCount() == 0)
+ if ( $this->getPageSet()->getGoodTitleCount() == 0 )
return; // nothing to do
$params = $this->extractRequestParams();
- $this->addFields(array (
+ $this->addFields( array (
$this->prefix . '_from AS pl_from',
$this->prefix . '_namespace AS pl_namespace',
$this->prefix . '_title AS pl_title'
- ));
-
- $this->addTables($this->table);
- $this->addWhereFld($this->prefix . '_from', array_keys($this->getPageSet()->getGoodTitles()));
- $this->addWhereFld($this->prefix . '_namespace', $params['namespace']);
-
- if(!is_null($params['continue'])) {
- $cont = explode('|', $params['continue']);
- if(count($cont) != 3)
- $this->dieUsage("Invalid continue param. You should pass the " .
- "original value returned by the previous query", "_badcontinue");
- $plfrom = intval($cont[0]);
- $plns = intval($cont[1]);
- $pltitle = $this->getDB()->strencode($this->titleToKey($cont[2]));
- $this->addWhere("{$this->prefix}_from > $plfrom OR ".
- "({$this->prefix}_from = $plfrom AND ".
- "({$this->prefix}_namespace > $plns OR ".
- "({$this->prefix}_namespace = $plns AND ".
- "{$this->prefix}_title >= '$pltitle')))");
+ ) );
+
+ $this->addTables( $this->table );
+ $this->addWhereFld( $this->prefix . '_from', array_keys( $this->getPageSet()->getGoodTitles() ) );
+ $this->addWhereFld( $this->prefix . '_namespace', $params['namespace'] );
+
+ if ( !is_null( $params['continue'] ) ) {
+ $cont = explode( '|', $params['continue'] );
+ if ( count( $cont ) != 3 )
+ $this->dieUsage( "Invalid continue param. You should pass the " .
+ "original value returned by the previous query", "_badcontinue" );
+ $plfrom = intval( $cont[0] );
+ $plns = intval( $cont[1] );
+ $pltitle = $this->getDB()->strencode( $this->titleToKey( $cont[2] ) );
+ $this->addWhere( "{$this->prefix}_from > $plfrom OR " .
+ "({$this->prefix}_from = $plfrom AND " .
+ "({$this->prefix}_namespace > $plns OR " .
+ "({$this->prefix}_namespace = $plns AND " .
+ "{$this->prefix}_title >= '$pltitle')))" );
}
- # Here's some MySQL craziness going on: if you use WHERE foo='bar'
- # and later ORDER BY foo MySQL doesn't notice the ORDER BY is pointless
- # but instead goes and filesorts, because the index for foo was used
- # already. To work around this, we drop constant fields in the WHERE
- # clause from the ORDER BY clause
+ // Here's some MySQL craziness going on: if you use WHERE foo='bar'
+ // and later ORDER BY foo MySQL doesn't notice the ORDER BY is pointless
+ // but instead goes and filesorts, because the index for foo was used
+ // already. To work around this, we drop constant fields in the WHERE
+ // clause from the ORDER BY clause
$order = array();
- if(count($this->getPageSet()->getGoodTitles()) != 1)
+ if ( count( $this->getPageSet()->getGoodTitles() ) != 1 )
$order[] = "{$this->prefix}_from";
- if(count($params['namespace']) != 1)
+ if ( count( $params['namespace'] ) != 1 )
$order[] = "{$this->prefix}_namespace";
+
$order[] = "{$this->prefix}_title";
- $this->addOption('ORDER BY', implode(", ", $order));
- $this->addOption('USE INDEX', "{$this->prefix}_from");
- $this->addOption('LIMIT', $params['limit'] + 1);
+ $this->addOption( 'ORDER BY', implode( ", ", $order ) );
+ $this->addOption( 'USE INDEX', "{$this->prefix}_from" );
+ $this->addOption( 'LIMIT', $params['limit'] + 1 );
$db = $this->getDB();
- $res = $this->select(__METHOD__);
+ $res = $this->select( __METHOD__ );
- if (is_null($resultPageSet)) {
+ if ( is_null( $resultPageSet ) ) {
$count = 0;
- while ($row = $db->fetchObject($res)) {
- if(++$count > $params['limit']) {
+ while ( $row = $db->fetchObject( $res ) ) {
+ if ( ++$count > $params['limit'] ) {
// We've reached the one extra which shows that
// there are additional pages to be had. Stop here...
- $this->setContinueEnumParameter('continue',
+ $this->setContinueEnumParameter( 'continue',
"{$row->pl_from}|{$row->pl_namespace}|" .
- $this->keyToTitle($row->pl_title));
+ $this->keyToTitle( $row->pl_title ) );
break;
}
$vals = array();
- ApiQueryBase :: addTitleInfo($vals, Title :: makeTitle($row->pl_namespace, $row->pl_title));
- $fit = $this->addPageSubItem($row->pl_from, $vals);
- if(!$fit)
+ ApiQueryBase :: addTitleInfo( $vals, Title :: makeTitle( $row->pl_namespace, $row->pl_title ) );
+ $fit = $this->addPageSubItem( $row->pl_from, $vals );
+ if ( !$fit )
{
- $this->setContinueEnumParameter('continue',
+ $this->setContinueEnumParameter( 'continue',
"{$row->pl_from}|{$row->pl_namespace}|" .
- $this->keyToTitle($row->pl_title));
+ $this->keyToTitle( $row->pl_title ) );
break;
}
}
} else {
-
$titles = array();
$count = 0;
- while ($row = $db->fetchObject($res)) {
- if(++$count > $params['limit']) {
+ while ( $row = $db->fetchObject( $res ) ) {
+ if ( ++$count > $params['limit'] ) {
// We've reached the one extra which shows that
// there are additional pages to be had. Stop here...
- $this->setContinueEnumParameter('continue',
+ $this->setContinueEnumParameter( 'continue',
"{$row->pl_from}|{$row->pl_namespace}|" .
- $this->keyToTitle($row->pl_title));
+ $this->keyToTitle( $row->pl_title ) );
break;
}
- $titles[] = Title :: makeTitle($row->pl_namespace, $row->pl_title);
+ $titles[] = Title :: makeTitle( $row->pl_namespace, $row->pl_title );
}
- $resultPageSet->populateFromTitles($titles);
+ $resultPageSet->populateFromTitles( $titles );
}
- $db->freeResult($res);
+ $db->freeResult( $res );
}
public function getAllowedParams()
@@ -208,6 +208,6 @@ class ApiQueryLinks extends ApiQueryGeneratorBase {
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiQueryLinks.php 69986 2010-07-27 03:57:39Z tstarling $';
+ return __CLASS__ . ': $Id: ApiQueryLinks.php 69932 2010-07-26 08:03:21Z tstarling $';
}
}
diff --git a/includes/api/ApiQueryLogEvents.php b/includes/api/ApiQueryLogEvents.php
index 7afed844..bdeee952 100644
--- a/includes/api/ApiQueryLogEvents.php
+++ b/includes/api/ApiQueryLogEvents.php
@@ -23,9 +23,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ('ApiQueryBase.php');
+ require_once ( 'ApiQueryBase.php' );
}
/**
@@ -35,136 +35,153 @@ if (!defined('MEDIAWIKI')) {
*/
class ApiQueryLogEvents extends ApiQueryBase {
- public function __construct($query, $moduleName) {
- parent :: __construct($query, $moduleName, 'le');
+ public function __construct( $query, $moduleName ) {
+ parent :: __construct( $query, $moduleName, 'le' );
}
public function execute() {
$params = $this->extractRequestParams();
$db = $this->getDB();
-
- $prop = $params['prop'];
- $this->fld_ids = in_array('ids', $prop);
- $this->fld_title = in_array('title', $prop);
- $this->fld_type = in_array('type', $prop);
- $this->fld_user = in_array('user', $prop);
- $this->fld_timestamp = in_array('timestamp', $prop);
- $this->fld_comment = in_array('comment', $prop);
- $this->fld_details = in_array('details', $prop);
-
- list($tbl_logging, $tbl_page, $tbl_user) = $db->tableNamesN('logging', 'page', 'user');
-
- $hideLogs = LogEventsList::getExcludeClause($db);
- if($hideLogs !== false)
- $this->addWhere($hideLogs);
+
+ $prop = array_flip( $params['prop'] );
+
+ $this->fld_ids = isset( $prop['ids'] );
+ $this->fld_title = isset( $prop['title'] );
+ $this->fld_type = isset( $prop['type'] );
+ $this->fld_user = isset( $prop['user'] );
+ $this->fld_timestamp = isset( $prop['timestamp'] );
+ $this->fld_comment = isset( $prop['comment'] );
+ $this->fld_parsedcomment = isset ( $prop['parsedcomment'] );
+ $this->fld_details = isset( $prop['details'] );
+ $this->fld_tags = isset( $prop['tags'] );
+
+ list( $tbl_logging, $tbl_page, $tbl_user ) = $db->tableNamesN( 'logging', 'page', 'user' );
+
+ $hideLogs = LogEventsList::getExcludeClause( $db );
+ if ( $hideLogs !== false )
+ $this->addWhere( $hideLogs );
// Order is significant here
- $this->addTables(array('logging', 'user', 'page'));
- $this->addOption('STRAIGHT_JOIN');
- $this->addJoinConds(array(
- 'user' => array('JOIN',
- 'user_id=log_user'),
- 'page' => array('LEFT JOIN',
+ $this->addTables( array( 'logging', 'user', 'page' ) );
+ $this->addOption( 'STRAIGHT_JOIN' );
+ $this->addJoinConds( array(
+ 'user' => array( 'JOIN',
+ 'user_id=log_user' ),
+ 'page' => array( 'LEFT JOIN',
array( 'log_namespace=page_namespace',
- 'log_title=page_title'))));
- $index = 'times'; // default, may change
+ 'log_title=page_title' ) ) ) );
+ $index = array( 'logging' => 'times' ); // default, may change
- $this->addFields(array (
+ $this->addFields( array (
'log_type',
'log_action',
'log_timestamp',
'log_deleted',
- ));
-
- $this->addFieldsIf('log_id', $this->fld_ids);
- $this->addFieldsIf('page_id', $this->fld_ids);
- $this->addFieldsIf('log_user', $this->fld_user);
- $this->addFieldsIf('user_name', $this->fld_user);
- $this->addFieldsIf('log_namespace', $this->fld_title);
- $this->addFieldsIf('log_title', $this->fld_title);
- $this->addFieldsIf('log_comment', $this->fld_comment);
- $this->addFieldsIf('log_params', $this->fld_details);
+ ) );
+
+ $this->addFieldsIf( 'log_id', $this->fld_ids );
+ $this->addFieldsIf( 'page_id', $this->fld_ids );
+ $this->addFieldsIf( 'log_user', $this->fld_user );
+ $this->addFieldsIf( 'user_name', $this->fld_user );
+ $this->addFieldsIf( 'log_namespace', $this->fld_title );
+ $this->addFieldsIf( 'log_title', $this->fld_title );
+ $this->addFieldsIf( 'log_comment', $this->fld_comment || $this->fld_parsedcomment );
+ $this->addFieldsIf( 'log_params', $this->fld_details );
+
+ if ( $this->fld_tags ) {
+ $this->addTables( 'tag_summary' );
+ $this->addJoinConds( array( 'tag_summary' => array( 'LEFT JOIN', 'log_id=ts_log_id' ) ) );
+ $this->addFields( 'ts_tags' );
+ }
+
+ if ( !is_null( $params['tag'] ) ) {
+ $this->addTables( 'change_tag' );
+ $this->addJoinConds( array( 'change_tag' => array( 'INNER JOIN', array( 'log_id=ct_log_id' ) ) ) );
+ $this->addWhereFld( 'ct_tag', $params['tag'] );
+ global $wgOldChangeTagsIndex;
+ $index['change_tag'] = $wgOldChangeTagsIndex ? 'ct_tag' : 'change_tag_tag_id';
+ }
- if( !is_null($params['type']) ) {
- $this->addWhereFld('log_type', $params['type']);
- $index = 'type_time';
+ if ( !is_null( $params['type'] ) ) {
+ $this->addWhereFld( 'log_type', $params['type'] );
+ $index['logging'] = 'type_time';
}
- $this->addWhereRange('log_timestamp', $params['dir'], $params['start'], $params['end']);
+ $this->addWhereRange( 'log_timestamp', $params['dir'], $params['start'], $params['end'] );
$limit = $params['limit'];
- $this->addOption('LIMIT', $limit +1);
+ $this->addOption( 'LIMIT', $limit + 1 );
$user = $params['user'];
- if (!is_null($user)) {
- $userid = User::idFromName($user);
- if (!$userid)
- $this->dieUsage("User name $user not found", 'param_user');
- $this->addWhereFld('log_user', $userid);
- $index = 'user_time';
+ if ( !is_null( $user ) ) {
+ $userid = User::idFromName( $user );
+ if ( !$userid )
+ $this->dieUsage( "User name $user not found", 'param_user' );
+ $this->addWhereFld( 'log_user', $userid );
+ $index['logging'] = 'user_time';
}
$title = $params['title'];
- if (!is_null($title)) {
- $titleObj = Title :: newFromText($title);
- if (is_null($titleObj))
- $this->dieUsage("Bad title value '$title'", 'param_title');
- $this->addWhereFld('log_namespace', $titleObj->getNamespace());
- $this->addWhereFld('log_title', $titleObj->getDBkey());
+ if ( !is_null( $title ) ) {
+ $titleObj = Title :: newFromText( $title );
+ if ( is_null( $titleObj ) )
+ $this->dieUsage( "Bad title value '$title'", 'param_title' );
+ $this->addWhereFld( 'log_namespace', $titleObj->getNamespace() );
+ $this->addWhereFld( 'log_title', $titleObj->getDBkey() );
// Use the title index in preference to the user index if there is a conflict
- $index = is_null($user) ? 'page_time' : array('page_time','user_time');
+ $index['logging'] = is_null( $user ) ? 'page_time' : array( 'page_time', 'user_time' );
}
- $this->addOption( 'USE INDEX', array( 'logging' => $index ) );
+ $this->addOption( 'USE INDEX', $index );
// Paranoia: avoid brute force searches (bug 17342)
- if (!is_null($title)) {
- $this->addWhere('log_deleted & ' . LogPage::DELETED_ACTION . ' = 0');
+ if ( !is_null( $title ) ) {
+ $this->addWhere( $db->bitAnd( 'log_deleted', LogPage::DELETED_ACTION ) . ' = 0' );
}
- if (!is_null($user)) {
- $this->addWhere('log_deleted & ' . LogPage::DELETED_USER . ' = 0');
+ if ( !is_null( $user ) ) {
+ $this->addWhere( $db->bitAnd( 'log_deleted', LogPage::DELETED_USER ) . ' = 0' );
}
$count = 0;
- $res = $this->select(__METHOD__);
- while ($row = $db->fetchObject($res)) {
- if (++ $count > $limit) {
+ $res = $this->select( __METHOD__ );
+ while ( $row = $db->fetchObject( $res ) ) {
+ if ( ++ $count > $limit ) {
// We've reached the one extra which shows that there are additional pages to be had. Stop here...
- $this->setContinueEnumParameter('start', wfTimestamp(TS_ISO_8601, $row->log_timestamp));
+ $this->setContinueEnumParameter( 'start', wfTimestamp( TS_ISO_8601, $row->log_timestamp ) );
break;
}
- $vals = $this->extractRowInfo($row);
- if(!$vals)
+ $vals = $this->extractRowInfo( $row );
+ if ( !$vals )
continue;
- $fit = $this->getResult()->addValue(array('query', $this->getModuleName()), null, $vals);
- if(!$fit)
+ $fit = $this->getResult()->addValue( array( 'query', $this->getModuleName() ), null, $vals );
+ if ( !$fit )
{
- $this->setContinueEnumParameter('start', wfTimestamp(TS_ISO_8601, $row->log_timestamp));
+ $this->setContinueEnumParameter( 'start', wfTimestamp( TS_ISO_8601, $row->log_timestamp ) );
break;
}
}
- $db->freeResult($res);
+ $db->freeResult( $res );
- $this->getResult()->setIndexedTagName_internal(array('query', $this->getModuleName()), 'item');
+ $this->getResult()->setIndexedTagName_internal( array( 'query', $this->getModuleName() ), 'item' );
}
- public static function addLogParams($result, &$vals, $params, $type, $ts) {
- $params = explode("\n", $params);
- switch ($type) {
+ public static function addLogParams( $result, &$vals, $params, $type, $ts ) {
+ $params = explode( "\n", $params );
+ switch ( $type ) {
case 'move':
- if (isset ($params[0])) {
- $title = Title :: newFromText($params[0]);
- if ($title) {
+ if ( isset ( $params[0] ) ) {
+ $title = Title :: newFromText( $params[0] );
+ if ( $title ) {
$vals2 = array();
- ApiQueryBase :: addTitleInfo($vals2, $title, "new_");
+ ApiQueryBase :: addTitleInfo( $vals2, $title, "new_" );
$vals[$type] = $vals2;
}
}
- if (isset ($params[1]) && $params[1]) {
+ if ( isset ( $params[1] ) && $params[1] ) {
$vals[$type]['suppressedredirect'] = '';
- }
+ }
$params = null;
break;
case 'patrol':
@@ -182,77 +199,99 @@ class ApiQueryLogEvents extends ApiQueryBase {
case 'block':
$vals2 = array();
list( $vals2['duration'], $vals2['flags'] ) = $params;
- $vals2['expiry'] = wfTimestamp(TS_ISO_8601,
- strtotime($params[0], wfTimestamp(TS_UNIX, $ts)));
+ $vals2['expiry'] = wfTimestamp( TS_ISO_8601,
+ strtotime( $params[0], wfTimestamp( TS_UNIX, $ts ) ) );
$vals[$type] = $vals2;
$params = null;
break;
}
- if (!is_null($params)) {
- $result->setIndexedTagName($params, 'param');
- $vals = array_merge($vals, $params);
+ if ( !is_null( $params ) ) {
+ $result->setIndexedTagName( $params, 'param' );
+ $vals = array_merge( $vals, $params );
}
return $vals;
}
- private function extractRowInfo($row) {
+ private function extractRowInfo( $row ) {
$vals = array();
- if ($this->fld_ids) {
- $vals['logid'] = intval($row->log_id);
- $vals['pageid'] = intval($row->page_id);
+ if ( $this->fld_ids ) {
+ $vals['logid'] = intval( $row->log_id );
+ $vals['pageid'] = intval( $row->page_id );
}
- if ($this->fld_title) {
- if (LogEventsList::isDeleted($row, LogPage::DELETED_ACTION)) {
+ $title = Title::makeTitle( $row->log_namespace, $row->log_title );
+
+ if ( $this->fld_title ) {
+ if ( LogEventsList::isDeleted( $row, LogPage::DELETED_ACTION ) ) {
$vals['actionhidden'] = '';
} else {
- $title = Title :: makeTitle($row->log_namespace, $row->log_title);
- ApiQueryBase :: addTitleInfo($vals, $title);
+ ApiQueryBase::addTitleInfo( $vals, $title );
}
}
- if ($this->fld_type) {
+ if ( $this->fld_type ) {
$vals['type'] = $row->log_type;
$vals['action'] = $row->log_action;
}
- if ($this->fld_details && $row->log_params !== '') {
- if (LogEventsList::isDeleted($row, LogPage::DELETED_ACTION)) {
+ if ( $this->fld_details && $row->log_params !== '' ) {
+ if ( LogEventsList::isDeleted( $row, LogPage::DELETED_ACTION ) ) {
$vals['actionhidden'] = '';
} else {
- self::addLogParams($this->getResult(), $vals,
+ self::addLogParams( $this->getResult(), $vals,
$row->log_params, $row->log_type,
- $row->log_timestamp);
+ $row->log_timestamp );
}
}
- if ($this->fld_user) {
- if (LogEventsList::isDeleted($row, LogPage::DELETED_USER)) {
+ if ( $this->fld_user ) {
+ if ( LogEventsList::isDeleted( $row, LogPage::DELETED_USER ) ) {
$vals['userhidden'] = '';
} else {
$vals['user'] = $row->user_name;
- if(!$row->log_user)
+ if ( !$row->log_user )
$vals['anon'] = '';
}
}
- if ($this->fld_timestamp) {
- $vals['timestamp'] = wfTimestamp(TS_ISO_8601, $row->log_timestamp);
+ if ( $this->fld_timestamp ) {
+ $vals['timestamp'] = wfTimestamp( TS_ISO_8601, $row->log_timestamp );
}
- if ($this->fld_comment && isset($row->log_comment)) {
- if (LogEventsList::isDeleted($row, LogPage::DELETED_COMMENT)) {
+
+ if ( ( $this->fld_comment || $this->fld_parsedcomment ) && isset( $row->log_comment ) ) {
+ if ( LogEventsList::isDeleted( $row, LogPage::DELETED_COMMENT ) ) {
$vals['commenthidden'] = '';
} else {
- $vals['comment'] = $row->log_comment;
+ if ( $this->fld_comment )
+ $vals['comment'] = $row->log_comment;
+
+ if ( $this->fld_parsedcomment ) {
+ global $wgUser;
+ $vals['parsedcomment'] = $wgUser->getSkin()->formatComment( $row->log_comment, $title );
+ }
}
}
+ if ( $this->fld_tags ) {
+ if ( $row->ts_tags ) {
+ $tags = explode( ',', $row->ts_tags );
+ $this->getResult()->setIndexedTagName( $tags, 'tag' );
+ $vals['tags'] = $tags;
+ } else {
+ $vals['tags'] = array();
+ }
+ }
+
return $vals;
}
-
-
+
public function getCacheMode( $params ) {
- return 'public';
+ if ( !is_null( $params['prop'] ) && in_array( 'parsedcomment', $params['prop'] ) ) {
+ // formatComment() calls wfMsg() among other things
+ return 'anon-public-user-private';
+ } else {
+ return 'public';
+ }
}
public function getAllowedParams() {
@@ -268,7 +307,9 @@ class ApiQueryLogEvents extends ApiQueryBase {
'user',
'timestamp',
'comment',
+ 'parsedcomment',
'details',
+ 'tags'
)
),
'type' => array (
@@ -289,6 +330,7 @@ class ApiQueryLogEvents extends ApiQueryBase {
),
'user' => null,
'title' => null,
+ 'tag' => null,
'limit' => array (
ApiBase :: PARAM_DFLT => 10,
ApiBase :: PARAM_TYPE => 'limit',
@@ -308,13 +350,21 @@ class ApiQueryLogEvents extends ApiQueryBase {
'dir' => 'In which direction to enumerate.',
'user' => 'Filter entries to those made by the given user.',
'title' => 'Filter entries to those related to a page.',
- 'limit' => 'How many total event entries to return.'
+ 'limit' => 'How many total event entries to return.',
+ 'tag' => 'Only list event entries tagged with this tag.',
);
}
public function getDescription() {
return 'Get events from logs.';
}
+
+ public function getPossibleErrors() {
+ return array_merge( parent::getPossibleErrors(), array(
+ array( 'code' => 'param_user', 'info' => 'User name $user not found' ),
+ array( 'code' => 'param_title', 'info' => 'Bad title value \'title\'' ),
+ ) );
+ }
protected function getExamples() {
return array (
@@ -323,6 +373,6 @@ class ApiQueryLogEvents extends ApiQueryBase {
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiQueryLogEvents.php 69986 2010-07-27 03:57:39Z tstarling $';
+ return __CLASS__ . ': $Id: ApiQueryLogEvents.php 69932 2010-07-26 08:03:21Z tstarling $';
}
}
diff --git a/includes/api/ApiQueryProtectedTitles.php b/includes/api/ApiQueryProtectedTitles.php
index 67a2a829..ab794805 100644
--- a/includes/api/ApiQueryProtectedTitles.php
+++ b/includes/api/ApiQueryProtectedTitles.php
@@ -23,9 +23,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ('ApiQueryBase.php');
+ require_once ( 'ApiQueryBase.php' );
}
/**
@@ -35,91 +35,104 @@ if (!defined('MEDIAWIKI')) {
*/
class ApiQueryProtectedTitles extends ApiQueryGeneratorBase {
- public function __construct($query, $moduleName) {
- parent :: __construct($query, $moduleName, 'pt');
+ public function __construct( $query, $moduleName ) {
+ parent :: __construct( $query, $moduleName, 'pt' );
}
public function execute() {
$this->run();
}
- public function executeGenerator($resultPageSet) {
- $this->run($resultPageSet);
+ public function executeGenerator( $resultPageSet ) {
+ $this->run( $resultPageSet );
}
- private function run($resultPageSet = null) {
+ private function run( $resultPageSet = null ) {
$db = $this->getDB();
$params = $this->extractRequestParams();
- $this->addTables('protected_titles');
- $this->addFields(array('pt_namespace', 'pt_title', 'pt_timestamp'));
+ $this->addTables( 'protected_titles' );
+ $this->addFields( array( 'pt_namespace', 'pt_title', 'pt_timestamp' ) );
- $prop = array_flip($params['prop']);
- $this->addFieldsIf('pt_user', isset($prop['user']));
- $this->addFieldsIf('pt_reason', isset($prop['comment']));
- $this->addFieldsIf('pt_expiry', isset($prop['expiry']));
- $this->addFieldsIf('pt_create_perm', isset($prop['level']));
+ $prop = array_flip( $params['prop'] );
+ $this->addFieldsIf( 'pt_user', isset( $prop['user'] ) );
+ $this->addFieldsIf( 'pt_reason', isset( $prop['comment'] ) || isset( $prop['parsedcomment'] ) );
+ $this->addFieldsIf( 'pt_expiry', isset( $prop['expiry'] ) );
+ $this->addFieldsIf( 'pt_create_perm', isset( $prop['level'] ) );
- $this->addWhereRange('pt_timestamp', $params['dir'], $params['start'], $params['end']);
- $this->addWhereFld('pt_namespace', $params['namespace']);
- $this->addWhereFld('pt_create_perm', $params['level']);
+ $this->addWhereRange( 'pt_timestamp', $params['dir'], $params['start'], $params['end'] );
+ $this->addWhereFld( 'pt_namespace', $params['namespace'] );
+ $this->addWhereFld( 'pt_create_perm', $params['level'] );
- if(isset($prop['user']))
+ if ( isset( $prop['user'] ) )
{
- $this->addTables('user');
- $this->addFields('user_name');
- $this->addJoinConds(array('user' => array('LEFT JOIN',
+ $this->addTables( 'user' );
+ $this->addFields( 'user_name' );
+ $this->addJoinConds( array( 'user' => array( 'LEFT JOIN',
'user_id=pt_user'
- )));
+ ) ) );
}
- $this->addOption('LIMIT', $params['limit'] + 1);
- $res = $this->select(__METHOD__);
+ $this->addOption( 'LIMIT', $params['limit'] + 1 );
+ $res = $this->select( __METHOD__ );
$count = 0;
$result = $this->getResult();
- while ($row = $db->fetchObject($res)) {
- if (++ $count > $params['limit']) {
+ while ( $row = $db->fetchObject( $res ) ) {
+ if ( ++ $count > $params['limit'] ) {
// We've reached the one extra which shows that there are additional pages to be had. Stop here...
- $this->setContinueEnumParameter('start', wfTimestamp(TS_ISO_8601, $row->pt_timestamp));
+ $this->setContinueEnumParameter( 'start', wfTimestamp( TS_ISO_8601, $row->pt_timestamp ) );
break;
}
- $title = Title::makeTitle($row->pt_namespace, $row->pt_title);
- if (is_null($resultPageSet)) {
+ $title = Title::makeTitle( $row->pt_namespace, $row->pt_title );
+ if ( is_null( $resultPageSet ) ) {
$vals = array();
- ApiQueryBase::addTitleInfo($vals, $title);
- if(isset($prop['timestamp']))
- $vals['timestamp'] = wfTimestamp(TS_ISO_8601, $row->pt_timestamp);
- if(isset($prop['user']) && !is_null($row->user_name))
+ ApiQueryBase::addTitleInfo( $vals, $title );
+ if ( isset( $prop['timestamp'] ) )
+ $vals['timestamp'] = wfTimestamp( TS_ISO_8601, $row->pt_timestamp );
+
+ if ( isset( $prop['user'] ) && !is_null( $row->user_name ) )
$vals['user'] = $row->user_name;
- if(isset($prop['comment']))
+
+ if ( isset( $prop['comment'] ) )
$vals['comment'] = $row->pt_reason;
- if(isset($prop['expiry']))
- $vals['expiry'] = Block::decodeExpiry($row->pt_expiry, TS_ISO_8601);
- if(isset($prop['level']))
+
+ if ( isset( $prop['parsedcomment'] ) ) {
+ global $wgUser;
+ $vals['parsedcomment'] = $wgUser->getSkin()->formatComment( $row->pt_reason, $title );
+ }
+
+ if ( isset( $prop['expiry'] ) )
+ $vals['expiry'] = Block::decodeExpiry( $row->pt_expiry, TS_ISO_8601 );
+
+ if ( isset( $prop['level'] ) )
$vals['level'] = $row->pt_create_perm;
- $fit = $result->addValue(array('query', $this->getModuleName()), null, $vals);
- if(!$fit)
- {
- $this->setContinueEnumParameter('start',
- wfTimestamp(TS_ISO_8601, $row->pt_timestamp));
+ $fit = $result->addValue( array( 'query', $this->getModuleName() ), null, $vals );
+ if ( !$fit ) {
+ $this->setContinueEnumParameter( 'start',
+ wfTimestamp( TS_ISO_8601, $row->pt_timestamp ) );
break;
}
} else {
$titles[] = $title;
}
}
- $db->freeResult($res);
- if(is_null($resultPageSet))
- $result->setIndexedTagName_internal(array('query', $this->getModuleName()), $this->getModulePrefix());
+ $db->freeResult( $res );
+ if ( is_null( $resultPageSet ) )
+ $result->setIndexedTagName_internal( array( 'query', $this->getModuleName() ), $this->getModulePrefix() );
else
- $resultPageSet->populateFromTitles($titles);
+ $resultPageSet->populateFromTitles( $titles );
}
public function getCacheMode( $params ) {
- return 'public';
+ if ( !is_null( $params['prop'] ) && in_array( 'parsedcomment', $params['prop'] ) ) {
+ // formatComment() calls wfMsg() among other things
+ return 'anon-public-user-private';
+ } else {
+ return 'public';
+ }
}
public function getAllowedParams() {
@@ -131,7 +144,7 @@ class ApiQueryProtectedTitles extends ApiQueryGeneratorBase {
),
'level' => array(
ApiBase :: PARAM_ISMULTI => true,
- ApiBase :: PARAM_TYPE => array_diff($wgRestrictionLevels, array(''))
+ ApiBase :: PARAM_TYPE => array_diff( $wgRestrictionLevels, array( '' ) )
),
'limit' => array (
ApiBase :: PARAM_DFLT => 10,
@@ -160,6 +173,7 @@ class ApiQueryProtectedTitles extends ApiQueryGeneratorBase {
'timestamp',
'user',
'comment',
+ 'parsedcomment',
'expiry',
'level'
)
@@ -190,6 +204,6 @@ class ApiQueryProtectedTitles extends ApiQueryGeneratorBase {
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiQueryProtectedTitles.php 69986 2010-07-27 03:57:39Z tstarling $';
+ return __CLASS__ . ': $Id: ApiQueryProtectedTitles.php 69932 2010-07-26 08:03:21Z tstarling $';
}
}
diff --git a/includes/api/ApiQueryRandom.php b/includes/api/ApiQueryRandom.php
index 1811b7e8..10796810 100644
--- a/includes/api/ApiQueryRandom.php
+++ b/includes/api/ApiQueryRandom.php
@@ -23,9 +23,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ('ApiQueryBase.php');
+ require_once ( 'ApiQueryBase.php' );
}
/**
@@ -36,88 +36,88 @@ if (!defined('MEDIAWIKI')) {
class ApiQueryRandom extends ApiQueryGeneratorBase {
- public function __construct($query, $moduleName) {
- parent :: __construct($query, $moduleName, 'rn');
+ public function __construct( $query, $moduleName ) {
+ parent :: __construct( $query, $moduleName, 'rn' );
}
public function execute() {
$this->run();
}
- public function executeGenerator($resultPageSet) {
- $this->run($resultPageSet);
+ public function executeGenerator( $resultPageSet ) {
+ $this->run( $resultPageSet );
}
- protected function prepareQuery($randstr, $limit, $namespace, &$resultPageSet, $redirect) {
+ protected function prepareQuery( $randstr, $limit, $namespace, &$resultPageSet, $redirect ) {
$this->resetQueryParams();
- $this->addTables('page');
- $this->addOption('LIMIT', $limit);
- $this->addWhereFld('page_namespace', $namespace);
- $this->addWhereRange('page_random', 'newer', $randstr, null);
- $this->addWhereFld('page_is_redirect', $redirect);
- $this->addOption('USE INDEX', 'page_random');
- if(is_null($resultPageSet))
- $this->addFields(array('page_id', 'page_title', 'page_namespace'));
+ $this->addTables( 'page' );
+ $this->addOption( 'LIMIT', $limit );
+ $this->addWhereFld( 'page_namespace', $namespace );
+ $this->addWhereRange( 'page_random', 'newer', $randstr, null );
+ $this->addWhereFld( 'page_is_redirect', $redirect );
+ $this->addOption( 'USE INDEX', 'page_random' );
+ if ( is_null( $resultPageSet ) )
+ $this->addFields( array( 'page_id', 'page_title', 'page_namespace' ) );
else
- $this->addFields($resultPageSet->getPageTableFields());
+ $this->addFields( $resultPageSet->getPageTableFields() );
}
- protected function runQuery(&$resultPageSet) {
+ protected function runQuery( &$resultPageSet ) {
$db = $this->getDB();
- $res = $this->select(__METHOD__);
+ $res = $this->select( __METHOD__ );
$count = 0;
- while($row = $db->fetchObject($res)) {
+ while ( $row = $db->fetchObject( $res ) ) {
$count++;
- if(is_null($resultPageSet))
+ if ( is_null( $resultPageSet ) )
{
// Prevent duplicates
- if(!in_array($row->page_id, $this->pageIDs))
+ if ( !in_array( $row->page_id, $this->pageIDs ) )
{
$fit = $this->getResult()->addValue(
- array('query', $this->getModuleName()),
- null, $this->extractRowInfo($row));
- if(!$fit)
- # We can't really query-continue a random list.
- # Return an insanely high value so
- # $count < $limit is false
+ array( 'query', $this->getModuleName() ),
+ null, $this->extractRowInfo( $row ) );
+ if ( !$fit )
+ // We can't really query-continue a random list.
+ // Return an insanely high value so
+ // $count < $limit is false
return 1E9;
$this->pageIDs[] = $row->page_id;
}
}
else
- $resultPageSet->processDbRow($row);
+ $resultPageSet->processDbRow( $row );
}
- $db->freeResult($res);
+ $db->freeResult( $res );
return $count;
}
- public function run($resultPageSet = null) {
+ public function run( $resultPageSet = null ) {
$params = $this->extractRequestParams();
$result = $this->getResult();
$this->pageIDs = array();
- $this->prepareQuery(wfRandom(), $params['limit'], $params['namespace'], $resultPageSet, $params['redirect']);
- $count = $this->runQuery($resultPageSet);
- if($count < $params['limit'])
+ $this->prepareQuery( wfRandom(), $params['limit'], $params['namespace'], $resultPageSet, $params['redirect'] );
+ $count = $this->runQuery( $resultPageSet );
+ if ( $count < $params['limit'] )
{
/* We got too few pages, we probably picked a high value
* for page_random. We'll just take the lowest ones, see
* also the comment in Title::getRandomTitle()
*/
- $this->prepareQuery(0, $params['limit'] - $count, $params['namespace'], $resultPageSet, $params['redirect']);
- $this->runQuery($resultPageSet);
+ $this->prepareQuery( 0, $params['limit'] - $count, $params['namespace'], $resultPageSet, $params['redirect'] );
+ $this->runQuery( $resultPageSet );
}
- if(is_null($resultPageSet)) {
- $result->setIndexedTagName_internal(array('query', $this->getModuleName()), 'page');
+ if ( is_null( $resultPageSet ) ) {
+ $result->setIndexedTagName_internal( array( 'query', $this->getModuleName() ), 'page' );
}
}
- private function extractRowInfo($row) {
- $title = Title::makeTitle($row->page_namespace, $row->page_title);
+ private function extractRowInfo( $row ) {
+ $title = Title::makeTitle( $row->page_namespace, $row->page_title );
$vals = array();
- $vals['id'] = intval($row->page_id);
- ApiQueryBase::addTitleInfo($vals, $title);
+ $vals['id'] = intval( $row->page_id );
+ ApiQueryBase::addTitleInfo( $vals, $title );
return $vals;
}
diff --git a/includes/api/ApiQueryRecentChanges.php b/includes/api/ApiQueryRecentChanges.php
index b5a56864..1f0de3be 100644
--- a/includes/api/ApiQueryRecentChanges.php
+++ b/includes/api/ApiQueryRecentChanges.php
@@ -23,9 +23,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ('ApiQueryBase.php');
+ require_once ( 'ApiQueryBase.php' );
}
/**
@@ -36,43 +36,45 @@ if (!defined('MEDIAWIKI')) {
*/
class ApiQueryRecentChanges extends ApiQueryBase {
- public function __construct($query, $moduleName) {
- parent :: __construct($query, $moduleName, 'rc');
+ public function __construct( $query, $moduleName ) {
+ parent :: __construct( $query, $moduleName, 'rc' );
}
- private $fld_comment = false, $fld_user = false, $fld_flags = false,
+ private $fld_comment = false, $fld_parsedcomment = false, $fld_user = false, $fld_flags = false,
$fld_timestamp = false, $fld_title = false, $fld_ids = false,
$fld_sizes = false;
-
+ /**
+ * Get an array mapping token names to their handler functions.
+ * The prototype for a token function is func($pageid, $title, $rc)
+ * it should return a token or false (permission denied)
+ * @return array(tokenname => function)
+ */
protected function getTokenFunctions() {
- // tokenname => function
- // function prototype is func($pageid, $title, $rev)
- // should return token or false
-
// Don't call the hooks twice
- if(isset($this->tokenFunctions))
+ if ( isset( $this->tokenFunctions ) )
return $this->tokenFunctions;
// If we're in JSON callback mode, no tokens can be obtained
- if(!is_null($this->getMain()->getRequest()->getVal('callback')))
+ if ( !is_null( $this->getMain()->getRequest()->getVal( 'callback' ) ) )
return array();
$this->tokenFunctions = array(
'patrol' => array( 'ApiQueryRecentChanges', 'getPatrolToken' )
);
- wfRunHooks('APIQueryRecentChangesTokens', array(&$this->tokenFunctions));
+ wfRunHooks( 'APIQueryRecentChangesTokens', array( &$this->tokenFunctions ) );
return $this->tokenFunctions;
}
- public static function getPatrolToken($pageid, $title, $rc)
+ public static function getPatrolToken( $pageid, $title, $rc )
{
global $wgUser;
- if(!$wgUser->useRCPatrol() && !$wgUser->useNPPatrol())
+ if ( !$wgUser->useRCPatrol() && ( !$wgUser->useNPPatrol() ||
+ $rc->getAttribute( 'rc_type' ) != RC_NEW ) )
return false;
// The patrol token is always the same, let's exploit that
static $cachedPatrolToken = null;
- if(!is_null($cachedPatrolToken))
+ if ( !is_null( $cachedPatrolToken ) )
return $cachedPatrolToken;
$cachedPatrolToken = $wgUser->editToken();
@@ -80,6 +82,25 @@ class ApiQueryRecentChanges extends ApiQueryBase {
}
/**
+ * Sets internal state to include the desired properties in the output.
+ * @param $prop associative array of properties, only keys are used here
+ */
+ public function initProperties( $prop ) {
+ $this->fld_comment = isset ( $prop['comment'] );
+ $this->fld_parsedcomment = isset ( $prop['parsedcomment'] );
+ $this->fld_user = isset ( $prop['user'] );
+ $this->fld_flags = isset ( $prop['flags'] );
+ $this->fld_timestamp = isset ( $prop['timestamp'] );
+ $this->fld_title = isset ( $prop['title'] );
+ $this->fld_ids = isset ( $prop['ids'] );
+ $this->fld_sizes = isset ( $prop['sizes'] );
+ $this->fld_redirect = isset( $prop['redirect'] );
+ $this->fld_patrolled = isset( $prop['patrolled'] );
+ $this->fld_loginfo = isset( $prop['loginfo'] );
+ $this->fld_tags = isset( $prop['tags'] );
+ }
+
+ /**
* Generates and outputs the result of this query based upon the provided parameters.
*/
public function execute() {
@@ -92,49 +113,65 @@ class ApiQueryRecentChanges extends ApiQueryBase {
* AND rc_deleted = '0'
*/
$db = $this->getDB();
- $this->addTables('recentchanges');
- $this->addOption('USE INDEX', array('recentchanges' => 'rc_timestamp'));
- $this->addWhereRange('rc_timestamp', $params['dir'], $params['start'], $params['end']);
- $this->addWhereFld('rc_namespace', $params['namespace']);
- $this->addWhereFld('rc_deleted', 0);
+ $this->addTables( 'recentchanges' );
+ $index = array( 'recentchanges' => 'rc_timestamp' ); // May change
+ $this->addWhereRange( 'rc_timestamp', $params['dir'], $params['start'], $params['end'] );
+ $this->addWhereFld( 'rc_namespace', $params['namespace'] );
+ $this->addWhereFld( 'rc_deleted', 0 );
- if(!is_null($params['type']))
- $this->addWhereFld('rc_type', $this->parseRCType($params['type']));
+ if ( !is_null( $params['type'] ) )
+ $this->addWhereFld( 'rc_type', $this->parseRCType( $params['type'] ) );
- if (!is_null($params['show'])) {
- $show = array_flip($params['show']);
+ if ( !is_null( $params['show'] ) ) {
+ $show = array_flip( $params['show'] );
/* Check for conflicting parameters. */
- if ((isset ($show['minor']) && isset ($show['!minor']))
- || (isset ($show['bot']) && isset ($show['!bot']))
- || (isset ($show['anon']) && isset ($show['!anon']))
- || (isset ($show['redirect']) && isset ($show['!redirect']))
- || (isset ($show['patrolled']) && isset ($show['!patrolled']))) {
+ if ( ( isset ( $show['minor'] ) && isset ( $show['!minor'] ) )
+ || ( isset ( $show['bot'] ) && isset ( $show['!bot'] ) )
+ || ( isset ( $show['anon'] ) && isset ( $show['!anon'] ) )
+ || ( isset ( $show['redirect'] ) && isset ( $show['!redirect'] ) )
+ || ( isset ( $show['patrolled'] ) && isset ( $show['!patrolled'] ) ) ) {
- $this->dieUsage("Incorrect parameter - mutually exclusive values may not be supplied", 'show');
+ $this->dieUsageMsg( array( 'show' ) );
}
// Check permissions
global $wgUser;
- if((isset($show['patrolled']) || isset($show['!patrolled'])) && !$wgUser->useRCPatrol() && !$wgUser->useNPPatrol())
- $this->dieUsage("You need the patrol right to request the patrolled flag", 'permissiondenied');
+ if ( ( isset( $show['patrolled'] ) || isset( $show['!patrolled'] ) ) && !$wgUser->useRCPatrol() && !$wgUser->useNPPatrol() )
+ $this->dieUsage( "You need the patrol right to request the patrolled flag", 'permissiondenied' );
/* Add additional conditions to query depending upon parameters. */
- $this->addWhereIf('rc_minor = 0', isset ($show['!minor']));
- $this->addWhereIf('rc_minor != 0', isset ($show['minor']));
- $this->addWhereIf('rc_bot = 0', isset ($show['!bot']));
- $this->addWhereIf('rc_bot != 0', isset ($show['bot']));
- $this->addWhereIf('rc_user = 0', isset ($show['anon']));
- $this->addWhereIf('rc_user != 0', isset ($show['!anon']));
- $this->addWhereIf('rc_patrolled = 0', isset($show['!patrolled']));
- $this->addWhereIf('rc_patrolled != 0', isset($show['patrolled']));
- $this->addWhereIf('page_is_redirect = 1', isset ($show['redirect']));
+ $this->addWhereIf( 'rc_minor = 0', isset ( $show['!minor'] ) );
+ $this->addWhereIf( 'rc_minor != 0', isset ( $show['minor'] ) );
+ $this->addWhereIf( 'rc_bot = 0', isset ( $show['!bot'] ) );
+ $this->addWhereIf( 'rc_bot != 0', isset ( $show['bot'] ) );
+ $this->addWhereIf( 'rc_user = 0', isset ( $show['anon'] ) );
+ $this->addWhereIf( 'rc_user != 0', isset ( $show['!anon'] ) );
+ $this->addWhereIf( 'rc_patrolled = 0', isset( $show['!patrolled'] ) );
+ $this->addWhereIf( 'rc_patrolled != 0', isset( $show['patrolled'] ) );
+ $this->addWhereIf( 'page_is_redirect = 1', isset ( $show['redirect'] ) );
+
// Don't throw log entries out the window here
- $this->addWhereIf('page_is_redirect = 0 OR page_is_redirect IS NULL', isset ($show['!redirect']));
+ $this->addWhereIf( 'page_is_redirect = 0 OR page_is_redirect IS NULL', isset ( $show['!redirect'] ) );
}
-
- /* Add the fields we're concerned with to out query. */
- $this->addFields(array (
+
+ if ( !is_null( $params['user'] ) && !is_null( $param['excludeuser'] ) )
+ $this->dieUsage( 'user and excludeuser cannot be used together', 'user-excludeuser' );
+
+ if ( !is_null( $params['user'] ) )
+ {
+ $this->addWhereFld( 'rc_user_text', $params['user'] );
+ $index['recentchanges'] = 'rc_user_text';
+ }
+
+ if ( !is_null( $params['excludeuser'] ) )
+ // We don't use the rc_user_text index here because
+ // * it would require us to sort by rc_user_text before rc_timestamp
+ // * the != condition doesn't throw out too many rows anyway
+ $this->addWhere( 'rc_user_text != ' . $this->getDB()->addQuotes( $params['excludeuser'] ) );
+
+ /* Add the fields we're concerned with to our query. */
+ $this->addFields( array (
'rc_timestamp',
'rc_namespace',
'rc_title',
@@ -142,86 +179,93 @@ class ApiQueryRecentChanges extends ApiQueryBase {
'rc_type',
'rc_moved_to_ns',
'rc_moved_to_title'
- ));
+ ) );
/* Determine what properties we need to display. */
- if (!is_null($params['prop'])) {
- $prop = array_flip($params['prop']);
+ if ( !is_null( $params['prop'] ) ) {
+ $prop = array_flip( $params['prop'] );
/* Set up internal members based upon params. */
- $this->fld_comment = isset ($prop['comment']);
- $this->fld_user = isset ($prop['user']);
- $this->fld_flags = isset ($prop['flags']);
- $this->fld_timestamp = isset ($prop['timestamp']);
- $this->fld_title = isset ($prop['title']);
- $this->fld_ids = isset ($prop['ids']);
- $this->fld_sizes = isset ($prop['sizes']);
- $this->fld_redirect = isset($prop['redirect']);
- $this->fld_patrolled = isset($prop['patrolled']);
- $this->fld_loginfo = isset($prop['loginfo']);
+ $this->initProperties( $prop );
global $wgUser;
- if($this->fld_patrolled && !$wgUser->useRCPatrol() && !$wgUser->useNPPatrol())
- $this->dieUsage("You need the patrol right to request the patrolled flag", 'permissiondenied');
+ if ( $this->fld_patrolled && !$wgUser->useRCPatrol() && !$wgUser->useNPPatrol() )
+ $this->dieUsage( "You need the patrol right to request the patrolled flag", 'permissiondenied' );
/* Add fields to our query if they are specified as a needed parameter. */
- $this->addFieldsIf('rc_id', $this->fld_ids);
- $this->addFieldsIf('rc_this_oldid', $this->fld_ids);
- $this->addFieldsIf('rc_last_oldid', $this->fld_ids);
- $this->addFieldsIf('rc_comment', $this->fld_comment);
- $this->addFieldsIf('rc_user', $this->fld_user);
- $this->addFieldsIf('rc_user_text', $this->fld_user);
- $this->addFieldsIf('rc_minor', $this->fld_flags);
- $this->addFieldsIf('rc_bot', $this->fld_flags);
- $this->addFieldsIf('rc_new', $this->fld_flags);
- $this->addFieldsIf('rc_old_len', $this->fld_sizes);
- $this->addFieldsIf('rc_new_len', $this->fld_sizes);
- $this->addFieldsIf('rc_patrolled', $this->fld_patrolled);
- $this->addFieldsIf('rc_logid', $this->fld_loginfo);
- $this->addFieldsIf('rc_log_type', $this->fld_loginfo);
- $this->addFieldsIf('rc_log_action', $this->fld_loginfo);
- $this->addFieldsIf('rc_params', $this->fld_loginfo);
- if($this->fld_redirect || isset($show['redirect']) || isset($show['!redirect']))
+ $this->addFieldsIf( 'rc_id', $this->fld_ids );
+ $this->addFieldsIf( 'rc_this_oldid', $this->fld_ids );
+ $this->addFieldsIf( 'rc_last_oldid', $this->fld_ids );
+ $this->addFieldsIf( 'rc_comment', $this->fld_comment || $this->fld_parsedcomment );
+ $this->addFieldsIf( 'rc_user', $this->fld_user );
+ $this->addFieldsIf( 'rc_user_text', $this->fld_user );
+ $this->addFieldsIf( 'rc_minor', $this->fld_flags );
+ $this->addFieldsIf( 'rc_bot', $this->fld_flags );
+ $this->addFieldsIf( 'rc_new', $this->fld_flags );
+ $this->addFieldsIf( 'rc_old_len', $this->fld_sizes );
+ $this->addFieldsIf( 'rc_new_len', $this->fld_sizes );
+ $this->addFieldsIf( 'rc_patrolled', $this->fld_patrolled );
+ $this->addFieldsIf( 'rc_logid', $this->fld_loginfo );
+ $this->addFieldsIf( 'rc_log_type', $this->fld_loginfo );
+ $this->addFieldsIf( 'rc_log_action', $this->fld_loginfo );
+ $this->addFieldsIf( 'rc_params', $this->fld_loginfo );
+ if ( $this->fld_redirect || isset( $show['redirect'] ) || isset( $show['!redirect'] ) )
{
- $this->addTables('page');
- $this->addJoinConds(array('page' => array('LEFT JOIN', array('rc_namespace=page_namespace', 'rc_title=page_title'))));
- $this->addFields('page_is_redirect');
+ $this->addTables( 'page' );
+ $this->addJoinConds( array( 'page' => array( 'LEFT JOIN', array( 'rc_namespace=page_namespace', 'rc_title=page_title' ) ) ) );
+ $this->addFields( 'page_is_redirect' );
}
}
+
+ if ( $this->fld_tags ) {
+ $this->addTables( 'tag_summary' );
+ $this->addJoinConds( array( 'tag_summary' => array( 'LEFT JOIN', array( 'rc_id=ts_rc_id' ) ) ) );
+ $this->addFields( 'ts_tags' );
+ }
+
+ if ( !is_null( $params['tag'] ) ) {
+ $this->addTables( 'change_tag' );
+ $this->addJoinConds( array( 'change_tag' => array( 'INNER JOIN', array( 'rc_id=ct_rc_id' ) ) ) );
+ $this->addWhereFld( 'ct_tag' , $params['tag'] );
+ global $wgOldChangeTagsIndex;
+ $index['change_tag'] = $wgOldChangeTagsIndex ? 'ct_tag' : 'change_tag_tag_id';
+ }
+
$this->token = $params['token'];
- $this->addOption('LIMIT', $params['limit'] +1);
+ $this->addOption( 'LIMIT', $params['limit'] + 1 );
+ $this->addOption( 'USE INDEX', $index );
$count = 0;
/* Perform the actual query. */
$db = $this->getDB();
- $res = $this->select(__METHOD__);
+ $res = $this->select( __METHOD__ );
/* Iterate through the rows, adding data extracted from them to our query result. */
- while ($row = $db->fetchObject($res)) {
- if (++ $count > $params['limit']) {
+ while ( $row = $db->fetchObject( $res ) ) {
+ if ( ++ $count > $params['limit'] ) {
// We've reached the one extra which shows that there are additional pages to be had. Stop here...
- $this->setContinueEnumParameter('start', wfTimestamp(TS_ISO_8601, $row->rc_timestamp));
+ $this->setContinueEnumParameter( 'start', wfTimestamp( TS_ISO_8601, $row->rc_timestamp ) );
break;
}
/* Extract the data from a single row. */
- $vals = $this->extractRowInfo($row);
+ $vals = $this->extractRowInfo( $row );
/* Add that row's data to our final output. */
- if(!$vals)
+ if ( !$vals )
continue;
- $fit = $this->getResult()->addValue(array('query', $this->getModuleName()), null, $vals);
- if(!$fit)
+ $fit = $this->getResult()->addValue( array( 'query', $this->getModuleName() ), null, $vals );
+ if ( !$fit )
{
- $this->setContinueEnumParameter('start', wfTimestamp(TS_ISO_8601, $row->rc_timestamp));
+ $this->setContinueEnumParameter( 'start', wfTimestamp( TS_ISO_8601, $row->rc_timestamp ) );
break;
}
}
- $db->freeResult($res);
+ $db->freeResult( $res );
/* Format the result */
- $this->getResult()->setIndexedTagName_internal(array('query', $this->getModuleName()), 'rc');
+ $this->getResult()->setIndexedTagName_internal( array( 'query', $this->getModuleName() ), 'rc' );
}
/**
@@ -229,16 +273,16 @@ class ApiQueryRecentChanges extends ApiQueryBase {
*
* @param $row The row from which to extract the data.
* @return An array mapping strings (descriptors) to their respective string values.
- * @access private
+ * @access public
*/
- private function extractRowInfo($row) {
+ public function extractRowInfo( $row ) {
/* If page was moved somewhere, get the title of the move target. */
$movedToTitle = false;
- if (isset($row->rc_moved_to_title) && $row->rc_moved_to_title !== '')
- $movedToTitle = Title :: makeTitle($row->rc_moved_to_ns, $row->rc_moved_to_title);
+ if ( isset( $row->rc_moved_to_title ) && $row->rc_moved_to_title !== '' )
+ $movedToTitle = Title :: makeTitle( $row->rc_moved_to_ns, $row->rc_moved_to_title );
/* Determine the title of the page that has been changed. */
- $title = Title :: makeTitle($row->rc_namespace, $row->rc_title);
+ $title = Title :: makeTitle( $row->rc_namespace, $row->rc_title );
/* Our output data. */
$vals = array ();
@@ -247,87 +291,112 @@ class ApiQueryRecentChanges extends ApiQueryBase {
/* Determine what kind of change this was. */
switch ( $type ) {
- case RC_EDIT: $vals['type'] = 'edit'; break;
- case RC_NEW: $vals['type'] = 'new'; break;
- case RC_MOVE: $vals['type'] = 'move'; break;
- case RC_LOG: $vals['type'] = 'log'; break;
- case RC_MOVE_OVER_REDIRECT: $vals['type'] = 'move over redirect'; break;
- default: $vals['type'] = $type;
+ case RC_EDIT:
+ $vals['type'] = 'edit';
+ break;
+ case RC_NEW:
+ $vals['type'] = 'new';
+ break;
+ case RC_MOVE:
+ $vals['type'] = 'move';
+ break;
+ case RC_LOG:
+ $vals['type'] = 'log';
+ break;
+ case RC_MOVE_OVER_REDIRECT:
+ $vals['type'] = 'move over redirect';
+ break;
+ default:
+ $vals['type'] = $type;
}
/* Create a new entry in the result for the title. */
- if ($this->fld_title) {
- ApiQueryBase :: addTitleInfo($vals, $title);
- if ($movedToTitle)
- ApiQueryBase :: addTitleInfo($vals, $movedToTitle, "new_");
+ if ( $this->fld_title ) {
+ ApiQueryBase :: addTitleInfo( $vals, $title );
+ if ( $movedToTitle )
+ ApiQueryBase :: addTitleInfo( $vals, $movedToTitle, "new_" );
}
/* Add ids, such as rcid, pageid, revid, and oldid to the change's info. */
- if ($this->fld_ids) {
- $vals['rcid'] = intval($row->rc_id);
- $vals['pageid'] = intval($row->rc_cur_id);
- $vals['revid'] = intval($row->rc_this_oldid);
+ if ( $this->fld_ids ) {
+ $vals['rcid'] = intval( $row->rc_id );
+ $vals['pageid'] = intval( $row->rc_cur_id );
+ $vals['revid'] = intval( $row->rc_this_oldid );
$vals['old_revid'] = intval( $row->rc_last_oldid );
}
/* Add user data and 'anon' flag, if use is anonymous. */
- if ($this->fld_user) {
+ if ( $this->fld_user ) {
$vals['user'] = $row->rc_user_text;
- if(!$row->rc_user)
+ if ( !$row->rc_user )
$vals['anon'] = '';
}
/* Add flags, such as new, minor, bot. */
- if ($this->fld_flags) {
- if ($row->rc_bot)
+ if ( $this->fld_flags ) {
+ if ( $row->rc_bot )
$vals['bot'] = '';
- if ($row->rc_new)
+ if ( $row->rc_new )
$vals['new'] = '';
- if ($row->rc_minor)
+ if ( $row->rc_minor )
$vals['minor'] = '';
}
/* Add sizes of each revision. (Only available on 1.10+) */
- if ($this->fld_sizes) {
- $vals['oldlen'] = intval($row->rc_old_len);
- $vals['newlen'] = intval($row->rc_new_len);
+ if ( $this->fld_sizes ) {
+ $vals['oldlen'] = intval( $row->rc_old_len );
+ $vals['newlen'] = intval( $row->rc_new_len );
}
/* Add the timestamp. */
- if ($this->fld_timestamp)
- $vals['timestamp'] = wfTimestamp(TS_ISO_8601, $row->rc_timestamp);
+ if ( $this->fld_timestamp )
+ $vals['timestamp'] = wfTimestamp( TS_ISO_8601, $row->rc_timestamp );
/* Add edit summary / log summary. */
- if ($this->fld_comment && isset($row->rc_comment)) {
+ if ( $this->fld_comment && isset( $row->rc_comment ) )
$vals['comment'] = $row->rc_comment;
+
+ if ( $this->fld_parsedcomment && isset( $row->rc_comment ) ) {
+ global $wgUser;
+ $vals['parsedcomment'] = $wgUser->getSkin()->formatComment( $row->rc_comment, $title );
}
- if ($this->fld_redirect)
- if($row->page_is_redirect)
+ if ( $this->fld_redirect )
+ if ( $row->page_is_redirect )
$vals['redirect'] = '';
/* Add the patrolled flag */
- if ($this->fld_patrolled && $row->rc_patrolled == 1)
+ if ( $this->fld_patrolled && $row->rc_patrolled == 1 )
$vals['patrolled'] = '';
- if ($this->fld_loginfo && $row->rc_type == RC_LOG) {
- $vals['logid'] = intval($row->rc_logid);
+ if ( $this->fld_loginfo && $row->rc_type == RC_LOG ) {
+ $vals['logid'] = intval( $row->rc_logid );
$vals['logtype'] = $row->rc_log_type;
$vals['logaction'] = $row->rc_log_action;
- ApiQueryLogEvents::addLogParams($this->getResult(),
+ ApiQueryLogEvents::addLogParams( $this->getResult(),
$vals, $row->rc_params,
- $row->rc_log_type, $row->rc_timestamp);
+ $row->rc_log_type, $row->rc_timestamp );
}
- if(!is_null($this->token))
+ if ( $this->fld_tags ) {
+ if ( $row->ts_tags ) {
+ $tags = explode( ',', $row->ts_tags );
+ $this->getResult()->setIndexedTagName( $tags, 'tag' );
+ $vals['tags'] = $tags;
+ } else {
+ $vals['tags'] = array();
+ }
+ }
+
+ if ( !is_null( $this->token ) )
{
$tokenFunctions = $this->getTokenFunctions();
- foreach($this->token as $t)
+ foreach ( $this->token as $t )
{
- $val = call_user_func($tokenFunctions[$t], $row->rc_cur_id,
- $title, RecentChange::newFromRow($row));
- if($val === false)
- $this->setWarning("Action '$t' is not allowed for the current user");
+ $val = call_user_func( $tokenFunctions[$t], $row->rc_cur_id,
+ $title, RecentChange::newFromRow( $row ) );
+ if ( $val === false )
+ $this->setWarning( "Action '$t' is not allowed for the current user" );
else
$vals[$t . 'token'] = $val;
}
@@ -336,16 +405,16 @@ class ApiQueryRecentChanges extends ApiQueryBase {
return $vals;
}
- private function parseRCType($type)
+ private function parseRCType( $type )
{
- if(is_array($type))
+ if ( is_array( $type ) )
{
$retval = array();
- foreach($type as $t)
- $retval[] = $this->parseRCType($t);
+ foreach ( $type as $t )
+ $retval[] = $this->parseRCType( $t );
return $retval;
}
- switch($type)
+ switch( $type )
{
case 'edit': return RC_EDIT;
case 'new': return RC_NEW;
@@ -364,6 +433,10 @@ class ApiQueryRecentChanges extends ApiQueryBase {
if ( isset( $params['token'] ) ) {
return 'private';
}
+ if ( !is_null( $params['prop'] ) && in_array( 'parsedcomment', $params['prop'] ) ) {
+ // formatComment() calls wfMsg() among other things
+ return 'anon-public-user-private';
+ }
return 'public';
}
@@ -386,12 +459,20 @@ class ApiQueryRecentChanges extends ApiQueryBase {
ApiBase :: PARAM_ISMULTI => true,
ApiBase :: PARAM_TYPE => 'namespace'
),
+ 'user' => array(
+ ApiBase :: PARAM_TYPE => 'user'
+ ),
+ 'excludeuser' => array(
+ ApiBase :: PARAM_TYPE => 'user'
+ ),
+ 'tag' => null,
'prop' => array (
ApiBase :: PARAM_ISMULTI => true,
ApiBase :: PARAM_DFLT => 'title|timestamp|ids',
ApiBase :: PARAM_TYPE => array (
'user',
'comment',
+ 'parsedcomment',
'flags',
'timestamp',
'title',
@@ -400,10 +481,11 @@ class ApiQueryRecentChanges extends ApiQueryBase {
'redirect',
'patrolled',
'loginfo',
+ 'tags'
)
),
'token' => array(
- ApiBase :: PARAM_TYPE => array_keys($this->getTokenFunctions()),
+ ApiBase :: PARAM_TYPE => array_keys( $this->getTokenFunctions() ),
ApiBase :: PARAM_ISMULTI => true
),
'show' => array (
@@ -445,6 +527,8 @@ class ApiQueryRecentChanges extends ApiQueryBase {
'end' => 'The timestamp to end enumerating.',
'dir' => 'In which direction to enumerate.',
'namespace' => 'Filter log entries to only this namespace(s)',
+ 'user' => 'Only list changes by this user',
+ 'excludeuser' => 'Don\'t list changes by this user',
'prop' => 'Include additional pieces of information',
'token' => 'Which tokens to obtain for each change',
'show' => array (
@@ -452,13 +536,22 @@ class ApiQueryRecentChanges extends ApiQueryBase {
'For example, to see only minor edits done by logged-in users, set show=minor|!anon'
),
'type' => 'Which types of changes to show.',
- 'limit' => 'How many total changes to return.'
+ 'limit' => 'How many total changes to return.',
+ 'tag' => 'Only list changes tagged with this tag.',
);
}
public function getDescription() {
return 'Enumerate recent changes';
}
+
+ public function getPossibleErrors() {
+ return array_merge( parent::getPossibleErrors(), array(
+ array( 'show' ),
+ array( 'code' => 'permissiondenied', 'info' => 'You need the patrol right to request the patrolled flag' ),
+ array( 'code' => 'user-excludeuser', 'info' => 'user and excludeuser cannot be used together' ),
+ ) );
+ }
protected function getExamples() {
return array (
@@ -467,6 +560,6 @@ class ApiQueryRecentChanges extends ApiQueryBase {
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiQueryRecentChanges.php 69986 2010-07-27 03:57:39Z tstarling $';
+ return __CLASS__ . ': $Id: ApiQueryRecentChanges.php 69932 2010-07-26 08:03:21Z tstarling $';
}
}
diff --git a/includes/api/ApiQueryRevisions.php b/includes/api/ApiQueryRevisions.php
index eba526a3..6166b6a2 100644
--- a/includes/api/ApiQueryRevisions.php
+++ b/includes/api/ApiQueryRevisions.php
@@ -23,9 +23,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ('ApiQueryBase.php');
+ require_once ( 'ApiQueryBase.php' );
}
/**
@@ -37,12 +37,12 @@ if (!defined('MEDIAWIKI')) {
*/
class ApiQueryRevisions extends ApiQueryBase {
- public function __construct($query, $moduleName) {
- parent :: __construct($query, $moduleName, 'rv');
+ public function __construct( $query, $moduleName ) {
+ parent :: __construct( $query, $moduleName, 'rv' );
}
private $fld_ids = false, $fld_flags = false, $fld_timestamp = false, $fld_size = false,
- $fld_comment = false, $fld_user = false, $fld_content = false;
+ $fld_comment = false, $fld_parsedcomment = false, $fld_user = false, $fld_content = false, $fld_tags = false;
protected function getTokenFunctions() {
// tokenname => function
@@ -50,40 +50,40 @@ class ApiQueryRevisions extends ApiQueryBase {
// should return token or false
// Don't call the hooks twice
- if(isset($this->tokenFunctions))
+ if ( isset( $this->tokenFunctions ) )
return $this->tokenFunctions;
// If we're in JSON callback mode, no tokens can be obtained
- if(!is_null($this->getMain()->getRequest()->getVal('callback')))
+ if ( !is_null( $this->getMain()->getRequest()->getVal( 'callback' ) ) )
return array();
$this->tokenFunctions = array(
'rollback' => array( 'ApiQueryRevisions', 'getRollbackToken' )
);
- wfRunHooks('APIQueryRevisionsTokens', array(&$this->tokenFunctions));
+ wfRunHooks( 'APIQueryRevisionsTokens', array( &$this->tokenFunctions ) );
return $this->tokenFunctions;
}
- public static function getRollbackToken($pageid, $title, $rev)
+ public static function getRollbackToken( $pageid, $title, $rev )
{
global $wgUser;
- if(!$wgUser->isAllowed('rollback'))
+ if ( !$wgUser->isAllowed( 'rollback' ) )
return false;
- return $wgUser->editToken(array($title->getPrefixedText(),
- $rev->getUserText()));
+ return $wgUser->editToken( array( $title->getPrefixedText(),
+ $rev->getUserText() ) );
}
public function execute() {
- $params = $this->extractRequestParams(false);
+ $params = $this->extractRequestParams( false );
// 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 extremely
// difficult to manage continuations and require additional SQL indexes
- $enumRevMode = (!is_null($params['user']) || !is_null($params['excludeuser']) ||
- !is_null($params['limit']) || !is_null($params['startid']) ||
- !is_null($params['endid']) || $params['dir'] === 'newer' ||
- !is_null($params['start']) || !is_null($params['end']));
+ $enumRevMode = ( !is_null( $params['user'] ) || !is_null( $params['excludeuser'] ) ||
+ !is_null( $params['limit'] ) || !is_null( $params['startid'] ) ||
+ !is_null( $params['endid'] ) || $params['dir'] === 'newer' ||
+ !is_null( $params['start'] ) || !is_null( $params['end'] ) );
$pageSet = $this->getPageSet();
@@ -91,77 +91,99 @@ class ApiQueryRevisions extends ApiQueryBase {
$revCount = $pageSet->getRevisionCount();
// Optimization -- nothing to do
- if ($revCount === 0 && $pageCount === 0)
+ if ( $revCount === 0 && $pageCount === 0 )
return;
- if ($revCount > 0 && $enumRevMode)
- $this->dieUsage('The revids= parameter may not be used with the list options (limit, startid, endid, dirNewer, start, end).', 'revids');
+ if ( $revCount > 0 && $enumRevMode )
+ $this->dieUsage( 'The revids= parameter may not be used with the list options (limit, startid, endid, dirNewer, start, end).', 'revids' );
- if ($pageCount > 1 && $enumRevMode)
- $this->dieUsage('titles, pageids or a generator was used to supply multiple pages, but the limit, startid, endid, dirNewer, user, excludeuser, start and end parameters may only be used on a single page.', 'multpages');
+ if ( $pageCount > 1 && $enumRevMode )
+ $this->dieUsage( 'titles, pageids or a generator was used to supply multiple pages, but the limit, startid, endid, dirNewer, user, excludeuser, start and end parameters may only be used on a single page.', 'multpages' );
- if (!is_null($params['diffto'])) {
- if ($params['diffto'] == 'cur')
+ $this->diffto = $this->difftotext = null;
+ if ( !is_null( $params['difftotext'] ) ) {
+ $this->difftotext = $params['difftotext'];
+ } else if ( !is_null( $params['diffto'] ) ) {
+ if ( $params['diffto'] == 'cur' )
$params['diffto'] = 0;
- if ((!ctype_digit($params['diffto']) || $params['diffto'] < 0)
- && $params['diffto'] != 'prev' && $params['diffto'] != 'next')
- $this->dieUsage('rvdiffto must be set to a non-negative number, "prev", "next" or "cur"', 'diffto');
+ if ( ( !ctype_digit( $params['diffto'] ) || $params['diffto'] < 0 )
+ && $params['diffto'] != 'prev' && $params['diffto'] != 'next' )
+ $this->dieUsage( 'rvdiffto must be set to a non-negative number, "prev", "next" or "cur"', 'diffto' );
// Check whether the revision exists and is readable,
// DifferenceEngine returns a rather ambiguous empty
// string if that's not the case
- if ($params['diffto'] != 0) {
- $difftoRev = Revision::newFromID($params['diffto']);
- if (!$difftoRev)
- $this->dieUsageMsg(array('nosuchrevid', $params['diffto']));
- if (!$difftoRev->userCan(Revision::DELETED_TEXT)) {
- $this->setWarning("Couldn't diff to r{$difftoRev->getID()}: content is hidden");
+ if ( $params['diffto'] != 0 ) {
+ $difftoRev = Revision::newFromID( $params['diffto'] );
+ if ( !$difftoRev )
+ $this->dieUsageMsg( array( 'nosuchrevid', $params['diffto'] ) );
+ if ( !$difftoRev->userCan( Revision::DELETED_TEXT ) ) {
+ $this->setWarning( "Couldn't diff to r{$difftoRev->getID()}: content is hidden" );
$params['diffto'] = null;
}
}
+ $this->diffto = $params['diffto'];
}
- $this->addTables('revision');
- $this->addFields(Revision::selectFields());
- $this->addTables('page');
- $this->addWhere('page_id = rev_page');
+ $db = $this->getDB();
+ $this->addTables( array( 'page', 'revision' ) );
+ $this->addFields( Revision::selectFields() );
+ $this->addWhere( 'page_id = rev_page' );
- $prop = array_flip($params['prop']);
+ $prop = array_flip( $params['prop'] );
// Optional fields
- $this->fld_ids = isset ($prop['ids']);
+ $this->fld_ids = isset ( $prop['ids'] );
// $this->addFieldsIf('rev_text_id', $this->fld_ids); // should this be exposed?
- $this->fld_flags = isset ($prop['flags']);
- $this->fld_timestamp = isset ($prop['timestamp']);
- $this->fld_comment = isset ($prop['comment']);
- $this->fld_size = isset ($prop['size']);
- $this->fld_user = isset ($prop['user']);
+ $this->fld_flags = isset ( $prop['flags'] );
+ $this->fld_timestamp = isset ( $prop['timestamp'] );
+ $this->fld_comment = isset ( $prop['comment'] );
+ $this->fld_parsedcomment = isset ( $prop['parsedcomment'] );
+ $this->fld_size = isset ( $prop['size'] );
+ $this->fld_user = isset ( $prop['user'] );
$this->token = $params['token'];
- $this->diffto = $params['diffto'];
- if ( !is_null($this->token) || $pageCount > 0) {
+ // Possible indexes used
+ $index = array();
+
+ if ( !is_null( $this->token ) || $pageCount > 0 ) {
$this->addFields( Revision::selectPageFields() );
}
- if (isset ($prop['content'])) {
+ if ( isset ( $prop['tags'] ) ) {
+ $this->fld_tags = true;
+ $this->addTables( 'tag_summary' );
+ $this->addJoinConds( array( 'tag_summary' => array( 'LEFT JOIN', array( 'rev_id=ts_rev_id' ) ) ) );
+ $this->addFields( 'ts_tags' );
+ }
+
+ if ( !is_null( $params['tag'] ) ) {
+ $this->addTables( 'change_tag' );
+ $this->addJoinConds( array( 'change_tag' => array( 'INNER JOIN', array( 'rev_id=ct_rev_id' ) ) ) );
+ $this->addWhereFld( 'ct_tag' , $params['tag'] );
+ global $wgOldChangeTagsIndex;
+ $index['change_tag'] = $wgOldChangeTagsIndex ? 'ct_tag' : 'change_tag_tag_id';
+ }
+
+ if ( isset( $prop['content'] ) || !is_null( $this->difftotext ) ) {
// For each page we will request, the user must have read rights for that page
- foreach ($pageSet->getGoodTitles() as $title) {
- if( !$title->userCanRead() )
+ foreach ( $pageSet->getGoodTitles() as $title ) {
+ if ( !$title->userCanRead() )
$this->dieUsage(
'The current user is not allowed to read ' . $title->getPrefixedText(),
- 'accessdenied');
+ 'accessdenied' );
}
- $this->addTables('text');
- $this->addWhere('rev_text_id=old_id');
- $this->addFields('old_id');
- $this->addFields(Revision::selectTextFields());
+ $this->addTables( 'text' );
+ $this->addWhere( 'rev_text_id=old_id' );
+ $this->addFields( 'old_id' );
+ $this->addFields( Revision::selectTextFields() );
- $this->fld_content = true;
+ $this->fld_content = isset( $prop['content'] );
$this->expandTemplates = $params['expandtemplates'];
$this->generateXML = $params['generatexml'];
- if(isset($params['section']))
+ if ( isset( $params['section'] ) )
$this->section = $params['section'];
else
$this->section = false;
@@ -170,22 +192,22 @@ class ApiQueryRevisions extends ApiQueryBase {
$userMax = ( $this->fld_content ? ApiBase::LIMIT_SML1 : ApiBase::LIMIT_BIG1 );
$botMax = ( $this->fld_content ? ApiBase::LIMIT_SML2 : ApiBase::LIMIT_BIG2 );
$limit = $params['limit'];
- if( $limit == 'max' ) {
+ if ( $limit == 'max' ) {
$limit = $this->getMain()->canApiHighLimits() ? $botMax : $userMax;
$this->getResult()->addValue( 'limits', $this->getModuleName(), $limit );
}
- if ($enumRevMode) {
+ if ( $enumRevMode ) {
// This is mostly to prevent parameter errors (and optimize SQL?)
- if (!is_null($params['startid']) && !is_null($params['start']))
- $this->dieUsage('start and startid cannot be used together', 'badparams');
+ if ( !is_null( $params['startid'] ) && !is_null( $params['start'] ) )
+ $this->dieUsage( 'start and startid cannot be used together', 'badparams' );
- if (!is_null($params['endid']) && !is_null($params['end']))
- $this->dieUsage('end and endid cannot be used together', 'badparams');
+ if ( !is_null( $params['endid'] ) && !is_null( $params['end'] ) )
+ $this->dieUsage( 'end and endid cannot be used together', 'badparams' );
- if(!is_null($params['user']) && !is_null($params['excludeuser']))
- $this->dieUsage('user and excludeuser cannot be used together', 'badparams');
+ if ( !is_null( $params['user'] ) && !is_null( $params['excludeuser'] ) )
+ $this->dieUsage( 'user and excludeuser cannot be used together', 'badparams' );
// This code makes an assumption that sorting by rev_id and rev_timestamp produces
// the same result. This way users may request revisions starting at a given time,
@@ -194,187 +216,212 @@ class ApiQueryRevisions extends ApiQueryBase {
// one row with the same timestamp for the same page.
// The order needs to be the same as start parameter to avoid SQL filesort.
- if (is_null($params['startid']) && is_null($params['endid']))
- $this->addWhereRange('rev_timestamp', $params['dir'],
- $params['start'], $params['end']);
+ if ( is_null( $params['startid'] ) && is_null( $params['endid'] ) )
+ $this->addWhereRange( 'rev_timestamp', $params['dir'],
+ $params['start'], $params['end'] );
else {
- $this->addWhereRange('rev_id', $params['dir'],
- $params['startid'], $params['endid']);
+ $this->addWhereRange( 'rev_id', $params['dir'],
+ $params['startid'], $params['endid'] );
// One of start and end can be set
// If neither is set, this does nothing
- $this->addWhereRange('rev_timestamp', $params['dir'],
- $params['start'], $params['end'], false);
+ $this->addWhereRange( 'rev_timestamp', $params['dir'],
+ $params['start'], $params['end'], false );
}
// must manually initialize unset limit
- if (is_null($limit))
+ if ( is_null( $limit ) )
$limit = 10;
- $this->validateLimit('limit', $limit, 1, $userMax, $botMax);
+ $this->validateLimit( 'limit', $limit, 1, $userMax, $botMax );
// There is only one ID, use it
- $this->addWhereFld('rev_page', reset(array_keys($pageSet->getGoodTitles())));
-
- if(!is_null($params['user'])) {
- $this->addWhereFld('rev_user_text', $params['user']);
- } elseif (!is_null($params['excludeuser'])) {
- $this->addWhere('rev_user_text != ' .
- $this->getDB()->addQuotes($params['excludeuser']));
+ $ids = array_keys( $pageSet->getGoodTitles() );
+ $this->addWhereFld( 'rev_page', reset( $ids ) );
+
+ if ( !is_null( $params['user'] ) ) {
+ $this->addWhereFld( 'rev_user_text', $params['user'] );
+ } elseif ( !is_null( $params['excludeuser'] ) ) {
+ $this->addWhere( 'rev_user_text != ' .
+ $db->addQuotes( $params['excludeuser'] ) );
}
- if(!is_null($params['user']) || !is_null($params['excludeuser'])) {
+ if ( !is_null( $params['user'] ) || !is_null( $params['excludeuser'] ) ) {
// Paranoia: avoid brute force searches (bug 17342)
- $this->addWhere('rev_deleted & ' . Revision::DELETED_USER . ' = 0');
+ $this->addWhere( $db->bitAnd( 'rev_deleted', Revision::DELETED_USER ) . ' = 0' );
}
}
- elseif ($revCount > 0) {
+ elseif ( $revCount > 0 ) {
$max = $this->getMain()->canApiHighLimits() ? $botMax : $userMax;
$revs = $pageSet->getRevisionIDs();
- if(self::truncateArray($revs, $max))
- $this->setWarning("Too many values supplied for parameter 'revids': the limit is $max");
+ if ( self::truncateArray( $revs, $max ) )
+ $this->setWarning( "Too many values supplied for parameter 'revids': the limit is $max" );
// Get all revision IDs
- $this->addWhereFld('rev_id', array_keys($revs));
+ $this->addWhereFld( 'rev_id', array_keys( $revs ) );
- if(!is_null($params['continue']))
- $this->addWhere("rev_id >= '" . intval($params['continue']) . "'");
- $this->addOption('ORDER BY', 'rev_id');
+ if ( !is_null( $params['continue'] ) )
+ $this->addWhere( "rev_id >= '" . intval( $params['continue'] ) . "'" );
+ $this->addOption( 'ORDER BY', 'rev_id' );
// assumption testing -- we should never get more then $revCount rows.
$limit = $revCount;
}
- elseif ($pageCount > 0) {
+ elseif ( $pageCount > 0 ) {
$max = $this->getMain()->canApiHighLimits() ? $botMax : $userMax;
$titles = $pageSet->getGoodTitles();
- if(self::truncateArray($titles, $max))
- $this->setWarning("Too many values supplied for parameter 'titles': the limit is $max");
+ if ( self::truncateArray( $titles, $max ) )
+ $this->setWarning( "Too many values supplied for parameter 'titles': the limit is $max" );
// When working in multi-page non-enumeration mode,
// limit to the latest revision only
- $this->addWhere('page_id=rev_page');
- $this->addWhere('page_latest=rev_id');
+ $this->addWhere( 'page_id=rev_page' );
+ $this->addWhere( 'page_latest=rev_id' );
// Get all page IDs
- $this->addWhereFld('page_id', array_keys($titles));
+ $this->addWhereFld( 'page_id', array_keys( $titles ) );
// Every time someone relies on equality propagation, god kills a kitten :)
- $this->addWhereFld('rev_page', array_keys($titles));
+ $this->addWhereFld( 'rev_page', array_keys( $titles ) );
- if(!is_null($params['continue']))
+ if ( !is_null( $params['continue'] ) )
{
- $cont = explode('|', $params['continue']);
- if(count($cont) != 2)
- $this->dieUsage("Invalid continue param. You should pass the original " .
- "value returned by the previous query", "_badcontinue");
- $pageid = intval($cont[0]);
- $revid = intval($cont[1]);
- $this->addWhere("rev_page > '$pageid' OR " .
+ $cont = explode( '|', $params['continue'] );
+ if ( count( $cont ) != 2 )
+ $this->dieUsage( "Invalid continue param. You should pass the original " .
+ "value returned by the previous query", "_badcontinue" );
+ $pageid = intval( $cont[0] );
+ $revid = intval( $cont[1] );
+ $this->addWhere( "rev_page > '$pageid' OR " .
"(rev_page = '$pageid' AND " .
- "rev_id >= '$revid')");
+ "rev_id >= '$revid')" );
}
- $this->addOption('ORDER BY', 'rev_page, rev_id');
+ $this->addOption( 'ORDER BY', 'rev_page, rev_id' );
// assumption testing -- we should never get more then $pageCount rows.
$limit = $pageCount;
} else
- ApiBase :: dieDebug(__METHOD__, 'param validation?');
+ ApiBase :: dieDebug( __METHOD__, 'param validation?' );
- $this->addOption('LIMIT', $limit +1);
+ $this->addOption( 'LIMIT', $limit + 1 );
+ $this->addOption( 'USE INDEX', $index );
$data = array ();
$count = 0;
- $res = $this->select(__METHOD__);
+ $res = $this->select( __METHOD__ );
- $db = $this->getDB();
- while ($row = $db->fetchObject($res)) {
+ while ( $row = $db->fetchObject( $res ) ) {
- if (++ $count > $limit) {
+ if ( ++ $count > $limit ) {
// We've reached the one extra which shows that there are additional pages to be had. Stop here...
- if (!$enumRevMode)
- ApiBase :: dieDebug(__METHOD__, 'Got more rows then expected'); // bug report
- $this->setContinueEnumParameter('startid', intval($row->rev_id));
+ if ( !$enumRevMode )
+ ApiBase :: dieDebug( __METHOD__, 'Got more rows then expected' ); // bug report
+ $this->setContinueEnumParameter( 'startid', intval( $row->rev_id ) );
break;
}
- $revision = new Revision( $row );
+
//
- $fit = $this->addPageSubItem($revision->getPage(), $this->extractRowInfo($revision), 'rev');
- if(!$fit)
+ $fit = $this->addPageSubItem( $row->rev_page, $this->extractRowInfo( $row ), 'rev' );
+ if ( !$fit )
{
- if($enumRevMode)
- $this->setContinueEnumParameter('startid', intval($row->rev_id));
- else if($revCount > 0)
- $this->setContinueEnumParameter('continue', intval($row->rev_id));
+ if ( $enumRevMode )
+ $this->setContinueEnumParameter( 'startid', intval( $row->rev_id ) );
+ else if ( $revCount > 0 )
+ $this->setContinueEnumParameter( 'continue', intval( $row->rev_id ) );
else
- $this->setContinueEnumParameter('continue', intval($row->rev_page) .
- '|' . intval($row->rev_id));
+ $this->setContinueEnumParameter( 'continue', intval( $row->rev_page ) .
+ '|' . intval( $row->rev_id ) );
break;
}
}
- $db->freeResult($res);
+ $db->freeResult( $res );
}
- private function extractRowInfo( $revision ) {
+ private function extractRowInfo( $row ) {
+ $revision = new Revision( $row );
$title = $revision->getTitle();
$vals = array ();
- if ($this->fld_ids) {
- $vals['revid'] = intval($revision->getId());
+ if ( $this->fld_ids ) {
+ $vals['revid'] = intval( $revision->getId() );
// $vals['oldid'] = intval($row->rev_text_id); // todo: should this be exposed?
+ if ( !is_null( $revision->getParentId() ) )
+ $vals['parentid'] = intval( $revision->getParentId() );
}
- if ($this->fld_flags && $revision->isMinor())
+ if ( $this->fld_flags && $revision->isMinor() )
$vals['minor'] = '';
- if ($this->fld_user) {
- if ($revision->isDeleted(Revision::DELETED_USER)) {
+ if ( $this->fld_user ) {
+ if ( $revision->isDeleted( Revision::DELETED_USER ) ) {
$vals['userhidden'] = '';
} else {
$vals['user'] = $revision->getUserText();
- if (!$revision->getUser())
+ if ( !$revision->getUser() )
$vals['anon'] = '';
}
}
- if ($this->fld_timestamp) {
- $vals['timestamp'] = wfTimestamp(TS_ISO_8601, $revision->getTimestamp());
+ if ( $this->fld_timestamp ) {
+ $vals['timestamp'] = wfTimestamp( TS_ISO_8601, $revision->getTimestamp() );
}
- if ($this->fld_size && !is_null($revision->getSize())) {
- $vals['size'] = intval($revision->getSize());
+ if ( $this->fld_size && !is_null( $revision->getSize() ) ) {
+ $vals['size'] = intval( $revision->getSize() );
}
- if ($this->fld_comment) {
- if ($revision->isDeleted(Revision::DELETED_COMMENT)) {
+ if ( $this->fld_comment || $this->fld_parsedcomment ) {
+ if ( $revision->isDeleted( Revision::DELETED_COMMENT ) ) {
$vals['commenthidden'] = '';
} else {
$comment = $revision->getComment();
- if (strval($comment) !== '')
- $vals['comment'] = $comment;
+ if ( strval( $comment ) !== '' )
+ {
+ if ( $this->fld_comment )
+ $vals['comment'] = $comment;
+
+ if ( $this->fld_parsedcomment ) {
+ global $wgUser;
+ $vals['parsedcomment'] = $wgUser->getSkin()->formatComment( $comment, $title );
+ }
+ }
}
- }
+ }
- if(!is_null($this->token))
+ if ( $this->fld_tags ) {
+ if ( $row->ts_tags ) {
+ $tags = explode( ',', $row->ts_tags );
+ $this->getResult()->setIndexedTagName( $tags, 'tag' );
+ $vals['tags'] = $tags;
+ } else {
+ $vals['tags'] = array();
+ }
+ }
+
+ if ( !is_null( $this->token ) )
{
$tokenFunctions = $this->getTokenFunctions();
- foreach($this->token as $t)
+ foreach ( $this->token as $t )
{
- $val = call_user_func($tokenFunctions[$t], $title->getArticleID(), $title, $revision);
- if($val === false)
- $this->setWarning("Action '$t' is not allowed for the current user");
+ $val = call_user_func( $tokenFunctions[$t], $title->getArticleID(), $title, $revision );
+ if ( $val === false )
+ $this->setWarning( "Action '$t' is not allowed for the current user" );
else
$vals[$t . 'token'] = $val;
}
}
- if ($this->fld_content && !$revision->isDeleted(Revision::DELETED_TEXT)) {
+ $text = null;
+ if ( $this->fld_content || !is_null( $this->difftotext ) ) {
global $wgParser;
$text = $revision->getText();
- # Expand templates after getting section content because
- # template-added sections don't count and Parser::preprocess()
- # will have less input
- if ($this->section !== false) {
- $text = $wgParser->getSection( $text, $this->section, false);
- if($text === false)
- $this->dieUsage("There is no section {$this->section} in r".$revision->getId(), 'nosuchsection');
+ // Expand templates after getting section content because
+ // template-added sections don't count and Parser::preprocess()
+ // will have less input
+ if ( $this->section !== false ) {
+ $text = $wgParser->getSection( $text, $this->section, false );
+ if ( $text === false )
+ $this->dieUsage( "There is no section {$this->section} in r" . $revision->getId(), 'nosuchsection' );
}
- if ($this->generateXML) {
+ }
+ if ( $this->fld_content && !$revision->isDeleted( Revision::DELETED_TEXT ) ) {
+ if ( $this->generateXML ) {
$wgParser->startExternalParse( $title, new ParserOptions(), OT_PREPROCESS );
$dom = $wgParser->preprocessToDom( $text );
if ( is_callable( array( $dom, 'saveXML' ) ) ) {
@@ -385,24 +432,30 @@ class ApiQueryRevisions extends ApiQueryBase {
$vals['parsetree'] = $xml;
}
- if ($this->expandTemplates) {
+ if ( $this->expandTemplates ) {
$text = $wgParser->preprocess( $text, $title, new ParserOptions() );
}
- ApiResult :: setContent($vals, $text);
- } else if ($this->fld_content) {
+ ApiResult :: setContent( $vals, $text );
+ } else if ( $this->fld_content ) {
$vals['texthidden'] = '';
}
- if (!is_null($this->diffto)) {
+ if ( !is_null( $this->diffto ) || !is_null( $this->difftotext ) ) {
global $wgAPIMaxUncachedDiffs;
- static $n = 0; // Numer of uncached diffs we've had
- if($n< $wgAPIMaxUncachedDiffs) {
- $engine = new DifferenceEngine($title, $revision->getID(), $this->diffto);
+ static $n = 0; // Number of uncached diffs we've had
+ if ( $n < $wgAPIMaxUncachedDiffs ) {
+ $vals['diff'] = array();
+ if ( !is_null( $this->difftotext ) ) {
+ $engine = new DifferenceEngine( $title );
+ $engine->setText( $text, $this->difftotext );
+ } else {
+ $engine = new DifferenceEngine( $title, $revision->getID(), $this->diffto );
+ $vals['diff']['from'] = $engine->getOldid();
+ $vals['diff']['to'] = $engine->getNewid();
+ }
$difftext = $engine->getDiffBody();
- $vals['diff']['from'] = $engine->getOldid();
- $vals['diff']['to'] = $engine->getNewid();
- ApiResult::setContent($vals['diff'], $difftext);
- if(!$engine->wasCacheHit())
+ ApiResult::setContent( $vals['diff'], $difftext );
+ if ( !$engine->wasCacheHit() )
$n++;
} else {
$vals['diff']['notcached'] = '';
@@ -434,7 +487,9 @@ class ApiQueryRevisions extends ApiQueryBase {
'user',
'size',
'comment',
+ 'parsedcomment',
'content',
+ 'tags'
)
),
'limit' => array (
@@ -468,36 +523,41 @@ class ApiQueryRevisions extends ApiQueryBase {
'excludeuser' => array(
ApiBase :: PARAM_TYPE => 'user'
),
+ 'tag' => null,
'expandtemplates' => false,
'generatexml' => false,
'section' => null,
'token' => array(
- ApiBase :: PARAM_TYPE => array_keys($this->getTokenFunctions()),
+ ApiBase :: PARAM_TYPE => array_keys( $this->getTokenFunctions() ),
ApiBase :: PARAM_ISMULTI => true
),
'continue' => null,
'diffto' => null,
+ 'difftotext' => null,
);
}
public function getParamDescription() {
return array (
'prop' => 'Which properties to get for each revision.',
- 'limit' => 'limit how many revisions will be returned (enum)',
- 'startid' => 'from which revision id to start enumeration (enum)',
- 'endid' => 'stop revision enumeration on this revid (enum)',
- 'start' => 'from which revision timestamp to start enumeration (enum)',
- 'end' => 'enumerate up to this timestamp (enum)',
- 'dir' => 'direction of enumeration - towards "newer" or "older" revisions (enum)',
- 'user' => 'only include revisions made by user',
- 'excludeuser' => 'exclude revisions made by user',
- 'expandtemplates' => 'expand templates in revision content',
- 'generatexml' => 'generate XML parse tree for revision content',
- 'section' => 'only retrieve the content of this section',
+ 'limit' => 'Limit how many revisions will be returned (enum)',
+ 'startid' => 'From which revision id to start enumeration (enum)',
+ 'endid' => 'Stop revision enumeration on this revid (enum)',
+ 'start' => 'From which revision timestamp to start enumeration (enum)',
+ 'end' => 'Enumerate up to this timestamp (enum)',
+ 'dir' => 'Direction of enumeration - towards "newer" or "older" revisions (enum)',
+ 'user' => 'Only include revisions made by user',
+ 'excludeuser' => 'Exclude revisions made by user',
+ 'expandtemplates' => 'Expand templates in revision content',
+ 'generatexml' => 'Generate XML parse tree for revision content',
+ 'section' => 'Only retrieve the content of this section',
'token' => 'Which tokens to obtain for each revision',
'continue' => 'When more results are available, use this to continue',
- 'diffto' => array('Revision ID to diff each revision to.',
- 'Use "prev", "next" and "cur" for the previous, next and current revision respectively.'),
+ 'diffto' => array( 'Revision ID to diff each revision to.',
+ 'Use "prev", "next" and "cur" for the previous, next and current revision respectively.' ),
+ 'difftotext' => array( 'Text to diff each revision to. Only diffs a limited number of revisions.',
+ 'Overrides diffto. If rvsection is set, only that section will be diffed against this text.' ),
+ 'tag' => 'Only list revisions tagged with this tag',
);
}
@@ -511,6 +571,19 @@ class ApiQueryRevisions extends ApiQueryBase {
'All parameters marked as (enum) may only be used with a single page (#2).'
);
}
+
+ public function getPossibleErrors() {
+ return array_merge( parent::getPossibleErrors(), array(
+ array( 'nosuchrevid', 'diffto' ),
+ array( 'code' => 'revids', 'info' => 'The revids= parameter may not be used with the list options (limit, startid, endid, dirNewer, start, end).' ),
+ array( 'code' => 'multpages', 'info' => 'titles, pageids or a generator was used to supply multiple pages, but the limit, startid, endid, dirNewer, user, excludeuser, start and end parameters may only be used on a single page.' ),
+ array( 'code' => 'diffto', 'info' => 'rvdiffto must be set to a non-negative number, "prev", "next" or "cur"' ),
+ array( 'code' => 'badparams', 'info' => 'start and startid cannot be used together' ),
+ array( 'code' => 'badparams', 'info' => 'end and endid cannot be used together' ),
+ array( 'code' => 'badparams', 'info' => 'user and excludeuser cannot be used together' ),
+ array( 'code' => 'nosuchsection', 'info' => 'There is no section section in rID' ),
+ ) );
+ }
protected function getExamples() {
return array (
@@ -530,6 +603,6 @@ class ApiQueryRevisions extends ApiQueryBase {
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiQueryRevisions.php 69986 2010-07-27 03:57:39Z tstarling $';
+ return __CLASS__ . ': $Id: ApiQueryRevisions.php 69932 2010-07-26 08:03:21Z tstarling $';
}
}
diff --git a/includes/api/ApiQuerySearch.php b/includes/api/ApiQuerySearch.php
index a8f3fcc8..4e032321 100644
--- a/includes/api/ApiQuerySearch.php
+++ b/includes/api/ApiQuerySearch.php
@@ -23,9 +23,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ('ApiQueryBase.php');
+ require_once ( 'ApiQueryBase.php' );
}
/**
@@ -35,36 +35,42 @@ if (!defined('MEDIAWIKI')) {
*/
class ApiQuerySearch extends ApiQueryGeneratorBase {
- public function __construct($query, $moduleName) {
- parent :: __construct($query, $moduleName, 'sr');
+ public function __construct( $query, $moduleName ) {
+ parent :: __construct( $query, $moduleName, 'sr' );
}
public function execute() {
$this->run();
}
- public function executeGenerator($resultPageSet) {
- $this->run($resultPageSet);
+ public function executeGenerator( $resultPageSet ) {
+ $this->run( $resultPageSet );
}
- private function run($resultPageSet = null) {
-
+ private function run( $resultPageSet = null ) {
+ global $wgContLang;
$params = $this->extractRequestParams();
+ // Extract parameters
$limit = $params['limit'];
$query = $params['search'];
$what = $params['what'];
- if (strval($query) === '')
- $this->dieUsage("empty search string is not allowed", 'param-search');
+ $searchInfo = array_flip( $params['info'] );
+ $prop = array_flip( $params['prop'] );
+
+ if ( strval( $query ) === '' )
+ $this->dieUsage( "empty search string is not allowed", 'param-search' );
+ // Create search engine instance and set options
$search = SearchEngine::create();
- $search->setLimitOffset( $limit+1, $params['offset'] );
+ $search->setLimitOffset( $limit + 1, $params['offset'] );
$search->setNamespaces( $params['namespace'] );
$search->showRedirects = $params['redirects'];
- if ($what == 'text') {
+ // Perform the actual search
+ if ( $what == 'text' ) {
$matches = $search->searchText( $query );
- } elseif( $what == 'title' ) {
+ } elseif ( $what == 'title' ) {
$matches = $search->searchTitle( $query );
} else {
// We default to title searches; this is a terrible legacy
@@ -78,36 +84,61 @@ class ApiQuerySearch extends ApiQueryGeneratorBase {
// for instance the Lucene-based engine we use on Wikipedia.
// In this case, fall back to full-text search (which will
// include titles in it!)
- if( is_null( $matches ) ) {
+ if ( is_null( $matches ) ) {
$what = 'text';
$matches = $search->searchText( $query );
}
}
- if (is_null($matches))
- $this->dieUsage("{$what} search is disabled",
- "search-{$what}-disabled");
+ if ( is_null( $matches ) )
+ $this->dieUsage( "{$what} search is disabled", "search-{$what}-disabled" );
+
+ // Add search meta data to result
+ if ( isset( $searchInfo['totalhits'] ) ) {
+ $totalhits = $matches->getTotalHits();
+ if ( $totalhits !== null ) {
+ $this->getResult()->addValue( array( 'query', 'searchinfo' ),
+ 'totalhits', $totalhits );
+ }
+ }
+ if ( isset( $searchInfo['suggestion'] ) && $matches->hasSuggestion() ) {
+ $this->getResult()->addValue( array( 'query', 'searchinfo' ),
+ 'suggestion', $matches->getSuggestionQuery() );
+ }
+ // Add the search results to the result
+ $terms = $wgContLang->convertForSearchResult( $matches->termMatches() );
$titles = array ();
$count = 0;
- while( $result = $matches->next() ) {
- if (++ $count > $limit) {
+ while ( $result = $matches->next() ) {
+ if ( ++ $count > $limit ) {
// We've reached the one extra which shows that there are additional items to be had. Stop here...
- $this->setContinueEnumParameter('offset', $params['offset'] + $params['limit']);
+ $this->setContinueEnumParameter( 'offset', $params['offset'] + $params['limit'] );
break;
}
// Silently skip broken and missing titles
- if ($result->isBrokenTitle() || $result->isMissingRevision())
+ if ( $result->isBrokenTitle() || $result->isMissingRevision() )
continue;
$title = $result->getTitle();
- if (is_null($resultPageSet)) {
+ if ( is_null( $resultPageSet ) ) {
$vals = array();
- ApiQueryBase::addTitleInfo($vals, $title);
- $fit = $this->getResult()->addValue(array('query', $this->getModuleName()), null, $vals);
- if(!$fit)
- {
- $this->setContinueEnumParameter('offset', $params['offset'] + $count - 1);
+ ApiQueryBase::addTitleInfo( $vals, $title );
+
+ if ( isset( $prop['snippet'] ) )
+ $vals['snippet'] = $result->getTextSnippet( $terms );
+ if ( isset( $prop['size'] ) )
+ $vals['size'] = $result->getByteSize();
+ if ( isset( $prop['wordcount'] ) )
+ $vals['wordcount'] = $result->getWordCount();
+ if ( isset( $prop['timestamp'] ) )
+ $vals['timestamp'] = wfTimestamp( TS_ISO_8601, $result->getTimestamp() );
+
+ // Add item to results and see whether it fits
+ $fit = $this->getResult()->addValue( array( 'query', $this->getModuleName() ),
+ null, $vals );
+ if ( !$fit ) {
+ $this->setContinueEnumParameter( 'offset', $params['offset'] + $count - 1 );
break;
}
} else {
@@ -115,10 +146,12 @@ class ApiQuerySearch extends ApiQueryGeneratorBase {
}
}
- if (is_null($resultPageSet)) {
- $this->getResult()->setIndexedTagName_internal(array('query', $this->getModuleName()), 'p');
+ if ( is_null( $resultPageSet ) ) {
+ $this->getResult()->setIndexedTagName_internal( array(
+ 'query', $this->getModuleName()
+ ), 'p' );
} else {
- $resultPageSet->populateFromTitles($titles);
+ $resultPageSet->populateFromTitles( $titles );
}
}
@@ -141,14 +174,32 @@ class ApiQuerySearch extends ApiQueryGeneratorBase {
'text',
)
),
+ 'info' => array(
+ ApiBase :: PARAM_DFLT => 'totalhits|suggestion',
+ ApiBase :: PARAM_TYPE => array (
+ 'totalhits',
+ 'suggestion',
+ ),
+ ApiBase :: PARAM_ISMULTI => true,
+ ),
+ 'prop' => array(
+ ApiBase :: PARAM_DFLT => 'size|wordcount|timestamp|snippet',
+ ApiBase :: PARAM_TYPE => array (
+ 'size',
+ 'wordcount',
+ 'timestamp',
+ 'snippet',
+ ),
+ ApiBase :: PARAM_ISMULTI => true,
+ ),
'redirects' => false,
'offset' => 0,
'limit' => array (
ApiBase :: PARAM_DFLT => 10,
ApiBase :: PARAM_TYPE => 'limit',
ApiBase :: PARAM_MIN => 1,
- ApiBase :: PARAM_MAX => ApiBase :: LIMIT_BIG1,
- ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2
+ ApiBase :: PARAM_MAX => ApiBase :: LIMIT_SML1,
+ ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_SML2
)
);
}
@@ -158,6 +209,8 @@ class ApiQuerySearch extends ApiQueryGeneratorBase {
'search' => 'Search for all page titles (or content) that has this value.',
'namespace' => 'The namespace(s) to enumerate.',
'what' => 'Search inside the text or titles.',
+ 'info' => 'What metadata to return.',
+ 'prop' => 'What properties to return.',
'redirects' => 'Include redirect pages in the search.',
'offset' => 'Use this value to continue paging (return by query)',
'limit' => 'How many total pages to return.'
@@ -167,6 +220,14 @@ class ApiQuerySearch extends ApiQueryGeneratorBase {
public function getDescription() {
return 'Perform a full text search';
}
+
+ public function getPossibleErrors() {
+ return array_merge( parent::getPossibleErrors(), array(
+ array( 'code' => 'param-search', 'info' => 'empty search string is not allowed' ),
+ array( 'code' => 'search-text-disabled', 'info' => 'text search is disabled' ),
+ array( 'code' => 'search-title-disabled', 'info' => 'title search is disabled' ),
+ ) );
+ }
protected function getExamples() {
return array (
@@ -177,6 +238,6 @@ class ApiQuerySearch extends ApiQueryGeneratorBase {
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiQuerySearch.php 69986 2010-07-27 03:57:39Z tstarling $';
+ return __CLASS__ . ': $Id: ApiQuerySearch.php 69932 2010-07-26 08:03:21Z tstarling $';
}
-} \ No newline at end of file
+}
diff --git a/includes/api/ApiQuerySiteinfo.php b/includes/api/ApiQuerySiteinfo.php
index 623855f6..0385e192 100644
--- a/includes/api/ApiQuerySiteinfo.php
+++ b/includes/api/ApiQuerySiteinfo.php
@@ -23,7 +23,7 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if( !defined('MEDIAWIKI') ) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
require_once( 'ApiQueryBase.php' );
}
@@ -42,7 +42,7 @@ class ApiQuerySiteinfo extends ApiQueryBase {
public function execute() {
$params = $this->extractRequestParams();
$done = array();
- foreach( $params['prop'] as $p )
+ foreach ( $params['prop'] as $p )
{
switch ( $p )
{
@@ -72,7 +72,7 @@ class ApiQuerySiteinfo extends ApiQueryBase {
$fit = $this->appendStatistics( $p );
break;
case 'usergroups':
- $fit = $this->appendUserGroups( $p );
+ $fit = $this->appendUserGroups( $p, $params['numberingroup'] );
break;
case 'extensions':
$fit = $this->appendExtensions( $p );
@@ -83,15 +83,18 @@ class ApiQuerySiteinfo extends ApiQueryBase {
case 'rightsinfo':
$fit = $this->appendRightsInfo( $p );
break;
+ case 'languages':
+ $fit = $this->appendLanguages( $p );
+ break;
default :
ApiBase :: dieDebug( __METHOD__, "Unknown prop=$p" );
}
- if(!$fit)
+ if ( !$fit )
{
- # Abuse siprop as a query-continue parameter
- # and set it to all unprocessed props
- $this->setContinueEnumParameter('prop', implode('|',
- array_diff($params['prop'], $done)));
+ // Abuse siprop as a query-continue parameter
+ // and set it to all unprocessed props
+ $this->setContinueEnumParameter( 'prop', implode( '|',
+ array_diff( $params['prop'], $done ) ) );
break;
}
$done[] = $p;
@@ -99,45 +102,59 @@ class ApiQuerySiteinfo extends ApiQueryBase {
}
protected function appendGeneralInfo( $property ) {
- global $wgSitename, $wgVersion, $wgCapitalLinks, $wgRightsCode, $wgRightsText, $wgContLang;
- global $wgLanguageCode, $IP, $wgEnableWriteAPI, $wgLang, $wgLocaltimezone, $wgLocalTZoffset;
+ global $wgContLang;
+ global $wgLang;
$data = array();
- $mainPage = Title :: newFromText(wfMsgForContent('mainpage'));
+ $mainPage = Title :: newFromText( wfMsgForContent( 'mainpage' ) );
$data['mainpage'] = $mainPage->getPrefixedText();
$data['base'] = $mainPage->getFullUrl();
- $data['sitename'] = $wgSitename;
- $data['generator'] = "MediaWiki $wgVersion";
-
- $svn = SpecialVersion::getSvnRevision( $IP );
- if( $svn )
+ $data['sitename'] = $GLOBALS['wgSitename'];
+ $data['generator'] = "MediaWiki {$GLOBALS['wgVersion']}";
+ $data['phpversion'] = phpversion();
+ $data['phpsapi'] = php_sapi_name();
+ $data['dbtype'] = $GLOBALS['wgDBtype'];
+ $data['dbversion'] = $this->getDB()->getServerVersion();
+
+ $svn = SpecialVersion::getSvnRevision( $GLOBALS['IP'] );
+ if ( $svn )
$data['rev'] = $svn;
- $data['case'] = $wgCapitalLinks ? 'first-letter' : 'case-sensitive'; // 'case-insensitive' option is reserved for future
+ // 'case-insensitive' option is reserved for future
+ $data['case'] = $GLOBALS['wgCapitalLinks'] ? 'first-letter' : 'case-sensitive';
- if( isset( $wgRightsCode ) )
- $data['rightscode'] = $wgRightsCode;
- $data['rights'] = $wgRightsText;
- $data['lang'] = $wgLanguageCode;
- if( $wgContLang->isRTL() )
+ if ( isset( $GLOBALS['wgRightsCode'] ) )
+ $data['rightscode'] = $GLOBALS['wgRightsCode'];
+ $data['rights'] = $GLOBALS['wgRightsText'];
+ $data['lang'] = $GLOBALS['wgLanguageCode'];
+ if ( $wgContLang->isRTL() )
$data['rtl'] = '';
$data['fallback8bitEncoding'] = $wgLang->fallback8bitEncoding();
- if( wfReadOnly() )
+ if ( wfReadOnly() ) {
$data['readonly'] = '';
- if( $wgEnableWriteAPI )
+ $data['readonlyreason'] = wfReadOnlyReason();
+ }
+ if ( $GLOBALS['wgEnableWriteAPI'] )
$data['writeapi'] = '';
- $tz = $wgLocaltimezone;
- $offset = $wgLocalTZoffset;
- if( is_null( $tz ) ) {
+ $tz = $GLOBALS['wgLocaltimezone'];
+ $offset = $GLOBALS['wgLocalTZoffset'];
+ if ( is_null( $tz ) ) {
$tz = 'UTC';
$offset = 0;
- } elseif( is_null( $offset ) ) {
+ } elseif ( is_null( $offset ) ) {
$offset = 0;
}
$data['timezone'] = $tz;
- $data['timeoffset'] = intval($offset);
+ $data['timeoffset'] = intval( $offset );
+ $data['articlepath'] = $GLOBALS['wgArticlePath'];
+ $data['scriptpath'] = $GLOBALS['wgScriptPath'];
+ $data['script'] = $GLOBALS['wgScript'];
+ $data['variantarticlepath'] = $GLOBALS['wgVariantArticlePath'];
+ $data['server'] = $GLOBALS['wgServer'];
+ $data['wikiid'] = wfWikiID();
+ $data['time'] = wfTimestamp( TS_ISO_8601, time() );
return $this->getResult()->addValue( 'query', $property, $data );
}
@@ -145,19 +162,23 @@ class ApiQuerySiteinfo extends ApiQueryBase {
protected function appendNamespaces( $property ) {
global $wgContLang;
$data = array();
- foreach( $wgContLang->getFormattedNamespaces() as $ns => $title )
+ foreach ( $wgContLang->getFormattedNamespaces() as $ns => $title )
{
$data[$ns] = array(
- 'id' => intval($ns)
+ 'id' => intval( $ns ),
+ 'case' => MWNamespace::isCapitalized( $ns ) ? 'first-letter' : 'case-sensitive',
);
ApiResult :: setContent( $data[$ns], $title );
$canonical = MWNamespace::getCanonicalName( $ns );
- if( MWNamespace::hasSubpages( $ns ) )
+ if ( MWNamespace::hasSubpages( $ns ) )
$data[$ns]['subpages'] = '';
- if( $canonical )
- $data[$ns]['canonical'] = strtr($canonical, '_', ' ');
+ if ( $canonical )
+ $data[$ns]['canonical'] = strtr( $canonical, '_', ' ' );
+
+ if ( MWNamespace::isContent( $ns ) )
+ $data[$ns]['content'] = '';
}
$this->getResult()->setIndexedTagName( $data, 'ns' );
@@ -166,17 +187,16 @@ class ApiQuerySiteinfo extends ApiQueryBase {
protected function appendNamespaceAliases( $property ) {
global $wgNamespaceAliases, $wgContLang;
- $wgContLang->load();
- $aliases = array_merge( $wgNamespaceAliases, $wgContLang->namespaceAliases );
+ $aliases = array_merge( $wgNamespaceAliases, $wgContLang->getNamespaceAliases() );
$namespaces = $wgContLang->getNamespaces();
$data = array();
- foreach( $aliases as $title => $ns ) {
- if( $namespaces[$ns] == $title ) {
+ foreach ( $aliases as $title => $ns ) {
+ if ( $namespaces[$ns] == $title ) {
// Don't list duplicates
continue;
}
$item = array(
- 'id' => intval($ns)
+ 'id' => intval( $ns )
);
ApiResult :: setContent( $item, strtr( $title, '_', ' ' ) );
$data[] = $item;
@@ -189,7 +209,7 @@ class ApiQuerySiteinfo extends ApiQueryBase {
protected function appendSpecialPageAliases( $property ) {
global $wgLang;
$data = array();
- foreach( $wgLang->getSpecialPageAliases() as $specialpage => $aliases )
+ foreach ( $wgLang->getSpecialPageAliases() as $specialpage => $aliases )
{
$arr = array( 'realname' => $specialpage, 'aliases' => $aliases );
$this->getResult()->setIndexedTagName( $arr['aliases'], 'alias' );
@@ -202,16 +222,16 @@ class ApiQuerySiteinfo extends ApiQueryBase {
protected function appendMagicWords( $property ) {
global $wgContLang;
$data = array();
- foreach($wgContLang->getMagicWords() as $magicword => $aliases)
+ foreach ( $wgContLang->getMagicWords() as $magicword => $aliases )
{
- $caseSensitive = array_shift($aliases);
- $arr = array('name' => $magicword, 'aliases' => $aliases);
- if($caseSensitive)
+ $caseSensitive = array_shift( $aliases );
+ $arr = array( 'name' => $magicword, 'aliases' => $aliases );
+ if ( $caseSensitive )
$arr['case-sensitive'] = '';
- $this->getResult()->setIndexedTagName($arr['aliases'], 'alias');
+ $this->getResult()->setIndexedTagName( $arr['aliases'], 'alias' );
$data[] = $arr;
}
- $this->getResult()->setIndexedTagName($data, 'magicword');
+ $this->getResult()->setIndexedTagName( $data, 'magicword' );
return $this->getResult()->addValue( 'query', $property, $data );
}
@@ -220,11 +240,11 @@ class ApiQuerySiteinfo extends ApiQueryBase {
$this->addTables( 'interwiki' );
$this->addFields( array( 'iw_prefix', 'iw_local', 'iw_url' ) );
- if( $filter === 'local' )
+ if ( $filter === 'local' )
$this->addWhere( 'iw_local = 1' );
- elseif( $filter === '!local' )
+ elseif ( $filter === '!local' )
$this->addWhere( 'iw_local = 0' );
- elseif( $filter )
+ elseif ( $filter )
ApiBase :: dieDebug( __METHOD__, "Unknown filter=$filter" );
$this->addOption( 'ORDER BY', 'iw_prefix' );
@@ -234,14 +254,14 @@ class ApiQuerySiteinfo extends ApiQueryBase {
$data = array();
$langNames = Language::getLanguageNames();
- while( $row = $db->fetchObject($res) )
+ while ( $row = $db->fetchObject( $res ) )
{
$val = array();
$val['prefix'] = $row->iw_prefix;
- if( $row->iw_local == '1' )
+ if ( $row->iw_local == '1' )
$val['local'] = '';
// $val['trans'] = intval($row->iw_trans); // should this be exposed?
- if( isset( $langNames[$row->iw_prefix] ) )
+ if ( isset( $langNames[$row->iw_prefix] ) )
$val['language'] = $langNames[$row->iw_prefix];
$val['url'] = $row->iw_url;
@@ -256,13 +276,13 @@ class ApiQuerySiteinfo extends ApiQueryBase {
protected function appendDbReplLagInfo( $property, $includeAll ) {
global $wgShowHostnames;
$data = array();
- if( $includeAll ) {
+ if ( $includeAll ) {
if ( !$wgShowHostnames )
- $this->dieUsage('Cannot view all servers info unless $wgShowHostnames is true', 'includeAllDenied');
+ $this->dieUsage( 'Cannot view all servers info unless $wgShowHostnames is true', 'includeAllDenied' );
$lb = wfGetLB();
$lags = $lb->getLagTimes();
- foreach( $lags as $i => $lag ) {
+ foreach ( $lags as $i => $lag ) {
$data[] = array(
'host' => $lb->getServerName( $i ),
'lag' => $lag
@@ -293,16 +313,22 @@ class ApiQuerySiteinfo extends ApiQueryBase {
$data['images'] = intval( SiteStats::images() );
$data['users'] = intval( SiteStats::users() );
$data['activeusers'] = intval( SiteStats::activeUsers() );
- $data['admins'] = intval( SiteStats::numberingroup('sysop') );
+ $data['admins'] = intval( SiteStats::numberingroup( 'sysop' ) );
$data['jobs'] = intval( SiteStats::jobs() );
return $this->getResult()->addValue( 'query', $property, $data );
}
- protected function appendUserGroups( $property ) {
+ protected function appendUserGroups( $property, $numberInGroup ) {
global $wgGroupPermissions;
$data = array();
- foreach( $wgGroupPermissions as $group => $permissions ) {
- $arr = array( 'name' => $group, 'rights' => array_keys( $permissions, true ) );
+ foreach ( $wgGroupPermissions as $group => $permissions ) {
+ $arr = array(
+ 'name' => $group,
+ 'rights' => array_keys( $permissions, true ),
+ );
+ if ( $numberInGroup )
+ $arr['number'] = SiteStats::numberInGroup( $group );
+
$this->getResult()->setIndexedTagName( $arr['rights'], 'permission' );
$data[] = $arr;
}
@@ -315,7 +341,7 @@ class ApiQuerySiteinfo extends ApiQueryBase {
global $wgFileExtensions;
$data = array();
- foreach( $wgFileExtensions as $ext ) {
+ foreach ( $wgFileExtensions as $ext ) {
$data[] = array( 'ext' => $ext );
}
$this->getResult()->setIndexedTagName( $data, 'fe' );
@@ -329,21 +355,32 @@ class ApiQuerySiteinfo extends ApiQueryBase {
foreach ( $extensions as $ext ) {
$ret = array();
$ret['type'] = $type;
- if ( isset( $ext['name'] ) )
+ if ( isset( $ext['name'] ) )
$ret['name'] = $ext['name'];
- if ( isset( $ext['description'] ) )
+ if ( isset( $ext['description'] ) )
$ret['description'] = $ext['description'];
- if ( isset( $ext['descriptionmsg'] ) )
- $ret['descriptionmsg'] = $ext['descriptionmsg'];
+ if ( isset( $ext['descriptionmsg'] ) ) {
+ // Can be a string or array( key, param1, param2, ... )
+ if ( is_array( $ext['descriptionmsg'] ) ) {
+ $ret['descriptionmsg'] = $ext['descriptionmsg'][0];
+ $ret['descriptionmsgparams'] = array_slice( $ext['descriptionmsg'], 1 );
+ $this->getResult()->setIndexedTagName( $ret['descriptionmsgparams'], 'param' );
+ } else {
+ $ret['descriptionmsg'] = $ext['descriptionmsg'];
+ }
+ }
if ( isset( $ext['author'] ) ) {
- $ret['author'] = is_array( $ext['author'] ) ?
+ $ret['author'] = is_array( $ext['author'] ) ?
implode( ', ', $ext['author' ] ) : $ext['author'];
}
+ if ( isset( $ext['url'] ) ) {
+ $ret['url'] = $ext['url'];
+ }
if ( isset( $ext['version'] ) ) {
$ret['version'] = $ext['version'];
- } elseif ( isset( $ext['svn-revision'] ) &&
- preg_match( '/\$(?:Rev|LastChangedRevision|Revision): *(\d+)/',
- $ext['svn-revision'], $m ) )
+ } elseif ( isset( $ext['svn-revision'] ) &&
+ preg_match( '/\$(?:Rev|LastChangedRevision|Revision): *(\d+)/',
+ $ext['svn-revision'], $m ) )
{
$ret['version'] = 'r' . $m[1];
}
@@ -361,7 +398,7 @@ class ApiQuerySiteinfo extends ApiQueryBase {
$title = Title::newFromText( $wgRightsPage );
$url = $title ? $title->getFullURL() : $wgRightsUrl;
$text = $wgRightsText;
- if( !$text && $title ) {
+ if ( !$text && $title ) {
$text = $title->getPrefixedText();
}
@@ -373,6 +410,17 @@ class ApiQuerySiteinfo extends ApiQueryBase {
return $this->getResult()->addValue( 'query', $property, $data );
}
+ public function appendLanguages( $property ) {
+ $data = array();
+ foreach ( Language::getLanguageNames() as $code => $name ) {
+ $lang = array( 'code' => $code );
+ ApiResult::setContent( $lang, $name );
+ $data[] = $lang;
+ }
+ $this->getResult()->setIndexedTagName( $data, 'lang' );
+ return $this->getResult()->addValue( 'query', $property, $data );
+ }
+
public function getCacheMode( $params ) {
return 'public';
}
@@ -395,6 +443,7 @@ class ApiQuerySiteinfo extends ApiQueryBase {
'extensions',
'fileextensions',
'rightsinfo',
+ 'languages',
)
),
'filteriw' => array(
@@ -404,6 +453,7 @@ class ApiQuerySiteinfo extends ApiQueryBase {
)
),
'showalldb' => false,
+ 'numberingroup' => false,
);
}
@@ -423,9 +473,11 @@ class ApiQuerySiteinfo extends ApiQueryBase {
' extensions - Returns extensions installed on the wiki',
' fileextensions - Returns list of file extensions allowed to be uploaded',
' rightsinfo - Returns wiki rights (license) information if available',
+ ' languages - Returns a list of languages MediaWiki supports',
),
'filteriw' => 'Return only local or only nonlocal entries of the interwiki map',
'showalldb' => 'List all database servers, not just the one lagging the most',
+ 'numberingroup' => 'Lists the number of users in user groups',
);
}
@@ -433,6 +485,12 @@ class ApiQuerySiteinfo extends ApiQueryBase {
return 'Return general information about the site.';
}
+ public function getPossibleErrors() {
+ return array_merge( parent::getPossibleErrors(), array(
+ array( 'code' => 'includeAllDenied', 'info' => 'Cannot view all servers info unless $wgShowHostnames is true' ),
+ ) );
+ }
+
protected function getExamples() {
return array(
'api.php?action=query&meta=siteinfo&siprop=general|namespaces|namespacealiases|statistics',
@@ -442,6 +500,6 @@ class ApiQuerySiteinfo extends ApiQueryBase {
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiQuerySiteinfo.php 69986 2010-07-27 03:57:39Z tstarling $';
+ return __CLASS__ . ': $Id: ApiQuerySiteinfo.php 69932 2010-07-26 08:03:21Z tstarling $';
}
}
diff --git a/includes/api/ApiQueryTags.php b/includes/api/ApiQueryTags.php
new file mode 100644
index 00000000..a5d152bc
--- /dev/null
+++ b/includes/api/ApiQueryTags.php
@@ -0,0 +1,181 @@
+<?php
+
+/*
+ * Created on Jul 9, 2009
+ *
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2009
+ *
+ * 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if ( !defined( 'MEDIAWIKI' ) ) {
+ // Eclipse helper - will be ignored in production
+ require_once ( 'ApiQueryBase.php' );
+}
+
+/**
+ * Query module to enumerate change tags.
+ *
+ * @ingroup API
+ */
+class ApiQueryTags extends ApiQueryBase {
+
+ private $limit, $result;
+ private $fld_displayname = false, $fld_description = false,
+ $fld_hitcount = false;
+
+ public function __construct( $query, $moduleName ) {
+ parent :: __construct( $query, $moduleName, 'tg' );
+ }
+
+ public function execute() {
+ $params = $this->extractRequestParams();
+
+ $prop = array_flip( $params['prop'] );
+
+ $this->fld_displayname = isset( $prop['displayname'] );
+ $this->fld_description = isset( $prop['description'] );
+ $this->fld_hitcount = isset( $prop['hitcount'] );
+
+ $this->limit = $params['limit'];
+ $this->result = $this->getResult();
+
+ $pageSet = $this->getPageSet();
+ $titles = $pageSet->getTitles();
+ $data = array();
+
+ $this->addTables( 'change_tag' );
+ $this->addFields( 'ct_tag' );
+
+ if ( $this->fld_hitcount )
+ $this->addFields( 'count(*) AS hitcount' );
+
+ $this->addOption( 'LIMIT', $this->limit + 1 );
+ $this->addOption( 'GROUP BY', 'ct_tag' );
+ $this->addWhereRange( 'ct_tag', 'newer', $params['continue'], null );
+
+ $res = $this->select( __METHOD__ );
+
+ $ok = true;
+
+ while ( $row = $res->fetchObject() ) {
+ if ( !$ok ) break;
+ $ok = $this->doTag( $row->ct_tag, $row->hitcount );
+ }
+
+ // include tags with no hits yet
+ foreach ( ChangeTags::listDefinedTags() as $tag ) {
+ if ( !$ok ) break;
+ $ok = $this->doTag( $tag, 0 );
+ }
+
+ $this->result->setIndexedTagName_internal( array( 'query', $this->getModuleName() ), 'tag' );
+ }
+
+ private function doTag( $tagName, $hitcount ) {
+ static $count = 0;
+ static $doneTags = array();
+
+ if ( in_array( $tagName, $doneTags ) ) {
+ return true;
+ }
+
+ if ( ++$count > $this->limit )
+ {
+ $this->setContinueEnumParameter( 'continue', $tagName );
+ return false;
+ }
+
+ $tag = array();
+ $tag['name'] = $tagName;
+
+ if ( $this->fld_displayname )
+ $tag['displayname'] = ChangeTags::tagDescription( $tagName );
+
+ if ( $this->fld_description )
+ {
+ $msg = wfMsg( "tag-$tagName-description" );
+ $msg = wfEmptyMsg( "tag-$tagName-description", $msg ) ? '' : $msg;
+ $tag['description'] = $msg;
+ }
+
+ if ( $this->fld_hitcount )
+ $tag['hitcount'] = $hitcount;
+
+ $doneTags[] = $tagName;
+
+ $fit = $this->result->addValue( array( 'query', $this->getModuleName() ), null, $tag );
+ if ( !$fit )
+ {
+ $this->setContinueEnumParameter( 'continue', $tagName );
+ return false;
+ }
+
+ return true;
+ }
+
+ public function getCacheMode( $params ) {
+ return 'public';
+ }
+
+ public function getAllowedParams() {
+ return array (
+ 'continue' => array(
+ ),
+ 'limit' => array(
+ ApiBase :: PARAM_DFLT => 10,
+ ApiBase :: PARAM_TYPE => 'limit',
+ ApiBase :: PARAM_MIN => 1,
+ ApiBase :: PARAM_MAX => ApiBase :: LIMIT_BIG1,
+ ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2
+ ),
+ 'prop' => array(
+ ApiBase :: PARAM_DFLT => 'name',
+ ApiBase :: PARAM_TYPE => array(
+ 'name',
+ 'displayname',
+ 'description',
+ 'hitcount'
+ ),
+ ApiBase :: PARAM_ISMULTI => true
+ )
+ );
+ }
+
+ public function getParamDescription() {
+ return array (
+ 'continue' => 'When more results are available, use this to continue',
+ 'limit' => 'The maximum number of tags to list',
+ 'prop' => 'Which properties to get',
+ );
+ }
+
+ public function getDescription() {
+ return 'List change tags.';
+ }
+
+ protected function getExamples() {
+ return array (
+ 'api.php?action=query&list=tags&tgprop=displayname|description|hitcount'
+ );
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id: ApiQueryTags.php 69932 2010-07-26 08:03:21Z tstarling $';
+ }
+}
diff --git a/includes/api/ApiQueryUserContributions.php b/includes/api/ApiQueryUserContributions.php
index 1c5cffa5..b51b9adb 100644
--- a/includes/api/ApiQueryUserContributions.php
+++ b/includes/api/ApiQueryUserContributions.php
@@ -23,9 +23,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ('ApiQueryBase.php');
+ require_once ( 'ApiQueryBase.php' );
}
/**
@@ -35,33 +35,35 @@ if (!defined('MEDIAWIKI')) {
*/
class ApiQueryContributions extends ApiQueryBase {
- public function __construct($query, $moduleName) {
- parent :: __construct($query, $moduleName, 'uc');
+ public function __construct( $query, $moduleName ) {
+ parent :: __construct( $query, $moduleName, 'uc' );
}
private $params, $username;
private $fld_ids = false, $fld_title = false, $fld_timestamp = false,
- $fld_comment = false, $fld_flags = false,
- $fld_patrolled = false;
+ $fld_comment = false, $fld_parsedcomment = false, $fld_flags = false,
+ $fld_patrolled = false, $fld_tags = false;
public function execute() {
-
// Parse some parameters
$this->params = $this->extractRequestParams();
- $prop = array_flip($this->params['prop']);
- $this->fld_ids = isset($prop['ids']);
- $this->fld_title = isset($prop['title']);
- $this->fld_comment = isset($prop['comment']);
- $this->fld_flags = isset($prop['flags']);
- $this->fld_timestamp = isset($prop['timestamp']);
- $this->fld_patrolled = isset($prop['patrolled']);
+ $prop = array_flip( $this->params['prop'] );
+ $this->fld_ids = isset( $prop['ids'] );
+ $this->fld_title = isset( $prop['title'] );
+ $this->fld_comment = isset( $prop['comment'] );
+ $this->fld_parsedcomment = isset ( $prop['parsedcomment'] );
+ $this->fld_size = isset( $prop['size'] );
+ $this->fld_flags = isset( $prop['flags'] );
+ $this->fld_timestamp = isset( $prop['timestamp'] );
+ $this->fld_patrolled = isset( $prop['patrolled'] );
+ $this->fld_tags = isset( $prop['tags'] );
// TODO: if the query is going only against the revision table, should this be done?
- $this->selectNamedDB('contributions', DB_SLAVE, 'contributions');
+ $this->selectNamedDB( 'contributions', DB_SLAVE, 'contributions' );
$db = $this->getDB();
- if(isset($this->params['userprefix']))
+ if ( isset( $this->params['userprefix'] ) )
{
$this->prefixMode = true;
$this->multiUserMode = true;
@@ -70,61 +72,63 @@ class ApiQueryContributions extends ApiQueryBase {
else
{
$this->usernames = array();
- if(!is_array($this->params['user']))
- $this->params['user'] = array($this->params['user']);
- foreach($this->params['user'] as $u)
- $this->prepareUsername($u);
+ if ( !is_array( $this->params['user'] ) )
+ $this->params['user'] = array( $this->params['user'] );
+ if ( !count( $this->params['user'] ) )
+ $this->dieUsage( 'User parameter may not be empty.', 'param_user' );
+ foreach ( $this->params['user'] as $u )
+ $this->prepareUsername( $u );
$this->prefixMode = false;
- $this->multiUserMode = (count($this->params['user']) > 1);
+ $this->multiUserMode = ( count( $this->params['user'] ) > 1 );
}
$this->prepareQuery();
- //Do the actual query.
+ // Do the actual query.
$res = $this->select( __METHOD__ );
- //Initialise some variables
+ // Initialise some variables
$count = 0;
$limit = $this->params['limit'];
- //Fetch each row
+ // Fetch each row
while ( $row = $db->fetchObject( $res ) ) {
- if (++ $count > $limit) {
+ if ( ++ $count > $limit ) {
// We've reached the one extra which shows that there are additional pages to be had. Stop here...
- if($this->multiUserMode)
- $this->setContinueEnumParameter('continue', $this->continueStr($row));
+ if ( $this->multiUserMode )
+ $this->setContinueEnumParameter( 'continue', $this->continueStr( $row ) );
else
- $this->setContinueEnumParameter('start', wfTimestamp(TS_ISO_8601, $row->rev_timestamp));
+ $this->setContinueEnumParameter( 'start', wfTimestamp( TS_ISO_8601, $row->rev_timestamp ) );
break;
}
- $vals = $this->extractRowInfo($row);
- $fit = $this->getResult()->addValue(array('query', $this->getModuleName()), null, $vals);
- if(!$fit)
+ $vals = $this->extractRowInfo( $row );
+ $fit = $this->getResult()->addValue( array( 'query', $this->getModuleName() ), null, $vals );
+ if ( !$fit )
{
- if($this->multiUserMode)
- $this->setContinueEnumParameter('continue', $this->continueStr($row));
+ if ( $this->multiUserMode )
+ $this->setContinueEnumParameter( 'continue', $this->continueStr( $row ) );
else
- $this->setContinueEnumParameter('start', wfTimestamp(TS_ISO_8601, $row->rev_timestamp));
+ $this->setContinueEnumParameter( 'start', wfTimestamp( TS_ISO_8601, $row->rev_timestamp ) );
break;
}
}
- //Free the database record so the connection can get on with other stuff
- $db->freeResult($res);
+ // Free the database record so the connection can get on with other stuff
+ $db->freeResult( $res );
- $this->getResult()->setIndexedTagName_internal(array('query', $this->getModuleName()), 'item');
+ $this->getResult()->setIndexedTagName_internal( array( 'query', $this->getModuleName() ), 'item' );
}
/**
* Validate the 'user' parameter and set the value to compare
* against `revision`.`rev_user_text`
*/
- private function prepareUsername($user) {
- if( $user ) {
+ private function prepareUsername( $user ) {
+ if ( !is_null( $user ) && $user !== '' ) {
$name = User::isIP( $user )
? $user
: User::getCanonicalName( $user, 'valid' );
- if( $name === false ) {
+ if ( $name === false ) {
$this->dieUsage( "User name {$user} is not valid", 'param_user' );
} else {
$this->usernames[] = $name;
@@ -140,155 +144,202 @@ class ApiQueryContributions extends ApiQueryBase {
private function prepareQuery() {
// We're after the revision table, and the corresponding page
// row for anything we retrieve. We may also need the
- // recentchanges row.
- $tables = array('page', 'revision'); // Order may change
- $this->addWhere('page_id=rev_page');
+ // recentchanges row and/or tag summary row.
+ global $wgUser;
+ $tables = array( 'page', 'revision' ); // Order may change
+ $this->addWhere( 'page_id=rev_page' );
// Handle continue parameter
- if($this->multiUserMode && !is_null($this->params['continue']))
+ if ( $this->multiUserMode && !is_null( $this->params['continue'] ) )
{
- $continue = explode('|', $this->params['continue']);
- if(count($continue) != 2)
- $this->dieUsage("Invalid continue param. You should pass the original " .
- "value returned by the previous query", "_badcontinue");
- $encUser = $this->getDB()->strencode($continue[0]);
- $encTS = wfTimestamp(TS_MW, $continue[1]);
- $op = ($this->params['dir'] == 'older' ? '<' : '>');
- $this->addWhere("rev_user_text $op '$encUser' OR " .
+ $continue = explode( '|', $this->params['continue'] );
+ if ( count( $continue ) != 2 )
+ $this->dieUsage( "Invalid continue param. You should pass the original " .
+ "value returned by the previous query", "_badcontinue" );
+ $encUser = $this->getDB()->strencode( $continue[0] );
+ $encTS = wfTimestamp( TS_MW, $continue[1] );
+ $op = ( $this->params['dir'] == 'older' ? '<' : '>' );
+ $this->addWhere( "rev_user_text $op '$encUser' OR " .
"(rev_user_text = '$encUser' AND " .
- "rev_timestamp $op= '$encTS')");
+ "rev_timestamp $op= '$encTS')" );
}
- $this->addWhereFld('rev_deleted', 0);
+ if ( !$wgUser->isAllowed( 'hideuser' ) )
+ $this->addWhere( $this->getDB()->bitAnd( 'rev_deleted', Revision::DELETED_USER ) . ' = 0' );
// We only want pages by the specified users.
- if($this->prefixMode)
- $this->addWhere("rev_user_text LIKE '" . $this->getDB()->escapeLike($this->userprefix) . "%'");
+ if ( $this->prefixMode )
+ $this->addWhere( 'rev_user_text' . $this->getDB()->buildLike( $this->userprefix, $this->getDB()->anyString() ) );
else
- $this->addWhereFld('rev_user_text', $this->usernames);
+ $this->addWhereFld( 'rev_user_text', $this->usernames );
// ... and in the specified timeframe.
// Ensure the same sort order for rev_user_text and rev_timestamp
// so our query is indexed
- if($this->multiUserMode)
- $this->addWhereRange('rev_user_text', $this->params['dir'], null, null);
- $this->addWhereRange('rev_timestamp',
+ if ( $this->multiUserMode )
+ $this->addWhereRange( 'rev_user_text', $this->params['dir'], null, null );
+ $this->addWhereRange( 'rev_timestamp',
$this->params['dir'], $this->params['start'], $this->params['end'] );
- $this->addWhereFld('page_namespace', $this->params['namespace']);
+ $this->addWhereFld( 'page_namespace', $this->params['namespace'] );
$show = $this->params['show'];
- if (!is_null($show)) {
- $show = array_flip($show);
- if ((isset($show['minor']) && isset($show['!minor']))
- || (isset($show['patrolled']) && isset($show['!patrolled'])))
- $this->dieUsage("Incorrect parameter - mutually exclusive values may not be supplied", 'show');
-
- $this->addWhereIf('rev_minor_edit = 0', isset($show['!minor']));
- $this->addWhereIf('rev_minor_edit != 0', isset($show['minor']));
- $this->addWhereIf('rc_patrolled = 0', isset($show['!patrolled']));
- $this->addWhereIf('rc_patrolled != 0', isset($show['patrolled']));
+ if ( !is_null( $show ) ) {
+ $show = array_flip( $show );
+ if ( ( isset( $show['minor'] ) && isset( $show['!minor'] ) )
+ || ( isset( $show['patrolled'] ) && isset( $show['!patrolled'] ) ) )
+ $this->dieUsageMsg( array( 'show' ) );
+
+ $this->addWhereIf( 'rev_minor_edit = 0', isset( $show['!minor'] ) );
+ $this->addWhereIf( 'rev_minor_edit != 0', isset( $show['minor'] ) );
+ $this->addWhereIf( 'rc_patrolled = 0', isset( $show['!patrolled'] ) );
+ $this->addWhereIf( 'rc_patrolled != 0', isset( $show['patrolled'] ) );
}
- $this->addOption('LIMIT', $this->params['limit'] + 1);
- $index['revision'] = 'usertext_timestamp';
+ $this->addOption( 'LIMIT', $this->params['limit'] + 1 );
+ $index = array( 'revision' => 'usertext_timestamp' );
// Mandatory fields: timestamp allows request continuation
// ns+title checks if the user has access rights for this page
// user_text is necessary if multiple users were specified
- $this->addFields(array(
+ $this->addFields( array(
'rev_timestamp',
'page_namespace',
'page_title',
'rev_user_text',
- ));
+ 'rev_deleted'
+ ) );
- if(isset($show['patrolled']) || isset($show['!patrolled']) ||
- $this->fld_patrolled)
+ if ( isset( $show['patrolled'] ) || isset( $show['!patrolled'] ) ||
+ $this->fld_patrolled )
{
global $wgUser;
- if(!$wgUser->useRCPatrol() && !$wgUser->useNPPatrol())
- $this->dieUsage("You need the patrol right to request the patrolled flag", 'permissiondenied');
+ if ( !$wgUser->useRCPatrol() && !$wgUser->useNPPatrol() )
+ $this->dieUsage( "You need the patrol right to request the patrolled flag", 'permissiondenied' );
// Use a redundant join condition on both
// timestamp and ID so we can use the timestamp
// index
$index['recentchanges'] = 'rc_user_text';
- if(isset($show['patrolled']) || isset($show['!patrolled']))
+ if ( isset( $show['patrolled'] ) || isset( $show['!patrolled'] ) )
{
// Put the tables in the right order for
// STRAIGHT_JOIN
- $tables = array('revision', 'recentchanges', 'page');
- $this->addOption('STRAIGHT_JOIN');
- $this->addWhere('rc_user_text=rev_user_text');
- $this->addWhere('rc_timestamp=rev_timestamp');
- $this->addWhere('rc_this_oldid=rev_id');
+ $tables = array( 'revision', 'recentchanges', 'page' );
+ $this->addOption( 'STRAIGHT_JOIN' );
+ $this->addWhere( 'rc_user_text=rev_user_text' );
+ $this->addWhere( 'rc_timestamp=rev_timestamp' );
+ $this->addWhere( 'rc_this_oldid=rev_id' );
}
else
{
$tables[] = 'recentchanges';
- $this->addJoinConds(array('recentchanges' => array(
+ $this->addJoinConds( array( 'recentchanges' => array(
'LEFT JOIN', array(
'rc_user_text=rev_user_text',
'rc_timestamp=rev_timestamp',
- 'rc_this_oldid=rev_id'))));
+ 'rc_this_oldid=rev_id' ) ) ) );
}
}
- $this->addTables($tables);
- $this->addOption('USE INDEX', $index);
- $this->addFieldsIf('rev_page', $this->fld_ids);
- $this->addFieldsIf('rev_id', $this->fld_ids || $this->fld_flags);
- $this->addFieldsIf('page_latest', $this->fld_flags);
+ $this->addTables( $tables );
+ $this->addFieldsIf( 'rev_page', $this->fld_ids );
+ $this->addFieldsIf( 'rev_id', $this->fld_ids || $this->fld_flags );
+ $this->addFieldsIf( 'page_latest', $this->fld_flags );
// $this->addFieldsIf('rev_text_id', $this->fld_ids); // Should this field be exposed?
- $this->addFieldsIf('rev_comment', $this->fld_comment);
- $this->addFieldsIf('rev_minor_edit', $this->fld_flags);
- $this->addFieldsIf('rev_parent_id', $this->fld_flags);
- $this->addFieldsIf('rc_patrolled', $this->fld_patrolled);
+ $this->addFieldsIf( 'rev_comment', $this->fld_comment || $this->fld_parsedcomment );
+ $this->addFieldsIf( 'rev_len', $this->fld_size );
+ $this->addFieldsIf( 'rev_minor_edit', $this->fld_flags );
+ $this->addFieldsIf( 'rev_parent_id', $this->fld_flags );
+ $this->addFieldsIf( 'rc_patrolled', $this->fld_patrolled );
+
+ if ( $this->fld_tags )
+ {
+ $this->addTables( 'tag_summary' );
+ $this->addJoinConds( array( 'tag_summary' => array( 'LEFT JOIN', array( 'rev_id=ts_rev_id' ) ) ) );
+ $this->addFields( 'ts_tags' );
+ }
+
+ if ( isset( $this->params['tag'] ) ) {
+ $this->addTables( 'change_tag' );
+ $this->addJoinConds( array( 'change_tag' => array( 'INNER JOIN', array( 'rev_id=ct_rev_id' ) ) ) );
+ $this->addWhereFld( 'ct_tag', $this->params['tag'] );
+ global $wgOldChangeTagsIndex;
+ $index['change_tag'] = $wgOldChangeTagsIndex ? 'ct_tag' : 'change_tag_tag_id';
+ }
+
+ $this->addOption( 'USE INDEX', $index );
}
/**
* Extract fields from the database row and append them to a result array
*/
- private function extractRowInfo($row) {
+ private function extractRowInfo( $row ) {
$vals = array();
$vals['user'] = $row->rev_user_text;
- if ($this->fld_ids) {
- $vals['pageid'] = intval($row->rev_page);
- $vals['revid'] = intval($row->rev_id);
+ if ( $row->rev_deleted & Revision::DELETED_USER )
+ $vals['userhidden'] = '';
+ if ( $this->fld_ids ) {
+ $vals['pageid'] = intval( $row->rev_page );
+ $vals['revid'] = intval( $row->rev_id );
// $vals['textid'] = intval($row->rev_text_id); // todo: Should this field be exposed?
}
- if ($this->fld_title)
- ApiQueryBase :: addTitleInfo($vals,
- Title :: makeTitle($row->page_namespace, $row->page_title));
+ $title = Title::makeTitle( $row->page_namespace, $row->page_title );
- if ($this->fld_timestamp)
- $vals['timestamp'] = wfTimestamp(TS_ISO_8601, $row->rev_timestamp);
+ if ( $this->fld_title )
+ ApiQueryBase::addTitleInfo( $vals, $title );
- if ($this->fld_flags) {
- if ($row->rev_parent_id == 0)
+ if ( $this->fld_timestamp )
+ $vals['timestamp'] = wfTimestamp( TS_ISO_8601, $row->rev_timestamp );
+
+ if ( $this->fld_flags ) {
+ if ( $row->rev_parent_id == 0 && !is_null( $row->rev_parent_id ) )
$vals['new'] = '';
- if ($row->rev_minor_edit)
+ if ( $row->rev_minor_edit )
$vals['minor'] = '';
- if ($row->page_latest == $row->rev_id)
+ if ( $row->page_latest == $row->rev_id )
$vals['top'] = '';
}
- if ($this->fld_comment && isset($row->rev_comment))
- $vals['comment'] = $row->rev_comment;
+ if ( ( $this->fld_comment || $this->fld_parsedcomment ) && isset( $row->rev_comment ) ) {
+ if ( $row->rev_deleted & Revision::DELETED_COMMENT )
+ $vals['commenthidden'] = '';
+ else {
+ if ( $this->fld_comment )
+ $vals['comment'] = $row->rev_comment;
+
+ if ( $this->fld_parsedcomment ) {
+ global $wgUser;
+ $vals['parsedcomment'] = $wgUser->getSkin()->formatComment( $row->rev_comment, $title );
+ }
+ }
+ }
- if ($this->fld_patrolled && $row->rc_patrolled)
+ if ( $this->fld_patrolled && $row->rc_patrolled )
$vals['patrolled'] = '';
-
+
+ if ( $this->fld_size && !is_null( $row->rev_len ) )
+ $vals['size'] = intval( $row->rev_len );
+
+ if ( $this->fld_tags ) {
+ if ( $row->ts_tags ) {
+ $tags = explode( ',', $row->ts_tags );
+ $this->getResult()->setIndexedTagName( $tags, 'tag' );
+ $vals['tags'] = $tags;
+ } else {
+ $vals['tags'] = array();
+ }
+ }
+
return $vals;
}
- private function continueStr($row)
+ private function continueStr( $row )
{
return $row->rev_user_text . '|' .
- wfTimestamp(TS_ISO_8601, $row->rev_timestamp);
+ wfTimestamp( TS_ISO_8601, $row->rev_timestamp );
}
public function getCacheMode( $params ) {
- // This module provides access to patrol flags if
+ // This module provides access to deleted revisions and patrol flags if
// the requester is logged in
return 'anon-public-user-private';
}
@@ -326,14 +377,17 @@ class ApiQueryContributions extends ApiQueryBase {
),
'prop' => array (
ApiBase :: PARAM_ISMULTI => true,
- ApiBase :: PARAM_DFLT => 'ids|title|timestamp|flags|comment',
+ ApiBase :: PARAM_DFLT => 'ids|title|timestamp|comment|size|flags',
ApiBase :: PARAM_TYPE => array (
'ids',
'title',
'timestamp',
'comment',
+ 'parsedcomment',
+ 'size',
'flags',
'patrolled',
+ 'tags'
)
),
'show' => array (
@@ -345,6 +399,7 @@ class ApiQueryContributions extends ApiQueryBase {
'!patrolled',
)
),
+ 'tag' => null,
);
}
@@ -359,14 +414,24 @@ class ApiQueryContributions extends ApiQueryBase {
'dir' => 'The direction to search (older or newer).',
'namespace' => 'Only list contributions in these namespaces',
'prop' => 'Include additional pieces of information',
- 'show' => array('Show only items that meet this criteria, e.g. non minor edits only: show=!minor',
- 'NOTE: if show=patrolled or show=!patrolled is set, revisions older than $wgRCMaxAge won\'t be shown',),
+ 'show' => array( 'Show only items that meet this criteria, e.g. non minor edits only: show=!minor',
+ 'NOTE: if show=patrolled or show=!patrolled is set, revisions older than $wgRCMaxAge won\'t be shown', ),
+ 'tag' => 'Only list revisions tagged with this tag',
);
}
public function getDescription() {
return 'Get all edits by a user';
}
+
+ public function getPossibleErrors() {
+ return array_merge( parent::getPossibleErrors(), array(
+ array( 'code' => 'param_user', 'info' => 'User parameter may not be empty.' ),
+ array( 'code' => 'param_user', 'info' => 'User name user is not valid' ),
+ array( 'show' ),
+ array( 'code' => 'permissiondenied', 'info' => 'You need the patrol right to request the patrolled flag' ),
+ ) );
+ }
protected function getExamples() {
return array (
@@ -376,6 +441,6 @@ class ApiQueryContributions extends ApiQueryBase {
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiQueryUserContributions.php 69986 2010-07-27 03:57:39Z tstarling $';
+ return __CLASS__ . ': $Id: ApiQueryUserContributions.php 69932 2010-07-26 08:03:21Z tstarling $';
}
}
diff --git a/includes/api/ApiQueryUserInfo.php b/includes/api/ApiQueryUserInfo.php
index e445c46e..42cb47b9 100644
--- a/includes/api/ApiQueryUserInfo.php
+++ b/includes/api/ApiQueryUserInfo.php
@@ -23,9 +23,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ('ApiQueryBase.php');
+ require_once ( 'ApiQueryBase.php' );
}
/**
@@ -35,8 +35,8 @@ if (!defined('MEDIAWIKI')) {
*/
class ApiQueryUserInfo extends ApiQueryBase {
- public function __construct($query, $moduleName) {
- parent :: __construct($query, $moduleName, 'ui');
+ public function __construct( $query, $moduleName ) {
+ parent :: __construct( $query, $moduleName, 'ui' );
}
public function execute() {
@@ -44,59 +44,76 @@ class ApiQueryUserInfo extends ApiQueryBase {
$result = $this->getResult();
$r = array();
- if (!is_null($params['prop'])) {
- $this->prop = array_flip($params['prop']);
+ if ( !is_null( $params['prop'] ) ) {
+ $this->prop = array_flip( $params['prop'] );
} else {
$this->prop = array();
}
$r = $this->getCurrentUserInfo();
- $result->addValue("query", $this->getModuleName(), $r);
+ $result->addValue( "query", $this->getModuleName(), $r );
}
protected function getCurrentUserInfo() {
global $wgUser;
$result = $this->getResult();
$vals = array();
- $vals['id'] = intval($wgUser->getId());
+ $vals['id'] = intval( $wgUser->getId() );
$vals['name'] = $wgUser->getName();
- if($wgUser->isAnon())
+ if ( $wgUser->isAnon() )
$vals['anon'] = '';
- if (isset($this->prop['blockinfo'])) {
- if ($wgUser->isBlocked()) {
- $vals['blockedby'] = User::whoIs($wgUser->blockedBy());
+
+ if ( isset( $this->prop['blockinfo'] ) ) {
+ if ( $wgUser->isBlocked() ) {
+ $vals['blockedby'] = User::whoIs( $wgUser->blockedBy() );
$vals['blockreason'] = $wgUser->blockedFor();
}
}
- if (isset($this->prop['hasmsg']) && $wgUser->getNewtalk()) {
+
+ if ( isset( $this->prop['hasmsg'] ) && $wgUser->getNewtalk() ) {
$vals['messages'] = '';
}
- if (isset($this->prop['groups'])) {
+
+ if ( isset( $this->prop['groups'] ) ) {
$vals['groups'] = $wgUser->getGroups();
- $result->setIndexedTagName($vals['groups'], 'g'); // even if empty
+ $result->setIndexedTagName( $vals['groups'], 'g' ); // even if empty
}
- if (isset($this->prop['rights'])) {
+
+ if ( isset( $this->prop['rights'] ) ) {
// User::getRights() may return duplicate values, strip them
- $vals['rights'] = array_values(array_unique($wgUser->getRights()));
- $result->setIndexedTagName($vals['rights'], 'r'); // even if empty
+ $vals['rights'] = array_values( array_unique( $wgUser->getRights() ) );
+ $result->setIndexedTagName( $vals['rights'], 'r' ); // even if empty
}
- if (isset($this->prop['options'])) {
- $vals['options'] = (is_null($wgUser->mOptions) ? User::getDefaultOptions() : $wgUser->mOptions);
+
+ if ( isset( $this->prop['changeablegroups'] ) ) {
+ $vals['changeablegroups'] = $wgUser->changeableGroups();
+ $result->setIndexedTagName( $vals['changeablegroups']['add'], 'g' );
+ $result->setIndexedTagName( $vals['changeablegroups']['remove'], 'g' );
+ $result->setIndexedTagName( $vals['changeablegroups']['add-self'], 'g' );
+ $result->setIndexedTagName( $vals['changeablegroups']['remove-self'], 'g' );
}
- if (isset($this->prop['preferencestoken']) && is_null($this->getMain()->getRequest()->getVal('callback'))) {
+
+ if ( isset( $this->prop['options'] ) ) {
+ $vals['options'] = $wgUser->getOptions();
+ }
+
+ if ( isset( $this->prop['preferencestoken'] ) && is_null( $this->getMain()->getRequest()->getVal( 'callback' ) ) ) {
$vals['preferencestoken'] = $wgUser->editToken();
}
- if (isset($this->prop['editcount'])) {
- $vals['editcount'] = intval($wgUser->getEditCount());
+
+ if ( isset( $this->prop['editcount'] ) ) {
+ $vals['editcount'] = intval( $wgUser->getEditCount() );
}
- if (isset($this->prop['ratelimits'])) {
+
+ if ( isset( $this->prop['ratelimits'] ) ) {
$vals['ratelimits'] = $this->getRateLimits();
}
- if (isset($this->prop['email'])) {
+
+ if ( isset( $this->prop['email'] ) ) {
$vals['email'] = $wgUser->getEmail();
$auth = $wgUser->getEmailAuthenticationTimestamp();
- if(!is_null($auth))
- $vals['emailauthenticated'] = wfTimestamp(TS_ISO_8601, $auth);
+ if ( !is_null( $auth ) )
+ $vals['emailauthenticated'] = wfTimestamp( TS_ISO_8601, $auth );
}
return $vals;
}
@@ -104,32 +121,32 @@ class ApiQueryUserInfo extends ApiQueryBase {
protected function getRateLimits()
{
global $wgUser, $wgRateLimits;
- if(!$wgUser->isPingLimitable())
+ if ( !$wgUser->isPingLimitable() )
return array(); // No limits
// Find out which categories we belong to
$categories = array();
- if($wgUser->isAnon())
+ if ( $wgUser->isAnon() )
$categories[] = 'anon';
else
$categories[] = 'user';
- if($wgUser->isNewBie())
+ if ( $wgUser->isNewBie() )
{
$categories[] = 'ip';
$categories[] = 'subnet';
- if(!$wgUser->isAnon())
+ if ( !$wgUser->isAnon() )
$categories[] = 'newbie';
}
- $categories = array_merge($categories, $wgUser->getGroups());
+ $categories = array_merge( $categories, $wgUser->getGroups() );
// Now get the actual limits
$retval = array();
- foreach($wgRateLimits as $action => $limits)
- foreach($categories as $cat)
- if(isset($limits[$cat]) && !is_null($limits[$cat]))
+ foreach ( $wgRateLimits as $action => $limits )
+ foreach ( $categories as $cat )
+ if ( isset( $limits[$cat] ) && !is_null( $limits[$cat] ) )
{
- $retval[$action][$cat]['hits'] = intval($limits[$cat][0]);
- $retval[$action][$cat]['seconds'] = intval($limits[$cat][1]);
+ $retval[$action][$cat]['hits'] = intval( $limits[$cat][0] );
+ $retval[$action][$cat]['seconds'] = intval( $limits[$cat][1] );
}
return $retval;
}
@@ -137,13 +154,14 @@ class ApiQueryUserInfo extends ApiQueryBase {
public function getAllowedParams() {
return array (
'prop' => array (
- ApiBase :: PARAM_DFLT => NULL,
+ ApiBase :: PARAM_DFLT => null,
ApiBase :: PARAM_ISMULTI => true,
ApiBase :: PARAM_TYPE => array (
'blockinfo',
'hasmsg',
'groups',
'rights',
+ 'changeablegroups',
'options',
'preferencestoken',
'editcount',
@@ -161,7 +179,8 @@ class ApiQueryUserInfo extends ApiQueryBase {
' blockinfo - tags if the current user is blocked, by whom, and for what reason',
' hasmsg - adds a tag "message" if the current user has pending messages',
' groups - lists all the groups the current user belongs to',
- ' rights - lists of all rights the current user has',
+ ' rights - lists all the rights the current user has',
+ ' changeablegroups - lists the groups the current user can add to and remove from',
' options - lists all preferences the current user has set',
' editcount - adds the current user\'s edit count',
' ratelimits - lists all rate limits applying to the current user'
@@ -181,6 +200,6 @@ class ApiQueryUserInfo extends ApiQueryBase {
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiQueryUserInfo.php 69579 2010-07-20 02:49:55Z tstarling $';
+ return __CLASS__ . ': $Id: ApiQueryUserInfo.php 69578 2010-07-20 02:46:20Z tstarling $';
}
}
diff --git a/includes/api/ApiQueryUsers.php b/includes/api/ApiQueryUsers.php
index 1e50c59a..5dc0e4a6 100644
--- a/includes/api/ApiQueryUsers.php
+++ b/includes/api/ApiQueryUsers.php
@@ -23,9 +23,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ('ApiQueryBase.php');
+ require_once ( 'ApiQueryBase.php' );
}
/**
@@ -33,11 +33,40 @@ if (!defined('MEDIAWIKI')) {
*
* @ingroup API
*/
-
class ApiQueryUsers extends ApiQueryBase {
- public function __construct($query, $moduleName) {
- parent :: __construct($query, $moduleName, 'us');
+ public function __construct( $query, $moduleName ) {
+ parent :: __construct( $query, $moduleName, 'us' );
+ }
+
+ /**
+ * Get an array mapping token names to their handler functions.
+ * The prototype for a token function is func($user)
+ * it should return a token or false (permission denied)
+ * @return array(tokenname => function)
+ */
+ protected function getTokenFunctions() {
+ // Don't call the hooks twice
+ if ( isset( $this->tokenFunctions ) )
+ return $this->tokenFunctions;
+
+ // If we're in JSON callback mode, no tokens can be obtained
+ if ( !is_null( $this->getMain()->getRequest()->getVal( 'callback' ) ) )
+ return array();
+
+ $this->tokenFunctions = array(
+ 'userrights' => array( 'ApiQueryUsers', 'getUserrightsToken' ),
+ );
+ wfRunHooks( 'APIQueryUsersTokens', array( &$this->tokenFunctions ) );
+ return $this->tokenFunctions;
+ }
+
+ public static function getUserrightsToken( $user )
+ {
+ global $wgUser;
+ // Since the permissions check for userrights is non-trivial,
+ // don't bother with it here
+ return $wgUser->editToken( $user->getName() );
}
public function execute() {
@@ -45,8 +74,8 @@ if (!defined('MEDIAWIKI')) {
$result = $this->getResult();
$r = array();
- if (!is_null($params['prop'])) {
- $this->prop = array_flip($params['prop']);
+ if ( !is_null( $params['prop'] ) ) {
+ $this->prop = array_flip( $params['prop'] );
} else {
$this->prop = array();
}
@@ -55,17 +84,17 @@ if (!defined('MEDIAWIKI')) {
$goodNames = $done = array();
$result = $this->getResult();
// Canonicalize user names
- foreach($users as $u) {
- $n = User::getCanonicalName($u);
- if($n === false || $n === '')
+ foreach ( $users as $u ) {
+ $n = User::getCanonicalName( $u );
+ if ( $n === false || $n === '' )
{
- $vals = array('name' => $u, 'invalid' => '');
- $fit = $result->addValue(array('query', $this->getModuleName()),
- null, $vals);
- if(!$fit)
+ $vals = array( 'name' => $u, 'invalid' => '' );
+ $fit = $result->addValue( array( 'query', $this->getModuleName() ),
+ null, $vals );
+ if ( !$fit )
{
- $this->setContinueEnumParameter('users',
- implode('|', array_diff($users, $done)));
+ $this->setContinueEnumParameter( 'users',
+ implode( '|', array_diff( $users, $done ) ) );
$goodNames = array();
break;
}
@@ -74,78 +103,122 @@ if (!defined('MEDIAWIKI')) {
else
$goodNames[] = $n;
}
- if(count($goodNames))
+
+ if ( count( $goodNames ) )
{
$db = $this->getDb();
- $this->addTables('user', 'u1');
- $this->addFields('u1.*');
- $this->addWhereFld('u1.user_name', $goodNames);
-
- if(isset($this->prop['groups'])) {
- $this->addTables('user_groups');
- $this->addJoinConds(array('user_groups' => array('LEFT JOIN', 'ug_user=u1.user_id')));
- $this->addFields('ug_group');
+ $this->addTables( 'user', 'u1' );
+ $this->addFields( 'u1.*' );
+ $this->addWhereFld( 'u1.user_name', $goodNames );
+
+ if ( isset( $this->prop['groups'] ) ) {
+ $this->addTables( 'user_groups' );
+ $this->addJoinConds( array( 'user_groups' => array( 'LEFT JOIN', 'ug_user=u1.user_id' ) ) );
+ $this->addFields( 'ug_group' );
}
- if(isset($this->prop['blockinfo'])) {
- $this->addTables('ipblocks');
- $this->addTables('user', 'u2');
- $u2 = $this->getAliasedName('user', 'u2');
- $this->addJoinConds(array(
- 'ipblocks' => array('LEFT JOIN', 'ipb_user=u1.user_id'),
- $u2 => array('LEFT JOIN', 'ipb_by=u2.user_id')));
- $this->addFields(array('ipb_reason', 'u2.user_name AS blocker_name'));
+ if ( isset( $this->prop['blockinfo'] ) ) {
+ $this->addTables( 'ipblocks' );
+ $this->addTables( 'user', 'u2' );
+ $u2 = $this->getAliasedName( 'user', 'u2' );
+ $this->addJoinConds( array(
+ 'ipblocks' => array( 'LEFT JOIN', 'ipb_user=u1.user_id' ),
+ $u2 => array( 'LEFT JOIN', 'ipb_by=u2.user_id' ) ) );
+ $this->addFields( array( 'ipb_reason', 'u2.user_name AS blocker_name' ) );
}
$data = array();
- $res = $this->select(__METHOD__);
- while(($r = $db->fetchObject($res))) {
- $user = User::newFromRow($r);
+ $res = $this->select( __METHOD__ );
+ while ( ( $r = $db->fetchObject( $res ) ) ) {
+ $user = User::newFromRow( $r );
$name = $user->getName();
$data[$name]['name'] = $name;
- if(isset($this->prop['editcount']))
- $data[$name]['editcount'] = intval($user->getEditCount());
- if(isset($this->prop['registration']))
- $data[$name]['registration'] = wfTimestampOrNull(TS_ISO_8601, $user->getRegistration());
- if(isset($this->prop['groups']) && !is_null($r->ug_group))
+ if ( isset( $this->prop['editcount'] ) )
+ $data[$name]['editcount'] = intval( $user->getEditCount() );
+ if ( isset( $this->prop['registration'] ) )
+ $data[$name]['registration'] = wfTimestampOrNull( TS_ISO_8601, $user->getRegistration() );
+ if ( isset( $this->prop['groups'] ) && !is_null( $r->ug_group ) )
// This row contains only one group, others will be added from other rows
$data[$name]['groups'][] = $r->ug_group;
- if(isset($this->prop['blockinfo']) && !is_null($r->blocker_name)) {
+ if ( isset( $this->prop['blockinfo'] ) && !is_null( $r->blocker_name ) ) {
$data[$name]['blockedby'] = $r->blocker_name;
$data[$name]['blockreason'] = $r->ipb_reason;
}
- if(isset($this->prop['emailable']) && $user->canReceiveEmail())
+ if ( isset( $this->prop['emailable'] ) && $user->canReceiveEmail() )
$data[$name]['emailable'] = '';
+
+ if ( isset( $this->prop['gender'] ) ) {
+ $gender = $user->getOption( 'gender' );
+ if ( strval( $gender ) === '' ) {
+ $gender = 'unknown';
+ }
+ $data[$name]['gender'] = $gender;
+ }
+
+ if ( !is_null( $params['token'] ) )
+ {
+ $tokenFunctions = $this->getTokenFunctions();
+ foreach ( $params['token'] as $t )
+ {
+ $val = call_user_func( $tokenFunctions[$t], $user );
+ if ( $val === false )
+ $this->setWarning( "Action '$t' is not allowed for the current user" );
+ else
+ $data[$name][$t . 'token'] = $val;
+ }
+ }
}
}
// Second pass: add result data to $retval
- foreach($goodNames as $u) {
- if(!isset($data[$u]))
- $data[$u] = array('name' => $u, 'missing' => '');
- else {
- if(isset($this->prop['groups']) && isset($data[$u]['groups']))
- $this->getResult()->setIndexedTagName($data[$u]['groups'], 'g');
+ foreach ( $goodNames as $u ) {
+ if ( !isset( $data[$u] ) ) {
+ $data[$u] = array( 'name' => $u );
+ $urPage = new UserrightsPage;
+ $iwUser = $urPage->fetchUser( $u );
+ if ( $iwUser instanceof UserRightsProxy ) {
+ $data[$u]['interwiki'] = '';
+ if ( !is_null( $params['token'] ) )
+ {
+ $tokenFunctions = $this->getTokenFunctions();
+ foreach ( $params['token'] as $t )
+ {
+ $val = call_user_func( $tokenFunctions[$t], $iwUser );
+ if ( $val === false )
+ $this->setWarning( "Action '$t' is not allowed for the current user" );
+ else
+ $data[$u][$t . 'token'] = $val;
+ }
+ }
+ } else
+ $data[$u]['missing'] = '';
+ } else {
+ if ( isset( $this->prop['groups'] ) && isset( $data[$u]['groups'] ) )
+ $this->getResult()->setIndexedTagName( $data[$u]['groups'], 'g' );
}
- $fit = $result->addValue(array('query', $this->getModuleName()),
- null, $data[$u]);
- if(!$fit)
+ $fit = $result->addValue( array( 'query', $this->getModuleName() ),
+ null, $data[$u] );
+ if ( !$fit )
{
- $this->setContinueEnumParameter('users',
- implode('|', array_diff($users, $done)));
+ $this->setContinueEnumParameter( 'users',
+ implode( '|', array_diff( $users, $done ) ) );
break;
}
$done[] = $u;
}
- return $this->getResult()->setIndexedTagName_internal(array('query', $this->getModuleName()), 'user');
+ return $this->getResult()->setIndexedTagName_internal( array( 'query', $this->getModuleName() ), 'user' );
}
public function getCacheMode( $params ) {
- return 'public';
+ if ( isset( $params['token'] ) ) {
+ return 'private';
+ } else {
+ return 'public';
+ }
}
public function getAllowedParams() {
return array (
'prop' => array (
- ApiBase :: PARAM_DFLT => NULL,
+ ApiBase :: PARAM_DFLT => null,
ApiBase :: PARAM_ISMULTI => true,
ApiBase :: PARAM_TYPE => array (
'blockinfo',
@@ -153,11 +226,16 @@ if (!defined('MEDIAWIKI')) {
'editcount',
'registration',
'emailable',
+ 'gender',
)
),
'users' => array(
ApiBase :: PARAM_ISMULTI => true
- )
+ ),
+ 'token' => array(
+ ApiBase :: PARAM_TYPE => array_keys( $this->getTokenFunctions() ),
+ ApiBase :: PARAM_ISMULTI => true
+ ),
);
}
@@ -170,8 +248,10 @@ if (!defined('MEDIAWIKI')) {
' editcount - adds the user\'s edit count',
' registration - adds the user\'s registration timestamp',
' emailable - tags if the user can and wants to receive e-mail through [[Special:Emailuser]]',
+ ' gender - tags the gender of the user. Returns "male", "female", or "unknown"',
),
- 'users' => 'A list of users to obtain the same information for'
+ 'users' => 'A list of users to obtain the same information for',
+ 'token' => 'Which tokens to obtain for each user',
);
}
@@ -180,10 +260,10 @@ if (!defined('MEDIAWIKI')) {
}
protected function getExamples() {
- return 'api.php?action=query&list=users&ususers=brion|TimStarling&usprop=groups|editcount';
+ return 'api.php?action=query&list=users&ususers=brion|TimStarling&usprop=groups|editcount|gender';
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiQueryUsers.php 69986 2010-07-27 03:57:39Z tstarling $';
+ return __CLASS__ . ': $Id: ApiQueryUsers.php 69932 2010-07-26 08:03:21Z tstarling $';
}
}
diff --git a/includes/api/ApiQueryWatchlist.php b/includes/api/ApiQueryWatchlist.php
index eb5c531f..caac0706 100644
--- a/includes/api/ApiQueryWatchlist.php
+++ b/includes/api/ApiQueryWatchlist.php
@@ -23,9 +23,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ('ApiQueryBase.php');
+ require_once ( 'ApiQueryBase.php' );
}
/**
@@ -36,221 +36,244 @@ if (!defined('MEDIAWIKI')) {
*/
class ApiQueryWatchlist extends ApiQueryGeneratorBase {
- public function __construct($query, $moduleName) {
- parent :: __construct($query, $moduleName, 'wl');
+ public function __construct( $query, $moduleName ) {
+ parent :: __construct( $query, $moduleName, 'wl' );
}
public function execute() {
$this->run();
}
- public function executeGenerator($resultPageSet) {
- $this->run($resultPageSet);
+ public function executeGenerator( $resultPageSet ) {
+ $this->run( $resultPageSet );
}
private $fld_ids = false, $fld_title = false, $fld_patrol = false, $fld_flags = false,
- $fld_timestamp = false, $fld_user = false, $fld_comment = false, $fld_sizes = false;
+ $fld_timestamp = false, $fld_user = false, $fld_comment = false, $fld_parsedcomment = false, $fld_sizes = false,
+ $fld_notificationtimestamp = false;
- private function run($resultPageSet = null) {
- global $wgUser, $wgDBtype;
+ private function run( $resultPageSet = null ) {
+ global $wgUser;
- $this->selectNamedDB('watchlist', DB_SLAVE, 'watchlist');
-
- if (!$wgUser->isLoggedIn())
- $this->dieUsage('You must be logged-in to have a watchlist', 'notloggedin');
+ $this->selectNamedDB( 'watchlist', DB_SLAVE, 'watchlist' );
$params = $this->extractRequestParams();
- if (!is_null($params['prop']) && is_null($resultPageSet)) {
+ if ( !is_null( $params['owner'] ) && !is_null( $params['token'] ) ) {
+ $user = User::newFromName( $params['owner'], false );
+ if ( !$user->getId() ) {
+ $this->dieUsage( 'Specified user does not exist', 'bad_wlowner' );
+ }
+ $token = $user->getOption( 'watchlisttoken' );
+ if ( $token == '' || $token != $params['token'] ) {
+ $this->dieUsage( 'Incorrect watchlist token provided -- please set a correct token in Special:Preferences', 'bad_wltoken' );
+ }
+ } elseif ( !$wgUser->isLoggedIn() ) {
+ $this->dieUsage( 'You must be logged-in to have a watchlist', 'notloggedin' );
+ } else {
+ $user = $wgUser;
+ }
+
+ if ( !is_null( $params['prop'] ) && is_null( $resultPageSet ) ) {
- $prop = array_flip($params['prop']);
+ $prop = array_flip( $params['prop'] );
- $this->fld_ids = isset($prop['ids']);
- $this->fld_title = isset($prop['title']);
- $this->fld_flags = isset($prop['flags']);
- $this->fld_user = isset($prop['user']);
- $this->fld_comment = isset($prop['comment']);
- $this->fld_timestamp = isset($prop['timestamp']);
- $this->fld_sizes = isset($prop['sizes']);
- $this->fld_patrol = isset($prop['patrol']);
+ $this->fld_ids = isset( $prop['ids'] );
+ $this->fld_title = isset( $prop['title'] );
+ $this->fld_flags = isset( $prop['flags'] );
+ $this->fld_user = isset( $prop['user'] );
+ $this->fld_comment = isset( $prop['comment'] );
+ $this->fld_parsedcomment = isset ( $prop['parsedcomment'] );
+ $this->fld_timestamp = isset( $prop['timestamp'] );
+ $this->fld_sizes = isset( $prop['sizes'] );
+ $this->fld_patrol = isset( $prop['patrol'] );
+ $this->fld_notificationtimestamp = isset( $prop['notificationtimestamp'] );
- if ($this->fld_patrol) {
- global $wgUser;
- if (!$wgUser->useRCPatrol() && !$wgUser->useNPPatrol())
- $this->dieUsage('patrol property is not available', 'patrol');
+ if ( $this->fld_patrol ) {
+ if ( !$user->useRCPatrol() && !$user->useNPPatrol() )
+ $this->dieUsage( 'patrol property is not available', 'patrol' );
}
}
-
- if (is_null($resultPageSet)) {
- $this->addFields(array (
+
+ $this->addFields( array (
+ 'rc_namespace',
+ 'rc_title',
+ 'rc_timestamp'
+ ) );
+
+ if ( is_null( $resultPageSet ) ) {
+ $this->addFields( array (
'rc_cur_id',
- 'rc_this_oldid',
- 'rc_namespace',
- 'rc_title',
- 'rc_timestamp'
- ));
-
- $this->addFieldsIf('rc_new', $this->fld_flags);
- $this->addFieldsIf('rc_minor', $this->fld_flags);
- $this->addFieldsIf('rc_bot', $this->fld_flags);
- $this->addFieldsIf('rc_user', $this->fld_user);
- $this->addFieldsIf('rc_user_text', $this->fld_user);
- $this->addFieldsIf('rc_comment', $this->fld_comment);
- $this->addFieldsIf('rc_patrolled', $this->fld_patrol);
- $this->addFieldsIf('rc_old_len', $this->fld_sizes);
- $this->addFieldsIf('rc_new_len', $this->fld_sizes);
- }
- elseif ($params['allrev']) {
- $this->addFields(array (
- 'rc_this_oldid',
- 'rc_namespace',
- 'rc_title',
- 'rc_timestamp'
- ));
+ 'rc_this_oldid'
+ ) );
+
+ $this->addFieldsIf( 'rc_new', $this->fld_flags );
+ $this->addFieldsIf( 'rc_minor', $this->fld_flags );
+ $this->addFieldsIf( 'rc_bot', $this->fld_flags );
+ $this->addFieldsIf( 'rc_user', $this->fld_user );
+ $this->addFieldsIf( 'rc_user_text', $this->fld_user );
+ $this->addFieldsIf( 'rc_comment', $this->fld_comment || $this->fld_parsedcomment );
+ $this->addFieldsIf( 'rc_patrolled', $this->fld_patrol );
+ $this->addFieldsIf( 'rc_old_len', $this->fld_sizes );
+ $this->addFieldsIf( 'rc_new_len', $this->fld_sizes );
+ $this->addFieldsIf( 'wl_notificationtimestamp', $this->fld_notificationtimestamp );
+ } elseif ( $params['allrev'] ) {
+ $this->addFields( 'rc_this_oldid' );
} else {
- $this->addFields(array (
- 'rc_cur_id',
- 'rc_namespace',
- 'rc_title',
- 'rc_timestamp'
- ));
+ $this->addFields( 'rc_cur_id' );
}
- $this->addTables(array (
+ $this->addTables( array (
'watchlist',
'page',
'recentchanges'
- ));
+ ) );
- $userId = $wgUser->getId();
- $this->addWhere(array (
+ $userId = $user->getId();
+ $this->addWhere( array (
'wl_namespace = rc_namespace',
'wl_title = rc_title',
'rc_cur_id = page_id',
'wl_user' => $userId,
'rc_deleted' => 0,
- ));
+ ) );
- $this->addWhereRange('rc_timestamp', $params['dir'], $params['start'], $params['end']);
- $this->addWhereFld('wl_namespace', $params['namespace']);
- $this->addWhereIf('rc_this_oldid=page_latest', !$params['allrev']);
+ $this->addWhereRange( 'rc_timestamp', $params['dir'], $params['start'], $params['end'] );
+ $this->addWhereFld( 'wl_namespace', $params['namespace'] );
+ $this->addWhereIf( 'rc_this_oldid=page_latest', !$params['allrev'] );
- if (!is_null($params['show'])) {
- $show = array_flip($params['show']);
+ if ( !is_null( $params['show'] ) ) {
+ $show = array_flip( $params['show'] );
/* Check for conflicting parameters. */
- if ((isset ($show['minor']) && isset ($show['!minor']))
- || (isset ($show['bot']) && isset ($show['!bot']))
- || (isset ($show['anon']) && isset ($show['!anon']))
- || (isset ($show['patrolled']) && isset ($show['!patrolled']))) {
+ if ( ( isset ( $show['minor'] ) && isset ( $show['!minor'] ) )
+ || ( isset ( $show['bot'] ) && isset ( $show['!bot'] ) )
+ || ( isset ( $show['anon'] ) && isset ( $show['!anon'] ) )
+ || ( isset ( $show['patrolled'] ) && isset ( $show['!patrolled'] ) ) ) {
- $this->dieUsage("Incorrect parameter - mutually exclusive values may not be supplied", 'show');
+ $this->dieUsageMsg( array( 'show' ) );
}
- // Check permissions
- global $wgUser;
- if((isset($show['patrolled']) || isset($show['!patrolled'])) && !$wgUser->useRCPatrol() && !$wgUser->useNPPatrol())
- $this->dieUsage("You need the patrol right to request the patrolled flag", 'permissiondenied');
+ // Check permissions.
+ if ( ( isset( $show['patrolled'] ) || isset( $show['!patrolled'] ) ) && !$wgUser->useRCPatrol() && !$wgUser->useNPPatrol() )
+ $this->dieUsage( "You need the patrol right to request the patrolled flag", 'permissiondenied' );
/* Add additional conditions to query depending upon parameters. */
- $this->addWhereIf('rc_minor = 0', isset ($show['!minor']));
- $this->addWhereIf('rc_minor != 0', isset ($show['minor']));
- $this->addWhereIf('rc_bot = 0', isset ($show['!bot']));
- $this->addWhereIf('rc_bot != 0', isset ($show['bot']));
- $this->addWhereIf('rc_user = 0', isset ($show['anon']));
- $this->addWhereIf('rc_user != 0', isset ($show['!anon']));
- $this->addWhereIf('rc_patrolled = 0', isset($show['!patrolled']));
- $this->addWhereIf('rc_patrolled != 0', isset($show['patrolled']));
+ $this->addWhereIf( 'rc_minor = 0', isset ( $show['!minor'] ) );
+ $this->addWhereIf( 'rc_minor != 0', isset ( $show['minor'] ) );
+ $this->addWhereIf( 'rc_bot = 0', isset ( $show['!bot'] ) );
+ $this->addWhereIf( 'rc_bot != 0', isset ( $show['bot'] ) );
+ $this->addWhereIf( 'rc_user = 0', isset ( $show['anon'] ) );
+ $this->addWhereIf( 'rc_user != 0', isset ( $show['!anon'] ) );
+ $this->addWhereIf( 'rc_patrolled = 0', isset( $show['!patrolled'] ) );
+ $this->addWhereIf( 'rc_patrolled != 0', isset( $show['patrolled'] ) );
}
+ if ( !is_null( $params['user'] ) && !is_null( $params['excludeuser'] ) )
+ $this->dieUsage( 'user and excludeuser cannot be used together', 'user-excludeuser' );
+ if ( !is_null( $params['user'] ) )
+ $this->addWhereFld( 'rc_user_text', $params['user'] );
+ if ( !is_null( $params['excludeuser'] ) )
+ $this->addWhere( 'rc_user_text != ' . $this->getDB()->addQuotes( $params['excludeuser'] ) );
- # This is an index optimization for mysql, as done in the Special:Watchlist page
- $this->addWhereIf("rc_timestamp > ''", !isset ($params['start']) && !isset ($params['end']) && $wgDBtype == 'mysql');
+ $db = $this->getDB();
+
+ // This is an index optimization for mysql, as done in the Special:Watchlist page
+ $this->addWhereIf( "rc_timestamp > ''", !isset ( $params['start'] ) && !isset ( $params['end'] ) && $db->getType() == 'mysql' );
- $this->addOption('LIMIT', $params['limit'] +1);
+ $this->addOption( 'LIMIT', $params['limit'] + 1 );
$ids = array ();
$count = 0;
- $res = $this->select(__METHOD__);
+ $res = $this->select( __METHOD__ );
- $db = $this->getDB();
- while ($row = $db->fetchObject($res)) {
- if (++ $count > $params['limit']) {
+ while ( $row = $db->fetchObject( $res ) ) {
+ if ( ++ $count > $params['limit'] ) {
// We've reached the one extra which shows that there are additional pages to be had. Stop here...
- $this->setContinueEnumParameter('start', wfTimestamp(TS_ISO_8601, $row->rc_timestamp));
+ $this->setContinueEnumParameter( 'start', wfTimestamp( TS_ISO_8601, $row->rc_timestamp ) );
break;
}
- if (is_null($resultPageSet)) {
- $vals = $this->extractRowInfo($row);
- $fit = $this->getResult()->addValue(array('query', $this->getModuleName()), null, $vals);
- if(!$fit)
+ if ( is_null( $resultPageSet ) ) {
+ $vals = $this->extractRowInfo( $row );
+ $fit = $this->getResult()->addValue( array( 'query', $this->getModuleName() ), null, $vals );
+ if ( !$fit )
{
- $this->setContinueEnumParameter('start',
- wfTimestamp(TS_ISO_8601, $row->rc_timestamp));
+ $this->setContinueEnumParameter( 'start',
+ wfTimestamp( TS_ISO_8601, $row->rc_timestamp ) );
break;
}
} else {
- if ($params['allrev']) {
- $ids[] = intval($row->rc_this_oldid);
+ if ( $params['allrev'] ) {
+ $ids[] = intval( $row->rc_this_oldid );
} else {
- $ids[] = intval($row->rc_cur_id);
+ $ids[] = intval( $row->rc_cur_id );
}
}
}
- $db->freeResult($res);
+ $db->freeResult( $res );
- if (is_null($resultPageSet)) {
- $this->getResult()->setIndexedTagName_internal(array('query', $this->getModuleName()), 'item');
+ if ( is_null( $resultPageSet ) ) {
+ $this->getResult()->setIndexedTagName_internal( array( 'query', $this->getModuleName() ), 'item' );
}
- elseif ($params['allrev']) {
- $resultPageSet->populateFromRevisionIDs($ids);
+ elseif ( $params['allrev'] ) {
+ $resultPageSet->populateFromRevisionIDs( $ids );
} else {
- $resultPageSet->populateFromPageIDs($ids);
+ $resultPageSet->populateFromPageIDs( $ids );
}
}
- private function extractRowInfo($row) {
+ private function extractRowInfo( $row ) {
$vals = array ();
- if ($this->fld_ids) {
- $vals['pageid'] = intval($row->rc_cur_id);
- $vals['revid'] = intval($row->rc_this_oldid);
+ if ( $this->fld_ids ) {
+ $vals['pageid'] = intval( $row->rc_cur_id );
+ $vals['revid'] = intval( $row->rc_this_oldid );
}
- if ($this->fld_title)
- ApiQueryBase :: addTitleInfo($vals, Title :: makeTitle($row->rc_namespace, $row->rc_title));
+ $title = Title::makeTitle( $row->rc_namespace, $row->rc_title );
+
+ if ( $this->fld_title )
+ ApiQueryBase::addTitleInfo( $vals, $title );
- if ($this->fld_user) {
+ if ( $this->fld_user ) {
$vals['user'] = $row->rc_user_text;
- if (!$row->rc_user)
+ if ( !$row->rc_user )
$vals['anon'] = '';
}
- if ($this->fld_flags) {
- if ($row->rc_new)
+ if ( $this->fld_flags ) {
+ if ( $row->rc_new )
$vals['new'] = '';
- if ($row->rc_minor)
+ if ( $row->rc_minor )
$vals['minor'] = '';
- if ($row->rc_bot)
+ if ( $row->rc_bot )
$vals['bot'] = '';
}
- if ($this->fld_patrol && isset($row->rc_patrolled))
+ if ( $this->fld_patrol && isset( $row->rc_patrolled ) )
$vals['patrolled'] = '';
- if ($this->fld_timestamp)
- $vals['timestamp'] = wfTimestamp(TS_ISO_8601, $row->rc_timestamp);
+ if ( $this->fld_timestamp )
+ $vals['timestamp'] = wfTimestamp( TS_ISO_8601, $row->rc_timestamp );
- if ($this->fld_sizes) {
- $vals['oldlen'] = intval($row->rc_old_len);
- $vals['newlen'] = intval($row->rc_new_len);
+ if ( $this->fld_sizes ) {
+ $vals['oldlen'] = intval( $row->rc_old_len );
+ $vals['newlen'] = intval( $row->rc_new_len );
}
+
+ if ( $this->fld_notificationtimestamp )
+ $vals['notificationtimestamp'] = ( $row->wl_notificationtimestamp == null ) ? '' : wfTimestamp( TS_ISO_8601, $row->wl_notificationtimestamp );
- if ($this->fld_comment && isset( $row->rc_comment ))
+ if ( $this->fld_comment && isset( $row->rc_comment ) )
$vals['comment'] = $row->rc_comment;
+
+ if ( $this->fld_parsedcomment && isset( $row->rc_comment ) ) {
+ global $wgUser;
+ $vals['parsedcomment'] = $wgUser->getSkin()->formatComment( $row->rc_comment, $title );
+ }
return $vals;
}
@@ -268,6 +291,12 @@ class ApiQueryWatchlist extends ApiQueryGeneratorBase {
ApiBase :: PARAM_ISMULTI => true,
ApiBase :: PARAM_TYPE => 'namespace'
),
+ 'user' => array(
+ ApiBase :: PARAM_TYPE => 'user',
+ ),
+ 'excludeuser' => array(
+ ApiBase :: PARAM_TYPE => 'user',
+ ),
'dir' => array (
ApiBase :: PARAM_DFLT => 'older',
ApiBase :: PARAM_TYPE => array (
@@ -291,9 +320,11 @@ class ApiQueryWatchlist extends ApiQueryGeneratorBase {
'flags',
'user',
'comment',
+ 'parsedcomment',
'timestamp',
'patrol',
'sizes',
+ 'notificationtimestamp'
)
),
'show' => array (
@@ -308,6 +339,12 @@ class ApiQueryWatchlist extends ApiQueryGeneratorBase {
'patrolled',
'!patrolled',
)
+ ),
+ 'owner' => array (
+ ApiBase :: PARAM_TYPE => 'user'
+ ),
+ 'token' => array (
+ ApiBase :: PARAM_TYPE => 'string'
)
);
}
@@ -318,19 +355,35 @@ class ApiQueryWatchlist extends ApiQueryGeneratorBase {
'start' => 'The timestamp to start enumerating from.',
'end' => 'The timestamp to end enumerating.',
'namespace' => 'Filter changes to only the given namespace(s).',
+ 'user' => 'Only list changes by this user',
+ 'excludeuser' => 'Don\'t list changes by this user',
'dir' => 'In which direction to enumerate pages.',
'limit' => 'How many total results to return per request.',
'prop' => 'Which additional items to get (non-generator mode only).',
'show' => array (
'Show only items that meet this criteria.',
'For example, to see only minor edits done by logged-in users, set show=minor|!anon'
- )
+ ),
+ 'owner' => "The name of the user whose watchlist you'd like to access",
+ 'token' => "Give a security token (settable in preferences) to allow access to another user's watchlist"
);
}
public function getDescription() {
return "Get all recent changes to pages in the logged in user's watchlist";
}
+
+ public function getPossibleErrors() {
+ return array_merge( parent::getPossibleErrors(), array(
+ array( 'code' => 'bad_wlowner', 'info' => 'Specified user does not exist' ),
+ array( 'code' => 'bad_wltoken', 'info' => 'Incorrect watchlist token provided -- please set a correct token in Special:Preferences' ),
+ array( 'code' => 'notloggedin', 'info' => 'You must be logged-in to have a watchlist' ),
+ array( 'code' => 'patrol', 'info' => 'patrol property is not available' ),
+ array( 'show' ),
+ array( 'code' => 'permissiondenied', 'info' => 'You need the patrol right to request the patrolled flag' ),
+ array( 'code' => 'user-excludeuser', 'info' => 'user and excludeuser cannot be used together' ),
+ ) );
+ }
protected function getExamples() {
return array (
@@ -338,11 +391,12 @@ class ApiQueryWatchlist extends ApiQueryGeneratorBase {
'api.php?action=query&list=watchlist&wlprop=ids|title|timestamp|user|comment',
'api.php?action=query&list=watchlist&wlallrev&wlprop=ids|title|timestamp|user|comment',
'api.php?action=query&generator=watchlist&prop=info',
- 'api.php?action=query&generator=watchlist&gwlallrev&prop=revisions&rvprop=timestamp|user'
+ 'api.php?action=query&generator=watchlist&gwlallrev&prop=revisions&rvprop=timestamp|user',
+ 'api.php?action=query&list=watchlist&wlowner=Bob_Smith&wltoken=d8d562e9725ea1512894cdab28e5ceebc7f20237'
);
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiQueryWatchlist.php 69986 2010-07-27 03:57:39Z tstarling $';
+ return __CLASS__ . ': $Id: ApiQueryWatchlist.php 69932 2010-07-26 08:03:21Z tstarling $';
}
}
diff --git a/includes/api/ApiQueryWatchlistRaw.php b/includes/api/ApiQueryWatchlistRaw.php
index f3982bcb..42d4005b 100644
--- a/includes/api/ApiQueryWatchlistRaw.php
+++ b/includes/api/ApiQueryWatchlistRaw.php
@@ -23,9 +23,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ('ApiQueryBase.php');
+ require_once ( 'ApiQueryBase.php' );
}
/**
@@ -36,92 +36,95 @@ if (!defined('MEDIAWIKI')) {
*/
class ApiQueryWatchlistRaw extends ApiQueryGeneratorBase {
- public function __construct($query, $moduleName) {
- parent :: __construct($query, $moduleName, 'wr');
+ public function __construct( $query, $moduleName ) {
+ parent :: __construct( $query, $moduleName, 'wr' );
}
public function execute() {
$this->run();
}
- public function executeGenerator($resultPageSet) {
- $this->run($resultPageSet);
+ public function executeGenerator( $resultPageSet ) {
+ $this->run( $resultPageSet );
}
- private function run($resultPageSet = null) {
+ private function run( $resultPageSet = null ) {
global $wgUser;
- $this->selectNamedDB('watchlist', DB_SLAVE, 'watchlist');
+ $this->selectNamedDB( 'watchlist', DB_SLAVE, 'watchlist' );
- if (!$wgUser->isLoggedIn())
- $this->dieUsage('You must be logged-in to have a watchlist', 'notloggedin');
+ if ( !$wgUser->isLoggedIn() )
+ $this->dieUsage( 'You must be logged-in to have a watchlist', 'notloggedin' );
$params = $this->extractRequestParams();
- $prop = array_flip((array)$params['prop']);
- $show = array_flip((array)$params['show']);
- if(isset($show['changed']) && isset($show['!changed']))
- $this->dieUsage("Incorrect parameter - mutually exclusive values may not be supplied", 'show');
-
- $this->addTables('watchlist');
- $this->addFields(array('wl_namespace', 'wl_title'));
- $this->addFieldsIf('wl_notificationtimestamp', isset($prop['changed']));
- $this->addWhereFld('wl_user', $wgUser->getId());
- $this->addWhereFld('wl_namespace', $params['namespace']);
- $this->addWhereIf('wl_notificationtimestamp IS NOT NULL', isset($show['changed']));
- $this->addWhereIf('wl_notificationtimestamp IS NULL', isset($show['!changed']));
- if(isset($params['continue']))
+ $prop = array_flip( (array)$params['prop'] );
+ $show = array_flip( (array)$params['show'] );
+ if ( isset( $show['changed'] ) && isset( $show['!changed'] ) )
+ $this->dieUsageMsg( array( 'show' ) );
+
+ $this->addTables( 'watchlist' );
+ $this->addFields( array( 'wl_namespace', 'wl_title' ) );
+ $this->addFieldsIf( 'wl_notificationtimestamp', isset( $prop['changed'] ) );
+ $this->addWhereFld( 'wl_user', $wgUser->getId() );
+ $this->addWhereFld( 'wl_namespace', $params['namespace'] );
+ $this->addWhereIf( 'wl_notificationtimestamp IS NOT NULL', isset( $show['changed'] ) );
+ $this->addWhereIf( 'wl_notificationtimestamp IS NULL', isset( $show['!changed'] ) );
+
+ if ( isset( $params['continue'] ) )
{
- $cont = explode('|', $params['continue']);
- if(count($cont) != 2)
- $this->dieUsage("Invalid continue param. You should pass the " .
- "original value returned by the previous query", "_badcontinue");
- $ns = intval($cont[0]);
- $title = $this->getDB()->strencode($this->titleToKey($cont[1]));
- $this->addWhere("wl_namespace > '$ns' OR ".
- "(wl_namespace = '$ns' AND ".
- "wl_title >= '$title')");
+ $cont = explode( '|', $params['continue'] );
+ if ( count( $cont ) != 2 )
+ $this->dieUsage( "Invalid continue param. You should pass the " .
+ "original value returned by the previous query", "_badcontinue" );
+ $ns = intval( $cont[0] );
+ $title = $this->getDB()->strencode( $this->titleToKey( $cont[1] ) );
+ $this->addWhere( "wl_namespace > '$ns' OR " .
+ "(wl_namespace = '$ns' AND " .
+ "wl_title >= '$title')" );
}
+
// Don't ORDER BY wl_namespace if it's constant in the WHERE clause
- if(count($params['namespace']) == 1)
- $this->addOption('ORDER BY', 'wl_title');
+ if ( count( $params['namespace'] ) == 1 )
+ $this->addOption( 'ORDER BY', 'wl_title' );
else
- $this->addOption('ORDER BY', 'wl_namespace, wl_title');
- $this->addOption('LIMIT', $params['limit'] + 1);
- $res = $this->select(__METHOD__);
+ $this->addOption( 'ORDER BY', 'wl_namespace, wl_title' );
+ $this->addOption( 'LIMIT', $params['limit'] + 1 );
+ $res = $this->select( __METHOD__ );
$db = $this->getDB();
$titles = array();
$count = 0;
- while($row = $db->fetchObject($res))
+ while ( $row = $db->fetchObject( $res ) )
{
- if(++$count > $params['limit'])
+ if ( ++$count > $params['limit'] )
{
// We've reached the one extra which shows that there are additional pages to be had. Stop here...
- $this->setContinueEnumParameter('continue', $row->wl_namespace . '|' .
- $this->keyToTitle($row->wl_title));
+ $this->setContinueEnumParameter( 'continue', $row->wl_namespace . '|' .
+ $this->keyToTitle( $row->wl_title ) );
break;
}
- $t = Title::makeTitle($row->wl_namespace, $row->wl_title);
- if(is_null($resultPageSet))
+ $t = Title::makeTitle( $row->wl_namespace, $row->wl_title );
+
+ if ( is_null( $resultPageSet ) )
{
$vals = array();
- ApiQueryBase::addTitleInfo($vals, $t);
- if(isset($prop['changed']) && !is_null($row->wl_notificationtimestamp))
- $vals['changed'] = wfTimestamp(TS_ISO_8601, $row->wl_notificationtimestamp);
- $fit = $this->getResult()->addValue($this->getModuleName(), null, $vals);
- if(!$fit)
+ ApiQueryBase::addTitleInfo( $vals, $t );
+ if ( isset( $prop['changed'] ) && !is_null( $row->wl_notificationtimestamp ) )
+ $vals['changed'] = wfTimestamp( TS_ISO_8601, $row->wl_notificationtimestamp );
+ $fit = $this->getResult()->addValue( $this->getModuleName(), null, $vals );
+ if ( !$fit )
{
- $this->setContinueEnumParameter('continue', $row->wl_namespace . '|' .
- $this->keyToTitle($row->wl_title));
+ $this->setContinueEnumParameter( 'continue', $row->wl_namespace . '|' .
+ $this->keyToTitle( $row->wl_title ) );
break;
}
}
else
$titles[] = $t;
}
- if(is_null($resultPageSet))
- $this->getResult()->setIndexedTagName_internal($this->getModuleName(), 'wr');
+ if ( is_null( $resultPageSet ) )
+ $this->getResult()->setIndexedTagName_internal( $this->getModuleName(), 'wr' );
else
- $resultPageSet->populateFromTitles($titles);
+ $resultPageSet->populateFromTitles( $titles );
}
public function getAllowedParams() {
@@ -167,6 +170,13 @@ class ApiQueryWatchlistRaw extends ApiQueryGeneratorBase {
public function getDescription() {
return "Get all pages on the logged in user's watchlist";
}
+
+ public function getPossibleErrors() {
+ return array_merge( parent::getPossibleErrors(), array(
+ array( 'code' => 'notloggedin', 'info' => 'You must be logged-in to have a watchlist' ),
+ array( 'show' ),
+ ) );
+ }
protected function getExamples() {
return array (
@@ -176,6 +186,6 @@ class ApiQueryWatchlistRaw extends ApiQueryGeneratorBase {
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiQueryWatchlistRaw.php 69579 2010-07-20 02:49:55Z tstarling $';
+ return __CLASS__ . ': $Id: ApiQueryWatchlistRaw.php 69578 2010-07-20 02:46:20Z tstarling $';
}
} \ No newline at end of file
diff --git a/includes/api/ApiResult.php b/includes/api/ApiResult.php
index 3dbee08a..64c2c3fb 100644
--- a/includes/api/ApiResult.php
+++ b/includes/api/ApiResult.php
@@ -23,9 +23,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ('ApiBase.php');
+ require_once ( 'ApiBase.php' );
}
/**
@@ -53,8 +53,8 @@ class ApiResult extends ApiBase {
* Constructor
* @param $main ApiMain object
*/
- public function __construct($main) {
- parent :: __construct($main, 'result');
+ public function __construct( $main ) {
+ parent :: __construct( $main, 'result' );
$this->mIsRawMode = false;
$this->mCheckingSize = true;
$this->reset();
@@ -91,21 +91,21 @@ class ApiResult extends ApiBase {
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) {
+ public static function size( $value ) {
$s = 0;
- if(is_array($value))
- foreach($value as $v)
- $s += self::size($v);
- else if(!is_object($value))
+ 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);
+ $s = strlen( $value );
return $s;
}
@@ -116,7 +116,7 @@ class ApiResult extends ApiBase {
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
@@ -125,7 +125,7 @@ class ApiResult extends ApiBase {
public function disableSizeCheck() {
$this->mCheckingSize = false;
}
-
+
/**
* Re-enable size checking in addValue()
*/
@@ -140,21 +140,21 @@ class ApiResult extends ApiBase {
* @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))
- ApiBase :: dieDebug(__METHOD__, 'Bad parameter');
+ public static function setElement( & $arr, $name, $value ) {
+ if ( $arr === null || $name === null || $value === null || !is_array( $arr ) || is_array( $name ) )
+ ApiBase :: dieDebug( __METHOD__, 'Bad parameter' );
- if (!isset ($arr[$name])) {
+ if ( !isset ( $arr[$name] ) ) {
$arr[$name] = $value;
}
- elseif (is_array($arr[$name]) && is_array($value)) {
- $merged = array_intersect_key($arr[$name], $value);
- if (!count($merged))
+ elseif ( is_array( $arr[$name] ) && is_array( $value ) ) {
+ $merged = array_intersect_key( $arr[$name], $value );
+ if ( !count( $merged ) )
$arr[$name] += $value;
else
- ApiBase :: dieDebug(__METHOD__, "Attempting to merge element $name");
+ ApiBase :: dieDebug( __METHOD__, "Attempting to merge element $name" );
} else
- ApiBase :: dieDebug(__METHOD__, "Attempting to add element $name=$value, existing value is {$arr[$name]}");
+ ApiBase :: dieDebug( __METHOD__, "Attempting to add element $name=$value, existing value is {$arr[$name]}" );
}
/**
@@ -165,15 +165,15 @@ class ApiResult extends ApiBase {
* 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))
- ApiBase :: dieDebug(__METHOD__, 'Bad parameter');
- if (is_null($subElemName)) {
- ApiResult :: setElement($arr, '*', $value);
+ public static function setContent( & $arr, $value, $subElemName = null ) {
+ if ( is_array( $value ) )
+ ApiBase :: dieDebug( __METHOD__, 'Bad parameter' );
+ if ( is_null( $subElemName ) ) {
+ ApiResult :: setElement( $arr, '*', $value );
} else {
- if (!isset ($arr[$subElemName]))
+ if ( !isset ( $arr[$subElemName] ) )
$arr[$subElemName] = array ();
- ApiResult :: setElement($arr[$subElemName], '*', $value);
+ ApiResult :: setElement( $arr[$subElemName], '*', $value );
}
}
@@ -184,12 +184,12 @@ class ApiResult extends ApiBase {
* @param $arr array
* @param $tag string Tag name
*/
- public function setIndexedTagName(& $arr, $tag) {
+ public function setIndexedTagName( & $arr, $tag ) {
// In raw mode, add the '_element', otherwise just ignore
- if (!$this->getIsRawMode())
+ if ( !$this->getIsRawMode() )
return;
- if ($arr === null || $tag === null || !is_array($arr) || is_array($tag))
- ApiBase :: dieDebug(__METHOD__, 'Bad parameter');
+ 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;
}
@@ -199,17 +199,16 @@ class ApiResult extends ApiBase {
* @param $arr array
* @param $tag string Tag name
*/
- 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);
- }
+ 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 );
+ }
}
/**
@@ -221,15 +220,15 @@ class ApiResult extends ApiBase {
*/
public function setIndexedTagName_internal( $path, $tag ) {
$data = & $this->mData;
- foreach((array)$path as $p) {
+ foreach ( (array)$path as $p ) {
if ( !isset( $data[$p] ) ) {
$data[$p] = array();
}
$data = & $data[$p];
}
- if(is_null($data))
+ if ( is_null( $data ) )
return;
- $this->setIndexedTagName($data, $tag);
+ $this->setIndexedTagName( $data, $tag );
}
/**
@@ -239,34 +238,34 @@ class ApiResult extends ApiBase {
* 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) {
+ public function addValue( $path, $name, $value ) {
global $wgAPIMaxResultSize;
$data = & $this->mData;
- if( $this->mCheckingSize ) {
- $newsize = $this->mSize + self::size($value);
- if($newsize > $wgAPIMaxResultSize)
+ 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)) {
- foreach ($path as $p) {
- if (!isset ($data[$p]))
+ if ( !is_null( $path ) ) {
+ if ( is_array( $path ) ) {
+ foreach ( $path as $p ) {
+ if ( !isset ( $data[$p] ) )
$data[$p] = array ();
$data = & $data[$p];
}
} else {
- if (!isset ($data[$path]))
+ if ( !isset ( $data[$path] ) )
$data[$path] = array ();
$data = & $data[$path];
}
}
- if (!$name)
+ if ( !$name )
$data[] = $value; // Add list element
else
- ApiResult :: setElement($data, $name, $value); // Add named element
+ ApiResult :: setElement( $data, $name, $value ); // Add named element
return true;
}
@@ -277,16 +276,16 @@ class ApiResult extends ApiBase {
* @param $path array
* @param $name string
*/
- public function unsetValue($path, $name) {
+ public function unsetValue( $path, $name ) {
$data = & $this->mData;
- if(!is_null($path))
- foreach((array)$path as $p) {
- if(!isset($data[$p]))
+ 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]);
+ $this->mSize -= self::size( $data[$name] );
+ unset( $data[$name] );
}
/**
@@ -294,52 +293,25 @@ class ApiResult extends ApiBase {
*/
public function cleanUpUTF8()
{
- array_walk_recursive($this->mData, array('ApiResult', 'cleanUp_helper'));
+ array_walk_recursive( $this->mData, array( 'ApiResult', 'cleanUp_helper' ) );
}
/**
* Callback function for cleanUpUTF8()
*/
- private static function cleanUp_helper(&$s)
+ private static function cleanUp_helper( &$s )
{
- if(!is_string($s))
+ if ( !is_string( $s ) )
return;
- $s = UtfNormal::cleanUp($s);
+ global $wgContLang;
+ $s = $wgContLang->normalize( $s );
}
public function execute() {
- ApiBase :: dieDebug(__METHOD__, 'execute() is not supported on Result object');
+ ApiBase :: dieDebug( __METHOD__, 'execute() is not supported on Result object' );
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiResult.php 47447 2009-02-18 12:41:28Z tstarling $';
- }
-}
-
-/* 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);
-
- foreach (array_keys($isec) as $key) {
- if (!isset($arr[$key]))
- unset($isec[$key]);
- }
- }
-
- return $isec;
- } else {
- $res = array();
- foreach (array_keys($isec) as $key) {
- if (isset($keys[$key]))
- $res[$key] = $isec[$key];
- }
-
- return $res;
- }
+ return __CLASS__ . ': $Id: ApiResult.php 62354 2010-02-12 06:44:16Z mah $';
}
}
diff --git a/includes/api/ApiRollback.php b/includes/api/ApiRollback.php
index 0f0eae10..5c259f4e 100644
--- a/includes/api/ApiRollback.php
+++ b/includes/api/ApiRollback.php
@@ -22,9 +22,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ("ApiBase.php");
+ require_once ( "ApiBase.php" );
}
/**
@@ -32,53 +32,51 @@ if (!defined('MEDIAWIKI')) {
*/
class ApiRollback extends ApiBase {
- public function __construct($main, $action) {
- parent :: __construct($main, $action);
+ public function __construct( $main, $action ) {
+ parent :: __construct( $main, $action );
}
public function execute() {
$params = $this->extractRequestParams();
- $titleObj = NULL;
- if(!isset($params['title']))
- $this->dieUsageMsg(array('missingparam', 'title'));
- if(!isset($params['user']))
- $this->dieUsageMsg(array('missingparam', 'user'));
- if(!isset($params['token']))
- $this->dieUsageMsg(array('missingparam', 'token'));
-
- $titleObj = Title::newFromText($params['title']);
- if(!$titleObj)
- $this->dieUsageMsg(array('invalidtitle', $params['title']));
- if(!$titleObj->exists())
- $this->dieUsageMsg(array('notanarticle'));
-
- #We need to be able to revert IPs, but getCanonicalName rejects them
- $username = User::isIP($params['user'])
+ $titleObj = null;
+ if ( !isset( $params['title'] ) )
+ $this->dieUsageMsg( array( 'missingparam', 'title' ) );
+ if ( !isset( $params['user'] ) )
+ $this->dieUsageMsg( array( 'missingparam', 'user' ) );
+
+ $titleObj = Title::newFromText( $params['title'] );
+ if ( !$titleObj )
+ $this->dieUsageMsg( array( 'invalidtitle', $params['title'] ) );
+ if ( !$titleObj->exists() )
+ $this->dieUsageMsg( array( 'notanarticle' ) );
+
+ // We need to be able to revert IPs, but getCanonicalName rejects them
+ $username = User::isIP( $params['user'] )
? $params['user']
- : User::getCanonicalName($params['user']);
- if(!$username)
- $this->dieUsageMsg(array('invaliduser', $params['user']));
+ : User::getCanonicalName( $params['user'] );
+ if ( !$username )
+ $this->dieUsageMsg( array( 'invaliduser', $params['user'] ) );
- $articleObj = new Article($titleObj);
- $summary = (isset($params['summary']) ? $params['summary'] : "");
+ $articleObj = new Article( $titleObj );
+ $summary = ( isset( $params['summary'] ) ? $params['summary'] : "" );
$details = null;
- $retval = $articleObj->doRollback($username, $summary, $params['token'], $params['markbot'], $details);
+ $retval = $articleObj->doRollback( $username, $summary, $params['token'], $params['markbot'], $details );
- if($retval)
+ if ( $retval )
// We don't care about multiple errors, just report one of them
- $this->dieUsageMsg(reset($retval));
+ $this->dieUsageMsg( reset( $retval ) );
$info = array(
'title' => $titleObj->getPrefixedText(),
- 'pageid' => intval($details['current']->getPage()),
+ 'pageid' => intval( $details['current']->getPage() ),
'summary' => $details['summary'],
- 'revid' => intval($titleObj->getLatestRevID()),
- 'old_revid' => intval($details['current']->getID()),
- 'last_revid' => intval($details['target']->getID())
+ 'revid' => intval( $details['newid'] ),
+ 'old_revid' => intval( $details['current']->getID() ),
+ 'last_revid' => intval( $details['target']->getID() )
);
- $this->getResult()->addValue(null, $this->getModuleName(), $info);
+ $this->getResult()->addValue( null, $this->getModuleName(), $info );
}
public function mustBePosted() { return true; }
@@ -113,6 +111,16 @@ class ApiRollback extends ApiBase {
'they will all be rolled back.'
);
}
+
+ public function getPossibleErrors() {
+ return array_merge( parent::getPossibleErrors(), array(
+ array( 'missingparam', 'title' ),
+ array( 'missingparam', 'user' ),
+ array( 'invalidtitle', 'title' ),
+ array( 'notanarticle' ),
+ array( 'invaliduser', 'user' ),
+ ) );
+ }
protected function getExamples() {
return array (
@@ -122,6 +130,6 @@ class ApiRollback extends ApiBase {
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiRollback.php 48122 2009-03-07 12:58:41Z catrope $';
+ return __CLASS__ . ': $Id: ApiRollback.php 65371 2010-04-21 10:41:25Z tstarling $';
}
}
diff --git a/includes/api/ApiUnblock.php b/includes/api/ApiUnblock.php
index 9216317a..2ffae504 100644
--- a/includes/api/ApiUnblock.php
+++ b/includes/api/ApiUnblock.php
@@ -22,9 +22,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ("ApiBase.php");
+ require_once ( "ApiBase.php" );
}
/**
@@ -35,8 +35,8 @@ if (!defined('MEDIAWIKI')) {
*/
class ApiUnblock extends ApiBase {
- public function __construct($main, $action) {
- parent :: __construct($main, $action);
+ public function __construct( $main, $action ) {
+ parent :: __construct( $main, $action );
}
/**
@@ -46,38 +46,37 @@ class ApiUnblock extends ApiBase {
global $wgUser;
$params = $this->extractRequestParams();
- if($params['gettoken'])
+ if ( $params['gettoken'] )
{
$res['unblocktoken'] = $wgUser->editToken();
- $this->getResult()->addValue(null, $this->getModuleName(), $res);
+ $this->getResult()->addValue( null, $this->getModuleName(), $res );
return;
}
- if(is_null($params['id']) && is_null($params['user']))
- $this->dieUsageMsg(array('unblock-notarget'));
- if(!is_null($params['id']) && !is_null($params['user']))
- $this->dieUsageMsg(array('unblock-idanduser'));
- if(is_null($params['token']))
- $this->dieUsageMsg(array('missingparam', 'token'));
- if(!$wgUser->matchEditToken($params['token']))
- $this->dieUsageMsg(array('sessionfailure'));
- if(!$wgUser->isAllowed('block'))
- $this->dieUsageMsg(array('cantunblock'));
+ if ( is_null( $params['id'] ) && is_null( $params['user'] ) )
+ $this->dieUsageMsg( array( 'unblock-notarget' ) );
+ if ( !is_null( $params['id'] ) && !is_null( $params['user'] ) )
+ $this->dieUsageMsg( array( 'unblock-idanduser' ) );
+
+ if ( !$wgUser->isAllowed( 'block' ) )
+ $this->dieUsageMsg( array( 'cantunblock' ) );
$id = $params['id'];
$user = $params['user'];
- $reason = (is_null($params['reason']) ? '' : $params['reason']);
- $retval = IPUnblockForm::doUnblock($id, $user, $reason, $range);
- if($retval)
- $this->dieUsageMsg($retval);
+ $reason = ( is_null( $params['reason'] ) ? '' : $params['reason'] );
+ $retval = IPUnblockForm::doUnblock( $id, $user, $reason, $range );
+ if ( $retval )
+ $this->dieUsageMsg( $retval );
- $res['id'] = intval($id);
+ $res['id'] = intval( $id );
$res['user'] = $user;
$res['reason'] = $reason;
- $this->getResult()->addValue(null, $this->getModuleName(), $res);
+ $this->getResult()->addValue( null, $this->getModuleName(), $res );
}
- public function mustBePosted() { return true; }
+ public function mustBePosted() {
+ return true;
+ }
public function isWriteMode() {
return true;
@@ -108,6 +107,18 @@ class ApiUnblock extends ApiBase {
'Unblock a user.'
);
}
+
+ public function getPossibleErrors() {
+ return array_merge( parent::getPossibleErrors(), array(
+ array( 'unblock-notarget' ),
+ array( 'unblock-idanduser' ),
+ array( 'cantunblock' ),
+ ) );
+ }
+
+ public function getTokenSalt() {
+ return '';
+ }
protected function getExamples() {
return array (
@@ -117,6 +128,6 @@ class ApiUnblock extends ApiBase {
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiUnblock.php 48091 2009-03-06 13:49:44Z catrope $';
+ return __CLASS__ . ': $Id: ApiUnblock.php 62599 2010-02-16 21:59:16Z reedy $';
}
}
diff --git a/includes/api/ApiUndelete.php b/includes/api/ApiUndelete.php
index ddc9f7f8..9efba5f3 100644
--- a/includes/api/ApiUndelete.php
+++ b/includes/api/ApiUndelete.php
@@ -22,9 +22,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ("ApiBase.php");
+ require_once ( "ApiBase.php" );
}
/**
@@ -32,58 +32,57 @@ if (!defined('MEDIAWIKI')) {
*/
class ApiUndelete extends ApiBase {
- public function __construct($main, $action) {
- parent :: __construct($main, $action);
+ public function __construct( $main, $action ) {
+ parent :: __construct( $main, $action );
}
public function execute() {
global $wgUser;
$params = $this->extractRequestParams();
- $titleObj = NULL;
- if(!isset($params['title']))
- $this->dieUsageMsg(array('missingparam', 'title'));
- if(!isset($params['token']))
- $this->dieUsageMsg(array('missingparam', 'token'));
+ $titleObj = null;
+ if ( !isset( $params['title'] ) )
+ $this->dieUsageMsg( array( 'missingparam', 'title' ) );
- if(!$wgUser->isAllowed('undelete'))
- $this->dieUsageMsg(array('permdenied-undelete'));
- if($wgUser->isBlocked())
- $this->dieUsageMsg(array('blockedtext'));
- if(!$wgUser->matchEditToken($params['token']))
- $this->dieUsageMsg(array('sessionfailure'));
+ if ( !$wgUser->isAllowed( 'undelete' ) )
+ $this->dieUsageMsg( array( 'permdenied-undelete' ) );
- $titleObj = Title::newFromText($params['title']);
- if(!$titleObj)
- $this->dieUsageMsg(array('invalidtitle', $params['title']));
+ if ( $wgUser->isBlocked() )
+ $this->dieUsageMsg( array( 'blockedtext' ) );
+
+ $titleObj = Title::newFromText( $params['title'] );
+ if ( !$titleObj )
+ $this->dieUsageMsg( array( 'invalidtitle', $params['title'] ) );
// Convert timestamps
- if(!isset($params['timestamps']))
+ if ( !isset( $params['timestamps'] ) )
$params['timestamps'] = array();
- if(!is_array($params['timestamps']))
- $params['timestamps'] = array($params['timestamps']);
- foreach($params['timestamps'] as $i => $ts)
- $params['timestamps'][$i] = wfTimestamp(TS_MW, $ts);
+ if ( !is_array( $params['timestamps'] ) )
+ $params['timestamps'] = array( $params['timestamps'] );
+ foreach ( $params['timestamps'] as $i => $ts )
+ $params['timestamps'][$i] = wfTimestamp( TS_MW, $ts );
- $pa = new PageArchive($titleObj);
- $dbw = wfGetDB(DB_MASTER);
+ $pa = new PageArchive( $titleObj );
+ $dbw = wfGetDB( DB_MASTER );
$dbw->begin();
- $retval = $pa->undelete((isset($params['timestamps']) ? $params['timestamps'] : array()), $params['reason']);
- if(!is_array($retval))
- $this->dieUsageMsg(array('cannotundelete'));
+ $retval = $pa->undelete( ( isset( $params['timestamps'] ) ? $params['timestamps'] : array() ), $params['reason'] );
+ if ( !is_array( $retval ) )
+ $this->dieUsageMsg( array( 'cannotundelete' ) );
- if($retval[1])
- wfRunHooks( 'FileUndeleteComplete',
- array($titleObj, array(), $wgUser, $params['reason']) );
+ if ( $retval[1] )
+ wfRunHooks( 'FileUndeleteComplete',
+ array( $titleObj, array(), $wgUser, $params['reason'] ) );
$info['title'] = $titleObj->getPrefixedText();
- $info['revisions'] = intval($retval[0]);
- $info['fileversions'] = intval($retval[1]);
- $info['reason'] = intval($retval[2]);
- $this->getResult()->addValue(null, $this->getModuleName(), $info);
+ $info['revisions'] = intval( $retval[0] );
+ $info['fileversions'] = intval( $retval[1] );
+ $info['reason'] = intval( $retval[2] );
+ $this->getResult()->addValue( null, $this->getModuleName(), $info );
}
- public function mustBePosted() { return true; }
+ public function mustBePosted() {
+ return true;
+ }
public function isWriteMode() {
return true;
@@ -115,6 +114,20 @@ class ApiUndelete extends ApiBase {
'retrieved through list=deletedrevs'
);
}
+
+ public function getPossibleErrors() {
+ return array_merge( parent::getPossibleErrors(), array(
+ array( 'missingparam', 'title' ),
+ array( 'permdenied-undelete' ),
+ array( 'blockedtext' ),
+ array( 'invalidtitle', 'title' ),
+ array( 'cannotundelete' ),
+ ) );
+ }
+
+ public function getTokenSalt() {
+ return '';
+ }
protected function getExamples() {
return array (
@@ -124,6 +137,6 @@ class ApiUndelete extends ApiBase {
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiUndelete.php 48091 2009-03-06 13:49:44Z catrope $';
+ return __CLASS__ . ': $Id: ApiUndelete.php 62599 2010-02-16 21:59:16Z reedy $';
}
}
diff --git a/includes/api/ApiUpload.php b/includes/api/ApiUpload.php
new file mode 100644
index 00000000..6b91b223
--- /dev/null
+++ b/includes/api/ApiUpload.php
@@ -0,0 +1,325 @@
+<?php
+/*
+ * Created on Aug 21, 2008
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2008 - 2010 Bryan Tong Minh <Bryan.TongMinh@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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if ( !defined( 'MEDIAWIKI' ) ) {
+ // Eclipse helper - will be ignored in production
+ require_once( "ApiBase.php" );
+}
+
+/**
+ * @ingroup API
+ */
+class ApiUpload extends ApiBase {
+ protected $mUpload = null;
+ protected $mParams;
+
+ public function __construct( $main, $action ) {
+ parent::__construct( $main, $action );
+ }
+
+ public function execute() {
+ global $wgUser, $wgAllowCopyUploads;
+
+ // Check whether upload is enabled
+ if ( !UploadBase::isEnabled() )
+ $this->dieUsageMsg( array( 'uploaddisabled' ) );
+
+ $this->mParams = $this->extractRequestParams();
+ $request = $this->getMain()->getRequest();
+
+ // Add the uploaded file to the params array
+ $this->mParams['file'] = $request->getFileName( 'file' );
+
+ // One and only one of the following parameters is needed
+ $this->requireOnlyOneParameter( $this->mParams,
+ 'sessionkey', 'file', 'url' );
+
+ if ( $this->mParams['sessionkey'] ) {
+ /**
+ * Upload stashed in a previous request
+ */
+ // Check the session key
+ if ( !isset( $_SESSION['wsUploadData'][$this->mParams['sessionkey']] ) )
+ $this->dieUsageMsg( array( 'invalid-session-key' ) );
+
+ $this->mUpload = new UploadFromStash();
+ $this->mUpload->initialize( $this->mParams['filename'],
+ $this->mParams['sessionkey'],
+ $_SESSION['wsUploadData'][$this->mParams['sessionkey']] );
+ } elseif ( isset( $this->mParams['filename'] ) ) {
+ /**
+ * Upload from url, etc
+ * Parameter filename is required
+ */
+
+ if ( isset( $this->mParams['file'] ) ) {
+ $this->mUpload = new UploadFromFile();
+ $this->mUpload->initialize(
+ $this->mParams['filename'],
+ $request->getFileTempName( 'file' ),
+ $request->getFileSize( 'file' )
+ );
+ } elseif ( isset( $this->mParams['url'] ) ) {
+ // make sure upload by url is enabled:
+ if ( !$wgAllowCopyUploads )
+ $this->dieUsageMsg( array( 'uploaddisabled' ) );
+
+ // make sure the current user can upload
+ if ( ! $wgUser->isAllowed( 'upload_by_url' ) )
+ $this->dieUsageMsg( array( 'badaccess-groups' ) );
+
+ $this->mUpload = new UploadFromUrl();
+ $this->mUpload->initialize( $this->mParams['filename'],
+ $this->mParams['url'] );
+
+ $status = $this->mUpload->fetchFile();
+ if ( !$status->isOK() ) {
+ $this->dieUsage( $status->getWikiText(), 'fetchfileerror' );
+ }
+ }
+ } else $this->dieUsageMsg( array( 'missingparam', 'filename' ) );
+
+ if ( !isset( $this->mUpload ) )
+ $this->dieUsage( 'No upload module set', 'nomodule' );
+
+ // Check whether the user has the appropriate permissions to upload anyway
+ $permission = $this->mUpload->isAllowed( $wgUser );
+
+ if ( $permission !== true ) {
+ if ( !$wgUser->isLoggedIn() )
+ $this->dieUsageMsg( array( 'mustbeloggedin', 'upload' ) );
+ else
+ $this->dieUsageMsg( array( 'badaccess-groups' ) );
+ }
+ // Perform the upload
+ $result = $this->performUpload();
+
+ // Cleanup any temporary mess
+ $this->mUpload->cleanupTempFile();
+
+ $this->getResult()->addValue( null, $this->getModuleName(), $result );
+ }
+
+ protected function performUpload() {
+ global $wgUser;
+ $result = array();
+ $permErrors = $this->mUpload->verifyPermissions( $wgUser );
+ if ( $permErrors !== true ) {
+ $this->dieUsageMsg( array( 'badaccess-groups' ) );
+ }
+
+ // TODO: Move them to ApiBase's message map
+ $verification = $this->mUpload->verifyUpload();
+ if ( $verification['status'] !== UploadBase::OK ) {
+ $result['result'] = 'Failure';
+ switch( $verification['status'] ) {
+ case UploadBase::EMPTY_FILE:
+ $this->dieUsage( 'The file you submitted was empty', 'empty-file' );
+ break;
+ case UploadBase::FILETYPE_MISSING:
+ $this->dieUsage( 'The file is missing an extension', 'filetype-missing' );
+ break;
+ case UploadBase::FILETYPE_BADTYPE:
+ global $wgFileExtensions;
+ $this->dieUsage( 'This type of file is banned', 'filetype-banned',
+ 0, array(
+ 'filetype' => $verification['finalExt'],
+ 'allowed' => $wgFileExtensions
+ ) );
+ break;
+ case UploadBase::MIN_LENGTH_PARTNAME:
+ $this->dieUsage( 'The filename is too short', 'filename-tooshort' );
+ break;
+ case UploadBase::ILLEGAL_FILENAME:
+ $this->dieUsage( 'The filename is not allowed', 'illegal-filename',
+ 0, array( 'filename' => $verification['filtered'] ) );
+ break;
+ case UploadBase::OVERWRITE_EXISTING_FILE:
+ $this->dieUsage( 'Overwriting an existing file is not allowed', 'overwrite' );
+ break;
+ case UploadBase::VERIFICATION_ERROR:
+ $this->getResult()->setIndexedTagName( $verification['details'], 'detail' );
+ $this->dieUsage( 'This file did not pass file verification', 'verification-error',
+ 0, array( 'details' => $verification['details'] ) );
+ break;
+ case UploadBase::HOOK_ABORTED:
+ $this->dieUsage( "The modification you tried to make was aborted by an extension hook",
+ 'hookaborted', 0, array( 'error' => $verification['error'] ) );
+ break;
+ default:
+ $this->dieUsage( 'An unknown error occurred', 'unknown-error',
+ 0, array( 'code' => $verification['status'] ) );
+ break;
+ }
+ return $result;
+ }
+ if ( !$this->mParams['ignorewarnings'] ) {
+ $warnings = $this->mUpload->checkWarnings();
+ if ( $warnings ) {
+ // Add indices
+ $this->getResult()->setIndexedTagName( $warnings, 'warning' );
+
+ if ( isset( $warnings['duplicate'] ) ) {
+ $dupes = array();
+ foreach ( $warnings['duplicate'] as $key => $dupe )
+ $dupes[] = $dupe->getName();
+ $this->getResult()->setIndexedTagName( $dupes, 'duplicate' );
+ $warnings['duplicate'] = $dupes;
+ }
+
+
+ if ( isset( $warnings['exists'] ) ) {
+ $warning = $warnings['exists'];
+ unset( $warnings['exists'] );
+ $warnings[$warning['warning']] = $warning['file']->getName();
+ }
+
+ $result['result'] = 'Warning';
+ $result['warnings'] = $warnings;
+
+ $sessionKey = $this->mUpload->stashSession();
+ if ( !$sessionKey )
+ $this->dieUsage( 'Stashing temporary file failed', 'stashfailed' );
+
+ $result['sessionkey'] = $sessionKey;
+
+ return $result;
+ }
+ }
+
+ // Use comment as initial page text by default
+ if ( is_null( $this->mParams['text'] ) )
+ $this->mParams['text'] = $this->mParams['comment'];
+
+ // No errors, no warnings: do the upload
+ $status = $this->mUpload->performUpload( $this->mParams['comment'],
+ $this->mParams['text'], $this->mParams['watch'], $wgUser );
+
+ if ( !$status->isGood() ) {
+ $error = $status->getErrorsArray();
+ $this->getResult()->setIndexedTagName( $result['details'], 'error' );
+
+ $this->dieUsage( 'An internal error occurred', 'internal-error', 0, $error );
+ }
+
+ $file = $this->mUpload->getLocalFile();
+ $result['result'] = 'Success';
+ $result['filename'] = $file->getName();
+ $result['imageinfo'] = $this->mUpload->getImageInfo( $this->getResult() );
+
+ return $result;
+ }
+
+ public function mustBePosted() {
+ return true;
+ }
+
+ public function isWriteMode() {
+ return true;
+ }
+
+ public function getAllowedParams() {
+ $params = array(
+ 'filename' => null,
+ 'comment' => array(
+ ApiBase::PARAM_DFLT => ''
+ ),
+ 'text' => null,
+ 'token' => null,
+ 'watch' => false,
+ 'ignorewarnings' => false,
+ 'file' => null,
+ 'url' => null,
+ 'sessionkey' => null,
+ );
+ return $params;
+
+ }
+
+ public function getParamDescription() {
+ return array(
+ 'filename' => 'Target filename',
+ 'token' => 'Edit token. You can get one of these through prop=info',
+ 'comment' => 'Upload comment. Also used as the initial page text for new files if "text" is not specified',
+ 'text' => 'Initial page text for new files',
+ 'watch' => 'Watch the page',
+ 'ignorewarnings' => 'Ignore any warnings',
+ 'file' => 'File contents',
+ 'url' => 'Url to fetch the file from',
+ 'sessionkey' => array(
+ 'Session key returned by a previous upload that failed due to warnings',
+ ),
+ );
+ }
+
+ public function getDescription() {
+ return array(
+ 'Upload a file, or get the status of pending uploads. Several methods are available:',
+ ' * Upload file contents directly, using the "file" parameter',
+ ' * Have the MediaWiki server fetch a file from a URL, using the "url" parameter',
+ ' * Complete an earlier upload that failed due to warnings, using the "sessionkey" parameter',
+ 'Note that the HTTP POST must be done as a file upload (i.e. using multipart/form-data) when',
+ 'sending the "file". Note also that queries using session keys must be',
+ 'done in the same login session as the query that originally returned the key (i.e. do not',
+ 'log out and then log back in). Also you must get and send an edit token before doing any upload stuff.'
+ );
+ }
+
+ public function getPossibleErrors() {
+ return array_merge( parent::getPossibleErrors(), array(
+ array( 'uploaddisabled' ),
+ array( 'invalid-session-key' ),
+ array( 'uploaddisabled' ),
+ array( 'badaccess-groups' ),
+ array( 'missingparam', 'filename' ),
+ array( 'mustbeloggedin', 'upload' ),
+ array( 'badaccess-groups' ),
+ array( 'badaccess-groups' ),
+ array( 'code' => 'fetchfileerror', 'info' => '' ),
+ array( 'code' => 'nomodule', 'info' => 'No upload module set' ),
+ array( 'code' => 'empty-file', 'info' => 'The file you submitted was empty' ),
+ array( 'code' => 'filetype-missing', 'info' => 'The file is missing an extension' ),
+ array( 'code' => 'filename-tooshort', 'info' => 'The filename is too short' ),
+ array( 'code' => 'overwrite', 'info' => 'Overwriting an existing file is not allowed' ),
+ array( 'code' => 'stashfailed', 'info' => 'Stashing temporary file failed' ),
+ array( 'code' => 'internal-error', 'info' => 'An internal error occurred' ),
+ ) );
+ }
+
+ public function getTokenSalt() {
+ return '';
+ }
+
+ protected function getExamples() {
+ return array(
+ 'Upload from a URL:',
+ ' api.php?action=upload&filename=Wiki.png&url=http%3A//upload.wikimedia.org/wikipedia/en/b/bc/Wiki.png',
+ 'Complete an upload that failed due to warnings:',
+ ' api.php?action=upload&filename=Wiki.png&sessionkey=sessionkey&ignorewarnings=1',
+ );
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id: ApiUpload.php 51812 2009-06-12 23:45:20Z dale $';
+ }
+}
diff --git a/includes/api/ApiUserrights.php b/includes/api/ApiUserrights.php
new file mode 100644
index 00000000..6296a8f8
--- /dev/null
+++ b/includes/api/ApiUserrights.php
@@ -0,0 +1,128 @@
+<?php
+
+/*
+ * Created on Mar 24, 2009
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2009 Roan Kattouw <Firstname>.<Lastname>@home.nl
+ *
+ * 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if ( !defined( 'MEDIAWIKI' ) ) {
+ // Eclipse helper - will be ignored in production
+ require_once ( "ApiBase.php" );
+}
+
+/**
+ * @ingroup API
+ */
+class ApiUserrights extends ApiBase {
+
+ public function __construct( $main, $action ) {
+ parent :: __construct( $main, $action );
+ }
+
+ public function execute() {
+ $params = $this->extractRequestParams();
+
+ // User already validated in call to getTokenSalt from Main
+ $form = new UserrightsPage;
+ $user = $form->fetchUser( $params['user'] );
+
+ $r['user'] = $user->getName();
+ list( $r['added'], $r['removed'] ) =
+ $form->doSaveUserGroups(
+ $user, (array)$params['add'],
+ (array)$params['remove'], $params['reason'] );
+
+ $this->getResult()->setIndexedTagName( $r['added'], 'group' );
+ $this->getResult()->setIndexedTagName( $r['removed'], 'group' );
+ $this->getResult()->addValue( null, $this->getModuleName(), $r );
+ }
+
+ public function mustBePosted() {
+ return true;
+ }
+
+ public function isWriteMode() {
+ return true;
+ }
+
+ public function getAllowedParams() {
+ return array (
+ 'user' => null,
+ 'add' => array(
+ ApiBase :: PARAM_TYPE => User::getAllGroups(),
+ ApiBase :: PARAM_ISMULTI => true
+ ),
+ 'remove' => array(
+ ApiBase :: PARAM_TYPE => User::getAllGroups(),
+ ApiBase :: PARAM_ISMULTI => true
+ ),
+ 'token' => null,
+ 'reason' => array(
+ ApiBase :: PARAM_DFLT => ''
+ )
+ );
+ }
+
+ public function getParamDescription() {
+ return array (
+ 'user' => 'User name',
+ 'add' => 'Add the user to these groups',
+ 'remove' => 'Remove the user from these groups',
+ 'token' => 'A userrights token previously retrieved through list=users',
+ 'reason' => 'Reason for the change',
+ );
+ }
+
+ public function getDescription() {
+ return array(
+ 'Add/remove a user to/from groups',
+ );
+ }
+
+ public function getPossibleErrors() {
+ return array_merge( parent::getPossibleErrors(), array(
+ array( 'missingparam', 'user' ),
+ ) );
+ }
+
+ public function getTokenSalt() {
+ $params = $this->extractRequestParams();
+ if ( is_null( $params['user'] ) )
+ $this->dieUsageMsg( array( 'missingparam', 'user' ) );
+
+ $form = new UserrightsPage;
+ $user = $form->fetchUser( $params['user'] );
+ if ( $user instanceof WikiErrorMsg )
+ $this->dieUsageMsg( array_merge(
+ (array)$user->getMessageKey(), $user->getMessageArgs() ) );
+
+ return $user->getName();
+ }
+
+ protected function getExamples() {
+ return array (
+ 'api.php?action=userrights&user=FooBot&add=bot&remove=sysop|bureaucrat&token=123ABC'
+ );
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id: ApiUserrights.php 62686 2010-02-19 01:25:57Z reedy $';
+ }
+}
diff --git a/includes/api/ApiWatch.php b/includes/api/ApiWatch.php
index 7901b6ac..391d91e2 100644
--- a/includes/api/ApiWatch.php
+++ b/includes/api/ApiWatch.php
@@ -23,9 +23,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-if (!defined('MEDIAWIKI')) {
+if ( !defined( 'MEDIAWIKI' ) ) {
// Eclipse helper - will be ignored in production
- require_once ('ApiBase.php');
+ require_once ( 'ApiBase.php' );
}
/**
@@ -35,21 +35,25 @@ if (!defined('MEDIAWIKI')) {
*/
class ApiWatch extends ApiBase {
- public function __construct($main, $action) {
- parent :: __construct($main, $action);
+ public function __construct( $main, $action ) {
+ parent :: __construct( $main, $action );
}
public function execute() {
global $wgUser;
- if(!$wgUser->isLoggedIn())
- $this->dieUsage('You must be logged-in to have a watchlist', 'notloggedin');
+ if ( !$wgUser->isLoggedIn() )
+ $this->dieUsage( 'You must be logged-in to have a watchlist', 'notloggedin' );
+
$params = $this->extractRequestParams();
- $title = Title::newFromText($params['title']);
- if(!$title)
- $this->dieUsageMsg(array('invalidtitle', $params['title']));
- $article = new Article($title);
- $res = array('title' => $title->getPrefixedText());
- if($params['unwatch'])
+ $title = Title::newFromText( $params['title'] );
+
+ if ( !$title )
+ $this->dieUsageMsg( array( 'invalidtitle', $params['title'] ) );
+
+ $article = new Article( $title );
+ $res = array( 'title' => $title->getPrefixedText() );
+
+ if ( $params['unwatch'] )
{
$res['unwatched'] = '';
$success = $article->doUnwatch();
@@ -59,14 +63,14 @@ class ApiWatch extends ApiBase {
$res['watched'] = '';
$success = $article->doWatch();
}
- if(!$success)
- $this->dieUsageMsg(array('hookaborted'));
- $this->getResult()->addValue(null, $this->getModuleName(), $res);
+ if ( !$success )
+ $this->dieUsageMsg( array( 'hookaborted' ) );
+ $this->getResult()->addValue( null, $this->getModuleName(), $res );
}
public function isWriteMode() {
return true;
- }
+ }
public function getAllowedParams() {
return array (
@@ -87,6 +91,14 @@ class ApiWatch extends ApiBase {
'Add or remove a page from/to the current user\'s watchlist'
);
}
+
+ public function getPossibleErrors() {
+ return array_merge( parent::getPossibleErrors(), array(
+ array( 'code' => 'notloggedin', 'info' => 'You must be logged-in to have a watchlist' ),
+ array( 'invalidtitle', 'title' ),
+ array( 'hookaborted' ),
+ ) );
+ }
protected function getExamples() {
return array(
@@ -96,6 +108,6 @@ class ApiWatch extends ApiBase {
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiWatch.php 69579 2010-07-20 02:49:55Z tstarling $';
+ return __CLASS__ . ': $Id: ApiWatch.php 69578 2010-07-20 02:46:20Z tstarling $';
}
}