use MediaWiki\Logger\LoggerFactory;
use MediaWiki\MediaWikiServices;
use MediaWiki\Session\SessionManager;
+use Wikimedia\Rdbms\IResultWrapper;
use Wikimedia\RelPath;
use Wikimedia\WrappedString;
use Wikimedia\WrappedStringList;
protected $mCanonicalUrl = false;
/**
- * @var string Should be private - has getter and setter. Contains
- * the HTML title */
- public $mPagetitle = '';
+ * @var string The contents of <h1> */
+ private $mPageTitle = '';
/**
* @var string Contains all of the "<body>" content. Should be private we
* @var bool Is the displayed content related to the source of the
* corresponding wiki article.
*/
- private $mIsarticle = false;
+ private $mIsArticle = false;
/** @var bool Stores "article flag" toggle. */
private $mIsArticleRelated = true;
*/
public $mNoGallery = false;
- /** @var string */
- private $mPageTitleActionText = '';
-
/** @var int Cache stuff. Looks like mEnableClientCache */
protected $mCdnMaxage = 0;
/** @var int Upper limit on mCdnMaxage */
private $mIndexPolicy = 'index';
private $mFollowPolicy = 'follow';
+
+ /**
+ * @var array Headers that cause the cache to vary. Key is header name, value is an array of
+ * options for the Key header.
+ */
private $mVaryHeader = [
'Accept-Encoding' => [ 'match=gzip' ],
];
return $this->mLinktags;
}
- /**
- * Add a new \<link\> with "rel" attribute set to "meta"
- *
- * @param array $linkarr Associative array mapping attribute names to their
- * values, both keys and values will be escaped, and the
- * "rel" attribute will be automatically added
- */
- function addMetadataLink( array $linkarr ) {
- $linkarr['rel'] = $this->getMetadataAttribute();
- $this->addLink( $linkarr );
- }
-
/**
* Set the URL to be used for the <link rel=canonical>. This should be used
* in preference to addLink(), to avoid duplicate link tags.
return $this->mCanonicalUrl;
}
- /**
- * Get the value of the "rel" attribute for metadata links
- *
- * @return string
- */
- public function getMetadataAttribute() {
- # note: buggy CC software only reads first "meta" link
- static $haveMeta = false;
- if ( $haveMeta ) {
- return 'alternate meta';
- } else {
- $haveMeta = true;
- return 'meta';
- }
- }
-
/**
* Add raw HTML to the list of scripts (including \<script\> tag, etc.)
* Internal use only. Use OutputPage::addModules() or OutputPage::addJsConfigVars()
* Internal use only. Use OutputPage::addModules() if possible.
*
* @param string $file URL to file (absolute path, protocol-relative, or full url)
- * @param string $unused Previously used to change the cache-busting query parameter
+ * @param string|null $unused Previously used to change the cache-busting query parameter
*/
public function addScriptFile( $file, $unused = null ) {
if ( substr( $file, 0, 1 ) !== '/' && !preg_match( '#^[a-z]*://#i', $file ) ) {
# this breaks strtotime().
$clientHeader = preg_replace( '/;.*$/', '', $clientHeader );
- Wikimedia\suppressWarnings(); // E_STRICT system time bitching
+ Wikimedia\suppressWarnings(); // E_STRICT system time warnings
$clientHeaderTime = strtotime( $clientHeader );
Wikimedia\restoreWarnings();
if ( !$clientHeaderTime ) {
}
}
- /**
- * Set the new value of the "action text", this will be added to the
- * "HTML title", separated from it with " - ".
- *
- * @param string $text New value of the "action text"
- */
- public function setPageTitleActionText( $text ) {
- $this->mPageTitleActionText = $text;
- }
-
- /**
- * Get the value of the "action text"
- *
- * @return string
- */
- public function getPageTitleActionText() {
- return $this->mPageTitleActionText;
- }
-
/**
* "HTML title" means the contents of "<title>".
* It is stored as plain, unescaped text and will be run through htmlspecialchars in the skin file.
# change "<script>foo&bar</script>" to "<script>foo&bar</script>"
# but leave "<i>foobar</i>" alone
$nameWithTags = Sanitizer::normalizeCharReferences( Sanitizer::removeHTMLtags( $name ) );
- $this->mPagetitle = $nameWithTags;
+ $this->mPageTitle = $nameWithTags;
# change "<i>foo&bar</i>" to "foo&bar"
$this->setHTMLTitle(
* @return string
*/
public function getPageTitle() {
- return $this->mPagetitle;
+ return $this->mPageTitle;
}
/**
* corresponding article on the wiki
* Setting true will cause the change "article related" toggle to true
*
- * @param bool $v
+ * @param bool $newVal
*/
- public function setArticleFlag( $v ) {
- $this->mIsarticle = $v;
- if ( $v ) {
- $this->mIsArticleRelated = $v;
+ public function setArticleFlag( $newVal ) {
+ $this->mIsArticle = $newVal;
+ if ( $newVal ) {
+ $this->mIsArticleRelated = $newVal;
}
}
* @return bool
*/
public function isArticle() {
- return $this->mIsarticle;
+ return $this->mIsArticle;
}
/**
* Set whether this page is related an article on the wiki
* Setting false will cause the change of "article flag" toggle to false
*
- * @param bool $v
+ * @param bool $newVal
*/
- public function setArticleRelated( $v ) {
- $this->mIsArticleRelated = $v;
- if ( !$v ) {
- $this->mIsarticle = false;
+ public function setArticleRelated( $newVal ) {
+ $this->mIsArticleRelated = $newVal;
+ if ( !$newVal ) {
+ $this->mIsArticle = false;
}
}
* (e.g. 'fr:Test page')
*/
public function addLanguageLinks( array $newLinkArray ) {
- $this->mLanguageLinks += $newLinkArray;
+ $this->mLanguageLinks = array_merge( $this->mLanguageLinks, $newLinkArray );
}
/**
* @param array $categories Mapping category name => sort key
*/
public function addCategoryLinks( array $categories ) {
- global $wgContLang;
-
- if ( !is_array( $categories ) || count( $categories ) == 0 ) {
+ if ( !$categories ) {
return;
}
'OutputPageMakeCategoryLinks',
[ &$outputPage, $categories, &$this->mCategoryLinks ] )
) {
- $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
+ $services = MediaWikiServices::getInstance();
+ $linkRenderer = $services->getLinkRenderer();
foreach ( $categories as $category => $type ) {
// array keys will cast numeric category names to ints, so cast back to string
$category = (string)$category;
if ( !$title ) {
continue;
}
- $wgContLang->findVariantLink( $category, $title, true );
+ $services->getContentLanguage()->findVariantLink( $category, $title, true );
if ( $category != $origcategory && array_key_exists( $category, $categories ) ) {
continue;
}
- $text = $wgContLang->convertHtml( $title->getText() );
+ $text = $services->getContentLanguage()->convertHtml( $title->getText() );
$this->mCategories[$type][] = $title->getText();
$this->mCategoryLinks[$type][] = $linkRenderer->makeLink( $title, new HtmlArmor( $text ) );
}
/**
* @param array $categories
- * @return bool|ResultWrapper
+ * @return bool|IResultWrapper
*/
protected function addCategoryLinksToLBAndGetResult( array $categories ) {
# Add the links to a LinkBatch
);
# Add the results to the link cache
- $lb->addResultToCache( LinkCache::singleton(), $res );
+ $linkCache = MediaWikiServices::getInstance()->getLinkCache();
+ $lb->addResultToCache( $linkCache, $res );
return $res;
}
* Set the revision ID which will be seen by the wiki text parser
* for things such as embedded {{REVISIONID}} variable use.
*
- * @param int|null $revid An positive integer, or null
+ * @param int|null $revid A positive integer, or null
* @return mixed Previous value
*/
public function setRevisionId( $revid ) {
$val = is_null( $revid ) ? null : intval( $revid );
- return wfSetVar( $this->mRevisionId, $val );
+ return wfSetVar( $this->mRevisionId, $val, true );
}
/**
* @return mixed Previous value
*/
public function setRevisionTimestamp( $timestamp ) {
- return wfSetVar( $this->mRevisionTimestamp, $timestamp );
+ return wfSetVar( $this->mRevisionTimestamp, $timestamp, true );
}
/**
/**
* Set the displayed file version
*
- * @param File|bool $file
+ * @param File|null $file
* @return mixed Previous value
*/
public function setFileVersion( $file ) {
* Add wikitext with a custom Title object
*
* @param string $text Wikitext
- * @param Title &$title
+ * @param Title $title
* @param bool $linestart Is this the start of a line?
*/
- public function addWikiTextWithTitle( $text, &$title, $linestart = true ) {
+ public function addWikiTextWithTitle( $text, Title $title, $linestart = true ) {
$this->addWikiTextTitle( $text, $title, $linestart );
}
* Add wikitext with a custom Title object and tidy enabled.
*
* @param string $text Wikitext
- * @param Title &$title
+ * @param Title $title
* @param bool $linestart Is this the start of a line?
*/
- function addWikiTextTitleTidy( $text, &$title, $linestart = true ) {
+ function addWikiTextTitleTidy( $text, Title $title, $linestart = true ) {
$this->addWikiTextTitle( $text, $title, $linestart, true );
}
* @since 1.24
* @param ParserOutput $parserOutput
*/
- public function addParserOutputMetadata( $parserOutput ) {
- $this->mLanguageLinks += $parserOutput->getLanguageLinks();
+ public function addParserOutputMetadata( ParserOutput $parserOutput ) {
+ $this->mLanguageLinks =
+ array_merge( $this->mLanguageLinks, $parserOutput->getLanguageLinks() );
$this->addCategoryLinks( $parserOutput->getCategories() );
$this->setIndicators( $parserOutput->getIndicators() );
$this->mNewSectionLink = $parserOutput->getNewSection();
foreach ( $parserOutput->getOutputHooks() as $hookInfo ) {
list( $hookName, $data ) = $hookInfo;
if ( isset( $parserOutputHooks[$hookName] ) ) {
- call_user_func( $parserOutputHooks[$hookName], $this, $parserOutput, $data );
+ $parserOutputHooks[$hookName]( $this, $parserOutput, $data );
}
}
* @param ParserOutput $parserOutput
* @param array $poOptions Options to ParserOutput::getText()
*/
- public function addParserOutputContent( $parserOutput, $poOptions = [] ) {
+ public function addParserOutputContent( ParserOutput $parserOutput, $poOptions = [] ) {
$this->addParserOutputText( $parserOutput, $poOptions );
$this->addModules( $parserOutput->getModules() );
* @param ParserOutput $parserOutput
* @param array $poOptions Options to ParserOutput::getText()
*/
- public function addParserOutputText( $parserOutput, $poOptions = [] ) {
+ public function addParserOutputText( ParserOutput $parserOutput, $poOptions = [] ) {
$text = $parserOutput->getText( $poOptions );
// Avoid PHP 7.1 warning of passing $this by reference
$outputPage = $this;
* @param ParserOutput $parserOutput
* @param array $poOptions Options to ParserOutput::getText()
*/
- function addParserOutput( $parserOutput, $poOptions = [] ) {
+ function addParserOutput( ParserOutput $parserOutput, $poOptions = [] ) {
$this->addParserOutputMetadata( $parserOutput );
$this->addParserOutputText( $parserOutput, $poOptions );
}
*
* @param string $text
* @param bool $linestart Is this the start of a line?
- * @param bool $interface Use interface language ($wgLang instead of
- * $wgContLang) while parsing language sensitive magic words like GRAMMAR and PLURAL.
- * This also disables LanguageConverter.
- * @param Language $language Target language object, will override $interface
+ * @param bool $interface Use interface language (instead of content language) while parsing
+ * language sensitive magic words like GRAMMAR and PLURAL. This also disables
+ * LanguageConverter.
+ * @param Language|null $language Target language object, will override $interface
* @throws MWException
* @return string HTML
*/
*
* @param string $text
* @param bool $linestart Is this the start of a line?
- * @param bool $interface Use interface language ($wgLang instead of
- * $wgContLang) while parsing language sensitive magic
- * words like GRAMMAR and PLURAL
+ * @param bool $interface Use interface language (instead of content language) while parsing
+ * language sensitive magic words like GRAMMAR and PLURAL
* @return string HTML
*/
public function parseInline( $text, $linestart = true, $interface = false ) {
}
/**
- * Lower the value of the "s-maxage" part of the "Cache-control" HTTP header
+ * Set the value of the "s-maxage" part of the "Cache-control" HTTP header to $maxage if that is
+ * lower than the current s-maxage. Either way, $maxage is now an upper limit on s-maxage, so
+ * that future calls to setCdnMaxage() will no longer be able to raise the s-maxage above
+ * $maxage.
*
* @param int $maxage Maximum cache time on the CDN, in seconds
* @since 1.27
* TTL is 90% of the age of the object, subject to the min and max.
*
* @param string|int|float|bool|null $mtime Last-Modified timestamp
- * @param int $minTTL Mimimum TTL in seconds [default: 1 minute]
+ * @param int $minTTL Minimum TTL in seconds [default: 1 minute]
* @param int $maxTTL Maximum TTL in seconds [default: $wgSquidMaxage]
- * @return int TTL in seconds
+ * @return int TTL in seconds passed to lowerCdnMaxage() (may not be the same as the new
+ * s-maxage)
* @since 1.28
*/
public function adaptCdnTTL( $mtime, $minTTL = 0, $maxTTL = 0 ) {
/**
* Use enableClientCache(false) to force it to send nocache headers
*
- * @param bool $state
+ * @param bool|null $state New value, or null to not set the value
*
- * @return bool
+ * @return bool Old value
*/
public function enableClientCache( $state ) {
return wfSetVar( $this->mEnableClientCache, $state );
}
/**
- * Get the list of cookies that will influence on the cache
+ * Get the list of cookie names that will influence the cache
*
* @return array
*/
if ( !is_array( $option ) ) {
$option = [];
}
- $this->mVaryHeader[$header] = array_unique( array_merge( $this->mVaryHeader[$header], $option ) );
+ $this->mVaryHeader[$header] =
+ array_unique( array_merge( $this->mVaryHeader[$header], $option ) );
}
/**
}
/**
- * T23672: Add Accept-Language to Vary and Key headers
- * if there's no 'variant' parameter existed in GET.
+ * T23672: Add Accept-Language to Vary and Key headers if there's no 'variant' parameter in GET.
*
* For example:
- * /w/index.php?title=Main_page should always be served; but
- * /w/index.php?title=Main_page&variant=zh-cn should never be served.
+ * /w/index.php?title=Main_page will vary based on Accept-Language; but
+ * /w/index.php?title=Main_page&variant=zh-cn will not.
*/
- function addAcceptLanguage() {
+ private function addAcceptLanguage() {
$title = $this->getTitle();
if ( !$title instanceof Title ) {
return;
foreach ( $variants as $variant ) {
if ( $variant === $lang->getCode() ) {
continue;
- } else {
- $aloption[] = 'substr=' . $variant;
-
- // IE and some other browsers use BCP 47 standards in
- // their Accept-Language header, like "zh-CN" or "zh-Hant".
- // We should handle these too.
- $variantBCP47 = LanguageCode::bcp47( $variant );
- if ( $variantBCP47 !== $variant ) {
- $aloption[] = 'substr=' . $variantBCP47;
- }
+ }
+
+ $aloption[] = "substr=$variant";
+
+ // IE and some other browsers use BCP 47 standards in their Accept-Language header,
+ // like "zh-CN" or "zh-Hant". We should handle these too.
+ $variantBCP47 = LanguageCode::bcp47( $variant );
+ if ( $variantBCP47 !== $variant ) {
+ $aloption[] = "substr=$variantBCP47";
}
}
$this->addVaryHeader( 'Accept-Language', $aloption );
* @throws MWException
*/
public function output( $return = false ) {
- global $wgContLang;
-
if ( $this->mDoNothing ) {
return $return ? '' : null;
}
ob_start();
$response->header( 'Content-type: ' . $config->get( 'MimeType' ) . '; charset=UTF-8' );
- $response->header( 'Content-language: ' . $wgContLang->getHtmlCode() );
+ $response->header( 'Content-language: ' .
+ MediaWikiServices::getInstance()->getContentLanguage()->getHtmlCode() );
if ( !$this->mArticleBodyOnly ) {
$sk = $this->getSkin();
* Output a standard permission error page
*
* @param array $errors Error message keys or [key, param...] arrays
- * @param string $action Action that was denied or null if unknown
+ * @param string|null $action Action that was denied or null if unknown
*/
public function showPermissionsErrorPage( array $errors, $action = null ) {
foreach ( $errors as $key => $error ) {
* Format a list of error messages
*
* @param array $errors Array of arrays returned by Title::getUserPermissionsErrors
- * @param string $action Action that was denied or null if unknown
+ * @param string|null $action Action that was denied or null if unknown
* @return string The wikitext error-messages, formatted into a list.
*/
public function formatPermissionsErrorMessage( array $errors, $action = null ) {
}
}
+ /**
+ * Output an error page
+ *
+ * @note FatalError exception class provides an alternative.
+ * @param string $message Error to output. Must be escaped for HTML.
+ */
public function showFatalError( $message ) {
$this->prepareErrorPage( $this->msg( 'internalerror' ) );
$this->addHTML( $message );
}
+ /**
+ * @deprecated 1.32 Use OutputPage::showFatalError or throw FatalError instead.
+ */
public function showUnexpectedValueError( $name, $val ) {
- $this->showFatalError( $this->msg( 'unexpected', $name, $val )->text() );
+ wfDeprecated( __METHOD__, '1.32' );
+ $this->showFatalError( $this->msg( 'unexpected', $name, $val )->escaped() );
}
+ /**
+ * @deprecated 1.32 Use OutputPage::showFatalError or throw FatalError instead.
+ */
public function showFileCopyError( $old, $new ) {
- $this->showFatalError( $this->msg( 'filecopyerror', $old, $new )->text() );
+ wfDeprecated( __METHOD__, '1.32' );
+ $this->showFatalError( $this->msg( 'filecopyerror', $old, $new )->escaped() );
}
+ /**
+ * @deprecated 1.32 Use OutputPage::showFatalError or throw FatalError instead.
+ */
public function showFileRenameError( $old, $new ) {
- $this->showFatalError( $this->msg( 'filerenameerror', $old, $new )->text() );
+ wfDeprecated( __METHOD__, '1.32' );
+ $this->showFatalError( $this->msg( 'filerenameerror', $old, $new )->escpaed() );
}
+ /**
+ * @deprecated 1.32 Use OutputPage::showFatalError or throw FatalError instead.
+ */
public function showFileDeleteError( $name ) {
- $this->showFatalError( $this->msg( 'filedeleteerror', $name )->text() );
+ wfDeprecated( __METHOD__, '1.32' );
+ $this->showFatalError( $this->msg( 'filedeleteerror', $name )->escaped() );
}
+ /**
+ * @deprecated 1.32 Use OutputPage::showFatalError or throw FatalError instead.
+ */
public function showFileNotFoundError( $name ) {
- $this->showFatalError( $this->msg( 'filenotfound', $name )->text() );
+ wfDeprecated( __METHOD__, '1.32' );
+ $this->showFatalError( $this->msg( 'filenotfound', $name )->escaped() );
}
/**
*
* @param Title $title Title to link
* @param array $query Query string parameters
- * @param string $text Text of the link (input is not escaped)
+ * @param string|null $text Text of the link (input is not escaped)
* @param array $options Options array to pass to Linker
*/
public function addReturnTo( $title, array $query = [], $text = null, $options = [] ) {
* Add a "return to" link pointing to a specified title,
* or the title indicated in the request, or else the main page
*
- * @param mixed $unused
- * @param Title|string $returnto Title or String to return to
- * @param string $returntoquery Query string for the return to link
+ * @param mixed|null $unused
+ * @param Title|string|null $returnto Title or String to return to
+ * @param string|null $returntoquery Query string for the return to link
*/
public function returnToMain( $unused = null, $returnto = null, $returntoquery = null ) {
if ( $returnto == null ) {
$this->rlClientContext = new DerivativeResourceLoaderContext( $this->rlClientContext );
$this->rlClientContext->setContentOverrideCallback( function ( Title $title ) {
foreach ( $this->contentOverrideCallbacks as $callback ) {
- $content = call_user_func( $callback, $title );
+ $content = $callback( $title );
if ( $content !== null ) {
return $content;
}
* @return string The doctype, opening "<html>", and head element.
*/
public function headElement( Skin $sk, $includeStyle = true ) {
- global $wgContLang;
-
$userdir = $this->getLanguage()->getDir();
- $sitedir = $wgContLang->getDir();
+ $sitedir = MediaWikiServices::getInstance()->getContentLanguage()->getDir();
$pieces = [];
$pieces[] = Html::htmlHeader( Sanitizer::mergeAttributes(
* Add one or more variables to be set in mw.config in JavaScript
*
* @param string|array $keys Key or array of key/value pairs
- * @param mixed $value [optional] Value of the configuration variable
+ * @param mixed|null $value [optional] Value of the configuration variable
*/
public function addJsConfigVars( $keys, $value = null ) {
if ( is_array( $keys ) ) {
* @return array
*/
public function getJSVars() {
- global $wgContLang;
-
$curRevisionId = 0;
$articleId = 0;
$canonicalSpecialPageName = false; # T23115
'wgRelevantPageName' => $relevantTitle->getPrefixedDBkey(),
'wgRelevantArticleId' => $relevantTitle->getArticleID(),
'wgRequestId' => WebRequest::getRequestId(),
+ 'wgCSPNonce' => $this->getCSPNonce(),
];
if ( $user->isLoggedIn() ) {
$vars['wgUserNewMsgRevisionId'] = $user->getNewMessageRevisionId();
}
- if ( $wgContLang->hasVariants() ) {
- $vars['wgUserVariant'] = $wgContLang->getPreferredVariant();
+ $contLang = MediaWikiServices::getInstance()->getContentLanguage();
+ if ( $contLang->hasVariants() ) {
+ $vars['wgUserVariant'] = $contLang->getPreferredVariant();
}
// Same test as SkinTemplate
$vars['wgIsProbablyEditable'] = $title->quickUserCan( 'edit', $user )
] );
}
+ // Allow extensions to add, remove and/or otherwise manipulate these links
+ // If you want only to *add* <head> links, please use the addHeadItem()
+ // (or addHeadItems() for multiple items) method instead.
+ // This hook is provided as a last resort for extensions to modify these
+ // links before the output is sent to client.
+ Hooks::run( 'OutputPageAfterGetHeadLinksArray', [ &$tags, $this ] );
+
return $tags;
}
* @since 1.32
*/
public function getCSPNonce() {
- if ( !ContentSecurityPolicy::isEnabled( $this->getConfig() ) ) {
+ if ( !ContentSecurityPolicy::isNonceRequired( $this->getConfig() ) ) {
return false;
}
if ( $this->CSPNonce === null ) {