From c0012fa277f8a774da19175219b65a13a1a45d2f Mon Sep 17 00:00:00 2001 From: Yuri Astrakhan Date: Wed, 25 Oct 2006 17:16:37 +0000 Subject: [PATCH] API * backlinks (forgot to add) --- includes/api/ApiQueryBacklinks.php | 233 +++++++++++++++++++++++++++++ 1 file changed, 233 insertions(+) create mode 100644 includes/api/ApiQueryBacklinks.php diff --git a/includes/api/ApiQueryBacklinks.php b/includes/api/ApiQueryBacklinks.php new file mode 100644 index 0000000000..714840cd00 --- /dev/null +++ b/includes/api/ApiQueryBacklinks.php @@ -0,0 +1,233 @@ + + * + * 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"); +} + +class ApiQueryBacklinks extends ApiQueryGeneratorBase { + + private $rootTitle; + + public function __construct($query, $moduleName) { + parent :: __construct($query, $moduleName, 'bl'); + } + + public function execute() { + $this->run(); + } + + public function executeGenerator($resultPageSet) { + $this->run($resultPageSet); + } + + private function run($resultPageSet = null) { + $continue = $namespace = $redirect = $limit = null; + extract($this->extractRequestParams()); + + if ($redirect) + $this->dieDebug('Redirect is not yet been implemented', 'notimplemented'); + + $this->processContinue($continue, $redirect); + + if (is_null($resultPageSet)) { + $this->addFields( array ( + 'page_id', + 'page_namespace', + 'page_title' + )); + } else { + $this->addFields( $resultPageSet->getPageTableFields()); + } + + $this->addTables(array ( + 'pagelinks', + 'page' + )); + $this->addWhere('pl_from=page_id'); + + $this->addWhereFld('pl_namespace', $this->rootTitle->getNamespace()); + $this->addWhereFld('pl_title', $this->rootTitle->getDBkey()); + $this->addWhereFld('page_namespace', $namespace); + $this->addOption('LIMIT', $limit +1); + $this->addOption('ORDER BY', 'page_namespace, page_title'); + + if ($redirect) + $this->addWhereFld('page_is_redirect', 0); + + $db = & $this->getDB(); + if(!is_null($this->fromTitle)) { + $ns = $this->fromTitle->getNamespace(); + $t = $db->addQuotes($this->fromTitle->getDBkey()); + $this->addWhere("(page_namespace>$ns OR (page_namespace=$ns AND page_title>=$t))"); + } + + $res = $this->select(__METHOD__); + + $count = 0; + $data = array (); + 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... + $continue = $this->rootTitle->getNamespace() . '|' . $this->rootTitle->getDBkey() . '|1|0|' . $row->page_namespace . '|' . $row->page_title; + $this->setContinueEnumParameter('continue', $continue); + break; + } + + if (is_null($resultPageSet)) { + $vals = $this->addRowInfo('page', $row); + if ($vals) + $data[intval($row->page_id)] = $vals; + } else { + $resultPageSet->processDbRow($row); + } + } + $db->freeResult($res); + + if (is_null($resultPageSet)) { + $result = $this->getResult(); + $result->setIndexedTagName($data, 'bl'); + $result->addValue('query', $this->getModuleName(), $data); + } + } + + protected function processContinue($continue, $redirect) { + $pageSet = $this->getPageSet(); + $count = $pageSet->getGoodTitleCount(); + if (!is_null($continue)) { + if ($count !== 0) + $this->dieUsage('When continuing the backlink query, no other titles may be provided', 'titles_on_continue'); + $this->parseContinueParam($continue, $redirect); + + // Skip all completed links + $db = & $this->getDB(); + + } else { + if ($count !== 1) + $this->dieUsage('Backlinks requires one title to start the query', 'bad_title_count'); + $this->rootTitle = array_pop($pageSet->getGoodTitles()); // only one title there + $this->contFromRedirs = false; + $this->contFromLevel = 0; + // $this->contFromPageId = 0; + $this->fromTitle = null; + } + } + + protected function parseContinueParam($continue, $redirect) { + // + // the parameter will be in the format: + // ns|db_key|step|level|ns|db_key + // ns+db_key -- the root title + // step = 1 or 2 - which step to continue from - 1-titles, 2-redirects + // level -- how many levels to follow before starting enumerating. + // ns+title to continue from + // + $continueList = explode('|', $continue); + if (count($continueList) === 6) { + $rootNs = intval($continueList[0]); + if (($rootNs !== 0 || $continueList[0] === '0') && !empty ($continueList[1])) { + $this->rootTitle = Title :: makeTitleSafe($rootNs, $continueList[1]); + if ($this->rootTitle && $this->rootTitle->userCanRead()) { + + $step = intval($continueList[2]); + if ($step === 1 || $step === 2) { + $this->continueRedirs = ($step === 2); + + $level = intval($continueList[3]); + if ($level !== 0 || $continueList[3] === '0') { + $this->continueLevel = $level; + +// $pageid = intval($continueList[4]); +// if ($pageid !== 0 || $continueList[4] === '0') { +// $this->continuePageId = $pageid; + + $fromNs = intval($continueList[4]); + if (($fromNs !== 0 || $continueList[4] === '0') && !empty ($continueList[5])) { + $this->fromTitle = Title :: makeTitleSafe($fromNs, $continueList[5]); + + // When not processing redirects, only page through the non-redirects + // if ($redirect || ($step === 1 && $level === 0 && $pageid > 0)) { + + if ($redirect || ($step === 1 && $level === 0 && $this->fromTitle && $this->fromTitle->userCanRead())) { + return; // done + } + } + } + } + } + } + } + + $this->dieUsage("Invalid continue param. You should pass the original value returned by the previous query", "_badcontinue"); + } + + protected function getAllowedParams() { + + $namespaces = $this->getQuery()->getValidNamespaces(); + return array ( + 'continue' => null, + 'namespace' => array ( + ApiBase :: PARAM_ISMULTI => true, + ApiBase :: PARAM_TYPE => $namespaces + ), + 'redirect' => false, + 'limit' => array ( + ApiBase :: PARAM_DFLT => 10, + ApiBase :: PARAM_TYPE => 'limit', + ApiBase :: PARAM_MIN => 1, + ApiBase :: PARAM_MAX1 => ApiBase :: LIMIT_BIG1, + ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2 + ) + ); + } + + protected function getParamDescription() { + return array ( + 'continue' => 'When more results are available, use this to continue.', + 'namespace' => 'The namespace to enumerate.', + 'redirect' => 'If linking page is a redirect, find all pages that link to that redirect (not implemented)', + 'limit' => 'How many total pages to return.' + ); + } + + protected function getDescription() { + return 'Find all pages that link to the given page'; + } + + protected function getExamples() { + return array ( + 'api.php?action=query&list=backlinks&titles=Main%20Page', + 'api.php?action=query&generator=backlinks&titles=Main%20Page&prop=info', + + ); + } + + public function getVersion() { + return __CLASS__ . ': $Id$'; + } +} +?> \ No newline at end of file -- 2.20.1