Index: trunk/extensions/FlaggedRevs/backend/FRInclusionCache.php |
— | — | @@ -19,55 +19,98 @@ |
20 | 20 | ) { |
21 | 21 | global $wgParser, $wgMemc; |
22 | 22 | wfProfileIn( __METHOD__ ); |
23 | | - $versions = false; |
| 23 | + |
24 | 24 | $key = self::getCacheKey( $article->getTitle(), $rev->getId() ); |
25 | | - if ( $regen !== 'regen' ) { // check cache |
| 25 | + if ( $regen === 'regen' ) { |
| 26 | + $versions = false; // skip cache |
| 27 | + } elseif ( $rev->isCurrent() ) { |
| 28 | + // Check cache entry against page_touched |
| 29 | + $versions = FlaggedRevs::getMemcValue( $wgMemc->get( $key ), $article ); |
| 30 | + } else { |
| 31 | + // Old revs won't always be invalidated with template/file changes. |
| 32 | + // Also, we don't care if page_touched changed due to a direct edit. |
26 | 33 | $versions = FlaggedRevs::getMemcValue( $wgMemc->get( $key ), $article, 'allowStale' ); |
| 34 | + if ( is_array( $versions ) ) { // entry exists |
| 35 | + // Sanity check that the cache is reasonably up to date |
| 36 | + list( $templates, $files ) = $versions; |
| 37 | + if ( self::templatesStale( $templates ) || self::filesStale( $files ) ) { |
| 38 | + $versions = false; // no good |
| 39 | + } |
| 40 | + } |
27 | 41 | } |
| 42 | + |
28 | 43 | if ( !is_array( $versions ) ) { // cache miss |
29 | 44 | $pOut = false; |
30 | 45 | if ( $rev->isCurrent() ) { |
31 | 46 | $parserCache = ParserCache::singleton(); |
32 | | - # Try current version parser cache (as anon)... |
| 47 | + # Try current version parser cache for this user... |
33 | 48 | $pOut = $parserCache->get( $article, $article->makeParserOptions( $user ) ); |
34 | | - if ( $pOut == false && $rev->getUser() ) { // try the user who saved the change |
35 | | - $author = User::newFromId( $rev->getUser() ); |
36 | | - $pOut = $parserCache->get( $article, $article->makeParserOptions( $author ) ); |
| 49 | + if ( $pOut == false ) { |
| 50 | + # Try current version parser cache for the revision author... |
| 51 | + $optsUser = $rev->getUser() |
| 52 | + ? User::newFromId( $rev->getUser() ) |
| 53 | + : 'canonical'; |
| 54 | + $pOut = $parserCache->get( $article, $article->makeParserOptions( $optsUser ) ); |
37 | 55 | } |
38 | 56 | } |
39 | 57 | // ParserOutput::mImageTimeKeys wasn't always there |
40 | 58 | if ( $pOut == false || !FlaggedRevs::parserOutputIsVersioned( $pOut ) ) { |
41 | | - $title = $article->getTitle(); |
42 | | - $pOpts = ParserOptions::newFromUser( $user ); // Note: tidy off |
43 | 59 | $pOut = $wgParser->parse( |
44 | | - $rev->getText(), $title, $pOpts, true, true, $rev->getId() ); |
| 60 | + $rev->getText(), |
| 61 | + $article->getTitle(), |
| 62 | + ParserOptions::newFromUser( $user ), // Note: tidy off |
| 63 | + true, |
| 64 | + true, |
| 65 | + $rev->getId() |
| 66 | + ); |
45 | 67 | } |
46 | 68 | # Get the template/file versions used... |
47 | 69 | $versions = array( $pOut->getTemplateIds(), $pOut->getFileSearchOptions() ); |
48 | 70 | # Save to cache (check cache expiry for dynamic elements)... |
49 | 71 | $data = FlaggedRevs::makeMemcObj( $versions ); |
50 | 72 | $wgMemc->set( $key, $data, $pOut->getCacheExpiry() ); |
51 | | - } else { |
52 | | - $tVersions =& $versions[0]; // templates |
53 | | - # Do a link batch query for page_latest... |
54 | | - $lb = new LinkBatch(); |
55 | | - foreach ( $tVersions as $ns => $tmps ) { |
56 | | - foreach ( $tmps as $dbKey => $revIdDraft ) { |
57 | | - $lb->add( $ns, $dbKey ); |
| 73 | + } |
| 74 | + |
| 75 | + wfProfileOut( __METHOD__ ); |
| 76 | + return $versions; |
| 77 | + } |
| 78 | + |
| 79 | + protected static function templatesStale( array $tVersions ) { |
| 80 | + # Do a link batch query for page_latest... |
| 81 | + $lb = new LinkBatch(); |
| 82 | + foreach ( $tVersions as $ns => $tmps ) { |
| 83 | + foreach ( $tmps as $dbKey => $revIdDraft ) { |
| 84 | + $lb->add( $ns, $dbKey ); |
| 85 | + } |
| 86 | + } |
| 87 | + $lb->execute(); |
| 88 | + # Check if any of these templates have a newer version |
| 89 | + foreach ( $tVersions as $ns => $tmps ) { |
| 90 | + foreach ( $tmps as $dbKey => $revIdDraft ) { |
| 91 | + $title = Title::makeTitle( $ns, $dbKey ); |
| 92 | + if ( $revIdDraft != $title->getLatestRevID() ) { |
| 93 | + return true; |
58 | 94 | } |
59 | 95 | } |
60 | | - $lb->execute(); |
61 | | - # Update array with the current page_latest values. |
62 | | - # This kludge is there since $newTemplates (thus $revIdDraft) is cached. |
63 | | - foreach ( $tVersions as $ns => &$tmps ) { |
64 | | - foreach ( $tmps as $dbKey => &$revIdDraft ) { |
65 | | - $title = Title::makeTitle( $ns, $dbKey ); |
66 | | - $revIdDraft = (int)$title->getLatestRevID(); |
| 96 | + } |
| 97 | + return false; |
| 98 | + } |
| 99 | + |
| 100 | + protected static function filesStale( array $fVersions ) { |
| 101 | + # Check if any of these files have a newer version |
| 102 | + foreach ( $fVersions as $name => $timeAndSHA1 ) { |
| 103 | + $file = wfFindFile( $name ); |
| 104 | + if ( $file ) { |
| 105 | + if ( $file->getTimestamp() != $timeAndSHA1['time'] ) { |
| 106 | + return true; |
67 | 107 | } |
| 108 | + } else { |
| 109 | + if ( $timeAndSHA1['time'] ) { |
| 110 | + return true; |
| 111 | + } |
68 | 112 | } |
69 | 113 | } |
70 | | - wfProfileOut( __METHOD__ ); |
71 | | - return $versions; |
| 114 | + return false; |
72 | 115 | } |
73 | 116 | |
74 | 117 | /** |