* Bulk mail options ($wgEnotifImpersonal, $wgEnotifUseJobQ) for large sites
* Links to redirect pages in categories are wrapped in <span
class="redirect-in-category"></span>
-
+
== Bugfixes since 1.10 ==
* (bug 9712) Use Arabic comma in date/time formats for Arabic and Farsi
* (bug 9896) Documentation for $wgSquidServers and X-FORWARDED-FOR
+== MediaWiki API changes since 1.10 ==
+
+For the current progress and discussion, see http://meta.wikimedia.org/wiki/API
+
+* New properties: links, templates, images, langlinks
+* Breaking Change: imagelinks renamed into imageusage (il->iu)
+* Bug fix: incorrect generator behavior in some cases
+
+
== Maintenance script changes since 1.10 ==
* Add support for wgMaxTocLevel option in parserTests
'ApiQueryBase' => 'includes/api/ApiQueryBase.php',
'ApiQueryBacklinks' => 'includes/api/ApiQueryBacklinks.php',
'ApiQueryContributions' => 'includes/api/ApiQueryUserContributions.php',
+ 'ApiQueryImages' => 'includes/api/ApiQueryImages.php',
'ApiQueryInfo' => 'includes/api/ApiQueryInfo.php',
+ 'ApiQueryLangLinks' => 'includes/api/ApiQueryLangLinks.php',
+ 'ApiQueryLinks' => 'includes/api/ApiQueryLinks.php',
'ApiQueryLogEvents' => 'includes/api/ApiQueryLogEvents.php',
'ApiQueryRecentChanges'=> 'includes/api/ApiQueryRecentChanges.php',
'ApiQueryRevisions' => 'includes/api/ApiQueryRevisions.php',
ApiBase :: dieDebug(__METHOD__, 'called without calling profileDBOut() first');
return $this->mDBTime;
}
+
+ public static function debugPrint($value, $name = 'unknown') {
+ print "\n\n<pre><b>Debuging value '$location':</b>\n\n";
+ var_export($value);
+ print "\n</pre>\n";
+ }
public abstract function getVersion();
private static $Modules = array (
'help' => 'ApiHelp',
'login' => 'ApiLogin',
+ 'query' => 'ApiQuery',
'opensearch' => 'ApiOpenSearch',
- 'feedwatchlist' => 'ApiFeedWatchlist',
- 'query' => 'ApiQuery'
+ 'feedwatchlist' => 'ApiFeedWatchlist'
);
/**
private function initFromTitles($titles) {
// Get validated and normalized title objects
- $linkBatch = $this->processTitlesStrArray($titles);
+ $linkBatch = $this->processTitlesArray($titles);
if($linkBatch->isEmpty())
return;
*
* @return LinkBatch of title objects.
*/
- private function processTitlesStrArray($titles) {
+ private function processTitlesArray($titles) {
$linkBatch = new LinkBatch();
- foreach ($titles as $titleString) {
- $titleObj = Title :: newFromText($titleString);
+ foreach ($titles as $title) {
+
+ $titleObj = is_string($title) ? Title :: newFromText($title) : $title;
// Validation
if (!$titleObj)
// Make sure we remember the original title that was given to us
// This way the caller can correlate new titles with the originally requested,
// i.e. namespace is localized or capitalization is different
- if ($titleString !== $titleObj->getPrefixedText()) {
- $this->mNormalizedTitles[$titleString] = $titleObj->getPrefixedText();
+ if (is_string($title) && $title !== $titleObj->getPrefixedText()) {
+ $this->mNormalizedTitles[$title] = $titleObj->getPrefixedText();
}
}
return $linkBatch;
}
+
+ public static function debugPrint($name = 'unknown') {
+ ApiBase::debugPrint($this->mAllPages, $name);
+ }
protected function getAllowedParams() {
return array (
private $mQueryPropModules = array (
'info' => 'ApiQueryInfo',
- 'revisions' => 'ApiQueryRevisions'
+ 'revisions' => 'ApiQueryRevisions',
+ 'links' => 'ApiQueryLinks',
+ 'langlinks' => 'ApiQueryLangLinks',
+ 'images' => 'ApiQueryImages',
+ 'templates' => 'ApiQueryLinks',
);
// 'categories' => 'ApiQueryCategories',
// 'imageinfo' => 'ApiQueryImageinfo',
- // 'langlinks' => 'ApiQueryLanglinks',
- // 'links' => 'ApiQueryLinks',
// 'templates' => 'ApiQueryTemplates',
private $mQueryListModules = array (
'recentchanges' => 'ApiQueryRecentChanges',
'backlinks' => 'ApiQueryBacklinks',
'embeddedin' => 'ApiQueryBacklinks',
- 'imagelinks' => 'ApiQueryBacklinks',
+ 'imageusage' => 'ApiQueryBacklinks',
'usercontribs' => 'ApiQueryContributions'
);
// 'categorymembers' => 'ApiQueryCategorymembers',
- // 'embeddedin' => 'ApiQueryEmbeddedin',
- // 'imagelinks' => 'ApiQueryImagelinks',
// 'recentchanges' => 'ApiQueryRecentchanges',
// 'users' => 'ApiQueryUsers',
// 'watchlist' => 'ApiQueryWatchlist',
}
//
- // If given, execute generator to substitute user supplied data with generated data.
+ // Populate page information for the given pageSet
//
- if (isset ($generator))
- $this->executeGeneratorModule($generator, $redirects);
+ $this->mPageSet->execute();
//
- // Populate page information for the given pageSet
+ // If given, execute generator to substitute user supplied data with generated data.
//
- $this->mPageSet->execute();
+ if (isset ($generator))
+ $this->executeGeneratorModule($generator, $redirects);
//
// Record page information (title, namespace, if exists, etc)
ApiBase :: dieDebug(__METHOD__, "Unknown generator=$generatorName");
}
- // Use current pageset as the result, and create a new one just for the generator
- $resultPageSet = $this->mPageSet;
- $this->mPageSet = new ApiPageSet($this, $redirects);
+ // Generator results
+ $resultPageSet = new ApiPageSet($this, $redirects);
// Create and execute the generator
$generator = new $className ($this, $generatorName);
$generator->setGeneratorMode();
$generator->requestExtraData();
- // execute current pageSet to get the data for the generator module
- $this->mPageSet->execute();
-
// populate resultPageSet with the generator output
$generator->profileIn();
$generator->executeGenerator($resultPageSet);
'prefix' => 'tl',
'linktbl' => 'templatelinks'
),
- 'imagelinks' => array (
- 'code' => 'il',
+ 'imageusage' => array (
+ 'code' => 'iu',
'prefix' => 'il',
'linktbl' => 'imagelinks'
)
);
$this->bl_code = $code;
- $this->hasNS = $moduleName !== 'imagelinks';
+ $this->hasNS = $moduleName !== 'imageusage';
if ($this->hasNS) {
$this->bl_title = $prefix . '_title';
$this->bl_sort = "{$this->bl_ns}, {$this->bl_title}, {$this->bl_from}";
extract($this->extractRequestParams());
if ($redirect)
- ApiBase :: dieDebug(__METHOD__, 'Redirect is not yet been implemented', 'notimplemented');
+ ApiBase :: dieDebug(__METHOD__, 'Redirect has not been implemented', 'notimplemented');
$this->processContinue($continue, $redirect);
return 'Find all pages that link to the given page';
case 'embeddedin' :
return 'Find all pages that embed (transclude) the given title';
- case 'imagelinks' :
+ case 'imageusage' :
return 'Find all pages that use the given image title.';
default :
ApiBase :: dieDebug(__METHOD__, 'Unknown module name');
"api.php?action=query&list=embeddedin&titles=Template:Stub",
"api.php?action=query&generator=embeddedin&titles=Template:Stub&prop=info"
),
- 'imagelinks' => array (
- "api.php?action=query&list=imagelinks&titles=Image:Albert%20Einstein%20Head.jpg",
- "api.php?action=query&generator=imagelinks&titles=Image:Albert%20Einstein%20Head.jpg&prop=info"
+ 'imageusage' => array (
+ "api.php?action=query&list=imageusage&titles=Image:Albert%20Einstein%20Head.jpg",
+ "api.php?action=query&generator=imageusage&titles=Image:Albert%20Einstein%20Head.jpg&prop=info"
)
);
// Title
$title = ApiQueryBase :: addRowInfo_title($row, $prefix . '_namespace', $prefix . '_title');
- if ($title) {
- if (!$title->userCanRead())
- return false;
- $vals['ns'] = $title->getNamespace();
- $vals['title'] = $title->getPrefixedText();
- }
+ if ($title)
+ ApiQueryBase :: addTitleInfo($vals, $title);
switch ($prefix) {
return $vals;
}
+ protected static function addTitleInfo(&$arr, $title) {
+ $arr['ns'] = $title->getNamespace();
+ $arr['title'] = $title->getPrefixedText();
+ }
+
private static function addRowInfo_title($row, $nsfld, $titlefld) {
if ( isset( $row-> $nsfld ) ) {
$ns = $row-> $nsfld;
--- /dev/null
+<?php
+
+/*
+ * Created on May 13, 2007
+ *
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2006 Yuri Astrakhan <FirstnameLastname@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 ("ApiQueryBase.php");
+}
+
+/**
+ * @addtogroup API
+ */
+class ApiQueryImages extends ApiQueryGeneratorBase {
+
+ public function __construct($query, $moduleName) {
+ parent :: __construct($query, $moduleName, 'im');
+ }
+
+ public function execute() {
+ $this->run();
+ }
+
+ public function executeGenerator($resultPageSet) {
+ $this->run($resultPageSet);
+ }
+
+ private function run($resultPageSet = null) {
+
+ $this->addFields(array (
+ 'il_from',
+ 'il_to'
+ ));
+
+ $this->addTables('imagelinks');
+ $this->addWhereFld('il_from', array_keys($this->getPageSet()->getGoodTitles()));
+ $this->addOption('ORDER BY', "il_from, il_to");
+
+ $db = $this->getDB();
+ $res = $this->select(__METHOD__);
+
+ if (is_null($resultPageSet)) {
+
+ $data = array();
+ $lastId = 0; // database has no ID 0
+ while ($row = $db->fetchObject($res)) {
+ if ($lastId != $row->il_from) {
+ if($lastId != 0) {
+ $this->addPageSubItems($lastId, $data);
+ $data = array();
+ }
+ $lastId = $row->il_from;
+ }
+
+ $entry = array();
+ $title = Title :: makeTitle(NS_IMAGE, $row->il_to);
+ $vals = ApiQueryBase :: addTitleInfo($entry, $title);
+ $data[] = $entry;
+ }
+
+ if($lastId != 0) {
+ $this->addPageSubItems($lastId, $data);
+ }
+
+ } else {
+
+ $titles = array();
+ while ($row = $db->fetchObject($res)) {
+ $titles[] = Title :: makeTitle(NS_IMAGE, $row->il_to);
+ }
+ $resultPageSet->populateFromTitles($titles);
+ }
+
+ $db->freeResult($res);
+ }
+
+ private function addPageSubItems($pageId, $data) {
+ $result = $this->getResult();
+ $result->setIndexedTagName($data, 'i');
+ $result->addValue(array ('query', 'pages', intval($pageId)),
+ 'images',
+ $data);
+ }
+
+ protected function getDescription() {
+ return 'Returns all links from the given page(s)';
+ }
+
+ protected function getExamples() {
+ return array (
+ "Get a list of images used in the [[Main Page]]:",
+ " api.php?action=query&prop=images&titles=Main%20Page",
+ "Get information about all images used in the [[Main Page]]:",
+ " api.php?action=query&generator=images&titles=Main%20Page&prop=info"
+ );
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
+?>
--- /dev/null
+<?php
+
+/*
+ * Created on May 13, 2007
+ *
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2006 Yuri Astrakhan <FirstnameLastname@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 ("ApiQueryBase.php");
+}
+
+/**
+ * @addtogroup API
+ */
+class ApiQueryLangLinks extends ApiQueryBase {
+
+ public function __construct($query, $moduleName) {
+ parent :: __construct($query, $moduleName, 'll');
+ }
+
+ public function execute() {
+ $this->addFields(array (
+ 'll_from',
+ 'll_lang',
+ 'll_title'
+ ));
+
+ $this->addTables('langlinks');
+ $this->addWhereFld('ll_from', array_keys($this->getPageSet()->getGoodTitles()));
+ $this->addOption('ORDER BY', "ll_from, ll_lang");
+ $res = $this->select(__METHOD__);
+
+ $data = array();
+ $lastId = 0; // database has no ID 0
+ $db = $this->getDB();
+ while ($row = $db->fetchObject($res)) {
+
+ if ($lastId != $row->ll_from) {
+ if($lastId != 0) {
+ $this->addPageSubItems($lastId, $data);
+ $data = array();
+ }
+ $lastId = $row->ll_from;
+ }
+
+ $entry = array('lang'=>$row->ll_lang);
+ ApiResult :: setContent($entry, $row->ll_title);
+ $data[] = $entry;
+ }
+
+ if($lastId != 0) {
+ $this->addPageSubItems($lastId, $data);
+ }
+
+ $db->freeResult($res);
+ }
+
+ private function addPageSubItems($pageId, $data) {
+ $result = $this->getResult();
+ $result->setIndexedTagName($data, 'll');
+ $result->addValue(array ('query', 'pages', intval($pageId)),
+ 'langlinks',
+ $data);
+ }
+
+ protected function getDescription() {
+ return 'Returns all interlanguage links from the given page(s)';
+ }
+
+ protected function getExamples() {
+ return array (
+ "Get interlanguage links from the [[Main Page]]:",
+ " api.php?action=query&prop=langlinks&titles=Main%20Page&redirects",
+ );
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
+?>
--- /dev/null
+<?php
+
+/*
+ * Created on May 12, 2007
+ *
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2006 Yuri Astrakhan <FirstnameLastname@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 ("ApiQueryBase.php");
+}
+
+/**
+ * @addtogroup API
+ */
+class ApiQueryLinks extends ApiQueryGeneratorBase {
+
+ const LINKS = 'links';
+ const TEMPLATES = 'templates';
+
+ private $table, $prefix, $description;
+
+ public function __construct($query, $moduleName) {
+
+ switch ($moduleName) {
+ case self::LINKS :
+ $this->table = 'pagelinks';
+ $this->prefix = 'pl';
+ $this->description = 'link';
+ break;
+ case self::TEMPLATES :
+ $this->table = 'templatelinks';
+ $this->prefix = 'tl';
+ $this->description = 'template';
+ break;
+ default :
+ ApiBase :: dieDebug(__METHOD__, 'Unknown module name');
+ }
+
+ parent :: __construct($query, $moduleName, $this->prefix);
+ }
+
+ public function execute() {
+ $this->run();
+ }
+
+ public function executeGenerator($resultPageSet) {
+ $this->run($resultPageSet);
+ }
+
+ private function run($resultPageSet = null) {
+
+ $this->addFields(array (
+ $this->prefix . '_from pl_from',
+ $this->prefix . '_namespace pl_namespace',
+ $this->prefix . '_title pl_title'
+ ));
+
+ $this->addTables($this->table);
+ $this->addWhereFld($this->prefix . '_from', array_keys($this->getPageSet()->getGoodTitles()));
+ $this->addOption('ORDER BY', str_replace('pl_', $this->prefix . '_', 'pl_from, pl_namespace, pl_title'));
+
+ $db = $this->getDB();
+ $res = $this->select(__METHOD__);
+
+ if (is_null($resultPageSet)) {
+
+ $data = array();
+ $lastId = 0; // database has no ID 0
+ while ($row = $db->fetchObject($res)) {
+ if ($lastId != $row->pl_from) {
+ if($lastId != 0) {
+ $this->addPageSubItems($lastId, $data);
+ $data = array();
+ }
+ $lastId = $row->pl_from;
+ }
+ $vals = $this->addRowInfo('pl', $row);
+ if ($vals)
+ $data[] = $vals;
+ }
+
+ if($lastId != 0) {
+ $this->addPageSubItems($lastId, $data);
+ }
+
+ } else {
+
+ $titles = array();
+ while ($row = $db->fetchObject($res)) {
+ $titles[] = Title :: makeTitle($row->pl_namespace, $row->pl_title);
+ }
+ $resultPageSet->populateFromTitles($titles);
+ }
+
+ $db->freeResult($res);
+ }
+
+ private function addPageSubItems($pageId, $data) {
+ $result = $this->getResult();
+ $result->setIndexedTagName($data, $this->prefix);
+ $result->addValue(array ('query', 'pages', intval($pageId)),
+ $this->getModuleName(),
+ $data);
+ }
+
+ protected function getDescription() {
+ return "Returns all {$this->description}s from the given page(s)";
+ }
+
+ protected function getExamples() {
+ return array (
+ "Get {$this->description}s from the [[Main Page]]:",
+ " api.php?action=query&prop={$this->getModuleName()}&titles=Main%20Page",
+ "Get information about the {$this->description} pages in the [[Main Page]]:",
+ " api.php?action=query&generator={$this->getModuleName()}&titles=Main%20Page&prop=info"
+ );
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
+?>