+Add BrokenRedirects and DoubleRedirects API script for bot development.
authorAlex Shih-Han Lin <alexsh@users.mediawiki.org>
Thu, 23 Jul 2009 16:25:31 +0000 (16:25 +0000)
committerAlex Shih-Han Lin <alexsh@users.mediawiki.org>
Thu, 23 Jul 2009 16:25:31 +0000 (16:25 +0000)
includes/AutoLoader.php
includes/api/ApiQuery.php
includes/api/ApiQueryBrokenRedirects.php [new file with mode: 0644]
includes/api/ApiQueryDoubleRedirects.php [new file with mode: 0644]

index 180beeb..97aa525 100644 (file)
@@ -295,12 +295,14 @@ $wgAutoloadLocalClasses = array(
        'ApiQueryBacklinks' => 'includes/api/ApiQueryBacklinks.php',
        'ApiQueryBase' => 'includes/api/ApiQueryBase.php',
        'ApiQueryBlocks' => 'includes/api/ApiQueryBlocks.php',
+       'ApiQueryBrokenRedirects' => 'includes/api/ApiQueryBrokenRedirects.php',
        'ApiQueryCategories' => 'includes/api/ApiQueryCategories.php',
        'ApiQueryCategoryInfo' => 'includes/api/ApiQueryCategoryInfo.php',
        'ApiQueryCategoryMembers' => 'includes/api/ApiQueryCategoryMembers.php',
        'ApiQueryContributions' => 'includes/api/ApiQueryUserContributions.php',
        'ApiQueryDeletedrevs' => 'includes/api/ApiQueryDeletedrevs.php',
        'ApiQueryDisabled' => 'includes/api/ApiQueryDisabled.php',
+       'ApiQueryDoubleRedirects' => 'includes/api/ApiQueryDoubleRedirects.php',
        'ApiQueryDuplicateFiles' => 'includes/api/ApiQueryDuplicateFiles.php',
        'ApiQueryExtLinksUsage' => 'includes/api/ApiQueryExtLinksUsage.php',
        'ApiQueryExternalLinks' => 'includes/api/ApiQueryExternalLinks.php',
index e3719e0..9e526a4 100644 (file)
@@ -67,7 +67,9 @@ class ApiQuery extends ApiBase {
                'allusers' => 'ApiQueryAllUsers',
                'backlinks' => 'ApiQueryBacklinks',
                'blocks' => 'ApiQueryBlocks',
+        'brokenredirects' => 'ApiQueryBrokenRedirects',
                'categorymembers' => 'ApiQueryCategoryMembers',
+        'doubleredirects' => 'ApiQueryDoubleRedirects',
                'deletedrevs' => 'ApiQueryDeletedrevs',
                'embeddedin' => 'ApiQueryBacklinks',
                'imageusage' => 'ApiQueryBacklinks',
diff --git a/includes/api/ApiQueryBrokenRedirects.php b/includes/api/ApiQueryBrokenRedirects.php
new file mode 100644 (file)
index 0000000..bcc7b00
--- /dev/null
@@ -0,0 +1,149 @@
+<?php\r
+\r
+/*\r
+ * Created on Sep 25, 2006\r
+ *\r
+ * API for MediaWiki 1.8+\r
+ *\r
+ * Copyright (C) 2006 Yuri Astrakhan <Firstname><Lastname>@gmail.com\r
+ *\r
+ * This program is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License along\r
+ * with this program; if not, write to the Free Software Foundation, Inc.,\r
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\r
+ * http://www.gnu.org/copyleft/gpl.html\r
+ */\r
+\r
+if (!defined('MEDIAWIKI')) {\r
+       // Eclipse helper - will be ignored in production\r
+       require_once ('ApiQueryBase.php');\r
+}\r
+\r
+/**\r
+ * Query module to enumerate all available pages.\r
+ *\r
+ * @ingroup API\r
+ */\r
+class ApiQueryBrokenRedirects extends ApiQueryGeneratorBase {\r
+       public function __construct($query, $moduleName) {\r
+               parent :: __construct($query, $moduleName, 'br');\r
+       }\r
+\r
+       public function execute() {\r
+               $this->run();\r
+       }\r
+\r
+       public function executeGenerator($resultPageSet) {\r
+               if ($resultPageSet->isResolvingRedirects())\r
+                       $this->dieUsage('Use "gapfilterredir=nonredirects" option instead of "redirects" when using allpages as a generator', 'params');\r
+\r
+               $this->run($resultPageSet);\r
+       }\r
+\r
+       private function run($resultPageSet = null) {\r
+               $db = $this->getDB();\r
+               $params = $this->extractRequestParams();\r
+               list( $page, $redirect ) = $db->tableNamesN( 'page', 'redirect' );\r
+               \r
+               $this->addFields( array(\r
+                       "'BrokenRedirects' AS type",\r
+                       "p1.page_namespace AS namespace",\r
+                       "p1.page_title AS title",\r
+                       "p1.page_id AS pageid",\r
+                       "rd_namespace",\r
+                       "rd_title",\r
+               ));\r
+               $this->addTables("redirect AS rd JOIN page p1 ON (rd.rd_from=p1.page_id) LEFT JOIN page AS p2 ON (rd_namespace=p2.page_namespace AND rd_title=p2.page_title )");\r
+               # I don't know why these two not work ~~Alexsh\r
+               #$this->addJoinConds(array("$page AS p1" => array('JOIN', 'rd.rd_from=p1.page_id')));\r
+               #$this->addJoinConds(array("$page AS p2" => array('LEFT JOIN', 'rd_namespace=p2.page_namespace AND rd_title=p2.page_title')));\r
+               $this->addWhere( array(\r
+                       "rd_namespace >= 0",\r
+                       "p2.page_namespace IS NULL",\r
+               ));\r
+\r
+               $limit = $params['limit'];\r
+               $this->addOption('LIMIT', $limit+1);\r
+               if(!is_null($params['offset']))\r
+                       $this->addOption('OFFSET', $params['offset']);\r
+               \r
+               $res = $this->select(__METHOD__);\r
+               $result = $this->getResult();\r
+               $count = 0;\r
+               while ($row = $db->fetchObject($res)) {\r
+                       if (++ $count > $limit) {\r
+                               // We've reached the one extra which shows that there are additional pages to be had. Stop here...\r
+                               // TODO: Security issue - if the user has no right to view next title, it will still be shown\r
+                               $this->setContinueEnumParameter('offset', @$params['offset'] + $params['limit']);\r
+                               break;\r
+                       }\r
+                       if (is_null($resultPageSet)) {\r
+                               $title = Title :: makeTitle($row->page_namespace, $row->title);\r
+                               $rdtitle = Title :: makeTitle($row->page_namespace, $row->rd_title);\r
+                               $vals = array(\r
+                                       'pageid' => intval($row->pageid),\r
+                                       'ns' => intval($row->namespace),\r
+                                       'title' => $title->getPrefixedText(),\r
+                                       'target' => $rdtitle->getPrefixedText()\r
+                               );\r
+                               $fit = $result->addValue(array('query', $this->getModuleName()), null, $vals);\r
+                               if(!$fit)\r
+                               {\r
+                                       $this->setContinueEnumParameter('offset', @$params['offset'] + $count - 1);\r
+                                       break;\r
+                               }\r
+                       } else {\r
+                               $resultPageSet->processDbRow($row);\r
+                       }\r
+               }\r
+               $db->freeResult($res);\r
+\r
+               if (is_null($resultPageSet)) {\r
+                       $result->setIndexedTagName_internal(array('query', $this->getModuleName()), 'p');\r
+               }\r
+       }\r
+\r
+       public function getAllowedParams() {\r
+               return array (\r
+                       'limit' => array(\r
+                               ApiBase :: PARAM_DFLT => 10,\r
+                               ApiBase :: PARAM_TYPE => 'limit',\r
+                               ApiBase :: PARAM_MIN => 1,\r
+                               ApiBase :: PARAM_MAX => ApiBase :: LIMIT_BIG1,\r
+                               ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2\r
+                       ),\r
+                       'offset' => null,\r
+               );\r
+       }\r
+\r
+       public function getParamDescription() {\r
+               return array(\r
+                       'limit' => 'How many links to return',\r
+                       'offset' => 'When more results are available, use this to continue',\r
+               );\r
+       }\r
+\r
+       public function getDescription() {\r
+               return 'Enumerate all broken redirects';\r
+       }\r
+\r
+       protected function getExamples() {\r
+               return array (\r
+                       'api.php?action=query&list=brokenredirects',\r
+               );\r
+       }\r
+\r
+       public function getVersion() {\r
+               return __CLASS__ . ': $Id: ApiQueryBrokenRedirects.php 46845 2009-07-23 14:00:00Z alexsh $';\r
+       }\r
+\r
+}
\ No newline at end of file
diff --git a/includes/api/ApiQueryDoubleRedirects.php b/includes/api/ApiQueryDoubleRedirects.php
new file mode 100644 (file)
index 0000000..1f34018
--- /dev/null
@@ -0,0 +1,163 @@
+<?php\r
+\r
+/*\r
+ * Created on Sep 25, 2006\r
+ *\r
+ * API for MediaWiki 1.8+\r
+ *\r
+ * Copyright (C) 2006 Yuri Astrakhan <Firstname><Lastname>@gmail.com\r
+ *\r
+ * This program is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License along\r
+ * with this program; if not, write to the Free Software Foundation, Inc.,\r
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\r
+ * http://www.gnu.org/copyleft/gpl.html\r
+ */\r
+\r
+if (!defined('MEDIAWIKI')) {\r
+       // Eclipse helper - will be ignored in production\r
+       require_once ('ApiQueryBase.php');\r
+}\r
+\r
+/**\r
+ * Query module to enumerate all available pages.\r
+ *\r
+ * @ingroup API\r
+ */\r
+class ApiQueryDoubleRedirects extends ApiQueryGeneratorBase {\r
+       public function __construct($query, $moduleName) {\r
+               parent :: __construct($query, $moduleName, 'do');\r
+       }\r
+\r
+       public function execute() {\r
+               $this->run();\r
+       }\r
+\r
+       public function executeGenerator($resultPageSet) {\r
+               if ($resultPageSet->isResolvingRedirects())\r
+                       $this->dieUsage('Use "gapfilterredir=nonredirects" option instead of "redirects" when using allpages as a generator', 'params');\r
+\r
+               $this->run($resultPageSet);\r
+       }\r
+\r
+       private function run($resultPageSet = null) {\r
+               $db = $this->getDB();\r
+               $params = $this->extractRequestParams();\r
+               \r
+               list( $page, $redirect ) = $db->tableNamesN( 'page', 'redirect' );\r
+               $this->addFields( array(\r
+                       "pa.page_namespace as namespace",\r
+                       "pa.page_title as title",\r
+                       "pa.page_id as pageid",\r
+                       "pb.page_namespace as nsb",\r
+                       "pb.page_title as tb",\r
+                       "pb.page_id as idb",\r
+                       "pc.page_namespace as nsc",\r
+                       "pc.page_title as tc",\r
+                       "pc.page_id as idc",\r
+                       )\r
+               );\r
+               $this->addTables($redirect, 'ra');\r
+               $this->addTables($redirect, 'rb');\r
+               $this->addTables($page, 'pa');\r
+               $this->addTables($page, 'pb');\r
+               $this->addTables($page, 'pc');\r
+               $this->addWhere(array(\r
+                       "ra.rd_from=pa.page_id",\r
+                       "ra.rd_namespace=pb.page_namespace",\r
+                       "ra.rd_title=pb.page_title",\r
+                       "rb.rd_from=pb.page_id",\r
+                       "rb.rd_namespace=pc.page_namespace",\r
+                       "rb.rd_title=pc.page_title"\r
+                       )\r
+               );\r
+               $limit = $params['limit'];\r
+               $this->addOption('LIMIT', $limit+1);\r
+               if(!is_null($params['offset']))\r
+                       $this->addOption('OFFSET', $params['offset']);\r
+               $res = $this->select(__METHOD__);\r
+               $result = $this->getResult();\r
+               $count = 0;\r
+               while ($row = $db->fetchObject($res)) {\r
+                       if (++ $count > $limit) {\r
+                               // We've reached the one extra which shows that there are additional pages to be had. Stop here...\r
+                               // TODO: Security issue - if the user has no right to view next title, it will still be shown\r
+                               $this->setContinueEnumParameter('offset', @$params['offset'] + $params['limit']);\r
+                               break;\r
+                       }\r
+                       if (is_null($resultPageSet)) {\r
+                               $title = Title :: makeTitle($row->page_namespace, $row->title);\r
+                               $titleB = Title :: makeTitle($row->page_namespace, $row->tb);\r
+                               $titleC = Title :: makeTitle($row->page_namespace, $row->tc);\r
+                               $vals = array(\r
+                                       'pageid' => $row->pageid,\r
+                                       'ns' => intval($row->namespace),\r
+                                       'title' => $title->getPrefixedText(),\r
+                                       'idb' => intval($row->idb),\r
+                                       'nsb' => intval($row->nsb),\r
+                                       'tb' => $titleB->getPrefixedText(),\r
+                                       'idc' => intval($row->idc),\r
+                                       'nsc' => intval($row->nsc),\r
+                                       'tc' => $titleC->getPrefixedText(),\r
+                               );\r
+                               $fit = $result->addValue(array('query', $this->getModuleName()), null, $vals);\r
+                               if(!$fit)\r
+                               {\r
+                                       $this->setContinueEnumParameter('offset', @$params['offset'] + $count - 1);\r
+                                       break;\r
+                               }\r
+                       } else {\r
+                               $resultPageSet->processDbRow($row);\r
+                       }\r
+               }\r
+               $db->freeResult($res);\r
+\r
+               if (is_null($resultPageSet)) {\r
+                       $result->setIndexedTagName_internal(array('query', $this->getModuleName()), 'p');\r
+               }\r
+       }\r
+\r
+       public function getAllowedParams() {\r
+               return array (\r
+                       'limit' => array(\r
+                               ApiBase :: PARAM_DFLT => 10,\r
+                               ApiBase :: PARAM_TYPE => 'limit',\r
+                               ApiBase :: PARAM_MIN => 1,\r
+                               ApiBase :: PARAM_MAX => ApiBase :: LIMIT_BIG1,\r
+                               ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2\r
+                       ),\r
+                       'offset' => null,\r
+               );\r
+       }\r
+\r
+       public function getParamDescription() {\r
+               return array(\r
+                       'limit' => 'How many links to return',\r
+                       'offset' => 'When more results are available, use this to continue',\r
+               );\r
+       }\r
+\r
+       public function getDescription() {\r
+               return 'Enumerate all double redirects';\r
+       }\r
+\r
+       protected function getExamples() {\r
+               return array (\r
+                       'api.php?action=query&list=doubleredirects',\r
+               );\r
+       }\r
+\r
+       public function getVersion() {\r
+               return __CLASS__ . ': $Id: ApiQueryDoubleRedirects.php 46845 2009-07-24 14:00:00Z alexsh $';\r
+       }\r
+\r
+}
\ No newline at end of file