MediaWiki  1.30.0
OutputPage.php
Go to the documentation of this file.
1 <?php
26 use WrappedString\WrappedString;
27 use WrappedString\WrappedStringList;
28 
44 class OutputPage extends ContextSource {
46  protected $mMetatags = [];
47 
49  protected $mLinktags = [];
50 
52  protected $mCanonicalUrl = false;
53 
58  protected $mExtStyles = [];
59 
63  public $mPagetitle = '';
64 
69  public $mBodytext = '';
70 
72  private $mHTMLtitle = '';
73 
78  private $mIsarticle = false;
79 
81  private $mIsArticleRelated = true;
82 
87  private $mPrintable = false;
88 
93  private $mSubtitle = [];
94 
96  public $mRedirect = '';
97 
99  protected $mStatusCode;
100 
105  protected $mLastModified = '';
106 
108  protected $mCategoryLinks = [];
109 
111  protected $mCategories = [
112  'hidden' => [],
113  'normal' => [],
114  ];
115 
117  protected $mIndicators = [];
118 
120  private $mLanguageLinks = [];
121 
128  private $mScripts = '';
129 
131  protected $mInlineStyles = '';
132 
137  public $mPageLinkTitle = '';
138 
140  protected $mHeadItems = [];
141 
143  protected $mAdditionalBodyClasses = [];
144 
146  protected $mModules = [];
147 
149  protected $mModuleScripts = [];
150 
152  protected $mModuleStyles = [];
153 
155  protected $mResourceLoader;
156 
158  private $rlClient;
159 
162 
165 
168 
170  protected $mJsConfigVars = [];
171 
173  protected $mTemplateIds = [];
174 
176  protected $mImageTimeKeys = [];
177 
179  public $mRedirectCode = '';
180 
181  protected $mFeedLinksAppendQuery = null;
182 
188  protected $mAllowedModules = [
190  ];
191 
193  protected $mDoNothing = false;
194 
195  // Parser related.
196 
198  protected $mContainsNewMagic = 0;
199 
204  protected $mParserOptions = null;
205 
211  private $mFeedLinks = [];
212 
213  // Gwicke work on squid caching? Roughly from 2003.
214  protected $mEnableClientCache = true;
215 
217  private $mArticleBodyOnly = false;
218 
220  protected $mNewSectionLink = false;
221 
223  protected $mHideNewSectionLink = false;
224 
230  public $mNoGallery = false;
231 
233  private $mPageTitleActionText = '';
234 
236  protected $mCdnMaxage = 0;
238  protected $mCdnMaxageLimit = INF;
239 
245  protected $mPreventClickjacking = true;
246 
248  private $mRevisionId = null;
249 
251  private $mRevisionTimestamp = null;
252 
254  protected $mFileVersion = null;
255 
264  protected $styles = [];
265 
266  private $mIndexPolicy = 'index';
267  private $mFollowPolicy = 'follow';
268  private $mVaryHeader = [
269  'Accept-Encoding' => [ 'match=gzip' ],
270  ];
271 
278  private $mRedirectedFrom = null;
279 
283  private $mProperties = [];
284 
288  private $mTarget = null;
289 
293  private $mEnableTOC = false;
294 
298  private $mEnableSectionEditLinks = true;
299 
303  private $copyrightUrl;
304 
306  private $limitReportJSData = [];
307 
311  private $mLinkHeader = [];
312 
319  function __construct( IContextSource $context = null ) {
320  if ( $context === null ) {
321  # Extensions should use `new RequestContext` instead of `new OutputPage` now.
322  wfDeprecated( __METHOD__, '1.18' );
323  } else {
324  $this->setContext( $context );
325  }
326  }
327 
334  public function redirect( $url, $responsecode = '302' ) {
335  # Strip newlines as a paranoia check for header injection in PHP<5.1.2
336  $this->mRedirect = str_replace( "\n", '', $url );
337  $this->mRedirectCode = $responsecode;
338  }
339 
345  public function getRedirect() {
346  return $this->mRedirect;
347  }
348 
357  public function setCopyrightUrl( $url ) {
358  $this->copyrightUrl = $url;
359  }
360 
366  public function setStatusCode( $statusCode ) {
367  $this->mStatusCode = $statusCode;
368  }
369 
377  function addMeta( $name, $val ) {
378  array_push( $this->mMetatags, [ $name, $val ] );
379  }
380 
387  public function getMetaTags() {
388  return $this->mMetatags;
389  }
390 
398  function addLink( array $linkarr ) {
399  array_push( $this->mLinktags, $linkarr );
400  }
401 
408  public function getLinkTags() {
409  return $this->mLinktags;
410  }
411 
419  function addMetadataLink( array $linkarr ) {
420  $linkarr['rel'] = $this->getMetadataAttribute();
421  $this->addLink( $linkarr );
422  }
423 
429  function setCanonicalUrl( $url ) {
430  $this->mCanonicalUrl = $url;
431  }
432 
440  public function getCanonicalUrl() {
441  return $this->mCanonicalUrl;
442  }
443 
449  public function getMetadataAttribute() {
450  # note: buggy CC software only reads first "meta" link
451  static $haveMeta = false;
452  if ( $haveMeta ) {
453  return 'alternate meta';
454  } else {
455  $haveMeta = true;
456  return 'meta';
457  }
458  }
459 
467  function addScript( $script ) {
468  $this->mScripts .= $script;
469  }
470 
480  public function addExtensionStyle( $url ) {
481  wfDeprecated( __METHOD__, '1.27' );
482  array_push( $this->mExtStyles, $url );
483  }
484 
491  function getExtStyle() {
492  wfDeprecated( __METHOD__, '1.27' );
493  return $this->mExtStyles;
494  }
495 
504  public function addScriptFile( $file, $version = null ) {
505  // See if $file parameter is an absolute URL or begins with a slash
506  if ( substr( $file, 0, 1 ) == '/' || preg_match( '#^[a-z]*://#i', $file ) ) {
507  $path = $file;
508  } else {
509  $path = $this->getConfig()->get( 'StylePath' ) . "/common/{$file}";
510  }
511  if ( is_null( $version ) ) {
512  $version = $this->getConfig()->get( 'StyleVersion' );
513  }
514  $this->addScript( Html::linkedScript( wfAppendQuery( $path, $version ) ) );
515  }
516 
523  public function addInlineScript( $script ) {
524  $this->mScripts .= Html::inlineScript( $script );
525  }
526 
535  protected function filterModules( array $modules, $position = null,
537  ) {
539  $filteredModules = [];
540  foreach ( $modules as $val ) {
541  $module = $resourceLoader->getModule( $val );
542  if ( $module instanceof ResourceLoaderModule
543  && $module->getOrigin() <= $this->getAllowedModules( $type )
544  && ( is_null( $position ) || $module->getPosition() == $position )
545  ) {
546  if ( $this->mTarget && !in_array( $this->mTarget, $module->getTargets() ) ) {
547  $this->warnModuleTargetFilter( $module->getName() );
548  continue;
549  }
550  $filteredModules[] = $val;
551  }
552  }
553  return $filteredModules;
554  }
555 
556  private function warnModuleTargetFilter( $moduleName ) {
557  static $warnings = [];
558  if ( isset( $warnings[$this->mTarget][$moduleName] ) ) {
559  return;
560  }
561  $warnings[$this->mTarget][$moduleName] = true;
562  $this->getResourceLoader()->getLogger()->debug(
563  'Module "{module}" not loadable on target "{target}".',
564  [
565  'module' => $moduleName,
566  'target' => $this->mTarget,
567  ]
568  );
569  }
570 
580  public function getModules( $filter = false, $position = null, $param = 'mModules',
582  ) {
583  $modules = array_values( array_unique( $this->$param ) );
584  return $filter
585  ? $this->filterModules( $modules, $position, $type )
586  : $modules;
587  }
588 
596  public function addModules( $modules ) {
597  $this->mModules = array_merge( $this->mModules, (array)$modules );
598  }
599 
607  public function getModuleScripts( $filter = false, $position = null ) {
608  return $this->getModules( $filter, $position, 'mModuleScripts',
610  );
611  }
612 
620  public function addModuleScripts( $modules ) {
621  $this->mModuleScripts = array_merge( $this->mModuleScripts, (array)$modules );
622  }
623 
631  public function getModuleStyles( $filter = false, $position = null ) {
632  return $this->getModules( $filter, $position, 'mModuleStyles',
634  );
635  }
636 
646  public function addModuleStyles( $modules ) {
647  $this->mModuleStyles = array_merge( $this->mModuleStyles, (array)$modules );
648  }
649 
653  public function getTarget() {
654  return $this->mTarget;
655  }
656 
662  public function setTarget( $target ) {
663  $this->mTarget = $target;
664  }
665 
671  function getHeadItemsArray() {
672  return $this->mHeadItems;
673  }
674 
687  public function addHeadItem( $name, $value ) {
688  $this->mHeadItems[$name] = $value;
689  }
690 
697  public function addHeadItems( $values ) {
698  $this->mHeadItems = array_merge( $this->mHeadItems, (array)$values );
699  }
700 
707  public function hasHeadItem( $name ) {
708  return isset( $this->mHeadItems[$name] );
709  }
710 
717  public function addBodyClasses( $classes ) {
718  $this->mAdditionalBodyClasses = array_merge( $this->mAdditionalBodyClasses, (array)$classes );
719  }
720 
725  public function setETag( $tag ) {
726  }
727 
735  public function setArticleBodyOnly( $only ) {
736  $this->mArticleBodyOnly = $only;
737  }
738 
744  public function getArticleBodyOnly() {
746  }
747 
755  public function setProperty( $name, $value ) {
756  $this->mProperties[$name] = $value;
757  }
758 
766  public function getProperty( $name ) {
767  if ( isset( $this->mProperties[$name] ) ) {
768  return $this->mProperties[$name];
769  } else {
770  return null;
771  }
772  }
773 
785  public function checkLastModified( $timestamp ) {
786  if ( !$timestamp || $timestamp == '19700101000000' ) {
787  wfDebug( __METHOD__ . ": CACHE DISABLED, NO TIMESTAMP\n" );
788  return false;
789  }
790  $config = $this->getConfig();
791  if ( !$config->get( 'CachePages' ) ) {
792  wfDebug( __METHOD__ . ": CACHE DISABLED\n" );
793  return false;
794  }
795 
796  $timestamp = wfTimestamp( TS_MW, $timestamp );
797  $modifiedTimes = [
798  'page' => $timestamp,
799  'user' => $this->getUser()->getTouched(),
800  'epoch' => $config->get( 'CacheEpoch' )
801  ];
802  if ( $config->get( 'UseSquid' ) ) {
803  // T46570: the core page itself may not change, but resources might
804  $modifiedTimes['sepoch'] = wfTimestamp( TS_MW, time() - $config->get( 'SquidMaxage' ) );
805  }
806  Hooks::run( 'OutputPageCheckLastModified', [ &$modifiedTimes, $this ] );
807 
808  $maxModified = max( $modifiedTimes );
809  $this->mLastModified = wfTimestamp( TS_RFC2822, $maxModified );
810 
811  $clientHeader = $this->getRequest()->getHeader( 'If-Modified-Since' );
812  if ( $clientHeader === false ) {
813  wfDebug( __METHOD__ . ": client did not send If-Modified-Since header", 'private' );
814  return false;
815  }
816 
817  # IE sends sizes after the date like this:
818  # Wed, 20 Aug 2003 06:51:19 GMT; length=5202
819  # this breaks strtotime().
820  $clientHeader = preg_replace( '/;.*$/', '', $clientHeader );
821 
822  MediaWiki\suppressWarnings(); // E_STRICT system time bitching
823  $clientHeaderTime = strtotime( $clientHeader );
824  MediaWiki\restoreWarnings();
825  if ( !$clientHeaderTime ) {
826  wfDebug( __METHOD__
827  . ": unable to parse the client's If-Modified-Since header: $clientHeader\n" );
828  return false;
829  }
830  $clientHeaderTime = wfTimestamp( TS_MW, $clientHeaderTime );
831 
832  # Make debug info
833  $info = '';
834  foreach ( $modifiedTimes as $name => $value ) {
835  if ( $info !== '' ) {
836  $info .= ', ';
837  }
838  $info .= "$name=" . wfTimestamp( TS_ISO_8601, $value );
839  }
840 
841  wfDebug( __METHOD__ . ": client sent If-Modified-Since: " .
842  wfTimestamp( TS_ISO_8601, $clientHeaderTime ), 'private' );
843  wfDebug( __METHOD__ . ": effective Last-Modified: " .
844  wfTimestamp( TS_ISO_8601, $maxModified ), 'private' );
845  if ( $clientHeaderTime < $maxModified ) {
846  wfDebug( __METHOD__ . ": STALE, $info", 'private' );
847  return false;
848  }
849 
850  # Not modified
851  # Give a 304 Not Modified response code and disable body output
852  wfDebug( __METHOD__ . ": NOT MODIFIED, $info", 'private' );
853  ini_set( 'zlib.output_compression', 0 );
854  $this->getRequest()->response()->statusHeader( 304 );
855  $this->sendCacheControl();
856  $this->disable();
857 
858  // Don't output a compressed blob when using ob_gzhandler;
859  // it's technically against HTTP spec and seems to confuse
860  // Firefox when the response gets split over two packets.
862 
863  return true;
864  }
865 
872  public function setLastModified( $timestamp ) {
873  $this->mLastModified = wfTimestamp( TS_RFC2822, $timestamp );
874  }
875 
884  public function setRobotPolicy( $policy ) {
885  $policy = Article::formatRobotPolicy( $policy );
886 
887  if ( isset( $policy['index'] ) ) {
888  $this->setIndexPolicy( $policy['index'] );
889  }
890  if ( isset( $policy['follow'] ) ) {
891  $this->setFollowPolicy( $policy['follow'] );
892  }
893  }
894 
902  public function setIndexPolicy( $policy ) {
903  $policy = trim( $policy );
904  if ( in_array( $policy, [ 'index', 'noindex' ] ) ) {
905  $this->mIndexPolicy = $policy;
906  }
907  }
908 
916  public function setFollowPolicy( $policy ) {
917  $policy = trim( $policy );
918  if ( in_array( $policy, [ 'follow', 'nofollow' ] ) ) {
919  $this->mFollowPolicy = $policy;
920  }
921  }
922 
929  public function setPageTitleActionText( $text ) {
930  $this->mPageTitleActionText = $text;
931  }
932 
938  public function getPageTitleActionText() {
940  }
941 
948  public function setHTMLTitle( $name ) {
949  if ( $name instanceof Message ) {
950  $this->mHTMLtitle = $name->setContext( $this->getContext() )->text();
951  } else {
952  $this->mHTMLtitle = $name;
953  }
954  }
955 
961  public function getHTMLTitle() {
962  return $this->mHTMLtitle;
963  }
964 
970  public function setRedirectedFrom( $t ) {
971  $this->mRedirectedFrom = $t;
972  }
973 
984  public function setPageTitle( $name ) {
985  if ( $name instanceof Message ) {
986  $name = $name->setContext( $this->getContext() )->text();
987  }
988 
989  # change "<script>foo&bar</script>" to "&lt;script&gt;foo&amp;bar&lt;/script&gt;"
990  # but leave "<i>foobar</i>" alone
991  $nameWithTags = Sanitizer::normalizeCharReferences( Sanitizer::removeHTMLtags( $name ) );
992  $this->mPagetitle = $nameWithTags;
993 
994  # change "<i>foo&amp;bar</i>" to "foo&bar"
995  $this->setHTMLTitle(
996  $this->msg( 'pagetitle' )->rawParams( Sanitizer::stripAllTags( $nameWithTags ) )
997  ->inContentLanguage()
998  );
999  }
1000 
1006  public function getPageTitle() {
1007  return $this->mPagetitle;
1008  }
1009 
1015  public function setTitle( Title $t ) {
1016  $this->getContext()->setTitle( $t );
1017  }
1018 
1024  public function setSubtitle( $str ) {
1025  $this->clearSubtitle();
1026  $this->addSubtitle( $str );
1027  }
1028 
1034  public function addSubtitle( $str ) {
1035  if ( $str instanceof Message ) {
1036  $this->mSubtitle[] = $str->setContext( $this->getContext() )->parse();
1037  } else {
1038  $this->mSubtitle[] = $str;
1039  }
1040  }
1041 
1050  public static function buildBacklinkSubtitle( Title $title, $query = [] ) {
1051  if ( $title->isRedirect() ) {
1052  $query['redirect'] = 'no';
1053  }
1054  $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
1055  return wfMessage( 'backlinksubtitle' )
1056  ->rawParams( $linkRenderer->makeLink( $title, null, [], $query ) );
1057  }
1058 
1065  public function addBacklinkSubtitle( Title $title, $query = [] ) {
1066  $this->addSubtitle( self::buildBacklinkSubtitle( $title, $query ) );
1067  }
1068 
1072  public function clearSubtitle() {
1073  $this->mSubtitle = [];
1074  }
1075 
1081  public function getSubtitle() {
1082  return implode( "<br />\n\t\t\t\t", $this->mSubtitle );
1083  }
1084 
1089  public function setPrintable() {
1090  $this->mPrintable = true;
1091  }
1092 
1098  public function isPrintable() {
1099  return $this->mPrintable;
1100  }
1101 
1105  public function disable() {
1106  $this->mDoNothing = true;
1107  }
1108 
1114  public function isDisabled() {
1115  return $this->mDoNothing;
1116  }
1117 
1123  public function showNewSectionLink() {
1124  return $this->mNewSectionLink;
1125  }
1126 
1132  public function forceHideNewSectionLink() {
1134  }
1135 
1144  public function setSyndicated( $show = true ) {
1145  if ( $show ) {
1146  $this->setFeedAppendQuery( false );
1147  } else {
1148  $this->mFeedLinks = [];
1149  }
1150  }
1151 
1161  public function setFeedAppendQuery( $val ) {
1162  $this->mFeedLinks = [];
1163 
1164  foreach ( $this->getConfig()->get( 'AdvertisedFeedTypes' ) as $type ) {
1165  $query = "feed=$type";
1166  if ( is_string( $val ) ) {
1167  $query .= '&' . $val;
1168  }
1169  $this->mFeedLinks[$type] = $this->getTitle()->getLocalURL( $query );
1170  }
1171  }
1172 
1179  public function addFeedLink( $format, $href ) {
1180  if ( in_array( $format, $this->getConfig()->get( 'AdvertisedFeedTypes' ) ) ) {
1181  $this->mFeedLinks[$format] = $href;
1182  }
1183  }
1184 
1189  public function isSyndicated() {
1190  return count( $this->mFeedLinks ) > 0;
1191  }
1192 
1197  public function getSyndicationLinks() {
1198  return $this->mFeedLinks;
1199  }
1200 
1206  public function getFeedAppendQuery() {
1208  }
1209 
1217  public function setArticleFlag( $v ) {
1218  $this->mIsarticle = $v;
1219  if ( $v ) {
1220  $this->mIsArticleRelated = $v;
1221  }
1222  }
1223 
1230  public function isArticle() {
1231  return $this->mIsarticle;
1232  }
1233 
1240  public function setArticleRelated( $v ) {
1241  $this->mIsArticleRelated = $v;
1242  if ( !$v ) {
1243  $this->mIsarticle = false;
1244  }
1245  }
1246 
1252  public function isArticleRelated() {
1253  return $this->mIsArticleRelated;
1254  }
1255 
1262  public function addLanguageLinks( array $newLinkArray ) {
1263  $this->mLanguageLinks += $newLinkArray;
1264  }
1265 
1272  public function setLanguageLinks( array $newLinkArray ) {
1273  $this->mLanguageLinks = $newLinkArray;
1274  }
1275 
1281  public function getLanguageLinks() {
1282  return $this->mLanguageLinks;
1283  }
1284 
1290  public function addCategoryLinks( array $categories ) {
1292 
1293  if ( !is_array( $categories ) || count( $categories ) == 0 ) {
1294  return;
1295  }
1296 
1297  $res = $this->addCategoryLinksToLBAndGetResult( $categories );
1298 
1299  # Set all the values to 'normal'.
1300  $categories = array_fill_keys( array_keys( $categories ), 'normal' );
1301 
1302  # Mark hidden categories
1303  foreach ( $res as $row ) {
1304  if ( isset( $row->pp_value ) ) {
1305  $categories[$row->page_title] = 'hidden';
1306  }
1307  }
1308 
1309  // Avoid PHP 7.1 warning of passing $this by reference
1310  $outputPage = $this;
1311  # Add the remaining categories to the skin
1312  if ( Hooks::run(
1313  'OutputPageMakeCategoryLinks',
1314  [ &$outputPage, $categories, &$this->mCategoryLinks ] )
1315  ) {
1316  $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
1317  foreach ( $categories as $category => $type ) {
1318  // array keys will cast numeric category names to ints, so cast back to string
1319  $category = (string)$category;
1320  $origcategory = $category;
1321  $title = Title::makeTitleSafe( NS_CATEGORY, $category );
1322  if ( !$title ) {
1323  continue;
1324  }
1325  $wgContLang->findVariantLink( $category, $title, true );
1326  if ( $category != $origcategory && array_key_exists( $category, $categories ) ) {
1327  continue;
1328  }
1329  $text = $wgContLang->convertHtml( $title->getText() );
1330  $this->mCategories[$type][] = $title->getText();
1331  $this->mCategoryLinks[$type][] = $linkRenderer->makeLink( $title, new HtmlArmor( $text ) );
1332  }
1333  }
1334  }
1335 
1340  protected function addCategoryLinksToLBAndGetResult( array $categories ) {
1341  # Add the links to a LinkBatch
1342  $arr = [ NS_CATEGORY => $categories ];
1343  $lb = new LinkBatch;
1344  $lb->setArray( $arr );
1345 
1346  # Fetch existence plus the hiddencat property
1347  $dbr = wfGetDB( DB_REPLICA );
1348  $fields = array_merge(
1350  [ 'page_namespace', 'page_title', 'pp_value' ]
1351  );
1352 
1353  $res = $dbr->select( [ 'page', 'page_props' ],
1354  $fields,
1355  $lb->constructSet( 'page', $dbr ),
1356  __METHOD__,
1357  [],
1358  [ 'page_props' => [ 'LEFT JOIN', [
1359  'pp_propname' => 'hiddencat',
1360  'pp_page = page_id'
1361  ] ] ]
1362  );
1363 
1364  # Add the results to the link cache
1365  $lb->addResultToCache( LinkCache::singleton(), $res );
1366 
1367  return $res;
1368  }
1369 
1375  public function setCategoryLinks( array $categories ) {
1376  $this->mCategoryLinks = [];
1377  $this->addCategoryLinks( $categories );
1378  }
1379 
1388  public function getCategoryLinks() {
1389  return $this->mCategoryLinks;
1390  }
1391 
1401  public function getCategories( $type = 'all' ) {
1402  if ( $type === 'all' ) {
1403  $allCategories = [];
1404  foreach ( $this->mCategories as $categories ) {
1405  $allCategories = array_merge( $allCategories, $categories );
1406  }
1407  return $allCategories;
1408  }
1409  if ( !isset( $this->mCategories[$type] ) ) {
1410  throw new InvalidArgumentException( 'Invalid category type given: ' . $type );
1411  }
1412  return $this->mCategories[$type];
1413  }
1414 
1424  public function setIndicators( array $indicators ) {
1425  $this->mIndicators = $indicators + $this->mIndicators;
1426  // Keep ordered by key
1427  ksort( $this->mIndicators );
1428  }
1429 
1438  public function getIndicators() {
1439  return $this->mIndicators;
1440  }
1441 
1450  public function addHelpLink( $to, $overrideBaseUrl = false ) {
1451  $this->addModuleStyles( 'mediawiki.helplink' );
1452  $text = $this->msg( 'helppage-top-gethelp' )->escaped();
1453 
1454  if ( $overrideBaseUrl ) {
1455  $helpUrl = $to;
1456  } else {
1457  $toUrlencoded = wfUrlencode( str_replace( ' ', '_', $to ) );
1458  $helpUrl = "//www.mediawiki.org/wiki/Special:MyLanguage/$toUrlencoded";
1459  }
1460 
1462  'a',
1463  [
1464  'href' => $helpUrl,
1465  'target' => '_blank',
1466  'class' => 'mw-helplink',
1467  ],
1468  $text
1469  );
1470 
1471  $this->setIndicators( [ 'mw-helplink' => $link ] );
1472  }
1473 
1482  public function disallowUserJs() {
1483  $this->reduceAllowedModules(
1486  );
1487 
1488  // Site-wide styles are controlled by a config setting, see T73621
1489  // for background on why. User styles are never allowed.
1490  if ( $this->getConfig()->get( 'AllowSiteCSSOnRestrictedPages' ) ) {
1492  } else {
1494  }
1495  $this->reduceAllowedModules(
1497  $styleOrigin
1498  );
1499  }
1500 
1507  public function getAllowedModules( $type ) {
1509  return min( array_values( $this->mAllowedModules ) );
1510  } else {
1511  return isset( $this->mAllowedModules[$type] )
1512  ? $this->mAllowedModules[$type]
1514  }
1515  }
1516 
1526  public function reduceAllowedModules( $type, $level ) {
1527  $this->mAllowedModules[$type] = min( $this->getAllowedModules( $type ), $level );
1528  }
1529 
1535  public function prependHTML( $text ) {
1536  $this->mBodytext = $text . $this->mBodytext;
1537  }
1538 
1544  public function addHTML( $text ) {
1545  $this->mBodytext .= $text;
1546  }
1547 
1557  public function addElement( $element, array $attribs = [], $contents = '' ) {
1558  $this->addHTML( Html::element( $element, $attribs, $contents ) );
1559  }
1560 
1564  public function clearHTML() {
1565  $this->mBodytext = '';
1566  }
1567 
1573  public function getHTML() {
1574  return $this->mBodytext;
1575  }
1576 
1584  public function parserOptions( $options = null ) {
1585  if ( $options !== null && !empty( $options->isBogus ) ) {
1586  // Someone is trying to set a bogus pre-$wgUser PO. Check if it has
1587  // been changed somehow, and keep it if so.
1588  $anonPO = ParserOptions::newFromAnon();
1589  $anonPO->setEditSection( false );
1590  $anonPO->setAllowUnsafeRawHtml( false );
1591  if ( !$options->matches( $anonPO ) ) {
1592  wfLogWarning( __METHOD__ . ': Setting a changed bogus ParserOptions: ' . wfGetAllCallers( 5 ) );
1593  $options->isBogus = false;
1594  }
1595  }
1596 
1597  if ( !$this->mParserOptions ) {
1598  if ( !$this->getContext()->getUser()->isSafeToLoad() ) {
1599  // $wgUser isn't unstubbable yet, so don't try to get a
1600  // ParserOptions for it. And don't cache this ParserOptions
1601  // either.
1603  $po->setEditSection( false );
1604  $po->setAllowUnsafeRawHtml( false );
1605  $po->isBogus = true;
1606  if ( $options !== null ) {
1607  $this->mParserOptions = empty( $options->isBogus ) ? $options : null;
1608  }
1609  return $po;
1610  }
1611 
1612  $this->mParserOptions = ParserOptions::newFromContext( $this->getContext() );
1613  $this->mParserOptions->setEditSection( false );
1614  $this->mParserOptions->setAllowUnsafeRawHtml( false );
1615  }
1616 
1617  if ( $options !== null && !empty( $options->isBogus ) ) {
1618  // They're trying to restore the bogus pre-$wgUser PO. Do the right
1619  // thing.
1620  return wfSetVar( $this->mParserOptions, null, true );
1621  } else {
1622  return wfSetVar( $this->mParserOptions, $options );
1623  }
1624  }
1625 
1633  public function setRevisionId( $revid ) {
1634  $val = is_null( $revid ) ? null : intval( $revid );
1635  return wfSetVar( $this->mRevisionId, $val );
1636  }
1637 
1643  public function getRevisionId() {
1644  return $this->mRevisionId;
1645  }
1646 
1654  public function setRevisionTimestamp( $timestamp ) {
1655  return wfSetVar( $this->mRevisionTimestamp, $timestamp );
1656  }
1657 
1664  public function getRevisionTimestamp() {
1666  }
1667 
1674  public function setFileVersion( $file ) {
1675  $val = null;
1676  if ( $file instanceof File && $file->exists() ) {
1677  $val = [ 'time' => $file->getTimestamp(), 'sha1' => $file->getSha1() ];
1678  }
1679  return wfSetVar( $this->mFileVersion, $val, true );
1680  }
1681 
1687  public function getFileVersion() {
1688  return $this->mFileVersion;
1689  }
1690 
1697  public function getTemplateIds() {
1698  return $this->mTemplateIds;
1699  }
1700 
1707  public function getFileSearchOptions() {
1708  return $this->mImageTimeKeys;
1709  }
1710 
1720  public function addWikiText( $text, $linestart = true, $interface = true ) {
1721  $title = $this->getTitle(); // Work around E_STRICT
1722  if ( !$title ) {
1723  throw new MWException( 'Title is null' );
1724  }
1725  $this->addWikiTextTitle( $text, $title, $linestart, /*tidy*/false, $interface );
1726  }
1727 
1735  public function addWikiTextWithTitle( $text, &$title, $linestart = true ) {
1736  $this->addWikiTextTitle( $text, $title, $linestart );
1737  }
1738 
1746  function addWikiTextTitleTidy( $text, &$title, $linestart = true ) {
1747  $this->addWikiTextTitle( $text, $title, $linestart, true );
1748  }
1749 
1756  public function addWikiTextTidy( $text, $linestart = true ) {
1757  $title = $this->getTitle();
1758  $this->addWikiTextTitleTidy( $text, $title, $linestart );
1759  }
1760 
1771  public function addWikiTextTitle( $text, Title $title, $linestart,
1772  $tidy = false, $interface = false
1773  ) {
1774  global $wgParser;
1775 
1776  $popts = $this->parserOptions();
1777  $oldTidy = $popts->setTidy( $tidy );
1778  $popts->setInterfaceMessage( (bool)$interface );
1779 
1780  $parserOutput = $wgParser->getFreshParser()->parse(
1781  $text, $title, $popts,
1782  $linestart, true, $this->mRevisionId
1783  );
1784 
1785  $popts->setTidy( $oldTidy );
1786 
1787  $this->addParserOutput( $parserOutput );
1788  }
1789 
1798  public function addParserOutputMetadata( $parserOutput ) {
1799  $this->mLanguageLinks += $parserOutput->getLanguageLinks();
1800  $this->addCategoryLinks( $parserOutput->getCategories() );
1801  $this->setIndicators( $parserOutput->getIndicators() );
1802  $this->mNewSectionLink = $parserOutput->getNewSection();
1803  $this->mHideNewSectionLink = $parserOutput->getHideNewSection();
1804 
1805  if ( !$parserOutput->isCacheable() ) {
1806  $this->enableClientCache( false );
1807  }
1808  $this->mNoGallery = $parserOutput->getNoGallery();
1809  $this->mHeadItems = array_merge( $this->mHeadItems, $parserOutput->getHeadItems() );
1810  $this->addModules( $parserOutput->getModules() );
1811  $this->addModuleScripts( $parserOutput->getModuleScripts() );
1812  $this->addModuleStyles( $parserOutput->getModuleStyles() );
1813  $this->addJsConfigVars( $parserOutput->getJsConfigVars() );
1814  $this->mPreventClickjacking = $this->mPreventClickjacking
1815  || $parserOutput->preventClickjacking();
1816 
1817  // Template versioning...
1818  foreach ( (array)$parserOutput->getTemplateIds() as $ns => $dbks ) {
1819  if ( isset( $this->mTemplateIds[$ns] ) ) {
1820  $this->mTemplateIds[$ns] = $dbks + $this->mTemplateIds[$ns];
1821  } else {
1822  $this->mTemplateIds[$ns] = $dbks;
1823  }
1824  }
1825  // File versioning...
1826  foreach ( (array)$parserOutput->getFileSearchOptions() as $dbk => $data ) {
1827  $this->mImageTimeKeys[$dbk] = $data;
1828  }
1829 
1830  // Hooks registered in the object
1831  $parserOutputHooks = $this->getConfig()->get( 'ParserOutputHooks' );
1832  foreach ( $parserOutput->getOutputHooks() as $hookInfo ) {
1833  list( $hookName, $data ) = $hookInfo;
1834  if ( isset( $parserOutputHooks[$hookName] ) ) {
1835  call_user_func( $parserOutputHooks[$hookName], $this, $parserOutput, $data );
1836  }
1837  }
1838 
1839  // Enable OOUI if requested via ParserOutput
1840  if ( $parserOutput->getEnableOOUI() ) {
1841  $this->enableOOUI();
1842  }
1843 
1844  // Include parser limit report
1845  if ( !$this->limitReportJSData ) {
1846  $this->limitReportJSData = $parserOutput->getLimitReportJSData();
1847  }
1848 
1849  // Link flags are ignored for now, but may in the future be
1850  // used to mark individual language links.
1851  $linkFlags = [];
1852  // Avoid PHP 7.1 warning of passing $this by reference
1853  $outputPage = $this;
1854  Hooks::run( 'LanguageLinks', [ $this->getTitle(), &$this->mLanguageLinks, &$linkFlags ] );
1855  Hooks::run( 'OutputPageParserOutput', [ &$outputPage, $parserOutput ] );
1856 
1857  // This check must be after 'OutputPageParserOutput' runs in addParserOutputMetadata
1858  // so that extensions may modify ParserOutput to toggle TOC.
1859  // This cannot be moved to addParserOutputText because that is not
1860  // called by EditPage for Preview.
1861  if ( $parserOutput->getTOCEnabled() && $parserOutput->getTOCHTML() ) {
1862  $this->mEnableTOC = true;
1863  }
1864  }
1865 
1873  public function addParserOutputContent( $parserOutput ) {
1874  $this->addParserOutputText( $parserOutput );
1875 
1876  $this->addModules( $parserOutput->getModules() );
1877  $this->addModuleScripts( $parserOutput->getModuleScripts() );
1878  $this->addModuleStyles( $parserOutput->getModuleStyles() );
1879 
1880  $this->addJsConfigVars( $parserOutput->getJsConfigVars() );
1881  }
1882 
1889  public function addParserOutputText( $parserOutput ) {
1890  $text = $parserOutput->getText();
1891  // Avoid PHP 7.1 warning of passing $this by reference
1892  $outputPage = $this;
1893  Hooks::run( 'OutputPageBeforeHTML', [ &$outputPage, &$text ] );
1894  $this->addHTML( $text );
1895  }
1896 
1902  function addParserOutput( $parserOutput ) {
1903  $this->addParserOutputMetadata( $parserOutput );
1904 
1905  // Touch section edit links only if not previously disabled
1906  if ( $parserOutput->getEditSectionTokens() ) {
1907  $parserOutput->setEditSectionTokens( $this->mEnableSectionEditLinks );
1908  }
1909 
1910  $this->addParserOutputText( $parserOutput );
1911  }
1912 
1918  public function addTemplate( &$template ) {
1919  $this->addHTML( $template->getHTML() );
1920  }
1921 
1934  public function parse( $text, $linestart = true, $interface = false, $language = null ) {
1935  global $wgParser;
1936 
1937  if ( is_null( $this->getTitle() ) ) {
1938  throw new MWException( 'Empty $mTitle in ' . __METHOD__ );
1939  }
1940 
1941  $popts = $this->parserOptions();
1942  if ( $interface ) {
1943  $popts->setInterfaceMessage( true );
1944  }
1945  if ( $language !== null ) {
1946  $oldLang = $popts->setTargetLanguage( $language );
1947  }
1948 
1949  $parserOutput = $wgParser->getFreshParser()->parse(
1950  $text, $this->getTitle(), $popts,
1951  $linestart, true, $this->mRevisionId
1952  );
1953 
1954  if ( $interface ) {
1955  $popts->setInterfaceMessage( false );
1956  }
1957  if ( $language !== null ) {
1958  $popts->setTargetLanguage( $oldLang );
1959  }
1960 
1961  return $parserOutput->getText();
1962  }
1963 
1974  public function parseInline( $text, $linestart = true, $interface = false ) {
1975  $parsed = $this->parse( $text, $linestart, $interface );
1976  return Parser::stripOuterParagraph( $parsed );
1977  }
1978 
1983  public function setSquidMaxage( $maxage ) {
1984  $this->setCdnMaxage( $maxage );
1985  }
1986 
1992  public function setCdnMaxage( $maxage ) {
1993  $this->mCdnMaxage = min( $maxage, $this->mCdnMaxageLimit );
1994  }
1995 
2002  public function lowerCdnMaxage( $maxage ) {
2003  $this->mCdnMaxageLimit = min( $maxage, $this->mCdnMaxageLimit );
2004  $this->setCdnMaxage( $this->mCdnMaxage );
2005  }
2006 
2020  public function adaptCdnTTL( $mtime, $minTTL = 0, $maxTTL = 0 ) {
2021  $minTTL = $minTTL ?: IExpiringStore::TTL_MINUTE;
2022  $maxTTL = $maxTTL ?: $this->getConfig()->get( 'SquidMaxage' );
2023 
2024  if ( $mtime === null || $mtime === false ) {
2025  return $minTTL; // entity does not exist
2026  }
2027 
2028  $age = time() - wfTimestamp( TS_UNIX, $mtime );
2029  $adaptiveTTL = max( 0.9 * $age, $minTTL );
2030  $adaptiveTTL = min( $adaptiveTTL, $maxTTL );
2031 
2032  $this->lowerCdnMaxage( (int)$adaptiveTTL );
2033 
2034  return $adaptiveTTL;
2035  }
2036 
2044  public function enableClientCache( $state ) {
2045  return wfSetVar( $this->mEnableClientCache, $state );
2046  }
2047 
2053  function getCacheVaryCookies() {
2054  static $cookies;
2055  if ( $cookies === null ) {
2056  $config = $this->getConfig();
2057  $cookies = array_merge(
2058  SessionManager::singleton()->getVaryCookies(),
2059  [
2060  'forceHTTPS',
2061  ],
2062  $config->get( 'CacheVaryCookies' )
2063  );
2064  Hooks::run( 'GetCacheVaryCookies', [ $this, &$cookies ] );
2065  }
2066  return $cookies;
2067  }
2068 
2076  $request = $this->getRequest();
2077  foreach ( $this->getCacheVaryCookies() as $cookieName ) {
2078  if ( $request->getCookie( $cookieName, '', '' ) !== '' ) {
2079  wfDebug( __METHOD__ . ": found $cookieName\n" );
2080  return true;
2081  }
2082  }
2083  wfDebug( __METHOD__ . ": no cache-varying cookies found\n" );
2084  return false;
2085  }
2086 
2095  public function addVaryHeader( $header, array $option = null ) {
2096  if ( !array_key_exists( $header, $this->mVaryHeader ) ) {
2097  $this->mVaryHeader[$header] = [];
2098  }
2099  if ( !is_array( $option ) ) {
2100  $option = [];
2101  }
2102  $this->mVaryHeader[$header] = array_unique( array_merge( $this->mVaryHeader[$header], $option ) );
2103  }
2104 
2111  public function getVaryHeader() {
2112  // If we vary on cookies, let's make sure it's always included here too.
2113  if ( $this->getCacheVaryCookies() ) {
2114  $this->addVaryHeader( 'Cookie' );
2115  }
2116 
2117  foreach ( SessionManager::singleton()->getVaryHeaders() as $header => $options ) {
2118  $this->addVaryHeader( $header, $options );
2119  }
2120  return 'Vary: ' . implode( ', ', array_keys( $this->mVaryHeader ) );
2121  }
2122 
2128  public function addLinkHeader( $header ) {
2129  $this->mLinkHeader[] = $header;
2130  }
2131 
2137  public function getLinkHeader() {
2138  if ( !$this->mLinkHeader ) {
2139  return false;
2140  }
2141 
2142  return 'Link: ' . implode( ',', $this->mLinkHeader );
2143  }
2144 
2150  public function getKeyHeader() {
2151  $cvCookies = $this->getCacheVaryCookies();
2152 
2153  $cookiesOption = [];
2154  foreach ( $cvCookies as $cookieName ) {
2155  $cookiesOption[] = 'param=' . $cookieName;
2156  }
2157  $this->addVaryHeader( 'Cookie', $cookiesOption );
2158 
2159  foreach ( SessionManager::singleton()->getVaryHeaders() as $header => $options ) {
2160  $this->addVaryHeader( $header, $options );
2161  }
2162 
2163  $headers = [];
2164  foreach ( $this->mVaryHeader as $header => $option ) {
2165  $newheader = $header;
2166  if ( is_array( $option ) && count( $option ) > 0 ) {
2167  $newheader .= ';' . implode( ';', $option );
2168  }
2169  $headers[] = $newheader;
2170  }
2171  $key = 'Key: ' . implode( ',', $headers );
2172 
2173  return $key;
2174  }
2175 
2184  function addAcceptLanguage() {
2185  $title = $this->getTitle();
2186  if ( !$title instanceof Title ) {
2187  return;
2188  }
2189 
2190  $lang = $title->getPageLanguage();
2191  if ( !$this->getRequest()->getCheck( 'variant' ) && $lang->hasVariants() ) {
2192  $variants = $lang->getVariants();
2193  $aloption = [];
2194  foreach ( $variants as $variant ) {
2195  if ( $variant === $lang->getCode() ) {
2196  continue;
2197  } else {
2198  $aloption[] = 'substr=' . $variant;
2199 
2200  // IE and some other browsers use BCP 47 standards in
2201  // their Accept-Language header, like "zh-CN" or "zh-Hant".
2202  // We should handle these too.
2203  $variantBCP47 = wfBCP47( $variant );
2204  if ( $variantBCP47 !== $variant ) {
2205  $aloption[] = 'substr=' . $variantBCP47;
2206  }
2207  }
2208  }
2209  $this->addVaryHeader( 'Accept-Language', $aloption );
2210  }
2211  }
2212 
2223  public function preventClickjacking( $enable = true ) {
2224  $this->mPreventClickjacking = $enable;
2225  }
2226 
2232  public function allowClickjacking() {
2233  $this->mPreventClickjacking = false;
2234  }
2235 
2242  public function getPreventClickjacking() {
2244  }
2245 
2253  public function getFrameOptions() {
2254  $config = $this->getConfig();
2255  if ( $config->get( 'BreakFrames' ) ) {
2256  return 'DENY';
2257  } elseif ( $this->mPreventClickjacking && $config->get( 'EditPageFrameOptions' ) ) {
2258  return $config->get( 'EditPageFrameOptions' );
2259  }
2260  return false;
2261  }
2262 
2266  public function sendCacheControl() {
2267  $response = $this->getRequest()->response();
2268  $config = $this->getConfig();
2269 
2270  $this->addVaryHeader( 'Cookie' );
2271  $this->addAcceptLanguage();
2272 
2273  # don't serve compressed data to clients who can't handle it
2274  # maintain different caches for logged-in users and non-logged in ones
2275  $response->header( $this->getVaryHeader() );
2276 
2277  if ( $config->get( 'UseKeyHeader' ) ) {
2278  $response->header( $this->getKeyHeader() );
2279  }
2280 
2281  if ( $this->mEnableClientCache ) {
2282  if (
2283  $config->get( 'UseSquid' ) &&
2284  !$response->hasCookies() &&
2285  !SessionManager::getGlobalSession()->isPersistent() &&
2286  !$this->isPrintable() &&
2287  $this->mCdnMaxage != 0 &&
2288  !$this->haveCacheVaryCookies()
2289  ) {
2290  if ( $config->get( 'UseESI' ) ) {
2291  # We'll purge the proxy cache explicitly, but require end user agents
2292  # to revalidate against the proxy on each visit.
2293  # Surrogate-Control controls our CDN, Cache-Control downstream caches
2294  wfDebug( __METHOD__ .
2295  ": proxy caching with ESI; {$this->mLastModified} **", 'private' );
2296  # start with a shorter timeout for initial testing
2297  # header( 'Surrogate-Control: max-age=2678400+2678400, content="ESI/1.0"');
2298  $response->header(
2299  "Surrogate-Control: max-age={$config->get( 'SquidMaxage' )}" .
2300  "+{$this->mCdnMaxage}, content=\"ESI/1.0\""
2301  );
2302  $response->header( 'Cache-Control: s-maxage=0, must-revalidate, max-age=0' );
2303  } else {
2304  # We'll purge the proxy cache for anons explicitly, but require end user agents
2305  # to revalidate against the proxy on each visit.
2306  # IMPORTANT! The CDN needs to replace the Cache-Control header with
2307  # Cache-Control: s-maxage=0, must-revalidate, max-age=0
2308  wfDebug( __METHOD__ .
2309  ": local proxy caching; {$this->mLastModified} **", 'private' );
2310  # start with a shorter timeout for initial testing
2311  # header( "Cache-Control: s-maxage=2678400, must-revalidate, max-age=0" );
2312  $response->header( "Cache-Control: " .
2313  "s-maxage={$this->mCdnMaxage}, must-revalidate, max-age=0" );
2314  }
2315  } else {
2316  # We do want clients to cache if they can, but they *must* check for updates
2317  # on revisiting the page.
2318  wfDebug( __METHOD__ . ": private caching; {$this->mLastModified} **", 'private' );
2319  $response->header( 'Expires: ' . gmdate( 'D, d M Y H:i:s', 0 ) . ' GMT' );
2320  $response->header( "Cache-Control: private, must-revalidate, max-age=0" );
2321  }
2322  if ( $this->mLastModified ) {
2323  $response->header( "Last-Modified: {$this->mLastModified}" );
2324  }
2325  } else {
2326  wfDebug( __METHOD__ . ": no caching **", 'private' );
2327 
2328  # In general, the absence of a last modified header should be enough to prevent
2329  # the client from using its cache. We send a few other things just to make sure.
2330  $response->header( 'Expires: ' . gmdate( 'D, d M Y H:i:s', 0 ) . ' GMT' );
2331  $response->header( 'Cache-Control: no-cache, no-store, max-age=0, must-revalidate' );
2332  $response->header( 'Pragma: no-cache' );
2333  }
2334  }
2335 
2346  public function output( $return = false ) {
2348 
2349  if ( $this->mDoNothing ) {
2350  return $return ? '' : null;
2351  }
2352 
2353  $response = $this->getRequest()->response();
2354  $config = $this->getConfig();
2355 
2356  if ( $this->mRedirect != '' ) {
2357  # Standards require redirect URLs to be absolute
2358  $this->mRedirect = wfExpandUrl( $this->mRedirect, PROTO_CURRENT );
2359 
2360  $redirect = $this->mRedirect;
2362 
2363  if ( Hooks::run( "BeforePageRedirect", [ $this, &$redirect, &$code ] ) ) {
2364  if ( $code == '301' || $code == '303' ) {
2365  if ( !$config->get( 'DebugRedirects' ) ) {
2366  $response->statusHeader( $code );
2367  }
2368  $this->mLastModified = wfTimestamp( TS_RFC2822 );
2369  }
2370  if ( $config->get( 'VaryOnXFP' ) ) {
2371  $this->addVaryHeader( 'X-Forwarded-Proto' );
2372  }
2373  $this->sendCacheControl();
2374 
2375  $response->header( "Content-Type: text/html; charset=utf-8" );
2376  if ( $config->get( 'DebugRedirects' ) ) {
2377  $url = htmlspecialchars( $redirect );
2378  print "<!DOCTYPE html>\n<html>\n<head>\n<title>Redirect</title>\n</head>\n<body>\n";
2379  print "<p>Location: <a href=\"$url\">$url</a></p>\n";
2380  print "</body>\n</html>\n";
2381  } else {
2382  $response->header( 'Location: ' . $redirect );
2383  }
2384  }
2385 
2386  return $return ? '' : null;
2387  } elseif ( $this->mStatusCode ) {
2388  $response->statusHeader( $this->mStatusCode );
2389  }
2390 
2391  # Buffer output; final headers may depend on later processing
2392  ob_start();
2393 
2394  $response->header( 'Content-type: ' . $config->get( 'MimeType' ) . '; charset=UTF-8' );
2395  $response->header( 'Content-language: ' . $wgContLang->getHtmlCode() );
2396 
2397  // Avoid Internet Explorer "compatibility view" in IE 8-10, so that
2398  // jQuery etc. can work correctly.
2399  $response->header( 'X-UA-Compatible: IE=Edge' );
2400 
2401  if ( !$this->mArticleBodyOnly ) {
2402  $sk = $this->getSkin();
2403 
2404  if ( $sk->shouldPreloadLogo() ) {
2405  $this->addLogoPreloadLinkHeaders();
2406  }
2407  }
2408 
2409  $linkHeader = $this->getLinkHeader();
2410  if ( $linkHeader ) {
2411  $response->header( $linkHeader );
2412  }
2413 
2414  // Prevent framing, if requested
2415  $frameOptions = $this->getFrameOptions();
2416  if ( $frameOptions ) {
2417  $response->header( "X-Frame-Options: $frameOptions" );
2418  }
2419 
2420  if ( $this->mArticleBodyOnly ) {
2421  echo $this->mBodytext;
2422  } else {
2423  // Enable safe mode if requested
2424  if ( $this->getRequest()->getBool( 'safemode' ) ) {
2425  $this->disallowUserJs();
2426  }
2427 
2428  $sk = $this->getSkin();
2429  foreach ( $sk->getDefaultModules() as $group ) {
2430  $this->addModules( $group );
2431  }
2432 
2433  MWDebug::addModules( $this );
2434 
2435  // Avoid PHP 7.1 warning of passing $this by reference
2436  $outputPage = $this;
2437  // Hook that allows last minute changes to the output page, e.g.
2438  // adding of CSS or Javascript by extensions.
2439  Hooks::run( 'BeforePageDisplay', [ &$outputPage, &$sk ] );
2440 
2441  try {
2442  $sk->outputPage();
2443  } catch ( Exception $e ) {
2444  ob_end_clean(); // bug T129657
2445  throw $e;
2446  }
2447  }
2448 
2449  try {
2450  // This hook allows last minute changes to final overall output by modifying output buffer
2451  Hooks::run( 'AfterFinalPageOutput', [ $this ] );
2452  } catch ( Exception $e ) {
2453  ob_end_clean(); // bug T129657
2454  throw $e;
2455  }
2456 
2457  $this->sendCacheControl();
2458 
2459  if ( $return ) {
2460  return ob_get_clean();
2461  } else {
2462  ob_end_flush();
2463  return null;
2464  }
2465  }
2466 
2477  public function prepareErrorPage( $pageTitle, $htmlTitle = false ) {
2478  $this->setPageTitle( $pageTitle );
2479  if ( $htmlTitle !== false ) {
2480  $this->setHTMLTitle( $htmlTitle );
2481  }
2482  $this->setRobotPolicy( 'noindex,nofollow' );
2483  $this->setArticleRelated( false );
2484  $this->enableClientCache( false );
2485  $this->mRedirect = '';
2486  $this->clearSubtitle();
2487  $this->clearHTML();
2488  }
2489 
2502  public function showErrorPage( $title, $msg, $params = [] ) {
2503  if ( !$title instanceof Message ) {
2504  $title = $this->msg( $title );
2505  }
2506 
2507  $this->prepareErrorPage( $title );
2508 
2509  if ( $msg instanceof Message ) {
2510  if ( $params !== [] ) {
2511  trigger_error( 'Argument ignored: $params. The message parameters argument '
2512  . 'is discarded when the $msg argument is a Message object instead of '
2513  . 'a string.', E_USER_NOTICE );
2514  }
2515  $this->addHTML( $msg->parseAsBlock() );
2516  } else {
2517  $this->addWikiMsgArray( $msg, $params );
2518  }
2519 
2520  $this->returnToMain();
2521  }
2522 
2529  public function showPermissionsErrorPage( array $errors, $action = null ) {
2530  foreach ( $errors as $key => $error ) {
2531  $errors[$key] = (array)$error;
2532  }
2533 
2534  // For some action (read, edit, create and upload), display a "login to do this action"
2535  // error if all of the following conditions are met:
2536  // 1. the user is not logged in
2537  // 2. the only error is insufficient permissions (i.e. no block or something else)
2538  // 3. the error can be avoided simply by logging in
2539  if ( in_array( $action, [ 'read', 'edit', 'createpage', 'createtalk', 'upload' ] )
2540  && $this->getUser()->isAnon() && count( $errors ) == 1 && isset( $errors[0][0] )
2541  && ( $errors[0][0] == 'badaccess-groups' || $errors[0][0] == 'badaccess-group0' )
2542  && ( User::groupHasPermission( 'user', $action )
2543  || User::groupHasPermission( 'autoconfirmed', $action ) )
2544  ) {
2545  $displayReturnto = null;
2546 
2547  # Due to T34276, if a user does not have read permissions,
2548  # $this->getTitle() will just give Special:Badtitle, which is
2549  # not especially useful as a returnto parameter. Use the title
2550  # from the request instead, if there was one.
2551  $request = $this->getRequest();
2552  $returnto = Title::newFromText( $request->getVal( 'title', '' ) );
2553  if ( $action == 'edit' ) {
2554  $msg = 'whitelistedittext';
2555  $displayReturnto = $returnto;
2556  } elseif ( $action == 'createpage' || $action == 'createtalk' ) {
2557  $msg = 'nocreatetext';
2558  } elseif ( $action == 'upload' ) {
2559  $msg = 'uploadnologintext';
2560  } else { # Read
2561  $msg = 'loginreqpagetext';
2562  $displayReturnto = Title::newMainPage();
2563  }
2564 
2565  $query = [];
2566 
2567  if ( $returnto ) {
2568  $query['returnto'] = $returnto->getPrefixedText();
2569 
2570  if ( !$request->wasPosted() ) {
2571  $returntoquery = $request->getValues();
2572  unset( $returntoquery['title'] );
2573  unset( $returntoquery['returnto'] );
2574  unset( $returntoquery['returntoquery'] );
2575  $query['returntoquery'] = wfArrayToCgi( $returntoquery );
2576  }
2577  }
2578  $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
2579  $loginLink = $linkRenderer->makeKnownLink(
2580  SpecialPage::getTitleFor( 'Userlogin' ),
2581  $this->msg( 'loginreqlink' )->text(),
2582  [],
2583  $query
2584  );
2585 
2586  $this->prepareErrorPage( $this->msg( 'loginreqtitle' ) );
2587  $this->addHTML( $this->msg( $msg )->rawParams( $loginLink )->parse() );
2588 
2589  # Don't return to a page the user can't read otherwise
2590  # we'll end up in a pointless loop
2591  if ( $displayReturnto && $displayReturnto->userCan( 'read', $this->getUser() ) ) {
2592  $this->returnToMain( null, $displayReturnto );
2593  }
2594  } else {
2595  $this->prepareErrorPage( $this->msg( 'permissionserrors' ) );
2596  $this->addWikiText( $this->formatPermissionsErrorMessage( $errors, $action ) );
2597  }
2598  }
2599 
2606  public function versionRequired( $version ) {
2607  $this->prepareErrorPage( $this->msg( 'versionrequired', $version ) );
2608 
2609  $this->addWikiMsg( 'versionrequiredtext', $version );
2610  $this->returnToMain();
2611  }
2612 
2620  public function formatPermissionsErrorMessage( array $errors, $action = null ) {
2621  if ( $action == null ) {
2622  $text = $this->msg( 'permissionserrorstext', count( $errors ) )->plain() . "\n\n";
2623  } else {
2624  $action_desc = $this->msg( "action-$action" )->plain();
2625  $text = $this->msg(
2626  'permissionserrorstext-withaction',
2627  count( $errors ),
2628  $action_desc
2629  )->plain() . "\n\n";
2630  }
2631 
2632  if ( count( $errors ) > 1 ) {
2633  $text .= '<ul class="permissions-errors">' . "\n";
2634 
2635  foreach ( $errors as $error ) {
2636  $text .= '<li>';
2637  $text .= call_user_func_array( [ $this, 'msg' ], $error )->plain();
2638  $text .= "</li>\n";
2639  }
2640  $text .= '</ul>';
2641  } else {
2642  $text .= "<div class=\"permissions-errors\">\n" .
2643  call_user_func_array( [ $this, 'msg' ], reset( $errors ) )->plain() .
2644  "\n</div>";
2645  }
2646 
2647  return $text;
2648  }
2649 
2661  public function readOnlyPage() {
2662  if ( func_num_args() > 0 ) {
2663  throw new MWException( __METHOD__ . ' no longer accepts arguments since 1.25.' );
2664  }
2665 
2666  throw new ReadOnlyError;
2667  }
2668 
2675  public function rateLimited() {
2676  wfDeprecated( __METHOD__, '1.25' );
2677  throw new ThrottledError;
2678  }
2679 
2689  public function showLagWarning( $lag ) {
2690  $config = $this->getConfig();
2691  if ( $lag >= $config->get( 'SlaveLagWarning' ) ) {
2692  $lag = floor( $lag ); // floor to avoid nano seconds to display
2693  $message = $lag < $config->get( 'SlaveLagCritical' )
2694  ? 'lag-warn-normal'
2695  : 'lag-warn-high';
2696  $wrap = Html::rawElement( 'div', [ 'class' => "mw-{$message}" ], "\n$1\n" );
2697  $this->wrapWikiMsg( "$wrap\n", [ $message, $this->getLanguage()->formatNum( $lag ) ] );
2698  }
2699  }
2700 
2701  public function showFatalError( $message ) {
2702  $this->prepareErrorPage( $this->msg( 'internalerror' ) );
2703 
2704  $this->addHTML( $message );
2705  }
2706 
2707  public function showUnexpectedValueError( $name, $val ) {
2708  $this->showFatalError( $this->msg( 'unexpected', $name, $val )->text() );
2709  }
2710 
2711  public function showFileCopyError( $old, $new ) {
2712  $this->showFatalError( $this->msg( 'filecopyerror', $old, $new )->text() );
2713  }
2714 
2715  public function showFileRenameError( $old, $new ) {
2716  $this->showFatalError( $this->msg( 'filerenameerror', $old, $new )->text() );
2717  }
2718 
2719  public function showFileDeleteError( $name ) {
2720  $this->showFatalError( $this->msg( 'filedeleteerror', $name )->text() );
2721  }
2722 
2723  public function showFileNotFoundError( $name ) {
2724  $this->showFatalError( $this->msg( 'filenotfound', $name )->text() );
2725  }
2726 
2735  public function addReturnTo( $title, array $query = [], $text = null, $options = [] ) {
2736  $linkRenderer = MediaWikiServices::getInstance()
2737  ->getLinkRendererFactory()->createFromLegacyOptions( $options );
2738  $link = $this->msg( 'returnto' )->rawParams(
2739  $linkRenderer->makeLink( $title, $text, [], $query ) )->escaped();
2740  $this->addHTML( "<p id=\"mw-returnto\">{$link}</p>\n" );
2741  }
2742 
2751  public function returnToMain( $unused = null, $returnto = null, $returntoquery = null ) {
2752  if ( $returnto == null ) {
2753  $returnto = $this->getRequest()->getText( 'returnto' );
2754  }
2755 
2756  if ( $returntoquery == null ) {
2757  $returntoquery = $this->getRequest()->getText( 'returntoquery' );
2758  }
2759 
2760  if ( $returnto === '' ) {
2761  $returnto = Title::newMainPage();
2762  }
2763 
2764  if ( is_object( $returnto ) ) {
2765  $titleObj = $returnto;
2766  } else {
2767  $titleObj = Title::newFromText( $returnto );
2768  }
2769  // We don't want people to return to external interwiki. That
2770  // might potentially be used as part of a phishing scheme
2771  if ( !is_object( $titleObj ) || $titleObj->isExternal() ) {
2772  $titleObj = Title::newMainPage();
2773  }
2774 
2775  $this->addReturnTo( $titleObj, wfCgiToArray( $returntoquery ) );
2776  }
2777 
2778  private function getRlClientContext() {
2779  if ( !$this->rlClientContext ) {
2780  $query = ResourceLoader::makeLoaderQuery(
2781  [], // modules; not relevant
2782  $this->getLanguage()->getCode(),
2783  $this->getSkin()->getSkinName(),
2784  $this->getUser()->isLoggedIn() ? $this->getUser()->getName() : null,
2785  null, // version; not relevant
2786  ResourceLoader::inDebugMode(),
2787  null, // only; not relevant
2788  $this->isPrintable(),
2789  $this->getRequest()->getBool( 'handheld' )
2790  );
2791  $this->rlClientContext = new ResourceLoaderContext(
2792  $this->getResourceLoader(),
2793  new FauxRequest( $query )
2794  );
2795  }
2796  return $this->rlClientContext;
2797  }
2798 
2810  public function getRlClient() {
2811  if ( !$this->rlClient ) {
2812  $context = $this->getRlClientContext();
2813  $rl = $this->getResourceLoader();
2814  $this->addModules( [
2815  'user.options',
2816  'user.tokens',
2817  ] );
2818  $this->addModuleStyles( [
2819  'site.styles',
2820  'noscript',
2821  'user.styles',
2822  ] );
2823  $this->getSkin()->setupSkinUserCss( $this );
2824 
2825  // Prepare exempt modules for buildExemptModules()
2826  $exemptGroups = [ 'site' => [], 'noscript' => [], 'private' => [], 'user' => [] ];
2827  $exemptStates = [];
2828  $moduleStyles = $this->getModuleStyles( /*filter*/ true );
2829 
2830  // Preload getTitleInfo for isKnownEmpty calls below and in ResourceLoaderClientHtml
2831  // Separate user-specific batch for improved cache-hit ratio.
2832  $userBatch = [ 'user.styles', 'user' ];
2833  $siteBatch = array_diff( $moduleStyles, $userBatch );
2834  $dbr = wfGetDB( DB_REPLICA );
2837 
2838  // Filter out modules handled by buildExemptModules()
2839  $moduleStyles = array_filter( $moduleStyles,
2840  function ( $name ) use ( $rl, $context, &$exemptGroups, &$exemptStates ) {
2841  $module = $rl->getModule( $name );
2842  if ( $module ) {
2843  if ( $name === 'user.styles' && $this->isUserCssPreview() ) {
2844  $exemptStates[$name] = 'ready';
2845  // Special case in buildExemptModules()
2846  return false;
2847  }
2848  $group = $module->getGroup();
2849  if ( isset( $exemptGroups[$group] ) ) {
2850  $exemptStates[$name] = 'ready';
2851  if ( !$module->isKnownEmpty( $context ) ) {
2852  // E.g. Don't output empty <styles>
2853  $exemptGroups[$group][] = $name;
2854  }
2855  return false;
2856  }
2857  }
2858  return true;
2859  }
2860  );
2861  $this->rlExemptStyleModules = $exemptGroups;
2862 
2863  $isUserModuleFiltered = !$this->filterModules( [ 'user' ] );
2864  // If this page filters out 'user', makeResourceLoaderLink will drop it.
2865  // Avoid indefinite "loading" state or untrue "ready" state (T145368).
2866  if ( !$isUserModuleFiltered ) {
2867  // Manually handled by getBottomScripts()
2868  $userModule = $rl->getModule( 'user' );
2869  $userState = $userModule->isKnownEmpty( $context ) && !$this->isUserJsPreview()
2870  ? 'ready'
2871  : 'loading';
2872  $this->rlUserModuleState = $exemptStates['user'] = $userState;
2873  }
2874 
2876  $rlClient->setConfig( $this->getJSVars() );
2877  $rlClient->setModules( $this->getModules( /*filter*/ true ) );
2878  $rlClient->setModuleStyles( $moduleStyles );
2879  $rlClient->setModuleScripts( $this->getModuleScripts( /*filter*/ true ) );
2880  $rlClient->setExemptStates( $exemptStates );
2881  $this->rlClient = $rlClient;
2882  }
2883  return $this->rlClient;
2884  }
2885 
2891  public function headElement( Skin $sk, $includeStyle = true ) {
2893 
2894  $userdir = $this->getLanguage()->getDir();
2895  $sitedir = $wgContLang->getDir();
2896 
2897  $pieces = [];
2898  $pieces[] = Html::htmlHeader( Sanitizer::mergeAttributes(
2899  $this->getRlClient()->getDocumentAttributes(),
2901  ) );
2902  $pieces[] = Html::openElement( 'head' );
2903 
2904  if ( $this->getHTMLTitle() == '' ) {
2905  $this->setHTMLTitle( $this->msg( 'pagetitle', $this->getPageTitle() )->inContentLanguage() );
2906  }
2907 
2908  if ( !Html::isXmlMimeType( $this->getConfig()->get( 'MimeType' ) ) ) {
2909  // Add <meta charset="UTF-8">
2910  // This should be before <title> since it defines the charset used by
2911  // text including the text inside <title>.
2912  // The spec recommends defining XHTML5's charset using the XML declaration
2913  // instead of meta.
2914  // Our XML declaration is output by Html::htmlHeader.
2915  // https://html.spec.whatwg.org/multipage/semantics.html#attr-meta-http-equiv-content-type
2916  // https://html.spec.whatwg.org/multipage/semantics.html#charset
2917  $pieces[] = Html::element( 'meta', [ 'charset' => 'UTF-8' ] );
2918  }
2919 
2920  $pieces[] = Html::element( 'title', null, $this->getHTMLTitle() );
2921  $pieces[] = $this->getRlClient()->getHeadHtml();
2922  $pieces[] = $this->buildExemptModules();
2923  $pieces = array_merge( $pieces, array_values( $this->getHeadLinksArray() ) );
2924  $pieces = array_merge( $pieces, array_values( $this->mHeadItems ) );
2925 
2926  $min = ResourceLoader::inDebugMode() ? '' : '.min';
2927  // Use an IE conditional comment to serve the script only to old IE
2928  $pieces[] = '<!--[if lt IE 9]>' .
2929  Html::element( 'script', [
2930  'src' => self::transformResourcePath(
2931  $this->getConfig(),
2932  "/resources/lib/html5shiv/html5shiv{$min}.js"
2933  ),
2934  ] ) .
2935  '<![endif]-->';
2936 
2937  $pieces[] = Html::closeElement( 'head' );
2938 
2939  $bodyClasses = $this->mAdditionalBodyClasses;
2940  $bodyClasses[] = 'mediawiki';
2941 
2942  # Classes for LTR/RTL directionality support
2943  $bodyClasses[] = $userdir;
2944  $bodyClasses[] = "sitedir-$sitedir";
2945 
2946  $underline = $this->getUser()->getOption( 'underline' );
2947  if ( $underline < 2 ) {
2948  // The following classes can be used here:
2949  // * mw-underline-always
2950  // * mw-underline-never
2951  $bodyClasses[] = 'mw-underline-' . ( $underline ? 'always' : 'never' );
2952  }
2953 
2954  if ( $this->getLanguage()->capitalizeAllNouns() ) {
2955  # A <body> class is probably not the best way to do this . . .
2956  $bodyClasses[] = 'capitalize-all-nouns';
2957  }
2958 
2959  // Parser feature migration class
2960  // The idea is that this will eventually be removed, after the wikitext
2961  // which requires it is cleaned up.
2962  $bodyClasses[] = 'mw-hide-empty-elt';
2963 
2964  $bodyClasses[] = $sk->getPageClasses( $this->getTitle() );
2965  $bodyClasses[] = 'skin-' . Sanitizer::escapeClass( $sk->getSkinName() );
2966  $bodyClasses[] =
2967  'action-' . Sanitizer::escapeClass( Action::getActionName( $this->getContext() ) );
2968 
2969  $bodyAttrs = [];
2970  // While the implode() is not strictly needed, it's used for backwards compatibility
2971  // (this used to be built as a string and hooks likely still expect that).
2972  $bodyAttrs['class'] = implode( ' ', $bodyClasses );
2973 
2974  // Allow skins and extensions to add body attributes they need
2975  $sk->addToBodyAttributes( $this, $bodyAttrs );
2976  Hooks::run( 'OutputPageBodyAttributes', [ $this, $sk, &$bodyAttrs ] );
2977 
2978  $pieces[] = Html::openElement( 'body', $bodyAttrs );
2979 
2980  return self::combineWrappedStrings( $pieces );
2981  }
2982 
2988  public function getResourceLoader() {
2989  if ( is_null( $this->mResourceLoader ) ) {
2990  $this->mResourceLoader = new ResourceLoader(
2991  $this->getConfig(),
2992  LoggerFactory::getInstance( 'resourceloader' )
2993  );
2994  }
2995  return $this->mResourceLoader;
2996  }
2997 
3006  public function makeResourceLoaderLink( $modules, $only, array $extraQuery = [] ) {
3007  // Apply 'target' and 'origin' filters
3008  $modules = $this->filterModules( (array)$modules, null, $only );
3009 
3011  $this->getRlClientContext(),
3012  $modules,
3013  $only,
3014  $extraQuery
3015  );
3016  }
3017 
3024  protected static function combineWrappedStrings( array $chunks ) {
3025  // Filter out empty values
3026  $chunks = array_filter( $chunks, 'strlen' );
3027  return WrappedString::join( "\n", $chunks );
3028  }
3029 
3030  private function isUserJsPreview() {
3031  return $this->getConfig()->get( 'AllowUserJs' )
3032  && $this->getTitle()
3033  && $this->getTitle()->isJsSubpage()
3034  && $this->userCanPreview();
3035  }
3036 
3037  protected function isUserCssPreview() {
3038  return $this->getConfig()->get( 'AllowUserCss' )
3039  && $this->getTitle()
3040  && $this->getTitle()->isCssSubpage()
3041  && $this->userCanPreview();
3042  }
3043 
3050  public function getBottomScripts() {
3051  $chunks = [];
3052  $chunks[] = $this->getRlClient()->getBodyHtml();
3053 
3054  // Legacy non-ResourceLoader scripts
3055  $chunks[] = $this->mScripts;
3056 
3057  // Exempt 'user' module
3058  // - May need excludepages for live preview. (T28283)
3059  // - Must use TYPE_COMBINED so its response is handled by mw.loader.implement() which
3060  // ensures execution is scheduled after the "site" module.
3061  // - Don't load if module state is already resolved as "ready".
3062  if ( $this->rlUserModuleState === 'loading' ) {
3063  if ( $this->isUserJsPreview() ) {
3064  $chunks[] = $this->makeResourceLoaderLink( 'user', ResourceLoaderModule::TYPE_COMBINED,
3065  [ 'excludepage' => $this->getTitle()->getPrefixedDBkey() ]
3066  );
3067  $chunks[] = ResourceLoader::makeInlineScript(
3068  Xml::encodeJsCall( 'mw.loader.using', [
3069  [ 'user', 'site' ],
3070  new XmlJsCode(
3071  'function () {'
3072  . Xml::encodeJsCall( '$.globalEval', [
3073  $this->getRequest()->getText( 'wpTextbox1' )
3074  ] )
3075  . '}'
3076  )
3077  ] )
3078  );
3079  // FIXME: If the user is previewing, say, ./vector.js, his ./common.js will be loaded
3080  // asynchronously and may arrive *after* the inline script here. So the previewed code
3081  // may execute before ./common.js runs. Normally, ./common.js runs before ./vector.js.
3082  // Similarly, when previewing ./common.js and the user module does arrive first,
3083  // it will arrive without common.js and the inline script runs after.
3084  // Thus running common after the excluded subpage.
3085  } else {
3086  // Load normally
3087  $chunks[] = $this->makeResourceLoaderLink( 'user', ResourceLoaderModule::TYPE_COMBINED );
3088  }
3089  }
3090 
3091  if ( $this->limitReportJSData ) {
3092  $chunks[] = ResourceLoader::makeInlineScript(
3093  ResourceLoader::makeConfigSetScript(
3094  [ 'wgPageParseReport' => $this->limitReportJSData ]
3095  )
3096  );
3097  }
3098 
3099  return self::combineWrappedStrings( $chunks );
3100  }
3101 
3108  public function getJsConfigVars() {
3109  return $this->mJsConfigVars;
3110  }
3111 
3118  public function addJsConfigVars( $keys, $value = null ) {
3119  if ( is_array( $keys ) ) {
3120  foreach ( $keys as $key => $value ) {
3121  $this->mJsConfigVars[$key] = $value;
3122  }
3123  return;
3124  }
3125 
3126  $this->mJsConfigVars[$keys] = $value;
3127  }
3128 
3138  public function getJSVars() {
3140 
3141  $curRevisionId = 0;
3142  $articleId = 0;
3143  $canonicalSpecialPageName = false; # T23115
3144 
3145  $title = $this->getTitle();
3146  $ns = $title->getNamespace();
3147  $canonicalNamespace = MWNamespace::exists( $ns )
3149  : $title->getNsText();
3150 
3151  $sk = $this->getSkin();
3152  // Get the relevant title so that AJAX features can use the correct page name
3153  // when making API requests from certain special pages (T36972).
3154  $relevantTitle = $sk->getRelevantTitle();
3155  $relevantUser = $sk->getRelevantUser();
3156 
3157  if ( $ns == NS_SPECIAL ) {
3158  list( $canonicalSpecialPageName, /*...*/ ) =
3160  } elseif ( $this->canUseWikiPage() ) {
3161  $wikiPage = $this->getWikiPage();
3162  $curRevisionId = $wikiPage->getLatest();
3163  $articleId = $wikiPage->getId();
3164  }
3165 
3166  $lang = $title->getPageViewLanguage();
3167 
3168  // Pre-process information
3169  $separatorTransTable = $lang->separatorTransformTable();
3170  $separatorTransTable = $separatorTransTable ? $separatorTransTable : [];
3171  $compactSeparatorTransTable = [
3172  implode( "\t", array_keys( $separatorTransTable ) ),
3173  implode( "\t", $separatorTransTable ),
3174  ];
3175  $digitTransTable = $lang->digitTransformTable();
3176  $digitTransTable = $digitTransTable ? $digitTransTable : [];
3177  $compactDigitTransTable = [
3178  implode( "\t", array_keys( $digitTransTable ) ),
3179  implode( "\t", $digitTransTable ),
3180  ];
3181 
3182  $user = $this->getUser();
3183 
3184  $vars = [
3185  'wgCanonicalNamespace' => $canonicalNamespace,
3186  'wgCanonicalSpecialPageName' => $canonicalSpecialPageName,
3187  'wgNamespaceNumber' => $title->getNamespace(),
3188  'wgPageName' => $title->getPrefixedDBkey(),
3189  'wgTitle' => $title->getText(),
3190  'wgCurRevisionId' => $curRevisionId,
3191  'wgRevisionId' => (int)$this->getRevisionId(),
3192  'wgArticleId' => $articleId,
3193  'wgIsArticle' => $this->isArticle(),
3194  'wgIsRedirect' => $title->isRedirect(),
3195  'wgAction' => Action::getActionName( $this->getContext() ),
3196  'wgUserName' => $user->isAnon() ? null : $user->getName(),
3197  'wgUserGroups' => $user->getEffectiveGroups(),
3198  'wgCategories' => $this->getCategories(),
3199  'wgBreakFrames' => $this->getFrameOptions() == 'DENY',
3200  'wgPageContentLanguage' => $lang->getCode(),
3201  'wgPageContentModel' => $title->getContentModel(),
3202  'wgSeparatorTransformTable' => $compactSeparatorTransTable,
3203  'wgDigitTransformTable' => $compactDigitTransTable,
3204  'wgDefaultDateFormat' => $lang->getDefaultDateFormat(),
3205  'wgMonthNames' => $lang->getMonthNamesArray(),
3206  'wgMonthNamesShort' => $lang->getMonthAbbreviationsArray(),
3207  'wgRelevantPageName' => $relevantTitle->getPrefixedDBkey(),
3208  'wgRelevantArticleId' => $relevantTitle->getArticleID(),
3209  'wgRequestId' => WebRequest::getRequestId(),
3210  ];
3211 
3212  if ( $user->isLoggedIn() ) {
3213  $vars['wgUserId'] = $user->getId();
3214  $vars['wgUserEditCount'] = $user->getEditCount();
3215  $userReg = $user->getRegistration();
3216  $vars['wgUserRegistration'] = $userReg ? wfTimestamp( TS_UNIX, $userReg ) * 1000 : null;
3217  // Get the revision ID of the oldest new message on the user's talk
3218  // page. This can be used for constructing new message alerts on
3219  // the client side.
3220  $vars['wgUserNewMsgRevisionId'] = $user->getNewMessageRevisionId();
3221  }
3222 
3223  if ( $wgContLang->hasVariants() ) {
3224  $vars['wgUserVariant'] = $wgContLang->getPreferredVariant();
3225  }
3226  // Same test as SkinTemplate
3227  $vars['wgIsProbablyEditable'] = $title->quickUserCan( 'edit', $user )
3228  && ( $title->exists() || $title->quickUserCan( 'create', $user ) );
3229 
3230  $vars['wgRelevantPageIsProbablyEditable'] = $relevantTitle
3231  && $relevantTitle->quickUserCan( 'edit', $user )
3232  && ( $relevantTitle->exists() || $relevantTitle->quickUserCan( 'create', $user ) );
3233 
3234  foreach ( $title->getRestrictionTypes() as $type ) {
3235  $vars['wgRestriction' . ucfirst( $type )] = $title->getRestrictions( $type );
3236  }
3237 
3238  if ( $title->isMainPage() ) {
3239  $vars['wgIsMainPage'] = true;
3240  }
3241 
3242  if ( $this->mRedirectedFrom ) {
3243  $vars['wgRedirectedFrom'] = $this->mRedirectedFrom->getPrefixedDBkey();
3244  }
3245 
3246  if ( $relevantUser ) {
3247  $vars['wgRelevantUserName'] = $relevantUser->getName();
3248  }
3249 
3250  // Allow extensions to add their custom variables to the mw.config map.
3251  // Use the 'ResourceLoaderGetConfigVars' hook if the variable is not
3252  // page-dependant but site-wide (without state).
3253  // Alternatively, you may want to use OutputPage->addJsConfigVars() instead.
3254  Hooks::run( 'MakeGlobalVariablesScript', [ &$vars, $this ] );
3255 
3256  // Merge in variables from addJsConfigVars last
3257  return array_merge( $vars, $this->getJsConfigVars() );
3258  }
3259 
3269  public function userCanPreview() {
3270  $request = $this->getRequest();
3271  if (
3272  $request->getVal( 'action' ) !== 'submit' ||
3273  !$request->getCheck( 'wpPreview' ) ||
3274  !$request->wasPosted()
3275  ) {
3276  return false;
3277  }
3278 
3279  $user = $this->getUser();
3280 
3281  if ( !$user->isLoggedIn() ) {
3282  // Anons have predictable edit tokens
3283  return false;
3284  }
3285  if ( !$user->matchEditToken( $request->getVal( 'wpEditToken' ) ) ) {
3286  return false;
3287  }
3288 
3289  $title = $this->getTitle();
3290  if ( !$title->isJsSubpage() && !$title->isCssSubpage() ) {
3291  return false;
3292  }
3293  if ( !$title->isSubpageOf( $user->getUserPage() ) ) {
3294  // Don't execute another user's CSS or JS on preview (T85855)
3295  return false;
3296  }
3297 
3298  $errors = $title->getUserPermissionsErrors( 'edit', $user );
3299  if ( count( $errors ) !== 0 ) {
3300  return false;
3301  }
3302 
3303  return true;
3304  }
3305 
3309  public function getHeadLinksArray() {
3311 
3312  $tags = [];
3313  $config = $this->getConfig();
3314 
3315  $canonicalUrl = $this->mCanonicalUrl;
3316 
3317  $tags['meta-generator'] = Html::element( 'meta', [
3318  'name' => 'generator',
3319  'content' => "MediaWiki $wgVersion",
3320  ] );
3321 
3322  if ( $config->get( 'ReferrerPolicy' ) !== false ) {
3323  $tags['meta-referrer'] = Html::element( 'meta', [
3324  'name' => 'referrer',
3325  'content' => $config->get( 'ReferrerPolicy' )
3326  ] );
3327  }
3328 
3329  $p = "{$this->mIndexPolicy},{$this->mFollowPolicy}";
3330  if ( $p !== 'index,follow' ) {
3331  // http://www.robotstxt.org/wc/meta-user.html
3332  // Only show if it's different from the default robots policy
3333  $tags['meta-robots'] = Html::element( 'meta', [
3334  'name' => 'robots',
3335  'content' => $p,
3336  ] );
3337  }
3338 
3339  foreach ( $this->mMetatags as $tag ) {
3340  if ( strncasecmp( $tag[0], 'http:', 5 ) === 0 ) {
3341  $a = 'http-equiv';
3342  $tag[0] = substr( $tag[0], 5 );
3343  } elseif ( strncasecmp( $tag[0], 'og:', 3 ) === 0 ) {
3344  $a = 'property';
3345  } else {
3346  $a = 'name';
3347  }
3348  $tagName = "meta-{$tag[0]}";
3349  if ( isset( $tags[$tagName] ) ) {
3350  $tagName .= $tag[1];
3351  }
3352  $tags[$tagName] = Html::element( 'meta',
3353  [
3354  $a => $tag[0],
3355  'content' => $tag[1]
3356  ]
3357  );
3358  }
3359 
3360  foreach ( $this->mLinktags as $tag ) {
3361  $tags[] = Html::element( 'link', $tag );
3362  }
3363 
3364  # Universal edit button
3365  if ( $config->get( 'UniversalEditButton' ) && $this->isArticleRelated() ) {
3366  $user = $this->getUser();
3367  if ( $this->getTitle()->quickUserCan( 'edit', $user )
3368  && ( $this->getTitle()->exists() ||
3369  $this->getTitle()->quickUserCan( 'create', $user ) )
3370  ) {
3371  // Original UniversalEditButton
3372  $msg = $this->msg( 'edit' )->text();
3373  $tags['universal-edit-button'] = Html::element( 'link', [
3374  'rel' => 'alternate',
3375  'type' => 'application/x-wiki',
3376  'title' => $msg,
3377  'href' => $this->getTitle()->getEditURL(),
3378  ] );
3379  // Alternate edit link
3380  $tags['alternative-edit'] = Html::element( 'link', [
3381  'rel' => 'edit',
3382  'title' => $msg,
3383  'href' => $this->getTitle()->getEditURL(),
3384  ] );
3385  }
3386  }
3387 
3388  # Generally the order of the favicon and apple-touch-icon links
3389  # should not matter, but Konqueror (3.5.9 at least) incorrectly
3390  # uses whichever one appears later in the HTML source. Make sure
3391  # apple-touch-icon is specified first to avoid this.
3392  if ( $config->get( 'AppleTouchIcon' ) !== false ) {
3393  $tags['apple-touch-icon'] = Html::element( 'link', [
3394  'rel' => 'apple-touch-icon',
3395  'href' => $config->get( 'AppleTouchIcon' )
3396  ] );
3397  }
3398 
3399  if ( $config->get( 'Favicon' ) !== false ) {
3400  $tags['favicon'] = Html::element( 'link', [
3401  'rel' => 'shortcut icon',
3402  'href' => $config->get( 'Favicon' )
3403  ] );
3404  }
3405 
3406  # OpenSearch description link
3407  $tags['opensearch'] = Html::element( 'link', [
3408  'rel' => 'search',
3409  'type' => 'application/opensearchdescription+xml',
3410  'href' => wfScript( 'opensearch_desc' ),
3411  'title' => $this->msg( 'opensearch-desc' )->inContentLanguage()->text(),
3412  ] );
3413 
3414  if ( $config->get( 'EnableAPI' ) ) {
3415  # Real Simple Discovery link, provides auto-discovery information
3416  # for the MediaWiki API (and potentially additional custom API
3417  # support such as WordPress or Twitter-compatible APIs for a
3418  # blogging extension, etc)
3419  $tags['rsd'] = Html::element( 'link', [
3420  'rel' => 'EditURI',
3421  'type' => 'application/rsd+xml',
3422  // Output a protocol-relative URL here if $wgServer is protocol-relative.
3423  // Whether RSD accepts relative or protocol-relative URLs is completely
3424  // undocumented, though.
3425  'href' => wfExpandUrl( wfAppendQuery(
3426  wfScript( 'api' ),
3427  [ 'action' => 'rsd' ] ),
3429  ),
3430  ] );
3431  }
3432 
3433  # Language variants
3434  if ( !$config->get( 'DisableLangConversion' ) ) {
3435  $lang = $this->getTitle()->getPageLanguage();
3436  if ( $lang->hasVariants() ) {
3437  $variants = $lang->getVariants();
3438  foreach ( $variants as $variant ) {
3439  $tags["variant-$variant"] = Html::element( 'link', [
3440  'rel' => 'alternate',
3441  'hreflang' => wfBCP47( $variant ),
3442  'href' => $this->getTitle()->getLocalURL(
3443  [ 'variant' => $variant ] )
3444  ]
3445  );
3446  }
3447  # x-default link per https://support.google.com/webmasters/answer/189077?hl=en
3448  $tags["variant-x-default"] = Html::element( 'link', [
3449  'rel' => 'alternate',
3450  'hreflang' => 'x-default',
3451  'href' => $this->getTitle()->getLocalURL() ] );
3452  }
3453  }
3454 
3455  # Copyright
3456  if ( $this->copyrightUrl !== null ) {
3457  $copyright = $this->copyrightUrl;
3458  } else {
3459  $copyright = '';
3460  if ( $config->get( 'RightsPage' ) ) {
3461  $copy = Title::newFromText( $config->get( 'RightsPage' ) );
3462 
3463  if ( $copy ) {
3464  $copyright = $copy->getLocalURL();
3465  }
3466  }
3467 
3468  if ( !$copyright && $config->get( 'RightsUrl' ) ) {
3469  $copyright = $config->get( 'RightsUrl' );
3470  }
3471  }
3472 
3473  if ( $copyright ) {
3474  $tags['copyright'] = Html::element( 'link', [
3475  'rel' => 'license',
3476  'href' => $copyright ]
3477  );
3478  }
3479 
3480  # Feeds
3481  if ( $config->get( 'Feed' ) ) {
3482  $feedLinks = [];
3483 
3484  foreach ( $this->getSyndicationLinks() as $format => $link ) {
3485  # Use the page name for the title. In principle, this could
3486  # lead to issues with having the same name for different feeds
3487  # corresponding to the same page, but we can't avoid that at
3488  # this low a level.
3489 
3490  $feedLinks[] = $this->feedLink(
3491  $format,
3492  $link,
3493  # Used messages: 'page-rss-feed' and 'page-atom-feed' (for an easier grep)
3494  $this->msg(
3495  "page-{$format}-feed", $this->getTitle()->getPrefixedText()
3496  )->text()
3497  );
3498  }
3499 
3500  # Recent changes feed should appear on every page (except recentchanges,
3501  # that would be redundant). Put it after the per-page feed to avoid
3502  # changing existing behavior. It's still available, probably via a
3503  # menu in your browser. Some sites might have a different feed they'd
3504  # like to promote instead of the RC feed (maybe like a "Recent New Articles"
3505  # or "Breaking news" one). For this, we see if $wgOverrideSiteFeed is defined.
3506  # If so, use it instead.
3507  $sitename = $config->get( 'Sitename' );
3508  if ( $config->get( 'OverrideSiteFeed' ) ) {
3509  foreach ( $config->get( 'OverrideSiteFeed' ) as $type => $feedUrl ) {
3510  // Note, this->feedLink escapes the url.
3511  $feedLinks[] = $this->feedLink(
3512  $type,
3513  $feedUrl,
3514  $this->msg( "site-{$type}-feed", $sitename )->text()
3515  );
3516  }
3517  } elseif ( !$this->getTitle()->isSpecial( 'Recentchanges' ) ) {
3518  $rctitle = SpecialPage::getTitleFor( 'Recentchanges' );
3519  foreach ( $config->get( 'AdvertisedFeedTypes' ) as $format ) {
3520  $feedLinks[] = $this->feedLink(
3521  $format,
3522  $rctitle->getLocalURL( [ 'feed' => $format ] ),
3523  # For grep: 'site-rss-feed', 'site-atom-feed'
3524  $this->msg( "site-{$format}-feed", $sitename )->text()
3525  );
3526  }
3527  }
3528 
3529  # Allow extensions to change the list pf feeds. This hook is primarily for changing,
3530  # manipulating or removing existing feed tags. If you want to add new feeds, you should
3531  # use OutputPage::addFeedLink() instead.
3532  Hooks::run( 'AfterBuildFeedLinks', [ &$feedLinks ] );
3533 
3534  $tags += $feedLinks;
3535  }
3536 
3537  # Canonical URL
3538  if ( $config->get( 'EnableCanonicalServerLink' ) ) {
3539  if ( $canonicalUrl !== false ) {
3540  $canonicalUrl = wfExpandUrl( $canonicalUrl, PROTO_CANONICAL );
3541  } else {
3542  if ( $this->isArticleRelated() ) {
3543  // This affects all requests where "setArticleRelated" is true. This is
3544  // typically all requests that show content (query title, curid, oldid, diff),
3545  // and all wikipage actions (edit, delete, purge, info, history etc.).
3546  // It does not apply to File pages and Special pages.
3547  // 'history' and 'info' actions address page metadata rather than the page
3548  // content itself, so they may not be canonicalized to the view page url.
3549  // TODO: this ought to be better encapsulated in the Action class.
3550  $action = Action::getActionName( $this->getContext() );
3551  if ( in_array( $action, [ 'history', 'info' ] ) ) {
3552  $query = "action={$action}";
3553  } else {
3554  $query = '';
3555  }
3556  $canonicalUrl = $this->getTitle()->getCanonicalURL( $query );
3557  } else {
3558  $reqUrl = $this->getRequest()->getRequestURL();
3559  $canonicalUrl = wfExpandUrl( $reqUrl, PROTO_CANONICAL );
3560  }
3561  }
3562  }
3563  if ( $canonicalUrl !== false ) {
3564  $tags[] = Html::element( 'link', [
3565  'rel' => 'canonical',
3566  'href' => $canonicalUrl
3567  ] );
3568  }
3569 
3570  return $tags;
3571  }
3572 
3581  private function feedLink( $type, $url, $text ) {
3582  return Html::element( 'link', [
3583  'rel' => 'alternate',
3584  'type' => "application/$type+xml",
3585  'title' => $text,
3586  'href' => $url ]
3587  );
3588  }
3589 
3599  public function addStyle( $style, $media = '', $condition = '', $dir = '' ) {
3600  $options = [];
3601  if ( $media ) {
3602  $options['media'] = $media;
3603  }
3604  if ( $condition ) {
3605  $options['condition'] = $condition;
3606  }
3607  if ( $dir ) {
3608  $options['dir'] = $dir;
3609  }
3610  $this->styles[$style] = $options;
3611  }
3612 
3620  public function addInlineStyle( $style_css, $flip = 'noflip' ) {
3621  if ( $flip === 'flip' && $this->getLanguage()->isRTL() ) {
3622  # If wanted, and the interface is right-to-left, flip the CSS
3623  $style_css = CSSJanus::transform( $style_css, true, false );
3624  }
3625  $this->mInlineStyles .= Html::inlineStyle( $style_css );
3626  }
3627 
3633  protected function buildExemptModules() {
3635 
3636  $chunks = [];
3637  // Things that go after the ResourceLoaderDynamicStyles marker
3638  $append = [];
3639 
3640  // Exempt 'user' styles module (may need 'excludepages' for live preview)
3641  if ( $this->isUserCssPreview() ) {
3642  $append[] = $this->makeResourceLoaderLink(
3643  'user.styles',
3645  [ 'excludepage' => $this->getTitle()->getPrefixedDBkey() ]
3646  );
3647 
3648  // Load the previewed CSS. Janus it if needed.
3649  // User-supplied CSS is assumed to in the wiki's content language.
3650  $previewedCSS = $this->getRequest()->getText( 'wpTextbox1' );
3651  if ( $this->getLanguage()->getDir() !== $wgContLang->getDir() ) {
3652  $previewedCSS = CSSJanus::transform( $previewedCSS, true, false );
3653  }
3654  $append[] = Html::inlineStyle( $previewedCSS );
3655  }
3656 
3657  // We want site, private and user styles to override dynamically added styles from
3658  // general modules, but we want dynamically added styles to override statically added
3659  // style modules. So the order has to be:
3660  // - page style modules (formatted by ResourceLoaderClientHtml::getHeadHtml())
3661  // - dynamically loaded styles (added by mw.loader before ResourceLoaderDynamicStyles)
3662  // - ResourceLoaderDynamicStyles marker
3663  // - site/private/user styles
3664 
3665  // Add legacy styles added through addStyle()/addInlineStyle() here
3666  $chunks[] = implode( '', $this->buildCssLinksArray() ) . $this->mInlineStyles;
3667 
3668  $chunks[] = Html::element(
3669  'meta',
3670  [ 'name' => 'ResourceLoaderDynamicStyles', 'content' => '' ]
3671  );
3672 
3673  $separateReq = [ 'site.styles', 'user.styles' ];
3674  foreach ( $this->rlExemptStyleModules as $group => $moduleNames ) {
3675  // Combinable modules
3676  $chunks[] = $this->makeResourceLoaderLink(
3677  array_diff( $moduleNames, $separateReq ),
3679  );
3680 
3681  foreach ( array_intersect( $moduleNames, $separateReq ) as $name ) {
3682  // These require their own dedicated request in order to support "@import"
3683  // syntax, which is incompatible with concatenation. (T147667, T37562)
3684  $chunks[] = $this->makeResourceLoaderLink( $name,
3686  );
3687  }
3688  }
3689 
3690  return self::combineWrappedStrings( array_merge( $chunks, $append ) );
3691  }
3692 
3696  public function buildCssLinksArray() {
3697  $links = [];
3698 
3699  // Add any extension CSS
3700  foreach ( $this->mExtStyles as $url ) {
3701  $this->addStyle( $url );
3702  }
3703  $this->mExtStyles = [];
3704 
3705  foreach ( $this->styles as $file => $options ) {
3706  $link = $this->styleLink( $file, $options );
3707  if ( $link ) {
3708  $links[$file] = $link;
3709  }
3710  }
3711  return $links;
3712  }
3713 
3721  protected function styleLink( $style, array $options ) {
3722  if ( isset( $options['dir'] ) ) {
3723  if ( $this->getLanguage()->getDir() != $options['dir'] ) {
3724  return '';
3725  }
3726  }
3727 
3728  if ( isset( $options['media'] ) ) {
3729  $media = self::transformCssMedia( $options['media'] );
3730  if ( is_null( $media ) ) {
3731  return '';
3732  }
3733  } else {
3734  $media = 'all';
3735  }
3736 
3737  if ( substr( $style, 0, 1 ) == '/' ||
3738  substr( $style, 0, 5 ) == 'http:' ||
3739  substr( $style, 0, 6 ) == 'https:' ) {
3740  $url = $style;
3741  } else {
3742  $config = $this->getConfig();
3743  $url = $config->get( 'StylePath' ) . '/' . $style . '?' .
3744  $config->get( 'StyleVersion' );
3745  }
3746 
3747  $link = Html::linkedStyle( $url, $media );
3748 
3749  if ( isset( $options['condition'] ) ) {
3750  $condition = htmlspecialchars( $options['condition'] );
3751  $link = "<!--[if $condition]>$link<![endif]-->";
3752  }
3753  return $link;
3754  }
3755 
3777  public static function transformResourcePath( Config $config, $path ) {
3778  global $IP;
3779 
3780  $localDir = $IP;
3781  $remotePathPrefix = $config->get( 'ResourceBasePath' );
3782  if ( $remotePathPrefix === '' ) {
3783  // The configured base path is required to be empty string for
3784  // wikis in the domain root
3785  $remotePath = '/';
3786  } else {
3787  $remotePath = $remotePathPrefix;
3788  }
3789  if ( strpos( $path, $remotePath ) !== 0 || substr( $path, 0, 2 ) === '//' ) {
3790  // - Path is outside wgResourceBasePath, ignore.
3791  // - Path is protocol-relative. Fixes T155310. Not supported by RelPath lib.
3792  return $path;
3793  }
3794  // For files in resources, extensions/ or skins/, ResourceBasePath is preferred here.
3795  // For other misc files in $IP, we'll fallback to that as well. There is, however, a fourth
3796  // supported dir/path pair in the configuration (wgUploadDirectory, wgUploadPath)
3797  // which is not expected to be in wgResourceBasePath on CDNs. (T155146)
3798  $uploadPath = $config->get( 'UploadPath' );
3799  if ( strpos( $path, $uploadPath ) === 0 ) {
3800  $localDir = $config->get( 'UploadDirectory' );
3801  $remotePathPrefix = $remotePath = $uploadPath;
3802  }
3803 
3804  $path = RelPath\getRelativePath( $path, $remotePath );
3805  return self::transformFilePath( $remotePathPrefix, $localDir, $path );
3806  }
3807 
3819  public static function transformFilePath( $remotePathPrefix, $localPath, $file ) {
3820  $hash = md5_file( "$localPath/$file" );
3821  if ( $hash === false ) {
3822  wfLogWarning( __METHOD__ . ": Failed to hash $localPath/$file" );
3823  $hash = '';
3824  }
3825  return "$remotePathPrefix/$file?" . substr( $hash, 0, 5 );
3826  }
3827 
3835  public static function transformCssMedia( $media ) {
3837 
3838  // https://www.w3.org/TR/css3-mediaqueries/#syntax
3839  $screenMediaQueryRegex = '/^(?:only\s+)?screen\b/i';
3840 
3841  // Switch in on-screen display for media testing
3842  $switches = [
3843  'printable' => 'print',
3844  'handheld' => 'handheld',
3845  ];
3846  foreach ( $switches as $switch => $targetMedia ) {
3847  if ( $wgRequest->getBool( $switch ) ) {
3848  if ( $media == $targetMedia ) {
3849  $media = '';
3850  } elseif ( preg_match( $screenMediaQueryRegex, $media ) === 1 ) {
3851  /* This regex will not attempt to understand a comma-separated media_query_list
3852  *
3853  * Example supported values for $media:
3854  * 'screen', 'only screen', 'screen and (min-width: 982px)' ),
3855  * Example NOT supported value for $media:
3856  * '3d-glasses, screen, print and resolution > 90dpi'
3857  *
3858  * If it's a print request, we never want any kind of screen stylesheets
3859  * If it's a handheld request (currently the only other choice with a switch),
3860  * we don't want simple 'screen' but we might want screen queries that
3861  * have a max-width or something, so we'll pass all others on and let the
3862  * client do the query.
3863  */
3864  if ( $targetMedia == 'print' || $media == 'screen' ) {
3865  return null;
3866  }
3867  }
3868  }
3869  }
3870 
3871  return $media;
3872  }
3873 
3880  public function addWikiMsg( /*...*/ ) {
3881  $args = func_get_args();
3882  $name = array_shift( $args );
3883  $this->addWikiMsgArray( $name, $args );
3884  }
3885 
3894  public function addWikiMsgArray( $name, $args ) {
3895  $this->addHTML( $this->msg( $name, $args )->parseAsBlock() );
3896  }
3897 
3923  public function wrapWikiMsg( $wrap /*, ...*/ ) {
3924  $msgSpecs = func_get_args();
3925  array_shift( $msgSpecs );
3926  $msgSpecs = array_values( $msgSpecs );
3927  $s = $wrap;
3928  foreach ( $msgSpecs as $n => $spec ) {
3929  if ( is_array( $spec ) ) {
3930  $args = $spec;
3931  $name = array_shift( $args );
3932  if ( isset( $args['options'] ) ) {
3933  unset( $args['options'] );
3934  wfDeprecated(
3935  'Adding "options" to ' . __METHOD__ . ' is no longer supported',
3936  '1.20'
3937  );
3938  }
3939  } else {
3940  $args = [];
3941  $name = $spec;
3942  }
3943  $s = str_replace( '$' . ( $n + 1 ), $this->msg( $name, $args )->plain(), $s );
3944  }
3945  $this->addWikiText( $s );
3946  }
3947 
3953  public function isTOCEnabled() {
3954  return $this->mEnableTOC;
3955  }
3956 
3962  public function enableSectionEditLinks( $flag = true ) {
3963  $this->mEnableSectionEditLinks = $flag;
3964  }
3965 
3970  public function sectionEditLinksEnabled() {
3972  }
3973 
3981  public static function setupOOUI( $skinName = 'default', $dir = 'ltr' ) {
3983  $theme = isset( $themes[$skinName] ) ? $themes[$skinName] : $themes['default'];
3984  // For example, 'OOUI\WikimediaUITheme'.
3985  $themeClass = "OOUI\\{$theme}Theme";
3986  OOUI\Theme::setSingleton( new $themeClass() );
3987  OOUI\Element::setDefaultDir( $dir );
3988  }
3989 
3996  public function enableOOUI() {
3998  strtolower( $this->getSkin()->getSkinName() ),
3999  $this->getLanguage()->getDir()
4000  );
4001  $this->addModuleStyles( [
4002  'oojs-ui-core.styles',
4003  'oojs-ui.styles.indicators',
4004  'oojs-ui.styles.textures',
4005  'mediawiki.widgets.styles',
4006  'oojs-ui.styles.icons-content',
4007  'oojs-ui.styles.icons-alerts',
4008  'oojs-ui.styles.icons-interactions',
4009  ] );
4010  }
4011 
4017  protected function addLogoPreloadLinkHeaders() {
4018  $logo = ResourceLoaderSkinModule::getLogo( $this->getConfig() );
4019 
4020  $tags = [];
4021  $logosPerDppx = [];
4022  $logos = [];
4023 
4024  if ( !is_array( $logo ) ) {
4025  // No media queries required if we only have one variant
4026  $this->addLinkHeader( '<' . $logo . '>;rel=preload;as=image' );
4027  return;
4028  }
4029 
4030  foreach ( $logo as $dppx => $src ) {
4031  // Keys are in this format: "1.5x"
4032  $dppx = substr( $dppx, 0, -1 );
4033  $logosPerDppx[$dppx] = $src;
4034  }
4035 
4036  // Because PHP can't have floats as array keys
4037  uksort( $logosPerDppx, function ( $a , $b ) {
4038  $a = floatval( $a );
4039  $b = floatval( $b );
4040 
4041  if ( $a == $b ) {
4042  return 0;
4043  }
4044  // Sort from smallest to largest (e.g. 1x, 1.5x, 2x)
4045  return ( $a < $b ) ? -1 : 1;
4046  } );
4047 
4048  foreach ( $logosPerDppx as $dppx => $src ) {
4049  $logos[] = [ 'dppx' => $dppx, 'src' => $src ];
4050  }
4051 
4052  $logosCount = count( $logos );
4053  // Logic must match ResourceLoaderSkinModule:
4054  // - 1x applies to resolution < 1.5dppx
4055  // - 1.5x applies to resolution >= 1.5dppx && < 2dppx
4056  // - 2x applies to resolution >= 2dppx
4057  // Note that min-resolution and max-resolution are both inclusive.
4058  for ( $i = 0; $i < $logosCount; $i++ ) {
4059  if ( $i === 0 ) {
4060  // Smallest dppx
4061  // min-resolution is ">=" (larger than or equal to)
4062  // "not min-resolution" is essentially "<"
4063  $media_query = 'not all and (min-resolution: ' . $logos[ 1 ]['dppx'] . 'dppx)';
4064  } elseif ( $i !== $logosCount - 1 ) {
4065  // In between
4066  // Media query expressions can only apply "not" to the entire expression
4067  // (e.g. can't express ">= 1.5 and not >= 2).
4068  // Workaround: Use <= 1.9999 in place of < 2.
4069  $upper_bound = floatval( $logos[ $i + 1 ]['dppx'] ) - 0.000001;
4070  $media_query = '(min-resolution: ' . $logos[ $i ]['dppx'] .
4071  'dppx) and (max-resolution: ' . $upper_bound . 'dppx)';
4072  } else {
4073  // Largest dppx
4074  $media_query = '(min-resolution: ' . $logos[ $i ]['dppx'] . 'dppx)';
4075  }
4076 
4077  $this->addLinkHeader(
4078  '<' . $logos[$i]['src'] . '>;rel=preload;as=image;media=' . $media_query
4079  );
4080  }
4081  }
4082 }
ReadOnlyError
Show an error when the wiki is locked/read-only and the user tries to do something that requires writ...
Definition: ReadOnlyError.php:28
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:122
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:2223
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:2346
OutputPage\$mCategories
array $mCategories
Definition: OutputPage.php:111
OutputPage\addBacklinkSubtitle
addBacklinkSubtitle(Title $title, $query=[])
Add a subtitle containing a backlink to a page.
Definition: OutputPage.php:1065
OutputPage\$mLastModified
string $mLastModified
Used for sending cache control.
Definition: OutputPage.php:105
ParserOptions
Set options of the Parser.
Definition: ParserOptions.php:40
OutputPage\getCategoryLinks
getCategoryLinks()
Get the list of category links, in a 2-D array with the following format: $arr[$type][] = $link,...
Definition: OutputPage.php:1388
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:377
ContextSource\$context
IContextSource $context
Definition: ContextSource.php:34
ContextSource\getConfig
getConfig()
Get the Config object.
Definition: ContextSource.php:68
OutputPage\getTarget
getTarget()
Definition: OutputPage.php:653
OutputPage\setArticleRelated
setArticleRelated( $v)
Set whether this page is related an article on the wiki Setting false will cause the change of "artic...
Definition: OutputPage.php:1240
ResourceLoaderContext
Object passed around to modules which contains information about the state of a specific loader reque...
Definition: ResourceLoaderContext.php:32
$user
please add to it if you re going to add events to the MediaWiki code where normally authentication against an external auth plugin would be creating a account $user
Definition: hooks.txt:244
OutputPage\getSubtitle
getSubtitle()
Get the subtitle.
Definition: OutputPage.php:1081
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:2044
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:268
$template
this hook is for auditing only or null if authentication failed before getting that far or null if we can t even determine that probably a stub it is not rendered in wiki pages or galleries in category pages allow injecting custom HTML after the section Any uses of the hook need to handle escaping $template
Definition: hooks.txt:781
OutputPage\addWikiMsg
addWikiMsg()
Add a wikitext-formatted message to the output.
Definition: OutputPage.php:3880
ContextSource\getContext
getContext()
Get the base IContextSource object.
Definition: ContextSource.php:41
OutputPage\getLanguageLinks
getLanguageLinks()
Get the list of language links.
Definition: OutputPage.php:1281
OutputPage\buildBacklinkSubtitle
static buildBacklinkSubtitle(Title $title, $query=[])
Build message object for a subtitle containing a backlink to a page.
Definition: OutputPage.php:1050
HtmlArmor
Marks HTML that shouldn't be escaped.
Definition: HtmlArmor.php:28
ResourceLoaderClientHtml
Bootstrap a ResourceLoader client on an HTML page.
Definition: ResourceLoaderClientHtml.php:28
OutputPage\reduceAllowedModules
reduceAllowedModules( $type, $level)
Limit the highest level of CSS/JS untrustworthiness allowed.
Definition: OutputPage.php:1526
PROTO_CANONICAL
const PROTO_CANONICAL
Definition: Defines.php:224
wfBCP47
wfBCP47( $code)
Get the normalised IETF language tag See unit test for examples.
Definition: GlobalFunctions.php:3167
OutputPage\$mModuleStyles
array $mModuleStyles
Definition: OutputPage.php:152
OutputPage\addSubtitle
addSubtitle( $str)
Add $str to the subtitle.
Definition: OutputPage.php:1034
OutputPage\addAcceptLanguage
addAcceptLanguage()
T23672: Add Accept-Language to Vary and Key headers if there's no 'variant' parameter existed in GET.
Definition: OutputPage.php:2184
OutputPage\$mEnableSectionEditLinks
bool $mEnableSectionEditLinks
Whether parser output should contain section edit links.
Definition: OutputPage.php:298
false
processing should stop and the error should be shown to the user * false
Definition: hooks.txt:187
Article\formatRobotPolicy
static formatRobotPolicy( $policy)
Converts a String robot policy into an associative array, to allow merging of several policies using ...
Definition: Article.php:814
OutputPage\getJSVars
getJSVars()
Get an array containing the variables to be set in mw.config in JavaScript.
Definition: OutputPage.php:3138
OutputPage\showFileRenameError
showFileRenameError( $old, $new)
Definition: OutputPage.php:2715
OutputPage\getRlClientContext
getRlClientContext()
Definition: OutputPage.php:2778
OutputPage\$mRedirectedFrom
Title $mRedirectedFrom
If the current page was reached through a redirect, $mRedirectedFrom contains the Title of the redire...
Definition: OutputPage.php:278
$wgParser
$wgParser
Definition: Setup.php:824
OutputPage\setTitle
setTitle(Title $t)
Set the Title object to use.
Definition: OutputPage.php:1015
ResourceLoaderModule\TYPE_COMBINED
const TYPE_COMBINED
Definition: ResourceLoaderModule.php:38
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:398
OutputPage\addCategoryLinksToLBAndGetResult
addCategoryLinksToLBAndGetResult(array $categories)
Definition: OutputPage.php:1340
OutputPage\hasHeadItem
hasHeadItem( $name)
Check if the header item $name is already set.
Definition: OutputPage.php:707
OutputPage\__construct
__construct(IContextSource $context=null)
Constructor for OutputPage.
Definition: OutputPage.php:319
OutputPage\$mCanonicalUrl
bool $mCanonicalUrl
Definition: OutputPage.php:52
$lang
if(!isset( $args[0])) $lang
Definition: testCompression.php:33
OutputPage\getMetaTags
getMetaTags()
Returns the current <meta> tags.
Definition: OutputPage.php:387
OutputPage\addLanguageLinks
addLanguageLinks(array $newLinkArray)
Add new language links.
Definition: OutputPage.php:1262
OutputPage\addLinkHeader
addLinkHeader( $header)
Add an HTTP Link: header.
Definition: OutputPage.php:2128
OutputPage\addModuleStyles
addModuleStyles( $modules)
Add only CSS of one or more modules recognized by ResourceLoader.
Definition: OutputPage.php:646
OutputPage\$mNewSectionLink
bool $mNewSectionLink
Definition: OutputPage.php:220
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:1759
OutputPage\isArticleRelated
isArticleRelated()
Return whether this page is related an article on the wiki.
Definition: OutputPage.php:1252
captcha-old.count
count
Definition: captcha-old.py:249
OutputPage\enableSectionEditLinks
enableSectionEditLinks( $flag=true)
Enables/disables section edit links, doesn't override NOEDITSECTION
Definition: OutputPage.php:3962
ResourceLoaderModule\ORIGIN_USER_SITEWIDE
const ORIGIN_USER_SITEWIDE
Definition: ResourceLoaderModule.php:54
OutputPage\setArticleBodyOnly
setArticleBodyOnly( $only)
Set whether the output should only contain the body of the article, without any skin,...
Definition: OutputPage.php:735
OutputPage\getFrameOptions
getFrameOptions()
Get the X-Frame-Options header value (without the name part), or false if there isn't one.
Definition: OutputPage.php:2253
text
design txt This is a brief overview of the new design More thorough and up to date information is available on the documentation wiki at etc Handles the details of getting and saving to the user table of the and dealing with sessions and cookies OutputPage Encapsulates the entire HTML page that will be sent in response to any server request It is used by calling its functions to add text
Definition: design.txt:12
OutputPage\$mRedirectCode
string $mRedirectCode
Definition: OutputPage.php:179
ContextSource\msg
msg( $key)
Get a Message object with context set Parameters are the same as wfMessage()
Definition: ContextSource.php:189
OutputPage\getRevisionId
getRevisionId()
Get the displayed revision ID.
Definition: OutputPage.php:1643
ResourceLoaderClientHtml\setModuleScripts
setModuleScripts(array $modules)
Ensure the scripts of one or more modules are loaded.
Definition: ResourceLoaderClientHtml.php:103
OutputPage\addWikiTextTitleTidy
addWikiTextTitleTidy( $text, &$title, $linestart=true)
Add wikitext with a custom Title object and tidy enabled.
Definition: OutputPage.php:1746
OutputPage\clearHTML
clearHTML()
Clear the body HTML.
Definition: OutputPage.php:1564
Title\newMainPage
static newMainPage()
Create a new Title for the Main Page.
Definition: Title.php:581
OutputPage\addScript
addScript( $script)
Add raw HTML to the list of scripts (including <script> tag, etc.) Internal use only.
Definition: OutputPage.php:467
OutputPage\$mIsarticle
bool $mIsarticle
Is the displayed content related to the source of the corresponding wiki article.
Definition: OutputPage.php:78
wfTimestamp
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
Definition: GlobalFunctions.php:2040
$wgVersion
$wgVersion
MediaWiki version number.
Definition: DefaultSettings.php:78
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:2751
OutputPage\buildCssLinksArray
buildCssLinksArray()
Definition: OutputPage.php:3696
OutputPage\combineWrappedStrings
static combineWrappedStrings(array $chunks)
Combine WrappedString chunks and filter out empty ones.
Definition: OutputPage.php:3024
OutputPage\setPageTitleActionText
setPageTitleActionText( $text)
Set the new value of the "action text", this will be added to the "HTML title", separated from it wit...
Definition: OutputPage.php:929
OutputPage\$mHideNewSectionLink
bool $mHideNewSectionLink
Definition: OutputPage.php:223
OutputPage\$mBodytext
string $mBodytext
Contains all of the "<body>" content.
Definition: OutputPage.php:69
use
as see the revision history and available at free of to any person obtaining a copy of this software and associated documentation to deal in the Software without including without limitation the rights to use
Definition: MIT-LICENSE.txt:10
wfUrlencode
wfUrlencode( $s)
We want some things to be included as literal characters in our title URLs for prettiness,...
Definition: GlobalFunctions.php:405
OutputPage\getBottomScripts
getBottomScripts()
JS stuff to put at the bottom of the <body>.
Definition: OutputPage.php:3050
OutputPage\addParserOutputContent
addParserOutputContent( $parserOutput)
Add the HTML and enhancements for it (like ResourceLoader modules) associated with a ParserOutput obj...
Definition: OutputPage.php:1873
OutputPage\showFileNotFoundError
showFileNotFoundError( $name)
Definition: OutputPage.php:2723
OutputPage\$mPagetitle
string $mPagetitle
Should be private - has getter and setter.
Definition: OutputPage.php:63
ParserOptions\newFromAnon
static newFromAnon()
Get a ParserOptions object for an anonymous user.
Definition: ParserOptions.php:963
OutputPage\addHeadItems
addHeadItems( $values)
Add one or more head items to the output.
Definition: OutputPage.php:697
OutputPage\getModuleStyles
getModuleStyles( $filter=false, $position=null)
Get the list of module CSS to include on this page.
Definition: OutputPage.php:631
$params
$params
Definition: styleTest.css.php:40
Html\htmlHeader
static htmlHeader(array $attribs=[])
Constructs the opening html-tag with necessary doctypes depending on global variables.
Definition: Html.php:886
Skin\addToBodyAttributes
addToBodyAttributes( $out, &$bodyAttrs)
This will be called by OutputPage::headElement when it is creating the "<body>" tag,...
Definition: Skin.php:454
OutputPage\versionRequired
versionRequired( $version)
Display an error page indicating that a given version of MediaWiki is required to use it.
Definition: OutputPage.php:2606
ResourceLoaderClientHtml\setExemptStates
setExemptStates(array $states)
Set state of special modules that are handled by the caller manually.
Definition: ResourceLoaderClientHtml.php:114
OutputPage\parseInline
parseInline( $text, $linestart=true, $interface=false)
Parse wikitext, strip paragraphs, and return the HTML.
Definition: OutputPage.php:1974
OutputPage\addScriptFile
addScriptFile( $file, $version=null)
Add a JavaScript file out of skins/common, or a given relative path.
Definition: OutputPage.php:504
$s
$s
Definition: mergeMessageFileList.php:188
$linkRenderer
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped noclasses just before the function returns a value If you return an< a > element with HTML attributes $attribs and contents $html will be returned If you return $ret will be returned and may include noclasses after processing after in associative array form before processing starts Return false to skip default processing and return $ret $linkRenderer
Definition: hooks.txt:1965
OutputPage\parserOptions
parserOptions( $options=null)
Get/set the ParserOptions object to use for wikitext parsing.
Definition: OutputPage.php:1584
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:82
OutputPage\getFileVersion
getFileVersion()
Get the displayed file version.
Definition: OutputPage.php:1687
OutputPage\getSyndicationLinks
getSyndicationLinks()
Return URLs for each supported syndication format for this page.
Definition: OutputPage.php:1197
OutputPage\$mVaryHeader
$mVaryHeader
Definition: OutputPage.php:268
ContextSource\canUseWikiPage
canUseWikiPage()
Check whether a WikiPage object can be get with getWikiPage().
Definition: ContextSource.php:100
wfLogWarning
wfLogWarning( $msg, $callerOffset=1, $level=E_USER_WARNING)
Send a warning as a PHP error and the debug log.
Definition: GlobalFunctions.php:1203
$res
$res
Definition: database.txt:21
$name
Allows to change the fields on the form that will be generated $name
Definition: hooks.txt:302
ContextSource\getRequest
getRequest()
Get the WebRequest object.
Definition: ContextSource.php:78
$resourceLoader
do that in ParserLimitReportFormat instead use this to modify the parameters of the image all existing parser cache entries will be invalid To avoid you ll need to handle that somehow(e.g. with the RejectParserCacheValue hook) because MediaWiki won 't do it for you. & $defaults also a ContextSource after deleting those rows but within the same transaction you ll probably need to make sure the header is varied on and they can depend only on the ResourceLoaderContext such as when responding to a resource loader request or generating HTML output & $resourceLoader
Definition: hooks.txt:2581
IExpiringStore\TTL_MINUTE
const TTL_MINUTE
Definition: IExpiringStore.php:33
OutputPage\addParserOutput
addParserOutput( $parserOutput)
Add everything from a ParserOutput object.
Definition: OutputPage.php:1902
OutputPage\$mRevisionId
int $mRevisionId
To include the variable {{REVISIONID}}.
Definition: OutputPage.php:248
User\groupHasPermission
static groupHasPermission( $group, $role)
Check, if the given group has the given permission.
Definition: User.php:4791
OutputPage\getRedirect
getRedirect()
Get the URL to redirect to, or an empty string if not redirect URL set.
Definition: OutputPage.php:345
OutputPage\setCanonicalUrl
setCanonicalUrl( $url)
Set the URL to be used for the <link rel="canonical">.
Definition: OutputPage.php:429
ContextSource\getUser
getUser()
Get the User object.
Definition: ContextSource.php:133
ContextSource\getTitle
getTitle()
Get the Title object.
Definition: ContextSource.php:88
OutputPage\$mLinktags
array $mLinktags
Definition: OutputPage.php:49
OutputPage\$mIndexPolicy
$mIndexPolicy
Definition: OutputPage.php:266
Skin\getHtmlElementAttributes
getHtmlElementAttributes()
Return values for <html> element.
Definition: Skin.php:438
Html\inlineScript
static inlineScript( $contents)
Output a "<script>" tag with the given contents.
Definition: Html.php:562
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:97
OutputPage\setIndicators
setIndicators(array $indicators)
Add an array of indicators, with their identifiers as array keys and HTML contents as values.
Definition: OutputPage.php:1424
LinkCache\getSelectFields
static getSelectFields()
Fields that LinkCache needs to select.
Definition: LinkCache.php:213
OutputPage\showFileDeleteError
showFileDeleteError( $name)
Definition: OutputPage.php:2719
OutputPage\addHTML
addHTML( $text)
Append $text to the body HTML.
Definition: OutputPage.php:1544
OutputPage\addHeadItem
addHeadItem( $name, $value)
Add or replace a head item to the output.
Definition: OutputPage.php:687
OutputPage\addWikiTextTidy
addWikiTextTidy( $text, $linestart=true)
Add wikitext with tidy enabled.
Definition: OutputPage.php:1756
OutputPage\getModuleScripts
getModuleScripts( $filter=false, $position=null)
Get the list of module JS to include on this page.
Definition: OutputPage.php:607
php
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency which acts as the top level factory for services in MediaWiki which can be used to gain access to default instances of various services MediaWikiServices however also allows new services to be defined and default services to be redefined Services are defined or redefined by providing a callback the instantiator that will return a new instance of the service When it will create an instance of MediaWikiServices and populate it with the services defined in the files listed by thereby bootstrapping the DI framework Per $wgServiceWiringFiles lists includes ServiceWiring php
Definition: injection.txt:35
File\exists
exists()
Returns true if file exists in the repository.
Definition: File.php:877
OutputPage\getRevisionTimestamp
getRevisionTimestamp()
Get the timestamp of displayed revision.
Definition: OutputPage.php:1664
OutputPage\addWikiMsgArray
addWikiMsgArray( $name, $args)
Add a wikitext-formatted message to the output.
Definition: OutputPage.php:3894
OutputPage\transformCssMedia
static transformCssMedia( $media)
Transform "media" attribute based on request parameters.
Definition: OutputPage.php:3835
OutputPage\setLastModified
setLastModified( $timestamp)
Override the last modified timestamp.
Definition: OutputPage.php:872
ResourceLoaderClientHtml\setConfig
setConfig(array $vars)
Set mw.config variables.
Definition: ResourceLoaderClientHtml.php:72
ContextSource\getLanguage
getLanguage()
Get the Language object.
Definition: ContextSource.php:143
OutputPage\$mPageTitleActionText
string $mPageTitleActionText
Definition: OutputPage.php:233
OutputPage\$mImageTimeKeys
array $mImageTimeKeys
Definition: OutputPage.php:176
OutputPage\showPermissionsErrorPage
showPermissionsErrorPage(array $errors, $action=null)
Output a standard permission error page.
Definition: OutputPage.php:2529
OutputPage\$rlUserModuleState
string $rlUserModuleState
Definition: OutputPage.php:164
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:534
XmlJsCode
A wrapper class which causes Xml::encodeJsVar() and Xml::encodeJsCall() to interpret a given string a...
Definition: XmlJsCode.php:39
OutputPage\getLinkTags
getLinkTags()
Returns the current <link> tags.
Definition: OutputPage.php:408
OutputPage\forceHideNewSectionLink
forceHideNewSectionLink()
Forcibly hide the new section link?
Definition: OutputPage.php:1132
OutputPage\addWikiTextWithTitle
addWikiTextWithTitle( $text, &$title, $linestart=true)
Add wikitext with a custom Title object.
Definition: OutputPage.php:1735
Html\closeElement
static closeElement( $element)
Returns "</$element>".
Definition: Html.php:309
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:161
Html\isXmlMimeType
static isXmlMimeType( $mimetype)
Determines if the given MIME type is xml.
Definition: Html.php:925
OutputPage\addElement
addElement( $element, array $attribs=[], $contents='')
Shortcut for adding an Html::element via addHTML.
Definition: OutputPage.php:1557
$query
null for the wiki Added should default to null in handler for backwards compatibility add a value to it if you want to add a cookie that have to vary cache options can modify $query
Definition: hooks.txt:1581
NS_SPECIAL
const NS_SPECIAL
Definition: Defines.php:54
OutputPage\addParserOutputMetadata
addParserOutputMetadata( $parserOutput)
Add all metadata associated with a ParserOutput object, but without the actual HTML.
Definition: OutputPage.php:1798
File
Implements some public methods and some protected utility functions which are required by multiple ch...
Definition: File.php:51
OutputPage\feedLink
feedLink( $type, $url, $text)
Generate a "<link rel/>" for a feed.
Definition: OutputPage.php:3581
OutputPage\getKeyHeader
getKeyHeader()
Get a complete Key header.
Definition: OutputPage.php:2150
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:580
OutputPage\addStyle
addStyle( $style, $media='', $condition='', $dir='')
Add a local or specified stylesheet, with the given media options.
Definition: OutputPage.php:3599
$title
namespace and then decline to actually register it file or subcat img or subcat $title
Definition: hooks.txt:932
OutputPage\sendCacheControl
sendCacheControl()
Send cache control HTTP headers.
Definition: OutputPage.php:2266
OutputPage\setETag
setETag( $tag)
Definition: OutputPage.php:725
wfDeprecated
wfDeprecated( $function, $version=false, $component=false, $callerOffset=2)
Throws a warning that $function is deprecated.
Definition: GlobalFunctions.php:1176
OutputPage\$mCdnMaxageLimit
int $mCdnMaxageLimit
Upper limit on mCdnMaxage.
Definition: OutputPage.php:238
OutputPage\$mTemplateIds
array $mTemplateIds
Definition: OutputPage.php:173
wfScript
wfScript( $script='index')
Get the path to a specified script file, respecting file extensions; this is a wrapper around $wgScri...
Definition: GlobalFunctions.php:2934
ResourceLoaderWikiModule\preloadTitleInfo
static preloadTitleInfo(ResourceLoaderContext $context, IDatabase $db, array $moduleNames)
Definition: ResourceLoaderWikiModule.php:362
OutputPage\styleLink
styleLink( $style, array $options)
Generate <link> tags for stylesheets.
Definition: OutputPage.php:3721
OutputPage\$mEnableTOC
bool $mEnableTOC
Whether parser output contains a table of contents.
Definition: OutputPage.php:293
OutputPage\$mSubtitle
array $mSubtitle
Contains the page subtitle.
Definition: OutputPage.php:93
OutputPage\setFileVersion
setFileVersion( $file)
Set the displayed file version.
Definition: OutputPage.php:1674
wfGetDB
wfGetDB( $db, $groups=[], $wiki=false)
Get a Database object.
Definition: GlobalFunctions.php:2856
OutputPage\showUnexpectedValueError
showUnexpectedValueError( $name, $val)
Definition: OutputPage.php:2707
OutputPage\getLinkHeader
getLinkHeader()
Return a Link: header.
Definition: OutputPage.php:2137
OutputPage\getResourceLoader
getResourceLoader()
Get a ResourceLoader object associated with this OutputPage.
Definition: OutputPage.php:2988
OutputPage\isTOCEnabled
isTOCEnabled()
Whether the output has a table of contents.
Definition: OutputPage.php:3953
ContextSource
The simplest way of implementing IContextSource is to hold a RequestContext as a member variable and ...
Definition: ContextSource.php:30
Html\linkedScript
static linkedScript( $url)
Output a "<script>" tag linking to the given URL, e.g., "<script src=foo.js></script>".
Definition: Html.php:579
ContextSource\getWikiPage
getWikiPage()
Get the WikiPage object.
Definition: ContextSource.php:113
OutputPage\setFeedAppendQuery
setFeedAppendQuery( $val)
Add default feeds to the page header This is mainly kept for backward compatibility,...
Definition: OutputPage.php:1161
$attribs
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped noclasses just before the function returns a value If you return an< a > element with HTML attributes $attribs and contents $html will be returned If you return $ret will be returned and may include noclasses after processing & $attribs
Definition: hooks.txt:1965
$modules
$modules
Definition: HTMLFormElement.php:12
OutputPage\isDisabled
isDisabled()
Return whether the output will be completely disabled.
Definition: OutputPage.php:1114
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:1633
OutputPage\addParserOutputText
addParserOutputText( $parserOutput)
Add the HTML associated with a ParserOutput object, without any metadata.
Definition: OutputPage.php:1889
$IP
$IP
Definition: update.php:3
PROTO_CURRENT
const PROTO_CURRENT
Definition: Defines.php:223
OutputPage\setArticleFlag
setArticleFlag( $v)
Set whether the displayed content is related to the source of the corresponding article on the wiki S...
Definition: OutputPage.php:1217
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:1482
ContextSource\getSkin
getSkin()
Get the Skin object.
Definition: ContextSource.php:153
ResourceLoaderModule\TYPE_SCRIPTS
const TYPE_SCRIPTS
Definition: ResourceLoaderModule.php:36
OutputPage\setSubtitle
setSubtitle( $str)
Replace the subtitle with $str.
Definition: OutputPage.php:1024
OutputPage\$mInlineStyles
string $mInlineStyles
Inline CSS styles.
Definition: OutputPage.php:131
OutputPage\addWikiText
addWikiText( $text, $linestart=true, $interface=true)
Convert wikitext to HTML and add it to the buffer Default assumes that the current page title will be...
Definition: OutputPage.php:1720
ThrottledError
Show an error when the user hits a rate limit.
Definition: ThrottledError.php:27
wfCgiToArray
wfCgiToArray( $query)
This is the logical opposite of wfArrayToCgi(): it accepts a query string as its argument and returns...
Definition: GlobalFunctions.php:487
OutputPage\addLogoPreloadLinkHeaders
addLogoPreloadLinkHeaders()
Add Link headers for preloading the wiki's logo.
Definition: OutputPage.php:4017
OutputPage\getVaryHeader
getVaryHeader()
Return a Vary: header on which to vary caches.
Definition: OutputPage.php:2111
OutputPage\addModules
addModules( $modules)
Add one or more modules recognized by ResourceLoader.
Definition: OutputPage.php:596
OutputPage\showLagWarning
showLagWarning( $lag)
Show a warning about replica DB lag.
Definition: OutputPage.php:2689
OutputPage\getPageTitleActionText
getPageTitleActionText()
Get the value of the "action text".
Definition: OutputPage.php:938
OutputPage\getCacheVaryCookies
getCacheVaryCookies()
Get the list of cookies that will influence on the cache.
Definition: OutputPage.php:2053
OutputPage\setCopyrightUrl
setCopyrightUrl( $url)
Set the copyright URL to send with the output.
Definition: OutputPage.php:357
ResourceLoaderSkinModule\getLogo
static getLogo(Config $conf)
Definition: ResourceLoaderSkinModule.php:92
global
when a variable name is used in a it is silently declared as a new masking the global
Definition: design.txt:93
$vars
static configuration should be added through ResourceLoaderGetConfigVars instead & $vars
Definition: hooks.txt:2198
OutputPage\$mFollowPolicy
$mFollowPolicy
Definition: OutputPage.php:267
OutputPage\$rlClient
ResourceLoaderClientHtml $rlClient
Definition: OutputPage.php:158
DB_REPLICA
const DB_REPLICA
Definition: defines.php:25
NS_CATEGORY
const NS_CATEGORY
Definition: Defines.php:79
OutputPage\addBodyClasses
addBodyClasses( $classes)
Add a class to the <body> element.
Definition: OutputPage.php:717
ResourceLoaderModule\getOrigin
getOrigin()
Get this module's origin.
Definition: ResourceLoaderModule.php:126
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:1047
string
This code would result in ircNotify being run twice when an article is and once for brion Hooks can return three possible true was required This is the default since MediaWiki *some string
Definition: hooks.txt:175
ContextSource\setContext
setContext(IContextSource $context)
Set the IContextSource object.
Definition: ContextSource.php:58
OutputPage\isArticle
isArticle()
Return whether the content displayed page is related to the source of the corresponding article on th...
Definition: OutputPage.php:1230
OutputPage
This class should be covered by a general architecture document which does not exist as of January 20...
Definition: OutputPage.php:44
OutputPage\showErrorPage
showErrorPage( $title, $msg, $params=[])
Output a standard error page.
Definition: OutputPage.php:2502
list
deferred txt A few of the database updates required by various functions here can be deferred until after the result page is displayed to the user For updating the view updating the linked to tables after a etc PHP does not yet have any way to tell the server to actually return and disconnect while still running these but it might have such a feature in the future We handle these by creating a deferred update object and putting those objects on a global list
Definition: deferred.txt:11
$dir
$dir
Definition: Autoload.php:8
OutputPage\$mParserOptions
ParserOptions $mParserOptions
lazy initialised, use parserOptions()
Definition: OutputPage.php:204
OutputPage\$mContainsNewMagic
int $mContainsNewMagic
Definition: OutputPage.php:198
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:523
OutputPage\getArticleBodyOnly
getArticleBodyOnly()
Return whether the output will contain only the body of the article.
Definition: OutputPage.php:744
OutputPage\getPreventClickjacking
getPreventClickjacking()
Get the prevent-clickjacking flag.
Definition: OutputPage.php:2242
OutputPage\$mModules
array $mModules
Definition: OutputPage.php:146
$request
do that in ParserLimitReportFormat instead use this to modify the parameters of the image all existing parser cache entries will be invalid To avoid you ll need to handle that somehow(e.g. with the RejectParserCacheValue hook) because MediaWiki won 't do it for you. & $defaults also a ContextSource after deleting those rows but within the same transaction you ll probably need to make sure the header is varied on $request
Definition: hooks.txt:2581
OutputPage\getCanonicalUrl
getCanonicalUrl()
Returns the URL to be used for the <link rel="canonical"> if one is set.
Definition: OutputPage.php:440
OutputPage\getExtStyle
getExtStyle()
Get all styles added by extensions.
Definition: OutputPage.php:491
OutputPage\setStatusCode
setStatusCode( $statusCode)
Set the HTTP status code to send with the output.
Definition: OutputPage.php:366
OutputPage\$mRedirect
string $mRedirect
Definition: OutputPage.php:96
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:2075
OutputPage\getPageTitle
getPageTitle()
Return the "page title", i.e.
Definition: OutputPage.php:1006
OutputPage\disable
disable()
Disable output completely, i.e.
Definition: OutputPage.php:1105
OutputPage\sectionEditLinksEnabled
sectionEditLinksEnabled()
Definition: OutputPage.php:3970
OutputPage\setIndexPolicy
setIndexPolicy( $policy)
Set the index policy for the page, but leave the follow policy un- touched.
Definition: OutputPage.php:902
Title\makeTitleSafe
static makeTitleSafe( $ns, $title, $fragment='', $interwiki='')
Create a new Title from a namespace index and a DB key.
Definition: Title.php:557
OutputPage\$mResourceLoader
ResourceLoader $mResourceLoader
Definition: OutputPage.php:155
OutputPage\$mMetatags
array $mMetatags
Should be private.
Definition: OutputPage.php:46
Skin\getPageClasses
getPageClasses( $title)
TODO: document.
Definition: Skin.php:410
$e
div flags Integer display flags(NO_ACTION_LINK, NO_EXTRA_USER_LINKS) 'LogException' returning false will NOT prevent logging $e
Definition: hooks.txt:2141
OutputPage\addCategoryLinks
addCategoryLinks(array $categories)
Add an array of categories, with names in the keys.
Definition: OutputPage.php:1290
OutputPage\setRevisionTimestamp
setRevisionTimestamp( $timestamp)
Set the timestamp of the revision which will be displayed.
Definition: OutputPage.php:1654
OutputPage\getHeadItemsArray
getHeadItemsArray()
Get an array of head items.
Definition: OutputPage.php:671
wfClearOutputBuffers
wfClearOutputBuffers()
More legible than passing a 'false' parameter to wfResetOutputBuffers():
Definition: GlobalFunctions.php:1902
OutputPage\rateLimited
rateLimited()
Turn off regular page output and return an error response for when rate limiting has triggered.
Definition: OutputPage.php:2675
$value
$value
Definition: styleTest.css.php:45
OutputPage\$mModuleScripts
array $mModuleScripts
Definition: OutputPage.php:149
OutputPage\addReturnTo
addReturnTo( $title, array $query=[], $text=null, $options=[])
Add a "return to" link pointing to a specified title.
Definition: OutputPage.php:2735
OutputPage\buildExemptModules
buildExemptModules()
Build exempt modules and legacy non-ResourceLoader styles.
Definition: OutputPage.php:3633
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:766
ParserOptions\newFromContext
static newFromContext(IContextSource $context)
Get a ParserOptions object from a IContextSource object.
Definition: ParserOptions.php:1005
OutputPage\setSquidMaxage
setSquidMaxage( $maxage)
Definition: OutputPage.php:1983
$header
$header
Definition: updateCredits.php:35
OutputPage\addHelpLink
addHelpLink( $to, $overrideBaseUrl=false)
Adds help link with an icon via page indicators.
Definition: OutputPage.php:1450
OutputPage\formatPermissionsErrorMessage
formatPermissionsErrorMessage(array $errors, $action=null)
Format a list of error messages.
Definition: OutputPage.php:2620
OutputPage\$mIndicators
array $mIndicators
Definition: OutputPage.php:117
OutputPage\$mExtStyles
array $mExtStyles
Additional stylesheets.
Definition: OutputPage.php:58
OutputPage\setTarget
setTarget( $target)
Sets ResourceLoader target for load.php links.
Definition: OutputPage.php:662
MediaWiki\Session\SessionManager
This serves as the entry point to the MediaWiki session handling system.
Definition: SessionManager.php:49
OutputPage\setHTMLTitle
setHTMLTitle( $name)
"HTML title" means the contents of "<title>".
Definition: OutputPage.php:948
OutputPage\setLanguageLinks
setLanguageLinks(array $newLinkArray)
Reset the language links and add new language links.
Definition: OutputPage.php:1272
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:3981
SpecialPageFactory\resolveAlias
static resolveAlias( $alias)
Given a special page name with a possible subpage, return an array where the first element is the spe...
Definition: SpecialPageFactory.php:338
OutputPage\$rlExemptStyleModules
array $rlExemptStyleModules
Definition: OutputPage.php:167
OutputPage\$mProperties
$mProperties
Additional key => value data.
Definition: OutputPage.php:283
PROTO_RELATIVE
const PROTO_RELATIVE
Definition: Defines.php:222
OutputPage\wrapWikiMsg
wrapWikiMsg( $wrap)
This function takes a number of message/argument specifications, wraps them in some overall structure...
Definition: OutputPage.php:3923
Html\inlineStyle
static inlineStyle( $contents, $media='all')
Output a "<style>" tag with the given contents for the given media type (if any).
Definition: Html.php:594
OutputPage\prependHTML
prependHTML( $text)
Prepend $text to the body HTML.
Definition: OutputPage.php:1535
MWNamespace\exists
static exists( $index)
Returns whether the specified namespace exists.
Definition: MWNamespace.php:160
OutputPage\$mEnableClientCache
$mEnableClientCache
Definition: OutputPage.php:214
OutputPage\getHTMLTitle
getHTMLTitle()
Return the "HTML title", i.e.
Definition: OutputPage.php:961
OutputPage\showFileCopyError
showFileCopyError( $old, $new)
Definition: OutputPage.php:2711
ResourceLoaderModule\ORIGIN_CORE_INDIVIDUAL
const ORIGIN_CORE_INDIVIDUAL
Definition: ResourceLoaderModule.php:50
OutputPage\clearSubtitle
clearSubtitle()
Clear the subtitles.
Definition: OutputPage.php:1072
OutputPage\warnModuleTargetFilter
warnModuleTargetFilter( $moduleName)
Definition: OutputPage.php:556
OutputPage\getMetadataAttribute
getMetadataAttribute()
Get the value of the "rel" attribute for metadata links.
Definition: OutputPage.php:449
OutputPage\isUserJsPreview
isUserJsPreview()
Definition: OutputPage.php:3030
OutputPage\$mCdnMaxage
int $mCdnMaxage
Cache stuff.
Definition: OutputPage.php:236
OutputPage\enableOOUI
enableOOUI()
Add ResourceLoader module styles for OOUI and set up the PHP implementation of it for use with MediaW...
Definition: OutputPage.php:3996
plain
either a plain
Definition: hooks.txt:2026
OutputPage\$mScripts
$mScripts
Used for JavaScript (predates ResourceLoader)
Definition: OutputPage.php:128
OutputPage\$mAllowedModules
array $mAllowedModules
What level of 'untrustworthiness' is allowed in CSS/JS modules loaded on this page?
Definition: OutputPage.php:188
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:74
OutputPage\$mPrintable
bool $mPrintable
We have to set isPrintable().
Definition: OutputPage.php:87
$response
this hook is for auditing only $response
Definition: hooks.txt:781
IContextSource
Interface for objects which can provide a MediaWiki context on request.
Definition: IContextSource.php:55
ResourceLoaderModule\ORIGIN_ALL
const ORIGIN_ALL
Definition: ResourceLoaderModule.php:60
OutputPage\$mLanguageLinks
array $mLanguageLinks
Array of Interwiki Prefixed (non DB key) Titles (e.g.
Definition: OutputPage.php:120
wfGetAllCallers
wfGetAllCallers( $limit=3)
Return a string consisting of callers in the stack.
Definition: GlobalFunctions.php:1623
OutputPage\setCategoryLinks
setCategoryLinks(array $categories)
Reset the category links (but not the category list) and add $categories.
Definition: OutputPage.php:1375
OutputPage\setFollowPolicy
setFollowPolicy( $policy)
Set the follow policy for the page, but leave the index policy un- touched.
Definition: OutputPage.php:916
OutputPage\setPageTitle
setPageTitle( $name)
"Page title" means the contents of <h1>.
Definition: OutputPage.php:984
OutputPage\getRlClient
getRlClient()
Call this to freeze the module queue and JS config and create a formatter.
Definition: OutputPage.php:2810
OutputPage\$mFileVersion
array $mFileVersion
Definition: OutputPage.php:254
OutputPage\checkLastModified
checkLastModified( $timestamp)
checkLastModified tells the client to use the client-cached page if possible.
Definition: OutputPage.php:785
OutputPage\$mNoGallery
bool $mNoGallery
Comes from the parser.
Definition: OutputPage.php:230
ResourceLoaderClientHtml\makeLoad
static makeLoad(ResourceLoaderContext $mainContext, array $modules, $only, array $extraQuery=[])
Explicily load or embed modules on a page.
Definition: ResourceLoaderClientHtml.php:361
OutputPage\$mHeadItems
array $mHeadItems
Array of elements in "<head>".
Definition: OutputPage.php:140
$args
if( $line===false) $args
Definition: cdb.php:63
OutputPage\$mRevisionTimestamp
string $mRevisionTimestamp
Definition: OutputPage.php:251
Title
Represents a title within MediaWiki.
Definition: Title.php:39
ResourceLoaderModule
Abstraction for ResourceLoader modules, with name registration and maxage functionality.
Definition: ResourceLoaderModule.php:34
OutputPage\setCdnMaxage
setCdnMaxage( $maxage)
Set the value of the "s-maxage" part of the "Cache-control" HTTP header.
Definition: OutputPage.php:1992
OutputPage\getAllowedModules
getAllowedModules( $type)
Show what level of JavaScript / CSS untrustworthiness is allowed on this page.
Definition: OutputPage.php:1507
and
and that you know you can do these things To protect your we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights These restrictions translate to certain responsibilities for you if you distribute copies of the or if you modify it For if you distribute copies of such a whether gratis or for a you must give the recipients all the rights that you have You must make sure that receive or can get the source code And you must show them these terms so they know their rights We protect your rights with two and(2) offer you this license which gives you legal permission to copy
OutputPage\addVaryHeader
addVaryHeader( $header, array $option=null)
Add an HTTP header that will influence on the cache.
Definition: OutputPage.php:2095
OutputPage\setProperty
setProperty( $name, $value)
Set an additional output property.
Definition: OutputPage.php:755
OutputPage\isPrintable
isPrintable()
Return whether the page is "printable".
Definition: OutputPage.php:1098
OutputPage\setSyndicated
setSyndicated( $show=true)
Add or remove feed links in the page header This is mainly kept for backward compatibility,...
Definition: OutputPage.php:1144
$dbr
if(! $regexes) $dbr
Definition: cleanup.php:94
$options
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped & $options
Definition: hooks.txt:1965
OutputPage\$mTarget
string null $mTarget
ResourceLoader target for load.php links.
Definition: OutputPage.php:288
OutputPage\addInlineStyle
addInlineStyle( $style_css, $flip='noflip')
Adds inline CSS styles Internal use only.
Definition: OutputPage.php:3620
ResourceLoaderClientHtml\setModules
setModules(array $modules)
Ensure one or more modules are loaded.
Definition: ResourceLoaderClientHtml.php:83
OutputPage\userCanPreview
userCanPreview()
To make it harder for someone to slip a user a fake user-JavaScript or user-CSS preview,...
Definition: OutputPage.php:3269
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:623
OutputPage\addExtensionStyle
addExtensionStyle( $url)
Register and add a stylesheet from an extension directory.
Definition: OutputPage.php:480
$code
this hook is for auditing only or null if authentication failed before getting that far or null if we can t even determine that probably a stub it is not rendered in wiki pages or galleries in category pages allow injecting custom HTML after the section Any uses of the hook need to handle escaping see BaseTemplate::getToolbox and BaseTemplate::makeListItem for details on the format of individual items inside of this array or by returning and letting standard HTTP rendering take place modifiable or by returning false and taking over the output modifiable & $code
Definition: hooks.txt:781
OutputPage\setRedirectedFrom
setRedirectedFrom( $t)
Set $mRedirectedFrom, the Title of the page which redirected us to the current page.
Definition: OutputPage.php:970
ResourceLoaderClientHtml\setModuleStyles
setModuleStyles(array $modules)
Ensure the styles of one or more modules are loaded.
Definition: ResourceLoaderClientHtml.php:93
OutputPage\addWikiTextTitle
addWikiTextTitle( $text, Title $title, $linestart, $tidy=false, $interface=false)
Add wikitext with a custom Title object.
Definition: OutputPage.php:1771
OutputPage\addMetadataLink
addMetadataLink(array $linkarr)
Add a new <link> with "rel" attribute set to "meta".
Definition: OutputPage.php:419
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:535
WebRequest\getRequestId
static getRequestId()
Get the unique request ID.
Definition: WebRequest.php:272
LinkCache\singleton
static singleton()
Get an instance of this class.
Definition: LinkCache.php:67
OutputPage\redirect
redirect( $url, $responsecode='302')
Redirect to $url rather than displaying the normal page.
Definition: OutputPage.php:334
OutputPage\$mJsConfigVars
array $mJsConfigVars
Definition: OutputPage.php:170
$path
$path
Definition: NoLocalSettings.php:26
OutputPage\isUserCssPreview
isUserCssPreview()
Definition: OutputPage.php:3037
OutputPage\setPrintable
setPrintable()
Set the page as printable, i.e.
Definition: OutputPage.php:1089
OutputPage\getHeadLinksArray
getHeadLinksArray()
Definition: OutputPage.php:3309
OutputPage\readOnlyPage
readOnlyPage()
Display a page stating that the Wiki is in read-only mode.
Definition: OutputPage.php:2661
OutputPage\adaptCdnTTL
adaptCdnTTL( $mtime, $minTTL=0, $maxTTL=0)
Get TTL in [$minTTL,$maxTTL] in pass it to lowerCdnMaxage()
Definition: OutputPage.php:2020
as
This document is intended to provide useful advice for parties seeking to redistribute MediaWiki to end users It s targeted particularly at maintainers for Linux since it s been observed that distribution packages of MediaWiki often break We ve consistently had to recommend that users seeking support use official tarballs instead of their distribution s and this often solves whatever problem the user is having It would be nice if this could such as
Definition: distributors.txt:9
OutputPage\addModuleScripts
addModuleScripts( $modules)
Add only JS of one or more modules recognized by ResourceLoader.
Definition: OutputPage.php:620
OutputPage\allowClickjacking
allowClickjacking()
Turn off frame-breaking.
Definition: OutputPage.php:2232
OutputPage\showFatalError
showFatalError( $message)
Definition: OutputPage.php:2701
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
messages
passed in as a query string parameter to the various URLs constructed here(i.e. $prevlink) $ldel you ll need to handle error messages
Definition: hooks.txt:1265
OutputPage\getHTML
getHTML()
Get the body HTML.
Definition: OutputPage.php:1573
OutputPage\$mLinkHeader
$mLinkHeader
Link: header contents.
Definition: OutputPage.php:311
$keys
$keys
Definition: testCompression.php:65
$link
usually copyright or history_copyright This message must be in HTML not wikitext & $link
Definition: hooks.txt:2981
OutputPage\$styles
array $styles
An array of stylesheet filenames (relative from skins path), with options for CSS media,...
Definition: OutputPage.php:264
LoggerFactory
MediaWiki Logger LoggerFactory implements a PSR[0] compatible message logging system Named Psr Log LoggerInterface instances can be obtained from the MediaWiki Logger LoggerFactory::getInstance() static method. MediaWiki\Logger\LoggerFactory expects a class implementing the MediaWiki\Logger\Spi interface to act as a factory for new Psr\Log\LoggerInterface instances. The "Spi" in MediaWiki\Logger\Spi stands for "service provider interface". An SPI is an API intended to be implemented or extended by a third party. This software design pattern is intended to enable framework extension and replaceable components. It is specifically used in the MediaWiki\Logger\LoggerFactory service to allow alternate PSR-3 logging implementations to be easily integrated with MediaWiki. The service provider interface allows the backend logging library to be implemented in multiple ways. The $wgMWLoggerDefaultSpi global provides the classname of the default MediaWiki\Logger\Spi implementation to be loaded at runtime. This can either be the name of a class implementing the MediaWiki\Logger\Spi with a zero argument const ructor or a callable that will return an MediaWiki\Logger\Spi instance. Alternately the MediaWiki\Logger\LoggerFactory MediaWiki Logger LoggerFactory
Definition: logger.txt:5
ResourceLoaderModule\TYPE_STYLES
const TYPE_STYLES
Definition: ResourceLoaderModule.php:37
MWDebug\addModules
static addModules(OutputPage $out)
Add ResourceLoader modules to the OutputPage object if debugging is enabled.
Definition: MWDebug.php:96
OutputPage\showNewSectionLink
showNewSectionLink()
Show an "add new section" link?
Definition: OutputPage.php:1123
OutputPage\parse
parse( $text, $linestart=true, $interface=false, $language=null)
Parse wikitext and return the HTML.
Definition: OutputPage.php:1934
wfMessage
either a unescaped string or a HtmlArmor object after in associative array form externallinks including delete and has completed for all link tables whether this was an auto creation default is conds Array Extra conditions for the No matching items in log is displayed if loglist is empty msgKey Array If you want a nice box with a set this to the key of the message First element is the message additional optional elements are parameters for the key that are processed with wfMessage() -> params() ->parseAsBlock() - offset Set to overwrite offset parameter in $wgRequest set to '' to unset offset - wrap String Wrap the message in html(usually something like "&lt
OutputPage\$mPageLinkTitle
string $mPageLinkTitle
Used by skin template.
Definition: OutputPage.php:137
OutputPage\makeResourceLoaderLink
makeResourceLoaderLink( $modules, $only, array $extraQuery=[])
Explicily load or embed modules on a page.
Definition: OutputPage.php:3006
OutputPage\getIndicators
getIndicators()
Get the indicators associated with this page.
Definition: OutputPage.php:1438
$t
$t
Definition: testCompression.php:67
$wgRequest
if(! $wgDBerrorLogTZ) $wgRequest
Definition: Setup.php:662
Html\element
static element( $element, $attribs=[], $contents='')
Identical to rawElement(), but HTML-escapes $contents (like Xml::element()).
Definition: Html.php:231
Skin\getSkinName
getSkinName()
Definition: Skin.php:139
MediaWikiServices
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency MediaWikiServices
Definition: injection.txt:23
OutputPage\addJsConfigVars
addJsConfigVars( $keys, $value=null)
Add one or more variables to be set in mw.config in JavaScript.
Definition: OutputPage.php:3118
OutputPage\$mPreventClickjacking
bool $mPreventClickjacking
Controls if anti-clickjacking / frame-breaking headers will be sent.
Definition: OutputPage.php:245
Skin
The main skin class which provides methods and properties for all other skins.
Definition: Skin.php:36
OutputPage\getCategories
getCategories( $type='all')
Get the list of category names this page belongs to.
Definition: OutputPage.php:1401
OutputPage\getJsConfigVars
getJsConfigVars()
Get the javascript config vars to include on this page.
Definition: OutputPage.php:3108
OutputPage\getTemplateIds
getTemplateIds()
Get the templates used on this page.
Definition: OutputPage.php:1697
OutputPage\$mIsArticleRelated
bool $mIsArticleRelated
Stores "article flag" toggle.
Definition: OutputPage.php:81
Hooks\run
static run( $event, array $args=[], $deprecatedVersion=null)
Call hook functions defined in Hooks::register and $wgHooks.
Definition: Hooks.php:203
OutputPage\isSyndicated
isSyndicated()
Should we output feed links for this page?
Definition: OutputPage.php:1189
OutputPage\$mFeedLinksAppendQuery
$mFeedLinksAppendQuery
Definition: OutputPage.php:181
OutputPage\getFileSearchOptions
getFileSearchOptions()
Get the files used on this page.
Definition: OutputPage.php:1707
OutputPage\$mFeedLinks
$mFeedLinks
Handles the Atom / RSS links.
Definition: OutputPage.php:211
OutputPage\$mDoNothing
bool $mDoNothing
Whether output is disabled.
Definition: OutputPage.php:193
OutputPage\$mArticleBodyOnly
bool $mArticleBodyOnly
Flag if output should only contain the body of the article.
Definition: OutputPage.php:217
OutputPage\$mAdditionalBodyClasses
array $mAdditionalBodyClasses
Additional <body> classes; there are also <body> classes from other sources.
Definition: OutputPage.php:143
MWNamespace\getCanonicalName
static getCanonicalName( $index)
Returns the canonical (English) name for a given index.
Definition: MWNamespace.php:228
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:2477
OutputPage\addTemplate
addTemplate(&$template)
Add the output of a QuickTemplate to the output buffer.
Definition: OutputPage.php:1918
OutputPage\getFeedAppendQuery
getFeedAppendQuery()
Will currently always return null.
Definition: OutputPage.php:1206
OutputPage\lowerCdnMaxage
lowerCdnMaxage( $maxage)
Lower the value of the "s-maxage" part of the "Cache-control" HTTP header.
Definition: OutputPage.php:2002
OutputPage\$mHTMLtitle
string $mHTMLtitle
Stores contents of "<title>" tag.
Definition: OutputPage.php:72
wfExpandUrl
wfExpandUrl( $url, $defaultProto=PROTO_CURRENT)
Expand a potentially local URL to a fully-qualified URL.
Definition: GlobalFunctions.php:586
array
the array() calling protocol came about after MediaWiki 1.4rc1.
OutputPage\addFeedLink
addFeedLink( $format, $href)
Add a feed link to the page header.
Definition: OutputPage.php:1179
OutputPage\$mCategoryLinks
array $mCategoryLinks
Definition: OutputPage.php:108
OutputPage\transformResourcePath
static transformResourcePath(Config $config, $path)
Transform path to web-accessible static resource.
Definition: OutputPage.php:3777
OutputPage\setRobotPolicy
setRobotPolicy( $policy)
Set the robot policy for the page: http://www.robotstxt.org/meta.html
Definition: OutputPage.php:884
$wgContLang
this class mediates it Skin Encapsulates a look and feel for the wiki All of the functions that render HTML and make choices about how to render it are here and are called from various other places when and is meant to be subclassed with other skins that may override some of its functions The User object contains a reference to a and so rather than having a global skin object we just rely on the global User and get the skin with $wgUser and also has some character encoding functions and other locale stuff The current user interface language is instantiated as and the content language as $wgContLang
Definition: design.txt:56
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:442
OutputPage\transformFilePath
static transformFilePath( $remotePathPrefix, $localPath, $file)
Utility method for transformResourceFilePath().
Definition: OutputPage.php:3819
OutputPage\headElement
headElement(Skin $sk, $includeStyle=true)
Definition: OutputPage.php:2891
$type
$type
Definition: testCompression.php:48
OutputPage\$mStatusCode
int $mStatusCode
Definition: OutputPage.php:99