Make transcluded special pages not disable cache in miser mode.
authorBrian Wolff <bawolff+wn@gmail.com>
Fri, 20 Jun 2014 16:18:29 +0000 (13:18 -0300)
committerAaron Schulz <aschulz@wikimedia.org>
Wed, 15 Jun 2016 03:46:32 +0000 (20:46 -0700)
Previously {{Special:Foo}} would cause parser cache to be disabled,
now have a method in SpecialPage to control this behaviour and set
arbitrary caching times.

Note: This does not affect caching of direct views to the special page

The new default is now disabling cache if not in miser mode,
otherwise setting to 1 hour, except for Special:Recentchanges
and Special:Newpages which set to 5 minutes. These values are
possibly really low, but for now I think best to be close to the
old behaviour. We had 0 caching for these things for years, and
afaik it hasn't caused any big issues. Part of me wonders if
Special:Recentchanges should stay at 0, but that sounds crazy.

This change also causes transcluded special pages to not be
"per-user" if they are being cached (Specificly $wgUser et al
become 127.0.0.1).

Bug: 60561
Change-Id: Id9ce987adeaa69d886eb1c5cd74c01072583e84d

includes/parser/Parser.php
includes/specialpage/SpecialPage.php
includes/specials/SpecialNewpages.php
includes/specials/SpecialRecentchanges.php

index b563613..6c84623 100644 (file)
@@ -3125,6 +3125,7 @@ class Parser {
                                        && $this->mOptions->getAllowSpecialInclusion()
                                        && $this->ot['html']
                                ) {
+                                       $specialPage = SpecialPageFactory::getPage( $title->getDBkey() );
                                        // Pass the template arguments as URL parameters.
                                        // "uselang" will have no effect since the Language object
                                        // is forced to the one defined in ParserOptions.
@@ -3143,7 +3144,12 @@ class Parser {
                                        $context = new RequestContext;
                                        $context->setTitle( $title );
                                        $context->setRequest( new FauxRequest( $pageArgs ) );
-                                       $context->setUser( $this->getUser() );
+                                       if ( $specialPage && $specialPage->maxIncludeCacheTime() === 0 ) {
+                                               $context->setUser( $this->getUser() );
+                                       } else {
+                                               // If this page is cached, then we better not be per user.
+                                               $context->setUser( User::newFromName( '127.0.0.1', false ) );
+                                       }
                                        $context->setLanguage( $this->mOptions->getUserLangObj() );
                                        $ret = SpecialPageFactory::capturePath( $title, $context );
                                        if ( $ret ) {
@@ -3151,8 +3157,9 @@ class Parser {
                                                $this->mOutput->addOutputPageMetadata( $context->getOutput() );
                                                $found = true;
                                                $isHTML = true;
-                                               // Severely reduce cache time to keep content dynamic
-                                               $this->mOutput->updateCacheExpiry( 30 );
+                                               if ( $specialPage && $specialPage->maxIncludeCacheTime() !== false ) {
+                                                       $this->mOutput->updateCacheExpiry( $specialPage->maxIncludeCacheTime() );
+                                               }
                                        }
                                } elseif ( MWNamespace::isNonincludable( $title->getNamespace() ) ) {
                                        $found = false; # access denied
index 408c726..6624414 100644 (file)
@@ -175,6 +175,25 @@ class SpecialPage {
                return $this->mIncludable;
        }
 
+       /**
+        * How long to cache page when it is being included.
+        *
+        * @note If cache time is not 0, then the current user becomes an anon
+        *   if you want to do any per-user customizations, than this method
+        *   must be overriden to return 0.
+        * @since 1.26
+        * @return int Time in seconds, 0 to disable caching altogether,
+        *  false to use the parent page's cache settings
+        */
+       public function maxIncludeCacheTime() {
+               global $wgMiserMode;
+               if ( !$wgMiserMode ) {
+                       return 0;
+               } else {
+                       return 60*60;
+               }
+       }
+
        /**
         * Whether the special page is being evaluated via transclusion
         * @param bool $x
index c24b054..ff9a899 100644 (file)
@@ -478,4 +478,18 @@ class SpecialNewpages extends IncludableSpecialPage {
        protected function getGroupName() {
                return 'changes';
        }
+
+       /**
+        * How long to cache page when it is being included.
+        *
+        * @return int Time in seconds, 0 to disable caching altogether
+        */
+       public function maxIncludeCacheTime() {
+               global $wgMiserMode;
+               if ( !$wgMiserMode ) {
+                       return 0;
+               } else {
+                       return 60*5;
+               }
+       }
 }
index b6398cb..36ccd4a 100644 (file)
@@ -794,4 +794,19 @@ class SpecialRecentChanges extends ChangesListSpecialPage {
        public function isIncludable() {
                return true;
        }
+
+       /**
+        * How long to cache page when it is being included.
+        *
+        * @return int|bool Time in seconds, 0 to disable caching altogether
+        */
+       public function maxIncludeCacheTime() {
+               global $wgMiserMode;
+               if ( !$wgMiserMode ) {
+                       return 0;
+               } else {
+                       return 60*5;
+               }
+       }
+
 }