X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2FOutputPage.php;h=972369024fa90ae5886f5dab791338913064e2da;hb=18df3d63bdbc58a76bd20e0cdc2b13af7f053b8c;hp=fb7f67ef3eaf14a00d431329d46495fc534b0975;hpb=bd8da57b32aa680fa76caad9317440791bfde836;p=lhc%2Fweb%2Fwiklou.git
diff --git a/includes/OutputPage.php b/includes/OutputPage.php
index fb7f67ef3e..972369024f 100644
--- a/includes/OutputPage.php
+++ b/includes/OutputPage.php
@@ -13,12 +13,12 @@ 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
*/
-class OutputPage {
+class OutputPage extends ContextSource {
/// Should be private. Used with addMeta() which adds
var $mMetatags = array();
@@ -47,7 +47,13 @@ class OutputPage {
var $mHTMLtitle = '';
/// Should be private. Is the displayed content related to the source of the corresponding wiki article.
- var $mIsarticle = true;
+ var $mIsarticle = false;
+
+ /**
+ * Should be private. Has get/set methods properly documented.
+ * Stores "article flag" toggle.
+ */
+ var $mIsArticleRelated = true;
/**
* Should be private. We have to set isPrintable(). Some pages should
@@ -61,7 +67,7 @@ class OutputPage {
* 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;
@@ -118,6 +124,7 @@ class OutputPage {
// @todo FIXME: Next variables probably comes from the resource loader
var $mModules = array(), $mModuleScripts = array(), $mModuleStyles = array(), $mModuleMessages = array();
var $mResourceLoader;
+ var $mJsConfigVars = array();
/** @todo FIXME: Is this still used ?*/
var $mInlineMsg = array();
@@ -146,12 +153,9 @@ class OutputPage {
var $mContainsOldMagic = 0, $mContainsNewMagic = 0;
/**
- * Should be private. Has get/set methods properly documented.
- * Stores "article flag" toggle.
+ * lazy initialised, use parserOptions()
+ * @var ParserOptions
*/
- var $mIsArticleRelated = true;
-
- /// lazy initialised, use parserOptions()
protected $mParserOptions = null;
/**
@@ -193,11 +197,10 @@ class OutputPage {
/// should be private. To include the variable {{REVISIONID}}
var $mRevisionId = null;
+ private $mRevisionTimestamp = null;
var $mFileVersion = null;
- private $mContext;
-
/**
* An array of stylesheet filenames (relative from skins path), with options
* for CSS media, IE conditions, and RTL/LTR direction.
@@ -220,17 +223,26 @@ class OutputPage {
'Cookie' => null
);
+ /**
+ * If the current page was reached through a redirect, $mRedirectedFrom contains the Title
+ * of the redirect.
+ *
+ * @var Title
+ */
+ private $mRedirectedFrom = null;
+
/**
* Constructor for OutputPage. This should not be called directly.
* Instead a new RequestContext should be created and it will implicitly create
* a OutputPage tied to that context.
*/
- function __construct( RequestContext $context = null ) {
- if ( !isset($context) ) {
+ function __construct( IContextSource $context = null ) {
+ if ( $context === null ) {
# Extensions should use `new RequestContext` instead of `new OutputPage` now.
wfDeprecated( __METHOD__ );
+ } else {
+ $this->setContext( $context );
}
- $this->mContext = $context;
}
/**
@@ -510,6 +522,15 @@ class OutputPage {
$this->mModuleMessages = array_merge( $this->mModuleMessages, (array)$modules );
}
+ /**
+ * Get an array of head items
+ *
+ * @return Array
+ */
+ function getHeadItemsArray() {
+ return $this->mHeadItems;
+ }
+
/**
* Get all header items in a string
*
@@ -748,7 +769,11 @@ class OutputPage {
* @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;
+ }
}
/**
@@ -760,22 +785,35 @@ class OutputPage {
return $this->mHTMLtitle;
}
+ /**
+ * Set $mRedirectedFrom, the Title of the page which redirected us to the current page.
+ *
+ * param @t Title
+ */
+ public function setRedirectedFrom( $t ) {
+ $this->mRedirectedFrom = $t;
+ }
+
/**
* "Page title" means the contents of \
. It is stored as a valid HTML fragment.
* This function allows good tags like \ in the \ tag, but not bad tags like \" to "<script>foo&bar</script>"
# but leave "foobar" alone
$nameWithTags = Sanitizer::normalizeCharReferences( Sanitizer::removeHTMLtags( $name ) );
$this->mPagetitle = $nameWithTags;
# change "foo&bar" to "foo&bar"
- $this->setHTMLTitle( wfMsg( 'pagetitle', Sanitizer::stripAllTags( $nameWithTags ) ) );
+ $this->setHTMLTitle( $this->msg( 'pagetitle' )->rawParams( Sanitizer::stripAllTags( $nameWithTags ) ) );
}
/**
@@ -787,83 +825,67 @@ class OutputPage {
return $this->mPagetitle;
}
- /**
- * Get the RequestContext used in this instance
- *
- * @return RequestContext
- */
- private function getContext() {
- if ( !isset($this->mContext) ) {
- wfDebug( __METHOD__ . " called and \$mContext is null. Using RequestContext::getMain(); for sanity\n" );
- $this->mContext = RequestContext::getMain();
- }
- return $this->mContext;
- }
-
- /**
- * Get the WebRequest being used for this instance
- *
- * @return WebRequest
- * @since 1.18
- */
- public function getRequest() {
- return $this->getContext()->getRequest();
- }
-
/**
* Set the Title object to use
*
* @param $t Title object
*/
- public function setTitle( $t ) {
+ public function setTitle( Title $t ) {
$this->getContext()->setTitle( $t );
}
+
/**
- * Get the Title object used in this instance
+ * Replace the subtile with $str
*
- * @return Title
+ * @param $str String|Message: new value of the subtitle
*/
- public function getTitle() {
- return $this->getContext()->getTitle();
+ public function setSubtitle( $str ) {
+ $this->clearSubtitle();
+ $this->addSubtitle( $str );
}
/**
- * Get the User object used in this instance
+ * Add $str to the subtitle
*
- * @return User
- * @since 1.18
+ * @deprecated in 1.19; use addSubtitle() instead
+ * @param $str String|Message to add to the subtitle
*/
- public function getUser() {
- return $this->getContext()->getUser();
+ public function appendSubtitle( $str ) {
+ $this->addSubtitle( $str );
}
/**
- * Get the Skin object used to render this instance
+ * Add $str to the subtitle
*
- * @return Skin
- * @since 1.18
+ * @param $str String|Message to add to the subtitle
*/
- public function getSkin() {
- return $this->getContext()->getSkin();
+ public function addSubtitle( $str ) {
+ if ( $str instanceof Message ) {
+ $this->mSubtitle[] = $str->setContext( $this->getContext() )->parse();
+ } else {
+ $this->mSubtitle[] = $str;
+ }
}
/**
- * Replace the subtile with $str
+ * Add a subtitle containing a backlink to a page
*
- * @param $str String: new value of the subtitle
+ * @param $title Title to link to
*/
- public function setSubtitle( $str ) {
- $this->mSubtitle = /*$this->parse(*/ $str /*)*/; // @bug 2514
+ 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 ) ) );
}
/**
- * Add $str to the subtitle
- *
- * @param $str String to add to the subtitle
+ * Clear the subtitles
*/
- public function appendSubtitle( $str ) {
- $this->mSubtitle .= /*$this->parse(*/ $str /*)*/; // @bug 2514
+ public function clearSubtitle() {
+ $this->mSubtitle = array();
}
/**
@@ -872,7 +894,7 @@ class OutputPage {
* @return String
*/
public function getSubtitle() {
- return $this->mSubtitle;
+ return implode( "
\n\t\t\t\t", $this->mSubtitle );
}
/**
@@ -1053,7 +1075,7 @@ class OutputPage {
/**
* Add new language links
*
- * @param $newLinkArray Associative array mapping language code to the page
+ * @param $newLinkArray array Associative array mapping language code to the page
* name
*/
public function addLanguageLinks( $newLinkArray ) {
@@ -1063,7 +1085,7 @@ class OutputPage {
/**
* Reset the language links and add new language links
*
- * @param $newLinkArray Associative array mapping language code to the page
+ * @param $newLinkArray array Associative array mapping language code to the page
* name
*/
public function setLanguageLinks( $newLinkArray ) {
@@ -1186,9 +1208,11 @@ class OutputPage {
* Return whether user JavaScript is allowed for this page
* @deprecated since 1.18 Load modules with ResourceLoader, and origin and
* trustworthiness is identified and enforced automagically.
+ * Will be removed in 1.20.
* @return Boolean
*/
public function isUserJsAllowed() {
+ wfDeprecated( __METHOD__, '1.18' );
return $this->getAllowedModules( ResourceLoaderModule::TYPE_SCRIPTS ) >= ResourceLoaderModule::ORIGIN_USER_INDIVIDUAL;
}
@@ -1244,6 +1268,19 @@ class OutputPage {
$this->mBodytext .= $text;
}
+ /**
+ * Shortcut for adding an Html::element via addHTML.
+ *
+ * @since 1.19
+ *
+ * @param $element string
+ * @param $attribs array
+ * @param $contents string
+ */
+ public function addElement( $element, $attribs = array(), $contents = '' ) {
+ $this->addHTML( Html::element( $element, $attribs, $contents ) );
+ }
+
/**
* Clear the body HTML
*/
@@ -1278,7 +1315,7 @@ class OutputPage {
*/
public function parserOptions( $options = null ) {
if ( !$this->mParserOptions ) {
- $this->mParserOptions = new ParserOptions;
+ $this->mParserOptions = ParserOptions::newFromContext( $this->getContext() );
$this->mParserOptions->setEditSection( false );
}
return wfSetVar( $this->mParserOptions, $options );
@@ -1305,10 +1342,31 @@ class OutputPage {
return $this->mRevisionId;
}
+ /**
+ * Set the timestamp of the revision which will be displayed. This is used
+ * to avoid a extra DB call in Skin::lastModified().
+ *
+ * @param $revid Mixed: string, or null
+ * @return Mixed: previous value
+ */
+ public function setRevisionTimestamp( $timestmap ) {
+ return wfSetVar( $this->mRevisionTimestamp, $timestmap );
+ }
+
+ /**
+ * Get the timestamp of displayed revision.
+ * This will be null if not filled by setRevisionTimestamp().
+ *
+ * @return String or null
+ */
+ public function getRevisionTimestamp() {
+ return $this->mRevisionTimestamp;
+ }
+
/**
* Set the displayed file version
*
- * @param $file File|false
+ * @param $file File|bool
* @return Mixed: previous value
*/
public function setFileVersion( $file ) {
@@ -1344,7 +1402,7 @@ class OutputPage {
* @return Array (dbKey => array('time' => MW timestamp or null, 'sha1' => sha1 or ''))
* @since 1.18
*/
- public function getImageTimeKeys() {
+ public function getFileSearchOptions() {
return $this->mImageTimeKeys;
}
@@ -1354,10 +1412,11 @@ class OutputPage {
*
* @param $text String
* @param $linestart Boolean: is this the start of a line?
+ * @param $interface Boolean: is this text in the user interface language?
*/
- public function addWikiText( $text, $linestart = true ) {
+ public function addWikiText( $text, $linestart = true, $interface = true ) {
$title = $this->getTitle(); // Work arround E_STRICT
- $this->addWikiTextTitle( $text, $title, $linestart );
+ $this->addWikiTextTitle( $text, $title, $linestart, /*tidy*/false, $interface );
}
/**
@@ -1372,7 +1431,7 @@ class OutputPage {
}
/**
- * Add wikitext with a custom Title object and
+ * Add wikitext with a custom Title object and tidy enabled.
*
* @param $text String: wikitext
* @param $title Title object
@@ -1400,16 +1459,17 @@ class OutputPage {
* @param $title Title object
* @param $linestart Boolean: is this the start of a line?
* @param $tidy Boolean: whether to use tidy
+ * @param $interface Boolean: whether it is an interface message
+ * (for example disables conversion)
*/
- public function addWikiTextTitle( $text, &$title, $linestart, $tidy = false ) {
+ public function addWikiTextTitle( $text, &$title, $linestart, $tidy = false, $interface = false ) {
global $wgParser;
wfProfileIn( __METHOD__ );
- wfIncrStats( 'pcache_not_possible' );
-
$popts = $this->parserOptions();
$oldTidy = $popts->setTidy( $tidy );
+ $popts->setInterfaceMessage( (bool) $interface );
$parserOutput = $wgParser->parse(
$text, $title, $popts,
@@ -1441,6 +1501,9 @@ class OutputPage {
$this->mNoGallery = $parserOutput->getNoGallery();
$this->mHeadItems = array_merge( $this->mHeadItems, $parserOutput->getHeadItems() );
$this->addModules( $parserOutput->getModules() );
+ $this->addModuleScripts( $parserOutput->getModuleScripts() );
+ $this->addModuleStyles( $parserOutput->getModuleStyles() );
+ $this->addModuleMessages( $parserOutput->getModuleMessages() );
// Template versioning...
foreach ( (array)$parserOutput->getTemplateIds() as $ns => $dbks ) {
@@ -1451,7 +1514,7 @@ class OutputPage {
}
}
// File versioning...
- foreach ( (array)$parserOutput->getImageTimeKeys() as $dbk => $data ) {
+ foreach ( (array)$parserOutput->getFileSearchOptions() as $dbk => $data ) {
$this->mImageTimeKeys[$dbk] = $data;
}
@@ -1499,19 +1562,13 @@ class OutputPage {
* @param $linestart Boolean: is this the start of a line?
* @param $interface Boolean: use interface language ($wgLang instead of
* $wgContLang) while parsing language sensitive magic
- * words like GRAMMAR and PLURAL
+ * words like GRAMMAR and PLURAL. This also disables
+ * LanguageConverter.
* @param $language Language object: target language object, will override
* $interface
* @return String: HTML
*/
public function parse( $text, $linestart = true, $interface = false, $language = null ) {
- // Check one for one common cause for parser state resetting
- $callers = wfGetAllCallers( 10 );
- if ( strpos( $callers, 'Parser::extensionSubstitution' ) !== false ) {
- throw new MWException( "wfMsg* function with parsing cannot be used " .
- "inside a tag hook. Should use parser->recursiveTagParse() instead" );
- }
-
global $wgParser;
if( is_null( $this->getTitle() ) ) {
@@ -1657,7 +1714,7 @@ class OutputPage {
$this->mVaryHeader[$header] = $option;
}
}
- $this->mVaryHeader[$header] = array_unique( $this->mVaryHeader[$header] );
+ $this->mVaryHeader[$header] = array_unique( (array)$this->mVaryHeader[$header] );
}
/**
@@ -1696,12 +1753,12 @@ class OutputPage {
* /w/index.php?title=Main_page&variant=zh-cn should never be served.
*/
function addAcceptLanguage() {
- global $wgContLang;
- if( !$this->getRequest()->getCheck( 'variant' ) && $wgContLang->hasVariants() ) {
- $variants = $wgContLang->getVariants();
+ $lang = $this->getTitle()->getPageLanguage();
+ if( !$this->getRequest()->getCheck( 'variant' ) && $lang->hasVariants() ) {
+ $variants = $lang->getVariants();
$aloption = array();
foreach ( $variants as $variant ) {
- if( $variant === $wgContLang->getCode() ) {
+ if( $variant === $lang->getCode() ) {
continue;
} else {
$aloption[] = 'string-contains=' . $variant;
@@ -1758,6 +1815,7 @@ class OutputPage {
} elseif ( $this->mPreventClickjacking && $wgEditPageFrameOptions ) {
return $wgEditPageFrameOptions;
}
+ return false;
}
/**
@@ -1847,7 +1905,7 @@ class OutputPage {
* the object, let's actually output it:
*/
public function output() {
- global $wgLanguageCode, $wgDebugRedirects, $wgMimeType;
+ global $wgLanguageCode, $wgDebugRedirects, $wgMimeType, $wgVaryOnXFP;
if( $this->mDoNothing ) {
return;
@@ -1859,25 +1917,35 @@ class OutputPage {
if ( $this->mRedirect != '' ) {
# Standards require redirect URLs to be absolute
- $this->mRedirect = wfExpandUrl( $this->mRedirect );
- if( $this->mRedirectCode == '301' || $this->mRedirectCode == '303' ) {
- if( !$wgDebugRedirects ) {
- $message = HttpStatus::getMessage( $this->mRedirectCode );
- $response->header( "HTTP/1.1 {$this->mRedirectCode} $message" );
+ $this->mRedirect = wfExpandUrl( $this->mRedirect, PROTO_CURRENT );
+
+ $redirect = $this->mRedirect;
+ $code = $this->mRedirectCode;
+
+ if( wfRunHooks( "BeforePageRedirect", array( $this, &$redirect, &$code ) ) ) {
+ if( $code == '301' || $code == '303' ) {
+ if( !$wgDebugRedirects ) {
+ $message = HttpStatus::getMessage( $code );
+ $response->header( "HTTP/1.1 $code $message" );
+ }
+ $this->mLastModified = wfTimestamp( TS_RFC2822 );
+ }
+ if ( $wgVaryOnXFP ) {
+ $this->addVaryHeader( 'X-Forwarded-Proto' );
+ }
+ $this->sendCacheControl();
+
+ $response->header( "Content-Type: text/html; charset=utf-8" );
+ if( $wgDebugRedirects ) {
+ $url = htmlspecialchars( $redirect );
+ print "\n\nRedirect\n\n\n";
+ print "
Location: $url
\n";
+ print "\n\n";
+ } else {
+ $response->header( 'Location: ' . $redirect );
}
- $this->mLastModified = wfTimestamp( TS_RFC2822 );
- }
- $this->sendCacheControl();
-
- $response->header( "Content-Type: text/html; charset=utf-8" );
- if( $wgDebugRedirects ) {
- $url = htmlspecialchars( $this->mRedirect );
- print "\n\nRedirect\n\n\n";
- print "Location: $url
\n";
- print "\n\n";
- } else {
- $response->header( 'Location: ' . $this->mRedirect );
}
+
wfProfileOut( __METHOD__ );
return;
} elseif ( $this->mStatusCode ) {
@@ -1911,7 +1979,7 @@ class OutputPage {
wfRunHooks( 'BeforePageDisplay', array( &$this, &$sk ) );
wfProfileIn( 'Output-skin' );
- $sk->outputPage( $this );
+ $sk->outputPage();
wfProfileOut( 'Output-skin' );
}
@@ -1934,29 +2002,54 @@ class OutputPage {
* @deprecated since 1.18
*/
function blockedPage() {
- throw new UserBlockedError( $this->getUser()->getBlock() );
+ throw new UserBlockedError( $this->getUser()->mBlock );
}
/**
- * Output a standard error page
+ * 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 tag).
*
- * @param $title String: message key for page title
- * @param $msg String: message key for page text
- * @param $params Array: message parameters
+ * @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 attribute will be
+ * based on $pageTitle
*/
- public function showErrorPage( $title, $msg, $params = array() ) {
+ public function prepareErrorPage( $pageTitle, $htmlTitle = false ) {
if ( $this->getTitle() ) {
$this->mDebugtext .= 'Original title: ' . $this->getTitle()->getPrefixedText() . "\n";
}
- $this->setPageTitle( wfMsg( $title ) );
- $this->setHTMLTitle( wfMsg( 'errorpagetitle' ) );
+
+ $this->setPageTitle( $pageTitle );
+ if ( $htmlTitle !== false ) {
+ $this->setHTMLTitle( $htmlTitle );
+ }
$this->setRobotPolicy( 'noindex,nofollow' );
$this->setArticleRelated( false );
$this->enableClientCache( false );
$this->mRedirect = '';
- $this->mBodytext = '';
+ $this->clearSubtitle();
+ $this->clearHTML();
+ }
- $this->addWikiMsgArray( $msg, $params );
+ /**
+ * Output a standard error page
+ *
+ * showErrorPage( 'titlemsg', 'pagetextmsg', array( 'param1', 'param2' ) );
+ * showErrorPage( 'titlemsg', $messageObject );
+ *
+ * @param $title String: message key for page title
+ * @param $msg Mixed: message key (string) for page text, or a Message object
+ * @param $params Array: message parameters; ignored if $msg is a Message object
+ */
+ public function showErrorPage( $title, $msg, $params = array() ) {
+ $this->prepareErrorPage( $this->msg( $title ), $this->msg( 'errorpagetitle' ) );
+
+ if ( $msg instanceof Message ){
+ $this->addHTML( $msg->parse() );
+ } else {
+ $this->addWikiMsgArray( $msg, $params );
+ }
$this->returnToMain();
}
@@ -1968,16 +2061,71 @@ class OutputPage {
* @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;
+
+ # Due to bug 32276, if a user does not have read permissions,
+ # $this->getTitle() will just give Special:Badtitle, which is
+ # not especially useful as a returnto parameter. Use the title
+ # from the request instead, if there was one.
+ $request = $this->getRequest();
+ $returnto = Title::newFromURL( $request->getVal( 'title', '' ) );
+ 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();
+
+ 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->userCan( 'read', $this->getUser() ) ) {
+ $this->returnToMain( null, $displayReturnto );
+ }
+ } else {
+ $this->prepareErrorPage( $this->msg( 'permissionserrors' ) );
+ $this->addWikiText( $this->formatPermissionsErrorMessage( $errors, $action ) );
+ }
}
/**
@@ -1987,11 +2135,7 @@ class OutputPage {
* @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();
@@ -2008,33 +2152,11 @@ class OutputPage {
/**
* 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' );
-
- # 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' );
}
/**
@@ -2046,14 +2168,14 @@ class OutputPage {
*/
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 ) {
@@ -2061,13 +2183,13 @@ class OutputPage {
foreach( $errors as $error ) {
$text .= '';
- $text .= call_user_func_array( 'wfMsgNoTrans', $error );
+ $text .= call_user_func_array( array( $this, 'msg' ), $error )->plain();
$text .= "\n";
}
$text .= '';
} else {
$text .= "\n" .
- call_user_func_array( 'wfMsgNoTrans', reset( $errors ) ) .
+ call_user_func_array( array( $this, 'msg' ), reset( $errors ) )->plain() .
"\n
";
}
@@ -2107,12 +2229,10 @@ class OutputPage {
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 {
@@ -2124,18 +2244,20 @@ class OutputPage {
if( is_string( $source ) ) {
$this->addWikiMsg( 'viewsourcetext' );
+ $pageLang = $this->getTitle()->getPageLanguage();
$params = array(
'id' => 'wpTextbox1',
'name' => 'wpTextbox1',
'cols' => $this->getUser()->getOption( 'cols' ),
'rows' => $this->getUser()->getOption( 'rows' ),
- 'readonly' => 'readonly'
+ 'readonly' => 'readonly',
+ 'lang' => $pageLang->getHtmlCode(),
+ 'dir' => $pageLang->getDir(),
);
$this->addHTML( Html::element( 'textarea', $params, $source ) );
// Show templates used by this article
- $article = new Article( $this->getTitle() );
- $templates = Linker::formatTemplates( $article->getUsedTemplates() );
+ $templates = Linker::formatTemplates( $this->getTitle()->getTemplateLinksFrom() );
$this->addHTML( "
$templates
@@ -2174,37 +2296,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() );
}
/**
@@ -2216,10 +2335,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( "{$link}
\n" );
}
@@ -2262,18 +2379,19 @@ $templates
* @return String: The doctype, opening , and head element.
*/
public function headElement( Skin $sk, $includeStyle = true ) {
- global $wgLang, $wgContLang, $wgUseTrackbacks;
- $userdir = $wgLang->getDir();
+ global $wgContLang;
+
+ $userdir = $this->getLanguage()->getDir();
$sitedir = $wgContLang->getDir();
if ( $sk->commonPrintStylesheet() ) {
$this->addModuleStyles( 'mediawiki.legacy.wikiprintable' );
}
- $ret = Html::htmlHeader( array( 'lang' => $wgLang->getCode(), 'dir' => $userdir ) );
+ $ret = Html::htmlHeader( array( 'lang' => $this->getLanguage()->getHtmlCode(), 'dir' => $userdir, 'class' => 'client-nojs' ) );
if ( $this->getHTMLTitle() == '' ) {
- $this->setHTMLTitle( wfMsg( 'pagetitle', $this->getPageTitle() ) );
+ $this->setHTMLTitle( $this->msg( 'pagetitle', $this->getPageTitle() ) );
}
$openHead = Html::openElement( 'head' );
@@ -2291,10 +2409,6 @@ $templates
$this->getHeadItems()
) );
- if ( $wgUseTrackbacks && $this->isArticleRelated() ) {
- $ret .= $this->getTitle()->trackbackRDF();
- }
-
$closeHead = Html::closeElement( 'head' );
if ( $closeHead ) {
$ret .= "$closeHead\n";
@@ -2302,29 +2416,16 @@ $templates
$bodyAttrs = array();
- # Crazy edit-on-double-click stuff
- $action = $this->getRequest()->getVal( 'action', 'view' );
-
- if (
- $this->getTitle()->getNamespace() != NS_SPECIAL &&
- in_array( $action, array( 'view', 'purge' ) ) &&
- $this->getUser()->getOption( 'editondblclick' )
- )
- {
- $editUrl = $this->getTitle()->getLocalUrl( $sk->editUrlOptions() );
- $bodyAttrs['ondblclick'] = "document.location = '" .
- Xml::escapeJsString( $editUrl ) . "'";
- }
-
# Classes for LTR/RTL directionality support
$bodyAttrs['class'] = "mediawiki $userdir sitedir-$sitedir";
- if ( $this->getContext()->getLang()->capitalizeAllNouns() ) {
+ if ( $this->getLanguage()->capitalizeAllNouns() ) {
# A class is probably not the best way to do this . . .
$bodyAttrs['class'] .= ' capitalize-all-nouns';
}
$bodyAttrs['class'] .= ' ' . $sk->getPageClasses( $this->getTitle() );
$bodyAttrs['class'] .= ' skin-' . Sanitizer::escapeClass( $sk->getSkinName() );
+ $bodyAttrs['class'] .= ' action-' . Sanitizer::escapeClass( Action::getActionName( $this->getContext() ) );
$sk->addToBodyAttributes( $this, $bodyAttrs ); // Allow skins to add body attributes they need
wfRunHooks( 'OutputPageBodyAttributes', array( $this, $sk, &$bodyAttrs ) );
@@ -2338,13 +2439,12 @@ $templates
* Add the default ResourceLoader modules to this object
*/
private function addDefaultModules() {
- global $wgIncludeLegacyJavaScript, $wgUseAjax,
- $wgAjaxWatch, $wgEnableMWSuggest, $wgUseAJAXCategories;
+ global $wgIncludeLegacyJavaScript, $wgPreloadJavaScriptMwUtil, $wgUseAjax,
+ $wgAjaxWatch, $wgEnableMWSuggest;
// Add base resources
$this->addModules( array(
'mediawiki.user',
- 'mediawiki.util',
'mediawiki.page.startup',
'mediawiki.page.ready',
) );
@@ -2352,6 +2452,12 @@ $templates
$this->addModules( 'mediawiki.legacy.wikibits' );
}
+ if ( $wgPreloadJavaScriptMwUtil ) {
+ $this->addModules( 'mediawiki.util' );
+ }
+
+ MWDebug::addModules( $this );
+
// Add various resources if required
if ( $wgUseAjax ) {
$this->addModules( 'mediawiki.legacy.ajax' );
@@ -2363,7 +2469,7 @@ $templates
}
if ( $wgEnableMWSuggest && !$this->getUser()->getOption( 'disablesuggest', false ) ) {
- $this->addModules( 'mediawiki.page.mwsuggest' );
+ $this->addModules( 'mediawiki.legacy.mwsuggest' );
}
}
@@ -2371,14 +2477,9 @@ $templates
$this->addModules( 'mediawiki.action.view.rightClickEdit' );
}
- if ( $wgUseAJAXCategories ) {
- global $wgAJAXCategoriesNamespaces;
-
- $title = $this->getTitle();
-
- if( empty( $wgAJAXCategoriesNamespaces ) || in_array( $title->getNamespace(), $wgAJAXCategoriesNamespaces ) ) {
- $this->addModules( 'mediawiki.page.ajaxCategories.init' );
- }
+ # Crazy edit-on-double-click stuff
+ if ( $this->isArticle() && $this->getUser()->getOption( 'editondblclick' ) ) {
+ $this->addModules( 'mediawiki.action.view.dblClickEdit' );
}
}
@@ -2396,29 +2497,15 @@ $templates
/**
* TODO: Document
- * @param $modules Array/string with the module name
+ * @param $modules Array/string with the module name(s)
* @param $only String ResourceLoaderModule TYPE_ class constant
* @param $useESI boolean
+ * @param $extraQuery Array with extra query parameters to add to each request. array( param => value )
+ * @param $loadCall boolean If true, output a mw.loader.load() call rather than a