25use WrappedString\WrappedString;
26use WrappedString\WrappedStringList;
262 'Accept-Encoding' => [
'match=gzip' ],
306 # Extensions should use `new RequestContext` instead of `new OutputPage` now.
319 public function redirect( $url, $responsecode =
'302' ) {
320 # Strip newlines as a paranoia check for header injection in PHP<5.1.2
321 $this->mRedirect = str_replace(
"\n",
'', $url );
322 $this->mRedirectCode = $responsecode;
343 $this->copyrightUrl = $url;
352 $this->mStatusCode = $statusCode;
363 array_push( $this->mMetatags, [
$name, $val ] );
384 array_push( $this->mLinktags, $linkarr );
415 $this->mCanonicalUrl = $url;
435 # note: buggy CC software only reads first "meta" link
436 static $haveMeta =
false;
438 return 'alternate meta';
453 $this->mScripts .= $script;
467 array_push( $this->mExtStyles, $url );
491 if ( substr( $file, 0, 1 ) ==
'/' || preg_match(
'#^[a-z]*://#i', $file ) ) {
494 $path = $this->
getConfig()->get(
'StylePath' ) .
"/common/{$file}";
496 if ( is_null( $version ) ) {
497 $version = $this->
getConfig()->get(
'StyleVersion' );
509 $this->mScripts .= Html::inlineScript( $script );
524 $filteredModules = [];
529 && ( is_null( $position ) || $module->getPosition() == $position )
530 && ( !$this->mTarget || in_array( $this->mTarget, $module->getTargets() ) )
532 $filteredModules[] = $val;
535 return $filteredModules;
546 public function getModules( $filter =
false, $position =
null, $param =
'mModules',
549 $modules = array_values( array_unique( $this->$param ) );
563 $this->mModules = array_merge( $this->mModules, (
array)
$modules );
574 return $this->
getModules( $filter, $position,
'mModuleScripts',
587 $this->mModuleScripts = array_merge( $this->mModuleScripts, (
array)
$modules );
598 return $this->
getModules( $filter, $position,
'mModuleStyles',
613 $this->mModuleStyles = array_merge( $this->mModuleStyles, (
array)
$modules );
629 $this->mTarget = $target;
664 $this->mHeadItems = array_merge( $this->mHeadItems, (
array)$values );
674 return isset( $this->mHeadItems[
$name] );
692 $this->mArticleBodyOnly = $only;
723 if ( isset( $this->mProperties[
$name] ) ) {
724 return $this->mProperties[
$name];
743 wfDebug( __METHOD__ .
": CACHE DISABLED, NO TIMESTAMP\n" );
747 if ( !$config->get(
'CachePages' ) ) {
748 wfDebug( __METHOD__ .
": CACHE DISABLED\n" );
755 'user' => $this->
getUser()->getTouched(),
756 'epoch' => $config->get(
'CacheEpoch' )
758 if ( $config->get(
'UseSquid' ) ) {
760 $modifiedTimes[
'sepoch'] =
wfTimestamp(
TS_MW, time() - $config->get(
'SquidMaxage' ) );
762 Hooks::run(
'OutputPageCheckLastModified', [ &$modifiedTimes, $this ] );
764 $maxModified = max( $modifiedTimes );
767 $clientHeader = $this->
getRequest()->getHeader(
'If-Modified-Since' );
768 if ( $clientHeader ===
false ) {
769 wfDebug( __METHOD__ .
": client did not send If-Modified-Since header",
'private' );
773 # IE sends sizes after the date like this:
774 # Wed, 20 Aug 2003 06:51:19 GMT; length=5202
775 # this breaks strtotime().
776 $clientHeader = preg_replace(
'/;.*$/',
'', $clientHeader );
778 MediaWiki\suppressWarnings();
779 $clientHeaderTime = strtotime( $clientHeader );
780 MediaWiki\restoreWarnings();
781 if ( !$clientHeaderTime ) {
783 .
": unable to parse the client's If-Modified-Since header: $clientHeader\n" );
791 if ( $info !==
'' ) {
797 wfDebug( __METHOD__ .
": client sent If-Modified-Since: " .
799 wfDebug( __METHOD__ .
": effective Last-Modified: " .
801 if ( $clientHeaderTime < $maxModified ) {
802 wfDebug( __METHOD__ .
": STALE, $info",
'private' );
807 # Give a 304 Not Modified response code and disable body output
808 wfDebug( __METHOD__ .
": NOT MODIFIED, $info",
'private' );
809 ini_set(
'zlib.output_compression', 0 );
810 $this->
getRequest()->response()->statusHeader( 304 );
843 if ( isset( $policy[
'index'] ) ) {
846 if ( isset( $policy[
'follow'] ) ) {
859 $policy = trim( $policy );
860 if ( in_array( $policy, [
'index',
'noindex' ] ) ) {
861 $this->mIndexPolicy = $policy;
873 $policy = trim( $policy );
874 if ( in_array( $policy, [
'follow',
'nofollow' ] ) ) {
875 $this->mFollowPolicy = $policy;
886 $this->mPageTitleActionText = $text;
908 $this->mHTMLtitle =
$name;
927 $this->mRedirectedFrom =
$t;
945 # change "<script>foo&bar</script>" to "<script>foo&bar</script>"
946 # but leave "<i>foobar</i>" alone
947 $nameWithTags = Sanitizer::normalizeCharReferences( Sanitizer::removeHTMLtags(
$name ) );
948 $this->mPagetitle = $nameWithTags;
950 # change "<i>foo&bar</i>" to "foo&bar"
952 $this->
msg(
'pagetitle' )->rawParams( Sanitizer::stripAllTags( $nameWithTags ) )
953 ->inContentLanguage()
991 if ( $str instanceof
Message ) {
992 $this->mSubtitle[] = $str->setContext( $this->
getContext() )->parse();
994 $this->mSubtitle[] = $str;
1007 if (
$title->isRedirect() ) {
1008 $query[
'redirect'] =
'no';
1028 $this->mSubtitle = [];
1037 return implode(
"<br />\n\t\t\t\t", $this->mSubtitle );
1045 $this->mPrintable =
true;
1061 $this->mDoNothing =
true;
1103 $this->mFeedLinks = [];
1117 $this->mFeedLinks = [];
1121 if ( is_string( $val ) ) {
1135 if ( in_array( $format, $this->
getConfig()->
get(
'AdvertisedFeedTypes' ) ) ) {
1136 $this->mFeedLinks[$format] = $href;
1145 return count( $this->mFeedLinks ) > 0;
1173 $this->mIsarticle = $v;
1175 $this->mIsArticleRelated = $v;
1196 $this->mIsArticleRelated = $v;
1198 $this->mIsarticle =
false;
1218 $this->mLanguageLinks += $newLinkArray;
1228 $this->mLanguageLinks = $newLinkArray;
1248 if ( !is_array( $categories ) || count( $categories ) == 0 ) {
1252 # Add the links to a LinkBatch
1257 # Fetch existence plus the hiddencat property
1259 $fields = array_merge(
1260 LinkCache::getSelectFields(),
1261 [
'page_namespace',
'page_title',
'pp_value' ]
1264 $res =
$dbr->select( [
'page',
'page_props' ],
1266 $lb->constructSet(
'page',
$dbr ),
1269 [
'page_props' => [
'LEFT JOIN', [
1270 'pp_propname' =>
'hiddencat',
1275 # Add the results to the link cache
1276 $lb->addResultToCache( LinkCache::singleton(),
$res );
1278 # Set all the values to 'normal'.
1279 $categories = array_fill_keys( array_keys( $categories ),
'normal' );
1281 # Mark hidden categories
1282 foreach (
$res as $row ) {
1283 if ( isset( $row->pp_value ) ) {
1284 $categories[$row->page_title] =
'hidden';
1288 # Add the remaining categories to the skin
1290 'OutputPageMakeCategoryLinks',
1291 [ &$this, $categories, &$this->mCategoryLinks ] )
1293 foreach ( $categories
as $category =>
$type ) {
1295 $category = (
string)$category;
1296 $origcategory = $category;
1302 if ( $category != $origcategory && array_key_exists( $category, $categories ) ) {
1306 $this->mCategories[] =
$title->getText();
1318 $this->mCategoryLinks = [];
1355 ksort( $this->mIndicators );
1380 $text = $this->
msg(
'helppage-top-gethelp' )->escaped();
1382 if ( $overrideBaseUrl ) {
1385 $toUrlencoded =
wfUrlencode( str_replace(
' ',
'_', $to ) );
1386 $helpUrl =
"//www.mediawiki.org/wiki/Special:MyLanguage/$toUrlencoded";
1389 $link = Html::rawElement(
1393 'target' =>
'_blank',
1394 'class' =>
'mw-helplink',
1418 if ( $this->
getConfig()->
get(
'AllowSiteCSSOnRestrictedPages' ) ) {
1437 return min( array_values( $this->mAllowedModules ) );
1439 return isset( $this->mAllowedModules[
$type] )
1440 ? $this->mAllowedModules[
$type]
1473 $this->mBodytext .= $text;
1493 $this->mBodytext =
'';
1517 $anonPO->setEditSection(
false );
1518 $anonPO->setAllowUnsafeRawHtml(
false );
1519 if ( !
$options->matches( $anonPO ) ) {
1525 if ( !$this->mParserOptions ) {
1531 $po->setEditSection(
false );
1532 $po->setAllowUnsafeRawHtml(
false );
1533 $po->isBogus =
true;
1541 $this->mParserOptions->setEditSection(
false );
1542 $this->mParserOptions->setAllowUnsafeRawHtml(
false );
1548 return wfSetVar( $this->mParserOptions,
null,
true );
1562 $val = is_null( $revid ) ? null : intval( $revid );
1563 return wfSetVar( $this->mRevisionId, $val );
1604 if ( $file instanceof
File && $file->
exists() ) {
1605 $val = [
'time' => $file->getTimestamp(),
'sha1' => $file->getSha1() ];
1607 return wfSetVar( $this->mFileVersion, $val,
true );
1648 public function addWikiText( $text, $linestart =
true, $interface =
true ) {
1700 $tidy =
false, $interface =
false
1705 $oldTidy = $popts->setTidy( $tidy );
1706 $popts->setInterfaceMessage( (
bool)$interface );
1710 $linestart,
true, $this->mRevisionId
1713 $popts->setTidy( $oldTidy );
1743 $this->mHideNewSectionLink =
$parserOutput->getHideNewSection();
1749 $this->mHeadItems = array_merge( $this->mHeadItems,
$parserOutput->getHeadItems() );
1754 $this->mPreventClickjacking = $this->mPreventClickjacking
1759 if ( isset( $this->mTemplateIds[$ns] ) ) {
1760 $this->mTemplateIds[$ns] = $dbks + $this->mTemplateIds[$ns];
1762 $this->mTemplateIds[$ns] = $dbks;
1767 $this->mImageTimeKeys[$dbk] = $data;
1771 $parserOutputHooks = $this->
getConfig()->get(
'ParserOutputHooks' );
1773 list( $hookName, $data ) = $hookInfo;
1774 if ( isset( $parserOutputHooks[$hookName] ) ) {
1775 call_user_func( $parserOutputHooks[$hookName], $this,
$parserOutput, $data );
1787 Hooks::run(
'LanguageLinks', [ $this->
getTitle(), &$this->mLanguageLinks, &$linkFlags ] );
1788 Hooks::run(
'OutputPageParserOutput', [ &$this,
$parserOutput ] );
1816 Hooks::run(
'OutputPageBeforeHTML', [ &$this, &$text ] );
1831 $parserOutput->setEditSectionTokens( $this->mEnableSectionEditLinks );
1858 public function parse( $text, $linestart =
true, $interface =
false, $language =
null ) {
1861 if ( is_null( $this->
getTitle() ) ) {
1862 throw new MWException(
'Empty $mTitle in ' . __METHOD__ );
1867 $popts->setInterfaceMessage(
true );
1869 if ( $language !==
null ) {
1870 $oldLang = $popts->setTargetLanguage( $language );
1875 $linestart,
true, $this->mRevisionId
1879 $popts->setInterfaceMessage(
false );
1881 if ( $language !==
null ) {
1882 $popts->setTargetLanguage( $oldLang );
1898 public function parseInline( $text, $linestart =
true, $interface =
false ) {
1899 $parsed = $this->
parse( $text, $linestart, $interface );
1900 return Parser::stripOuterParagraph( $parsed );
1917 $this->mCdnMaxage = min( $maxage, $this->mCdnMaxageLimit );
1927 $this->mCdnMaxageLimit = min( $maxage, $this->mCdnMaxageLimit );
1946 $maxTTL = $maxTTL ?: $this->
getConfig()->get(
'SquidMaxage' );
1948 if ( $mtime ===
null || $mtime ===
false ) {
1953 $adaptiveTTL = max( .9 * $age, $minTTL );
1954 $adaptiveTTL = min( $adaptiveTTL, $maxTTL );
1958 return $adaptiveTTL;
1969 return wfSetVar( $this->mEnableClientCache, $state );
1979 if ( $cookies ===
null ) {
1981 $cookies = array_merge(
1982 SessionManager::singleton()->getVaryCookies(),
1986 $config->get(
'CacheVaryCookies' )
1988 Hooks::run(
'GetCacheVaryCookies', [ $this, &$cookies ] );
2002 if (
$request->getCookie( $cookieName,
'',
'' ) !==
'' ) {
2003 wfDebug( __METHOD__ .
": found $cookieName\n" );
2007 wfDebug( __METHOD__ .
": no cache-varying cookies found\n" );
2020 if ( !array_key_exists(
$header, $this->mVaryHeader ) ) {
2021 $this->mVaryHeader[
$header] = [];
2023 if ( !is_array( $option ) ) {
2026 $this->mVaryHeader[
$header] = array_unique( array_merge( $this->mVaryHeader[
$header], $option ) );
2041 foreach ( SessionManager::singleton()->getVaryHeaders()
as $header =>
$options ) {
2044 return 'Vary: ' . implode(
', ', array_keys( $this->mVaryHeader ) );
2055 $cookiesOption = [];
2056 foreach ( $cvCookies
as $cookieName ) {
2057 $cookiesOption[] =
'param=' . $cookieName;
2061 foreach ( SessionManager::singleton()->getVaryHeaders()
as $header =>
$options ) {
2066 foreach ( $this->mVaryHeader
as $header => $option ) {
2068 if ( is_array( $option ) && count( $option ) > 0 ) {
2069 $newheader .=
';' . implode(
';', $option );
2071 $headers[] = $newheader;
2073 $key =
'Key: ' . implode(
',', $headers );
2093 if ( !$this->
getRequest()->getCheck(
'variant' ) &&
$lang->hasVariants() ) {
2094 $variants =
$lang->getVariants();
2096 foreach ( $variants
as $variant ) {
2097 if ( $variant ===
$lang->getCode() ) {
2100 $aloption[] =
'substr=' . $variant;
2105 $variantBCP47 =
wfBCP47( $variant );
2106 if ( $variantBCP47 !== $variant ) {
2107 $aloption[] =
'substr=' . $variantBCP47;
2126 $this->mPreventClickjacking = $enable;
2135 $this->mPreventClickjacking =
false;
2157 if ( $config->get(
'BreakFrames' ) ) {
2159 } elseif ( $this->mPreventClickjacking && $config->get(
'EditPageFrameOptions' ) ) {
2160 return $config->get(
'EditPageFrameOptions' );
2175 # don't serve compressed data to clients who can't handle it
2176 # maintain different caches for logged-in users and non-logged in ones
2179 if ( $config->get(
'UseKeyHeader' ) ) {
2183 if ( $this->mEnableClientCache ) {
2185 $config->get(
'UseSquid' ) &&
2187 !SessionManager::getGlobalSession()->isPersistent() &&
2188 !$this->isPrintable() &&
2189 $this->mCdnMaxage != 0 &&
2190 !$this->haveCacheVaryCookies()
2192 if ( $config->get(
'UseESI' ) ) {
2193 # We'll purge the proxy cache explicitly, but require end user agents
2194 # to revalidate against the proxy on each visit.
2195 # Surrogate-Control controls our CDN, Cache-Control downstream caches
2196 wfDebug( __METHOD__ .
": proxy caching with ESI; {$this->mLastModified} **",
'private' );
2197 # start with a shorter timeout for initial testing
2198 # header( 'Surrogate-Control: max-age=2678400+2678400, content="ESI/1.0"');
2199 $response->header(
'Surrogate-Control: max-age=' . $config->get(
'SquidMaxage' )
2200 .
'+' . $this->mCdnMaxage .
', content="ESI/1.0"' );
2201 $response->header(
'Cache-Control: s-maxage=0, must-revalidate, max-age=0' );
2203 # We'll purge the proxy cache for anons explicitly, but require end user agents
2204 # to revalidate against the proxy on each visit.
2205 # IMPORTANT! The CDN needs to replace the Cache-Control header with
2206 # Cache-Control: s-maxage=0, must-revalidate, max-age=0
2207 wfDebug( __METHOD__ .
": local proxy caching; {$this->mLastModified} **",
'private' );
2208 # start with a shorter timeout for initial testing
2209 # header( "Cache-Control: s-maxage=2678400, must-revalidate, max-age=0" );
2210 $response->header(
'Cache-Control: s-maxage=' . $this->mCdnMaxage
2211 .
', must-revalidate, max-age=0' );
2214 # We do want clients to cache if they can, but they *must* check for updates
2215 # on revisiting the page.
2216 wfDebug( __METHOD__ .
": private caching; {$this->mLastModified} **",
'private' );
2217 $response->header(
'Expires: ' . gmdate(
'D, d M Y H:i:s', 0 ) .
' GMT' );
2218 $response->header(
"Cache-Control: private, must-revalidate, max-age=0" );
2220 if ( $this->mLastModified ) {
2221 $response->header(
"Last-Modified: {$this->mLastModified}" );
2224 wfDebug( __METHOD__ .
": no caching **",
'private' );
2226 # In general, the absence of a last modified header should be enough to prevent
2227 # the client from using its cache. We send a few other things just to make sure.
2228 $response->header(
'Expires: ' . gmdate(
'D, d M Y H:i:s', 0 ) .
' GMT' );
2229 $response->header(
'Cache-Control: no-cache, no-store, max-age=0, must-revalidate' );
2230 $response->header(
'Pragma: no-cache' );
2247 if ( $this->mDoNothing ) {
2248 return $return ?
'' :
null;
2254 if ( $this->mRedirect !=
'' ) {
2255 # Standards require redirect URLs to be absolute
2261 if ( Hooks::run(
"BeforePageRedirect", [ $this, &$redirect, &
$code ] ) ) {
2263 if ( !$config->get(
'DebugRedirects' ) ) {
2268 if ( $config->get(
'VaryOnXFP' ) ) {
2273 $response->header(
"Content-Type: text/html; charset=utf-8" );
2274 if ( $config->get(
'DebugRedirects' ) ) {
2275 $url = htmlspecialchars( $redirect );
2276 print "<html>\n<head>\n<title>Redirect</title>\n</head>\n<body>\n";
2277 print "<p>Location: <a href=\"$url\">$url</a></p>\n";
2278 print "</body>\n</html>\n";
2280 $response->header(
'Location: ' . $redirect );
2284 return $return ?
'' :
null;
2285 } elseif ( $this->mStatusCode ) {
2286 $response->statusHeader( $this->mStatusCode );
2289 # Buffer output; final headers may depend on later processing
2292 $response->header(
'Content-type: ' . $config->get(
'MimeType' ) .
'; charset=UTF-8' );
2297 $response->header(
'X-UA-Compatible: IE=Edge' );
2301 if ( $frameOptions ) {
2302 $response->header(
"X-Frame-Options: $frameOptions" );
2305 if ( $this->mArticleBodyOnly ) {
2310 $modules = $sk->getDefaultModules();
2316 'mediawiki.page.startup',
2321 if ( $config->get(
'ResponsiveImages' ) ) {
2322 $coreModules[] =
'mediawiki.hidpi';
2329 MWDebug::addModules( $this );
2333 Hooks::run(
'BeforePageDisplay', [ &$this, &$sk ] );
2337 }
catch ( Exception
$e ) {
2345 Hooks::run(
'AfterFinalPageOutput', [ $this ] );
2346 }
catch ( Exception
$e ) {
2354 return ob_get_clean();
2373 if ( $htmlTitle !==
false ) {
2379 $this->mRedirect =
'';
2403 if ( $msg instanceof
Message ) {
2405 trigger_error(
'Argument ignored: $params. The message parameters argument '
2406 .
'is discarded when the $msg argument is a Message object instead of '
2407 .
'a string.', E_USER_NOTICE );
2409 $this->
addHTML( $msg->parseAsBlock() );
2424 foreach ( $errors
as $key => $error ) {
2425 $errors[$key] = (
array)$error;
2433 if ( in_array( $action, [
'read',
'edit',
'createpage',
'createtalk',
'upload' ] )
2434 && $this->
getUser()->isAnon() && count( $errors ) == 1 && isset( $errors[0][0] )
2435 && ( $errors[0][0] ==
'badaccess-groups' || $errors[0][0] ==
'badaccess-group0' )
2436 && ( User::groupHasPermission(
'user', $action )
2437 || User::groupHasPermission(
'autoconfirmed', $action ) )
2439 $displayReturnto =
null;
2441 # Due to bug 32276, if a user does not have read permissions,
2442 # $this->getTitle() will just give Special:Badtitle, which is
2443 # not especially useful as a returnto parameter. Use the title
2444 # from the request instead, if there was one.
2446 $returnto = Title::newFromText(
$request->getVal(
'title',
'' ) );
2447 if ( $action ==
'edit' ) {
2448 $msg =
'whitelistedittext';
2449 $displayReturnto = $returnto;
2450 } elseif ( $action ==
'createpage' || $action ==
'createtalk' ) {
2451 $msg =
'nocreatetext';
2452 } elseif ( $action ==
'upload' ) {
2453 $msg =
'uploadnologintext';
2455 $msg =
'loginreqpagetext';
2456 $displayReturnto = Title::newMainPage();
2462 $query[
'returnto'] = $returnto->getPrefixedText();
2465 $returntoquery =
$request->getValues();
2466 unset( $returntoquery[
'title'] );
2467 unset( $returntoquery[
'returnto'] );
2468 unset( $returntoquery[
'returntoquery'] );
2474 $this->
msg(
'loginreqlink' )->escaped(),
2480 $this->
addHTML( $this->
msg( $msg )->rawParams( $loginLink )->
parse() );
2482 # Don't return to a page the user can't read otherwise
2483 # we'll end up in a pointless loop
2484 if ( $displayReturnto && $displayReturnto->userCan(
'read', $this->getUser() ) ) {
2502 $this->
addWikiMsg(
'versionrequiredtext', $version );
2514 if ( $action ==
null ) {
2515 $text = $this->
msg(
'permissionserrorstext', count( $errors ) )->plain() .
"\n\n";
2517 $action_desc = $this->
msg(
"action-$action" )->plain();
2519 'permissionserrorstext-withaction',
2522 )->plain() .
"\n\n";
2525 if ( count( $errors ) > 1 ) {
2526 $text .=
'<ul class="permissions-errors">' .
"\n";
2528 foreach ( $errors
as $error ) {
2530 $text .= call_user_func_array( [ $this,
'msg' ], $error )->plain();
2535 $text .=
"<div class=\"permissions-errors\">\n" .
2536 call_user_func_array( [ $this,
'msg' ], reset( $errors ) )->plain() .
2555 if ( func_num_args() > 0 ) {
2556 throw new MWException( __METHOD__ .
' no longer accepts arguments since 1.25.' );
2584 if ( $lag >= $config->get(
'SlaveLagWarning' ) ) {
2585 $lag = floor( $lag );
2586 $message = $lag < $config->get(
'SlaveLagCritical' )
2589 $wrap = Html::rawElement(
'div', [
'class' =>
"mw-{$message}" ],
"\n$1\n" );
2629 $link = $this->
msg(
'returnto' )->rawParams(
2631 $this->
addHTML(
"<p id=\"mw-returnto\">{$link}</p>\n" );
2642 public function returnToMain( $unused =
null, $returnto =
null, $returntoquery =
null ) {
2643 if ( $returnto ==
null ) {
2644 $returnto = $this->
getRequest()->getText(
'returnto' );
2647 if ( $returntoquery ==
null ) {
2648 $returntoquery = $this->
getRequest()->getText(
'returntoquery' );
2651 if ( $returnto ===
'' ) {
2652 $returnto = Title::newMainPage();
2655 if ( is_object( $returnto ) ) {
2656 $titleObj = $returnto;
2658 $titleObj = Title::newFromText( $returnto );
2662 if ( !is_object( $titleObj ) || $titleObj->isExternal() ) {
2663 $titleObj = Title::newMainPage();
2670 if ( !$this->rlClientContext ) {
2674 $this->
getSkin()->getSkinName(),
2675 $this->
getUser()->isLoggedIn() ? $this->
getUser()->getName() :
null,
2702 if ( !$this->rlClient ) {
2715 $this->
getSkin()->setupSkinUserCss( $this );
2718 $exemptGroups = [
'site' => [],
'noscript' => [],
'private' => [],
'user' => [] ];
2724 $userBatch = [
'user.styles',
'user' ];
2725 $siteBatch = array_diff( $moduleStyles, $userBatch );
2731 $moduleStyles = array_filter( $moduleStyles,
2733 $module = $rl->getModule(
$name );
2736 $exemptStates[
$name] =
'ready';
2740 $group = $module->getGroup();
2741 if ( isset( $exemptGroups[$group] ) ) {
2742 $exemptStates[
$name] =
'ready';
2743 if ( !$module->isKnownEmpty(
$context ) ) {
2745 $exemptGroups[$group][] = $name;
2753 $this->rlExemptStyleModules = $exemptGroups;
2755 $isUserModuleFiltered = !$this->
filterModules( [
'user' ] );
2758 if ( !$isUserModuleFiltered ) {
2760 $userModule = $rl->getModule(
'user' );
2764 $this->rlUserModuleState = $exemptStates[
'user'] = $userState;
2790 $pieces[] = Html::htmlHeader( Sanitizer::mergeAttributes(
2794 $pieces[] = Html::openElement(
'head' );
2800 if ( !Html::isXmlMimeType( $this->
getConfig()->
get(
'MimeType' ) ) ) {
2809 $pieces[] = Html::element(
'meta', [
'charset' =>
'UTF-8' ] );
2812 $pieces[] = Html::element(
'title',
null, $this->
getHTMLTitle() );
2816 $pieces = array_merge( $pieces, array_values( $this->mHeadItems ) );
2817 $pieces[] = Html::closeElement(
'head' );
2820 $bodyClasses[] =
'mediawiki';
2822 # Classes for LTR/RTL directionality support
2823 $bodyClasses[] = $userdir;
2824 $bodyClasses[] =
"sitedir-$sitedir";
2826 if ( $this->
getLanguage()->capitalizeAllNouns() ) {
2827 # A <body> class is probably not the best way to do this . . .
2828 $bodyClasses[] =
'capitalize-all-nouns';
2834 $bodyClasses[] =
'mw-hide-empty-elt';
2837 $bodyClasses[] =
'skin-' . Sanitizer::escapeClass( $sk->
getSkinName() );
2844 $bodyAttrs[
'class'] = implode(
' ', $bodyClasses );
2848 Hooks::run(
'OutputPageBodyAttributes', [ $this, $sk, &$bodyAttrs ] );
2850 $pieces[] = Html::openElement(
'body', $bodyAttrs );
2861 if ( is_null( $this->mResourceLoader ) ) {
2864 LoggerFactory::getInstance(
'resourceloader' )
2898 $chunks = array_filter( $chunks,
'strlen' );
2899 return WrappedString::join(
"\n", $chunks );
2903 return $this->
getConfig()->get(
'AllowUserJs' )
2905 && $this->
getTitle()->isJsSubpage()
2910 return $this->
getConfig()->get(
'AllowUserCss' )
2912 && $this->
getTitle()->isCssSubpage()
2934 if ( $this->rlUserModuleState ===
'loading' ) {
2937 [
'excludepage' => $this->
getTitle()->getPrefixedDBkey() ]
2983 if ( is_array(
$keys ) ) {
2985 $this->mJsConfigVars[$key] =
$value;
3007 $canonicalSpecialPageName =
false; # bug 21115
3010 $ns =
$title->getNamespace();
3011 $canonicalNamespace = MWNamespace::exists( $ns )
3012 ? MWNamespace::getCanonicalName( $ns )
3018 $relevantTitle = $sk->getRelevantTitle();
3019 $relevantUser = $sk->getRelevantUser();
3022 list( $canonicalSpecialPageName, ) =
3026 $curRevisionId = $wikiPage->getLatest();
3027 $articleId = $wikiPage->getId();
3033 $separatorTransTable =
$lang->separatorTransformTable();
3034 $separatorTransTable = $separatorTransTable ? $separatorTransTable : [];
3035 $compactSeparatorTransTable = [
3036 implode(
"\t", array_keys( $separatorTransTable ) ),
3037 implode(
"\t", $separatorTransTable ),
3039 $digitTransTable =
$lang->digitTransformTable();
3040 $digitTransTable = $digitTransTable ? $digitTransTable : [];
3041 $compactDigitTransTable = [
3042 implode(
"\t", array_keys( $digitTransTable ) ),
3043 implode(
"\t", $digitTransTable ),
3049 'wgCanonicalNamespace' => $canonicalNamespace,
3050 'wgCanonicalSpecialPageName' => $canonicalSpecialPageName,
3051 'wgNamespaceNumber' =>
$title->getNamespace(),
3052 'wgPageName' =>
$title->getPrefixedDBkey(),
3053 'wgTitle' =>
$title->getText(),
3054 'wgCurRevisionId' => $curRevisionId,
3056 'wgArticleId' => $articleId,
3058 'wgIsRedirect' => $title->isRedirect(),
3060 'wgUserName' =>
$user->isAnon() ? null :
$user->getName(),
3061 'wgUserGroups' =>
$user->getEffectiveGroups(),
3064 'wgPageContentLanguage' =>
$lang->getCode(),
3065 'wgPageContentModel' => $title->getContentModel(),
3066 'wgSeparatorTransformTable' => $compactSeparatorTransTable,
3067 'wgDigitTransformTable' => $compactDigitTransTable,
3068 'wgDefaultDateFormat' =>
$lang->getDefaultDateFormat(),
3069 'wgMonthNames' =>
$lang->getMonthNamesArray(),
3070 'wgMonthNamesShort' =>
$lang->getMonthAbbreviationsArray(),
3071 'wgRelevantPageName' => $relevantTitle->getPrefixedDBkey(),
3072 'wgRelevantArticleId' => $relevantTitle->getArticleID(),
3073 'wgRequestId' => WebRequest::getRequestId(),
3076 if (
$user->isLoggedIn() ) {
3078 $vars[
'wgUserEditCount'] =
$user->getEditCount();
3079 $userReg =
$user->getRegistration();
3084 $vars[
'wgUserNewMsgRevisionId'] =
$user->getNewMessageRevisionId();
3098 if (
$title->isMainPage() ) {
3099 $vars[
'wgIsMainPage'] =
true;
3102 if ( $this->mRedirectedFrom ) {
3103 $vars[
'wgRedirectedFrom'] = $this->mRedirectedFrom->getPrefixedDBkey();
3106 if ( $relevantUser ) {
3107 $vars[
'wgRelevantUserName'] = $relevantUser->getName();
3114 Hooks::run(
'MakeGlobalVariablesScript', [ &
$vars, $this ] );
3132 $request->getVal(
'action' ) !==
'submit' ||
3133 !
$request->getCheck(
'wpPreview' ) ||
3141 if ( !
$user->isLoggedIn() ) {
3145 if ( !
$user->matchEditToken(
$request->getVal(
'wpEditToken' ) ) ) {
3150 if ( !
$title->isJsSubpage() && !
$title->isCssSubpage() ) {
3153 if ( !
$title->isSubpageOf(
$user->getUserPage() ) ) {
3158 $errors =
$title->getUserPermissionsErrors(
'edit',
$user );
3159 if ( count( $errors ) !== 0 ) {
3177 $tags[
'meta-generator'] = Html::element(
'meta', [
3178 'name' =>
'generator',
3179 'content' =>
"MediaWiki $wgVersion",
3182 if ( $config->get(
'ReferrerPolicy' ) !==
false ) {
3183 $tags[
'meta-referrer'] = Html::element(
'meta', [
3184 'name' =>
'referrer',
3185 'content' => $config->get(
'ReferrerPolicy' )
3189 $p =
"{$this->mIndexPolicy},{$this->mFollowPolicy}";
3190 if ( $p !==
'index,follow' ) {
3193 $tags[
'meta-robots'] = Html::element(
'meta', [
3199 foreach ( $this->mMetatags
as $tag ) {
3200 if ( 0 == strcasecmp(
'http:', substr(
$tag[0], 0, 5 ) ) ) {
3206 $tagName =
"meta-{$tag[0]}";
3207 if ( isset( $tags[$tagName] ) ) {
3208 $tagName .=
$tag[1];
3210 $tags[$tagName] = Html::element(
'meta',
3213 'content' =>
$tag[1]
3218 foreach ( $this->mLinktags
as $tag ) {
3219 $tags[] = Html::element(
'link',
$tag );
3222 # Universal edit button
3223 if ( $config->get(
'UniversalEditButton' ) && $this->isArticleRelated() ) {
3226 && ( $this->
getTitle()->exists() ||
3230 $msg = $this->
msg(
'edit' )->text();
3231 $tags[
'universal-edit-button'] = Html::element(
'link', [
3232 'rel' =>
'alternate',
3233 'type' =>
'application/x-wiki',
3235 'href' => $this->
getTitle()->getEditURL(),
3238 $tags[
'alternative-edit'] = Html::element(
'link', [
3241 'href' => $this->
getTitle()->getEditURL(),
3246 # Generally the order of the favicon and apple-touch-icon links
3247 # should not matter, but Konqueror (3.5.9 at least) incorrectly
3248 # uses whichever one appears later in the HTML source. Make sure
3249 # apple-touch-icon is specified first to avoid this.
3250 if ( $config->get(
'AppleTouchIcon' ) !==
false ) {
3251 $tags[
'apple-touch-icon'] = Html::element(
'link', [
3252 'rel' =>
'apple-touch-icon',
3253 'href' => $config->get(
'AppleTouchIcon' )
3257 if ( $config->get(
'Favicon' ) !==
false ) {
3258 $tags[
'favicon'] = Html::element(
'link', [
3259 'rel' =>
'shortcut icon',
3260 'href' => $config->get(
'Favicon' )
3264 # OpenSearch description link
3265 $tags[
'opensearch'] = Html::element(
'link', [
3267 'type' =>
'application/opensearchdescription+xml',
3268 'href' =>
wfScript(
'opensearch_desc' ),
3269 'title' => $this->
msg(
'opensearch-desc' )->inContentLanguage()->
text(),
3272 if ( $config->get(
'EnableAPI' ) ) {
3273 # Real Simple Discovery link, provides auto-discovery information
3274 # for the MediaWiki API (and potentially additional custom API
3275 # support such as WordPress or Twitter-compatible APIs for a
3276 # blogging extension, etc)
3277 $tags[
'rsd'] = Html::element(
'link', [
3279 'type' =>
'application/rsd+xml',
3285 [
'action' =>
'rsd' ] ),
3292 if ( !$config->get(
'DisableLangConversion' ) ) {
3294 if (
$lang->hasVariants() ) {
3295 $variants =
$lang->getVariants();
3296 foreach ( $variants
as $variant ) {
3297 $tags[
"variant-$variant"] = Html::element(
'link', [
3298 'rel' =>
'alternate',
3299 'hreflang' =>
wfBCP47( $variant ),
3300 'href' => $this->
getTitle()->getLocalURL(
3301 [
'variant' => $variant ] )
3305 # x-default link per https:
3306 $tags[
"variant-x-default"] = Html::element(
'link', [
3307 'rel' =>
'alternate',
3308 'hreflang' =>
'x-default',
3309 'href' => $this->
getTitle()->getLocalURL() ] );
3314 if ( $this->copyrightUrl !==
null ) {
3318 if ( $config->get(
'RightsPage' ) ) {
3319 $copy = Title::newFromText( $config->get(
'RightsPage' ) );
3322 $copyright = $copy->getLocalURL();
3326 if ( !$copyright && $config->get(
'RightsUrl' ) ) {
3327 $copyright = $config->get(
'RightsUrl' );
3332 $tags[
'copyright'] = Html::element(
'link', [
3333 'rel' =>
'copyright',
3334 'href' => $copyright ]
3339 if ( $config->get(
'Feed' ) ) {
3343 # Use the page name for the title. In principle, this could
3344 # lead to issues with having the same name for different feeds
3345 # corresponding to the same page, but we can't avoid that at
3351 # Used
messages:
'page-rss-feed' and 'page-atom-feed' (
for an easier grep)
3353 "page-{$format}-feed", $this->
getTitle()->getPrefixedText()
3358 # Recent changes feed should appear on every page (except recentchanges,
3359 # that would be redundant). Put it after the per-page feed to avoid
3360 # changing existing behavior. It's still available, probably via a
3361 # menu in your browser. Some sites might have a different feed they'd
3362 # like to promote instead of the RC feed (maybe like a "Recent New Articles"
3363 # or "Breaking news" one). For this, we see if $wgOverrideSiteFeed is defined.
3364 # If so, use it instead.
3365 $sitename = $config->get(
'Sitename' );
3366 if ( $config->get(
'OverrideSiteFeed' ) ) {
3367 foreach ( $config->get(
'OverrideSiteFeed' )
as $type => $feedUrl ) {
3372 $this->
msg(
"site-{$type}-feed", $sitename )->
text()
3375 } elseif ( !$this->
getTitle()->isSpecial(
'Recentchanges' ) ) {
3377 foreach ( $config->get(
'AdvertisedFeedTypes' )
as $format ) {
3380 $rctitle->getLocalURL( [
'feed' => $format ] ),
3381 # For grep:
'site-rss-feed',
'site-atom-feed'
3382 $this->
msg(
"site-{$format}-feed", $sitename )->text()
3387 # Allow extensions to change the list pf feeds. This hook is primarily for changing,
3388 # manipulating or removing existing feed tags. If you want to add new feeds, you should
3389 # use OutputPage::addFeedLink() instead.
3390 Hooks::run(
'AfterBuildFeedLinks', [ &$feedLinks ] );
3392 $tags += $feedLinks;
3396 if ( $config->get(
'EnableCanonicalServerLink' ) ) {
3397 if ( $canonicalUrl !==
false ) {
3409 if ( in_array( $action, [
'history',
'info' ] ) ) {
3410 $query =
"action={$action}";
3416 $reqUrl = $this->
getRequest()->getRequestURL();
3421 if ( $canonicalUrl !==
false ) {
3422 $tags[] = Html::element(
'link', [
3423 'rel' =>
'canonical',
3424 'href' => $canonicalUrl
3450 return Html::element(
'link', [
3451 'rel' =>
'alternate',
3452 'type' =>
"application/$type+xml",
3467 public function addStyle( $style, $media =
'', $condition =
'',
$dir =
'' ) {
3473 $options[
'condition'] = $condition;
3489 if ( $flip ===
'flip' && $this->
getLanguage()->isRTL() ) {
3490 # If wanted, and the interface is right-to-left, flip the CSS
3491 $style_css = CSSJanus::transform( $style_css,
true,
false );
3493 $this->mInlineStyles .= Html::inlineStyle( $style_css );
3514 [
'excludepage' => $this->
getTitle()->getPrefixedDBkey() ]
3519 $previewedCSS = $this->
getRequest()->getText(
'wpTextbox1' );
3521 $previewedCSS = CSSJanus::transform( $previewedCSS,
true,
false );
3523 $append[] = Html::inlineStyle( $previewedCSS );
3537 $chunks[] = Html::element(
3539 [
'name' =>
'ResourceLoaderDynamicStyles',
'content' =>
'' ]
3542 foreach ( $this->rlExemptStyleModules
as $group => $moduleNames ) {
3558 foreach ( $this->mExtStyles
as $url ) {
3561 $this->mExtStyles = [];
3563 foreach ( $this->styles
as $file =>
$options ) {
3566 $links[$file] =
$link;
3586 if ( isset(
$options[
'media'] ) ) {
3588 if ( is_null( $media ) ) {
3595 if ( substr( $style, 0, 1 ) ==
'/' ||
3596 substr( $style, 0, 5 ) ==
'http:' ||
3597 substr( $style, 0, 6 ) ==
'https:' ) {
3601 $url = $config->get(
'StylePath' ) .
'/' . $style .
'?' .
3602 $config->get(
'StyleVersion' );
3605 $link = Html::linkedStyle( $url, $media );
3607 if ( isset(
$options[
'condition'] ) ) {
3608 $condition = htmlspecialchars(
$options[
'condition'] );
3609 $link =
"<!--[if $condition]>$link<![endif]-->";
3637 $remotePathPrefix = $config->
get(
'ResourceBasePath' );
3638 if ( $remotePathPrefix ===
'' ) {
3643 $remotePath = $remotePathPrefix;
3645 if ( strpos(
$path, $remotePath ) !== 0 ) {
3649 $path = RelPath\getRelativePath(
$path, $remotePath );
3665 $hash = md5_file(
"$localPath/$file" );
3666 if ( $hash ===
false ) {
3667 wfLogWarning( __METHOD__ .
": Failed to hash $localPath/$file" );
3670 return "$remotePathPrefix/$file?" . substr( $hash, 0, 5 );
3684 $screenMediaQueryRegex =
'/^(?:only\s+)?screen\b/i';
3688 'printable' =>
'print',
3689 'handheld' =>
'handheld',
3691 foreach ( $switches
as $switch => $targetMedia ) {
3693 if ( $media == $targetMedia ) {
3695 } elseif ( preg_match( $screenMediaQueryRegex, $media ) === 1 ) {
3709 if ( $targetMedia ==
'print' || $media ==
'screen' ) {
3726 $args = func_get_args();
3769 $msgSpecs = func_get_args();
3770 array_shift( $msgSpecs );
3771 $msgSpecs = array_values( $msgSpecs );
3773 foreach ( $msgSpecs
as $n => $spec ) {
3774 if ( is_array( $spec ) ) {
3777 if ( isset(
$args[
'options'] ) ) {
3778 unset(
$args[
'options'] );
3780 'Adding "options" to ' . __METHOD__ .
' is no longer supported',
3799 $this->mEnableTOC = $flag;
3816 $this->mEnableSectionEditLinks = $flag;
3837 $themes = array_change_key_case( $themes, CASE_LOWER );
3838 $theme = isset( $themes[$skinName] ) ? $themes[$skinName] :
'MediaWiki';
3840 $themeClass =
"OOUI\\{$theme}Theme";
3841 OOUI\Theme::setSingleton(
new $themeClass() );
3842 OOUI\Element::setDefaultDir(
$dir );
3853 strtolower( $this->
getSkin()->getSkinName() ),
3857 'oojs-ui-core.styles',
3858 'oojs-ui.styles.icons',
3859 'oojs-ui.styles.indicators',
3860 'oojs-ui.styles.textures',
3861 'mediawiki.widgets.styles',
and(b) You must cause any modified files to carry prominent notices stating that You changed the files
Apache License January AND DISTRIBUTION Definitions License shall mean the terms and conditions for use
$wgVersion
MediaWiki version number.
wfDebug( $text, $dest='all', array $context=[])
Sends a line to the debug log if enabled or, optionally, to a comment in output.
wfUrlencode( $s)
We want some things to be included as literal characters in our title URLs for prettiness,...
wfBCP47( $code)
Get the normalised IETF language tag See unit test for examples.
wfGetDB( $db, $groups=[], $wiki=false)
Get a Database object.
wfExpandUrl( $url, $defaultProto=PROTO_CURRENT)
Expand a potentially local URL to a fully-qualified URL.
wfSetVar(&$dest, $source, $force=false)
Sets dest to source and returns the original value of dest If source is NULL, it just returns the val...
wfGetAllCallers( $limit=3)
Return a string consisting of callers in the stack.
wfLogWarning( $msg, $callerOffset=1, $level=E_USER_WARNING)
Send a warning as a PHP error and the debug log.
wfClearOutputBuffers()
More legible than passing a 'false' parameter to wfResetOutputBuffers():
wfAppendQuery( $url, $query)
Append a query string to an existing URL, which may or may not already have query string parameters a...
wfArrayToCgi( $array1, $array2=null, $prefix='')
This function takes one or two arrays as input, and returns a CGI-style string, e....
wfScript( $script='index')
Get the path to a specified script file, respecting file extensions; this is a wrapper around $wgScri...
wfCgiToArray( $query)
This is the logical opposite of wfArrayToCgi(): it accepts a query string as its argument and returns...
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
wfDeprecated( $function, $version=false, $component=false, $callerOffset=2)
Throws a warning that $function is deprecated.
if(! $wgDBerrorLogTZ) $wgRequest
static getActionName(IContextSource $context)
Get the action that will be executed, not necessarily the one passed passed through the "action" requ...
static formatRobotPolicy( $policy)
Converts a String robot policy into an associative array, to allow merging of several policies using ...
The simplest way of implementing IContextSource is to hold a RequestContext as a member variable and ...
getSkin()
Get the Skin object.
getUser()
Get the User object.
getRequest()
Get the WebRequest object.
canUseWikiPage()
Check whether a WikiPage object can be get with getWikiPage().
getConfig()
Get the Config object.
msg()
Get a Message object with context set Parameters are the same as wfMessage()
getTitle()
Get the Title object.
getWikiPage()
Get the WikiPage object.
getLanguage()
Get the Language object.
getContext()
Get the base IContextSource object.
setContext(IContextSource $context)
Set the IContextSource object.
WebRequest clone which takes values from a provided array.
Implements some public methods and some protected utility functions which are required by multiple ch...
exists()
Returns true if file exists in the repository.
Class representing a list of titles The execute() method checks them all for existence and adds them ...
setArray( $array)
Set the link list to a given 2-d array First key is the namespace, second is the DB key,...
static link( $target, $html=null, $customAttribs=[], $query=[], $options=[])
This function returns an HTML link to the given target.
static linkKnown( $target, $html=null, $customAttribs=[], $query=[], $options=[ 'known'])
Identical to link(), except $options defaults to 'known'.
The Message class provides methods which fulfil two basic services:
This class should be covered by a general architecture document which does not exist as of January 20...
isArticle()
Return whether the content displayed page is related to the source of the corresponding article on th...
addWikiMsg()
Add a wikitext-formatted message to the output.
setFileVersion( $file)
Set the displayed file version.
$mScripts
Used for JavaScript (predates ResourceLoader)
addWikiTextWithTitle( $text, &$title, $linestart=true)
Add wikitext with a custom Title object.
addScriptFile( $file, $version=null)
Add a JavaScript file out of skins/common, or a given relative path.
disable()
Disable output completely, i.e.
addLink(array $linkarr)
Add a new <link> tag to the page header.
addParserOutputNoText( $parserOutput)
Add a ParserOutput object, but without Html.
ResourceLoader $mResourceLoader
showFileCopyError( $old, $new)
getCanonicalUrl()
Returns the URL to be used for the <link rel=canonical>> if one is set.
getPageTitle()
Return the "page title", i.e.
getModuleScripts( $filter=false, $position=null)
Get the list of module JS to include on this page.
isArticleRelated()
Return whether this page is related an article on the wiki.
getLanguageLinks()
Get the list of language links.
addWikiText( $text, $linestart=true, $interface=true)
Convert wikitext to HTML and add it to the buffer Default assumes that the current page title will be...
allowClickjacking()
Turn off frame-breaking.
filterModules(array $modules, $position=null, $type=ResourceLoaderModule::TYPE_COMBINED)
Filter an array of modules to remove insufficiently trustworthy members, and modules which are no lon...
getSyndicationLinks()
Return URLs for each supported syndication format for this page.
addMeta( $name, $val)
Add a new "<meta>" tag To add an http-equiv meta tag, precede the name with "http:".
showFileNotFoundError( $name)
bool $mIsarticle
Is the displayed content related to the source of the corresponding wiki article.
getMetadataAttribute()
Get the value of the "rel" attribute for metadata links.
bool $mEnableSectionEditLinks
Whether parser output should contain section edit links.
parseInline( $text, $linestart=true, $interface=false)
Parse wikitext, strip paragraphs, and return the HTML.
showFileRenameError( $old, $new)
$mFeedLinks
Handles the Atom / RSS links.
showUnexpectedValueError( $name, $val)
setCopyrightUrl( $url)
Set the copyright URL to send with the output.
setRobotPolicy( $policy)
Set the robot policy for the page: http://www.robotstxt.org/meta.html
setIndexPolicy( $policy)
Set the index policy for the page, but leave the follow policy un- touched.
getTemplateIds()
Get the templates used on this page.
setPageTitle( $name)
"Page title" means the contents of <h1>.
output( $return=false)
Finally, all the text has been munged and accumulated into the object, let's actually output it:
redirect( $url, $responsecode='302')
Redirect to $url rather than displaying the normal page.
readOnlyPage()
Display a page stating that the Wiki is in read-only mode.
getRedirect()
Get the URL to redirect to, or an empty string if not redirect URL set.
setLastModified( $timestamp)
Override the last modified timestamp.
setLanguageLinks(array $newLinkArray)
Reset the language links and add new language links.
addFeedLink( $format, $href)
Add a feed link to the page header.
setTitle(Title $t)
Set the Title object to use.
setCategoryLinks(array $categories)
Reset the category links (but not the category list) and add $categories.
getFileVersion()
Get the displayed file version.
setSyndicated( $show=true)
Add or remove feed links in the page header This is mainly kept for backward compatibility,...
bool $mHideNewSectionLink
adaptCdnTTL( $mtime, $minTTL=0, $maxTTL=0)
Get TTL in [$minTTL,$maxTTL] in pass it to lowerCdnMaxage()
sendCacheControl()
Send cache control HTTP headers.
string $mPageTitleActionText
setTarget( $target)
Sets ResourceLoader target for load.php links.
addCategoryLinks(array $categories)
Add an array of categories, with names in the keys.
int $mRevisionId
To include the variable {{REVISIONID}}.
showLagWarning( $lag)
Show a warning about replica DB lag.
clearSubtitle()
Clear the subtitles.
showFatalError( $message)
setCdnMaxage( $maxage)
Set the value of the "s-maxage" part of the "Cache-control" HTTP header.
getJsConfigVars()
Get the javascript config vars to include on this page.
getHTML()
Get the body HTML.
array $mMetatags
Should be private.
addWikiTextTitle( $text, Title $title, $linestart, $tidy=false, $interface=false)
Add wikitext with a custom Title object.
array $mAllowedModules
What level of 'untrustworthiness' is allowed in CSS/JS modules loaded on this page?
getJSVars()
Get an array containing the variables to be set in mw.config in JavaScript.
bool $mPreventClickjacking
Controls if anti-clickjacking / frame-breaking headers will be sent.
haveCacheVaryCookies()
Check if the request has a cache-varying cookie header If it does, it's very important that we don't ...
versionRequired( $version)
Display an error page indicating that a given version of MediaWiki is required to use it.
static setupOOUI( $skinName='', $dir='ltr')
Helper function to setup the PHP implementation of OOUI to use in this request.
reduceAllowedModules( $type, $level)
Limit the highest level of CSS/JS untrustworthiness allowed.
addInlineStyle( $style_css, $flip='noflip')
Adds inline CSS styles Internal use only.
getRevisionTimestamp()
Get the timestamp of displayed revision.
string $rlUserModuleState
preventClickjacking( $enable=true)
Set a flag which will cause an X-Frame-Options header appropriate for edit pages to be sent.
bool $mPrintable
We have to set isPrintable().
setFollowPolicy( $policy)
Set the follow policy for the page, but leave the index policy un- touched.
setArticleFlag( $v)
Set whether the displayed content is related to the source of the corresponding article on the wiki S...
getHeadItemsArray()
Get an array of head items.
isPrintable()
Return whether the page is "printable".
getModules( $filter=false, $position=null, $param='mModules', $type=ResourceLoaderModule::TYPE_COMBINED)
Get the list of modules to include on this page.
setRedirectedFrom( $t)
Set $mRedirectedFrom, the Title of the page which redirected us to the current page.
getFeedAppendQuery()
Will currently always return null.
addModuleStyles( $modules)
Add only CSS of one or more modules recognized by ResourceLoader.
setHTMLTitle( $name)
"HTML title" means the contents of "<title>".
returnToMain( $unused=null, $returnto=null, $returntoquery=null)
Add a "return to" link pointing to a specified title, or the title indicated in the request,...
array $mHeadItems
Array of elements in "<head>".
isSyndicated()
Should we output feed links for this page?
styleLink( $style, array $options)
Generate <link> tags for stylesheets.
rateLimited()
Turn off regular page output and return an error response for when rate limiting has triggered.
__construct(IContextSource $context=null)
Constructor for OutputPage.
getCategories()
Get the list of category names this page belongs to.
static transformResourcePath(Config $config, $path)
Transform path to web-accessible static resource.
addParserOutputText( $parserOutput)
Add the HTML associated with a ParserOutput object, without any metadata.
addExtensionStyle( $url)
Register and add a stylesheet from an extension directory.
addElement( $element, array $attribs=[], $contents='')
Shortcut for adding an Html::element via addHTML.
makeResourceLoaderLink( $modules, $only, array $extraQuery=[])
Explicily load or embed modules on a page.
getSubtitle()
Get the subtitle.
addWikiTextTitleTidy( $text, &$title, $linestart=true)
Add wikitext with a custom Title object and tidy enabled.
showPermissionsErrorPage(array $errors, $action=null)
Output a standard permission error page.
addSubtitle( $str)
Add $str to the subtitle.
setRevisionId( $revid)
Set the revision ID which will be seen by the wiki text parser for things such as embedded {{REVISION...
getPreventClickjacking()
Get the prevent-clickjacking flag.
string $mPagetitle
Should be private - has getter and setter.
enableOOUI()
Add ResourceLoader module styles for OOUI and set up the PHP implementation of it for use with MediaW...
sectionEditLinksEnabled()
getIndicators()
Get the indicators associated with this page.
$mProperties
Additional key => value data.
addParserOutputContent( $parserOutput)
Add the HTML and enhancements for it (like ResourceLoader modules) associated with a ParserOutput obj...
addWikiMsgArray( $name, $args)
Add a wikitext-formatted message to the output.
addModuleScripts( $modules)
Add only JS of one or more modules recognized by ResourceLoader.
array $mExtStyles
Additional stylesheets.
string $mBodytext
Contains all of the "<body>" content.
addScript( $script)
Add raw HTML to the list of scripts (including <script> tag, etc.) Internal use only.
clearHTML()
Clear the body HTML.
array $mSubtitle
Contains the page subtitle.
addVaryHeader( $header, array $option=null)
Add an HTTP header that will influence on the cache.
addStyle( $style, $media='', $condition='', $dir='')
Add a local or specified stylesheet, with the given media options.
setPrintable()
Set the page as printable, i.e.
getResourceLoader()
Get a ResourceLoader object associated with this OutputPage.
feedLink( $type, $url, $text)
Generate a "<link rel/>" for a feed.
bool $mNoGallery
Comes from the parser.
getModuleStyles( $filter=false, $position=null)
Get the list of module CSS to include on this page.
enableClientCache( $state)
Use enableClientCache(false) to force it to send nocache headers.
userCanPreview()
To make it harder for someone to slip a user a fake user-JavaScript or user-CSS preview,...
setPageTitleActionText( $text)
Set the new value of the "action text", this will be added to the "HTML title", separated from it wit...
getFileSearchOptions()
Get the files used on this page.
setArticleRelated( $v)
Set whether this page is related an article on the wiki Setting false will cause the change of "artic...
addWikiTextTidy( $text, $linestart=true)
Add wikitext with tidy enabled.
addHTML( $text)
Append $text to the body HTML.
formatPermissionsErrorMessage(array $errors, $action=null)
Format a list of error messages.
addParserOutput( $parserOutput)
Add everything from a ParserOutput object.
string $mRevisionTimestamp
string null $copyrightUrl
The URL to send in a <link> element with rel=copyright.
addHelpLink( $to, $overrideBaseUrl=false)
Adds help link with an icon via page indicators.
getHTMLTitle()
Return the "HTML title", i.e.
disallowUserJs()
Do not allow scripts which can be modified by wiki users to load on this page; only allow scripts bun...
string $mHTMLtitle
Stores contents of "<title>" tag.
addJsConfigVars( $keys, $value=null)
Add one or more variables to be set in mw.config in JavaScript.
static transformCssMedia( $media)
Transform "media" attribute based on request parameters.
enableSectionEditLinks( $flag=true)
Enables/disables section edit links, doesn't override NOEDITSECTION
setCanonicalUrl( $url)
Set the URL to be used for the <link rel=canonical>>.
ParserOptions $mParserOptions
lazy initialised, use parserOptions()
addTemplate(&$template)
Add the output of a QuickTemplate to the output buffer.
getRlClient()
Call this to freeze the module queue and JS config and create a formatter.
static transformFilePath( $remotePathPrefix, $localPath, $file)
Utility method for transformResourceFilePath().
int $mCdnMaxageLimit
Upper limit on mCdnMaxage.
ResourceLoaderClientHtml $rlClient
setArticleBodyOnly( $only)
Set whether the output should only contain the body of the article, without any skin,...
showFileDeleteError( $name)
addInlineScript( $script)
Add a self-contained script tag with the given contents Internal use only.
addAcceptLanguage()
T23672: Add Accept-Language to Vary and Key headers if there's no 'variant' parameter existed in GET.
setStatusCode( $statusCode)
Set the HTTP status code to send with the output.
getCacheVaryCookies()
Get the list of cookies that will influence on the cache.
ResourceLoaderContext $rlClientContext
showErrorPage( $title, $msg, $params=[])
Output a standard error page.
getLinkTags()
Returns the current <link> tags.
getArticleBodyOnly()
Return whether the output will contain only the body of the article.
setProperty( $name, $value)
Set an additional output property.
setRevisionTimestamp( $timestamp)
Set the timestamp of the revision which will be displayed.
checkLastModified( $timestamp)
checkLastModified tells the client to use the client-cached page if possible.
getVaryHeader()
Return a Vary: header on which to vary caches.
string $mLastModified
Used for sending cache control.
showNewSectionLink()
Show an "add new section" link?
getExtStyle()
Get all styles added by extensions.
bool $mDoNothing
Whether output is disabled.
string $mPageLinkTitle
Used by skin template.
addHeadItem( $name, $value)
Add or replace a head item to the output.
getRevisionId()
Get the displayed revision ID.
setIndicators(array $indicators)
Add an array of indicators, with their identifiers as array keys and HTML contents as values.
bool $mEnableTOC
Whether parser output should contain table of contents.
Title $mRedirectedFrom
If the current page was reached through a redirect, $mRedirectedFrom contains the Title of the redire...
lowerCdnMaxage( $maxage)
Lower the value of the "s-maxage" part of the "Cache-control" HTTP header.
forceHideNewSectionLink()
Forcibly hide the new section link?
string null $mTarget
ResourceLoader target for load.php links.
int $mCdnMaxage
Cache stuff.
addBacklinkSubtitle(Title $title, $query=[])
Add a subtitle containing a backlink to a page.
enableTOC( $flag=true)
Enables/disables TOC, doesn't override NOTOC
getAllowedModules( $type)
Show what level of JavaScript / CSS untrustworthiness is allowed on this page.
addMetadataLink(array $linkarr)
Add a new <link> with "rel" attribute set to "meta".
parserOptions( $options=null)
Get/set the ParserOptions object to use for wikitext parsing.
prependHTML( $text)
Prepend $text to the body HTML.
addLanguageLinks(array $newLinkArray)
Add new language links.
array $mLanguageLinks
Array of Interwiki Prefixed (non DB key) Titles (e.g.
wrapWikiMsg( $wrap)
This function takes a number of message/argument specifications, wraps them in some overall structure...
string $mInlineStyles
Inline CSS styles.
addModules( $modules)
Add one or more modules recognized by ResourceLoader.
buildExemptModules()
Build exempt modules and legacy non-ResourceLoader styles.
getProperty( $name)
Get an additional output property.
headElement(Skin $sk, $includeStyle=true)
prepareErrorPage( $pageTitle, $htmlTitle=false)
Prepare this object to display an error page; disable caching and indexing, clear the current text an...
static buildBacklinkSubtitle(Title $title, $query=[])
Build message object for a subtitle containing a backlink to a page.
setFeedAppendQuery( $val)
Add default feeds to the page header This is mainly kept for backward compatibility,...
getBottomScripts()
JS stuff to put at the bottom of the <body>.
addReturnTo( $title, array $query=[], $text=null, $options=[])
Add a "return to" link pointing to a specified title.
addParserOutputMetadata( $parserOutput)
Add all metadata associated with a ParserOutput object, but without the actual HTML.
getMetaTags()
Returns the current <meta> tags.
bool $mArticleBodyOnly
Flag if output should only contain the body of the article.
setSubtitle( $str)
Replace the subtitle with $str.
array $rlExemptStyleModules
getKeyHeader()
Get a complete Key header.
getCategoryLinks()
Get the list of category links, in a 2-D array with the following format: $arr[$type][] = $link,...
getFrameOptions()
Get the X-Frame-Options header value (without the name part), or false if there isn't one.
addHeadItems( $values)
Add one or more head items to the output.
static combineWrappedStrings(array $chunks)
Combine WrappedString chunks and filter out empty ones.
bool $mIsArticleRelated
Stores "article flag" toggle.
parse( $text, $linestart=true, $interface=false, $language=null)
Parse wikitext and return the HTML.
getPageTitleActionText()
Get the value of the "action text".
hasHeadItem( $name)
Check if the header item $name is already set.
array $styles
An array of stylesheet filenames (relative from skins path), with options for CSS media,...
isDisabled()
Return whether the output will be completely disabled.
Set options of the Parser.
static newFromContext(IContextSource $context)
Get a ParserOptions object from a IContextSource object.
static newFromAnon()
Get a ParserOptions object for an anonymous user.
Show an error when the wiki is locked/read-only and the user tries to do something that requires writ...
Bootstrap a ResourceLoader client on an HTML page.
setModules(array $modules)
Ensure one or more modules are loaded.
setModuleScripts(array $modules)
Ensure the scripts of one or more modules are loaded.
setConfig(array $vars)
Set mw.config variables.
setExemptStates(array $states)
Set state of special modules that are handled by the caller manually.
static makeLoad(ResourceLoaderContext $mainContext, array $modules, $only, array $extraQuery=[])
Explicily load or embed modules on a page.
setModuleStyles(array $modules)
Ensure the styles of one or more modules are loaded.
Object passed around to modules which contains information about the state of a specific loader reque...
Abstraction for ResourceLoader modules, with name registration and maxage functionality.
const ORIGIN_USER_SITEWIDE
getOrigin()
Get this module's origin.
const ORIGIN_CORE_INDIVIDUAL
static preloadTitleInfo(ResourceLoaderContext $context, IDatabase $db, array $moduleNames)
Dynamic JavaScript and CSS resource loading system.
static inDebugMode()
Determine whether debug mode was requested Order of priority is 1) request param, 2) cookie,...
static makeInlineScript( $script)
Construct an inline script tag with given JS code.
static makeLoaderQuery( $modules, $lang, $skin, $user=null, $version=null, $debug=false, $only=null, $printable=false, $handheld=false, $extraQuery=[])
Build a query array (array representation of query string) for load.php.
The main skin class which provides methods and properties for all other skins.
getHtmlElementAttributes()
Return values for <html> element.
addToBodyAttributes( $out, &$bodyAttrs)
This will be called by OutputPage::headElement when it is creating the "<body>" tag,...
getPageClasses( $title)
TODO: document.
static resolveAlias( $alias)
Given a special page name with a possible subpage, return an array where the first element is the spe...
static getTitleFor( $name, $subpage=false, $fragment='')
Get a localised Title object for a specified special page name If you don't need a full Title object,...
Show an error when the user hits a rate limit.
Represents a title within MediaWiki.
A wrapper class which causes Xml::encodeJsVar() and Xml::encodeJsCall() to interpret a given string a...
static encodeJsCall( $name, $args, $pretty=false)
Create a call to a JavaScript function.
deferred txt A few of the database updates required by various functions here can be deferred until after the result page is displayed to the user For updating the view updating the linked to tables after a etc PHP does not yet have any way to tell the server to actually return and disconnect while still running these but it might have such a feature in the future We handle these by creating a deferred update object and putting those objects on a global list
this class mediates it Skin Encapsulates a look and feel for the wiki All of the functions that render HTML and make choices about how to render it are here and are called from various other places when and is meant to be subclassed with other skins that may override some of its functions The User object contains a reference to a and so rather than having a global skin object we just rely on the global User and get the skin with $wgUser and also has some character encoding functions and other locale stuff The current user interface language is instantiated as and the local content language as $wgContLang
when a variable name is used in a it is silently declared as a new local masking the global
design txt This is a brief overview of the new design More thorough and up to date information is available on the documentation wiki at etc Handles the details of getting and saving to the user table of the and dealing with sessions and cookies OutputPage Encapsulates the entire HTML page that will be sent in response to any server request It is used by calling its functions to add text
This document is intended to provide useful advice for parties seeking to redistribute MediaWiki to end users It s targeted particularly at maintainers for Linux since it s been observed that distribution packages of MediaWiki often break We ve consistently had to recommend that users seeking support use official tarballs instead of their distribution s and this often solves whatever problem the user is having It would be nice if this could such as
while(( $__line=Maintenance::readconsole()) !==false) print
the array() calling protocol came about after MediaWiki 1.4rc1.
static configuration should be added through ResourceLoaderGetConfigVars instead & $vars
please add to it if you re going to add events to the MediaWiki code where normally authentication against an external auth plugin would be creating a local account $user
this hook is for auditing only RecentChangesLinked and Watchlist RecentChangesLinked and Watchlist e g Watchlist removed from all revisions and log entries to which it was applied This gives extensions a chance to take it off their books as the deletion has already been partly carried out by this point or something similar the user will be unable to create the tag set and then return false from the hook function Ensure you consume the ChangeTagAfterDelete hook to carry out custom deletion actions as context $parserOutput
namespace are movable Hooks may change this value to override the return value of MWNamespace::isMovable(). 'NewDifferenceEngine' do that in ParserLimitReportFormat instead use this to modify the parameters of the image and a DIV can begin in one section and end in another Make sure your code can handle that case gracefully See the EditSectionClearerLink extension for an example zero but section is usually empty its values are the globals values before the output is cached one of or reset my talk my contributions etc etc otherwise the built in rate limiting checks are if enabled allows for interception of redirect as a string mapping parameter names to values & $type
This code would result in ircNotify being run twice when an article is and once for brion Hooks can return three possible true was required This is the default since MediaWiki *some string
this hook is for auditing only or null if authentication failed before getting that far or null if we can t even determine that probably a stub it is not rendered in wiki pages or galleries in category pages allow injecting custom HTML after the section Any uses of the hook need to handle escaping $template
namespace and then decline to actually register it file or subcat img or subcat $title
this hook is for auditing only RecentChangesLinked and Watchlist RecentChangesLinked and Watchlist e g Watchlist removed from all revisions and log entries to which it was applied This gives extensions a chance to take it off their books as the deletion has already been partly carried out by this point or something similar the user will be unable to create the tag set and then return false from the hook function Ensure you consume the ChangeTagAfterDelete hook to carry out custom deletion actions as context called by AbstractContent::getParserOutput May be used to override the normal model specific rendering of page content as context as context $options
either a unescaped string or a HtmlArmor object after in associative array form externallinks including delete and has completed for all link tables whether this was an auto creation default is conds Array Extra conditions for the No matching items in log is displayed if loglist is empty msgKey Array If you want a nice box with a set this to the key of the message First element is the message additional optional elements are parameters for the key that are processed with wfMessage() -> params() ->parseAsBlock() - offset Set to overwrite offset parameter in $wgRequest set to '' to unset offset - wrap String Wrap the message in html(usually something like "<div ...>$1</div>"). - flags Integer display flags(NO_ACTION_LINK, NO_EXTRA_USER_LINKS) 'LogException':Called before an exception(or PHP error) is logged. This is meant for integration with external error aggregation services
error also a ContextSource you ll probably need to make sure the header is varied on $request
this hook is for auditing only RecentChangesLinked and Watchlist RecentChangesLinked and Watchlist e g Watchlist removed from all revisions and log entries to which it was applied This gives extensions a chance to take it off their books $tag
usually copyright or history_copyright This message must be in HTML not wikitext & $link
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped noclasses just before the function returns a value If you return an< a > element with HTML attributes $attribs and contents $html will be returned If you return $ret will be returned and may include noclasses after processing & $attribs
this hook is for auditing only $response
error also a ContextSource you ll probably need to make sure the header is varied on such as when responding to a resource loader request or generating HTML output & $resourceLoader
Allows to change the fields on the form that will be generated $name
null for the local wiki Added should default to null in handler for backwards compatibility add a value to it if you want to add a cookie that have to vary cache options can modify $query
passed in as a query string parameter to the various URLs constructed here(i.e. $prevlink) $ldel you ll need to handle error messages
returning false will NOT prevent logging $e
this hook is for auditing only or null if authentication failed before getting that far or null if we can t even determine that probably a stub it is not rendered in wiki pages or galleries in category pages allow injecting custom HTML after the section Any uses of the hook need to handle escaping see BaseTemplate::getToolbox and BaseTemplate::makeListItem for details on the format of individual items inside of this array or by returning and letting standard HTTP rendering take place modifiable or by returning false and taking over the output modifiable & $code
if(count( $args)==0) $dir
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency which acts as the top level factory for services in MediaWiki which can be used to gain access to default instances of various services MediaWikiServices however also allows new services to be defined and default services to be redefined Services are defined or redefined by providing a callback the instantiator that will return a new instance of the service When it will create an instance of MediaWikiServices and populate it with the services defined in the files listed by thereby bootstrapping the DI framework Per $wgServiceWiringFiles lists includes ServiceWiring php
Interface for configuration instances.
get( $name)
Get a configuration variable such as "Sitename" or "UploadMaintenance.".
Interface for objects which can provide a MediaWiki context on request.
if(!isset( $args[0])) $lang
const TS_ISO_8601
ISO 8601 format with no timezone: 1986-02-09T20:00:00Z.
const TS_UNIX
Unix time - the number of seconds since 1970-01-01 00:00:00 UTC.
const TS_MW
MediaWiki concatenated string timestamp (YYYYMMDDHHMMSS)
const TS_RFC2822
RFC 2822 format, for E-mail and HTTP headers.