]> scripts.mit.edu Git - autoinstalls/mediawiki.git/blob - includes/api/ApiQueryLinks.php
MediaWiki 1.30.2-scripts2
[autoinstalls/mediawiki.git] / includes / api / ApiQueryLinks.php
1 <?php
2 /**
3  *
4  *
5  * Created on May 12, 2007
6  *
7  * Copyright © 2006 Yuri Astrakhan "<Firstname><Lastname>@gmail.com"
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License along
20  * with this program; if not, write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22  * http://www.gnu.org/copyleft/gpl.html
23  *
24  * @file
25  */
26
27 /**
28  * A query module to list all wiki links on a given set of pages.
29  *
30  * @ingroup API
31  */
32 class ApiQueryLinks extends ApiQueryGeneratorBase {
33
34         const LINKS = 'links';
35         const TEMPLATES = 'templates';
36
37         private $table, $prefix, $titlesParam, $helpUrl;
38
39         public function __construct( ApiQuery $query, $moduleName ) {
40                 switch ( $moduleName ) {
41                         case self::LINKS:
42                                 $this->table = 'pagelinks';
43                                 $this->prefix = 'pl';
44                                 $this->titlesParam = 'titles';
45                                 $this->helpUrl = 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Links';
46                                 break;
47                         case self::TEMPLATES:
48                                 $this->table = 'templatelinks';
49                                 $this->prefix = 'tl';
50                                 $this->titlesParam = 'templates';
51                                 $this->helpUrl = 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Templates';
52                                 break;
53                         default:
54                                 ApiBase::dieDebug( __METHOD__, 'Unknown module name' );
55                 }
56
57                 parent::__construct( $query, $moduleName, $this->prefix );
58         }
59
60         public function execute() {
61                 $this->run();
62         }
63
64         public function getCacheMode( $params ) {
65                 return 'public';
66         }
67
68         public function executeGenerator( $resultPageSet ) {
69                 $this->run( $resultPageSet );
70         }
71
72         /**
73          * @param ApiPageSet $resultPageSet
74          */
75         private function run( $resultPageSet = null ) {
76                 if ( $this->getPageSet()->getGoodTitleCount() == 0 ) {
77                         return; // nothing to do
78                 }
79
80                 $params = $this->extractRequestParams();
81
82                 $this->addFields( [
83                         'pl_from' => $this->prefix . '_from',
84                         'pl_namespace' => $this->prefix . '_namespace',
85                         'pl_title' => $this->prefix . '_title'
86                 ] );
87
88                 $this->addTables( $this->table );
89                 $this->addWhereFld( $this->prefix . '_from', array_keys( $this->getPageSet()->getGoodTitles() ) );
90                 $this->addWhereFld( $this->prefix . '_namespace', $params['namespace'] );
91
92                 if ( !is_null( $params[$this->titlesParam] ) ) {
93                         $lb = new LinkBatch;
94                         foreach ( $params[$this->titlesParam] as $t ) {
95                                 $title = Title::newFromText( $t );
96                                 if ( !$title ) {
97                                         $this->addWarning( [ 'apiwarn-invalidtitle', wfEscapeWikiText( $t ) ] );
98                                 } else {
99                                         $lb->addObj( $title );
100                                 }
101                         }
102                         $cond = $lb->constructSet( $this->prefix, $this->getDB() );
103                         if ( $cond ) {
104                                 $this->addWhere( $cond );
105                         }
106                 }
107
108                 if ( !is_null( $params['continue'] ) ) {
109                         $cont = explode( '|', $params['continue'] );
110                         $this->dieContinueUsageIf( count( $cont ) != 3 );
111                         $op = $params['dir'] == 'descending' ? '<' : '>';
112                         $plfrom = intval( $cont[0] );
113                         $plns = intval( $cont[1] );
114                         $pltitle = $this->getDB()->addQuotes( $cont[2] );
115                         $this->addWhere(
116                                 "{$this->prefix}_from $op $plfrom OR " .
117                                 "({$this->prefix}_from = $plfrom AND " .
118                                 "({$this->prefix}_namespace $op $plns OR " .
119                                 "({$this->prefix}_namespace = $plns AND " .
120                                 "{$this->prefix}_title $op= $pltitle)))"
121                         );
122                 }
123
124                 $sort = ( $params['dir'] == 'descending' ? ' DESC' : '' );
125                 // Here's some MySQL craziness going on: if you use WHERE foo='bar'
126                 // and later ORDER BY foo MySQL doesn't notice the ORDER BY is pointless
127                 // but instead goes and filesorts, because the index for foo was used
128                 // already. To work around this, we drop constant fields in the WHERE
129                 // clause from the ORDER BY clause
130                 $order = [];
131                 if ( count( $this->getPageSet()->getGoodTitles() ) != 1 ) {
132                         $order[] = $this->prefix . '_from' . $sort;
133                 }
134                 if ( count( $params['namespace'] ) != 1 ) {
135                         $order[] = $this->prefix . '_namespace' . $sort;
136                 }
137
138                 $order[] = $this->prefix . '_title' . $sort;
139                 $this->addOption( 'ORDER BY', $order );
140                 $this->addOption( 'LIMIT', $params['limit'] + 1 );
141
142                 $res = $this->select( __METHOD__ );
143
144                 if ( is_null( $resultPageSet ) ) {
145                         $count = 0;
146                         foreach ( $res as $row ) {
147                                 if ( ++$count > $params['limit'] ) {
148                                         // We've reached the one extra which shows that
149                                         // there are additional pages to be had. Stop here...
150                                         $this->setContinueEnumParameter( 'continue',
151                                                 "{$row->pl_from}|{$row->pl_namespace}|{$row->pl_title}" );
152                                         break;
153                                 }
154                                 $vals = [];
155                                 ApiQueryBase::addTitleInfo( $vals, Title::makeTitle( $row->pl_namespace, $row->pl_title ) );
156                                 $fit = $this->addPageSubItem( $row->pl_from, $vals );
157                                 if ( !$fit ) {
158                                         $this->setContinueEnumParameter( 'continue',
159                                                 "{$row->pl_from}|{$row->pl_namespace}|{$row->pl_title}" );
160                                         break;
161                                 }
162                         }
163                 } else {
164                         $titles = [];
165                         $count = 0;
166                         foreach ( $res as $row ) {
167                                 if ( ++$count > $params['limit'] ) {
168                                         // We've reached the one extra which shows that
169                                         // there are additional pages to be had. Stop here...
170                                         $this->setContinueEnumParameter( 'continue',
171                                                 "{$row->pl_from}|{$row->pl_namespace}|{$row->pl_title}" );
172                                         break;
173                                 }
174                                 $titles[] = Title::makeTitle( $row->pl_namespace, $row->pl_title );
175                         }
176                         $resultPageSet->populateFromTitles( $titles );
177                 }
178         }
179
180         public function getAllowedParams() {
181                 return [
182                         'namespace' => [
183                                 ApiBase::PARAM_TYPE => 'namespace',
184                                 ApiBase::PARAM_ISMULTI => true,
185                                 ApiBase::PARAM_EXTRA_NAMESPACES => [ NS_MEDIA, NS_SPECIAL ],
186                         ],
187                         'limit' => [
188                                 ApiBase::PARAM_DFLT => 10,
189                                 ApiBase::PARAM_TYPE => 'limit',
190                                 ApiBase::PARAM_MIN => 1,
191                                 ApiBase::PARAM_MAX => ApiBase::LIMIT_BIG1,
192                                 ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2
193                         ],
194                         'continue' => [
195                                 ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
196                         ],
197                         $this->titlesParam => [
198                                 ApiBase::PARAM_ISMULTI => true,
199                         ],
200                         'dir' => [
201                                 ApiBase::PARAM_DFLT => 'ascending',
202                                 ApiBase::PARAM_TYPE => [
203                                         'ascending',
204                                         'descending'
205                                 ]
206                         ],
207                 ];
208         }
209
210         protected function getExamplesMessages() {
211                 $name = $this->getModuleName();
212                 $path = $this->getModulePath();
213
214                 return [
215                         "action=query&prop={$name}&titles=Main%20Page"
216                                 => "apihelp-{$path}-example-simple",
217                         "action=query&generator={$name}&titles=Main%20Page&prop=info"
218                                 => "apihelp-{$path}-example-generator",
219                         "action=query&prop={$name}&titles=Main%20Page&{$this->prefix}namespace=2|10"
220                                 => "apihelp-{$path}-example-namespaces",
221                 ];
222         }
223
224         public function getHelpUrls() {
225                 return $this->helpUrl;
226         }
227 }