Merge "mediawiki.jqueryMsg: Declare dependency on user.options"
[lhc/web/wiklou.git] / includes / OutputPage.php
index a3a5a27..0ed847e 100644 (file)
@@ -20,6 +20,8 @@
  * @file
  */
 
+use MediaWiki\Logger\LoggerFactory;
+
 /**
  * This class should be covered by a general architecture document which does
  * not exist as of January 2011.  This is one of the Core classes and should
@@ -302,6 +304,11 @@ class OutputPage extends ContextSource {
         */
        private $mEnableSectionEditLinks = true;
 
+       /**
+        * @var string|null The URL to send in a <link> element with rel=copyright
+        */
+       private $copyrightUrl;
+
        /**
         * Constructor for OutputPage. This should not be called directly.
         * Instead a new RequestContext should be created and it will implicitly create
@@ -338,6 +345,18 @@ class OutputPage extends ContextSource {
                return $this->mRedirect;
        }
 
+       /**
+        * Set the copyright URL to send with the output.
+        * Empty string to omit, null to reset.
+        *
+        * @since 1.26
+        *
+        * @param string|null $url
+        */
+       public function setCopyrightUrl( $url ) {
+               $this->copyrightUrl = $url;
+       }
+
        /**
         * Set the HTTP status code to send with the output.
         *
@@ -598,7 +617,8 @@ class OutputPage extends ContextSource {
                        $module = $resourceLoader->getModule( $val );
 
                        if ( $module instanceof ResourceLoaderModule && $module->isPositionDefault() ) {
-                               $warning = __METHOD__ . ': style module should define its position explicitly: ' . $val . ' ' . get_class( $module );
+                               $warning = __METHOD__ . ': style module should define its position explicitly: ' .
+                                       $val . ' ' . get_class( $module );
                                wfDebugLog( 'resourceloader', $warning );
                                wfLogWarning( $warning );
                        }
@@ -807,9 +827,9 @@ class OutputPage extends ContextSource {
                # this breaks strtotime().
                $clientHeader = preg_replace( '/;.*$/', '', $clientHeader );
 
-               wfSuppressWarnings(); // E_STRICT system time bitching
+               MediaWiki\suppressWarnings(); // E_STRICT system time bitching
                $clientHeaderTime = strtotime( $clientHeader );
-               wfRestoreWarnings();
+               MediaWiki\restoreWarnings();
                if ( !$clientHeaderTime ) {
                        wfDebug( __METHOD__
                                . ": unable to parse the client's If-Modified-Since header: $clientHeader\n" );
@@ -836,10 +856,10 @@ class OutputPage extends ContextSource {
                }
 
                # Not modified
-               # Give a 304 response code and disable body output
+               # Give a 304 Not Modified response code and disable body output
                wfDebug( __METHOD__ . ": NOT MODIFIED, $info\n", 'log' );
                ini_set( 'zlib.output_compression', 0 );
-               $this->getRequest()->response()->header( "HTTP/1.1 304 Not Modified" );
+               $this->getRequest()->response()->statusHeader( 304 );
                $this->sendCacheControl();
                $this->disable();
 
@@ -2218,8 +2238,7 @@ class OutputPage extends ContextSource {
                        if ( Hooks::run( "BeforePageRedirect", array( $this, &$redirect, &$code ) ) ) {
                                if ( $code == '301' || $code == '303' ) {
                                        if ( !$config->get( 'DebugRedirects' ) ) {
-                                               $message = HttpStatus::getMessage( $code );
-                                               $response->header( "HTTP/1.1 $code $message" );
+                                               $response->statusHeader( $code );
                                        }
                                        $this->mLastModified = wfTimestamp( TS_RFC2822 );
                                }
@@ -2241,10 +2260,7 @@ class OutputPage extends ContextSource {
 
                        return;
                } elseif ( $this->mStatusCode ) {
-                       $message = HttpStatus::getMessage( $this->mStatusCode );
-                       if ( $message ) {
-                               $response->header( 'HTTP/1.1 ' . $this->mStatusCode . ' ' . $message );
-                       }
+                       $response->statusHeader( $this->mStatusCode );
                }
 
                # Buffer output; final headers may depend on later processing
@@ -2266,7 +2282,6 @@ class OutputPage extends ContextSource {
                if ( $this->mArticleBodyOnly ) {
                        echo $this->mBodytext;
                } else {
-
                        $sk = $this->getSkin();
                        // add skin specific modules
                        $modules = $sk->getDefaultModules();
@@ -2737,7 +2752,10 @@ class OutputPage extends ContextSource {
         */
        public function getResourceLoader() {
                if ( is_null( $this->mResourceLoader ) ) {
-                       $this->mResourceLoader = new ResourceLoader( $this->getConfig() );
+                       $this->mResourceLoader = new ResourceLoader(
+                               $this->getConfig(),
+                               LoggerFactory::getInstance( 'resourceloader' )
+                       );
                }
                return $this->mResourceLoader;
        }
@@ -2981,8 +2999,10 @@ class OutputPage extends ContextSource {
                // Load embeddable private modules before any loader links
                // This needs to be TYPE_COMBINED so these modules are properly wrapped
                // in mw.loader.implement() calls and deferred until mw.user is available
-               $embedScripts = array( 'user.options', 'user.tokens' );
+               $embedScripts = array( 'user.options' );
                $links[] = $this->makeResourceLoaderLink( $embedScripts, ResourceLoaderModule::TYPE_COMBINED );
+               // Separate user.tokens as otherwise caching will be allowed (T84960)
+               $links[] = $this->makeResourceLoaderLink( 'user.tokens', ResourceLoaderModule::TYPE_COMBINED );
 
                // Scripts and messages "only" requests marked for top inclusion
                $links[] = $this->makeResourceLoaderLink(
@@ -3429,17 +3449,21 @@ class OutputPage extends ContextSource {
                }
 
                # Copyright
-               $copyright = '';
-               if ( $config->get( 'RightsPage' ) ) {
-                       $copy = Title::newFromText( $config->get( 'RightsPage' ) );
+               if ( $this->copyrightUrl !== null ) {
+                       $copyright = $this->copyrightUrl;
+               } else {
+                       $copyright = '';
+                       if ( $config->get( 'RightsPage' ) ) {
+                               $copy = Title::newFromText( $config->get( 'RightsPage' ) );
 
-                       if ( $copy ) {
-                               $copyright = $copy->getLocalURL();
+                               if ( $copy ) {
+                                       $copyright = $copy->getLocalURL();
+                               }
                        }
-               }
 
-               if ( !$copyright && $config->get( 'RightsUrl' ) ) {
-                       $copyright = $config->get( 'RightsUrl' );
+                       if ( !$copyright && $config->get( 'RightsUrl' ) ) {
+                               $copyright = $config->get( 'RightsUrl' );
+                       }
                }
 
                if ( $copyright ) {
@@ -3500,8 +3524,25 @@ class OutputPage extends ContextSource {
                        if ( $canonicalUrl !== false ) {
                                $canonicalUrl = wfExpandUrl( $canonicalUrl, PROTO_CANONICAL );
                        } else {
-                               $reqUrl = $this->getRequest()->getRequestURL();
-                               $canonicalUrl = wfExpandUrl( $reqUrl, PROTO_CANONICAL );
+                               if ( $this->isArticleRelated() ) {
+                                       // This affects all requests where "setArticleRelated" is true. This is
+                                       // typically all requests that show content (query title, curid, oldid, diff),
+                                       // and all wikipage actions (edit, delete, purge, info, history etc.).
+                                       // It does not apply to File pages and Special pages.
+                                       // 'history' and 'info' actions address page metadata rather than the page
+                                       // content itself, so they may not be canonicalized to the view page url.
+                                       // TODO: this ought to be better encapsulated in the Action class.
+                                       $action = Action::getActionName( $this->getContext() );
+                                       if ( in_array( $action, array( 'history', 'info' ) ) ) {
+                                               $query = "action={$action}";
+                                       } else {
+                                               $query = '';
+                                       }
+                                       $canonicalUrl = $this->getTitle()->getCanonicalURL( $query );
+                               } else {
+                                       $reqUrl = $this->getRequest()->getRequestURL();
+                                       $canonicalUrl = wfExpandUrl( $reqUrl, PROTO_CANONICAL );
+                               }
                        }
                }
                if ( $canonicalUrl !== false ) {