r68153 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r68152‎ | r68153 | r68154 >
Date:06:55, 17 June 2010
Author:aaron
Status:deferred
Tags:
Comment:
* Refactored extraLinksUpdate into FRLinksUpdate class and onLinksUpdate(), stabilizeCategories() functions
* Removed bogus old line from getPageCache(), added $staleOK param, and fixed comments
* Fixed msg-based stable categories feature, probably broken forever
* Added performance short-circuit to the above tasks
* Deal with refreshLinks for items used only in stable versions of pages (like FRCacheUpdate does for invalidations)
Modified paths:
  • /trunk/extensions/FlaggedRevs/FRLinksUpdate.php (added) (history)
  • /trunk/extensions/FlaggedRevs/FlaggedRevs.class.php (modified) (history)
  • /trunk/extensions/FlaggedRevs/FlaggedRevs.hooks.php (modified) (history)
  • /trunk/extensions/FlaggedRevs/FlaggedRevs.php (modified) (history)

Diff [purge]

Index: trunk/extensions/FlaggedRevs/FlaggedRevs.php
@@ -311,6 +311,7 @@
312312 $wgAutoloadClasses['FlaggedRevsLogs'] = $dir . 'FlaggedRevsLogs.php';
313313 $wgAutoloadClasses['FRCacheUpdate'] = $dir . 'FRCacheUpdate.php';
314314 $wgAutoloadClasses['FRCacheUpdateJob'] = $dir . 'FRCacheUpdate.php';
 315+$wgAutoloadClasses['FRLinksUpdate'] = $dir . 'FRLinksUpdate.php';
315316
316317 # Special case cache invalidations
317318 $wgJobClasses['flaggedrevs_CacheUpdate'] = 'FRCacheUpdateJob';
@@ -490,7 +491,7 @@
491492 # Extra cache updates for stable versions
492493 $wgHooks['HTMLCacheUpdate::doUpdate'][] = 'FlaggedRevsHooks::doCacheUpdate';
493494 # Updates stable version tracking data
494 -$wgHooks['LinksUpdate'][] = 'FlaggedRevsHooks::extraLinksUpdate';
 495+$wgHooks['LinksUpdate'][] = 'FlaggedRevsHooks::onLinksUpdate';
495496 # Clear dead config rows
496497 $wgHooks['ArticleDeleteComplete'][] = 'FlaggedRevsHooks::onArticleDelete';
497498 $wgHooks['ArticleRevisionVisibilitySet'][] = 'FlaggedRevsHooks::onRevisionDelete';
Index: trunk/extensions/FlaggedRevs/FlaggedRevs.class.php
@@ -561,14 +561,15 @@
562562 $options->setTidy( true );
563563 return $options;
564564 }
565 -
 565+
566566 /**
 567+ * Get the page cache for the stable version of an article
567568 * @param Article $article
568569 * @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)
571572 */
572 - public static function getPageCache( Article $article, $user ) {
 573+ public static function getPageCache( Article $article, $user, $okStale = false ) {
573574 global $parserMemc, $wgCacheEpoch;
574575 wfProfileIn( __METHOD__ );
575576 # Make sure it is valid
@@ -587,7 +588,7 @@
588589 $canCache = $article->checkTouched();
589590 $cacheTime = $value->getCacheTime();
590591 $touched = $article->mTouched;
591 - if ( !$canCache || $value->expired( $touched ) ) {
 592+ if ( !$canCache || ( $value->expired( $touched ) && $okStale !== 'okStale' ) ) {
592593 if ( !$canCache ) {
593594 wfIncrStats( "pcache_miss_invalid" );
594595 wfDebug( "Invalid cached redirect, touched $touched, epoch $wgCacheEpoch, cached $cacheTime\n" );
@@ -598,9 +599,6 @@
599600 $parserMemc->delete( $key );
600601 $value = false;
601602 } else {
602 - if ( isset( $value->mTimestamp ) ) {
603 - $article->mTimestamp = $value->mTimestamp;
604 - }
605603 wfIncrStats( "pcache_hit" );
606604 }
607605 } else {
@@ -608,7 +606,6 @@
609607 wfIncrStats( "pcache_miss_absent" );
610608 $value = false;
611609 }
612 -
613610 wfProfileOut( __METHOD__ );
614611 return $value;
615612 }
@@ -793,7 +790,9 @@
794791 * @param mixed $latest, the latest rev ID (optional)
795792 * Updates the tracking tables and pending edit count cache. Called on edit.
796793 */
797 - public static function updateStableVersion( Article $article, Revision $rev, $latest = null ) {
 794+ public static function updateStableVersion(
 795+ Article $article, Revision $rev, $latest = null
 796+ ) {
798797 if ( !$article->getId() ) {
799798 return true; // no bogus entries
800799 }
@@ -1392,8 +1391,29 @@
13931392 NS_FILE : $title->getNamespace(); // Treat NS_MEDIA as NS_FILE
13941393 return ( in_array( $ns, $namespaces ) );
13951394 }
1396 -
 1395+
13971396 /**
 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+ /**
13981418 * Clear FlaggedRevs tracking tables for this page
13991419 * @param mixed $pageId (int or array)
14001420 */
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
1196 + native
Index: trunk/extensions/FlaggedRevs/FlaggedRevs.hooks.php
@@ -282,179 +282,83 @@
283283 return true;
284284 }
285285
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 );
292291 # Check if this page has a stable version...
 292+ $sv = null;
293293 if ( isset( $u->fr_stableRev ) ) {
294294 $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
302297 }
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
371305 } 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+ }
373317 }
 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();
374323 }
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() );
384329 }
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() );
394333 }
395 - # Add any new links
396 - if ( count( $insertions ) ) {
397 - $dbw->insert( 'flaggedrevs_tracking', $insertions, __METHOD__, 'IGNORE' );
398 - }
 334+ wfProfileOut( __METHOD__ );
399335 return true;
400336 }
401337
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];
419359 }
420 - $arr[$row->ftr_namespace][$row->ftr_title] = 1;
421360 }
422 - return $arr;
423361 }
424362
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 -
459363 /*
460364 * Update pages where only the stable version links to a page
461365 * that was just changed in some way.

Status & tagging log