Conditions | 46 |
Paths | > 20000 |
Total Lines | 236 |
Code Lines | 149 |
Lines | 5 |
Ratio | 2.12 % |
Changes | 0 |
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
1 | <?php |
||
95 | private function run( ApiPageSet $resultPageSet = null ) { |
||
96 | $settings = self::$settings[$this->getModuleName()]; |
||
97 | |||
98 | $db = $this->getDB(); |
||
99 | $params = $this->extractRequestParams(); |
||
100 | $prop = array_flip( $params['prop'] ); |
||
101 | $emptyString = $db->addQuotes( '' ); |
||
102 | |||
103 | $pageSet = $this->getPageSet(); |
||
104 | $titles = $pageSet->getGoodAndMissingTitles(); |
||
105 | $map = $pageSet->getGoodAndMissingTitlesByNamespace(); |
||
106 | |||
107 | // Determine our fields to query on |
||
108 | $p = $settings['prefix']; |
||
109 | $hasNS = !isset( $settings['to_namespace'] ); |
||
110 | if ( $hasNS ) { |
||
111 | $bl_namespace = "{$p}_namespace"; |
||
112 | $bl_title = "{$p}_title"; |
||
113 | } else { |
||
114 | $bl_namespace = $settings['to_namespace']; |
||
115 | $bl_title = "{$p}_to"; |
||
116 | |||
117 | $titles = array_filter( $titles, function ( $t ) use ( $bl_namespace ) { |
||
118 | return $t->getNamespace() === $bl_namespace; |
||
119 | } ); |
||
120 | $map = array_intersect_key( $map, [ $bl_namespace => true ] ); |
||
121 | } |
||
122 | $bl_from = "{$p}_from"; |
||
123 | |||
124 | if ( !$titles ) { |
||
125 | return; // nothing to do |
||
126 | } |
||
127 | |||
128 | // Figure out what we're sorting by, and add associated WHERE clauses. |
||
129 | // MySQL's query planner screws up if we include a field in ORDER BY |
||
130 | // when it's constant in WHERE, so we have to test that for each field. |
||
131 | $sortby = []; |
||
132 | if ( $hasNS && count( $map ) > 1 ) { |
||
133 | $sortby[$bl_namespace] = 'ns'; |
||
134 | } |
||
135 | $theTitle = null; |
||
136 | foreach ( $map as $nsTitles ) { |
||
137 | reset( $nsTitles ); |
||
138 | $key = key( $nsTitles ); |
||
139 | if ( $theTitle === null ) { |
||
140 | $theTitle = $key; |
||
141 | } |
||
142 | if ( count( $nsTitles ) > 1 || $key !== $theTitle ) { |
||
143 | $sortby[$bl_title] = 'title'; |
||
144 | break; |
||
145 | } |
||
146 | } |
||
147 | $miser_ns = null; |
||
148 | if ( $params['namespace'] !== null ) { |
||
149 | if ( empty( $settings['from_namespace'] ) ) { |
||
150 | View Code Duplication | if ( $this->getConfig()->get( 'MiserMode' ) ) { |
|
151 | $miser_ns = $params['namespace']; |
||
152 | } else { |
||
153 | $this->addWhereFld( 'page_namespace', $params['namespace'] ); |
||
154 | } |
||
155 | } else { |
||
156 | $this->addWhereFld( "{$p}_from_namespace", $params['namespace'] ); |
||
157 | if ( !empty( $settings['from_namespace'] ) && count( $params['namespace'] ) > 1 ) { |
||
158 | $sortby["{$p}_from_namespace"] = 'int'; |
||
159 | } |
||
160 | } |
||
161 | } |
||
162 | $sortby[$bl_from] = 'int'; |
||
163 | |||
164 | // Now use the $sortby to figure out the continuation |
||
165 | if ( !is_null( $params['continue'] ) ) { |
||
166 | $cont = explode( '|', $params['continue'] ); |
||
167 | $this->dieContinueUsageIf( count( $cont ) != count( $sortby ) ); |
||
168 | $where = ''; |
||
169 | $i = count( $sortby ) - 1; |
||
170 | foreach ( array_reverse( $sortby, true ) as $field => $type ) { |
||
171 | $v = $cont[$i]; |
||
172 | switch ( $type ) { |
||
173 | case 'ns': |
||
174 | case 'int': |
||
175 | $v = (int)$v; |
||
176 | $this->dieContinueUsageIf( $v != $cont[$i] ); |
||
177 | break; |
||
178 | default: |
||
179 | $v = $db->addQuotes( $v ); |
||
180 | break; |
||
181 | } |
||
182 | |||
183 | if ( $where === '' ) { |
||
184 | $where = "$field >= $v"; |
||
185 | } else { |
||
186 | $where = "$field > $v OR ($field = $v AND ($where))"; |
||
187 | } |
||
188 | |||
189 | $i--; |
||
190 | } |
||
191 | $this->addWhere( $where ); |
||
192 | } |
||
193 | |||
194 | // Populate the rest of the query |
||
195 | $this->addTables( [ $settings['linktable'], 'page' ] ); |
||
196 | $this->addWhere( "$bl_from = page_id" ); |
||
197 | |||
198 | if ( $this->getModuleName() === 'redirects' ) { |
||
199 | $this->addWhere( "rd_interwiki = $emptyString OR rd_interwiki IS NULL" ); |
||
200 | } |
||
201 | |||
202 | $this->addFields( array_keys( $sortby ) ); |
||
203 | $this->addFields( [ 'bl_namespace' => $bl_namespace, 'bl_title' => $bl_title ] ); |
||
204 | if ( is_null( $resultPageSet ) ) { |
||
205 | $fld_pageid = isset( $prop['pageid'] ); |
||
206 | $fld_title = isset( $prop['title'] ); |
||
207 | $fld_redirect = isset( $prop['redirect'] ); |
||
208 | |||
209 | $this->addFieldsIf( 'page_id', $fld_pageid ); |
||
210 | $this->addFieldsIf( [ 'page_title', 'page_namespace' ], $fld_title ); |
||
211 | $this->addFieldsIf( 'page_is_redirect', $fld_redirect ); |
||
212 | |||
213 | // prop=redirects |
||
214 | $fld_fragment = isset( $prop['fragment'] ); |
||
215 | $this->addFieldsIf( 'rd_fragment', $fld_fragment ); |
||
216 | } else { |
||
217 | $this->addFields( $resultPageSet->getPageTableFields() ); |
||
218 | } |
||
219 | |||
220 | $this->addFieldsIf( 'page_namespace', $miser_ns !== null ); |
||
221 | |||
222 | if ( $hasNS ) { |
||
223 | $lb = new LinkBatch( $titles ); |
||
224 | $this->addWhere( $lb->constructSet( $p, $db ) ); |
||
|
|||
225 | } else { |
||
226 | $where = []; |
||
227 | foreach ( $titles as $t ) { |
||
228 | if ( $t->getNamespace() == $bl_namespace ) { |
||
229 | $where[] = "$bl_title = " . $db->addQuotes( $t->getDBkey() ); |
||
230 | } |
||
231 | } |
||
232 | $this->addWhere( $db->makeList( $where, LIST_OR ) ); |
||
233 | } |
||
234 | |||
235 | if ( $params['show'] !== null ) { |
||
236 | // prop=redirects only |
||
237 | $show = array_flip( $params['show'] ); |
||
238 | if ( isset( $show['fragment'] ) && isset( $show['!fragment'] ) || |
||
239 | isset( $show['redirect'] ) && isset( $show['!redirect'] ) |
||
240 | ) { |
||
241 | $this->dieUsageMsg( 'show' ); |
||
242 | } |
||
243 | $this->addWhereIf( "rd_fragment != $emptyString", isset( $show['fragment'] ) ); |
||
244 | $this->addWhereIf( |
||
245 | "rd_fragment = $emptyString OR rd_fragment IS NULL", |
||
246 | isset( $show['!fragment'] ) |
||
247 | ); |
||
248 | $this->addWhereIf( [ 'page_is_redirect' => 1 ], isset( $show['redirect'] ) ); |
||
249 | $this->addWhereIf( [ 'page_is_redirect' => 0 ], isset( $show['!redirect'] ) ); |
||
250 | } |
||
251 | |||
252 | // Override any ORDER BY from above with what we calculated earlier. |
||
253 | $this->addOption( 'ORDER BY', array_keys( $sortby ) ); |
||
254 | |||
255 | // MySQL's optimizer chokes if we have too many values in "$bl_title IN |
||
256 | // (...)" and chooses the wrong index, so specify the correct index to |
||
257 | // use for the query. See T139056 for details. |
||
258 | if ( !empty( $settings['indexes'] ) ) { |
||
259 | list( $idxNoFromNS, $idxWithFromNS ) = $settings['indexes']; |
||
260 | if ( $params['namespace'] !== null && !empty( $settings['from_namespace'] ) ) { |
||
261 | $this->addOption( 'USE INDEX', [ $settings['linktable'] => $idxWithFromNS ] ); |
||
262 | } else { |
||
263 | $this->addOption( 'USE INDEX', [ $settings['linktable'] => $idxNoFromNS ] ); |
||
264 | } |
||
265 | } |
||
266 | |||
267 | // MySQL (or at least 5.5.5-10.0.23-MariaDB) chooses a really bad query |
||
268 | // plan if it thinks there will be more matching rows in the linktable |
||
269 | // than are in page. Use STRAIGHT_JOIN here to force it to use the |
||
270 | // intended, fast plan. See T145079 for details. |
||
271 | $this->addOption( 'STRAIGHT_JOIN' ); |
||
272 | |||
273 | $this->addOption( 'LIMIT', $params['limit'] + 1 ); |
||
274 | |||
275 | $res = $this->select( __METHOD__ ); |
||
276 | |||
277 | if ( is_null( $resultPageSet ) ) { |
||
278 | $count = 0; |
||
279 | foreach ( $res as $row ) { |
||
280 | if ( ++$count > $params['limit'] ) { |
||
281 | // We've reached the one extra which shows that |
||
282 | // there are additional pages to be had. Stop here... |
||
283 | $this->setContinue( $row, $sortby ); |
||
284 | break; |
||
285 | } |
||
286 | |||
287 | if ( $miser_ns !== null && !in_array( $row->page_namespace, $miser_ns ) ) { |
||
288 | // Miser mode namespace check |
||
289 | continue; |
||
290 | } |
||
291 | |||
292 | // Get the ID of the current page |
||
293 | $id = $map[$row->bl_namespace][$row->bl_title]; |
||
294 | |||
295 | $vals = []; |
||
296 | if ( $fld_pageid ) { |
||
297 | $vals['pageid'] = (int)$row->page_id; |
||
298 | } |
||
299 | if ( $fld_title ) { |
||
300 | ApiQueryBase::addTitleInfo( $vals, |
||
301 | Title::makeTitle( $row->page_namespace, $row->page_title ) |
||
302 | ); |
||
303 | } |
||
304 | if ( $fld_fragment && $row->rd_fragment !== null && $row->rd_fragment !== '' ) { |
||
305 | $vals['fragment'] = $row->rd_fragment; |
||
306 | } |
||
307 | if ( $fld_redirect ) { |
||
308 | $vals['redirect'] = (bool)$row->page_is_redirect; |
||
309 | } |
||
310 | $fit = $this->addPageSubItem( $id, $vals ); |
||
311 | if ( !$fit ) { |
||
312 | $this->setContinue( $row, $sortby ); |
||
313 | break; |
||
314 | } |
||
315 | } |
||
316 | } else { |
||
317 | $titles = []; |
||
318 | $count = 0; |
||
319 | foreach ( $res as $row ) { |
||
320 | if ( ++$count > $params['limit'] ) { |
||
321 | // We've reached the one extra which shows that |
||
322 | // there are additional pages to be had. Stop here... |
||
323 | $this->setContinue( $row, $sortby ); |
||
324 | break; |
||
325 | } |
||
326 | $titles[] = Title::makeTitle( $row->page_namespace, $row->page_title ); |
||
327 | } |
||
328 | $resultPageSet->populateFromTitles( $titles ); |
||
329 | } |
||
330 | } |
||
331 | |||
430 |
This check looks at variables that are passed out again to other methods.
If the outgoing method call has stricter type requirements than the method itself, an issue is raised.
An additional type check may prevent trouble.