| Conditions | 65 |
| Paths | > 20000 |
| Total Lines | 271 |
| Code Lines | 171 |
| Lines | 83 |
| Ratio | 30.63 % |
| 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 |
||
| 143 | public function run( $resultPageSet = null ) { |
||
| 144 | $user = $this->getUser(); |
||
| 145 | /* Get the parameters of the request. */ |
||
| 146 | $params = $this->extractRequestParams(); |
||
| 147 | |||
| 148 | /* Build our basic query. Namely, something along the lines of: |
||
| 149 | * SELECT * FROM recentchanges WHERE rc_timestamp > $start |
||
| 150 | * AND rc_timestamp < $end AND rc_namespace = $namespace |
||
| 151 | */ |
||
| 152 | $this->addTables( 'recentchanges' ); |
||
| 153 | $index = [ 'recentchanges' => 'rc_timestamp' ]; // May change |
||
| 154 | $this->addTimestampWhereRange( 'rc_timestamp', $params['dir'], $params['start'], $params['end'] ); |
||
| 155 | |||
| 156 | View Code Duplication | if ( !is_null( $params['continue'] ) ) { |
|
| 157 | $cont = explode( '|', $params['continue'] ); |
||
| 158 | $this->dieContinueUsageIf( count( $cont ) != 2 ); |
||
| 159 | $db = $this->getDB(); |
||
| 160 | $timestamp = $db->addQuotes( $db->timestamp( $cont[0] ) ); |
||
| 161 | $id = intval( $cont[1] ); |
||
| 162 | $this->dieContinueUsageIf( $id != $cont[1] ); |
||
| 163 | $op = $params['dir'] === 'older' ? '<' : '>'; |
||
| 164 | $this->addWhere( |
||
| 165 | "rc_timestamp $op $timestamp OR " . |
||
| 166 | "(rc_timestamp = $timestamp AND " . |
||
| 167 | "rc_id $op= $id)" |
||
| 168 | ); |
||
| 169 | } |
||
| 170 | |||
| 171 | $order = $params['dir'] === 'older' ? 'DESC' : 'ASC'; |
||
| 172 | $this->addOption( 'ORDER BY', [ |
||
| 173 | "rc_timestamp $order", |
||
| 174 | "rc_id $order", |
||
| 175 | ] ); |
||
| 176 | |||
| 177 | $this->addWhereFld( 'rc_namespace', $params['namespace'] ); |
||
| 178 | |||
| 179 | View Code Duplication | if ( !is_null( $params['type'] ) ) { |
|
| 180 | try { |
||
| 181 | $this->addWhereFld( 'rc_type', RecentChange::parseToRCType( $params['type'] ) ); |
||
| 182 | } catch ( Exception $e ) { |
||
| 183 | ApiBase::dieDebug( __METHOD__, $e->getMessage() ); |
||
| 184 | } |
||
| 185 | } |
||
| 186 | |||
| 187 | if ( !is_null( $params['show'] ) ) { |
||
| 188 | $show = array_flip( $params['show'] ); |
||
| 189 | |||
| 190 | /* Check for conflicting parameters. */ |
||
| 191 | if ( ( isset( $show['minor'] ) && isset( $show['!minor'] ) ) |
||
| 192 | || ( isset( $show['bot'] ) && isset( $show['!bot'] ) ) |
||
| 193 | || ( isset( $show['anon'] ) && isset( $show['!anon'] ) ) |
||
| 194 | || ( isset( $show['redirect'] ) && isset( $show['!redirect'] ) ) |
||
| 195 | || ( isset( $show['patrolled'] ) && isset( $show['!patrolled'] ) ) |
||
| 196 | || ( isset( $show['patrolled'] ) && isset( $show['unpatrolled'] ) ) |
||
| 197 | || ( isset( $show['!patrolled'] ) && isset( $show['unpatrolled'] ) ) |
||
| 198 | ) { |
||
| 199 | $this->dieUsageMsg( 'show' ); |
||
| 200 | } |
||
| 201 | |||
| 202 | // Check permissions |
||
| 203 | View Code Duplication | if ( isset( $show['patrolled'] ) |
|
| 204 | || isset( $show['!patrolled'] ) |
||
| 205 | || isset( $show['unpatrolled'] ) |
||
| 206 | ) { |
||
| 207 | if ( !$user->useRCPatrol() && !$user->useNPPatrol() ) { |
||
| 208 | $this->dieUsage( |
||
| 209 | 'You need patrol or patrolmarks permission to request the patrolled flag', |
||
| 210 | 'permissiondenied' |
||
| 211 | ); |
||
| 212 | } |
||
| 213 | } |
||
| 214 | |||
| 215 | /* Add additional conditions to query depending upon parameters. */ |
||
| 216 | $this->addWhereIf( 'rc_minor = 0', isset( $show['!minor'] ) ); |
||
| 217 | $this->addWhereIf( 'rc_minor != 0', isset( $show['minor'] ) ); |
||
| 218 | $this->addWhereIf( 'rc_bot = 0', isset( $show['!bot'] ) ); |
||
| 219 | $this->addWhereIf( 'rc_bot != 0', isset( $show['bot'] ) ); |
||
| 220 | $this->addWhereIf( 'rc_user = 0', isset( $show['anon'] ) ); |
||
| 221 | $this->addWhereIf( 'rc_user != 0', isset( $show['!anon'] ) ); |
||
| 222 | $this->addWhereIf( 'rc_patrolled = 0', isset( $show['!patrolled'] ) ); |
||
| 223 | $this->addWhereIf( 'rc_patrolled != 0', isset( $show['patrolled'] ) ); |
||
| 224 | $this->addWhereIf( 'page_is_redirect = 1', isset( $show['redirect'] ) ); |
||
| 225 | |||
| 226 | if ( isset( $show['unpatrolled'] ) ) { |
||
| 227 | // See ChangesList::isUnpatrolled |
||
| 228 | if ( $user->useRCPatrol() ) { |
||
| 229 | $this->addWhere( 'rc_patrolled = 0' ); |
||
| 230 | } elseif ( $user->useNPPatrol() ) { |
||
| 231 | $this->addWhere( 'rc_patrolled = 0' ); |
||
| 232 | $this->addWhereFld( 'rc_type', RC_NEW ); |
||
| 233 | } |
||
| 234 | } |
||
| 235 | |||
| 236 | // Don't throw log entries out the window here |
||
| 237 | $this->addWhereIf( |
||
| 238 | 'page_is_redirect = 0 OR page_is_redirect IS NULL', |
||
| 239 | isset( $show['!redirect'] ) |
||
| 240 | ); |
||
| 241 | } |
||
| 242 | |||
| 243 | View Code Duplication | if ( !is_null( $params['user'] ) && !is_null( $params['excludeuser'] ) ) { |
|
| 244 | $this->dieUsage( 'user and excludeuser cannot be used together', 'user-excludeuser' ); |
||
| 245 | } |
||
| 246 | |||
| 247 | if ( !is_null( $params['user'] ) ) { |
||
| 248 | $this->addWhereFld( 'rc_user_text', $params['user'] ); |
||
| 249 | $index['recentchanges'] = 'rc_user_text'; |
||
| 250 | } |
||
| 251 | |||
| 252 | View Code Duplication | if ( !is_null( $params['excludeuser'] ) ) { |
|
| 253 | // We don't use the rc_user_text index here because |
||
| 254 | // * it would require us to sort by rc_user_text before rc_timestamp |
||
| 255 | // * the != condition doesn't throw out too many rows anyway |
||
| 256 | $this->addWhere( 'rc_user_text != ' . $this->getDB()->addQuotes( $params['excludeuser'] ) ); |
||
| 257 | } |
||
| 258 | |||
| 259 | /* Add the fields we're concerned with to our query. */ |
||
| 260 | $this->addFields( [ |
||
| 261 | 'rc_id', |
||
| 262 | 'rc_timestamp', |
||
| 263 | 'rc_namespace', |
||
| 264 | 'rc_title', |
||
| 265 | 'rc_cur_id', |
||
| 266 | 'rc_type', |
||
| 267 | 'rc_deleted' |
||
| 268 | ] ); |
||
| 269 | |||
| 270 | $showRedirects = false; |
||
| 271 | /* Determine what properties we need to display. */ |
||
| 272 | if ( !is_null( $params['prop'] ) ) { |
||
| 273 | $prop = array_flip( $params['prop'] ); |
||
| 274 | |||
| 275 | /* Set up internal members based upon params. */ |
||
| 276 | $this->initProperties( $prop ); |
||
| 277 | |||
| 278 | if ( $this->fld_patrolled && !$user->useRCPatrol() && !$user->useNPPatrol() ) { |
||
| 279 | $this->dieUsage( |
||
| 280 | 'You need patrol or patrolmarks permission to request the patrolled flag', |
||
| 281 | 'permissiondenied' |
||
| 282 | ); |
||
| 283 | } |
||
| 284 | |||
| 285 | /* Add fields to our query if they are specified as a needed parameter. */ |
||
| 286 | $this->addFieldsIf( [ 'rc_this_oldid', 'rc_last_oldid' ], $this->fld_ids ); |
||
| 287 | $this->addFieldsIf( 'rc_comment', $this->fld_comment || $this->fld_parsedcomment ); |
||
| 288 | $this->addFieldsIf( 'rc_user', $this->fld_user || $this->fld_userid ); |
||
| 289 | $this->addFieldsIf( 'rc_user_text', $this->fld_user ); |
||
| 290 | $this->addFieldsIf( [ 'rc_minor', 'rc_type', 'rc_bot' ], $this->fld_flags ); |
||
| 291 | $this->addFieldsIf( [ 'rc_old_len', 'rc_new_len' ], $this->fld_sizes ); |
||
| 292 | $this->addFieldsIf( [ 'rc_patrolled', 'rc_log_type' ], $this->fld_patrolled ); |
||
| 293 | $this->addFieldsIf( |
||
| 294 | [ 'rc_logid', 'rc_log_type', 'rc_log_action', 'rc_params' ], |
||
| 295 | $this->fld_loginfo |
||
| 296 | ); |
||
| 297 | $showRedirects = $this->fld_redirect || isset( $show['redirect'] ) |
||
| 298 | || isset( $show['!redirect'] ); |
||
| 299 | } |
||
| 300 | $this->addFieldsIf( [ 'rc_this_oldid' ], |
||
| 301 | $resultPageSet && $params['generaterevisions'] ); |
||
| 302 | |||
| 303 | View Code Duplication | if ( $this->fld_tags ) { |
|
| 304 | $this->addTables( 'tag_summary' ); |
||
| 305 | $this->addJoinConds( [ 'tag_summary' => [ 'LEFT JOIN', [ 'rc_id=ts_rc_id' ] ] ] ); |
||
| 306 | $this->addFields( 'ts_tags' ); |
||
| 307 | } |
||
| 308 | |||
| 309 | if ( $this->fld_sha1 ) { |
||
| 310 | $this->addTables( 'revision' ); |
||
| 311 | $this->addJoinConds( [ 'revision' => [ 'LEFT JOIN', |
||
| 312 | [ 'rc_this_oldid=rev_id' ] ] ] ); |
||
| 313 | $this->addFields( [ 'rev_sha1', 'rev_deleted' ] ); |
||
| 314 | } |
||
| 315 | |||
| 316 | if ( $params['toponly'] || $showRedirects ) { |
||
| 317 | $this->addTables( 'page' ); |
||
| 318 | $this->addJoinConds( [ 'page' => [ 'LEFT JOIN', |
||
| 319 | [ 'rc_namespace=page_namespace', 'rc_title=page_title' ] ] ] ); |
||
| 320 | $this->addFields( 'page_is_redirect' ); |
||
| 321 | |||
| 322 | if ( $params['toponly'] ) { |
||
| 323 | $this->addWhere( 'rc_this_oldid = page_latest' ); |
||
| 324 | } |
||
| 325 | } |
||
| 326 | |||
| 327 | View Code Duplication | if ( !is_null( $params['tag'] ) ) { |
|
| 328 | $this->addTables( 'change_tag' ); |
||
| 329 | $this->addJoinConds( [ 'change_tag' => [ 'INNER JOIN', [ 'rc_id=ct_rc_id' ] ] ] ); |
||
| 330 | $this->addWhereFld( 'ct_tag', $params['tag'] ); |
||
| 331 | } |
||
| 332 | |||
| 333 | // Paranoia: avoid brute force searches (bug 17342) |
||
| 334 | View Code Duplication | if ( !is_null( $params['user'] ) || !is_null( $params['excludeuser'] ) ) { |
|
| 335 | if ( !$user->isAllowed( 'deletedhistory' ) ) { |
||
| 336 | $bitmask = Revision::DELETED_USER; |
||
| 337 | } elseif ( !$user->isAllowedAny( 'suppressrevision', 'viewsuppressed' ) ) { |
||
| 338 | $bitmask = Revision::DELETED_USER | Revision::DELETED_RESTRICTED; |
||
| 339 | } else { |
||
| 340 | $bitmask = 0; |
||
| 341 | } |
||
| 342 | if ( $bitmask ) { |
||
| 343 | $this->addWhere( $this->getDB()->bitAnd( 'rc_deleted', $bitmask ) . " != $bitmask" ); |
||
| 344 | } |
||
| 345 | } |
||
| 346 | if ( $this->getRequest()->getCheck( 'namespace' ) ) { |
||
| 347 | // LogPage::DELETED_ACTION hides the affected page, too. |
||
| 348 | if ( !$user->isAllowed( 'deletedhistory' ) ) { |
||
| 349 | $bitmask = LogPage::DELETED_ACTION; |
||
| 350 | } elseif ( !$user->isAllowedAny( 'suppressrevision', 'viewsuppressed' ) ) { |
||
| 351 | $bitmask = LogPage::DELETED_ACTION | LogPage::DELETED_RESTRICTED; |
||
| 352 | } else { |
||
| 353 | $bitmask = 0; |
||
| 354 | } |
||
| 355 | View Code Duplication | if ( $bitmask ) { |
|
| 356 | $this->addWhere( $this->getDB()->makeList( [ |
||
| 357 | 'rc_type != ' . RC_LOG, |
||
| 358 | $this->getDB()->bitAnd( 'rc_deleted', $bitmask ) . " != $bitmask", |
||
| 359 | ], LIST_OR ) ); |
||
| 360 | } |
||
| 361 | } |
||
| 362 | |||
| 363 | $this->token = $params['token']; |
||
| 364 | $this->addOption( 'LIMIT', $params['limit'] + 1 ); |
||
| 365 | $this->addOption( 'USE INDEX', $index ); |
||
| 366 | |||
| 367 | $count = 0; |
||
| 368 | /* Perform the actual query. */ |
||
| 369 | $res = $this->select( __METHOD__ ); |
||
| 370 | |||
| 371 | $revids = []; |
||
| 372 | $titles = []; |
||
| 373 | |||
| 374 | $result = $this->getResult(); |
||
| 375 | |||
| 376 | /* Iterate through the rows, adding data extracted from them to our query result. */ |
||
| 377 | foreach ( $res as $row ) { |
||
| 378 | View Code Duplication | if ( ++$count > $params['limit'] ) { |
|
| 379 | // We've reached the one extra which shows that there are |
||
| 380 | // additional pages to be had. Stop here... |
||
| 381 | $this->setContinueEnumParameter( 'continue', "$row->rc_timestamp|$row->rc_id" ); |
||
| 382 | break; |
||
| 383 | } |
||
| 384 | |||
| 385 | if ( is_null( $resultPageSet ) ) { |
||
| 386 | /* Extract the data from a single row. */ |
||
| 387 | $vals = $this->extractRowInfo( $row ); |
||
| 388 | |||
| 389 | /* Add that row's data to our final output. */ |
||
| 390 | $fit = $result->addValue( [ 'query', $this->getModuleName() ], null, $vals ); |
||
| 391 | if ( !$fit ) { |
||
| 392 | $this->setContinueEnumParameter( 'continue', "$row->rc_timestamp|$row->rc_id" ); |
||
| 393 | break; |
||
| 394 | } |
||
| 395 | } elseif ( $params['generaterevisions'] ) { |
||
| 396 | $revid = (int)$row->rc_this_oldid; |
||
| 397 | if ( $revid > 0 ) { |
||
| 398 | $revids[] = $revid; |
||
| 399 | } |
||
| 400 | } else { |
||
| 401 | $titles[] = Title::makeTitle( $row->rc_namespace, $row->rc_title ); |
||
| 402 | } |
||
| 403 | } |
||
| 404 | |||
| 405 | View Code Duplication | if ( is_null( $resultPageSet ) ) { |
|
| 406 | /* Format the result */ |
||
| 407 | $result->addIndexedTagName( [ 'query', $this->getModuleName() ], 'rc' ); |
||
| 408 | } elseif ( $params['generaterevisions'] ) { |
||
| 409 | $resultPageSet->populateFromRevisionIDs( $revids ); |
||
| 410 | } else { |
||
| 411 | $resultPageSet->populateFromTitles( $titles ); |
||
| 412 | } |
||
| 413 | } |
||
| 414 | |||
| 706 |
Only declaring a single property per statement allows you to later on add doc comments more easily.
It is also recommended by PSR2, so it is a common style that many people expect.