]> scripts.mit.edu Git - autoinstalls/mediawiki.git/blob - includes/api/ApiQueryCategories.php
MediaWiki 1.30.2-scripts2
[autoinstalls/mediawiki.git] / includes / api / ApiQueryCategories.php
1 <?php
2 /**
3  *
4  *
5  * Created on May 13, 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 enumerate categories the set of pages belong to.
29  *
30  * @ingroup API
31  */
32 class ApiQueryCategories extends ApiQueryGeneratorBase {
33
34         public function __construct( ApiQuery $query, $moduleName ) {
35                 parent::__construct( $query, $moduleName, 'cl' );
36         }
37
38         public function execute() {
39                 $this->run();
40         }
41
42         public function getCacheMode( $params ) {
43                 return 'public';
44         }
45
46         public function executeGenerator( $resultPageSet ) {
47                 $this->run( $resultPageSet );
48         }
49
50         /**
51          * @param ApiPageSet $resultPageSet
52          */
53         private function run( $resultPageSet = null ) {
54                 if ( $this->getPageSet()->getGoodTitleCount() == 0 ) {
55                         return; // nothing to do
56                 }
57
58                 $params = $this->extractRequestParams();
59                 $prop = array_flip( (array)$params['prop'] );
60                 $show = array_flip( (array)$params['show'] );
61
62                 $this->addFields( [
63                         'cl_from',
64                         'cl_to'
65                 ] );
66
67                 $this->addFieldsIf( [ 'cl_sortkey', 'cl_sortkey_prefix' ], isset( $prop['sortkey'] ) );
68                 $this->addFieldsIf( 'cl_timestamp', isset( $prop['timestamp'] ) );
69
70                 $this->addTables( 'categorylinks' );
71                 $this->addWhereFld( 'cl_from', array_keys( $this->getPageSet()->getGoodTitles() ) );
72                 if ( !is_null( $params['categories'] ) ) {
73                         $cats = [];
74                         foreach ( $params['categories'] as $cat ) {
75                                 $title = Title::newFromText( $cat );
76                                 if ( !$title || $title->getNamespace() != NS_CATEGORY ) {
77                                         $this->addWarning( [ 'apiwarn-invalidcategory', wfEscapeWikiText( $cat ) ] );
78                                 } else {
79                                         $cats[] = $title->getDBkey();
80                                 }
81                         }
82                         $this->addWhereFld( 'cl_to', $cats );
83                 }
84
85                 if ( !is_null( $params['continue'] ) ) {
86                         $cont = explode( '|', $params['continue'] );
87                         $this->dieContinueUsageIf( count( $cont ) != 2 );
88                         $op = $params['dir'] == 'descending' ? '<' : '>';
89                         $clfrom = intval( $cont[0] );
90                         $clto = $this->getDB()->addQuotes( $cont[1] );
91                         $this->addWhere(
92                                 "cl_from $op $clfrom OR " .
93                                 "(cl_from = $clfrom AND " .
94                                 "cl_to $op= $clto)"
95                         );
96                 }
97
98                 if ( isset( $show['hidden'] ) && isset( $show['!hidden'] ) ) {
99                         $this->dieWithError( 'apierror-show' );
100                 }
101                 if ( isset( $show['hidden'] ) || isset( $show['!hidden'] ) || isset( $prop['hidden'] ) ) {
102                         $this->addOption( 'STRAIGHT_JOIN' );
103                         $this->addTables( [ 'page', 'page_props' ] );
104                         $this->addFieldsIf( 'pp_propname', isset( $prop['hidden'] ) );
105                         $this->addJoinConds( [
106                                 'page' => [ 'LEFT JOIN', [
107                                         'page_namespace' => NS_CATEGORY,
108                                         'page_title = cl_to' ] ],
109                                 'page_props' => [ 'LEFT JOIN', [
110                                         'pp_page=page_id',
111                                         'pp_propname' => 'hiddencat' ] ]
112                         ] );
113                         if ( isset( $show['hidden'] ) ) {
114                                 $this->addWhere( [ 'pp_propname IS NOT NULL' ] );
115                         } elseif ( isset( $show['!hidden'] ) ) {
116                                 $this->addWhere( [ 'pp_propname IS NULL' ] );
117                         }
118                 }
119
120                 $sort = ( $params['dir'] == 'descending' ? ' DESC' : '' );
121                 // Don't order by cl_from if it's constant in the WHERE clause
122                 if ( count( $this->getPageSet()->getGoodTitles() ) == 1 ) {
123                         $this->addOption( 'ORDER BY', 'cl_to' . $sort );
124                 } else {
125                         $this->addOption( 'ORDER BY', [
126                                 'cl_from' . $sort,
127                                 'cl_to' . $sort
128                         ] );
129                 }
130
131                 $res = $this->select( __METHOD__ );
132
133                 $count = 0;
134                 if ( is_null( $resultPageSet ) ) {
135                         foreach ( $res as $row ) {
136                                 if ( ++$count > $params['limit'] ) {
137                                         // We've reached the one extra which shows that
138                                         // there are additional pages to be had. Stop here...
139                                         $this->setContinueEnumParameter( 'continue', $row->cl_from . '|' . $row->cl_to );
140                                         break;
141                                 }
142
143                                 $title = Title::makeTitle( NS_CATEGORY, $row->cl_to );
144                                 $vals = [];
145                                 ApiQueryBase::addTitleInfo( $vals, $title );
146                                 if ( isset( $prop['sortkey'] ) ) {
147                                         $vals['sortkey'] = bin2hex( $row->cl_sortkey );
148                                         $vals['sortkeyprefix'] = $row->cl_sortkey_prefix;
149                                 }
150                                 if ( isset( $prop['timestamp'] ) ) {
151                                         $vals['timestamp'] = wfTimestamp( TS_ISO_8601, $row->cl_timestamp );
152                                 }
153                                 if ( isset( $prop['hidden'] ) ) {
154                                         $vals['hidden'] = !is_null( $row->pp_propname );
155                                 }
156
157                                 $fit = $this->addPageSubItem( $row->cl_from, $vals );
158                                 if ( !$fit ) {
159                                         $this->setContinueEnumParameter( 'continue', $row->cl_from . '|' . $row->cl_to );
160                                         break;
161                                 }
162                         }
163                 } else {
164                         $titles = [];
165                         foreach ( $res as $row ) {
166                                 if ( ++$count > $params['limit'] ) {
167                                         // We've reached the one extra which shows that
168                                         // there are additional pages to be had. Stop here...
169                                         $this->setContinueEnumParameter( 'continue', $row->cl_from . '|' . $row->cl_to );
170                                         break;
171                                 }
172
173                                 $titles[] = Title::makeTitle( NS_CATEGORY, $row->cl_to );
174                         }
175                         $resultPageSet->populateFromTitles( $titles );
176                 }
177         }
178
179         public function getAllowedParams() {
180                 return [
181                         'prop' => [
182                                 ApiBase::PARAM_ISMULTI => true,
183                                 ApiBase::PARAM_TYPE => [
184                                         'sortkey',
185                                         'timestamp',
186                                         'hidden',
187                                 ],
188                                 ApiBase::PARAM_HELP_MSG_PER_VALUE => [],
189                         ],
190                         'show' => [
191                                 ApiBase::PARAM_ISMULTI => true,
192                                 ApiBase::PARAM_TYPE => [
193                                         'hidden',
194                                         '!hidden',
195                                 ]
196                         ],
197                         'limit' => [
198                                 ApiBase::PARAM_DFLT => 10,
199                                 ApiBase::PARAM_TYPE => 'limit',
200                                 ApiBase::PARAM_MIN => 1,
201                                 ApiBase::PARAM_MAX => ApiBase::LIMIT_BIG1,
202                                 ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2
203                         ],
204                         'continue' => [
205                                 ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
206                         ],
207                         'categories' => [
208                                 ApiBase::PARAM_ISMULTI => true,
209                         ],
210                         'dir' => [
211                                 ApiBase::PARAM_DFLT => 'ascending',
212                                 ApiBase::PARAM_TYPE => [
213                                         'ascending',
214                                         'descending'
215                                 ]
216                         ],
217                 ];
218         }
219
220         protected function getExamplesMessages() {
221                 return [
222                         'action=query&prop=categories&titles=Albert%20Einstein'
223                                 => 'apihelp-query+categories-example-simple',
224                         'action=query&generator=categories&titles=Albert%20Einstein&prop=info'
225                                 => 'apihelp-query+categories-example-generator',
226                 ];
227         }
228
229         public function getHelpUrls() {
230                 return 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Categories';
231         }
232 }