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