(bug 32412) TOC links on [[Special:EditWatchlist]] now points to the fieldset
[lhc/web/wiklou.git] / includes / OutputPage.php
index 7e3812e..30cb9b7 100644 (file)
@@ -13,7 +13,7 @@ if ( !defined( 'MEDIAWIKI' ) ) {
  *
  * @todo FIXME: Another class handles sending the whole page to the client.
  *
- * Some comments comes from a pairing session between Zak Greant and Ashar Voultoiz
+ * Some comments comes from a pairing session between Zak Greant and Antoine Musso
  * in November 2010.
  *
  * @todo document
@@ -67,7 +67,7 @@ class OutputPage extends ContextSource {
         * Contains the page subtitle. Special pages usually have some links here.
         * Don't confuse with site subtitle added by skins.
         */
-       var $mSubtitle = '';
+       private $mSubtitle = array();
 
        var $mRedirect = '';
        var $mStatusCode;
@@ -152,7 +152,10 @@ class OutputPage extends ContextSource {
        // Parser related.
        var $mContainsOldMagic = 0, $mContainsNewMagic = 0;
 
-       /// lazy initialised, use parserOptions()
+       /**
+        * lazy initialised, use parserOptions()
+        * @var ParserOptions
+        */
        protected $mParserOptions = null;
 
        /**
@@ -757,7 +760,11 @@ class OutputPage extends ContextSource {
         * @param $name string
         */
        public function setHTMLTitle( $name ) {
-               $this->mHTMLtitle = $name;
+               if ( $name instanceof Message ) {
+                       $this->mHTMLtitle = $name->setContext( $this->getContext() )->text();
+               } else {
+                       $this->mHTMLtitle = $name;
+               }
        }
 
        /**
@@ -775,16 +782,20 @@ class OutputPage extends ContextSource {
         * This function automatically sets \<title\> to the same content as \<h1\> but with all tags removed.
         * Bad tags that were escaped in \<h1\> will still be escaped in \<title\>, and good tags like \<i\> will be dropped entirely.
         *
-        * @param $name string
+        * @param $name string|Message
         */
        public function setPageTitle( $name ) {
+               if ( $name instanceof Message ) {
+                       $name = $name->setContext( $this->getContext() )->text();
+               }
+
                # change "<script>foo&bar</script>" to "&lt;script&gt;foo&amp;bar&lt;/script&gt;"
                # but leave "<i>foobar</i>" alone
                $nameWithTags = Sanitizer::normalizeCharReferences( Sanitizer::removeHTMLtags( $name ) );
                $this->mPagetitle = $nameWithTags;
 
                # change "<i>foo&amp;bar</i>" to "foo&bar"
-               $this->setHTMLTitle( wfMsg( 'pagetitle', Sanitizer::stripAllTags( $nameWithTags ) ) );
+               $this->setHTMLTitle( $this->msg( 'pagetitle', Sanitizer::stripAllTags( $nameWithTags ) ) );
        }
 
        /**
@@ -809,19 +820,54 @@ class OutputPage extends ContextSource {
        /**
         * Replace the subtile with $str
         *
-        * @param $str String: new value of the subtitle
+        * @param $str String|Message: new value of the subtitle
         */
        public function setSubtitle( $str ) {
-               $this->mSubtitle = /*$this->parse(*/ $str /*)*/; // @bug 2514
+               $this->clearSubtitle();
+               $this->addSubtitle( $str );
        }
 
        /**
         * Add $str to the subtitle
         *
-        * @param $str String to add to the subtitle
+        * @deprecated in 1.19; use addSubtitle() instead
+        * @param $str String|Message to add to the subtitle
         */
        public function appendSubtitle( $str ) {
-               $this->mSubtitle .= /*$this->parse(*/ $str /*)*/; // @bug 2514
+               $this->addSubtitle( $str );
+       }
+
+       /**
+        * Add $str to the subtitle
+        *
+        * @param $str String|Message to add to the subtitle
+        */
+       public function addSubtitle( $str ) {
+               if ( $str instanceof Message ) {
+                       $this->mSubtitle[] = $str->setContext( $this->getContext() )->parse();
+               } else {
+                       $this->mSubtitle[] = $str;
+               }
+       }
+
+       /**
+        * Add a subtitle containing a backlink to a page
+        *
+        * @param $title Title to link to
+        */
+       public function addBacklinkSubtitle( Title $title ) {
+               $query = array();
+               if ( $title->isRedirect() ) {
+                       $query['redirect'] = 'no';
+               }
+               $this->addSubtitle( $this->msg( 'backlinksubtitle' )->rawParams( Linker::link( $title, null, array(), $query ) ) );
+       }
+
+       /**
+        * Clear the subtitles
+        */
+       public function clearSubtitle() {
+               $this->mSubtitle = array();
        }
 
        /**
@@ -830,7 +876,7 @@ class OutputPage extends ContextSource {
         * @return String
         */
        public function getSubtitle() {
-               return $this->mSubtitle;
+               return implode( "<br />\n\t\t\t\t", $this->mSubtitle );
        }
 
        /**
@@ -1629,7 +1675,7 @@ class OutputPage extends ContextSource {
                                $this->mVaryHeader[$header] = $option;
                        }
                }
-               $this->mVaryHeader[$header] = array_unique( $this->mVaryHeader[$header] );
+               $this->mVaryHeader[$header] = array_unique( (array)$this->mVaryHeader[$header] );
        }
 
        /**
@@ -1913,6 +1959,33 @@ class OutputPage extends ContextSource {
                throw new UserBlockedError( $this->getUser()->mBlock );
        }
 
+       /**
+        * Prepare this object to display an error page; disable caching and
+        * indexing, clear the current text and redirect, set the page's title
+        * and optionally an custom HTML title (content of the <title> tag).
+        *
+        * @param $pageTitle String|Message will be passed directly to setPageTitle()
+        * @param $htmlTitle String|Message will be passed directly to setHTMLTitle();
+        *                   optional, if not passed the <title> attribute will be
+        *                   based on $pageTitle
+        */
+       public function prepareErrorPage( $pageTitle, $htmlTitle = false ) {
+               if ( $this->getTitle() ) {
+                       $this->mDebugtext .= 'Original title: ' . $this->getTitle()->getPrefixedText() . "\n";
+               }
+
+               $this->setPageTitle( $pageTitle );
+               if ( $htmlTitle !== false ) {
+                       $this->setHTMLTitle( $htmlTitle );
+               }
+               $this->setRobotPolicy( 'noindex,nofollow' );
+               $this->setArticleRelated( false );
+               $this->enableClientCache( false );
+               $this->mRedirect = '';
+               $this->clearSubtitle();
+               $this->clearHTML();
+       }
+
        /**
         * Output a standard error page
         *
@@ -1924,16 +1997,7 @@ class OutputPage extends ContextSource {
         * @param $params Array: message parameters; ignored if $msg is a Message object
         */
        public function showErrorPage( $title, $msg, $params = array() ) {
-               if ( $this->getTitle() ) {
-                       $this->mDebugtext .= 'Original title: ' . $this->getTitle()->getPrefixedText() . "\n";
-               }
-               $this->setPageTitle( wfMsg( $title ) );
-               $this->setHTMLTitle( wfMsg( 'errorpagetitle' ) );
-               $this->setRobotPolicy( 'noindex,nofollow' );
-               $this->setArticleRelated( false );
-               $this->enableClientCache( false );
-               $this->mRedirect = '';
-               $this->mBodytext = '';
+               $this->prepareErrorPage( $this->msg( $title ), $this->msg( 'errorpagetitle' ) );
 
                if ( $msg instanceof Message ){
                        $this->addHTML( $msg->parse() );
@@ -1951,16 +2015,64 @@ class OutputPage extends ContextSource {
         * @param $action String: action that was denied or null if unknown
         */
        public function showPermissionsErrorPage( $errors, $action = null ) {
-               $this->mDebugtext .= 'Original title: ' .
-               $this->getTitle()->getPrefixedText() . "\n";
-               $this->setPageTitle( wfMsg( 'permissionserrors' ) );
-               $this->setHTMLTitle( wfMsg( 'permissionserrors' ) );
-               $this->setRobotPolicy( 'noindex,nofollow' );
-               $this->setArticleRelated( false );
-               $this->enableClientCache( false );
-               $this->mRedirect = '';
-               $this->mBodytext = '';
-               $this->addWikiText( $this->formatPermissionsErrorMessage( $errors, $action ) );
+               global $wgGroupPermissions;
+
+               // For some action (read, edit, create and upload), display a "login to do this action"
+               // error if all of the following conditions are met:
+               // 1. the user is not logged in
+               // 2. the only error is insufficient permissions (i.e. no block or something else)
+               // 3. the error can be avoided simply by logging in
+               if ( in_array( $action, array( 'read', 'edit', 'createpage', 'createtalk', 'upload' ) )
+                       && $this->getUser()->isAnon() && count( $errors ) == 1 && isset( $errors[0][0] )
+                       && ( $errors[0][0] == 'badaccess-groups' || $errors[0][0] == 'badaccess-group0' )
+                       && ( ( isset( $wgGroupPermissions['user'][$action] ) && $wgGroupPermissions['user'][$action] )
+                       || ( isset( $wgGroupPermissions['autoconfirmed'][$action] ) && $wgGroupPermissions['autoconfirmed'][$action] ) )
+               ) {
+                       $displayReturnto = null;
+                       $returnto = $this->getTitle();
+                       if ( $action == 'edit' ) {
+                               $msg = 'whitelistedittext';
+                               $displayReturnto = $returnto;
+                       } elseif ( $action == 'createpage' || $action == 'createtalk' ) {
+                               $msg = 'nocreatetext';
+                       } elseif ( $action == 'upload' ) {
+                               $msg = 'uploadnologintext';
+                       } else { # Read
+                               $msg = 'loginreqpagetext';
+                               $displayReturnto = Title::newMainPage();
+                       }
+
+                       $query = array();
+                       if ( $returnto ) {
+                               $query['returnto'] = $returnto->getPrefixedText();
+                               $request = $this->getRequest();
+                               if ( !$request->wasPosted() ) {
+                                       $returntoquery = $request->getValues();
+                                       unset( $returntoquery['title'] );
+                                       unset( $returntoquery['returnto'] );
+                                       unset( $returntoquery['returntoquery'] );
+                                       $query['returntoquery'] = wfArrayToCGI( $returntoquery );
+                               }
+                       }
+                       $loginLink = Linker::linkKnown(
+                               SpecialPage::getTitleFor( 'Userlogin' ),
+                               $this->msg( 'loginreqlink' )->escaped(),
+                               array(),
+                               $query
+                       );
+
+                       $this->prepareErrorPage( $this->msg( 'loginreqtitle' ) );
+                       $this->addHTML( $this->msg( $msg )->rawParams( $loginLink )->parse() );
+
+                       # Don't return to a page the user can't read otherwise
+                       # we'll end up in a pointless loop
+                       if ( $displayReturnto && $displayReturnto->userCanRead() ) {
+                               $this->returnToMain( null, $displayReturnto );
+                       }
+               } else {
+                       $this->prepareErrorPage( $this->msg( 'permissionserrors' ) );
+                       $this->addWikiText( $this->formatPermissionsErrorMessage( $errors, $action ) );
+               }
        }
 
        /**
@@ -1970,11 +2082,7 @@ class OutputPage extends ContextSource {
         * @param $version Mixed: the version of MediaWiki needed to use the page
         */
        public function versionRequired( $version ) {
-               $this->setPageTitle( wfMsg( 'versionrequired', $version ) );
-               $this->setHTMLTitle( wfMsg( 'versionrequired', $version ) );
-               $this->setRobotPolicy( 'noindex,nofollow' );
-               $this->setArticleRelated( false );
-               $this->mBodytext = '';
+               $this->prepareErrorPage( $this->msg( 'versionrequired', $version ) );
 
                $this->addWikiMsg( 'versionrequiredtext', $version );
                $this->returnToMain();
@@ -1991,33 +2099,11 @@ class OutputPage extends ContextSource {
 
        /**
         * Produce the stock "please login to use the wiki" page
+        *
+        * @deprecated in 1.19; throw the exception directly
         */
        public function loginToUse() {
-               if( $this->getUser()->isLoggedIn() ) {
-                       throw new PermissionsError( 'read' );
-               }
-
-               $this->setPageTitle( wfMsg( 'loginreqtitle' ) );
-               $this->setHtmlTitle( wfMsg( 'errorpagetitle' ) );
-               $this->setRobotPolicy( 'noindex,nofollow' );
-               $this->setArticleRelated( false );
-
-               $loginTitle = SpecialPage::getTitleFor( 'Userlogin' );
-               $loginLink = Linker::linkKnown(
-                       $loginTitle,
-                       wfMsgHtml( 'loginreqlink' ),
-                       array(),
-                       array( 'returnto' => $this->getTitle()->getPrefixedText() )
-               );
-               $this->addHTML( wfMessage( 'loginreqpagetext' )->rawParams( $loginLink )->parse() .
-                       "\n<!--" . $this->getTitle()->getPrefixedUrl() . '-->' );
-
-               # Don't return to the main page if the user can't read it
-               # otherwise we'll end up in a pointless loop
-               $mainPage = Title::newMainPage();
-               if( $mainPage->userCanRead() ) {
-                       $this->returnToMain( null, $mainPage );
-               }
+               throw new PermissionsError( 'read' );
        }
 
        /**
@@ -2029,14 +2115,14 @@ class OutputPage extends ContextSource {
         */
        public function formatPermissionsErrorMessage( $errors, $action = null ) {
                if ( $action == null ) {
-                       $text = wfMsgNoTrans( 'permissionserrorstext', count( $errors ) ) . "\n\n";
+                       $text = $this->msg( 'permissionserrorstext', count( $errors ) )->plain() . "\n\n";
                } else {
-                       $action_desc = wfMsgNoTrans( "action-$action" );
-                       $text = wfMsgNoTrans(
+                       $action_desc = $this->msg( "action-$action" )->plain();
+                       $text = $this->msg(
                                'permissionserrorstext-withaction',
                                count( $errors ),
                                $action_desc
-                       ) . "\n\n";
+                       )->plain() . "\n\n";
                }
 
                if ( count( $errors ) > 1 ) {
@@ -2044,13 +2130,13 @@ class OutputPage extends ContextSource {
 
                        foreach( $errors as $error ) {
                                $text .= '<li>';
-                               $text .= call_user_func_array( 'wfMsgNoTrans', $error );
+                               $text .= call_user_func_array( array( $this, 'msg' ), $error )->plain();
                                $text .= "</li>\n";
                        }
                        $text .= '</ul>';
                } else {
                        $text .= "<div class=\"permissions-errors\">\n" .
-                                       call_user_func_array( 'wfMsgNoTrans', reset( $errors ) ) .
+                                       call_user_func_array( array( $this, 'msg' ), reset( $errors ) )->plain() .
                                        "\n</div>";
                }
 
@@ -2090,12 +2176,10 @@ class OutputPage extends ContextSource {
                if ( !empty( $reasons ) ) {
                        // Permissions error
                        if( $source ) {
-                               $this->setPageTitle( wfMsg( 'viewsource' ) );
-                               $this->setSubtitle(
-                                       wfMsg( 'viewsourcefor', Linker::linkKnown( $this->getTitle() ) )
-                               );
+                               $this->setPageTitle( $this->msg( 'viewsource-title', $this->getTitle()->getPrefixedText() ) );
+                               $this->addBacklinkSubtitle( $this->getTitle() );
                        } else {
-                               $this->setPageTitle( wfMsg( 'badaccess' ) );
+                               $this->setPageTitle( $this->msg( 'badaccess' ) );
                        }
                        $this->addWikiText( $this->formatPermissionsErrorMessage( $reasons, $action ) );
                } else {
@@ -2120,8 +2204,8 @@ class OutputPage extends ContextSource {
                        $this->addHTML( Html::element( 'textarea', $params, $source ) );
 
                        // Show templates used by this article
-                       $article = new Article( $this->getTitle() );
-                       $templates = Linker::formatTemplates( $article->getUsedTemplates() );
+                       $page = WikiPage::factory( $this->getTitle() );
+                       $templates = Linker::formatTemplates( $page->getUsedTemplates() );
                        $this->addHTML( "<div class='templatesUsed'>
 $templates
 </div>
@@ -2160,37 +2244,34 @@ $templates
                                ? 'lag-warn-normal'
                                : 'lag-warn-high';
                        $wrap = Html::rawElement( 'div', array( 'class' => "mw-{$message}" ), "\n$1\n" );
-                       $this->wrapWikiMsg( "$wrap\n", array( $message, $this->getContext()->getLang()->formatNum( $lag ) ) );
+                       $this->wrapWikiMsg( "$wrap\n", array( $message, $this->getLanguage()->formatNum( $lag ) ) );
                }
        }
 
        public function showFatalError( $message ) {
-               $this->setPageTitle( wfMsg( 'internalerror' ) );
-               $this->setRobotPolicy( 'noindex,nofollow' );
-               $this->setArticleRelated( false );
-               $this->enableClientCache( false );
-               $this->mRedirect = '';
-               $this->mBodytext = $message;
+               $this->prepareErrorPage( $this->msg( 'internalerror' ) );
+
+               $this->addHTML( $message );
        }
 
        public function showUnexpectedValueError( $name, $val ) {
-               $this->showFatalError( wfMsg( 'unexpected', $name, $val ) );
+               $this->showFatalError( $this->msg( 'unexpected', $name, $val )->text() );
        }
 
        public function showFileCopyError( $old, $new ) {
-               $this->showFatalError( wfMsg( 'filecopyerror', $old, $new ) );
+               $this->showFatalError( $this->msg( 'filecopyerror', $old, $new )->text() );
        }
 
        public function showFileRenameError( $old, $new ) {
-               $this->showFatalError( wfMsg( 'filerenameerror', $old, $new ) );
+               $this->showFatalError( $this->msg( 'filerenameerror', $old, $new )->text() );
        }
 
        public function showFileDeleteError( $name ) {
-               $this->showFatalError( wfMsg( 'filedeleteerror', $name ) );
+               $this->showFatalError( $this->msg( 'filedeleteerror', $name )->text() );
        }
 
        public function showFileNotFoundError( $name ) {
-               $this->showFatalError( wfMsg( 'filenotfound', $name ) );
+               $this->showFatalError( $this->msg( 'filenotfound', $name )->text() );
        }
 
        /**
@@ -2202,10 +2283,8 @@ $templates
         */
        public function addReturnTo( $title, $query = array(), $text = null ) {
                $this->addLink( array( 'rel' => 'next', 'href' => $title->getFullURL() ) );
-               $link = wfMsgHtml(
-                       'returnto',
-                       Linker::link( $title, $text, array(), $query )
-               );
+               $link = $this->msg( 'returnto' )->rawParams(
+                       Linker::link( $title, $text, array(), $query ) )->escaped();
                $this->addHTML( "<p id=\"mw-returnto\">{$link}</p>\n" );
        }
 
@@ -2249,17 +2328,17 @@ $templates
         */
        public function headElement( Skin $sk, $includeStyle = true ) {
                global $wgContLang, $wgUseTrackbacks;
-               $userdir = $this->getLang()->getDir();
+               $userdir = $this->getLanguage()->getDir();
                $sitedir = $wgContLang->getDir();
 
                if ( $sk->commonPrintStylesheet() ) {
                        $this->addModuleStyles( 'mediawiki.legacy.wikiprintable' );
                }
 
-               $ret = Html::htmlHeader( array( 'lang' => $this->getLang()->getCode(), 'dir' => $userdir, 'class' => 'client-nojs' ) );
+               $ret = Html::htmlHeader( array( 'lang' => $this->getLanguage()->getCode(), 'dir' => $userdir ) );
 
                if ( $this->getHTMLTitle() == '' ) {
-                       $this->setHTMLTitle( wfMsg( 'pagetitle', $this->getPageTitle() ) );
+                       $this->setHTMLTitle( $this->msg( 'pagetitle', $this->getPageTitle() ) );
                }
 
                $openHead = Html::openElement( 'head' );
@@ -2289,9 +2368,9 @@ $templates
                $bodyAttrs = array();
 
                # Classes for LTR/RTL directionality support
-               $bodyAttrs['class'] = "mediawiki $userdir sitedir-$sitedir";
+               $bodyAttrs['class'] = "mediawiki $userdir sitedir-$sitedir client-nojs";
 
-               if ( $this->getContext()->getLang()->capitalizeAllNouns() ) {
+               if ( $this->getLanguage()->capitalizeAllNouns() ) {
                        # A <body> class is probably not the best way to do this . . .
                        $bodyAttrs['class'] .= ' capitalize-all-nouns';
                }
@@ -2425,7 +2504,7 @@ $templates
                        // correct timestamp and emptiness data
                        $query = ResourceLoader::makeLoaderQuery(
                                array(), // modules; not determined yet
-                               $this->getContext()->getLang()->getCode(),
+                               $this->getLanguage()->getCode(),
                                $this->getSkin()->getSkinName(),
                                $user,
                                null, // version; not determined yet
@@ -2481,7 +2560,7 @@ $templates
 
                        $url = ResourceLoader::makeLoaderURL(
                                array_keys( $modules ),
-                               $this->getContext()->getLang()->getCode(),
+                               $this->getLanguage()->getCode(),
                                $this->getSkin()->getSkinName(),
                                $user,
                                $version,
@@ -2684,7 +2763,7 @@ $templates
                // Use the 'ResourceLoaderGetConfigVars' hook if the variable is not
                // page-dependant but site-wide (without state).
                // Alternatively, you may want to use OutputPage->addJsConfigVars() instead.
-               wfRunHooks( 'MakeGlobalVariablesScript', array( &$vars, &$this ) );
+               wfRunHooks( 'MakeGlobalVariablesScript', array( &$vars, $this ) );
 
                // Merge in variables from addJsConfigVars last
                return array_merge( $vars, $this->mJsConfigVars );
@@ -2796,11 +2875,12 @@ $templates
                }
 
                # Universal edit button
-               if ( $wgUniversalEditButton ) {
-                       if ( $this->isArticleRelated() && $this->getTitle() && $this->getTitle()->quickUserCan( 'edit' )
-                               && ( $this->getTitle()->exists() || $this->getTitle()->quickUserCan( 'create' ) ) ) {
+               if ( $wgUniversalEditButton && $this->isArticleRelated() ) {
+                       $user = $this->getUser();
+                       if ( $this->getTitle()->quickUserCan( 'edit', $user )
+                               && ( $this->getTitle()->exists() || $this->getTitle()->quickUserCan( 'create', $user ) ) ) {
                                // Original UniversalEditButton
-                               $msg = wfMsg( 'edit' );
+                               $msg = $this->msg( 'edit' )->text();
                                $tags[] = Html::element( 'link', array(
                                        'rel' => 'alternate',
                                        'type' => 'application/x-wiki',
@@ -2833,7 +2913,7 @@ $templates
                        'rel' => 'search',
                        'type' => 'application/opensearchdescription+xml',
                        'href' => wfScript( 'opensearch_desc' ),
-                       'title' => wfMsgForContent( 'opensearch-desc' ),
+                       'title' => $this->msg( 'opensearch-desc' )->inContentLanguage()->text(),
                ) );
 
                if ( $wgEnableAPI ) {
@@ -2850,28 +2930,29 @@ $templates
                        ) );
                }
 
-               $lang = $this->getTitle()->getPageLanguage();
 
                # Language variants
-               if ( !$wgDisableLangConversion && $wgCanonicalLanguageLinks
-                       && $lang->hasVariants() ) {
-
-                       $urlvar = $lang->getURLVariant();
-
-                       if ( !$urlvar ) {
-                               $variants = $lang->getVariants();
-                               foreach ( $variants as $_v ) {
+               if ( !$wgDisableLangConversion && $wgCanonicalLanguageLinks ) {
+                       $lang = $this->getTitle()->getPageLanguage();
+                       if ( $lang->hasVariants() ) {
+
+                               $urlvar = $lang->getURLVariant();
+
+                               if ( !$urlvar ) {
+                                       $variants = $lang->getVariants();
+                                       foreach ( $variants as $_v ) {
+                                               $tags[] = Html::element( 'link', array(
+                                                       'rel' => 'alternate',
+                                                       'hreflang' => $_v,
+                                                       'href' => $this->getTitle()->getLocalURL( '', $_v ) )
+                                               );
+                                       }
+                               } else {
                                        $tags[] = Html::element( 'link', array(
-                                               'rel' => 'alternate',
-                                               'hreflang' => $_v,
-                                               'href' => $this->getTitle()->getLocalURL( '', $_v ) )
-                                       );
+                                               'rel' => 'canonical',
+                                               'href' => $this->getTitle()->getCanonicalUrl()
+                                       ) );
                                }
-                       } else {
-                               $tags[] = Html::element( 'link', array(
-                                       'rel' => 'canonical',
-                                       'href' => $this->getTitle()->getCanonicalUrl()
-                               ) );
                        }
                }
 
@@ -2908,7 +2989,7 @@ $templates
                                        $format,
                                        $link,
                                        # Used messages: 'page-rss-feed' and 'page-atom-feed' (for an easier grep)
-                                       wfMsg( "page-{$format}-feed", $this->getTitle()->getPrefixedText() )
+                                       $this->msg( "page-{$format}-feed", $this->getTitle()->getPrefixedText() )->text()
                                );
                        }
 
@@ -2919,24 +3000,21 @@ $templates
                        # like to promote instead of the RC feed (maybe like a "Recent New Articles"
                        # or "Breaking news" one). For this, we see if $wgOverrideSiteFeed is defined.
                        # If so, use it instead.
-
-                       $rctitle = SpecialPage::getTitleFor( 'Recentchanges' );
-
                        if ( $wgOverrideSiteFeed ) {
                                foreach ( $wgOverrideSiteFeed as $type => $feedUrl ) {
                                        // Note, this->feedLink escapes the url.
                                        $tags[] = $this->feedLink(
                                                $type,
                                                $feedUrl,
-                                               wfMsg( "site-{$type}-feed", $wgSitename )
+                                               $this->msg( "site-{$type}-feed", $wgSitename )->text()
                                        );
                                }
-                       } elseif ( $this->getTitle()->getPrefixedText() != $rctitle->getPrefixedText() ) {
+                       } elseif ( !$this->getTitle()->isSpecial( 'Recentchanges' ) ) {
                                foreach ( $wgAdvertisedFeedTypes as $format ) {
                                        $tags[] = $this->feedLink(
                                                $format,
-                                               $rctitle->getLocalURL( "feed={$format}" ),
-                                               wfMsg( "site-{$format}-feed", $wgSitename ) # For grep: 'site-rss-feed', 'site-atom-feed'.
+                                               $this->getTitle()->getLocalURL( "feed={$format}" ),
+                                               $this->msg( "site-{$format}-feed", $wgSitename )->text() # For grep: 'site-rss-feed', 'site-atom-feed'.
                                        );
                                }
                        }
@@ -2992,7 +3070,7 @@ $templates
         * @param $flip String: Set to 'flip' to flip the CSS if needed
         */
        public function addInlineStyle( $style_css, $flip = 'noflip' ) {
-               if( $flip === 'flip' && $this->getLang()->isRTL() ) {
+               if( $flip === 'flip' && $this->getLanguage()->isRTL() ) {
                        # If wanted, and the interface is right-to-left, flip the CSS
                        $style_css = CSSJanus::transform( $style_css, true, false );
                }
@@ -3111,7 +3189,7 @@ $templates
         */
        protected function styleLink( $style, $options ) {
                if( isset( $options['dir'] ) ) {
-                       if( $this->getLang()->getDir() != $options['dir'] ) {
+                       if( $this->getLanguage()->getDir() != $options['dir'] ) {
                                return '';
                        }
                }
@@ -3199,16 +3277,11 @@ $templates
         * Like addWikiMsg() except the parameters are taken as an array
         * instead of a variable argument list.
         *
-        * $options is passed through to wfMsgExt(), see that function for details.
-        *
         * @param $name string
         * @param $args array
-        * @param $options array
         */
-       public function addWikiMsgArray( $name, $args, $options = array() ) {
-               $options[] = 'parse';
-               $text = wfMsgExt( $name, $options, $args );
-               $this->addHTML( $text );
+       public function addWikiMsgArray( $name, $args ) {
+               $this->addWikiText( $this->msg( $name, $args )->plain() );
        }
 
        /**