Index: trunk/extensions/FlaggedRevs/FlaggedRevs.php |
— | — | @@ -311,6 +311,7 @@ |
312 | 312 | $wgAutoloadClasses['FlaggedRevsLogs'] = $dir . 'FlaggedRevsLogs.php'; |
313 | 313 | $wgAutoloadClasses['FRCacheUpdate'] = $dir . 'FRCacheUpdate.php'; |
314 | 314 | $wgAutoloadClasses['FRCacheUpdateJob'] = $dir . 'FRCacheUpdate.php'; |
| 315 | +$wgAutoloadClasses['FRLinksUpdate'] = $dir . 'FRLinksUpdate.php'; |
315 | 316 | |
316 | 317 | # Special case cache invalidations |
317 | 318 | $wgJobClasses['flaggedrevs_CacheUpdate'] = 'FRCacheUpdateJob'; |
— | — | @@ -490,7 +491,7 @@ |
491 | 492 | # Extra cache updates for stable versions |
492 | 493 | $wgHooks['HTMLCacheUpdate::doUpdate'][] = 'FlaggedRevsHooks::doCacheUpdate'; |
493 | 494 | # Updates stable version tracking data |
494 | | -$wgHooks['LinksUpdate'][] = 'FlaggedRevsHooks::extraLinksUpdate'; |
| 495 | +$wgHooks['LinksUpdate'][] = 'FlaggedRevsHooks::onLinksUpdate'; |
495 | 496 | # Clear dead config rows |
496 | 497 | $wgHooks['ArticleDeleteComplete'][] = 'FlaggedRevsHooks::onArticleDelete'; |
497 | 498 | $wgHooks['ArticleRevisionVisibilitySet'][] = 'FlaggedRevsHooks::onRevisionDelete'; |
Index: trunk/extensions/FlaggedRevs/FlaggedRevs.class.php |
— | — | @@ -561,14 +561,15 @@ |
562 | 562 | $options->setTidy( true ); |
563 | 563 | return $options; |
564 | 564 | } |
565 | | - |
| 565 | + |
566 | 566 | /** |
| 567 | + * Get the page cache for the stable version of an article |
567 | 568 | * @param Article $article |
568 | 569 | * @param User $user |
569 | | - * @return ParserOutput |
570 | | - * Get the page cache for the top stable revision of an article |
| 570 | + * @param string $okStale set to 'okStale' to ignore expiration date |
| 571 | + * @return mixed (ParserOutput/false) |
571 | 572 | */ |
572 | | - public static function getPageCache( Article $article, $user ) { |
| 573 | + public static function getPageCache( Article $article, $user, $okStale = false ) { |
573 | 574 | global $parserMemc, $wgCacheEpoch; |
574 | 575 | wfProfileIn( __METHOD__ ); |
575 | 576 | # Make sure it is valid |
— | — | @@ -587,7 +588,7 @@ |
588 | 589 | $canCache = $article->checkTouched(); |
589 | 590 | $cacheTime = $value->getCacheTime(); |
590 | 591 | $touched = $article->mTouched; |
591 | | - if ( !$canCache || $value->expired( $touched ) ) { |
| 592 | + if ( !$canCache || ( $value->expired( $touched ) && $okStale !== 'okStale' ) ) { |
592 | 593 | if ( !$canCache ) { |
593 | 594 | wfIncrStats( "pcache_miss_invalid" ); |
594 | 595 | wfDebug( "Invalid cached redirect, touched $touched, epoch $wgCacheEpoch, cached $cacheTime\n" ); |
— | — | @@ -598,9 +599,6 @@ |
599 | 600 | $parserMemc->delete( $key ); |
600 | 601 | $value = false; |
601 | 602 | } else { |
602 | | - if ( isset( $value->mTimestamp ) ) { |
603 | | - $article->mTimestamp = $value->mTimestamp; |
604 | | - } |
605 | 603 | wfIncrStats( "pcache_hit" ); |
606 | 604 | } |
607 | 605 | } else { |
— | — | @@ -608,7 +606,6 @@ |
609 | 607 | wfIncrStats( "pcache_miss_absent" ); |
610 | 608 | $value = false; |
611 | 609 | } |
612 | | - |
613 | 610 | wfProfileOut( __METHOD__ ); |
614 | 611 | return $value; |
615 | 612 | } |
— | — | @@ -793,7 +790,9 @@ |
794 | 791 | * @param mixed $latest, the latest rev ID (optional) |
795 | 792 | * Updates the tracking tables and pending edit count cache. Called on edit. |
796 | 793 | */ |
797 | | - public static function updateStableVersion( Article $article, Revision $rev, $latest = null ) { |
| 794 | + public static function updateStableVersion( |
| 795 | + Article $article, Revision $rev, $latest = null |
| 796 | + ) { |
798 | 797 | if ( !$article->getId() ) { |
799 | 798 | return true; // no bogus entries |
800 | 799 | } |
— | — | @@ -1392,8 +1391,29 @@ |
1393 | 1392 | NS_FILE : $title->getNamespace(); // Treat NS_MEDIA as NS_FILE |
1394 | 1393 | return ( in_array( $ns, $namespaces ) ); |
1395 | 1394 | } |
1396 | | - |
| 1395 | + |
1397 | 1396 | /** |
| 1397 | + * Get a list of stable categories which go in categorylinks |
| 1398 | + * iff they're in the stable version of of the page (if there is one). |
| 1399 | + * Note: used for bug 20813 |
| 1400 | + * @return array |
| 1401 | + */ |
| 1402 | + public static function getStableCategories() { |
| 1403 | + $reviewedCats = array(); |
| 1404 | + $msg = wfMsgForContent( 'flaggedrevs-stable-categories' ); |
| 1405 | + if ( !wfEmptyMsg( 'flaggedrevs-stable-categories', $msg ) ) { |
| 1406 | + $list = explode( "\n*", "\n$msg" ); |
| 1407 | + foreach ( $list as $category ) { |
| 1408 | + $category = trim( $category ); |
| 1409 | + if ( $category != '' ) { |
| 1410 | + $reviewedCats[] = $category; |
| 1411 | + } |
| 1412 | + } |
| 1413 | + } |
| 1414 | + return $reviewedCats; |
| 1415 | + } |
| 1416 | + |
| 1417 | + /** |
1398 | 1418 | * Clear FlaggedRevs tracking tables for this page |
1399 | 1419 | * @param mixed $pageId (int or array) |
1400 | 1420 | */ |
Index: trunk/extensions/FlaggedRevs/FRLinksUpdate.php |
— | — | @@ -0,0 +1,194 @@ |
| 2 | +<?php |
| 3 | +/** |
| 4 | + * Class containing link update methods and job construction |
| 5 | + * for the special case of refreshing page links due to templates |
| 6 | + * contained only in the stable version of pages |
| 7 | + * |
| 8 | + * @TODO: have flaggedrevs_templatelinks table for stable versions |
| 9 | + * to be more specific in what pages to effect |
| 10 | + */ |
| 11 | +class FRLinksUpdate { |
| 12 | + protected $title; |
| 13 | + protected $sLinks, $cLinks; |
| 14 | + protected $sTemplates, $cTemplates; |
| 15 | + protected $sImages, $cImages; |
| 16 | + protected $sCategories, $cCategories; |
| 17 | + |
| 18 | + // @TODO: replace raw $linksUpdate field accesses |
| 19 | + public function __construct( LinksUpdate $linksUpdate, ParserOutput $stableOutput ) { |
| 20 | + $this->title = $linksUpdate->mTitle; |
| 21 | + # Stable version links |
| 22 | + $this->sLinks = $stableOutput->getLinks(); |
| 23 | + $this->sTemplates = $stableOutput->getTemplates(); |
| 24 | + $this->sImages = $stableOutput->getImages(); |
| 25 | + $this->sCategories = $stableOutput->getCategories(); |
| 26 | + # Current version links |
| 27 | + $this->cLinks = $linksUpdate->mLinks; |
| 28 | + $this->cTemplates = $linksUpdate->mTemplates; |
| 29 | + $this->cImages = $linksUpdate->mImages; |
| 30 | + $this->cCategories = $linksUpdate->mCategories; |
| 31 | + } |
| 32 | + |
| 33 | + public function doUpdate() { |
| 34 | + $links = array(); |
| 35 | + # Get any links that are only in the stable version... |
| 36 | + foreach ( $this->sLinks as $ns => $titles ) { |
| 37 | + foreach ( $titles as $title => $id ) { |
| 38 | + if ( !isset( $this->cLinks[$ns] ) |
| 39 | + || !isset( $this->cLinks[$ns][$title] ) ) |
| 40 | + { |
| 41 | + self::addLink( $links, $ns, $title ); |
| 42 | + } |
| 43 | + } |
| 44 | + } |
| 45 | + # Get any images that are only in the stable version... |
| 46 | + foreach ( $this->sImages as $image => $n ) { |
| 47 | + if ( !isset( $this->cImages[$image] ) ) { |
| 48 | + self::addLink( $links, NS_FILE, $image ); |
| 49 | + } |
| 50 | + } |
| 51 | + # Get any templates that are only in the stable version... |
| 52 | + foreach ( $this->sTemplates as $ns => $titles ) { |
| 53 | + foreach ( $titles as $title => $id ) { |
| 54 | + if ( !isset( $this->cTemplates[$ns] ) |
| 55 | + || !isset( $this->cTemplates[$ns][$title] ) ) |
| 56 | + { |
| 57 | + self::addLink( $links, $ns, $title ); |
| 58 | + } |
| 59 | + } |
| 60 | + } |
| 61 | + # Get any categories that are only in the stable version... |
| 62 | + foreach ( $this->sCategories as $category => $sort ) { |
| 63 | + if ( !isset( $this->cCategories[$category] ) ) { |
| 64 | + self::addLink( $links, NS_CATEGORY, $category ); |
| 65 | + } |
| 66 | + } |
| 67 | + $pageId = $this->title->getArticleId(); |
| 68 | + # Get any link tracking changes |
| 69 | + $existing = self::getExistingLinks( $pageId ); |
| 70 | + $insertions = self::getLinkInsertions( $existing, $links, $pageId ); |
| 71 | + $deletions = self::getLinkDeletions( $existing, $links ); |
| 72 | + # Delete removed links |
| 73 | + $dbw = wfGetDB( DB_MASTER ); |
| 74 | + if ( $clause = self::makeWhereFrom2d( $deletions ) ) { |
| 75 | + $where = array( 'ftr_from' => $pageId ); |
| 76 | + $where[] = $clause; |
| 77 | + $dbw->delete( 'flaggedrevs_tracking', $where, __METHOD__ ); |
| 78 | + } |
| 79 | + # Add any new links |
| 80 | + if ( count( $insertions ) ) { |
| 81 | + $dbw->insert( 'flaggedrevs_tracking', $insertions, __METHOD__, 'IGNORE' ); |
| 82 | + } |
| 83 | + } |
| 84 | + |
| 85 | + protected static function addLink( array &$links, $ns, $dbKey ) { |
| 86 | + if ( !isset( $links[$ns] ) ) { |
| 87 | + $links[$ns] = array(); |
| 88 | + } |
| 89 | + $links[$ns][$dbKey] = 1; |
| 90 | + } |
| 91 | + |
| 92 | + protected static function getExistingLinks( $pageId ) { |
| 93 | + $dbr = wfGetDB( DB_SLAVE ); |
| 94 | + $res = $dbr->select( 'flaggedrevs_tracking', |
| 95 | + array( 'ftr_namespace', 'ftr_title' ), |
| 96 | + array( 'ftr_from' => $pageId ), |
| 97 | + __METHOD__ ); |
| 98 | + $arr = array(); |
| 99 | + while ( $row = $dbr->fetchObject( $res ) ) { |
| 100 | + if ( !isset( $arr[$row->ftr_namespace] ) ) { |
| 101 | + $arr[$row->ftr_namespace] = array(); |
| 102 | + } |
| 103 | + $arr[$row->ftr_namespace][$row->ftr_title] = 1; |
| 104 | + } |
| 105 | + return $arr; |
| 106 | + } |
| 107 | + |
| 108 | + protected static function makeWhereFrom2d( &$arr ) { |
| 109 | + $lb = new LinkBatch(); |
| 110 | + $lb->setArray( $arr ); |
| 111 | + return $lb->constructSet( 'ftr', wfGetDB( DB_SLAVE ) ); |
| 112 | + } |
| 113 | + |
| 114 | + protected static function getLinkInsertions( $existing, $new, $pageId ) { |
| 115 | + $arr = array(); |
| 116 | + foreach ( $new as $ns => $dbkeys ) { |
| 117 | + $diffs = isset( $existing[$ns] ) ? |
| 118 | + array_diff_key( $dbkeys, $existing[$ns] ) : $dbkeys; |
| 119 | + foreach ( $diffs as $dbk => $id ) { |
| 120 | + $arr[] = array( |
| 121 | + 'ftr_from' => $pageId, |
| 122 | + 'ftr_namespace' => $ns, |
| 123 | + 'ftr_title' => $dbk |
| 124 | + ); |
| 125 | + } |
| 126 | + } |
| 127 | + return $arr; |
| 128 | + } |
| 129 | + |
| 130 | + protected static function getLinkDeletions( $existing, $new ) { |
| 131 | + $del = array(); |
| 132 | + foreach ( $existing as $ns => $dbkeys ) { |
| 133 | + if ( isset( $new[$ns] ) ) { |
| 134 | + $del[$ns] = array_diff_key( $existing[$ns], $new[$ns] ); |
| 135 | + } else { |
| 136 | + $del[$ns] = $existing[$ns]; |
| 137 | + } |
| 138 | + } |
| 139 | + return $del; |
| 140 | + } |
| 141 | + |
| 142 | + /* |
| 143 | + * Refresh links of all pages with only the stable version |
| 144 | + * including this page. This will be in a separate transaction. |
| 145 | + * @param Title |
| 146 | + */ |
| 147 | + public static function queueRefreshLinksJobs( Title $title ) { |
| 148 | + global $wgUpdateRowsPerJob; |
| 149 | + wfProfileIn( __METHOD__ ); |
| 150 | + # Fetch the IDs |
| 151 | + $dbr = wfGetDB( DB_SLAVE ); |
| 152 | + $res = $dbr->select( 'flaggedrevs_tracking', |
| 153 | + 'ftr_from', |
| 154 | + array( 'ftr_namespace' => $title->getNamespace(), |
| 155 | + 'ftr_title' => $title->getDBkey() ), |
| 156 | + __METHOD__ |
| 157 | + ); |
| 158 | + $numRows = $res->numRows(); |
| 159 | + if ( !$numRows ) { |
| 160 | + wfProfileOut( __METHOD__ ); |
| 161 | + return; // sanity check |
| 162 | + } |
| 163 | + $numBatches = ceil( $numRows / $wgUpdateRowsPerJob ); |
| 164 | + $realBatchSize = ceil( $numRows / $numBatches ); |
| 165 | + $start = false; |
| 166 | + $jobs = array(); |
| 167 | + do { |
| 168 | + $first = $last = false; // first/last page_id of this batch |
| 169 | + # Get $realBatchSize items (or less if not enough)... |
| 170 | + for ( $i = 0; $i < $realBatchSize; $i++ ) { |
| 171 | + $row = $res->fetchRow(); |
| 172 | + # Is there another row? |
| 173 | + if ( $row ) { |
| 174 | + $id = $row[0]; |
| 175 | + $last = $id; // $id is the last page_id of this batch |
| 176 | + if ( $first === false ) { |
| 177 | + $first = $id; // set first page_id of this batch |
| 178 | + } |
| 179 | + # Out of rows? |
| 180 | + } else { |
| 181 | + $id = false; |
| 182 | + break; |
| 183 | + } |
| 184 | + } |
| 185 | + # Insert batch into the queue if there is anything there |
| 186 | + if ( $first ) { |
| 187 | + $params = array( 'start' => $first, 'end' => $last, ); |
| 188 | + $jobs[] = new RefreshLinksJob2( $title, $params ); |
| 189 | + } |
| 190 | + $start = $id; // Where the last ID left off |
| 191 | + } while ( $start ); |
| 192 | + Job::batchInsert( $jobs ); |
| 193 | + wfProfileOut( __METHOD__ ); |
| 194 | + } |
| 195 | +} |
Property changes on: trunk/extensions/FlaggedRevs/FRLinksUpdate.php |
___________________________________________________________________ |
Name: svn:eol-style |
1 | 196 | + native |
Index: trunk/extensions/FlaggedRevs/FlaggedRevs.hooks.php |
— | — | @@ -282,179 +282,83 @@ |
283 | 283 | return true; |
284 | 284 | } |
285 | 285 | |
286 | | - /** |
287 | | - * Inject stable links on LinksUpdate |
288 | | - */ |
289 | | - public static function extraLinksUpdate( LinksUpdate $linksUpdate ) { |
290 | | - $dbw = wfGetDB( DB_MASTER ); |
291 | | - $pageId = $linksUpdate->mTitle->getArticleId(); |
| 286 | + // @TODO: replace raw $linksUpdate field accesses |
| 287 | + public static function onLinksUpdate( LinksUpdate $linksUpdate ) { |
| 288 | + global $wgUser; |
| 289 | + wfProfileIn( __METHOD__ ); |
| 290 | + $fa = FlaggedArticle::getTitleInstance( $linksUpdate->mTitle ); |
292 | 291 | # Check if this page has a stable version... |
| 292 | + $sv = null; |
293 | 293 | if ( isset( $u->fr_stableRev ) ) { |
294 | 294 | $sv = $u->fr_stableRev; // Try the process cache... |
295 | | - } else { |
296 | | - $fa = FlaggedArticle::getTitleInstance( $linksUpdate->mTitle ); |
297 | | - if ( FlaggedRevs::inReviewNamespace( $linksUpdate->mTitle ) ) { |
298 | | - $sv = $fa->getStableRev( FR_MASTER ); // re-validate NS/config |
299 | | - } else { |
300 | | - $sv = null; |
301 | | - } |
| 295 | + } elseif ( $fa->isReviewable( FR_MASTER ) ) { |
| 296 | + $sv = $fa->getStableRev( FR_MASTER ); // re-validate NS/config |
302 | 297 | } |
303 | | - # Empty flagged revs data for this page if there is no stable version |
304 | | - if ( !$sv ) { |
305 | | - FlaggedRevs::clearTrackingRows( $pageId ); |
306 | | - return true; |
307 | | - } |
308 | | - # Try the process cache... |
309 | | - $article = new Article( $linksUpdate->mTitle ); |
310 | | - if ( isset( $linksUpdate->fr_stableParserOut ) ) { |
311 | | - $parserOut = $linksUpdate->fr_stableParserOut; |
312 | | - } else { |
313 | | - global $wgUser; |
314 | | - # Try stable version cache. This should be updated before this is called. |
315 | | - $anon = new User; // anon cache most likely to exist |
316 | | - $parserOut = FlaggedRevs::getPageCache( $article, $anon ); |
317 | | - if ( $parserOut == false && $wgUser->getId() ) |
318 | | - $parserOut = FlaggedRevs::getPageCache( $article, $wgUser ); |
319 | | - if ( $parserOut == false ) { |
320 | | - $text = $sv->getRevText(); |
321 | | - # Parse the text |
322 | | - $parserOut = FlaggedRevs::parseStableText( $article, $text, $sv->getRevId() ); |
323 | | - } |
324 | | - } |
325 | | - # Update page fields |
326 | | - FlaggedRevs::updateStableVersion( $article, $sv->getRevision() ); |
327 | | - # Get the list of categories that must be reviewed |
328 | | - $reviewedCats = array(); |
329 | | - $msg = wfMsgForContent( 'flaggedrevs-stable-categories' ); |
330 | | - if ( !wfEmptyMsg( 'flaggedrevs-stable-categories', $msg ) ) { |
331 | | - $list = explode( "\n*", "\n$msg" ); |
332 | | - foreach ( $list as $category ) { |
333 | | - $category = trim( $category ); |
334 | | - if ( $category != '' ) |
335 | | - $reviewedCats[$category] = 1; |
336 | | - } |
337 | | - } |
338 | | - $links = array(); |
339 | | - # Get any links that are only in the stable version... |
340 | | - foreach ( $parserOut->getLinks() as $ns => $titles ) { |
341 | | - foreach ( $titles as $title => $id ) { |
342 | | - if ( !isset( $linksUpdate->mLinks[$ns] ) |
343 | | - || !isset( $linksUpdate->mLinks[$ns][$title] ) ) |
344 | | - { |
345 | | - self::addLink( $links, $ns, $title ); |
346 | | - } |
347 | | - } |
348 | | - } |
349 | | - # Get any images that are only in the stable version... |
350 | | - foreach ( $parserOut->getImages() as $image => $n ) { |
351 | | - if ( !isset( $linksUpdate->mImages[$image] ) ) { |
352 | | - self::addLink( $links, NS_FILE, $image ); |
353 | | - } |
354 | | - } |
355 | | - # Get any templates that are only in the stable version... |
356 | | - foreach ( $parserOut->getTemplates() as $ns => $titles ) { |
357 | | - foreach ( $titles as $title => $id ) { |
358 | | - if ( !isset( $linksUpdate->mTemplates[$ns] ) |
359 | | - || !isset( $linksUpdate->mTemplates[$ns][$title] ) ) |
360 | | - { |
361 | | - self::addLink( $links, $ns, $title ); |
362 | | - } |
363 | | - } |
364 | | - } |
365 | | - # Get any categories that are only in the stable version... |
366 | | - foreach ( $parserOut->getCategories() as $category => $sort ) { |
367 | | - if ( !isset( $linksUpdate->mCategories[$category] ) ) { |
368 | | - // Stable categories must remain until removed from the stable version |
369 | | - if ( isset( $reviewedCats[$category] ) ) { |
370 | | - $linksUpdate->mCategories[$category] = $sort; |
| 298 | + if ( $sv ) { |
| 299 | + $stableCats = FlaggedRevs::getStableCategories(); |
| 300 | + // Short-circuit things that need stable version output |
| 301 | + if ( $stableCats || FlaggedRevs::inclusionSetting() != FR_INCLUDES_CURRENT ) { |
| 302 | + # Get the parsed stable version... |
| 303 | + if ( isset( $linksUpdate->fr_stableParserOut ) ) { |
| 304 | + $stableOut = $linksUpdate->fr_stableParserOut; // process cache |
371 | 305 | } else { |
372 | | - self::addLink( $links, NS_CATEGORY, $category ); |
| 306 | + # Try stable version cache, which should be up-to-date now. |
| 307 | + # Hack: use 'okStale' to ignore any previous invalidate() calls. |
| 308 | + $anon = new User(); // anon cache most likely to exist |
| 309 | + $stableOut = FlaggedRevs::getPageCache( $fa, $anon, 'okStale' ); |
| 310 | + if ( $stableOut == false && $wgUser->getId() ) { |
| 311 | + $stableOut = FlaggedRevs::getPageCache( $fa, $wgUser, 'okStale' ); |
| 312 | + } |
| 313 | + if ( $stableOut == false ) { // cache miss |
| 314 | + $text = $sv->getRevText(); |
| 315 | + $stableOut = FlaggedRevs::parseStableText( $fa, $text, $sv->getRevId() ); |
| 316 | + } |
373 | 317 | } |
| 318 | + # Tracking for certain categories depends only on the stable version |
| 319 | + self::stabilizeCategories( $linksUpdate, $stableOut, $stableCats ); |
| 320 | + # Update flaggedrevs link tracking tables |
| 321 | + $frLinksUpdate = new FRLinksUpdate( $linksUpdate, $stableOut ); |
| 322 | + $frLinksUpdate->doUpdate(); |
374 | 323 | } |
375 | | - } |
376 | | - $stableCats = $parserOut->getCategories(); // from stable version |
377 | | - foreach ( $reviewedCats as $category ) { |
378 | | - // Stable categories cannot be added until added to the stable version |
379 | | - if ( isset( $linksUpdate->mCategories[$category] ) |
380 | | - && !isset( $stableCats[$category] ) ) |
381 | | - { |
382 | | - unset( $linksUpdate->mCategories[$category] ); |
383 | | - } |
| 324 | + # Update flagged page related fields |
| 325 | + FlaggedRevs::updateStableVersion( $fa, $sv->getRevision() ); |
| 326 | + } else { |
| 327 | + # Empty flaggedrevs data for this page if there is no stable version |
| 328 | + FlaggedRevs::clearTrackingRows( $fa->getId() ); |
384 | 329 | } |
385 | | - # Get any link tracking changes |
386 | | - $existing = self::getExistingLinks( $pageId ); |
387 | | - $insertions = self::getLinkInsertions( $existing, $links, $pageId ); |
388 | | - $deletions = self::getLinkDeletions( $existing, $links ); |
389 | | - # Delete removed links |
390 | | - if ( $clause = self::makeWhereFrom2d( $deletions ) ) { |
391 | | - $where = array( 'ftr_from' => $pageId ); |
392 | | - $where[] = $clause; |
393 | | - $dbw->delete( 'flaggedrevs_tracking', $where, __METHOD__ ); |
| 330 | + # Refresh links for pages were only the stable version includes this page |
| 331 | + if ( $linksUpdate->mRecursive ) { |
| 332 | + FRLinksUpdate::queueRefreshLinksJobs( $fa->getTitle() ); |
394 | 333 | } |
395 | | - # Add any new links |
396 | | - if ( count( $insertions ) ) { |
397 | | - $dbw->insert( 'flaggedrevs_tracking', $insertions, __METHOD__, 'IGNORE' ); |
398 | | - } |
| 334 | + wfProfileOut( __METHOD__ ); |
399 | 335 | return true; |
400 | 336 | } |
401 | 337 | |
402 | | - protected static function addLink( array &$links, $ns, $dbKey ) { |
403 | | - if ( !isset( $links[$ns] ) ) { |
404 | | - $links[$ns] = array(); |
405 | | - } |
406 | | - $links[$ns][$dbKey] = 1; |
407 | | - } |
408 | | - |
409 | | - protected static function getExistingLinks( $pageId ) { |
410 | | - $dbr = wfGetDB( DB_SLAVE ); |
411 | | - $res = $dbr->select( 'flaggedrevs_tracking', |
412 | | - array( 'ftr_namespace', 'ftr_title' ), |
413 | | - array( 'ftr_from' => $pageId ), |
414 | | - __METHOD__ ); |
415 | | - $arr = array(); |
416 | | - while ( $row = $dbr->fetchObject( $res ) ) { |
417 | | - if ( !isset( $arr[$row->ftr_namespace] ) ) { |
418 | | - $arr[$row->ftr_namespace] = array(); |
| 338 | + /** |
| 339 | + * Make "stable categories" appear in categorylinks for a page |
| 340 | + * iff they are currently in the stable version of the page (if there is one) |
| 341 | + * @TODO: replace raw $linksUpdate field accesses |
| 342 | + */ |
| 343 | + protected static function stabilizeCategories( |
| 344 | + LinksUpdate $linksUpdate, ParserOutput $stableOut, array $stableCats |
| 345 | + ) { |
| 346 | + $sCategories = $stableOut->getCategories(); // assoc array (name => sortkey) |
| 347 | + foreach ( $stableCats as $category ) { |
| 348 | + $category = str_replace( ' ', '_', $category ); // ' ' -> underscore |
| 349 | + // Stable categories cannot be added until added to the stable version |
| 350 | + if ( isset( $linksUpdate->mCategories[$category] ) // in current |
| 351 | + && !isset( $sCategories[$category] ) ) // not in stable |
| 352 | + { |
| 353 | + unset( $linksUpdate->mCategories[$category] ); |
| 354 | + // Stable categories must remain until removed from the stable version |
| 355 | + } elseif ( !isset( $linksUpdate->mCategories[$category] ) // not in current |
| 356 | + && isset( $sCategories[$category] ) ) // in stable |
| 357 | + { |
| 358 | + $linksUpdate->mCategories[$category] = $sCategories[$category]; |
419 | 359 | } |
420 | | - $arr[$row->ftr_namespace][$row->ftr_title] = 1; |
421 | 360 | } |
422 | | - return $arr; |
423 | 361 | } |
424 | 362 | |
425 | | - protected static function makeWhereFrom2d( &$arr ) { |
426 | | - $lb = new LinkBatch(); |
427 | | - $lb->setArray( $arr ); |
428 | | - return $lb->constructSet( 'ftr', wfGetDB( DB_SLAVE ) ); |
429 | | - } |
430 | | - |
431 | | - protected static function getLinkInsertions( $existing, $new, $pageId ) { |
432 | | - $arr = array(); |
433 | | - foreach ( $new as $ns => $dbkeys ) { |
434 | | - $diffs = isset( $existing[$ns] ) ? |
435 | | - array_diff_key( $dbkeys, $existing[$ns] ) : $dbkeys; |
436 | | - foreach ( $diffs as $dbk => $id ) { |
437 | | - $arr[] = array( |
438 | | - 'ftr_from' => $pageId, |
439 | | - 'ftr_namespace' => $ns, |
440 | | - 'ftr_title' => $dbk |
441 | | - ); |
442 | | - } |
443 | | - } |
444 | | - return $arr; |
445 | | - } |
446 | | - |
447 | | - protected static function getLinkDeletions( $existing, $new ) { |
448 | | - $del = array(); |
449 | | - foreach ( $existing as $ns => $dbkeys ) { |
450 | | - if ( isset( $new[$ns] ) ) { |
451 | | - $del[$ns] = array_diff_key( $existing[$ns], $new[$ns] ); |
452 | | - } else { |
453 | | - $del[$ns] = $existing[$ns]; |
454 | | - } |
455 | | - } |
456 | | - return $del; |
457 | | - } |
458 | | - |
459 | 363 | /* |
460 | 364 | * Update pages where only the stable version links to a page |
461 | 365 | * that was just changed in some way. |