5 * Created on Oct 16, 2006
7 * API for MediaWiki 1.8+
9 * Copyright (C) 2006 Yuri Astrakhan <FirstnameLastname@gmail.com>
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 * http://www.gnu.org/copyleft/gpl.html
27 if (!defined('MEDIAWIKI')) {
28 // Eclipse helper - will be ignored in production
29 require_once ("ApiQueryBase.php");
32 class ApiQueryBacklinks
extends ApiQueryGeneratorBase
{
36 public function __construct($query, $moduleName) {
37 parent
:: __construct($query, $moduleName, 'bl');
40 public function execute() {
44 public function executeGenerator($resultPageSet) {
45 $this->run($resultPageSet);
48 private function run($resultPageSet = null) {
49 $continue = $namespace = $redirect = $limit = null;
50 extract($this->extractRequestParams());
53 $this->dieDebug('Redirect is not yet been implemented', 'notimplemented');
55 $this->processContinue($continue, $redirect);
57 if (is_null($resultPageSet)) {
58 $this->addFields( array (
64 $this->addFields( $resultPageSet->getPageTableFields());
67 $this->addTables(array (
71 $this->addWhere('pl_from=page_id');
73 $this->addWhereFld('pl_namespace', $this->rootTitle
->getNamespace());
74 $this->addWhereFld('pl_title', $this->rootTitle
->getDBkey());
75 $this->addWhereFld('page_namespace', $namespace);
76 $this->addOption('LIMIT', $limit +
1);
77 $this->addOption('ORDER BY', 'page_namespace, page_title');
80 $this->addWhereFld('page_is_redirect', 0);
82 $db = & $this->getDB();
83 if(!is_null($this->fromTitle
)) {
84 $ns = $this->fromTitle
->getNamespace();
85 $t = $db->addQuotes($this->fromTitle
->getDBkey());
86 $this->addWhere("(page_namespace>$ns OR (page_namespace=$ns AND page_title>=$t))");
89 $res = $this->select(__METHOD__
);
93 while ($row = $db->fetchObject($res)) {
94 if (++
$count > $limit) {
95 // We've reached the one extra which shows that there are additional pages to be had. Stop here...
96 $continue = $this->rootTitle
->getNamespace() . '|' . $this->rootTitle
->getDBkey() . '|1|0|' . $row->page_namespace
. '|' . $row->page_title
;
97 $this->setContinueEnumParameter('continue', $continue);
101 if (is_null($resultPageSet)) {
102 $vals = $this->addRowInfo('page', $row);
104 $data[intval($row->page_id
)] = $vals;
106 $resultPageSet->processDbRow($row);
109 $db->freeResult($res);
111 if (is_null($resultPageSet)) {
112 $result = $this->getResult();
113 $result->setIndexedTagName($data, 'bl');
114 $result->addValue('query', $this->getModuleName(), $data);
118 protected function processContinue($continue, $redirect) {
119 $pageSet = $this->getPageSet();
120 $count = $pageSet->getGoodTitleCount();
121 if (!is_null($continue)) {
123 $this->dieUsage('When continuing the backlink query, no other titles may be provided', 'titles_on_continue');
124 $this->parseContinueParam($continue, $redirect);
126 // Skip all completed links
127 $db = & $this->getDB();
131 $this->dieUsage('Backlinks requires one title to start the query', 'bad_title_count');
132 $this->rootTitle
= array_pop($pageSet->getGoodTitles()); // only one title there
133 $this->contFromRedirs
= false;
134 $this->contFromLevel
= 0;
135 // $this->contFromPageId = 0;
136 $this->fromTitle
= null;
140 protected function parseContinueParam($continue, $redirect) {
142 // the parameter will be in the format:
143 // ns|db_key|step|level|ns|db_key
144 // ns+db_key -- the root title
145 // step = 1 or 2 - which step to continue from - 1-titles, 2-redirects
146 // level -- how many levels to follow before starting enumerating.
147 // ns+title to continue from
149 $continueList = explode('|', $continue);
150 if (count($continueList) === 6) {
151 $rootNs = intval($continueList[0]);
152 if (($rootNs !== 0 ||
$continueList[0] === '0') && !empty ($continueList[1])) {
153 $this->rootTitle
= Title
:: makeTitleSafe($rootNs, $continueList[1]);
154 if ($this->rootTitle
&& $this->rootTitle
->userCanRead()) {
156 $step = intval($continueList[2]);
157 if ($step === 1 ||
$step === 2) {
158 $this->continueRedirs
= ($step === 2);
160 $level = intval($continueList[3]);
161 if ($level !== 0 ||
$continueList[3] === '0') {
162 $this->continueLevel
= $level;
164 // $pageid = intval($continueList[4]);
165 // if ($pageid !== 0 || $continueList[4] === '0') {
166 // $this->continuePageId = $pageid;
168 $fromNs = intval($continueList[4]);
169 if (($fromNs !== 0 ||
$continueList[4] === '0') && !empty ($continueList[5])) {
170 $this->fromTitle
= Title
:: makeTitleSafe($fromNs, $continueList[5]);
172 // When not processing redirects, only page through the non-redirects
173 // if ($redirect || ($step === 1 && $level === 0 && $pageid > 0)) {
175 if ($redirect ||
($step === 1 && $level === 0 && $this->fromTitle
&& $this->fromTitle
->userCanRead())) {
185 $this->dieUsage("Invalid continue param. You should pass the original value returned by the previous query", "_badcontinue");
188 protected function getAllowedParams() {
190 $namespaces = $this->getQuery()->getValidNamespaces();
193 'namespace' => array (
194 ApiBase
:: PARAM_ISMULTI
=> true,
195 ApiBase
:: PARAM_TYPE
=> $namespaces
199 ApiBase
:: PARAM_DFLT
=> 10,
200 ApiBase
:: PARAM_TYPE
=> 'limit',
201 ApiBase
:: PARAM_MIN
=> 1,
202 ApiBase
:: PARAM_MAX1
=> ApiBase
:: LIMIT_BIG1
,
203 ApiBase
:: PARAM_MAX2
=> ApiBase
:: LIMIT_BIG2
208 protected function getParamDescription() {
210 'continue' => 'When more results are available, use this to continue.',
211 'namespace' => 'The namespace to enumerate.',
212 'redirect' => 'If linking page is a redirect, find all pages that link to that redirect (not implemented)',
213 'limit' => 'How many total pages to return.'
217 protected function getDescription() {
218 return 'Find all pages that link to the given page';
221 protected function getExamples() {
223 'api.php?action=query&list=backlinks&titles=Main%20Page',
224 'api.php?action=query&generator=backlinks&titles=Main%20Page&prop=info',
229 public function getVersion() {
230 return __CLASS__
. ': $Id$';