From c3fb81f2f898fa0bdd765b58b09b729b490a281a Mon Sep 17 00:00:00 2001 From: Yuri Astrakhan Date: Sat, 7 Jul 2007 09:35:05 +0000 Subject: [PATCH] API: Added list=exturlusage - allows url searches within wiki --- RELEASE-NOTES | 1 + includes/AutoLoader.php | 1 + includes/api/ApiQuery.php | 1 + includes/api/ApiQueryExtLinksUsage.php | 203 +++++++++++++++++++++++++ 4 files changed, 206 insertions(+) create mode 100644 includes/api/ApiQueryExtLinksUsage.php diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 79fdf3f032..601372d5a0 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -307,6 +307,7 @@ Full API documentation is available at http://www.mediawiki.org/wiki/API instead of titles. Titles for these lists is obsolete and might stop working soon. * Added prop=imageinfo - gets image properties and upload history * (bug 10211) Added db server replication lag information in meta=siteinfo +* Added external url search within wiki pages (list=exturlusage) == Maintenance script changes since 1.10 == diff --git a/includes/AutoLoader.php b/includes/AutoLoader.php index ccd2c7a08a..f1e2a3d290 100644 --- a/includes/AutoLoader.php +++ b/includes/AutoLoader.php @@ -313,6 +313,7 @@ function __autoload($className) { 'ApiQueryCategoryMembers' => 'includes/api/ApiQueryCategoryMembers.php', 'ApiQueryContributions' => 'includes/api/ApiQueryUserContributions.php', 'ApiQueryExternalLinks' => 'includes/api/ApiQueryExternalLinks.php', + 'ApiQueryExtLinksUsage' => 'includes/api/ApiQueryExtLinksUsage.php', 'ApiQueryImages' => 'includes/api/ApiQueryImages.php', 'ApiQueryImageInfo' => 'includes/api/ApiQueryImageInfo.php', 'ApiQueryInfo' => 'includes/api/ApiQueryInfo.php', diff --git a/includes/api/ApiQuery.php b/includes/api/ApiQuery.php index 5168e04e7f..82e2b1dc5f 100644 --- a/includes/api/ApiQuery.php +++ b/includes/api/ApiQuery.php @@ -68,6 +68,7 @@ class ApiQuery extends ApiBase { 'usercontribs' => 'ApiQueryContributions', 'watchlist' => 'ApiQueryWatchlist', // 'users' => 'ApiQueryUsers', + 'exturlusage' => 'ApiQueryExtLinksUsage', ); private $mQueryMetaModules = array ( diff --git a/includes/api/ApiQueryExtLinksUsage.php b/includes/api/ApiQueryExtLinksUsage.php new file mode 100644 index 0000000000..5ce92221c4 --- /dev/null +++ b/includes/api/ApiQueryExtLinksUsage.php @@ -0,0 +1,203 @@ +@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 ApiQueryExtLinksUsage extends ApiQueryGeneratorBase { + + public function __construct($query, $moduleName) { + parent :: __construct($query, $moduleName, 'eu'); + } + + public function execute() { + $this->run(); + } + + public function executeGenerator($resultPageSet) { + $this->run($resultPageSet); + } + + private function run($resultPageSet = null) { + + $params = $this->extractRequestParams(); + + $protocol = $params['protocol']; + $query = $params['query']; + if (is_null($query)) + $this->dieUsage('Missing required query parameter', 'params'); + + // Find the right prefix + global $wgUrlProtocols; + foreach ($wgUrlProtocols as $p) { + if( substr( $p, 0, strlen( $protocol ) ) === $protocol ) { + $protocol = $p; + break; + } + } + + $likeQuery = LinkFilter::makeLike($query , $protocol); + if (!$likeQuery) + $this->dieUsage('Invalid query', 'bad_query'); + $likeQuery = substr($likeQuery, 0, strpos($likeQuery,'%')+1); + + $this->addTables(array('page','externallinks')); // must be in this order for 'USE INDEX' + $this->addOption('USE INDEX', 'el_index'); + + $db = $this->getDB(); + $this->addWhere('page_id=el_from'); + $this->addWhere('el_index LIKE ' . $db->addQuotes( $likeQuery )); + $this->addWhereFld('page_namespace', $params['namespace']); + + $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 ( + 'page_id', + 'page_namespace', + 'page_title' + )); + $this->addFieldsIf('el_to', $fld_url); + } else { + $this->addFields($resultPageSet->getPageTableFields()); + } + + $limit = $params['limit']; + $offset = $params['offset']; + $this->addOption('LIMIT', $limit +1); + if (isset ($offset)) + $this->addOption('OFFSET', $offset); + + $res = $this->select(__METHOD__); + + $data = array (); + $count = 0; + 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+1); + break; + } + + if (is_null($resultPageSet)) { + $title = Title :: makeTitle($row->page_namespace, $row->page_title); + if ($title->userCanRead()) { + $vals = array(); + if ($fld_ids) + $vals['pageid'] = intval($row->page_id); + if ($fld_title) { + $vals['ns'] = intval($title->getNamespace()); + $vals['title'] = $title->getPrefixedText(); + } + if ($fld_url) + $vals['url'] = $row->el_to; + $data[] = $vals; + } + } else { + $resultPageSet->processDbRow($row); + } + } + $db->freeResult($res); + + if (is_null($resultPageSet)) { + $result = $this->getResult(); + $result->setIndexedTagName($data, 'p'); + $result->addValue('query', $this->getModuleName(), $data); + } + } + + protected function getAllowedParams() { + global $wgUrlProtocols; + $protocols = array(); + foreach ($wgUrlProtocols as $p) { + $protocols[] = substr($p, 0, strpos($p,':')); + } + + return array ( + 'prop' => array ( + ApiBase :: PARAM_ISMULTI => true, + ApiBase :: PARAM_DFLT => 'ids|title|url', + ApiBase :: PARAM_TYPE => array ( + 'ids', + 'title', + 'url' + ) + ), + 'offset' => array ( + ApiBase :: PARAM_TYPE => 'integer' + ), + 'protocol' => array ( + ApiBase :: PARAM_TYPE => $protocols, + ApiBase :: PARAM_DFLT => 'http', + ), + 'query' => null, + 'namespace' => array ( + ApiBase :: PARAM_ISMULTI => true, + ApiBase :: PARAM_TYPE => 'namespace' + ), + '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 + ) + ); + } + + protected function getParamDescription() { + return array ( + 'prop' => 'What pieces of information to include', + 'offset' => 'Used for paging. Use the value returned for "continue"', + 'protocol' => 'Protocol of the url', + 'query' => 'Search string without protocol. See [[Special:LinkSearch]]', + 'namespace' => 'The page namespace(s) to enumerate.', + 'limit' => 'How many entries to return.' + ); + } + + protected function getDescription() { + return 'Enumerate pages that contain a given URL'; + } + + protected function getExamples() { + return array ( + 'api.php?action=query&list=exturlusage&euquery=www.mediawiki.org' + ); + } + + public function getVersion() { + return __CLASS__ . ': $Id:$'; + } +} +?> -- 2.20.1