MediaWiki  REL1_34
OutputPage.php
Go to the documentation of this file.
1 <?php
27 use Wikimedia\RelPath;
28 use Wikimedia\WrappedString;
29 use Wikimedia\WrappedStringList;
30 
46 class OutputPage extends ContextSource {
48  protected $mMetatags = [];
49 
51  protected $mLinktags = [];
52 
54  protected $mCanonicalUrl = false;
55 
59  private $mPageTitle = '';
60 
68  private $displayTitle;
69 
74  public $mBodytext = '';
75 
77  private $mHTMLtitle = '';
78 
83  private $mIsArticle = false;
84 
86  private $mIsArticleRelated = true;
87 
89  private $mHasCopyright = false;
90 
95  private $mPrintable = false;
96 
101  private $mSubtitle = [];
102 
104  public $mRedirect = '';
105 
107  protected $mStatusCode;
108 
113  protected $mLastModified = '';
114 
116  protected $mCategoryLinks = [];
117 
119  protected $mCategories = [
120  'hidden' => [],
121  'normal' => [],
122  ];
123 
125  protected $mIndicators = [];
126 
128  private $mLanguageLinks = [];
129 
136  private $mScripts = '';
137 
139  protected $mInlineStyles = '';
140 
145  public $mPageLinkTitle = '';
146 
148  protected $mHeadItems = [];
149 
151  protected $mAdditionalBodyClasses = [];
152 
154  protected $mModules = [];
155 
157  protected $mModuleStyles = [];
158 
160  protected $mResourceLoader;
161 
163  private $rlClient;
164 
167 
170 
172  protected $mJsConfigVars = [];
173 
175  protected $mTemplateIds = [];
176 
178  protected $mImageTimeKeys = [];
179 
181  public $mRedirectCode = '';
182 
183  protected $mFeedLinksAppendQuery = null;
184 
190  protected $mAllowedModules = [
191  ResourceLoaderModule::TYPE_COMBINED => ResourceLoaderModule::ORIGIN_ALL,
192  ];
193 
195  protected $mDoNothing = false;
196 
197  // Parser related.
198 
200  protected $mContainsNewMagic = 0;
201 
206  protected $mParserOptions = null;
207 
213  private $mFeedLinks = [];
214 
215  // Gwicke work on squid caching? Roughly from 2003.
216  protected $mEnableClientCache = true;
217 
219  private $mArticleBodyOnly = false;
220 
222  protected $mNewSectionLink = false;
223 
225  protected $mHideNewSectionLink = false;
226 
232  public $mNoGallery = false;
233 
235  protected $mCdnMaxage = 0;
237  protected $mCdnMaxageLimit = INF;
238 
244  protected $mPreventClickjacking = true;
245 
247  private $mRevisionId = null;
248 
250  private $mRevisionTimestamp = null;
251 
253  protected $mFileVersion = null;
254 
263  protected $styles = [];
264 
265  private $mIndexPolicy = 'index';
266  private $mFollowPolicy = 'follow';
267 
273  private $mVaryHeader = [
274  'Accept-Encoding' => null,
275  ];
276 
283  private $mRedirectedFrom = null;
284 
288  private $mProperties = [];
289 
293  private $mTarget = null;
294 
298  private $mEnableTOC = false;
299 
303  private $copyrightUrl;
304 
306  private $limitReportJSData = [];
307 
309  private $contentOverrides = [];
310 
313 
317  private $mLinkHeader = [];
318 
322  private $CSPNonce;
323 
327  private static $cacheVaryCookies = null;
328 
335  public function __construct( IContextSource $context ) {
336  $this->setContext( $context );
337  }
338 
345  public function redirect( $url, $responsecode = '302' ) {
346  # Strip newlines as a paranoia check for header injection in PHP<5.1.2
347  $this->mRedirect = str_replace( "\n", '', $url );
348  $this->mRedirectCode = $responsecode;
349  }
350 
356  public function getRedirect() {
357  return $this->mRedirect;
358  }
359 
368  public function setCopyrightUrl( $url ) {
369  $this->copyrightUrl = $url;
370  }
371 
377  public function setStatusCode( $statusCode ) {
378  $this->mStatusCode = $statusCode;
379  }
380 
388  public function addMeta( $name, $val ) {
389  $this->mMetatags[] = [ $name, $val ];
390  }
391 
398  public function getMetaTags() {
399  return $this->mMetatags;
400  }
401 
409  public function addLink( array $linkarr ) {
410  $this->mLinktags[] = $linkarr;
411  }
412 
419  public function getLinkTags() {
420  return $this->mLinktags;
421  }
422 
428  public function setCanonicalUrl( $url ) {
429  $this->mCanonicalUrl = $url;
430  }
431 
439  public function getCanonicalUrl() {
440  return $this->mCanonicalUrl;
441  }
442 
450  public function addScript( $script ) {
451  $this->mScripts .= $script;
452  }
453 
462  public function addScriptFile( $file, $unused = null ) {
463  $this->addScript( Html::linkedScript( $file, $this->getCSPNonce() ) );
464  }
465 
472  public function addInlineScript( $script ) {
473  $this->mScripts .= Html::inlineScript( "\n$script\n", $this->getCSPNonce() ) . "\n";
474  }
475 
484  protected function filterModules( array $modules, $position = null,
485  $type = ResourceLoaderModule::TYPE_COMBINED
486  ) {
488  $filteredModules = [];
489  foreach ( $modules as $val ) {
490  $module = $resourceLoader->getModule( $val );
491  if ( $module instanceof ResourceLoaderModule
492  && $module->getOrigin() <= $this->getAllowedModules( $type )
493  ) {
494  if ( $this->mTarget && !in_array( $this->mTarget, $module->getTargets() ) ) {
495  $this->warnModuleTargetFilter( $module->getName() );
496  continue;
497  }
498  $filteredModules[] = $val;
499  }
500  }
501  return $filteredModules;
502  }
503 
504  private function warnModuleTargetFilter( $moduleName ) {
505  static $warnings = [];
506  if ( isset( $warnings[$this->mTarget][$moduleName] ) ) {
507  return;
508  }
509  $warnings[$this->mTarget][$moduleName] = true;
510  $this->getResourceLoader()->getLogger()->debug(
511  'Module "{module}" not loadable on target "{target}".',
512  [
513  'module' => $moduleName,
514  'target' => $this->mTarget,
515  ]
516  );
517  }
518 
528  public function getModules( $filter = false, $position = null, $param = 'mModules',
529  $type = ResourceLoaderModule::TYPE_COMBINED
530  ) {
531  $modules = array_values( array_unique( $this->$param ) );
532  return $filter
533  ? $this->filterModules( $modules, null, $type )
534  : $modules;
535  }
536 
542  public function addModules( $modules ) {
543  $this->mModules = array_merge( $this->mModules, (array)$modules );
544  }
545 
553  public function getModuleStyles( $filter = false, $position = null ) {
554  return $this->getModules( $filter, null, 'mModuleStyles',
555  ResourceLoaderModule::TYPE_STYLES
556  );
557  }
558 
568  public function addModuleStyles( $modules ) {
569  $this->mModuleStyles = array_merge( $this->mModuleStyles, (array)$modules );
570  }
571 
575  public function getTarget() {
576  return $this->mTarget;
577  }
578 
584  public function setTarget( $target ) {
585  $this->mTarget = $target;
586  }
587 
595  public function addContentOverride( LinkTarget $target, Content $content ) {
596  if ( !$this->contentOverrides ) {
597  // Register a callback for $this->contentOverrides on the first call
598  $this->addContentOverrideCallback( function ( LinkTarget $target ) {
599  $key = $target->getNamespace() . ':' . $target->getDBkey();
600  return $this->contentOverrides[$key] ?? null;
601  } );
602  }
603 
604  $key = $target->getNamespace() . ':' . $target->getDBkey();
605  $this->contentOverrides[$key] = $content;
606  }
607 
615  public function addContentOverrideCallback( callable $callback ) {
616  $this->contentOverrideCallbacks[] = $callback;
617  }
618 
624  public function getHeadItemsArray() {
625  return $this->mHeadItems;
626  }
627 
640  public function addHeadItem( $name, $value ) {
641  $this->mHeadItems[$name] = $value;
642  }
643 
650  public function addHeadItems( $values ) {
651  $this->mHeadItems = array_merge( $this->mHeadItems, (array)$values );
652  }
653 
660  public function hasHeadItem( $name ) {
661  return isset( $this->mHeadItems[$name] );
662  }
663 
670  public function addBodyClasses( $classes ) {
671  $this->mAdditionalBodyClasses = array_merge( $this->mAdditionalBodyClasses, (array)$classes );
672  }
673 
681  public function setArticleBodyOnly( $only ) {
682  $this->mArticleBodyOnly = $only;
683  }
684 
690  public function getArticleBodyOnly() {
692  }
693 
701  public function setProperty( $name, $value ) {
702  $this->mProperties[$name] = $value;
703  }
704 
712  public function getProperty( $name ) {
713  return $this->mProperties[$name] ?? null;
714  }
715 
727  public function checkLastModified( $timestamp ) {
728  if ( !$timestamp || $timestamp == '19700101000000' ) {
729  wfDebug( __METHOD__ . ": CACHE DISABLED, NO TIMESTAMP\n" );
730  return false;
731  }
732  $config = $this->getConfig();
733  if ( !$config->get( 'CachePages' ) ) {
734  wfDebug( __METHOD__ . ": CACHE DISABLED\n" );
735  return false;
736  }
737 
738  $timestamp = wfTimestamp( TS_MW, $timestamp );
739  $modifiedTimes = [
740  'page' => $timestamp,
741  'user' => $this->getUser()->getTouched(),
742  'epoch' => $config->get( 'CacheEpoch' )
743  ];
744  if ( $config->get( 'UseCdn' ) ) {
745  $modifiedTimes['sepoch'] = wfTimestamp( TS_MW, $this->getCdnCacheEpoch(
746  time(),
747  $config->get( 'CdnMaxAge' )
748  ) );
749  }
750  Hooks::run( 'OutputPageCheckLastModified', [ &$modifiedTimes, $this ] );
751 
752  $maxModified = max( $modifiedTimes );
753  $this->mLastModified = wfTimestamp( TS_RFC2822, $maxModified );
754 
755  $clientHeader = $this->getRequest()->getHeader( 'If-Modified-Since' );
756  if ( $clientHeader === false ) {
757  wfDebug( __METHOD__ . ": client did not send If-Modified-Since header", 'private' );
758  return false;
759  }
760 
761  # IE sends sizes after the date like this:
762  # Wed, 20 Aug 2003 06:51:19 GMT; length=5202
763  # this breaks strtotime().
764  $clientHeader = preg_replace( '/;.*$/', '', $clientHeader );
765 
766  Wikimedia\suppressWarnings(); // E_STRICT system time warnings
767  $clientHeaderTime = strtotime( $clientHeader );
768  Wikimedia\restoreWarnings();
769  if ( !$clientHeaderTime ) {
770  wfDebug( __METHOD__
771  . ": unable to parse the client's If-Modified-Since header: $clientHeader\n" );
772  return false;
773  }
774  $clientHeaderTime = wfTimestamp( TS_MW, $clientHeaderTime );
775 
776  # Make debug info
777  $info = '';
778  foreach ( $modifiedTimes as $name => $value ) {
779  if ( $info !== '' ) {
780  $info .= ', ';
781  }
782  $info .= "$name=" . wfTimestamp( TS_ISO_8601, $value );
783  }
784 
785  wfDebug( __METHOD__ . ": client sent If-Modified-Since: " .
786  wfTimestamp( TS_ISO_8601, $clientHeaderTime ), 'private' );
787  wfDebug( __METHOD__ . ": effective Last-Modified: " .
788  wfTimestamp( TS_ISO_8601, $maxModified ), 'private' );
789  if ( $clientHeaderTime < $maxModified ) {
790  wfDebug( __METHOD__ . ": STALE, $info", 'private' );
791  return false;
792  }
793 
794  # Not modified
795  # Give a 304 Not Modified response code and disable body output
796  wfDebug( __METHOD__ . ": NOT MODIFIED, $info", 'private' );
797  ini_set( 'zlib.output_compression', 0 );
798  $this->getRequest()->response()->statusHeader( 304 );
799  $this->sendCacheControl();
800  $this->disable();
801 
802  // Don't output a compressed blob when using ob_gzhandler;
803  // it's technically against HTTP spec and seems to confuse
804  // Firefox when the response gets split over two packets.
806 
807  return true;
808  }
809 
815  private function getCdnCacheEpoch( $reqTime, $maxAge ) {
816  // Ensure Last-Modified is never more than $wgCdnMaxAge in the past,
817  // because even if the wiki page content hasn't changed since, static
818  // resources may have changed (skin HTML, interface messages, urls, etc.)
819  // and must roll-over in a timely manner (T46570)
820  return $reqTime - $maxAge;
821  }
822 
829  public function setLastModified( $timestamp ) {
830  $this->mLastModified = wfTimestamp( TS_RFC2822, $timestamp );
831  }
832 
841  public function setRobotPolicy( $policy ) {
842  $policy = Article::formatRobotPolicy( $policy );
843 
844  if ( isset( $policy['index'] ) ) {
845  $this->setIndexPolicy( $policy['index'] );
846  }
847  if ( isset( $policy['follow'] ) ) {
848  $this->setFollowPolicy( $policy['follow'] );
849  }
850  }
851 
859  public function setIndexPolicy( $policy ) {
860  $policy = trim( $policy );
861  if ( in_array( $policy, [ 'index', 'noindex' ] ) ) {
862  $this->mIndexPolicy = $policy;
863  }
864  }
865 
873  public function setFollowPolicy( $policy ) {
874  $policy = trim( $policy );
875  if ( in_array( $policy, [ 'follow', 'nofollow' ] ) ) {
876  $this->mFollowPolicy = $policy;
877  }
878  }
879 
886  public function setHTMLTitle( $name ) {
887  if ( $name instanceof Message ) {
888  $this->mHTMLtitle = $name->setContext( $this->getContext() )->text();
889  } else {
890  $this->mHTMLtitle = $name;
891  }
892  }
893 
899  public function getHTMLTitle() {
900  return $this->mHTMLtitle;
901  }
902 
908  public function setRedirectedFrom( $t ) {
909  $this->mRedirectedFrom = $t;
910  }
911 
924  public function setPageTitle( $name ) {
925  if ( $name instanceof Message ) {
926  $name = $name->setContext( $this->getContext() )->text();
927  }
928 
929  # change "<script>foo&bar</script>" to "&lt;script&gt;foo&amp;bar&lt;/script&gt;"
930  # but leave "<i>foobar</i>" alone
932  $this->mPageTitle = $nameWithTags;
933 
934  # change "<i>foo&amp;bar</i>" to "foo&bar"
935  $this->setHTMLTitle(
936  $this->msg( 'pagetitle' )->plaintextParams( Sanitizer::stripAllTags( $nameWithTags ) )
937  ->inContentLanguage()
938  );
939  }
940 
946  public function getPageTitle() {
947  return $this->mPageTitle;
948  }
949 
957  public function setDisplayTitle( $html ) {
958  $this->displayTitle = $html;
959  }
960 
969  public function getDisplayTitle() {
970  $html = $this->displayTitle;
971  if ( $html === null ) {
972  $html = $this->getTitle()->getPrefixedText();
973  }
974 
976  }
977 
984  public function getUnprefixedDisplayTitle() {
985  $text = $this->getDisplayTitle();
986  $nsPrefix = $this->getTitle()->getNsText() . ':';
987  $prefix = preg_quote( $nsPrefix, '/' );
988 
989  return preg_replace( "/^$prefix/i", '', $text );
990  }
991 
997  public function setTitle( Title $t ) {
998  // @phan-suppress-next-next-line PhanUndeclaredMethod
999  // @fixme Not all implementations of IContextSource have this method!
1000  $this->getContext()->setTitle( $t );
1001  }
1002 
1008  public function setSubtitle( $str ) {
1009  $this->clearSubtitle();
1010  $this->addSubtitle( $str );
1011  }
1012 
1018  public function addSubtitle( $str ) {
1019  if ( $str instanceof Message ) {
1020  $this->mSubtitle[] = $str->setContext( $this->getContext() )->parse();
1021  } else {
1022  $this->mSubtitle[] = $str;
1023  }
1024  }
1025 
1034  public static function buildBacklinkSubtitle( Title $title, $query = [] ) {
1035  if ( $title->isRedirect() ) {
1036  $query['redirect'] = 'no';
1037  }
1038  $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
1039  return wfMessage( 'backlinksubtitle' )
1040  ->rawParams( $linkRenderer->makeLink( $title, null, [], $query ) );
1041  }
1042 
1049  public function addBacklinkSubtitle( Title $title, $query = [] ) {
1050  $this->addSubtitle( self::buildBacklinkSubtitle( $title, $query ) );
1051  }
1052 
1056  public function clearSubtitle() {
1057  $this->mSubtitle = [];
1058  }
1059 
1065  public function getSubtitle() {
1066  return implode( "<br />\n\t\t\t\t", $this->mSubtitle );
1067  }
1068 
1073  public function setPrintable() {
1074  $this->mPrintable = true;
1075  }
1076 
1082  public function isPrintable() {
1083  return $this->mPrintable;
1084  }
1085 
1089  public function disable() {
1090  $this->mDoNothing = true;
1091  }
1092 
1098  public function isDisabled() {
1099  return $this->mDoNothing;
1100  }
1101 
1107  public function showNewSectionLink() {
1108  return $this->mNewSectionLink;
1109  }
1110 
1116  public function forceHideNewSectionLink() {
1118  }
1119 
1128  public function setSyndicated( $show = true ) {
1129  if ( $show ) {
1130  $this->setFeedAppendQuery( false );
1131  } else {
1132  $this->mFeedLinks = [];
1133  }
1134  }
1135 
1142  protected function getAdvertisedFeedTypes() {
1143  if ( $this->getConfig()->get( 'Feed' ) ) {
1144  return $this->getConfig()->get( 'AdvertisedFeedTypes' );
1145  } else {
1146  return [];
1147  }
1148  }
1149 
1159  public function setFeedAppendQuery( $val ) {
1160  $this->mFeedLinks = [];
1161 
1162  foreach ( $this->getAdvertisedFeedTypes() as $type ) {
1163  $query = "feed=$type";
1164  if ( is_string( $val ) ) {
1165  $query .= '&' . $val;
1166  }
1167  $this->mFeedLinks[$type] = $this->getTitle()->getLocalURL( $query );
1168  }
1169  }
1170 
1177  public function addFeedLink( $format, $href ) {
1178  if ( in_array( $format, $this->getAdvertisedFeedTypes() ) ) {
1179  $this->mFeedLinks[$format] = $href;
1180  }
1181  }
1182 
1187  public function isSyndicated() {
1188  return count( $this->mFeedLinks ) > 0;
1189  }
1190 
1195  public function getSyndicationLinks() {
1196  return $this->mFeedLinks;
1197  }
1198 
1204  public function getFeedAppendQuery() {
1206  }
1207 
1215  public function setArticleFlag( $newVal ) {
1216  $this->mIsArticle = $newVal;
1217  if ( $newVal ) {
1218  $this->mIsArticleRelated = $newVal;
1219  }
1220  }
1221 
1228  public function isArticle() {
1229  return $this->mIsArticle;
1230  }
1231 
1238  public function setArticleRelated( $newVal ) {
1239  $this->mIsArticleRelated = $newVal;
1240  if ( !$newVal ) {
1241  $this->mIsArticle = false;
1242  }
1243  }
1244 
1250  public function isArticleRelated() {
1251  return $this->mIsArticleRelated;
1252  }
1253 
1259  public function setCopyright( $hasCopyright ) {
1260  $this->mHasCopyright = $hasCopyright;
1261  }
1262 
1272  public function showsCopyright() {
1273  return $this->isArticle() || $this->mHasCopyright;
1274  }
1275 
1282  public function addLanguageLinks( array $newLinkArray ) {
1283  $this->mLanguageLinks = array_merge( $this->mLanguageLinks, $newLinkArray );
1284  }
1285 
1292  public function setLanguageLinks( array $newLinkArray ) {
1293  $this->mLanguageLinks = $newLinkArray;
1294  }
1295 
1301  public function getLanguageLinks() {
1302  return $this->mLanguageLinks;
1303  }
1304 
1310  public function addCategoryLinks( array $categories ) {
1311  if ( !$categories ) {
1312  return;
1313  }
1314 
1315  $res = $this->addCategoryLinksToLBAndGetResult( $categories );
1316 
1317  # Set all the values to 'normal'.
1318  $categories = array_fill_keys( array_keys( $categories ), 'normal' );
1319 
1320  # Mark hidden categories
1321  foreach ( $res as $row ) {
1322  if ( isset( $row->pp_value ) ) {
1323  $categories[$row->page_title] = 'hidden';
1324  }
1325  }
1326 
1327  // Avoid PHP 7.1 warning of passing $this by reference
1328  $outputPage = $this;
1329  # Add the remaining categories to the skin
1330  if ( Hooks::run(
1331  'OutputPageMakeCategoryLinks',
1332  [ &$outputPage, $categories, &$this->mCategoryLinks ] )
1333  ) {
1334  $services = MediaWikiServices::getInstance();
1335  $linkRenderer = $services->getLinkRenderer();
1336  foreach ( $categories as $category => $type ) {
1337  // array keys will cast numeric category names to ints, so cast back to string
1338  $category = (string)$category;
1339  $origcategory = $category;
1340  $title = Title::makeTitleSafe( NS_CATEGORY, $category );
1341  if ( !$title ) {
1342  continue;
1343  }
1344  $services->getContentLanguage()->findVariantLink( $category, $title, true );
1345  if ( $category != $origcategory && array_key_exists( $category, $categories ) ) {
1346  continue;
1347  }
1348  $text = $services->getContentLanguage()->convertHtml( $title->getText() );
1349  $this->mCategories[$type][] = $title->getText();
1350  $this->mCategoryLinks[$type][] = $linkRenderer->makeLink( $title, new HtmlArmor( $text ) );
1351  }
1352  }
1353  }
1354 
1359  protected function addCategoryLinksToLBAndGetResult( array $categories ) {
1360  # Add the links to a LinkBatch
1361  $arr = [ NS_CATEGORY => $categories ];
1362  $lb = new LinkBatch;
1363  $lb->setArray( $arr );
1364 
1365  # Fetch existence plus the hiddencat property
1366  $dbr = wfGetDB( DB_REPLICA );
1367  $fields = array_merge(
1369  [ 'page_namespace', 'page_title', 'pp_value' ]
1370  );
1371 
1372  $res = $dbr->select( [ 'page', 'page_props' ],
1373  $fields,
1374  $lb->constructSet( 'page', $dbr ),
1375  __METHOD__,
1376  [],
1377  [ 'page_props' => [ 'LEFT JOIN', [
1378  'pp_propname' => 'hiddencat',
1379  'pp_page = page_id'
1380  ] ] ]
1381  );
1382 
1383  # Add the results to the link cache
1384  $linkCache = MediaWikiServices::getInstance()->getLinkCache();
1385  $lb->addResultToCache( $linkCache, $res );
1386 
1387  return $res;
1388  }
1389 
1395  public function setCategoryLinks( array $categories ) {
1396  $this->mCategoryLinks = [];
1397  $this->addCategoryLinks( $categories );
1398  }
1399 
1408  public function getCategoryLinks() {
1409  return $this->mCategoryLinks;
1410  }
1411 
1421  public function getCategories( $type = 'all' ) {
1422  if ( $type === 'all' ) {
1423  $allCategories = [];
1424  foreach ( $this->mCategories as $categories ) {
1425  $allCategories = array_merge( $allCategories, $categories );
1426  }
1427  return $allCategories;
1428  }
1429  if ( !isset( $this->mCategories[$type] ) ) {
1430  throw new InvalidArgumentException( 'Invalid category type given: ' . $type );
1431  }
1432  return $this->mCategories[$type];
1433  }
1434 
1444  public function setIndicators( array $indicators ) {
1445  $this->mIndicators = $indicators + $this->mIndicators;
1446  // Keep ordered by key
1447  ksort( $this->mIndicators );
1448  }
1449 
1458  public function getIndicators() {
1459  return $this->mIndicators;
1460  }
1461 
1470  public function addHelpLink( $to, $overrideBaseUrl = false ) {
1471  $this->addModuleStyles( 'mediawiki.helplink' );
1472  $text = $this->msg( 'helppage-top-gethelp' )->escaped();
1473 
1474  if ( $overrideBaseUrl ) {
1475  $helpUrl = $to;
1476  } else {
1477  $toUrlencoded = wfUrlencode( str_replace( ' ', '_', $to ) );
1478  $helpUrl = "https://www.mediawiki.org/wiki/Special:MyLanguage/$toUrlencoded";
1479  }
1480 
1481  $link = Html::rawElement(
1482  'a',
1483  [
1484  'href' => $helpUrl,
1485  'target' => '_blank',
1486  'class' => 'mw-helplink',
1487  ],
1488  $text
1489  );
1490 
1491  $this->setIndicators( [ 'mw-helplink' => $link ] );
1492  }
1493 
1502  public function disallowUserJs() {
1503  $this->reduceAllowedModules(
1504  ResourceLoaderModule::TYPE_SCRIPTS,
1505  ResourceLoaderModule::ORIGIN_CORE_INDIVIDUAL
1506  );
1507 
1508  // Site-wide styles are controlled by a config setting, see T73621
1509  // for background on why. User styles are never allowed.
1510  if ( $this->getConfig()->get( 'AllowSiteCSSOnRestrictedPages' ) ) {
1511  $styleOrigin = ResourceLoaderModule::ORIGIN_USER_SITEWIDE;
1512  } else {
1513  $styleOrigin = ResourceLoaderModule::ORIGIN_CORE_INDIVIDUAL;
1514  }
1515  $this->reduceAllowedModules(
1516  ResourceLoaderModule::TYPE_STYLES,
1517  $styleOrigin
1518  );
1519  }
1520 
1527  public function getAllowedModules( $type ) {
1528  if ( $type == ResourceLoaderModule::TYPE_COMBINED ) {
1529  return min( array_values( $this->mAllowedModules ) );
1530  } else {
1531  return $this->mAllowedModules[$type] ?? ResourceLoaderModule::ORIGIN_ALL;
1532  }
1533  }
1534 
1544  public function reduceAllowedModules( $type, $level ) {
1545  $this->mAllowedModules[$type] = min( $this->getAllowedModules( $type ), $level );
1546  }
1547 
1553  public function prependHTML( $text ) {
1554  $this->mBodytext = $text . $this->mBodytext;
1555  }
1556 
1562  public function addHTML( $text ) {
1563  $this->mBodytext .= $text;
1564  }
1565 
1575  public function addElement( $element, array $attribs = [], $contents = '' ) {
1576  $this->addHTML( Html::element( $element, $attribs, $contents ) );
1577  }
1578 
1582  public function clearHTML() {
1583  $this->mBodytext = '';
1584  }
1585 
1591  public function getHTML() {
1592  return $this->mBodytext;
1593  }
1594 
1603  public function parserOptions( $options = null ) {
1604  if ( $options !== null ) {
1605  wfDeprecated( __METHOD__ . ' with non-null $options', '1.31' );
1606  }
1607 
1608  if ( $options !== null && !empty( $options->isBogus ) ) {
1609  // Someone is trying to set a bogus pre-$wgUser PO. Check if it has
1610  // been changed somehow, and keep it if so.
1611  $anonPO = ParserOptions::newFromAnon();
1612  $anonPO->setAllowUnsafeRawHtml( false );
1613  if ( !$options->matches( $anonPO ) ) {
1614  wfLogWarning( __METHOD__ . ': Setting a changed bogus ParserOptions: ' . wfGetAllCallers( 5 ) );
1615  $options->isBogus = false;
1616  }
1617  }
1618 
1619  if ( !$this->mParserOptions ) {
1620  if ( !$this->getUser()->isSafeToLoad() ) {
1621  // $wgUser isn't unstubbable yet, so don't try to get a
1622  // ParserOptions for it. And don't cache this ParserOptions
1623  // either.
1625  $po->setAllowUnsafeRawHtml( false );
1626  $po->isBogus = true;
1627  if ( $options !== null ) {
1628  $this->mParserOptions = empty( $options->isBogus ) ? $options : null;
1629  }
1630  return $po;
1631  }
1632 
1633  $this->mParserOptions = ParserOptions::newFromContext( $this->getContext() );
1634  $this->mParserOptions->setAllowUnsafeRawHtml( false );
1635  }
1636 
1637  if ( $options !== null && !empty( $options->isBogus ) ) {
1638  // They're trying to restore the bogus pre-$wgUser PO. Do the right
1639  // thing.
1640  return wfSetVar( $this->mParserOptions, null, true );
1641  } else {
1642  return wfSetVar( $this->mParserOptions, $options );
1643  }
1644  }
1645 
1653  public function setRevisionId( $revid ) {
1654  $val = is_null( $revid ) ? null : intval( $revid );
1655  return wfSetVar( $this->mRevisionId, $val, true );
1656  }
1657 
1663  public function getRevisionId() {
1664  return $this->mRevisionId;
1665  }
1666 
1673  public function isRevisionCurrent() {
1674  return $this->mRevisionId == 0 || $this->mRevisionId == $this->getTitle()->getLatestRevID();
1675  }
1676 
1684  public function setRevisionTimestamp( $timestamp ) {
1685  return wfSetVar( $this->mRevisionTimestamp, $timestamp, true );
1686  }
1687 
1694  public function getRevisionTimestamp() {
1696  }
1697 
1704  public function setFileVersion( $file ) {
1705  $val = null;
1706  if ( $file instanceof File && $file->exists() ) {
1707  $val = [ 'time' => $file->getTimestamp(), 'sha1' => $file->getSha1() ];
1708  }
1709  return wfSetVar( $this->mFileVersion, $val, true );
1710  }
1711 
1717  public function getFileVersion() {
1718  return $this->mFileVersion;
1719  }
1720 
1727  public function getTemplateIds() {
1728  return $this->mTemplateIds;
1729  }
1730 
1737  public function getFileSearchOptions() {
1738  return $this->mImageTimeKeys;
1739  }
1740 
1757  public function addWikiTextAsInterface(
1758  $text, $linestart = true, Title $title = null
1759  ) {
1760  if ( $title === null ) {
1761  $title = $this->getTitle();
1762  }
1763  if ( !$title ) {
1764  throw new MWException( 'Title is null' );
1765  }
1766  $this->addWikiTextTitleInternal( $text, $title, $linestart, /*interface*/true );
1767  }
1768 
1782  public function wrapWikiTextAsInterface(
1783  $wrapperClass, $text
1784  ) {
1785  $this->addWikiTextTitleInternal(
1786  $text, $this->getTitle(),
1787  /*linestart*/true, /*interface*/true,
1788  $wrapperClass
1789  );
1790  }
1791 
1807  public function addWikiTextAsContent(
1808  $text, $linestart = true, Title $title = null
1809  ) {
1810  if ( $title === null ) {
1811  $title = $this->getTitle();
1812  }
1813  if ( !$title ) {
1814  throw new MWException( 'Title is null' );
1815  }
1816  $this->addWikiTextTitleInternal( $text, $title, $linestart, /*interface*/false );
1817  }
1818 
1831  private function addWikiTextTitleInternal(
1832  $text, Title $title, $linestart, $interface, $wrapperClass = null
1833  ) {
1834  $parserOutput = $this->parseInternal(
1835  $text, $title, $linestart, true, $interface, /*language*/null
1836  );
1837 
1838  $this->addParserOutput( $parserOutput, [
1839  'enableSectionEditLinks' => false,
1840  'wrapperDivClass' => $wrapperClass ?? '',
1841  ] );
1842  }
1843 
1852  public function addParserOutputMetadata( ParserOutput $parserOutput ) {
1853  $this->mLanguageLinks =
1854  array_merge( $this->mLanguageLinks, $parserOutput->getLanguageLinks() );
1855  $this->addCategoryLinks( $parserOutput->getCategories() );
1856  $this->setIndicators( $parserOutput->getIndicators() );
1857  $this->mNewSectionLink = $parserOutput->getNewSection();
1858  $this->mHideNewSectionLink = $parserOutput->getHideNewSection();
1859 
1860  if ( !$parserOutput->isCacheable() ) {
1861  $this->enableClientCache( false );
1862  }
1863  $this->mNoGallery = $parserOutput->getNoGallery();
1864  $this->mHeadItems = array_merge( $this->mHeadItems, $parserOutput->getHeadItems() );
1865  $this->addModules( $parserOutput->getModules() );
1866  $this->addModuleStyles( $parserOutput->getModuleStyles() );
1867  $this->addJsConfigVars( $parserOutput->getJsConfigVars() );
1868  $this->mPreventClickjacking = $this->mPreventClickjacking
1869  || $parserOutput->preventClickjacking();
1870 
1871  // Template versioning...
1872  foreach ( (array)$parserOutput->getTemplateIds() as $ns => $dbks ) {
1873  if ( isset( $this->mTemplateIds[$ns] ) ) {
1874  $this->mTemplateIds[$ns] = $dbks + $this->mTemplateIds[$ns];
1875  } else {
1876  $this->mTemplateIds[$ns] = $dbks;
1877  }
1878  }
1879  // File versioning...
1880  foreach ( (array)$parserOutput->getFileSearchOptions() as $dbk => $data ) {
1881  $this->mImageTimeKeys[$dbk] = $data;
1882  }
1883 
1884  // Hooks registered in the object
1885  $parserOutputHooks = $this->getConfig()->get( 'ParserOutputHooks' );
1886  foreach ( $parserOutput->getOutputHooks() as $hookInfo ) {
1887  list( $hookName, $data ) = $hookInfo;
1888  if ( isset( $parserOutputHooks[$hookName] ) ) {
1889  $parserOutputHooks[$hookName]( $this, $parserOutput, $data );
1890  }
1891  }
1892 
1893  // Enable OOUI if requested via ParserOutput
1894  if ( $parserOutput->getEnableOOUI() ) {
1895  $this->enableOOUI();
1896  }
1897 
1898  // Include parser limit report
1899  if ( !$this->limitReportJSData ) {
1900  $this->limitReportJSData = $parserOutput->getLimitReportJSData();
1901  }
1902 
1903  // Link flags are ignored for now, but may in the future be
1904  // used to mark individual language links.
1905  $linkFlags = [];
1906  // Avoid PHP 7.1 warning of passing $this by reference
1907  $outputPage = $this;
1908  Hooks::run( 'LanguageLinks', [ $this->getTitle(), &$this->mLanguageLinks, &$linkFlags ] );
1909  Hooks::runWithoutAbort( 'OutputPageParserOutput', [ &$outputPage, $parserOutput ] );
1910 
1911  // This check must be after 'OutputPageParserOutput' runs in addParserOutputMetadata
1912  // so that extensions may modify ParserOutput to toggle TOC.
1913  // This cannot be moved to addParserOutputText because that is not
1914  // called by EditPage for Preview.
1915  if ( $parserOutput->getTOCHTML() ) {
1916  $this->mEnableTOC = true;
1917  }
1918  }
1919 
1928  public function addParserOutputContent( ParserOutput $parserOutput, $poOptions = [] ) {
1929  $this->addParserOutputText( $parserOutput, $poOptions );
1930 
1931  $this->addModules( $parserOutput->getModules() );
1932  $this->addModuleStyles( $parserOutput->getModuleStyles() );
1933 
1934  $this->addJsConfigVars( $parserOutput->getJsConfigVars() );
1935  }
1936 
1944  public function addParserOutputText( ParserOutput $parserOutput, $poOptions = [] ) {
1945  $text = $parserOutput->getText( $poOptions );
1946  // Avoid PHP 7.1 warning of passing $this by reference
1947  $outputPage = $this;
1948  Hooks::runWithoutAbort( 'OutputPageBeforeHTML', [ &$outputPage, &$text ] );
1949  $this->addHTML( $text );
1950  }
1951 
1958  public function addParserOutput( ParserOutput $parserOutput, $poOptions = [] ) {
1959  $this->addParserOutputMetadata( $parserOutput );
1960  $this->addParserOutputText( $parserOutput, $poOptions );
1961  }
1962 
1968  public function addTemplate( &$template ) {
1969  $this->addHTML( $template->getHTML() );
1970  }
1971 
1990  public function parse( $text, $linestart = true, $interface = false, $language = null ) {
1991  wfDeprecated( __METHOD__, '1.33' );
1992  return $this->parseInternal(
1993  $text, $this->getTitle(), $linestart, /*tidy*/false, $interface, $language
1994  )->getText( [
1995  'enableSectionEditLinks' => false,
1996  ] );
1997  }
1998 
2010  public function parseAsContent( $text, $linestart = true ) {
2011  return $this->parseInternal(
2012  $text, $this->getTitle(), $linestart, /*tidy*/true, /*interface*/false, /*language*/null
2013  )->getText( [
2014  'enableSectionEditLinks' => false,
2015  'wrapperDivClass' => ''
2016  ] );
2017  }
2018 
2031  public function parseAsInterface( $text, $linestart = true ) {
2032  return $this->parseInternal(
2033  $text, $this->getTitle(), $linestart, /*tidy*/true, /*interface*/true, /*language*/null
2034  )->getText( [
2035  'enableSectionEditLinks' => false,
2036  'wrapperDivClass' => ''
2037  ] );
2038  }
2039 
2054  public function parseInlineAsInterface( $text, $linestart = true ) {
2056  $this->parseAsInterface( $text, $linestart )
2057  );
2058  }
2059 
2073  public function parseInline( $text, $linestart = true, $interface = false ) {
2074  wfDeprecated( __METHOD__, '1.33' );
2075  $parsed = $this->parseInternal(
2076  $text, $this->getTitle(), $linestart, /*tidy*/false, $interface, /*language*/null
2077  )->getText( [
2078  'enableSectionEditLinks' => false,
2079  'wrapperDivClass' => '', /* no wrapper div */
2080  ] );
2081  return Parser::stripOuterParagraph( $parsed );
2082  }
2083 
2098  private function parseInternal( $text, $title, $linestart, $tidy, $interface, $language ) {
2099  if ( is_null( $title ) ) {
2100  throw new MWException( 'Empty $mTitle in ' . __METHOD__ );
2101  }
2102 
2103  $popts = $this->parserOptions();
2104  $oldTidy = $popts->setTidy( $tidy );
2105  $oldInterface = $popts->setInterfaceMessage( (bool)$interface );
2106 
2107  if ( $language !== null ) {
2108  $oldLang = $popts->setTargetLanguage( $language );
2109  }
2110 
2111  $parserOutput = MediaWikiServices::getInstance()->getParser()->getFreshParser()->parse(
2112  $text, $title, $popts,
2113  $linestart, true, $this->mRevisionId
2114  );
2115 
2116  $popts->setTidy( $oldTidy );
2117  $popts->setInterfaceMessage( $oldInterface );
2118 
2119  if ( $language !== null ) {
2120  $popts->setTargetLanguage( $oldLang );
2121  }
2122 
2123  return $parserOutput;
2124  }
2125 
2131  public function setCdnMaxage( $maxage ) {
2132  $this->mCdnMaxage = min( $maxage, $this->mCdnMaxageLimit );
2133  }
2134 
2144  public function lowerCdnMaxage( $maxage ) {
2145  $this->mCdnMaxageLimit = min( $maxage, $this->mCdnMaxageLimit );
2146  $this->setCdnMaxage( $this->mCdnMaxage );
2147  }
2148 
2161  public function adaptCdnTTL( $mtime, $minTTL = 0, $maxTTL = 0 ) {
2162  $minTTL = $minTTL ?: IExpiringStore::TTL_MINUTE;
2163  $maxTTL = $maxTTL ?: $this->getConfig()->get( 'CdnMaxAge' );
2164 
2165  if ( $mtime === null || $mtime === false ) {
2166  return; // entity does not exist
2167  }
2168 
2169  $age = MWTimestamp::time() - (int)wfTimestamp( TS_UNIX, $mtime );
2170  $adaptiveTTL = max( 0.9 * $age, $minTTL );
2171  $adaptiveTTL = min( $adaptiveTTL, $maxTTL );
2172 
2173  $this->lowerCdnMaxage( (int)$adaptiveTTL );
2174  }
2175 
2183  public function enableClientCache( $state ) {
2184  return wfSetVar( $this->mEnableClientCache, $state );
2185  }
2186 
2192  public function getCacheVaryCookies() {
2193  if ( self::$cacheVaryCookies === null ) {
2194  $config = $this->getConfig();
2195  self::$cacheVaryCookies = array_values( array_unique( array_merge(
2196  SessionManager::singleton()->getVaryCookies(),
2197  [
2198  'forceHTTPS',
2199  ],
2200  $config->get( 'CacheVaryCookies' )
2201  ) ) );
2202  Hooks::run( 'GetCacheVaryCookies', [ $this, &self::$cacheVaryCookies ] );
2203  }
2204  return self::$cacheVaryCookies;
2205  }
2206 
2213  public function haveCacheVaryCookies() {
2214  $request = $this->getRequest();
2215  foreach ( $this->getCacheVaryCookies() as $cookieName ) {
2216  if ( $request->getCookie( $cookieName, '', '' ) !== '' ) {
2217  wfDebug( __METHOD__ . ": found $cookieName\n" );
2218  return true;
2219  }
2220  }
2221  wfDebug( __METHOD__ . ": no cache-varying cookies found\n" );
2222  return false;
2223  }
2224 
2234  public function addVaryHeader( $header, array $option = null ) {
2235  if ( $option !== null && count( $option ) > 0 ) {
2236  wfDeprecated( 'addVaryHeader $option is ignored', '1.34' );
2237  }
2238  if ( !array_key_exists( $header, $this->mVaryHeader ) ) {
2239  $this->mVaryHeader[$header] = null;
2240  }
2241  }
2242 
2249  public function getVaryHeader() {
2250  // If we vary on cookies, let's make sure it's always included here too.
2251  if ( $this->getCacheVaryCookies() ) {
2252  $this->addVaryHeader( 'Cookie' );
2253  }
2254 
2255  foreach ( SessionManager::singleton()->getVaryHeaders() as $header => $options ) {
2256  $this->addVaryHeader( $header, $options );
2257  }
2258  return 'Vary: ' . implode( ', ', array_keys( $this->mVaryHeader ) );
2259  }
2260 
2266  public function addLinkHeader( $header ) {
2267  $this->mLinkHeader[] = $header;
2268  }
2269 
2275  public function getLinkHeader() {
2276  if ( !$this->mLinkHeader ) {
2277  return false;
2278  }
2279 
2280  return 'Link: ' . implode( ',', $this->mLinkHeader );
2281  }
2282 
2290  private function addAcceptLanguage() {
2291  $title = $this->getTitle();
2292  if ( !$title instanceof Title ) {
2293  return;
2294  }
2295 
2296  $lang = $title->getPageLanguage();
2297  if ( !$this->getRequest()->getCheck( 'variant' ) && $lang->hasVariants() ) {
2298  $this->addVaryHeader( 'Accept-Language' );
2299  }
2300  }
2301 
2312  public function preventClickjacking( $enable = true ) {
2313  $this->mPreventClickjacking = $enable;
2314  }
2315 
2321  public function allowClickjacking() {
2322  $this->mPreventClickjacking = false;
2323  }
2324 
2331  public function getPreventClickjacking() {
2333  }
2334 
2342  public function getFrameOptions() {
2343  $config = $this->getConfig();
2344  if ( $config->get( 'BreakFrames' ) ) {
2345  return 'DENY';
2346  } elseif ( $this->mPreventClickjacking && $config->get( 'EditPageFrameOptions' ) ) {
2347  return $config->get( 'EditPageFrameOptions' );
2348  }
2349  return false;
2350  }
2351 
2358  private function getOriginTrials() {
2359  $config = $this->getConfig();
2360 
2361  return $config->get( 'OriginTrials' );
2362  }
2363 
2364  private function getReportTo() {
2365  $config = $this->getConfig();
2366 
2367  $expiry = $config->get( 'ReportToExpiry' );
2368 
2369  if ( !$expiry ) {
2370  return false;
2371  }
2372 
2373  $endpoints = $config->get( 'ReportToEndpoints' );
2374 
2375  if ( !$endpoints ) {
2376  return false;
2377  }
2378 
2379  $output = [ 'max_age' => $expiry, 'endpoints' => [] ];
2380 
2381  foreach ( $endpoints as $endpoint ) {
2382  $output['endpoints'][] = [ 'url' => $endpoint ];
2383  }
2384 
2385  return json_encode( $output, JSON_UNESCAPED_SLASHES );
2386  }
2387 
2388  private function getFeaturePolicyReportOnly() {
2389  $config = $this->getConfig();
2390 
2391  $features = $config->get( 'FeaturePolicyReportOnly' );
2392  return implode( ';', $features );
2393  }
2394 
2398  public function sendCacheControl() {
2399  $response = $this->getRequest()->response();
2400  $config = $this->getConfig();
2401 
2402  $this->addVaryHeader( 'Cookie' );
2403  $this->addAcceptLanguage();
2404 
2405  # don't serve compressed data to clients who can't handle it
2406  # maintain different caches for logged-in users and non-logged in ones
2407  $response->header( $this->getVaryHeader() );
2408 
2409  if ( $this->mEnableClientCache ) {
2410  if (
2411  $config->get( 'UseCdn' ) &&
2412  !$response->hasCookies() &&
2413  !SessionManager::getGlobalSession()->isPersistent() &&
2414  !$this->isPrintable() &&
2415  $this->mCdnMaxage != 0 &&
2416  !$this->haveCacheVaryCookies()
2417  ) {
2418  # We'll purge the proxy cache for anons explicitly, but require end user agents
2419  # to revalidate against the proxy on each visit.
2420  # IMPORTANT! The CDN needs to replace the Cache-Control header with
2421  # Cache-Control: s-maxage=0, must-revalidate, max-age=0
2422  wfDebug( __METHOD__ .
2423  ": local proxy caching; {$this->mLastModified} **", 'private' );
2424  # start with a shorter timeout for initial testing
2425  # header( "Cache-Control: s-maxage=2678400, must-revalidate, max-age=0" );
2426  $response->header( "Cache-Control: " .
2427  "s-maxage={$this->mCdnMaxage}, must-revalidate, max-age=0" );
2428  } else {
2429  # We do want clients to cache if they can, but they *must* check for updates
2430  # on revisiting the page.
2431  wfDebug( __METHOD__ . ": private caching; {$this->mLastModified} **", 'private' );
2432  $response->header( 'Expires: ' . gmdate( 'D, d M Y H:i:s', 0 ) . ' GMT' );
2433  $response->header( "Cache-Control: private, must-revalidate, max-age=0" );
2434  }
2435  if ( $this->mLastModified ) {
2436  $response->header( "Last-Modified: {$this->mLastModified}" );
2437  }
2438  } else {
2439  wfDebug( __METHOD__ . ": no caching **", 'private' );
2440 
2441  # In general, the absence of a last modified header should be enough to prevent
2442  # the client from using its cache. We send a few other things just to make sure.
2443  $response->header( 'Expires: ' . gmdate( 'D, d M Y H:i:s', 0 ) . ' GMT' );
2444  $response->header( 'Cache-Control: no-cache, no-store, max-age=0, must-revalidate' );
2445  $response->header( 'Pragma: no-cache' );
2446  }
2447  }
2448 
2454  public function loadSkinModules( $sk ) {
2455  foreach ( $sk->getDefaultModules() as $group => $modules ) {
2456  if ( $group === 'styles' ) {
2457  foreach ( $modules as $key => $moduleMembers ) {
2458  $this->addModuleStyles( $moduleMembers );
2459  }
2460  } else {
2461  $this->addModules( $modules );
2462  }
2463  }
2464  }
2465 
2476  public function output( $return = false ) {
2477  if ( $this->mDoNothing ) {
2478  return $return ? '' : null;
2479  }
2480 
2481  $response = $this->getRequest()->response();
2482  $config = $this->getConfig();
2483 
2484  if ( $this->mRedirect != '' ) {
2485  # Standards require redirect URLs to be absolute
2486  $this->mRedirect = wfExpandUrl( $this->mRedirect, PROTO_CURRENT );
2487 
2488  $redirect = $this->mRedirect;
2489  $code = $this->mRedirectCode;
2490 
2491  if ( Hooks::run( "BeforePageRedirect", [ $this, &$redirect, &$code ] ) ) {
2492  if ( $code == '301' || $code == '303' ) {
2493  if ( !$config->get( 'DebugRedirects' ) ) {
2494  $response->statusHeader( $code );
2495  }
2496  $this->mLastModified = wfTimestamp( TS_RFC2822 );
2497  }
2498  if ( $config->get( 'VaryOnXFP' ) ) {
2499  $this->addVaryHeader( 'X-Forwarded-Proto' );
2500  }
2501  $this->sendCacheControl();
2502 
2503  $response->header( "Content-Type: text/html; charset=utf-8" );
2504  if ( $config->get( 'DebugRedirects' ) ) {
2505  $url = htmlspecialchars( $redirect );
2506  print "<!DOCTYPE html>\n<html>\n<head>\n<title>Redirect</title>\n</head>\n<body>\n";
2507  print "<p>Location: <a href=\"$url\">$url</a></p>\n";
2508  print "</body>\n</html>\n";
2509  } else {
2510  $response->header( 'Location: ' . $redirect );
2511  }
2512  }
2513 
2514  return $return ? '' : null;
2515  } elseif ( $this->mStatusCode ) {
2516  $response->statusHeader( $this->mStatusCode );
2517  }
2518 
2519  # Buffer output; final headers may depend on later processing
2520  ob_start();
2521 
2522  $response->header( 'Content-type: ' . $config->get( 'MimeType' ) . '; charset=UTF-8' );
2523  $response->header( 'Content-language: ' .
2524  MediaWikiServices::getInstance()->getContentLanguage()->getHtmlCode() );
2525 
2526  $linkHeader = $this->getLinkHeader();
2527  if ( $linkHeader ) {
2528  $response->header( $linkHeader );
2529  }
2530 
2531  // Prevent framing, if requested
2532  $frameOptions = $this->getFrameOptions();
2533  if ( $frameOptions ) {
2534  $response->header( "X-Frame-Options: $frameOptions" );
2535  }
2536 
2537  $originTrials = $this->getOriginTrials();
2538  foreach ( $originTrials as $originTrial ) {
2539  $response->header( "Origin-Trial: $originTrial", false );
2540  }
2541 
2542  $reportTo = $this->getReportTo();
2543  if ( $reportTo ) {
2544  $response->header( "Report-To: $reportTo" );
2545  }
2546 
2547  $featurePolicyReportOnly = $this->getFeaturePolicyReportOnly();
2548  if ( $featurePolicyReportOnly ) {
2549  $response->header( "Feature-Policy-Report-Only: $featurePolicyReportOnly" );
2550  }
2551 
2553 
2554  if ( $this->mArticleBodyOnly ) {
2555  echo $this->mBodytext;
2556  } else {
2557  // Enable safe mode if requested (T152169)
2558  if ( $this->getRequest()->getBool( 'safemode' ) ) {
2559  $this->disallowUserJs();
2560  }
2561 
2562  $sk = $this->getSkin();
2563  $this->loadSkinModules( $sk );
2564 
2565  MWDebug::addModules( $this );
2566 
2567  // Avoid PHP 7.1 warning of passing $this by reference
2568  $outputPage = $this;
2569  // Hook that allows last minute changes to the output page, e.g.
2570  // adding of CSS or Javascript by extensions.
2571  Hooks::runWithoutAbort( 'BeforePageDisplay', [ &$outputPage, &$sk ] );
2572 
2573  try {
2574  $sk->outputPage();
2575  } catch ( Exception $e ) {
2576  ob_end_clean(); // bug T129657
2577  throw $e;
2578  }
2579  }
2580 
2581  try {
2582  // This hook allows last minute changes to final overall output by modifying output buffer
2583  Hooks::runWithoutAbort( 'AfterFinalPageOutput', [ $this ] );
2584  } catch ( Exception $e ) {
2585  ob_end_clean(); // bug T129657
2586  throw $e;
2587  }
2588 
2589  $this->sendCacheControl();
2590 
2591  if ( $return ) {
2592  return ob_get_clean();
2593  } else {
2594  ob_end_flush();
2595  return null;
2596  }
2597  }
2598 
2609  public function prepareErrorPage( $pageTitle, $htmlTitle = false ) {
2610  $this->setPageTitle( $pageTitle );
2611  if ( $htmlTitle !== false ) {
2612  $this->setHTMLTitle( $htmlTitle );
2613  }
2614  $this->setRobotPolicy( 'noindex,nofollow' );
2615  $this->setArticleRelated( false );
2616  $this->enableClientCache( false );
2617  $this->mRedirect = '';
2618  $this->clearSubtitle();
2619  $this->clearHTML();
2620  }
2621 
2634  public function showErrorPage( $title, $msg, $params = [] ) {
2635  if ( !$title instanceof Message ) {
2636  $title = $this->msg( $title );
2637  }
2638 
2639  $this->prepareErrorPage( $title );
2640 
2641  if ( $msg instanceof Message ) {
2642  if ( $params !== [] ) {
2643  trigger_error( 'Argument ignored: $params. The message parameters argument '
2644  . 'is discarded when the $msg argument is a Message object instead of '
2645  . 'a string.', E_USER_NOTICE );
2646  }
2647  $this->addHTML( $msg->parseAsBlock() );
2648  } else {
2649  $this->addWikiMsgArray( $msg, $params );
2650  }
2651 
2652  $this->returnToMain();
2653  }
2654 
2661  public function showPermissionsErrorPage( array $errors, $action = null ) {
2662  $services = MediaWikiServices::getInstance();
2663  $permissionManager = $services->getPermissionManager();
2664  foreach ( $errors as $key => $error ) {
2665  $errors[$key] = (array)$error;
2666  }
2667 
2668  // For some action (read, edit, create and upload), display a "login to do this action"
2669  // error if all of the following conditions are met:
2670  // 1. the user is not logged in
2671  // 2. the only error is insufficient permissions (i.e. no block or something else)
2672  // 3. the error can be avoided simply by logging in
2673 
2674  if ( in_array( $action, [ 'read', 'edit', 'createpage', 'createtalk', 'upload' ] )
2675  && $this->getUser()->isAnon() && count( $errors ) == 1 && isset( $errors[0][0] )
2676  && ( $errors[0][0] == 'badaccess-groups' || $errors[0][0] == 'badaccess-group0' )
2677  && ( $permissionManager->groupHasPermission( 'user', $action )
2678  || $permissionManager->groupHasPermission( 'autoconfirmed', $action ) )
2679  ) {
2680  $displayReturnto = null;
2681 
2682  # Due to T34276, if a user does not have read permissions,
2683  # $this->getTitle() will just give Special:Badtitle, which is
2684  # not especially useful as a returnto parameter. Use the title
2685  # from the request instead, if there was one.
2686  $request = $this->getRequest();
2687  $returnto = Title::newFromText( $request->getVal( 'title', '' ) );
2688  if ( $action == 'edit' ) {
2689  $msg = 'whitelistedittext';
2690  $displayReturnto = $returnto;
2691  } elseif ( $action == 'createpage' || $action == 'createtalk' ) {
2692  $msg = 'nocreatetext';
2693  } elseif ( $action == 'upload' ) {
2694  $msg = 'uploadnologintext';
2695  } else { # Read
2696  $msg = 'loginreqpagetext';
2697  $displayReturnto = Title::newMainPage();
2698  }
2699 
2700  $query = [];
2701 
2702  if ( $returnto ) {
2703  $query['returnto'] = $returnto->getPrefixedText();
2704 
2705  if ( !$request->wasPosted() ) {
2706  $returntoquery = $request->getValues();
2707  unset( $returntoquery['title'] );
2708  unset( $returntoquery['returnto'] );
2709  unset( $returntoquery['returntoquery'] );
2710  $query['returntoquery'] = wfArrayToCgi( $returntoquery );
2711  }
2712  }
2713 
2714  $title = SpecialPage::getTitleFor( 'Userlogin' );
2715  $linkRenderer = $services->getLinkRenderer();
2716  $loginUrl = $title->getLinkURL( $query, false, PROTO_RELATIVE );
2717  $loginLink = $linkRenderer->makeKnownLink(
2718  $title,
2719  $this->msg( 'loginreqlink' )->text(),
2720  [],
2721  $query
2722  );
2723 
2724  $this->prepareErrorPage( $this->msg( 'loginreqtitle' ) );
2725  $this->addHTML( $this->msg( $msg )->rawParams( $loginLink )->params( $loginUrl )->parse() );
2726 
2727  # Don't return to a page the user can't read otherwise
2728  # we'll end up in a pointless loop
2729  if ( $displayReturnto && $permissionManager->userCan(
2730  'read', $this->getUser(), $displayReturnto
2731  ) ) {
2732  $this->returnToMain( null, $displayReturnto );
2733  }
2734  } else {
2735  $this->prepareErrorPage( $this->msg( 'permissionserrors' ) );
2736  $this->addWikiTextAsInterface( $this->formatPermissionsErrorMessage( $errors, $action ) );
2737  }
2738  }
2739 
2746  public function versionRequired( $version ) {
2747  $this->prepareErrorPage( $this->msg( 'versionrequired', $version ) );
2748 
2749  $this->addWikiMsg( 'versionrequiredtext', $version );
2750  $this->returnToMain();
2751  }
2752 
2760  public function formatPermissionsErrorMessage( array $errors, $action = null ) {
2761  if ( $action == null ) {
2762  $text = $this->msg( 'permissionserrorstext', count( $errors ) )->plain() . "\n\n";
2763  } else {
2764  $action_desc = $this->msg( "action-$action" )->plain();
2765  $text = $this->msg(
2766  'permissionserrorstext-withaction',
2767  count( $errors ),
2768  $action_desc
2769  )->plain() . "\n\n";
2770  }
2771 
2772  if ( count( $errors ) > 1 ) {
2773  $text .= '<ul class="permissions-errors">' . "\n";
2774 
2775  foreach ( $errors as $error ) {
2776  $text .= '<li>';
2777  $text .= $this->msg( ...$error )->plain();
2778  $text .= "</li>\n";
2779  }
2780  $text .= '</ul>';
2781  } else {
2782  $text .= "<div class=\"permissions-errors\">\n" .
2783  $this->msg( ...reset( $errors ) )->plain() .
2784  "\n</div>";
2785  }
2786 
2787  return $text;
2788  }
2789 
2799  public function showLagWarning( $lag ) {
2800  $config = $this->getConfig();
2801  if ( $lag >= $config->get( 'SlaveLagWarning' ) ) {
2802  $lag = floor( $lag ); // floor to avoid nano seconds to display
2803  $message = $lag < $config->get( 'SlaveLagCritical' )
2804  ? 'lag-warn-normal'
2805  : 'lag-warn-high';
2806  $wrap = Html::rawElement( 'div', [ 'class' => "mw-{$message}" ], "\n$1\n" );
2807  $this->wrapWikiMsg( "$wrap\n", [ $message, $this->getLanguage()->formatNum( $lag ) ] );
2808  }
2809  }
2810 
2817  public function showFatalError( $message ) {
2818  $this->prepareErrorPage( $this->msg( 'internalerror' ) );
2819 
2820  $this->addHTML( $message );
2821  }
2822 
2831  public function addReturnTo( $title, array $query = [], $text = null, $options = [] ) {
2832  $linkRenderer = MediaWikiServices::getInstance()
2833  ->getLinkRendererFactory()->createFromLegacyOptions( $options );
2834  $link = $this->msg( 'returnto' )->rawParams(
2835  $linkRenderer->makeLink( $title, $text, [], $query ) )->escaped();
2836  $this->addHTML( "<p id=\"mw-returnto\">{$link}</p>\n" );
2837  }
2838 
2847  public function returnToMain( $unused = null, $returnto = null, $returntoquery = null ) {
2848  if ( $returnto == null ) {
2849  $returnto = $this->getRequest()->getText( 'returnto' );
2850  }
2851 
2852  if ( $returntoquery == null ) {
2853  $returntoquery = $this->getRequest()->getText( 'returntoquery' );
2854  }
2855 
2856  if ( $returnto === '' ) {
2857  $returnto = Title::newMainPage();
2858  }
2859 
2860  if ( is_object( $returnto ) ) {
2861  $titleObj = $returnto;
2862  } else {
2863  $titleObj = Title::newFromText( $returnto );
2864  }
2865  // We don't want people to return to external interwiki. That
2866  // might potentially be used as part of a phishing scheme
2867  if ( !is_object( $titleObj ) || $titleObj->isExternal() ) {
2868  $titleObj = Title::newMainPage();
2869  }
2870 
2871  $this->addReturnTo( $titleObj, wfCgiToArray( $returntoquery ) );
2872  }
2873 
2874  private function getRlClientContext() {
2875  if ( !$this->rlClientContext ) {
2877  [], // modules; not relevant
2878  $this->getLanguage()->getCode(),
2879  $this->getSkin()->getSkinName(),
2880  $this->getUser()->isLoggedIn() ? $this->getUser()->getName() : null,
2881  null, // version; not relevant
2883  null, // only; not relevant
2884  $this->isPrintable(),
2885  $this->getRequest()->getBool( 'handheld' )
2886  );
2887  $this->rlClientContext = new ResourceLoaderContext(
2888  $this->getResourceLoader(),
2889  new FauxRequest( $query )
2890  );
2891  if ( $this->contentOverrideCallbacks ) {
2892  $this->rlClientContext = new DerivativeResourceLoaderContext( $this->rlClientContext );
2893  $this->rlClientContext->setContentOverrideCallback( function ( Title $title ) {
2894  foreach ( $this->contentOverrideCallbacks as $callback ) {
2895  $content = $callback( $title );
2896  if ( $content !== null ) {
2898  if ( strpos( $text, '</script>' ) !== false ) {
2899  // Proactively replace this so that we can display a message
2900  // to the user, instead of letting it go to Html::inlineScript(),
2901  // where it would be considered a server-side issue.
2902  $titleFormatted = $title->getPrefixedText();
2904  Xml::encodeJsCall( 'mw.log.error', [
2905  "Cannot preview $titleFormatted due to script-closing tag."
2906  ] )
2907  );
2908  }
2909  return $content;
2910  }
2911  }
2912  return null;
2913  } );
2914  }
2915  }
2916  return $this->rlClientContext;
2917  }
2918 
2930  public function getRlClient() {
2931  if ( !$this->rlClient ) {
2932  $context = $this->getRlClientContext();
2933  $rl = $this->getResourceLoader();
2934  $this->addModules( [
2935  'user',
2936  'user.options',
2937  'user.tokens',
2938  ] );
2939  $this->addModuleStyles( [
2940  'site.styles',
2941  'noscript',
2942  'user.styles',
2943  ] );
2944  $this->getSkin()->setupSkinUserCss( $this );
2945 
2946  // Prepare exempt modules for buildExemptModules()
2947  $exemptGroups = [ 'site' => [], 'noscript' => [], 'private' => [], 'user' => [] ];
2948  $exemptStates = [];
2949  $moduleStyles = $this->getModuleStyles( /*filter*/ true );
2950 
2951  // Preload getTitleInfo for isKnownEmpty calls below and in ResourceLoaderClientHtml
2952  // Separate user-specific batch for improved cache-hit ratio.
2953  $userBatch = [ 'user.styles', 'user' ];
2954  $siteBatch = array_diff( $moduleStyles, $userBatch );
2955  $dbr = wfGetDB( DB_REPLICA );
2958 
2959  // Filter out modules handled by buildExemptModules()
2960  $moduleStyles = array_filter( $moduleStyles,
2961  function ( $name ) use ( $rl, $context, &$exemptGroups, &$exemptStates ) {
2962  $module = $rl->getModule( $name );
2963  if ( $module ) {
2964  $group = $module->getGroup();
2965  if ( isset( $exemptGroups[$group] ) ) {
2966  $exemptStates[$name] = 'ready';
2967  if ( !$module->isKnownEmpty( $context ) ) {
2968  // E.g. Don't output empty <styles>
2969  $exemptGroups[$group][] = $name;
2970  }
2971  return false;
2972  }
2973  }
2974  return true;
2975  }
2976  );
2977  $this->rlExemptStyleModules = $exemptGroups;
2978 
2980  'target' => $this->getTarget(),
2981  'nonce' => $this->getCSPNonce(),
2982  // When 'safemode', disallowUserJs(), or reduceAllowedModules() is used
2983  // to only restrict modules to ORIGIN_CORE (ie. disallow ORIGIN_USER), the list of
2984  // modules enqueud for loading on this page is filtered to just those.
2985  // However, to make sure we also apply the restriction to dynamic dependencies and
2986  // lazy-loaded modules at run-time on the client-side, pass 'safemode' down to the
2987  // StartupModule so that the client-side registry will not contain any restricted
2988  // modules either. (T152169, T185303)
2989  'safemode' => ( $this->getAllowedModules( ResourceLoaderModule::TYPE_COMBINED )
2990  <= ResourceLoaderModule::ORIGIN_CORE_INDIVIDUAL
2991  ) ? '1' : null,
2992  ] );
2993  $rlClient->setConfig( $this->getJSVars() );
2994  $rlClient->setModules( $this->getModules( /*filter*/ true ) );
2995  $rlClient->setModuleStyles( $moduleStyles );
2996  $rlClient->setExemptStates( $exemptStates );
2997  $this->rlClient = $rlClient;
2998  }
2999  return $this->rlClient;
3000  }
3001 
3007  public function headElement( Skin $sk, $includeStyle = true ) {
3008  $config = $this->getConfig();
3009  $userdir = $this->getLanguage()->getDir();
3010  $sitedir = MediaWikiServices::getInstance()->getContentLanguage()->getDir();
3011 
3012  $pieces = [];
3013  $htmlAttribs = Sanitizer::mergeAttributes(
3014  $this->getRlClient()->getDocumentAttributes(),
3016  );
3017  $pieces[] = Html::htmlHeader( $htmlAttribs );
3018  $pieces[] = Html::openElement( 'head' );
3019 
3020  if ( $this->getHTMLTitle() == '' ) {
3021  $this->setHTMLTitle( $this->msg( 'pagetitle', $this->getPageTitle() )->inContentLanguage() );
3022  }
3023 
3024  if ( !Html::isXmlMimeType( $config->get( 'MimeType' ) ) ) {
3025  // Add <meta charset="UTF-8">
3026  // This should be before <title> since it defines the charset used by
3027  // text including the text inside <title>.
3028  // The spec recommends defining XHTML5's charset using the XML declaration
3029  // instead of meta.
3030  // Our XML declaration is output by Html::htmlHeader.
3031  // https://html.spec.whatwg.org/multipage/semantics.html#attr-meta-http-equiv-content-type
3032  // https://html.spec.whatwg.org/multipage/semantics.html#charset
3033  $pieces[] = Html::element( 'meta', [ 'charset' => 'UTF-8' ] );
3034  }
3035 
3036  $pieces[] = Html::element( 'title', null, $this->getHTMLTitle() );
3037  $pieces[] = $this->getRlClient()->getHeadHtml( $htmlAttribs['class'] ?? null );
3038  $pieces[] = $this->buildExemptModules();
3039  $pieces = array_merge( $pieces, array_values( $this->getHeadLinksArray() ) );
3040  $pieces = array_merge( $pieces, array_values( $this->mHeadItems ) );
3041 
3042  // This library is intended to run on older browsers that MediaWiki no longer
3043  // supports as Grade A. For these Grade C browsers, we provide an experience
3044  // using only HTML and CSS. But, where standards-compliant browsers are able to
3045  // style unknown HTML elements without issue, old IE ignores these styles.
3046  // The html5shiv library fixes that.
3047  // Use an IE conditional comment to serve the script only to old IE
3048  $shivUrl = $config->get( 'ResourceBasePath' ) . '/resources/lib/html5shiv/html5shiv.js';
3049  $pieces[] = '<!--[if lt IE 9]>' .
3050  Html::linkedScript( $shivUrl, $this->getCSPNonce() ) .
3051  '<![endif]-->';
3052 
3053  $pieces[] = Html::closeElement( 'head' );
3054 
3055  $bodyClasses = $this->mAdditionalBodyClasses;
3056  $bodyClasses[] = 'mediawiki';
3057 
3058  # Classes for LTR/RTL directionality support
3059  $bodyClasses[] = $userdir;
3060  $bodyClasses[] = "sitedir-$sitedir";
3061 
3062  $underline = $this->getUser()->getOption( 'underline' );
3063  if ( $underline < 2 ) {
3064  // The following classes can be used here:
3065  // * mw-underline-always
3066  // * mw-underline-never
3067  $bodyClasses[] = 'mw-underline-' . ( $underline ? 'always' : 'never' );
3068  }
3069 
3070  if ( $this->getLanguage()->capitalizeAllNouns() ) {
3071  # A <body> class is probably not the best way to do this . . .
3072  $bodyClasses[] = 'capitalize-all-nouns';
3073  }
3074 
3075  // Parser feature migration class
3076  // The idea is that this will eventually be removed, after the wikitext
3077  // which requires it is cleaned up.
3078  $bodyClasses[] = 'mw-hide-empty-elt';
3079 
3080  $bodyClasses[] = $sk->getPageClasses( $this->getTitle() );
3081  $bodyClasses[] = 'skin-' . Sanitizer::escapeClass( $sk->getSkinName() );
3082  $bodyClasses[] =
3083  'action-' . Sanitizer::escapeClass( Action::getActionName( $this->getContext() ) );
3084 
3085  $bodyAttrs = [];
3086  // While the implode() is not strictly needed, it's used for backwards compatibility
3087  // (this used to be built as a string and hooks likely still expect that).
3088  $bodyAttrs['class'] = implode( ' ', $bodyClasses );
3089 
3090  // Allow skins and extensions to add body attributes they need
3091  $sk->addToBodyAttributes( $this, $bodyAttrs );
3092  Hooks::run( 'OutputPageBodyAttributes', [ $this, $sk, &$bodyAttrs ] );
3093 
3094  $pieces[] = Html::openElement( 'body', $bodyAttrs );
3095 
3096  return self::combineWrappedStrings( $pieces );
3097  }
3098 
3104  public function getResourceLoader() {
3105  if ( is_null( $this->mResourceLoader ) ) {
3106  // Lazy-initialise as needed
3107  $this->mResourceLoader = MediaWikiServices::getInstance()->getResourceLoader();
3108  }
3109  return $this->mResourceLoader;
3110  }
3111 
3120  public function makeResourceLoaderLink( $modules, $only, array $extraQuery = [] ) {
3121  // Apply 'target' and 'origin' filters
3122  $modules = $this->filterModules( (array)$modules, null, $only );
3123 
3125  $this->getRlClientContext(),
3126  $modules,
3127  $only,
3128  $extraQuery,
3129  $this->getCSPNonce()
3130  );
3131  }
3132 
3139  protected static function combineWrappedStrings( array $chunks ) {
3140  // Filter out empty values
3141  $chunks = array_filter( $chunks, 'strlen' );
3142  return WrappedString::join( "\n", $chunks );
3143  }
3144 
3151  public function getBottomScripts() {
3152  $chunks = [];
3153  $chunks[] = $this->getRlClient()->getBodyHtml();
3154 
3155  // Legacy non-ResourceLoader scripts
3156  $chunks[] = $this->mScripts;
3157 
3158  if ( $this->limitReportJSData ) {
3161  [ 'wgPageParseReport' => $this->limitReportJSData ]
3162  ),
3163  $this->getCSPNonce()
3164  );
3165  }
3166 
3167  return self::combineWrappedStrings( $chunks );
3168  }
3169 
3176  public function getJsConfigVars() {
3177  return $this->mJsConfigVars;
3178  }
3179 
3186  public function addJsConfigVars( $keys, $value = null ) {
3187  if ( is_array( $keys ) ) {
3188  foreach ( $keys as $key => $value ) {
3189  $this->mJsConfigVars[$key] = $value;
3190  }
3191  return;
3192  }
3193 
3194  $this->mJsConfigVars[$keys] = $value;
3195  }
3196 
3206  public function getJSVars() {
3207  $curRevisionId = 0;
3208  $articleId = 0;
3209  $canonicalSpecialPageName = false; # T23115
3210  $services = MediaWikiServices::getInstance();
3211 
3212  $title = $this->getTitle();
3213  $ns = $title->getNamespace();
3214  $nsInfo = $services->getNamespaceInfo();
3215  $canonicalNamespace = $nsInfo->exists( $ns )
3216  ? $nsInfo->getCanonicalName( $ns )
3217  : $title->getNsText();
3218 
3219  $sk = $this->getSkin();
3220  // Get the relevant title so that AJAX features can use the correct page name
3221  // when making API requests from certain special pages (T36972).
3222  $relevantTitle = $sk->getRelevantTitle();
3223  $relevantUser = $sk->getRelevantUser();
3224 
3225  if ( $ns == NS_SPECIAL ) {
3226  list( $canonicalSpecialPageName, /*...*/ ) =
3227  $services->getSpecialPageFactory()->
3228  resolveAlias( $title->getDBkey() );
3229  } elseif ( $this->canUseWikiPage() ) {
3230  $wikiPage = $this->getWikiPage();
3231  $curRevisionId = $wikiPage->getLatest();
3232  $articleId = $wikiPage->getId();
3233  }
3234 
3235  $lang = $title->getPageViewLanguage();
3236 
3237  // Pre-process information
3238  $separatorTransTable = $lang->separatorTransformTable();
3239  $separatorTransTable = $separatorTransTable ?: [];
3240  $compactSeparatorTransTable = [
3241  implode( "\t", array_keys( $separatorTransTable ) ),
3242  implode( "\t", $separatorTransTable ),
3243  ];
3244  $digitTransTable = $lang->digitTransformTable();
3245  $digitTransTable = $digitTransTable ?: [];
3246  $compactDigitTransTable = [
3247  implode( "\t", array_keys( $digitTransTable ) ),
3248  implode( "\t", $digitTransTable ),
3249  ];
3250 
3251  $user = $this->getUser();
3252 
3253  $vars = [
3254  'wgCanonicalNamespace' => $canonicalNamespace,
3255  'wgCanonicalSpecialPageName' => $canonicalSpecialPageName,
3256  'wgNamespaceNumber' => $title->getNamespace(),
3257  'wgPageName' => $title->getPrefixedDBkey(),
3258  'wgTitle' => $title->getText(),
3259  'wgCurRevisionId' => $curRevisionId,
3260  'wgRevisionId' => (int)$this->getRevisionId(),
3261  'wgArticleId' => $articleId,
3262  'wgIsArticle' => $this->isArticle(),
3263  'wgIsRedirect' => $title->isRedirect(),
3264  'wgAction' => Action::getActionName( $this->getContext() ),
3265  'wgUserName' => $user->isAnon() ? null : $user->getName(),
3266  'wgUserGroups' => $user->getEffectiveGroups(),
3267  'wgCategories' => $this->getCategories(),
3268  'wgBreakFrames' => $this->getFrameOptions() == 'DENY',
3269  'wgPageContentLanguage' => $lang->getCode(),
3270  'wgPageContentModel' => $title->getContentModel(),
3271  'wgSeparatorTransformTable' => $compactSeparatorTransTable,
3272  'wgDigitTransformTable' => $compactDigitTransTable,
3273  'wgDefaultDateFormat' => $lang->getDefaultDateFormat(),
3274  'wgMonthNames' => $lang->getMonthNamesArray(),
3275  'wgMonthNamesShort' => $lang->getMonthAbbreviationsArray(),
3276  'wgRelevantPageName' => $relevantTitle->getPrefixedDBkey(),
3277  'wgRelevantArticleId' => $relevantTitle->getArticleID(),
3278  'wgRequestId' => WebRequest::getRequestId(),
3279  'wgCSPNonce' => $this->getCSPNonce(),
3280  ];
3281 
3282  if ( $user->isLoggedIn() ) {
3283  $vars['wgUserId'] = $user->getId();
3284  $vars['wgUserEditCount'] = $user->getEditCount();
3285  $userReg = $user->getRegistration();
3286  $vars['wgUserRegistration'] = $userReg ? (int)wfTimestamp( TS_UNIX, $userReg ) * 1000 : null;
3287  // Get the revision ID of the oldest new message on the user's talk
3288  // page. This can be used for constructing new message alerts on
3289  // the client side.
3290  $vars['wgUserNewMsgRevisionId'] = $user->getNewMessageRevisionId();
3291  }
3292 
3293  $contLang = $services->getContentLanguage();
3294  if ( $contLang->hasVariants() ) {
3295  $vars['wgUserVariant'] = $contLang->getPreferredVariant();
3296  }
3297  // Same test as SkinTemplate
3298  $vars['wgIsProbablyEditable'] = $this->userCanEditOrCreate( $user, $title );
3299 
3300  $vars['wgRelevantPageIsProbablyEditable'] = $relevantTitle &&
3301  $this->userCanEditOrCreate( $user, $relevantTitle );
3302 
3303  foreach ( $title->getRestrictionTypes() as $type ) {
3304  // Following keys are set in $vars:
3305  // wgRestrictionCreate, wgRestrictionEdit, wgRestrictionMove, wgRestrictionUpload
3306  $vars['wgRestriction' . ucfirst( $type )] = $title->getRestrictions( $type );
3307  }
3308 
3309  if ( $title->isMainPage() ) {
3310  $vars['wgIsMainPage'] = true;
3311  }
3312 
3313  if ( $this->mRedirectedFrom ) {
3314  $vars['wgRedirectedFrom'] = $this->mRedirectedFrom->getPrefixedDBkey();
3315  }
3316 
3317  if ( $relevantUser ) {
3318  $vars['wgRelevantUserName'] = $relevantUser->getName();
3319  }
3320 
3321  // Allow extensions to add their custom variables to the mw.config map.
3322  // Use the 'ResourceLoaderGetConfigVars' hook if the variable is not
3323  // page-dependant but site-wide (without state).
3324  // Alternatively, you may want to use OutputPage->addJsConfigVars() instead.
3325  Hooks::run( 'MakeGlobalVariablesScript', [ &$vars, $this ] );
3326 
3327  // Merge in variables from addJsConfigVars last
3328  return array_merge( $vars, $this->getJsConfigVars() );
3329  }
3330 
3340  public function userCanPreview() {
3341  $request = $this->getRequest();
3342  if (
3343  $request->getVal( 'action' ) !== 'submit' ||
3344  !$request->wasPosted()
3345  ) {
3346  return false;
3347  }
3348 
3349  $user = $this->getUser();
3350 
3351  if ( !$user->isLoggedIn() ) {
3352  // Anons have predictable edit tokens
3353  return false;
3354  }
3355  if ( !$user->matchEditToken( $request->getVal( 'wpEditToken' ) ) ) {
3356  return false;
3357  }
3358 
3359  $title = $this->getTitle();
3360  $errors = $title->getUserPermissionsErrors( 'edit', $user );
3361  if ( count( $errors ) !== 0 ) {
3362  return false;
3363  }
3364 
3365  return true;
3366  }
3367 
3373  private function userCanEditOrCreate(
3374  User $user,
3376  ) {
3377  $pm = MediaWikiServices::getInstance()->getPermissionManager();
3378  return $pm->quickUserCan( 'edit', $user, $title )
3379  && ( $this->getTitle()->exists() ||
3380  $pm->quickUserCan( 'create', $user, $title ) );
3381  }
3382 
3386  public function getHeadLinksArray() {
3387  global $wgVersion;
3388 
3389  $tags = [];
3390  $config = $this->getConfig();
3391 
3392  $canonicalUrl = $this->mCanonicalUrl;
3393 
3394  $tags['meta-generator'] = Html::element( 'meta', [
3395  'name' => 'generator',
3396  'content' => "MediaWiki $wgVersion",
3397  ] );
3398 
3399  if ( $config->get( 'ReferrerPolicy' ) !== false ) {
3400  // Per https://w3c.github.io/webappsec-referrer-policy/#unknown-policy-values
3401  // fallbacks should come before the primary value so we need to reverse the array.
3402  foreach ( array_reverse( (array)$config->get( 'ReferrerPolicy' ) ) as $i => $policy ) {
3403  $tags["meta-referrer-$i"] = Html::element( 'meta', [
3404  'name' => 'referrer',
3405  'content' => $policy,
3406  ] );
3407  }
3408  }
3409 
3410  $p = "{$this->mIndexPolicy},{$this->mFollowPolicy}";
3411  if ( $p !== 'index,follow' ) {
3412  // http://www.robotstxt.org/wc/meta-user.html
3413  // Only show if it's different from the default robots policy
3414  $tags['meta-robots'] = Html::element( 'meta', [
3415  'name' => 'robots',
3416  'content' => $p,
3417  ] );
3418  }
3419 
3420  foreach ( $this->mMetatags as $tag ) {
3421  if ( strncasecmp( $tag[0], 'http:', 5 ) === 0 ) {
3422  $a = 'http-equiv';
3423  $tag[0] = substr( $tag[0], 5 );
3424  } elseif ( strncasecmp( $tag[0], 'og:', 3 ) === 0 ) {
3425  $a = 'property';
3426  } else {
3427  $a = 'name';
3428  }
3429  $tagName = "meta-{$tag[0]}";
3430  if ( isset( $tags[$tagName] ) ) {
3431  $tagName .= $tag[1];
3432  }
3433  $tags[$tagName] = Html::element( 'meta',
3434  [
3435  $a => $tag[0],
3436  'content' => $tag[1]
3437  ]
3438  );
3439  }
3440 
3441  foreach ( $this->mLinktags as $tag ) {
3442  $tags[] = Html::element( 'link', $tag );
3443  }
3444 
3445  # Universal edit button
3446  if ( $config->get( 'UniversalEditButton' ) && $this->isArticleRelated() ) {
3447  if ( $this->userCanEditOrCreate( $this->getUser(), $this->getTitle() ) ) {
3448  // Original UniversalEditButton
3449  $msg = $this->msg( 'edit' )->text();
3450  $tags['universal-edit-button'] = Html::element( 'link', [
3451  'rel' => 'alternate',
3452  'type' => 'application/x-wiki',
3453  'title' => $msg,
3454  'href' => $this->getTitle()->getEditURL(),
3455  ] );
3456  // Alternate edit link
3457  $tags['alternative-edit'] = Html::element( 'link', [
3458  'rel' => 'edit',
3459  'title' => $msg,
3460  'href' => $this->getTitle()->getEditURL(),
3461  ] );
3462  }
3463  }
3464 
3465  # Generally the order of the favicon and apple-touch-icon links
3466  # should not matter, but Konqueror (3.5.9 at least) incorrectly
3467  # uses whichever one appears later in the HTML source. Make sure
3468  # apple-touch-icon is specified first to avoid this.
3469  if ( $config->get( 'AppleTouchIcon' ) !== false ) {
3470  $tags['apple-touch-icon'] = Html::element( 'link', [
3471  'rel' => 'apple-touch-icon',
3472  'href' => $config->get( 'AppleTouchIcon' )
3473  ] );
3474  }
3475 
3476  if ( $config->get( 'Favicon' ) !== false ) {
3477  $tags['favicon'] = Html::element( 'link', [
3478  'rel' => 'shortcut icon',
3479  'href' => $config->get( 'Favicon' )
3480  ] );
3481  }
3482 
3483  # OpenSearch description link
3484  $tags['opensearch'] = Html::element( 'link', [
3485  'rel' => 'search',
3486  'type' => 'application/opensearchdescription+xml',
3487  'href' => wfScript( 'opensearch_desc' ),
3488  'title' => $this->msg( 'opensearch-desc' )->inContentLanguage()->text(),
3489  ] );
3490 
3491  # Real Simple Discovery link, provides auto-discovery information
3492  # for the MediaWiki API (and potentially additional custom API
3493  # support such as WordPress or Twitter-compatible APIs for a
3494  # blogging extension, etc)
3495  $tags['rsd'] = Html::element( 'link', [
3496  'rel' => 'EditURI',
3497  'type' => 'application/rsd+xml',
3498  // Output a protocol-relative URL here if $wgServer is protocol-relative.
3499  // Whether RSD accepts relative or protocol-relative URLs is completely
3500  // undocumented, though.
3501  'href' => wfExpandUrl( wfAppendQuery(
3502  wfScript( 'api' ),
3503  [ 'action' => 'rsd' ] ),
3505  ),
3506  ] );
3507 
3508  # Language variants
3509  if ( !$config->get( 'DisableLangConversion' ) ) {
3510  $lang = $this->getTitle()->getPageLanguage();
3511  if ( $lang->hasVariants() ) {
3512  $variants = $lang->getVariants();
3513  foreach ( $variants as $variant ) {
3514  $tags["variant-$variant"] = Html::element( 'link', [
3515  'rel' => 'alternate',
3516  'hreflang' => LanguageCode::bcp47( $variant ),
3517  'href' => $this->getTitle()->getLocalURL(
3518  [ 'variant' => $variant ] )
3519  ]
3520  );
3521  }
3522  # x-default link per https://support.google.com/webmasters/answer/189077?hl=en
3523  $tags["variant-x-default"] = Html::element( 'link', [
3524  'rel' => 'alternate',
3525  'hreflang' => 'x-default',
3526  'href' => $this->getTitle()->getLocalURL() ] );
3527  }
3528  }
3529 
3530  # Copyright
3531  if ( $this->copyrightUrl !== null ) {
3532  $copyright = $this->copyrightUrl;
3533  } else {
3534  $copyright = '';
3535  if ( $config->get( 'RightsPage' ) ) {
3536  $copy = Title::newFromText( $config->get( 'RightsPage' ) );
3537 
3538  if ( $copy ) {
3539  $copyright = $copy->getLocalURL();
3540  }
3541  }
3542 
3543  if ( !$copyright && $config->get( 'RightsUrl' ) ) {
3544  $copyright = $config->get( 'RightsUrl' );
3545  }
3546  }
3547 
3548  if ( $copyright ) {
3549  $tags['copyright'] = Html::element( 'link', [
3550  'rel' => 'license',
3551  'href' => $copyright ]
3552  );
3553  }
3554 
3555  # Feeds
3556  if ( $config->get( 'Feed' ) ) {
3557  $feedLinks = [];
3558 
3559  foreach ( $this->getSyndicationLinks() as $format => $link ) {
3560  # Use the page name for the title. In principle, this could
3561  # lead to issues with having the same name for different feeds
3562  # corresponding to the same page, but we can't avoid that at
3563  # this low a level.
3564 
3565  $feedLinks[] = $this->feedLink(
3566  $format,
3567  $link,
3568  # Used messages: 'page-rss-feed' and 'page-atom-feed' (for an easier grep)
3569  $this->msg(
3570  "page-{$format}-feed", $this->getTitle()->getPrefixedText()
3571  )->text()
3572  );
3573  }
3574 
3575  # Recent changes feed should appear on every page (except recentchanges,
3576  # that would be redundant). Put it after the per-page feed to avoid
3577  # changing existing behavior. It's still available, probably via a
3578  # menu in your browser. Some sites might have a different feed they'd
3579  # like to promote instead of the RC feed (maybe like a "Recent New Articles"
3580  # or "Breaking news" one). For this, we see if $wgOverrideSiteFeed is defined.
3581  # If so, use it instead.
3582  $sitename = $config->get( 'Sitename' );
3583  $overrideSiteFeed = $config->get( 'OverrideSiteFeed' );
3584  if ( $overrideSiteFeed ) {
3585  foreach ( $overrideSiteFeed as $type => $feedUrl ) {
3586  // Note, this->feedLink escapes the url.
3587  $feedLinks[] = $this->feedLink(
3588  $type,
3589  $feedUrl,
3590  $this->msg( "site-{$type}-feed", $sitename )->text()
3591  );
3592  }
3593  } elseif ( !$this->getTitle()->isSpecial( 'Recentchanges' ) ) {
3594  $rctitle = SpecialPage::getTitleFor( 'Recentchanges' );
3595  foreach ( $this->getAdvertisedFeedTypes() as $format ) {
3596  $feedLinks[] = $this->feedLink(
3597  $format,
3598  $rctitle->getLocalURL( [ 'feed' => $format ] ),
3599  # For grep: 'site-rss-feed', 'site-atom-feed'
3600  $this->msg( "site-{$format}-feed", $sitename )->text()
3601  );
3602  }
3603  }
3604 
3605  # Allow extensions to change the list pf feeds. This hook is primarily for changing,
3606  # manipulating or removing existing feed tags. If you want to add new feeds, you should
3607  # use OutputPage::addFeedLink() instead.
3608  Hooks::run( 'AfterBuildFeedLinks', [ &$feedLinks ] );
3609 
3610  $tags += $feedLinks;
3611  }
3612 
3613  # Canonical URL
3614  if ( $config->get( 'EnableCanonicalServerLink' ) ) {
3615  if ( $canonicalUrl !== false ) {
3616  $canonicalUrl = wfExpandUrl( $canonicalUrl, PROTO_CANONICAL );
3617  } elseif ( $this->isArticleRelated() ) {
3618  // This affects all requests where "setArticleRelated" is true. This is
3619  // typically all requests that show content (query title, curid, oldid, diff),
3620  // and all wikipage actions (edit, delete, purge, info, history etc.).
3621  // It does not apply to File pages and Special pages.
3622  // 'history' and 'info' actions address page metadata rather than the page
3623  // content itself, so they may not be canonicalized to the view page url.
3624  // TODO: this ought to be better encapsulated in the Action class.
3625  $action = Action::getActionName( $this->getContext() );
3626  if ( in_array( $action, [ 'history', 'info' ] ) ) {
3627  $query = "action={$action}";
3628  } else {
3629  $query = '';
3630  }
3631  $canonicalUrl = $this->getTitle()->getCanonicalURL( $query );
3632  } else {
3633  $reqUrl = $this->getRequest()->getRequestURL();
3634  $canonicalUrl = wfExpandUrl( $reqUrl, PROTO_CANONICAL );
3635  }
3636  }
3637  if ( $canonicalUrl !== false ) {
3638  $tags[] = Html::element( 'link', [
3639  'rel' => 'canonical',
3640  'href' => $canonicalUrl
3641  ] );
3642  }
3643 
3644  // Allow extensions to add, remove and/or otherwise manipulate these links
3645  // If you want only to *add* <head> links, please use the addHeadItem()
3646  // (or addHeadItems() for multiple items) method instead.
3647  // This hook is provided as a last resort for extensions to modify these
3648  // links before the output is sent to client.
3649  Hooks::run( 'OutputPageAfterGetHeadLinksArray', [ &$tags, $this ] );
3650 
3651  return $tags;
3652  }
3653 
3662  private function feedLink( $type, $url, $text ) {
3663  return Html::element( 'link', [
3664  'rel' => 'alternate',
3665  'type' => "application/$type+xml",
3666  'title' => $text,
3667  'href' => $url ]
3668  );
3669  }
3670 
3680  public function addStyle( $style, $media = '', $condition = '', $dir = '' ) {
3681  $options = [];
3682  if ( $media ) {
3683  $options['media'] = $media;
3684  }
3685  if ( $condition ) {
3686  $options['condition'] = $condition;
3687  }
3688  if ( $dir ) {
3689  $options['dir'] = $dir;
3690  }
3691  $this->styles[$style] = $options;
3692  }
3693 
3701  public function addInlineStyle( $style_css, $flip = 'noflip' ) {
3702  if ( $flip === 'flip' && $this->getLanguage()->isRTL() ) {
3703  # If wanted, and the interface is right-to-left, flip the CSS
3704  $style_css = CSSJanus::transform( $style_css, true, false );
3705  }
3706  $this->mInlineStyles .= Html::inlineStyle( $style_css );
3707  }
3708 
3714  protected function buildExemptModules() {
3715  $chunks = [];
3716 
3717  // Requirements:
3718  // - Within modules provided by the software (core, skin, extensions),
3719  // styles from skin stylesheets should be overridden by styles
3720  // from modules dynamically loaded with JavaScript.
3721  // - Styles from site-specific, private, and user modules should override
3722  // both of the above.
3723  //
3724  // The effective order for stylesheets must thus be:
3725  // 1. Page style modules, formatted server-side by ResourceLoaderClientHtml.
3726  // 2. Dynamically-loaded styles, inserted client-side by mw.loader.
3727  // 3. Styles that are site-specific, private or from the user, formatted
3728  // server-side by this function.
3729  //
3730  // The 'ResourceLoaderDynamicStyles' marker helps JavaScript know where
3731  // point #2 is.
3732 
3733  // Add legacy styles added through addStyle()/addInlineStyle() here
3734  $chunks[] = implode( '', $this->buildCssLinksArray() ) . $this->mInlineStyles;
3735 
3736  // Things that go after the ResourceLoaderDynamicStyles marker
3737  $append = [];
3738  $separateReq = [ 'site.styles', 'user.styles' ];
3739  foreach ( $this->rlExemptStyleModules as $group => $moduleNames ) {
3740  if ( $moduleNames ) {
3741  $append[] = $this->makeResourceLoaderLink(
3742  array_diff( $moduleNames, $separateReq ),
3743  ResourceLoaderModule::TYPE_STYLES
3744  );
3745 
3746  foreach ( array_intersect( $moduleNames, $separateReq ) as $name ) {
3747  // These require their own dedicated request in order to support "@import"
3748  // syntax, which is incompatible with concatenation. (T147667, T37562)
3749  $append[] = $this->makeResourceLoaderLink( $name,
3750  ResourceLoaderModule::TYPE_STYLES
3751  );
3752  }
3753  }
3754  }
3755  if ( $append ) {
3756  $chunks[] = Html::element(
3757  'meta',
3758  [ 'name' => 'ResourceLoaderDynamicStyles', 'content' => '' ]
3759  );
3760  $chunks = array_merge( $chunks, $append );
3761  }
3762 
3763  return self::combineWrappedStrings( $chunks );
3764  }
3765 
3769  public function buildCssLinksArray() {
3770  $links = [];
3771 
3772  foreach ( $this->styles as $file => $options ) {
3773  $link = $this->styleLink( $file, $options );
3774  if ( $link ) {
3775  $links[$file] = $link;
3776  }
3777  }
3778  return $links;
3779  }
3780 
3788  protected function styleLink( $style, array $options ) {
3789  if ( isset( $options['dir'] ) && $this->getLanguage()->getDir() != $options['dir'] ) {
3790  return '';
3791  }
3792 
3793  if ( isset( $options['media'] ) ) {
3794  $media = self::transformCssMedia( $options['media'] );
3795  if ( is_null( $media ) ) {
3796  return '';
3797  }
3798  } else {
3799  $media = 'all';
3800  }
3801 
3802  if ( substr( $style, 0, 1 ) == '/' ||
3803  substr( $style, 0, 5 ) == 'http:' ||
3804  substr( $style, 0, 6 ) == 'https:' ) {
3805  $url = $style;
3806  } else {
3807  $config = $this->getConfig();
3808  // Append file hash as query parameter
3810  $config,
3811  $config->get( 'StylePath' ) . '/' . $style
3812  );
3813  }
3814 
3815  $link = Html::linkedStyle( $url, $media );
3816 
3817  if ( isset( $options['condition'] ) ) {
3818  $condition = htmlspecialchars( $options['condition'] );
3819  $link = "<!--[if $condition]>$link<![endif]-->";
3820  }
3821  return $link;
3822  }
3823 
3845  public static function transformResourcePath( Config $config, $path ) {
3846  global $IP;
3847 
3848  $localDir = $IP;
3849  $remotePathPrefix = $config->get( 'ResourceBasePath' );
3850  if ( $remotePathPrefix === '' ) {
3851  // The configured base path is required to be empty string for
3852  // wikis in the domain root
3853  $remotePath = '/';
3854  } else {
3855  $remotePath = $remotePathPrefix;
3856  }
3857  if ( strpos( $path, $remotePath ) !== 0 || substr( $path, 0, 2 ) === '//' ) {
3858  // - Path is outside wgResourceBasePath, ignore.
3859  // - Path is protocol-relative. Fixes T155310. Not supported by RelPath lib.
3860  return $path;
3861  }
3862  // For files in resources, extensions/ or skins/, ResourceBasePath is preferred here.
3863  // For other misc files in $IP, we'll fallback to that as well. There is, however, a fourth
3864  // supported dir/path pair in the configuration (wgUploadDirectory, wgUploadPath)
3865  // which is not expected to be in wgResourceBasePath on CDNs. (T155146)
3866  $uploadPath = $config->get( 'UploadPath' );
3867  if ( strpos( $path, $uploadPath ) === 0 ) {
3868  $localDir = $config->get( 'UploadDirectory' );
3869  $remotePathPrefix = $remotePath = $uploadPath;
3870  }
3871 
3872  $path = RelPath::getRelativePath( $path, $remotePath );
3873  return self::transformFilePath( $remotePathPrefix, $localDir, $path );
3874  }
3875 
3887  public static function transformFilePath( $remotePathPrefix, $localPath, $file ) {
3888  $hash = md5_file( "$localPath/$file" );
3889  if ( $hash === false ) {
3890  wfLogWarning( __METHOD__ . ": Failed to hash $localPath/$file" );
3891  $hash = '';
3892  }
3893  return "$remotePathPrefix/$file?" . substr( $hash, 0, 5 );
3894  }
3895 
3903  public static function transformCssMedia( $media ) {
3904  global $wgRequest;
3905 
3906  // https://www.w3.org/TR/css3-mediaqueries/#syntax
3907  $screenMediaQueryRegex = '/^(?:only\s+)?screen\b/i';
3908 
3909  // Switch in on-screen display for media testing
3910  $switches = [
3911  'printable' => 'print',
3912  'handheld' => 'handheld',
3913  ];
3914  foreach ( $switches as $switch => $targetMedia ) {
3915  if ( $wgRequest->getBool( $switch ) ) {
3916  if ( $media == $targetMedia ) {
3917  $media = '';
3918  } elseif ( preg_match( $screenMediaQueryRegex, $media ) === 1 ) {
3919  /* This regex will not attempt to understand a comma-separated media_query_list
3920  *
3921  * Example supported values for $media:
3922  * 'screen', 'only screen', 'screen and (min-width: 982px)' ),
3923  * Example NOT supported value for $media:
3924  * '3d-glasses, screen, print and resolution > 90dpi'
3925  *
3926  * If it's a print request, we never want any kind of screen stylesheets
3927  * If it's a handheld request (currently the only other choice with a switch),
3928  * we don't want simple 'screen' but we might want screen queries that
3929  * have a max-width or something, so we'll pass all others on and let the
3930  * client do the query.
3931  */
3932  if ( $targetMedia == 'print' || $media == 'screen' ) {
3933  return null;
3934  }
3935  }
3936  }
3937  }
3938 
3939  return $media;
3940  }
3941 
3948  public function addWikiMsg( /*...*/ ) {
3949  $args = func_get_args();
3950  $name = array_shift( $args );
3951  $this->addWikiMsgArray( $name, $args );
3952  }
3953 
3962  public function addWikiMsgArray( $name, $args ) {
3963  $this->addHTML( $this->msg( $name, $args )->parseAsBlock() );
3964  }
3965 
3991  public function wrapWikiMsg( $wrap /*, ...*/ ) {
3992  $msgSpecs = func_get_args();
3993  array_shift( $msgSpecs );
3994  $msgSpecs = array_values( $msgSpecs );
3995  $s = $wrap;
3996  foreach ( $msgSpecs as $n => $spec ) {
3997  if ( is_array( $spec ) ) {
3998  $args = $spec;
3999  $name = array_shift( $args );
4000  } else {
4001  $args = [];
4002  $name = $spec;
4003  }
4004  $s = str_replace( '$' . ( $n + 1 ), $this->msg( $name, $args )->plain(), $s );
4005  }
4006  $this->addWikiTextAsInterface( $s );
4007  }
4008 
4014  public function isTOCEnabled() {
4015  return $this->mEnableTOC;
4016  }
4017 
4025  public static function setupOOUI( $skinName = 'default', $dir = 'ltr' ) {
4027  $theme = $themes[$skinName] ?? $themes['default'];
4028  // For example, 'OOUI\WikimediaUITheme'.
4029  $themeClass = "OOUI\\{$theme}Theme";
4030  OOUI\Theme::setSingleton( new $themeClass() );
4031  OOUI\Element::setDefaultDir( $dir );
4032  }
4033 
4040  public function enableOOUI() {
4042  strtolower( $this->getSkin()->getSkinName() ),
4043  $this->getLanguage()->getDir()
4044  );
4045  $this->addModuleStyles( [
4046  'oojs-ui-core.styles',
4047  'oojs-ui.styles.indicators',
4048  'mediawiki.widgets.styles',
4049  'oojs-ui-core.icons',
4050  ] );
4051  }
4052 
4062  public function getCSPNonce() {
4064  return false;
4065  }
4066  if ( $this->CSPNonce === null ) {
4067  // XXX It might be expensive to generate randomness
4068  // on every request, on Windows.
4069  $rand = random_bytes( 15 );
4070  $this->CSPNonce = base64_encode( $rand );
4071  }
4072  return $this->CSPNonce;
4073  }
4074 
4075 }
$filter
$filter
Definition: profileinfo.php:344
Action\getActionName
static getActionName(IContextSource $context)
Get the action that will be executed, not necessarily the one passed passed through the "action" requ...
Definition: Action.php:123
OutputPage\preventClickjacking
preventClickjacking( $enable=true)
Set a flag which will cause an X-Frame-Options header appropriate for edit pages to be sent.
Definition: OutputPage.php:2312
OutputPage\output
output( $return=false)
Finally, all the text has been munged and accumulated into the object, let's actually output it:
Definition: OutputPage.php:2476
OutputPage\$mCategories
array $mCategories
Definition: OutputPage.php:119
ParserOutput\getEnableOOUI
getEnableOOUI()
Definition: ParserOutput.php:636
OutputPage\addBacklinkSubtitle
addBacklinkSubtitle(Title $title, $query=[])
Add a subtitle containing a backlink to a page.
Definition: OutputPage.php:1049
OutputPage\$mLastModified
string $mLastModified
Used for sending cache control.
Definition: OutputPage.php:113
ParserOptions
Set options of the Parser.
Definition: ParserOptions.php:42
OutputPage\getCategoryLinks
getCategoryLinks()
Get the list of category links, in a 2-D array with the following format: $arr[$type][] = $link,...
Definition: OutputPage.php:1408
OutputPage\addMeta
addMeta( $name, $val)
Add a new "<meta>" tag To add an http-equiv meta tag, precede the name with "http:".
Definition: OutputPage.php:388
ContextSource\$context
IContextSource $context
Definition: ContextSource.php:33
ContextSource\getConfig
getConfig()
Definition: ContextSource.php:63
OutputPage\getTarget
getTarget()
Definition: OutputPage.php:575
ResourceLoaderContext
Context object that contains information about the state of a specific ResourceLoader web request.
Definition: ResourceLoaderContext.php:33
OutputPage\getSubtitle
getSubtitle()
Get the subtitle.
Definition: OutputPage.php:1065
OutputPage\parseAsInterface
parseAsInterface( $text, $linestart=true)
Parse wikitext in the user interface language and return the HTML.
Definition: OutputPage.php:2031
FauxRequest
WebRequest clone which takes values from a provided array.
Definition: FauxRequest.php:33
OutputPage\enableClientCache
enableClientCache( $state)
Use enableClientCache(false) to force it to send nocache headers.
Definition: OutputPage.php:2183
Title\newFromText
static newFromText( $text, $defaultNamespace=NS_MAIN)
Create a new Title from text, such as what one would find in a link.
Definition: Title.php:316
OutputPage\addWikiMsg
addWikiMsg()
Add a wikitext-formatted message to the output.
Definition: OutputPage.php:3948
ContextSource\getContext
getContext()
Get the base IContextSource object.
Definition: ContextSource.php:40
OutputPage\getLanguageLinks
getLanguageLinks()
Get the list of language links.
Definition: OutputPage.php:1301
OutputPage\buildBacklinkSubtitle
static buildBacklinkSubtitle(Title $title, $query=[])
Build message object for a subtitle containing a backlink to a page.
Definition: OutputPage.php:1034
HtmlArmor
Marks HTML that shouldn't be escaped.
Definition: HtmlArmor.php:28
ResourceLoaderClientHtml
Load and configure a ResourceLoader client on an HTML page.
Definition: ResourceLoaderClientHtml.php:30
OutputPage\reduceAllowedModules
reduceAllowedModules( $type, $level)
Limit the highest level of CSS/JS untrustworthiness allowed.
Definition: OutputPage.php:1544
PROTO_CANONICAL
const PROTO_CANONICAL
Definition: Defines.php:212
OutputPage\$mModuleStyles
array $mModuleStyles
Definition: OutputPage.php:157
OutputPage\addSubtitle
addSubtitle( $str)
Add $str to the subtitle.
Definition: OutputPage.php:1018
OutputPage\addScriptFile
addScriptFile( $file, $unused=null)
Add a JavaScript file to be loaded as <script> on this page.
Definition: OutputPage.php:462
OutputPage\addAcceptLanguage
addAcceptLanguage()
T23672: Add Accept-Language to Vary header if there's no 'variant' parameter in GET.
Definition: OutputPage.php:2290
ParserOutput
Definition: ParserOutput.php:25
Article\formatRobotPolicy
static formatRobotPolicy( $policy)
Converts a String robot policy into an associative array, to allow merging of several policies using ...
Definition: Article.php:1047
OutputPage\getJSVars
getJSVars()
Get an array containing the variables to be set in mw.config in JavaScript.
Definition: OutputPage.php:3206
ResourceLoader\makeConfigSetScript
static makeConfigSetScript(array $configuration)
Returns JS code which will set the MediaWiki configuration array to the given value.
Definition: ResourceLoader.php:1562
OutputPage\getRlClientContext
getRlClientContext()
Definition: OutputPage.php:2874
OutputPage\getDisplayTitle
getDisplayTitle()
Returns page display title.
Definition: OutputPage.php:969
OutputPage\$mRedirectedFrom
Title $mRedirectedFrom
If the current page was reached through a redirect, $mRedirectedFrom contains the Title of the redire...
Definition: OutputPage.php:283
Sanitizer\stripAllTags
static stripAllTags( $html)
Take a fragment of (potentially invalid) HTML and return a version with any tags removed,...
Definition: Sanitizer.php:2045
OutputPage\setTitle
setTitle(Title $t)
Set the Title object to use.
Definition: OutputPage.php:997
OutputPage\$mVaryHeader
array $mVaryHeader
Headers that cause the cache to vary.
Definition: OutputPage.php:273
OutputPage\showsCopyright
showsCopyright()
Return whether the standard copyright should be shown for the current page.
Definition: OutputPage.php:1272
LinkBatch
Class representing a list of titles The execute() method checks them all for existence and adds them ...
Definition: LinkBatch.php:34
OutputPage\addLink
addLink(array $linkarr)
Add a new <link> tag to the page header.
Definition: OutputPage.php:409
OutputPage\addContentOverride
addContentOverride(LinkTarget $target, Content $content)
Add a mapping from a LinkTarget to a Content, for things like page preview.
Definition: OutputPage.php:595
$response
$response
Definition: opensearch_desc.php:38
OutputPage\addCategoryLinksToLBAndGetResult
addCategoryLinksToLBAndGetResult(array $categories)
Definition: OutputPage.php:1359
OutputPage\hasHeadItem
hasHeadItem( $name)
Check if the header item $name is already set.
Definition: OutputPage.php:660
MediaWiki\MediaWikiServices
MediaWikiServices is the service locator for the application scope of MediaWiki.
Definition: MediaWikiServices.php:117
OutputPage\$CSPNonce
string $CSPNonce
The nonce for Content-Security-Policy.
Definition: OutputPage.php:322
$lang
if(!isset( $args[0])) $lang
Definition: testCompression.php:33
OutputPage\getMetaTags
getMetaTags()
Returns the current <meta> tags.
Definition: OutputPage.php:398
OutputPage\addLanguageLinks
addLanguageLinks(array $newLinkArray)
Add new language links.
Definition: OutputPage.php:1282
OutputPage\addLinkHeader
addLinkHeader( $header)
Add an HTTP Link: header.
Definition: OutputPage.php:2266
OutputPage\addModuleStyles
addModuleStyles( $modules)
Load the styles of one or more ResourceLoader modules on this page.
Definition: OutputPage.php:568
OutputPage\$mNewSectionLink
bool $mNewSectionLink
Definition: OutputPage.php:222
wfSetVar
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...
Definition: GlobalFunctions.php:1587
OutputPage\isArticleRelated
isArticleRelated()
Return whether this page is related an article on the wiki.
Definition: OutputPage.php:1250
OutputPage\setArticleBodyOnly
setArticleBodyOnly( $only)
Set whether the output should only contain the body of the article, without any skin,...
Definition: OutputPage.php:681
OutputPage\getFrameOptions
getFrameOptions()
Get the X-Frame-Options header value (without the name part), or false if there isn't one.
Definition: OutputPage.php:2342
OutputPage\__construct
__construct(IContextSource $context)
Constructor for OutputPage.
Definition: OutputPage.php:335
ResourceLoader\makeInlineScript
static makeInlineScript( $script, $nonce=null)
Returns an HTML script tag that runs given JS code after startup and base modules.
Definition: ResourceLoader.php:1535
OutputPage\$mRedirectCode
string $mRedirectCode
Definition: OutputPage.php:181
OutputPage\getRevisionId
getRevisionId()
Get the displayed revision ID.
Definition: OutputPage.php:1663
OutputPage\clearHTML
clearHTML()
Clear the body HTML.
Definition: OutputPage.php:1582
OutputPage\addScript
addScript( $script)
Add raw HTML to the list of scripts (including <script> tag, etc.) Internal use only.
Definition: OutputPage.php:450
ParserOutput\getModules
getModules()
Definition: ParserOutput.php:589
wfTimestamp
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
Definition: GlobalFunctions.php:1849
$wgVersion
$wgVersion
MediaWiki version number.
Definition: DefaultSettings.php:76
OutputPage\returnToMain
returnToMain( $unused=null, $returnto=null, $returntoquery=null)
Add a "return to" link pointing to a specified title, or the title indicated in the request,...
Definition: OutputPage.php:2847
OutputPage\buildCssLinksArray
buildCssLinksArray()
Definition: OutputPage.php:3769
$resourceLoader
$resourceLoader
Definition: load.php:44
OutputPage\addParserOutputMetadata
addParserOutputMetadata(ParserOutput $parserOutput)
Add all metadata associated with a ParserOutput object, but without the actual HTML.
Definition: OutputPage.php:1852
OutputPage\combineWrappedStrings
static combineWrappedStrings(array $chunks)
Combine WrappedString chunks and filter out empty ones.
Definition: OutputPage.php:3139
Sanitizer\mergeAttributes
static mergeAttributes( $a, $b)
Merge two sets of HTML attributes.
Definition: Sanitizer.php:936
OutputPage\$mHideNewSectionLink
bool $mHideNewSectionLink
Definition: OutputPage.php:225
OutputPage\$contentOverrides
array $contentOverrides
Map Title to Content.
Definition: OutputPage.php:309
OutputPage\$mBodytext
string $mBodytext
Contains all of the "<body>" content.
Definition: OutputPage.php:74
OutputPage\getOriginTrials
getOriginTrials()
Get the Origin-Trial header values.
Definition: OutputPage.php:2358
ParserOutput\getJsConfigVars
getJsConfigVars()
Definition: ParserOutput.php:601
wfUrlencode
wfUrlencode( $s)
We want some things to be included as literal characters in our title URLs for prettiness,...
Definition: GlobalFunctions.php:309
OutputPage\getBottomScripts
getBottomScripts()
JS stuff to put at the bottom of the <body>.
Definition: OutputPage.php:3151
ParserOptions\newFromAnon
static newFromAnon()
Get a ParserOptions object for an anonymous user.
Definition: ParserOptions.php:1013
OutputPage\addHeadItems
addHeadItems( $values)
Add one or more head items to the output.
Definition: OutputPage.php:650
OutputPage\getModuleStyles
getModuleStyles( $filter=false, $position=null)
Get the list of style-only modules to load on this page.
Definition: OutputPage.php:553
OutputPage\getFeaturePolicyReportOnly
getFeaturePolicyReportOnly()
Definition: OutputPage.php:2388
$file
if(PHP_SAPI !='cli-server') if(!isset( $_SERVER['SCRIPT_FILENAME'])) $file
Item class for a filearchive table row.
Definition: router.php:42
Html\htmlHeader
static htmlHeader(array $attribs=[])
Constructs the opening html-tag with necessary doctypes depending on global variables.
Definition: Html.php:965
Skin\addToBodyAttributes
addToBodyAttributes( $out, &$bodyAttrs)
This will be called by OutputPage::headElement when it is creating the "<body>" tag,...
Definition: Skin.php:497
OutputPage\versionRequired
versionRequired( $version)
Display an error page indicating that a given version of MediaWiki is required to use it.
Definition: OutputPage.php:2746
ResourceLoaderClientHtml\setExemptStates
setExemptStates(array $states)
Set state of special modules that are handled by the caller manually.
Definition: ResourceLoaderClientHtml.php:109
wfMessage
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
Definition: GlobalFunctions.php:1263
OutputPage\parseInline
parseInline( $text, $linestart=true, $interface=false)
Parse wikitext, strip paragraph wrapper, and return the HTML.
Definition: OutputPage.php:2073
$s
$s
Definition: mergeMessageFileList.php:185
OutputPage\parserOptions
parserOptions( $options=null)
Get/set the ParserOptions object to use for wikitext parsing.
Definition: OutputPage.php:1603
SpecialPage\getTitleFor
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,...
Definition: SpecialPage.php:83
Sanitizer\escapeClass
static escapeClass( $class)
Given a value, escape it so that it can be used as a CSS class and return it.
Definition: Sanitizer.php:1422
OutputPage\getFileVersion
getFileVersion()
Get the displayed file version.
Definition: OutputPage.php:1717
OutputPage\getSyndicationLinks
getSyndicationLinks()
Return URLs for each supported syndication format for this page.
Definition: OutputPage.php:1195
ContextSource\canUseWikiPage
canUseWikiPage()
Check whether a WikiPage object can be get with getWikiPage().
Definition: ContextSource.php:91
wfLogWarning
wfLogWarning( $msg, $callerOffset=1, $level=E_USER_WARNING)
Send a warning as a PHP error and the debug log.
Definition: GlobalFunctions.php:1078
ContextSource\getRequest
getRequest()
Definition: ContextSource.php:71
Title\newMainPage
static newMainPage(MessageLocalizer $localizer=null)
Create a new Title for the Main Page.
Definition: Title.php:649
IExpiringStore\TTL_MINUTE
const TTL_MINUTE
Definition: IExpiringStore.php:33
OutputPage\$mRevisionId
int $mRevisionId
To include the variable {{REVISIONID}}.
Definition: OutputPage.php:247
OutputPage\getRedirect
getRedirect()
Get the URL to redirect to, or an empty string if not redirect URL set.
Definition: OutputPage.php:356
OutputPage\setCanonicalUrl
setCanonicalUrl( $url)
Set the URL to be used for the <link rel=canonical>>.
Definition: OutputPage.php:428
$res
$res
Definition: testCompression.php:52
ParserOutput\getHeadItems
getHeadItems()
Definition: ParserOutput.php:585
ContextSource\getUser
getUser()
Definition: ContextSource.php:120
ContextSource\getTitle
getTitle()
Definition: ContextSource.php:79
OutputPage\$mLinktags
array $mLinktags
Definition: OutputPage.php:51
OutputPage\$mIndexPolicy
$mIndexPolicy
Definition: OutputPage.php:265
Skin\getHtmlElementAttributes
getHtmlElementAttributes()
Return values for <html> element.
Definition: Skin.php:481
LinkBatch\setArray
setArray( $array)
Set the link list to a given 2-d array First key is the namespace, second is the DB key,...
Definition: LinkBatch.php:100
OutputPage\setIndicators
setIndicators(array $indicators)
Add an array of indicators, with their identifiers as array keys and HTML contents as values.
Definition: OutputPage.php:1444
LinkCache\getSelectFields
static getSelectFields()
Fields that LinkCache needs to select.
Definition: LinkCache.php:219
OutputPage\addHTML
addHTML( $text)
Append $text to the body HTML.
Definition: OutputPage.php:1562
OutputPage\getReportTo
getReportTo()
Definition: OutputPage.php:2364
OutputPage\addHeadItem
addHeadItem( $name, $value)
Add or replace a head item to the output.
Definition: OutputPage.php:640
OutputPage\addContentOverrideCallback
addContentOverrideCallback(callable $callback)
Add a callback for mapping from a Title to a Content object, for things like page preview.
Definition: OutputPage.php:615
OutputPage\getRevisionTimestamp
getRevisionTimestamp()
Get the timestamp of displayed revision.
Definition: OutputPage.php:1694
OutputPage\addWikiMsgArray
addWikiMsgArray( $name, $args)
Add a wikitext-formatted message to the output.
Definition: OutputPage.php:3962
OutputPage\transformCssMedia
static transformCssMedia( $media)
Transform "media" attribute based on request parameters.
Definition: OutputPage.php:3903
OutputPage\setLastModified
setLastModified( $timestamp)
Override the last modified timestamp.
Definition: OutputPage.php:829
$dbr
$dbr
Definition: testCompression.php:50
ResourceLoaderClientHtml\setConfig
setConfig(array $vars)
Set mw.config variables.
Definition: ResourceLoaderClientHtml.php:78
ContextSource\getLanguage
getLanguage()
Definition: ContextSource.php:128
OutputPage\$mImageTimeKeys
array $mImageTimeKeys
Definition: OutputPage.php:178
OutputPage\showPermissionsErrorPage
showPermissionsErrorPage(array $errors, $action=null)
Output a standard permission error page.
Definition: OutputPage.php:2661
wfAppendQuery
wfAppendQuery( $url, $query)
Append a query string to an existing URL, which may or may not already have query string parameters a...
Definition: GlobalFunctions.php:439
ParserOutput\getModuleStyles
getModuleStyles()
Definition: ParserOutput.php:593
OutputPage\getLinkTags
getLinkTags()
Returns the current <link> tags.
Definition: OutputPage.php:419
OutputPage\forceHideNewSectionLink
forceHideNewSectionLink()
Forcibly hide the new section link?
Definition: OutputPage.php:1116
Html\closeElement
static closeElement( $element)
Returns "</$element>".
Definition: Html.php:315
Xml\encodeJsCall
static encodeJsCall( $name, $args, $pretty=false)
Create a call to a JavaScript function.
Definition: Xml.php:677
OutputPage\$rlClientContext
ResourceLoaderContext $rlClientContext
Definition: OutputPage.php:166
ContentSecurityPolicy\sendHeaders
static sendHeaders(IContextSource $context)
Send CSP headers based on wiki config.
Definition: ContentSecurityPolicy.php:73
Html\isXmlMimeType
static isXmlMimeType( $mimetype)
Determines if the given MIME type is xml.
Definition: Html.php:1003
OutputPage\setArticleRelated
setArticleRelated( $newVal)
Set whether this page is related an article on the wiki Setting false will cause the change of "artic...
Definition: OutputPage.php:1238
OutputPage\addElement
addElement( $element, array $attribs=[], $contents='')
Shortcut for adding an Html::element via addHTML.
Definition: OutputPage.php:1575
OutputPage\addParserOutputContent
addParserOutputContent(ParserOutput $parserOutput, $poOptions=[])
Add the HTML and enhancements for it (like ResourceLoader modules) associated with a ParserOutput obj...
Definition: OutputPage.php:1928
Config
Interface for configuration instances.
Definition: Config.php:28
NS_SPECIAL
const NS_SPECIAL
Definition: Defines.php:58
MediaWiki\Linker\LinkTarget\getNamespace
getNamespace()
Get the namespace index.
OutputPage\userCanEditOrCreate
userCanEditOrCreate(User $user, LinkTarget $title)
Definition: OutputPage.php:3373
File
Implements some public methods and some protected utility functions which are required by multiple ch...
Definition: File.php:61
ParserOutput\getLimitReportJSData
getLimitReportJSData()
Definition: ParserOutput.php:632
Html\linkedScript
static linkedScript( $url, $nonce=null)
Output a "<script>" tag linking to the given URL, e.g., "<script src=foo.js></script>".
Definition: Html.php:596
OutputPage\feedLink
feedLink( $type, $url, $text)
Generate a "<link rel/>" for a feed.
Definition: OutputPage.php:3662
OutputPage\addWikiTextAsInterface
addWikiTextAsInterface( $text, $linestart=true, Title $title=null)
Convert wikitext in the user interface language to HTML and add it to the buffer.
Definition: OutputPage.php:1757
MWException
MediaWiki exception.
Definition: MWException.php:26
OutputPage\getModules
getModules( $filter=false, $position=null, $param='mModules', $type=ResourceLoaderModule::TYPE_COMBINED)
Get the list of modules to include on this page.
Definition: OutputPage.php:528
OutputPage\addStyle
addStyle( $style, $media='', $condition='', $dir='')
Add a local or specified stylesheet, with the given media options.
Definition: OutputPage.php:3680
OutputPage\sendCacheControl
sendCacheControl()
Send cache control HTTP headers.
Definition: OutputPage.php:2398
wfDeprecated
wfDeprecated( $function, $version=false, $component=false, $callerOffset=2)
Throws a warning that $function is deprecated.
Definition: GlobalFunctions.php:1044
OutputPage\$mCdnMaxageLimit
int $mCdnMaxageLimit
Upper limit on mCdnMaxage.
Definition: OutputPage.php:237
OutputPage\$mTemplateIds
array $mTemplateIds
Definition: OutputPage.php:175
wfScript
wfScript( $script='index')
Get the path to a specified script file, respecting file extensions; this is a wrapper around $wgScri...
Definition: GlobalFunctions.php:2622
Wikimedia\Rdbms\IResultWrapper
Result wrapper for grabbing data queried from an IDatabase object.
Definition: IResultWrapper.php:24
ResourceLoaderWikiModule\preloadTitleInfo
static preloadTitleInfo(ResourceLoaderContext $context, IDatabase $db, array $moduleNames)
Definition: ResourceLoaderWikiModule.php:450
OutputPage\styleLink
styleLink( $style, array $options)
Generate <link> tags for stylesheets.
Definition: OutputPage.php:3788
OutputPage\$mEnableTOC
bool $mEnableTOC
Whether parser output contains a table of contents.
Definition: OutputPage.php:298
Config\get
get( $name)
Get a configuration variable such as "Sitename" or "UploadMaintenance.".
OutputPage\$mSubtitle
array $mSubtitle
Contains the page subtitle.
Definition: OutputPage.php:101
OutputPage\setFileVersion
setFileVersion( $file)
Set the displayed file version.
Definition: OutputPage.php:1704
wfGetDB
wfGetDB( $db, $groups=[], $wiki=false)
Get a Database object.
Definition: GlobalFunctions.php:2555
OutputPage\getLinkHeader
getLinkHeader()
Return a Link: header.
Definition: OutputPage.php:2275
OutputPage\getResourceLoader
getResourceLoader()
Get a ResourceLoader object associated with this OutputPage.
Definition: OutputPage.php:3104
OutputPage\isTOCEnabled
isTOCEnabled()
Whether the output has a table of contents.
Definition: OutputPage.php:4014
ContextSource
The simplest way of implementing IContextSource is to hold a RequestContext as a member variable and ...
Definition: ContextSource.php:29
ContextSource\getWikiPage
getWikiPage()
Get the WikiPage object.
Definition: ContextSource.php:104
OutputPage\setFeedAppendQuery
setFeedAppendQuery( $val)
Add default feeds to the page header This is mainly kept for backward compatibility,...
Definition: OutputPage.php:1159
OutputPage\setDisplayTitle
setDisplayTitle( $html)
Same as page title but only contains name of the page, not any other text.
Definition: OutputPage.php:957
$modules
$modules
Definition: HTMLFormElement.php:13
OutputPage\isDisabled
isDisabled()
Return whether the output will be completely disabled.
Definition: OutputPage.php:1098
OutputPage\setRevisionId
setRevisionId( $revid)
Set the revision ID which will be seen by the wiki text parser for things such as embedded {{REVISION...
Definition: OutputPage.php:1653
OutputPage\setArticleFlag
setArticleFlag( $newVal)
Set whether the displayed content is related to the source of the corresponding article on the wiki S...
Definition: OutputPage.php:1215
PROTO_CURRENT
const PROTO_CURRENT
Definition: Defines.php:211
OutputPage\disallowUserJs
disallowUserJs()
Do not allow scripts which can be modified by wiki users to load on this page; only allow scripts bun...
Definition: OutputPage.php:1502
ContextSource\getSkin
getSkin()
Definition: ContextSource.php:136
OutputPage\setSubtitle
setSubtitle( $str)
Replace the subtitle with $str.
Definition: OutputPage.php:1008
OutputPage\$mInlineStyles
string $mInlineStyles
Inline CSS styles.
Definition: OutputPage.php:139
wfCgiToArray
wfCgiToArray( $query)
This is the logical opposite of wfArrayToCgi(): it accepts a query string as its argument and returns...
Definition: GlobalFunctions.php:392
OutputPage\getVaryHeader
getVaryHeader()
Return a Vary: header on which to vary caches.
Definition: OutputPage.php:2249
OutputPage\addModules
addModules( $modules)
Load one or more ResourceLoader modules on this page.
Definition: OutputPage.php:542
OutputPage\showLagWarning
showLagWarning( $lag)
Show a warning about replica DB lag.
Definition: OutputPage.php:2799
$title
$title
Definition: testCompression.php:34
OutputPage\getCacheVaryCookies
getCacheVaryCookies()
Get the list of cookie names that will influence the cache.
Definition: OutputPage.php:2192
OutputPage\setCopyrightUrl
setCopyrightUrl( $url)
Set the copyright URL to send with the output.
Definition: OutputPage.php:368
OutputPage\$mFollowPolicy
$mFollowPolicy
Definition: OutputPage.php:266
OutputPage\$rlClient
ResourceLoaderClientHtml $rlClient
Definition: OutputPage.php:163
DB_REPLICA
const DB_REPLICA
Definition: defines.php:25
NS_CATEGORY
const NS_CATEGORY
Definition: Defines.php:83
OutputPage\addBodyClasses
addBodyClasses( $classes)
Add a class to the <body> element.
Definition: OutputPage.php:670
ParserOutput\getIndicators
getIndicators()
Definition: ParserOutput.php:541
ResourceLoaderModule\getOrigin
getOrigin()
Get this module's origin.
Definition: ResourceLoaderModule.php:123
wfDebug
wfDebug( $text, $dest='all', array $context=[])
Sends a line to the debug log if enabled or, optionally, to a comment in output.
Definition: GlobalFunctions.php:913
ContextSource\setContext
setContext(IContextSource $context)
Definition: ContextSource.php:55
OutputPage\isArticle
isArticle()
Return whether the content displayed page is related to the source of the corresponding article on th...
Definition: OutputPage.php:1228
OutputPage
This is one of the Core classes and should be read at least once by any new developers.
Definition: OutputPage.php:46
ParserOutput\getLanguageLinks
& getLanguageLinks()
Definition: ParserOutput.php:521
OutputPage\showErrorPage
showErrorPage( $title, $msg, $params=[])
Output a standard error page.
Definition: OutputPage.php:2634
OutputPage\addParserOutputText
addParserOutputText(ParserOutput $parserOutput, $poOptions=[])
Add the HTML associated with a ParserOutput object, without any metadata.
Definition: OutputPage.php:1944
OutputPage\getCSPNonce
getCSPNonce()
Get (and set if not yet set) the CSP nonce.
Definition: OutputPage.php:4062
OutputPage\$mParserOptions
ParserOptions $mParserOptions
lazy initialised, use parserOptions()
Definition: OutputPage.php:206
OutputPage\$mContainsNewMagic
int $mContainsNewMagic
Definition: OutputPage.php:200
JavaScriptContent
Content for JavaScript pages.
Definition: JavaScriptContent.php:35
OutputPage\$limitReportJSData
array $limitReportJSData
Profiling data.
Definition: OutputPage.php:306
OutputPage\addInlineScript
addInlineScript( $script)
Add a self-contained script tag with the given contents Internal use only.
Definition: OutputPage.php:472
ParserOutput\getTemplateIds
& getTemplateIds()
Definition: ParserOutput.php:561
OutputPage\getArticleBodyOnly
getArticleBodyOnly()
Return whether the output will contain only the body of the article.
Definition: OutputPage.php:690
OutputPage\getPreventClickjacking
getPreventClickjacking()
Get the prevent-clickjacking flag.
Definition: OutputPage.php:2331
ParserOutput\getTOCHTML
getTOCHTML()
Definition: ParserOutput.php:617
OutputPage\$mModules
array $mModules
Definition: OutputPage.php:154
OutputPage\addWikiTextAsContent
addWikiTextAsContent( $text, $linestart=true, Title $title=null)
Convert wikitext in the page content language to HTML and add it to the buffer.
Definition: OutputPage.php:1807
OutputPage\getCanonicalUrl
getCanonicalUrl()
Returns the URL to be used for the <link rel=canonical>> if one is set.
Definition: OutputPage.php:439
OutputPage\setStatusCode
setStatusCode( $statusCode)
Set the HTTP status code to send with the output.
Definition: OutputPage.php:377
OutputPage\$mRedirect
string $mRedirect
Definition: OutputPage.php:104
Html\inlineStyle
static inlineStyle( $contents, $media='all', $attribs=[])
Output a "<style>" tag with the given contents for the given media type (if any).
Definition: Html.php:619
ContextSource\msg
msg( $key,... $params)
Get a Message object with context set Parameters are the same as wfMessage()
Definition: ContextSource.php:168
OutputPage\$mIsArticle
bool $mIsArticle
Is the displayed content related to the source of the corresponding wiki article.
Definition: OutputPage.php:83
OutputPage\haveCacheVaryCookies
haveCacheVaryCookies()
Check if the request has a cache-varying cookie header If it does, it's very important that we don't ...
Definition: OutputPage.php:2213
OutputPage\getPageTitle
getPageTitle()
Return the "page title", i.e.
Definition: OutputPage.php:946
OutputPage\disable
disable()
Disable output completely, i.e.
Definition: OutputPage.php:1089
OutputPage\setIndexPolicy
setIndexPolicy( $policy)
Set the index policy for the page, but leave the follow policy un- touched.
Definition: OutputPage.php:859
Title\makeTitleSafe
static makeTitleSafe( $ns, $title, $fragment='', $interwiki='')
Create a new Title from a namespace index and a DB key.
Definition: Title.php:613
OutputPage\$mResourceLoader
ResourceLoader $mResourceLoader
Definition: OutputPage.php:160
ParserOutput\getNewSection
getNewSection()
Definition: ParserOutput.php:720
Hooks\runWithoutAbort
static runWithoutAbort( $event, array $args=[], $deprecatedVersion=null)
Call hook functions defined in Hooks::register and $wgHooks.
Definition: Hooks.php:231
$content
$content
Definition: router.php:78
Skin\getPageClasses
getPageClasses( $title)
TODO: document.
Definition: Skin.php:443
OutputPage\addCategoryLinks
addCategoryLinks(array $categories)
Add an array of categories, with names in the keys.
Definition: OutputPage.php:1310
OutputPage\setRevisionTimestamp
setRevisionTimestamp( $timestamp)
Set the timestamp of the revision which will be displayed.
Definition: OutputPage.php:1684
OutputPage\getHeadItemsArray
getHeadItemsArray()
Get an array of head items.
Definition: OutputPage.php:624
wfClearOutputBuffers
wfClearOutputBuffers()
More legible than passing a 'false' parameter to wfResetOutputBuffers():
Definition: GlobalFunctions.php:1728
OutputPage\addReturnTo
addReturnTo( $title, array $query=[], $text=null, $options=[])
Add a "return to" link pointing to a specified title.
Definition: OutputPage.php:2831
OutputPage\buildExemptModules
buildExemptModules()
Build exempt modules and legacy non-ResourceLoader styles.
Definition: OutputPage.php:3714
OutputPage\$copyrightUrl
string null $copyrightUrl
The URL to send in a <link> element with rel=license.
Definition: OutputPage.php:303
OutputPage\getProperty
getProperty( $name)
Get an additional output property.
Definition: OutputPage.php:712
ParserOptions\newFromContext
static newFromContext(IContextSource $context)
Get a ParserOptions object from a IContextSource object.
Definition: ParserOptions.php:1052
Html\inlineScript
static inlineScript( $contents, $nonce=null)
Output an HTML script tag with the given contents.
Definition: Html.php:572
$header
$header
Definition: updateCredits.php:41
OutputPage\addHelpLink
addHelpLink( $to, $overrideBaseUrl=false)
Adds help link with an icon via page indicators.
Definition: OutputPage.php:1470
OutputPage\formatPermissionsErrorMessage
formatPermissionsErrorMessage(array $errors, $action=null)
Format a list of error messages.
Definition: OutputPage.php:2760
ParserOutput\getOutputHooks
getOutputHooks()
Definition: ParserOutput.php:605
OutputPage\$mIndicators
array $mIndicators
Definition: OutputPage.php:125
OutputPage\setTarget
setTarget( $target)
Sets ResourceLoader target for load.php links.
Definition: OutputPage.php:584
ParserOutput\getHideNewSection
getHideNewSection()
Definition: ParserOutput.php:716
MediaWiki\Session\SessionManager
This serves as the entry point to the MediaWiki session handling system.
Definition: SessionManager.php:50
OutputPage\$contentOverrideCallbacks
callable[] $contentOverrideCallbacks
Definition: OutputPage.php:312
OutputPage\setHTMLTitle
setHTMLTitle( $name)
"HTML title" means the contents of "<title>".
Definition: OutputPage.php:886
DerivativeResourceLoaderContext
A mutable version of ResourceLoaderContext.
Definition: DerivativeResourceLoaderContext.php:31
MediaWiki\Linker\LinkTarget\getDBkey
getDBkey()
Get the main part with underscores.
OutputPage\$mMetatags
string[][] $mMetatags
Should be private.
Definition: OutputPage.php:48
OutputPage\setLanguageLinks
setLanguageLinks(array $newLinkArray)
Reset the language links and add new language links.
Definition: OutputPage.php:1292
OutputPage\setupOOUI
static setupOOUI( $skinName='default', $dir='ltr')
Helper function to setup the PHP implementation of OOUI to use in this request.
Definition: OutputPage.php:4025
OutputPage\$rlExemptStyleModules
array $rlExemptStyleModules
Definition: OutputPage.php:169
OutputPage\$mProperties
$mProperties
Additional key => value data.
Definition: OutputPage.php:288
PROTO_RELATIVE
const PROTO_RELATIVE
Definition: Defines.php:210
OutputPage\wrapWikiMsg
wrapWikiMsg( $wrap)
This function takes a number of message/argument specifications, wraps them in some overall structure...
Definition: OutputPage.php:3991
OutputPage\prependHTML
prependHTML( $text)
Prepend $text to the body HTML.
Definition: OutputPage.php:1553
ParserOutput\getNoGallery
getNoGallery()
Definition: ParserOutput.php:581
OutputPage\$mEnableClientCache
$mEnableClientCache
Definition: OutputPage.php:216
OutputPage\getHTMLTitle
getHTMLTitle()
Return the "HTML title", i.e.
Definition: OutputPage.php:899
OutputPage\clearSubtitle
clearSubtitle()
Clear the subtitles.
Definition: OutputPage.php:1056
OutputPage\warnModuleTargetFilter
warnModuleTargetFilter( $moduleName)
Definition: OutputPage.php:504
OutputPage\$mCdnMaxage
int $mCdnMaxage
Cache stuff.
Definition: OutputPage.php:235
OutputPage\enableOOUI
enableOOUI()
Add ResourceLoader module styles for OOUI and set up the PHP implementation of it for use with MediaW...
Definition: OutputPage.php:4040
OutputPage\$cacheVaryCookies
static array $cacheVaryCookies
A cache of the names of the cookies that will influence the cache.
Definition: OutputPage.php:327
OutputPage\$mScripts
$mScripts
Used for JavaScript (predates ResourceLoader)
Definition: OutputPage.php:136
OutputPage\$mAllowedModules
array $mAllowedModules
What level of 'untrustworthiness' is allowed in CSS/JS modules loaded on this page?
Definition: OutputPage.php:190
getSkinThemeMap
static getSkinThemeMap()
Return a map of skin names (in lowercase) to OOUI theme names, defining which theme a given skin shou...
Definition: ResourceLoaderOOUIModule.php:76
OutputPage\$mPrintable
bool $mPrintable
We have to set isPrintable().
Definition: OutputPage.php:95
IContextSource
Interface for objects which can provide a MediaWiki context on request.
Definition: IContextSource.php:53
OutputPage\$mLanguageLinks
array $mLanguageLinks
Array of Interwiki Prefixed (non DB key) Titles (e.g.
Definition: OutputPage.php:128
wfGetAllCallers
wfGetAllCallers( $limit=3)
Return a string consisting of callers in the stack.
Definition: GlobalFunctions.php:1450
OutputPage\setCategoryLinks
setCategoryLinks(array $categories)
Reset the category links (but not the category list) and add $categories.
Definition: OutputPage.php:1395
OutputPage\setFollowPolicy
setFollowPolicy( $policy)
Set the follow policy for the page, but leave the index policy un- touched.
Definition: OutputPage.php:873
Content
Base interface for content objects.
Definition: Content.php:34
OutputPage\setPageTitle
setPageTitle( $name)
"Page title" means the contents of <h1>.
Definition: OutputPage.php:924
OutputPage\getRlClient
getRlClient()
Call this to freeze the module queue and JS config and create a formatter.
Definition: OutputPage.php:2930
ContentSecurityPolicy\isNonceRequired
static isNonceRequired(Config $config)
Should we set nonce attribute.
Definition: ContentSecurityPolicy.php:480
ResourceLoaderClientHtml\makeLoad
static makeLoad(ResourceLoaderContext $mainContext, array $modules, $only, array $extraQuery=[], $nonce=null)
Explicily load or embed modules on a page.
Definition: ResourceLoaderClientHtml.php:393
OutputPage\$mFileVersion
array $mFileVersion
Definition: OutputPage.php:253
OutputPage\checkLastModified
checkLastModified( $timestamp)
checkLastModified tells the client to use the client-cached page if possible.
Definition: OutputPage.php:727
OutputPage\$mNoGallery
bool $mNoGallery
Comes from the parser.
Definition: OutputPage.php:232
OutputPage\$mHeadItems
array $mHeadItems
Array of elements in "<head>".
Definition: OutputPage.php:148
$args
if( $line===false) $args
Definition: cdb.php:64
OutputPage\$mRevisionTimestamp
string $mRevisionTimestamp
Definition: OutputPage.php:250
OutputPage\$displayTitle
string $displayTitle
The displayed title of the page.
Definition: OutputPage.php:68
ParserOutput\getFileSearchOptions
& getFileSearchOptions()
Definition: ParserOutput.php:569
print
print
Definition: opensearch_desc.php:47
Title
Represents a title within MediaWiki.
Definition: Title.php:42
ResourceLoaderModule
Abstraction for ResourceLoader modules, with name registration and maxage functionality.
Definition: ResourceLoaderModule.php:37
OutputPage\setCdnMaxage
setCdnMaxage( $maxage)
Set the value of the "s-maxage" part of the "Cache-control" HTTP header.
Definition: OutputPage.php:2131
Parser\stripOuterParagraph
static stripOuterParagraph( $html)
Strip outer.
Definition: Parser.php:6797
OutputPage\getAllowedModules
getAllowedModules( $type)
Show what level of JavaScript / CSS untrustworthiness is allowed on this page.
Definition: OutputPage.php:1527
ResourceLoader
ResourceLoader is a loading system for JavaScript and CSS resources.
Definition: ResourceLoader.php:44
OutputPage\addVaryHeader
addVaryHeader( $header, array $option=null)
Add an HTTP header that will influence on the cache.
Definition: OutputPage.php:2234
ContentHandler\getContentText
static getContentText(Content $content=null)
Convenience function for getting flat text from a Content object.
Definition: ContentHandler.php:85
OutputPage\setProperty
setProperty( $name, $value)
Set an additional output property.
Definition: OutputPage.php:701
OutputPage\isPrintable
isPrintable()
Return whether the page is "printable".
Definition: OutputPage.php:1082
OutputPage\setSyndicated
setSyndicated( $show=true)
Add or remove feed links in the page header This is mainly kept for backward compatibility,...
Definition: OutputPage.php:1128
OutputPage\wrapWikiTextAsInterface
wrapWikiTextAsInterface( $wrapperClass, $text)
Convert wikitext in the user interface language to HTML and add it to the buffer with a <div class="$...
Definition: OutputPage.php:1782
OutputPage\parseInternal
parseInternal( $text, $title, $linestart, $tidy, $interface, $language)
Parse wikitext and return the HTML (internal implementation helper)
Definition: OutputPage.php:2098
OutputPage\$mTarget
string null $mTarget
ResourceLoader target for load.php links.
Definition: OutputPage.php:293
OutputPage\addInlineStyle
addInlineStyle( $style_css, $flip='noflip')
Adds inline CSS styles Internal use only.
Definition: OutputPage.php:3701
ResourceLoaderClientHtml\setModules
setModules(array $modules)
Ensure one or more modules are loaded.
Definition: ResourceLoaderClientHtml.php:89
OutputPage\userCanPreview
userCanPreview()
To make it harder for someone to slip a user a fake JavaScript or CSS preview, a random token is asso...
Definition: OutputPage.php:3340
Html\linkedStyle
static linkedStyle( $url, $media='all')
Output a "<link rel=stylesheet>" linking to the given URL for the given media type (if any).
Definition: Html.php:648
OutputPage\$mPageTitle
string $mPageTitle
The contents of.
Definition: OutputPage.php:59
ResourceLoader\inDebugMode
static inDebugMode()
Determine whether debug mode was requested Order of priority is 1) request param, 2) cookie,...
Definition: ResourceLoader.php:1648
OutputPage\setRedirectedFrom
setRedirectedFrom( $t)
Set $mRedirectedFrom, the Title of the page which redirected us to the current page.
Definition: OutputPage.php:908
ResourceLoaderClientHtml\setModuleStyles
setModuleStyles(array $modules)
Ensure the styles of one or more modules are loaded.
Definition: ResourceLoaderClientHtml.php:98
OutputPage\filterModules
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...
Definition: OutputPage.php:484
WebRequest\getRequestId
static getRequestId()
Get the unique request ID.
Definition: WebRequest.php:303
OutputPage\redirect
redirect( $url, $responsecode='302')
Redirect to $url rather than displaying the normal page.
Definition: OutputPage.php:345
OutputPage\getUnprefixedDisplayTitle
getUnprefixedDisplayTitle()
Returns page display title without namespace prefix if possible.
Definition: OutputPage.php:984
OutputPage\$mJsConfigVars
array $mJsConfigVars
Definition: OutputPage.php:172
$path
$path
Definition: NoLocalSettings.php:25
ParserOutput\getCategories
& getCategories()
Definition: ParserOutput.php:533
OutputPage\setPrintable
setPrintable()
Set the page as printable, i.e.
Definition: OutputPage.php:1073
OutputPage\getHeadLinksArray
getHeadLinksArray()
Definition: OutputPage.php:3386
OutputPage\adaptCdnTTL
adaptCdnTTL( $mtime, $minTTL=0, $maxTTL=0)
Get TTL in [$minTTL,$maxTTL] and pass it to lowerCdnMaxage()
Definition: OutputPage.php:2161
OutputPage\getCdnCacheEpoch
getCdnCacheEpoch( $reqTime, $maxAge)
Definition: OutputPage.php:815
OutputPage\allowClickjacking
allowClickjacking()
Turn off frame-breaking.
Definition: OutputPage.php:2321
LanguageCode\bcp47
static bcp47( $code)
Get the normalised IETF language tag See unit test for examples.
Definition: LanguageCode.php:178
OutputPage\loadSkinModules
loadSkinModules( $sk)
Transfer styles and JavaScript modules from skin.
Definition: OutputPage.php:2454
OutputPage\showFatalError
showFatalError( $message)
Output an error page.
Definition: OutputPage.php:2817
Html\openElement
static openElement( $element, $attribs=[])
Identical to rawElement(), but has no third parameter and omits the end tag (and the self-closing '/'...
Definition: Html.php:251
Html\rawElement
static rawElement( $element, $attribs=[], $contents='')
Returns an HTML element in a string.
Definition: Html.php:209
OutputPage\getHTML
getHTML()
Get the body HTML.
Definition: OutputPage.php:1591
Message
The Message class provides methods which fulfil two basic services:
Definition: Message.php:162
OutputPage\parseInlineAsInterface
parseInlineAsInterface( $text, $linestart=true)
Parse wikitext in the user interface language, strip paragraph wrapper, and return the HTML.
Definition: OutputPage.php:2054
OutputPage\$mLinkHeader
$mLinkHeader
Link: header contents.
Definition: OutputPage.php:317
$keys
$keys
Definition: testCompression.php:67
OutputPage\$styles
array $styles
An array of stylesheet filenames (relative from skins path), with options for CSS media,...
Definition: OutputPage.php:263
OutputPage\isRevisionCurrent
isRevisionCurrent()
Whether the revision displayed is the latest revision of the page.
Definition: OutputPage.php:1673
Sanitizer\normalizeCharReferences
static normalizeCharReferences( $text)
Ensure that any entities and character references are legal for XML and XHTML specifically.
Definition: Sanitizer.php:1573
MWDebug\addModules
static addModules(OutputPage $out)
Add ResourceLoader modules to the OutputPage object if debugging is enabled.
Definition: MWDebug.php:120
CacheTime\isCacheable
isCacheable()
Definition: CacheTime.php:155
OutputPage\showNewSectionLink
showNewSectionLink()
Show an "add new section" link?
Definition: OutputPage.php:1107
OutputPage\parse
parse( $text, $linestart=true, $interface=false, $language=null)
Parse wikitext and return the HTML.
Definition: OutputPage.php:1990
OutputPage\$mPageLinkTitle
string $mPageLinkTitle
Used by skin template.
Definition: OutputPage.php:145
ParserOutput\getText
getText( $options=[])
Get the output HTML.
Definition: ParserOutput.php:323
OutputPage\$mCanonicalUrl
string bool $mCanonicalUrl
Definition: OutputPage.php:54
OutputPage\makeResourceLoaderLink
makeResourceLoaderLink( $modules, $only, array $extraQuery=[])
Explicily load or embed modules on a page.
Definition: OutputPage.php:3120
OutputPage\addWikiTextTitleInternal
addWikiTextTitleInternal( $text, Title $title, $linestart, $interface, $wrapperClass=null)
Add wikitext with a custom Title object.
Definition: OutputPage.php:1831
OutputPage\getIndicators
getIndicators()
Get the indicators associated with this page.
Definition: OutputPage.php:1458
$t
$t
Definition: testCompression.php:69
$wgRequest
if(! $wgDBerrorLogTZ) $wgRequest
Definition: Setup.php:751
Html\element
static element( $element, $attribs=[], $contents='')
Identical to rawElement(), but HTML-escapes $contents (like Xml::element()).
Definition: Html.php:231
ResourceLoader\makeLoaderQuery
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.
Definition: ResourceLoader.php:1730
Skin\getSkinName
getSkinName()
Definition: Skin.php:158
MediaWiki\Linker\LinkTarget
Definition: LinkTarget.php:26
OutputPage\addJsConfigVars
addJsConfigVars( $keys, $value=null)
Add one or more variables to be set in mw.config in JavaScript.
Definition: OutputPage.php:3186
OutputPage\$mPreventClickjacking
bool $mPreventClickjacking
Controls if anti-clickjacking / frame-breaking headers will be sent.
Definition: OutputPage.php:244
Skin
The main skin class which provides methods and properties for all other skins.
Definition: Skin.php:38
OutputPage\getCategories
getCategories( $type='all')
Get the list of category names this page belongs to.
Definition: OutputPage.php:1421
OutputPage\getJsConfigVars
getJsConfigVars()
Get the javascript config vars to include on this page.
Definition: OutputPage.php:3176
OutputPage\setCopyright
setCopyright( $hasCopyright)
Set whether the standard copyright should be shown for the current page.
Definition: OutputPage.php:1259
OutputPage\getTemplateIds
getTemplateIds()
Get the templates used on this page.
Definition: OutputPage.php:1727
$IP
$IP
Definition: WebStart.php:41
User
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
Definition: User.php:51
OutputPage\$mIsArticleRelated
bool $mIsArticleRelated
Stores "article flag" toggle.
Definition: OutputPage.php:86
Hooks\run
static run( $event, array $args=[], $deprecatedVersion=null)
Call hook functions defined in Hooks::register and $wgHooks.
Definition: Hooks.php:200
OutputPage\isSyndicated
isSyndicated()
Should we output feed links for this page?
Definition: OutputPage.php:1187
OutputPage\$mFeedLinksAppendQuery
$mFeedLinksAppendQuery
Definition: OutputPage.php:183
OutputPage\getFileSearchOptions
getFileSearchOptions()
Get the files used on this page.
Definition: OutputPage.php:1737
OutputPage\$mFeedLinks
$mFeedLinks
Handles the Atom / RSS links.
Definition: OutputPage.php:213
OutputPage\$mDoNothing
bool $mDoNothing
Whether output is disabled.
Definition: OutputPage.php:195
OutputPage\$mArticleBodyOnly
bool $mArticleBodyOnly
Flag if output should only contain the body of the article.
Definition: OutputPage.php:219
OutputPage\$mHasCopyright
bool $mHasCopyright
Is the content subject to copyright.
Definition: OutputPage.php:89
OutputPage\addParserOutput
addParserOutput(ParserOutput $parserOutput, $poOptions=[])
Add everything from a ParserOutput object.
Definition: OutputPage.php:1958
OutputPage\$mAdditionalBodyClasses
array $mAdditionalBodyClasses
Additional <body> classes; there are also <body> classes from other sources.
Definition: OutputPage.php:151
OutputPage\prepareErrorPage
prepareErrorPage( $pageTitle, $htmlTitle=false)
Prepare this object to display an error page; disable caching and indexing, clear the current text an...
Definition: OutputPage.php:2609
OutputPage\addTemplate
addTemplate(&$template)
Add the output of a QuickTemplate to the output buffer.
Definition: OutputPage.php:1968
OutputPage\getFeedAppendQuery
getFeedAppendQuery()
Will currently always return null.
Definition: OutputPage.php:1204
OutputPage\lowerCdnMaxage
lowerCdnMaxage( $maxage)
Set the value of the "s-maxage" part of the "Cache-control" HTTP header to $maxage if that is lower t...
Definition: OutputPage.php:2144
OutputPage\$mHTMLtitle
string $mHTMLtitle
Stores contents of "<title>" tag.
Definition: OutputPage.php:77
wfExpandUrl
wfExpandUrl( $url, $defaultProto=PROTO_CURRENT)
Expand a potentially local URL to a fully-qualified URL.
Definition: GlobalFunctions.php:491
OutputPage\addFeedLink
addFeedLink( $format, $href)
Add a feed link to the page header.
Definition: OutputPage.php:1177
ParserOutput\preventClickjacking
preventClickjacking( $flag=null)
Get or set the prevent-clickjacking flag.
Definition: ParserOutput.php:1288
OutputPage\$mCategoryLinks
array $mCategoryLinks
Definition: OutputPage.php:116
OutputPage\transformResourcePath
static transformResourcePath(Config $config, $path)
Transform path to web-accessible static resource.
Definition: OutputPage.php:3845
OutputPage\parseAsContent
parseAsContent( $text, $linestart=true)
Parse wikitext in the page content language and return the HTML.
Definition: OutputPage.php:2010
Sanitizer\removeHTMLtags
static removeHTMLtags( $text, $processCallback=null, $args=[], $extratags=[], $removetags=[], $warnCallback=null)
Cleans up HTML, removes dangerous tags and attributes, and removes HTML comments.
Definition: Sanitizer.php:497
OutputPage\getAdvertisedFeedTypes
getAdvertisedFeedTypes()
Return effective list of advertised feed types.
Definition: OutputPage.php:1142
OutputPage\setRobotPolicy
setRobotPolicy( $policy)
Set the robot policy for the page: http://www.robotstxt.org/meta.html
Definition: OutputPage.php:841
wfArrayToCgi
wfArrayToCgi( $array1, $array2=null, $prefix='')
This function takes one or two arrays as input, and returns a CGI-style string, e....
Definition: GlobalFunctions.php:347
OutputPage\transformFilePath
static transformFilePath( $remotePathPrefix, $localPath, $file)
Utility method for transformResourceFilePath().
Definition: OutputPage.php:3887
OutputPage\headElement
headElement(Skin $sk, $includeStyle=true)
Definition: OutputPage.php:3007
$type
$type
Definition: testCompression.php:48
OutputPage\$mStatusCode
int $mStatusCode
Definition: OutputPage.php:107