| Conditions | 23 |
| Paths | 852 |
| Total Lines | 139 |
| Code Lines | 75 |
| Lines | 0 |
| Ratio | 0 % |
| Changes | 1 | ||
| Bugs | 0 | Features | 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 |
||
| 130 | protected function runForTitle( Title $title ) { |
||
| 131 | $page = WikiPage::factory( $title ); |
||
| 132 | if ( !empty( $this->params['triggeringRevisionId'] ) ) { |
||
| 133 | // Fetch the specified revision; lockAndGetLatest() below detects if the page |
||
| 134 | // was edited since and aborts in order to avoid corrupting the link tables |
||
| 135 | $revision = Revision::newFromId( |
||
| 136 | $this->params['triggeringRevisionId'], |
||
| 137 | Revision::READ_LATEST |
||
| 138 | ); |
||
| 139 | } else { |
||
| 140 | // Fetch current revision; READ_LATEST reduces lockAndGetLatest() check failures |
||
| 141 | $revision = Revision::newFromTitle( $title, false, Revision::READ_LATEST ); |
||
| 142 | } |
||
| 143 | |||
| 144 | $stats = MediaWikiServices::getInstance()->getStatsdDataFactory(); |
||
| 145 | |||
| 146 | if ( !$revision ) { |
||
| 147 | $stats->increment( 'refreshlinks.rev_not_found' ); |
||
| 148 | $this->setLastError( "Revision not found for {$title->getPrefixedDBkey()}" ); |
||
| 149 | return false; // just deleted? |
||
| 150 | } elseif ( !$revision->isCurrent() ) { |
||
| 151 | // If the revision isn't current, there's no point in doing a bunch |
||
| 152 | // of work just to fail at the lockAndGetLatest() check later. |
||
| 153 | $stats->increment( 'refreshlinks.rev_not_current' ); |
||
| 154 | $this->setLastError( "Revision {$revision->getId()} is not current" ); |
||
| 155 | return false; |
||
| 156 | } |
||
| 157 | |||
| 158 | $content = $revision->getContent( Revision::RAW ); |
||
| 159 | if ( !$content ) { |
||
| 160 | // If there is no content, pretend the content is empty |
||
| 161 | $content = $revision->getContentHandler()->makeEmptyContent(); |
||
| 162 | } |
||
| 163 | |||
| 164 | $parserOutput = false; |
||
| 165 | $parserOptions = $page->makeParserOptions( 'canonical' ); |
||
| 166 | // If page_touched changed after this root job, then it is likely that |
||
| 167 | // any views of the pages already resulted in re-parses which are now in |
||
| 168 | // cache. The cache can be reused to avoid expensive parsing in some cases. |
||
| 169 | if ( isset( $this->params['rootJobTimestamp'] ) ) { |
||
| 170 | $opportunistic = !empty( $this->params['isOpportunistic'] ); |
||
| 171 | |||
| 172 | $skewedTimestamp = $this->params['rootJobTimestamp']; |
||
| 173 | if ( $opportunistic ) { |
||
| 174 | // Neither clock skew nor DB snapshot/slave lag matter much for such |
||
| 175 | // updates; focus on reusing the (often recently updated) cache |
||
| 176 | } else { |
||
| 177 | // For transclusion updates, the template changes must be reflected |
||
| 178 | $skewedTimestamp = wfTimestamp( TS_MW, |
||
| 179 | wfTimestamp( TS_UNIX, $skewedTimestamp ) + self::CLOCK_FUDGE |
||
| 180 | ); |
||
| 181 | } |
||
| 182 | |||
| 183 | if ( $page->getLinksTimestamp() > $skewedTimestamp ) { |
||
| 184 | // Something already updated the backlinks since this job was made |
||
| 185 | $stats->increment( 'refreshlinks.update_skipped' ); |
||
| 186 | return true; |
||
| 187 | } |
||
| 188 | |||
| 189 | if ( $page->getTouched() >= $this->params['rootJobTimestamp'] || $opportunistic ) { |
||
| 190 | // Cache is suspected to be up-to-date. As long as the cache rev ID matches |
||
| 191 | // and it reflects the job's triggering change, then it is usable. |
||
| 192 | $parserOutput = ParserCache::singleton()->getDirty( $page, $parserOptions ); |
||
| 193 | if ( !$parserOutput |
||
| 194 | || $parserOutput->getCacheRevisionId() != $revision->getId() |
||
| 195 | || $parserOutput->getCacheTime() < $skewedTimestamp |
||
| 196 | ) { |
||
| 197 | $parserOutput = false; // too stale |
||
| 198 | } |
||
| 199 | } |
||
| 200 | } |
||
| 201 | |||
| 202 | // Fetch the current revision and parse it if necessary... |
||
| 203 | if ( $parserOutput ) { |
||
| 204 | $stats->increment( 'refreshlinks.parser_cached' ); |
||
| 205 | } else { |
||
| 206 | $start = microtime( true ); |
||
| 207 | // Revision ID must be passed to the parser output to get revision variables correct |
||
| 208 | $parserOutput = $content->getParserOutput( |
||
| 209 | $title, $revision->getId(), $parserOptions, false ); |
||
| 210 | $elapsed = microtime( true ) - $start; |
||
| 211 | // If it took a long time to render, then save this back to the cache to avoid |
||
| 212 | // wasted CPU by other apaches or job runners. We don't want to always save to |
||
| 213 | // cache as this can cause high cache I/O and LRU churn when a template changes. |
||
| 214 | if ( $elapsed >= self::PARSE_THRESHOLD_SEC |
||
| 215 | && $page->shouldCheckParserCache( $parserOptions, $revision->getId() ) |
||
| 216 | && $parserOutput->isCacheable() |
||
| 217 | ) { |
||
| 218 | $ctime = wfTimestamp( TS_MW, (int)$start ); // cache time |
||
| 219 | ParserCache::singleton()->save( |
||
| 220 | $parserOutput, $page, $parserOptions, $ctime, $revision->getId() |
||
| 221 | ); |
||
| 222 | } |
||
| 223 | $stats->increment( 'refreshlinks.parser_uncached' ); |
||
| 224 | } |
||
| 225 | |||
| 226 | $updates = $content->getSecondaryDataUpdates( |
||
| 227 | $title, |
||
| 228 | null, |
||
| 229 | !empty( $this->params['useRecursiveLinksUpdate'] ), |
||
| 230 | $parserOutput |
||
| 231 | ); |
||
| 232 | |||
| 233 | foreach ( $updates as $key => $update ) { |
||
| 234 | // FIXME: This code probably shouldn't be here? |
||
| 235 | // Needed by things like Echo notifications which need |
||
| 236 | // to know which user caused the links update |
||
| 237 | if ( $update instanceof LinksUpdate ) { |
||
| 238 | $update->setRevision( $revision ); |
||
| 239 | if ( !empty( $this->params['triggeringUser'] ) ) { |
||
| 240 | $userInfo = $this->params['triggeringUser']; |
||
| 241 | if ( $userInfo['userId'] ) { |
||
| 242 | $user = User::newFromId( $userInfo['userId'] ); |
||
| 243 | } else { |
||
| 244 | // Anonymous, use the username |
||
| 245 | $user = User::newFromName( $userInfo['userName'], false ); |
||
| 246 | } |
||
| 247 | $update->setTriggeringUser( $user ); |
||
| 248 | } |
||
| 249 | } |
||
| 250 | } |
||
| 251 | |||
| 252 | $latestNow = $page->lockAndGetLatest(); |
||
| 253 | if ( !$latestNow || $revision->getId() != $latestNow ) { |
||
| 254 | // Do not clobber over newer updates with older ones. If all jobs where FIFO and |
||
| 255 | // serialized, it would be OK to update links based on older revisions since it |
||
| 256 | // would eventually get to the latest. Since that is not the case (by design), |
||
| 257 | // only update the link tables to a state matching the current revision's output. |
||
| 258 | $stats->increment( 'refreshlinks.rev_cas_failure' ); |
||
| 259 | $this->setLastError( "page_latest changed from {$revision->getId()} to $latestNow" ); |
||
| 260 | return false; |
||
| 261 | } |
||
| 262 | |||
| 263 | DataUpdate::runUpdates( $updates ); |
||
| 264 | |||
| 265 | InfoAction::invalidateCache( $title ); |
||
| 266 | |||
| 267 | return true; |
||
| 268 | } |
||
| 269 | |||
| 288 |
This check looks for calls to
isset(...)orempty()on variables that are yet undefined. These calls will always produce the same result and can be removed.This is most likely caused by the renaming of a variable or the removal of a function/method parameter.