MediaWiki  1.27.4
OutputPage.php
Go to the documentation of this file.
1 <?php
26 
42 class OutputPage extends ContextSource {
44  protected $mMetatags = [];
45 
47  protected $mLinktags = [];
48 
50  protected $mCanonicalUrl = false;
51 
56  protected $mExtStyles = [];
57 
61  public $mPagetitle = '';
62 
67  public $mBodytext = '';
68 
74  public $mDebugtext = '';
75 
77  private $mHTMLtitle = '';
78 
83  private $mIsarticle = false;
84 
86  private $mIsArticleRelated = true;
87 
92  private $mPrintable = false;
93 
98  private $mSubtitle = [];
99 
101  public $mRedirect = '';
102 
104  protected $mStatusCode;
105 
110  protected $mLastModified = '';
111 
121  private $mETag = false;
122 
124  protected $mCategoryLinks = [];
125 
127  protected $mCategories = [];
128 
130  protected $mIndicators = [];
131 
133  private $mLanguageLinks = [];
134 
141  private $mScripts = '';
142 
144  protected $mInlineStyles = '';
145 
150  public $mPageLinkTitle = '';
151 
153  protected $mHeadItems = [];
154 
156  protected $mModules = [];
157 
159  protected $mModuleScripts = [];
160 
162  protected $mModuleStyles = [];
163 
165  protected $mResourceLoader;
166 
168  protected $mJsConfigVars = [];
169 
171  protected $mTemplateIds = [];
172 
174  protected $mImageTimeKeys = [];
175 
177  public $mRedirectCode = '';
178 
179  protected $mFeedLinksAppendQuery = null;
180 
186  protected $mAllowedModules = [
188  ];
189 
191  protected $mDoNothing = false;
192 
193  // Parser related.
194 
196  protected $mContainsNewMagic = 0;
197 
202  protected $mParserOptions = null;
203 
209  private $mFeedLinks = [];
210 
211  // Gwicke work on squid caching? Roughly from 2003.
212  protected $mEnableClientCache = true;
213 
215  private $mArticleBodyOnly = false;
216 
218  protected $mNewSectionLink = false;
219 
221  protected $mHideNewSectionLink = false;
222 
228  public $mNoGallery = false;
229 
231  private $mPageTitleActionText = '';
232 
234  protected $mCdnMaxage = 0;
236  protected $mCdnMaxageLimit = INF;
237 
243  protected $mPreventClickjacking = true;
244 
246  private $mRevisionId = null;
247 
249  private $mRevisionTimestamp = null;
250 
252  protected $mFileVersion = null;
253 
262  protected $styles = [];
263 
267  protected $mJQueryDone = false;
268 
269  private $mIndexPolicy = 'index';
270  private $mFollowPolicy = 'follow';
271  private $mVaryHeader = [
272  'Accept-Encoding' => [ 'match=gzip' ],
273  ];
274 
281  private $mRedirectedFrom = null;
282 
286  private $mProperties = [];
287 
291  private $mTarget = null;
292 
296  private $mEnableTOC = true;
297 
301  private $mEnableSectionEditLinks = true;
302 
306  private $copyrightUrl;
307 
314  function __construct( IContextSource $context = null ) {
315  if ( $context === null ) {
316  # Extensions should use `new RequestContext` instead of `new OutputPage` now.
317  wfDeprecated( __METHOD__, '1.18' );
318  } else {
319  $this->setContext( $context );
320  }
321  }
322 
329  public function redirect( $url, $responsecode = '302' ) {
330  # Strip newlines as a paranoia check for header injection in PHP<5.1.2
331  $this->mRedirect = str_replace( "\n", '', $url );
332  $this->mRedirectCode = $responsecode;
333  }
334 
340  public function getRedirect() {
341  return $this->mRedirect;
342  }
343 
352  public function setCopyrightUrl( $url ) {
353  $this->copyrightUrl = $url;
354  }
355 
361  public function setStatusCode( $statusCode ) {
362  $this->mStatusCode = $statusCode;
363  }
364 
372  function addMeta( $name, $val ) {
373  array_push( $this->mMetatags, [ $name, $val ] );
374  }
375 
382  public function getMetaTags() {
383  return $this->mMetatags;
384  }
385 
393  function addLink( array $linkarr ) {
394  array_push( $this->mLinktags, $linkarr );
395  }
396 
403  public function getLinkTags() {
404  return $this->mLinktags;
405  }
406 
414  function addMetadataLink( array $linkarr ) {
415  $linkarr['rel'] = $this->getMetadataAttribute();
416  $this->addLink( $linkarr );
417  }
418 
424  function setCanonicalUrl( $url ) {
425  $this->mCanonicalUrl = $url;
426  }
427 
435  public function getCanonicalUrl() {
436  return $this->mCanonicalUrl;
437  }
438 
444  public function getMetadataAttribute() {
445  # note: buggy CC software only reads first "meta" link
446  static $haveMeta = false;
447  if ( $haveMeta ) {
448  return 'alternate meta';
449  } else {
450  $haveMeta = true;
451  return 'meta';
452  }
453  }
454 
462  function addScript( $script ) {
463  $this->mScripts .= $script;
464  }
465 
475  public function addExtensionStyle( $url ) {
476  wfDeprecated( __METHOD__, '1.27' );
477  array_push( $this->mExtStyles, $url );
478  }
479 
486  function getExtStyle() {
487  wfDeprecated( __METHOD__, '1.27' );
488  return $this->mExtStyles;
489  }
490 
499  public function addScriptFile( $file, $version = null ) {
500  // See if $file parameter is an absolute URL or begins with a slash
501  if ( substr( $file, 0, 1 ) == '/' || preg_match( '#^[a-z]*://#i', $file ) ) {
502  $path = $file;
503  } else {
504  $path = $this->getConfig()->get( 'StylePath' ) . "/common/{$file}";
505  }
506  if ( is_null( $version ) ) {
507  $version = $this->getConfig()->get( 'StyleVersion' );
508  }
510  }
511 
518  public function addInlineScript( $script ) {
519  $this->mScripts .= Html::inlineScript( $script );
520  }
521 
530  protected function filterModules( array $modules, $position = null,
532  ) {
534  $filteredModules = [];
535  foreach ( $modules as $val ) {
536  $module = $resourceLoader->getModule( $val );
537  if ( $module instanceof ResourceLoaderModule
538  && $module->getOrigin() <= $this->getAllowedModules( $type )
539  && ( is_null( $position ) || $module->getPosition() == $position )
540  && ( !$this->mTarget || in_array( $this->mTarget, $module->getTargets() ) )
541  ) {
542  $filteredModules[] = $val;
543  }
544  }
545  return $filteredModules;
546  }
547 
556  public function getModules( $filter = false, $position = null, $param = 'mModules' ) {
557  $modules = array_values( array_unique( $this->$param ) );
558  return $filter
559  ? $this->filterModules( $modules, $position )
560  : $modules;
561  }
562 
570  public function addModules( $modules ) {
571  $this->mModules = array_merge( $this->mModules, (array)$modules );
572  }
573 
582  public function getModuleScripts( $filter = false, $position = null ) {
583  return $this->getModules( $filter, $position, 'mModuleScripts' );
584  }
585 
593  public function addModuleScripts( $modules ) {
594  $this->mModuleScripts = array_merge( $this->mModuleScripts, (array)$modules );
595  }
596 
605  public function getModuleStyles( $filter = false, $position = null ) {
606  return $this->getModules( $filter, $position, 'mModuleStyles' );
607  }
608 
618  public function addModuleStyles( $modules ) {
619  $this->mModuleStyles = array_merge( $this->mModuleStyles, (array)$modules );
620  }
621 
630  public function getModuleMessages( $filter = false, $position = null ) {
631  wfDeprecated( __METHOD__, '1.26' );
632  return [];
633  }
634 
641  public function addModuleMessages( $modules ) {
642  wfDeprecated( __METHOD__, '1.26' );
643  }
644 
648  public function getTarget() {
649  return $this->mTarget;
650  }
651 
657  public function setTarget( $target ) {
658  $this->mTarget = $target;
659  }
660 
666  function getHeadItemsArray() {
667  return $this->mHeadItems;
668  }
669 
682  public function addHeadItem( $name, $value ) {
683  $this->mHeadItems[$name] = $value;
684  }
685 
692  public function hasHeadItem( $name ) {
693  return isset( $this->mHeadItems[$name] );
694  }
695 
701  function setETag( $tag ) {
702  $this->mETag = $tag;
703  }
704 
712  public function setArticleBodyOnly( $only ) {
713  $this->mArticleBodyOnly = $only;
714  }
715 
721  public function getArticleBodyOnly() {
723  }
724 
732  public function setProperty( $name, $value ) {
733  $this->mProperties[$name] = $value;
734  }
735 
743  public function getProperty( $name ) {
744  if ( isset( $this->mProperties[$name] ) ) {
745  return $this->mProperties[$name];
746  } else {
747  return null;
748  }
749  }
750 
762  public function checkLastModified( $timestamp ) {
763  if ( !$timestamp || $timestamp == '19700101000000' ) {
764  wfDebug( __METHOD__ . ": CACHE DISABLED, NO TIMESTAMP\n" );
765  return false;
766  }
767  $config = $this->getConfig();
768  if ( !$config->get( 'CachePages' ) ) {
769  wfDebug( __METHOD__ . ": CACHE DISABLED\n" );
770  return false;
771  }
772 
774  $modifiedTimes = [
775  'page' => $timestamp,
776  'user' => $this->getUser()->getTouched(),
777  'epoch' => $config->get( 'CacheEpoch' )
778  ];
779  if ( $config->get( 'UseSquid' ) ) {
780  // bug 44570: the core page itself may not change, but resources might
781  $modifiedTimes['sepoch'] = wfTimestamp( TS_MW, time() - $config->get( 'SquidMaxage' ) );
782  }
783  Hooks::run( 'OutputPageCheckLastModified', [ &$modifiedTimes ] );
784 
785  $maxModified = max( $modifiedTimes );
786  $this->mLastModified = wfTimestamp( TS_RFC2822, $maxModified );
787 
788  $clientHeader = $this->getRequest()->getHeader( 'If-Modified-Since' );
789  if ( $clientHeader === false ) {
790  wfDebug( __METHOD__ . ": client did not send If-Modified-Since header", 'private' );
791  return false;
792  }
793 
794  # IE sends sizes after the date like this:
795  # Wed, 20 Aug 2003 06:51:19 GMT; length=5202
796  # this breaks strtotime().
797  $clientHeader = preg_replace( '/;.*$/', '', $clientHeader );
798 
799  MediaWiki\suppressWarnings(); // E_STRICT system time bitching
800  $clientHeaderTime = strtotime( $clientHeader );
801  MediaWiki\restoreWarnings();
802  if ( !$clientHeaderTime ) {
803  wfDebug( __METHOD__
804  . ": unable to parse the client's If-Modified-Since header: $clientHeader\n" );
805  return false;
806  }
807  $clientHeaderTime = wfTimestamp( TS_MW, $clientHeaderTime );
808 
809  # Make debug info
810  $info = '';
811  foreach ( $modifiedTimes as $name => $value ) {
812  if ( $info !== '' ) {
813  $info .= ', ';
814  }
815  $info .= "$name=" . wfTimestamp( TS_ISO_8601, $value );
816  }
817 
818  wfDebug( __METHOD__ . ": client sent If-Modified-Since: " .
819  wfTimestamp( TS_ISO_8601, $clientHeaderTime ), 'private' );
820  wfDebug( __METHOD__ . ": effective Last-Modified: " .
821  wfTimestamp( TS_ISO_8601, $maxModified ), 'private' );
822  if ( $clientHeaderTime < $maxModified ) {
823  wfDebug( __METHOD__ . ": STALE, $info", 'private' );
824  return false;
825  }
826 
827  # Not modified
828  # Give a 304 Not Modified response code and disable body output
829  wfDebug( __METHOD__ . ": NOT MODIFIED, $info", 'private' );
830  ini_set( 'zlib.output_compression', 0 );
831  $this->getRequest()->response()->statusHeader( 304 );
832  $this->sendCacheControl();
833  $this->disable();
834 
835  // Don't output a compressed blob when using ob_gzhandler;
836  // it's technically against HTTP spec and seems to confuse
837  // Firefox when the response gets split over two packets.
839 
840  return true;
841  }
842 
849  public function setLastModified( $timestamp ) {
850  $this->mLastModified = wfTimestamp( TS_RFC2822, $timestamp );
851  }
852 
861  public function setRobotPolicy( $policy ) {
862  $policy = Article::formatRobotPolicy( $policy );
863 
864  if ( isset( $policy['index'] ) ) {
865  $this->setIndexPolicy( $policy['index'] );
866  }
867  if ( isset( $policy['follow'] ) ) {
868  $this->setFollowPolicy( $policy['follow'] );
869  }
870  }
871 
879  public function setIndexPolicy( $policy ) {
880  $policy = trim( $policy );
881  if ( in_array( $policy, [ 'index', 'noindex' ] ) ) {
882  $this->mIndexPolicy = $policy;
883  }
884  }
885 
893  public function setFollowPolicy( $policy ) {
894  $policy = trim( $policy );
895  if ( in_array( $policy, [ 'follow', 'nofollow' ] ) ) {
896  $this->mFollowPolicy = $policy;
897  }
898  }
899 
906  public function setPageTitleActionText( $text ) {
907  $this->mPageTitleActionText = $text;
908  }
909 
915  public function getPageTitleActionText() {
917  }
918 
925  public function setHTMLTitle( $name ) {
926  if ( $name instanceof Message ) {
927  $this->mHTMLtitle = $name->setContext( $this->getContext() )->text();
928  } else {
929  $this->mHTMLtitle = $name;
930  }
931  }
932 
938  public function getHTMLTitle() {
939  return $this->mHTMLtitle;
940  }
941 
947  public function setRedirectedFrom( $t ) {
948  $this->mRedirectedFrom = $t;
949  }
950 
961  public function setPageTitle( $name ) {
962  if ( $name instanceof Message ) {
963  $name = $name->setContext( $this->getContext() )->text();
964  }
965 
966  # change "<script>foo&bar</script>" to "&lt;script&gt;foo&amp;bar&lt;/script&gt;"
967  # but leave "<i>foobar</i>" alone
969  $this->mPagetitle = $nameWithTags;
970 
971  # change "<i>foo&amp;bar</i>" to "foo&bar"
972  $this->setHTMLTitle(
973  $this->msg( 'pagetitle' )->rawParams( Sanitizer::stripAllTags( $nameWithTags ) )
974  ->inContentLanguage()
975  );
976  }
977 
983  public function getPageTitle() {
984  return $this->mPagetitle;
985  }
986 
992  public function setTitle( Title $t ) {
993  $this->getContext()->setTitle( $t );
994  }
995 
1001  public function setSubtitle( $str ) {
1002  $this->clearSubtitle();
1003  $this->addSubtitle( $str );
1004  }
1005 
1011  public function addSubtitle( $str ) {
1012  if ( $str instanceof Message ) {
1013  $this->mSubtitle[] = $str->setContext( $this->getContext() )->parse();
1014  } else {
1015  $this->mSubtitle[] = $str;
1016  }
1017  }
1018 
1027  public static function buildBacklinkSubtitle( Title $title, $query = [] ) {
1028  if ( $title->isRedirect() ) {
1029  $query['redirect'] = 'no';
1030  }
1031  return wfMessage( 'backlinksubtitle' )
1032  ->rawParams( Linker::link( $title, null, [], $query ) );
1033  }
1034 
1041  public function addBacklinkSubtitle( Title $title, $query = [] ) {
1042  $this->addSubtitle( self::buildBacklinkSubtitle( $title, $query ) );
1043  }
1044 
1048  public function clearSubtitle() {
1049  $this->mSubtitle = [];
1050  }
1051 
1057  public function getSubtitle() {
1058  return implode( "<br />\n\t\t\t\t", $this->mSubtitle );
1059  }
1060 
1065  public function setPrintable() {
1066  $this->mPrintable = true;
1067  }
1068 
1074  public function isPrintable() {
1075  return $this->mPrintable;
1076  }
1077 
1081  public function disable() {
1082  $this->mDoNothing = true;
1083  }
1084 
1090  public function isDisabled() {
1091  return $this->mDoNothing;
1092  }
1093 
1099  public function showNewSectionLink() {
1100  return $this->mNewSectionLink;
1101  }
1102 
1108  public function forceHideNewSectionLink() {
1110  }
1111 
1120  public function setSyndicated( $show = true ) {
1121  if ( $show ) {
1122  $this->setFeedAppendQuery( false );
1123  } else {
1124  $this->mFeedLinks = [];
1125  }
1126  }
1127 
1137  public function setFeedAppendQuery( $val ) {
1138  $this->mFeedLinks = [];
1139 
1140  foreach ( $this->getConfig()->get( 'AdvertisedFeedTypes' ) as $type ) {
1141  $query = "feed=$type";
1142  if ( is_string( $val ) ) {
1143  $query .= '&' . $val;
1144  }
1145  $this->mFeedLinks[$type] = $this->getTitle()->getLocalURL( $query );
1146  }
1147  }
1148 
1155  public function addFeedLink( $format, $href ) {
1156  if ( in_array( $format, $this->getConfig()->get( 'AdvertisedFeedTypes' ) ) ) {
1157  $this->mFeedLinks[$format] = $href;
1158  }
1159  }
1160 
1165  public function isSyndicated() {
1166  return count( $this->mFeedLinks ) > 0;
1167  }
1168 
1173  public function getSyndicationLinks() {
1174  return $this->mFeedLinks;
1175  }
1176 
1182  public function getFeedAppendQuery() {
1184  }
1185 
1193  public function setArticleFlag( $v ) {
1194  $this->mIsarticle = $v;
1195  if ( $v ) {
1196  $this->mIsArticleRelated = $v;
1197  }
1198  }
1199 
1206  public function isArticle() {
1207  return $this->mIsarticle;
1208  }
1209 
1216  public function setArticleRelated( $v ) {
1217  $this->mIsArticleRelated = $v;
1218  if ( !$v ) {
1219  $this->mIsarticle = false;
1220  }
1221  }
1222 
1228  public function isArticleRelated() {
1229  return $this->mIsArticleRelated;
1230  }
1231 
1238  public function addLanguageLinks( array $newLinkArray ) {
1239  $this->mLanguageLinks += $newLinkArray;
1240  }
1241 
1248  public function setLanguageLinks( array $newLinkArray ) {
1249  $this->mLanguageLinks = $newLinkArray;
1250  }
1251 
1257  public function getLanguageLinks() {
1258  return $this->mLanguageLinks;
1259  }
1260 
1266  public function addCategoryLinks( array $categories ) {
1268 
1269  if ( !is_array( $categories ) || count( $categories ) == 0 ) {
1270  return;
1271  }
1272 
1273  # Add the links to a LinkBatch
1274  $arr = [ NS_CATEGORY => $categories ];
1275  $lb = new LinkBatch;
1276  $lb->setArray( $arr );
1277 
1278  # Fetch existence plus the hiddencat property
1279  $dbr = wfGetDB( DB_SLAVE );
1280  $fields = [ 'page_id', 'page_namespace', 'page_title', 'page_len',
1281  'page_is_redirect', 'page_latest', 'pp_value' ];
1282 
1283  if ( $this->getConfig()->get( 'ContentHandlerUseDB' ) ) {
1284  $fields[] = 'page_content_model';
1285  }
1286  if ( $this->getConfig()->get( 'PageLanguageUseDB' ) ) {
1287  $fields[] = 'page_lang';
1288  }
1289 
1290  $res = $dbr->select( [ 'page', 'page_props' ],
1291  $fields,
1292  $lb->constructSet( 'page', $dbr ),
1293  __METHOD__,
1294  [],
1295  [ 'page_props' => [ 'LEFT JOIN', [
1296  'pp_propname' => 'hiddencat',
1297  'pp_page = page_id'
1298  ] ] ]
1299  );
1300 
1301  # Add the results to the link cache
1302  $lb->addResultToCache( LinkCache::singleton(), $res );
1303 
1304  # Set all the values to 'normal'.
1305  $categories = array_fill_keys( array_keys( $categories ), 'normal' );
1306 
1307  # Mark hidden categories
1308  foreach ( $res as $row ) {
1309  if ( isset( $row->pp_value ) ) {
1310  $categories[$row->page_title] = 'hidden';
1311  }
1312  }
1313 
1314  // Avoid PHP 7.1 warning of passing $this by reference
1315  $outputPage = $this;
1316  # Add the remaining categories to the skin
1317  if ( Hooks::run(
1318  'OutputPageMakeCategoryLinks',
1319  [ &$outputPage, $categories, &$this->mCategoryLinks ] )
1320  ) {
1321  foreach ( $categories as $category => $type ) {
1322  // array keys will cast numeric category names to ints, so cast back to string
1323  $category = (string)$category;
1324  $origcategory = $category;
1325  $title = Title::makeTitleSafe( NS_CATEGORY, $category );
1326  if ( !$title ) {
1327  continue;
1328  }
1329  $wgContLang->findVariantLink( $category, $title, true );
1330  if ( $category != $origcategory && array_key_exists( $category, $categories ) ) {
1331  continue;
1332  }
1333  $text = $wgContLang->convertHtml( $title->getText() );
1334  $this->mCategories[] = $title->getText();
1335  $this->mCategoryLinks[$type][] = Linker::link( $title, $text );
1336  }
1337  }
1338  }
1339 
1345  public function setCategoryLinks( array $categories ) {
1346  $this->mCategoryLinks = [];
1347  $this->addCategoryLinks( $categories );
1348  }
1349 
1358  public function getCategoryLinks() {
1359  return $this->mCategoryLinks;
1360  }
1361 
1367  public function getCategories() {
1368  return $this->mCategories;
1369  }
1370 
1380  public function setIndicators( array $indicators ) {
1381  $this->mIndicators = $indicators + $this->mIndicators;
1382  // Keep ordered by key
1383  ksort( $this->mIndicators );
1384  }
1385 
1394  public function getIndicators() {
1395  return $this->mIndicators;
1396  }
1397 
1406  public function addHelpLink( $to, $overrideBaseUrl = false ) {
1407  $this->addModuleStyles( 'mediawiki.helplink' );
1408  $text = $this->msg( 'helppage-top-gethelp' )->escaped();
1409 
1410  if ( $overrideBaseUrl ) {
1411  $helpUrl = $to;
1412  } else {
1413  $toUrlencoded = wfUrlencode( str_replace( ' ', '_', $to ) );
1414  $helpUrl = "//www.mediawiki.org/wiki/Special:MyLanguage/$toUrlencoded";
1415  }
1416 
1418  'a',
1419  [
1420  'href' => $helpUrl,
1421  'target' => '_blank',
1422  'class' => 'mw-helplink',
1423  ],
1424  $text
1425  );
1426 
1427  $this->setIndicators( [ 'mw-helplink' => $link ] );
1428  }
1429 
1438  public function disallowUserJs() {
1439  $this->reduceAllowedModules(
1442  );
1443 
1444  // Site-wide styles are controlled by a config setting, see bug 71621
1445  // for background on why. User styles are never allowed.
1446  if ( $this->getConfig()->get( 'AllowSiteCSSOnRestrictedPages' ) ) {
1448  } else {
1450  }
1451  $this->reduceAllowedModules(
1453  $styleOrigin
1454  );
1455  }
1456 
1463  public function getAllowedModules( $type ) {
1465  return min( array_values( $this->mAllowedModules ) );
1466  } else {
1467  return isset( $this->mAllowedModules[$type] )
1468  ? $this->mAllowedModules[$type]
1470  }
1471  }
1472 
1482  public function reduceAllowedModules( $type, $level ) {
1483  $this->mAllowedModules[$type] = min( $this->getAllowedModules( $type ), $level );
1484  }
1485 
1491  public function prependHTML( $text ) {
1492  $this->mBodytext = $text . $this->mBodytext;
1493  }
1494 
1500  public function addHTML( $text ) {
1501  $this->mBodytext .= $text;
1502  }
1503 
1513  public function addElement( $element, array $attribs = [], $contents = '' ) {
1514  $this->addHTML( Html::element( $element, $attribs, $contents ) );
1515  }
1516 
1520  public function clearHTML() {
1521  $this->mBodytext = '';
1522  }
1523 
1529  public function getHTML() {
1530  return $this->mBodytext;
1531  }
1532 
1540  public function parserOptions( $options = null ) {
1541  if ( $options !== null && !empty( $options->isBogus ) ) {
1542  // Someone is trying to set a bogus pre-$wgUser PO. Check if it has
1543  // been changed somehow, and keep it if so.
1544  $anonPO = ParserOptions::newFromAnon();
1545  $anonPO->setEditSection( false );
1546  $anonPO->setAllowUnsafeRawHtml( false );
1547  if ( !$options->matches( $anonPO ) ) {
1548  wfLogWarning( __METHOD__ . ': Setting a changed bogus ParserOptions: ' . wfGetAllCallers( 5 ) );
1549  $options->isBogus = false;
1550  }
1551  }
1552 
1553  if ( !$this->mParserOptions ) {
1554  if ( !$this->getContext()->getUser()->isSafeToLoad() ) {
1555  // $wgUser isn't unstubbable yet, so don't try to get a
1556  // ParserOptions for it. And don't cache this ParserOptions
1557  // either.
1559  $po->setEditSection( false );
1560  $po->setAllowUnsafeRawHtml( false );
1561  $po->isBogus = true;
1562  if ( $options !== null ) {
1563  $this->mParserOptions = empty( $options->isBogus ) ? $options : null;
1564  }
1565  return $po;
1566  }
1567 
1568  $this->mParserOptions = ParserOptions::newFromContext( $this->getContext() );
1569  $this->mParserOptions->setEditSection( false );
1570  $this->mParserOptions->setAllowUnsafeRawHtml( false );
1571  }
1572 
1573  if ( $options !== null && !empty( $options->isBogus ) ) {
1574  // They're trying to restore the bogus pre-$wgUser PO. Do the right
1575  // thing.
1576  return wfSetVar( $this->mParserOptions, null, true );
1577  } else {
1578  return wfSetVar( $this->mParserOptions, $options );
1579  }
1580  }
1581 
1589  public function setRevisionId( $revid ) {
1590  $val = is_null( $revid ) ? null : intval( $revid );
1591  return wfSetVar( $this->mRevisionId, $val );
1592  }
1593 
1599  public function getRevisionId() {
1600  return $this->mRevisionId;
1601  }
1602 
1610  public function setRevisionTimestamp( $timestamp ) {
1611  return wfSetVar( $this->mRevisionTimestamp, $timestamp );
1612  }
1613 
1620  public function getRevisionTimestamp() {
1622  }
1623 
1630  public function setFileVersion( $file ) {
1631  $val = null;
1632  if ( $file instanceof File && $file->exists() ) {
1633  $val = [ 'time' => $file->getTimestamp(), 'sha1' => $file->getSha1() ];
1634  }
1635  return wfSetVar( $this->mFileVersion, $val, true );
1636  }
1637 
1643  public function getFileVersion() {
1644  return $this->mFileVersion;
1645  }
1646 
1653  public function getTemplateIds() {
1654  return $this->mTemplateIds;
1655  }
1656 
1663  public function getFileSearchOptions() {
1664  return $this->mImageTimeKeys;
1665  }
1666 
1676  public function addWikiText( $text, $linestart = true, $interface = true ) {
1677  $title = $this->getTitle(); // Work around E_STRICT
1678  if ( !$title ) {
1679  throw new MWException( 'Title is null' );
1680  }
1681  $this->addWikiTextTitle( $text, $title, $linestart, /*tidy*/false, $interface );
1682  }
1683 
1691  public function addWikiTextWithTitle( $text, &$title, $linestart = true ) {
1692  $this->addWikiTextTitle( $text, $title, $linestart );
1693  }
1694 
1702  function addWikiTextTitleTidy( $text, &$title, $linestart = true ) {
1703  $this->addWikiTextTitle( $text, $title, $linestart, true );
1704  }
1705 
1712  public function addWikiTextTidy( $text, $linestart = true ) {
1713  $title = $this->getTitle();
1714  $this->addWikiTextTitleTidy( $text, $title, $linestart );
1715  }
1716 
1727  public function addWikiTextTitle( $text, Title $title, $linestart,
1728  $tidy = false, $interface = false
1729  ) {
1730  global $wgParser;
1731 
1732  $popts = $this->parserOptions();
1733  $oldTidy = $popts->setTidy( $tidy );
1734  $popts->setInterfaceMessage( (bool)$interface );
1735 
1736  $parserOutput = $wgParser->getFreshParser()->parse(
1737  $text, $title, $popts,
1738  $linestart, true, $this->mRevisionId
1739  );
1740 
1741  $popts->setTidy( $oldTidy );
1742 
1743  $this->addParserOutput( $parserOutput );
1744 
1745  }
1746 
1754  wfDeprecated( __METHOD__, '1.24' );
1756  }
1757 
1767  $this->mLanguageLinks += $parserOutput->getLanguageLinks();
1768  $this->addCategoryLinks( $parserOutput->getCategories() );
1769  $this->setIndicators( $parserOutput->getIndicators() );
1770  $this->mNewSectionLink = $parserOutput->getNewSection();
1771  $this->mHideNewSectionLink = $parserOutput->getHideNewSection();
1772 
1773  if ( !$parserOutput->isCacheable() ) {
1774  $this->enableClientCache( false );
1775  }
1776  $this->mNoGallery = $parserOutput->getNoGallery();
1777  $this->mHeadItems = array_merge( $this->mHeadItems, $parserOutput->getHeadItems() );
1778  $this->addModules( $parserOutput->getModules() );
1779  $this->addModuleScripts( $parserOutput->getModuleScripts() );
1780  $this->addModuleStyles( $parserOutput->getModuleStyles() );
1781  $this->addJsConfigVars( $parserOutput->getJsConfigVars() );
1782  $this->mPreventClickjacking = $this->mPreventClickjacking
1783  || $parserOutput->preventClickjacking();
1784 
1785  // Template versioning...
1786  foreach ( (array)$parserOutput->getTemplateIds() as $ns => $dbks ) {
1787  if ( isset( $this->mTemplateIds[$ns] ) ) {
1788  $this->mTemplateIds[$ns] = $dbks + $this->mTemplateIds[$ns];
1789  } else {
1790  $this->mTemplateIds[$ns] = $dbks;
1791  }
1792  }
1793  // File versioning...
1794  foreach ( (array)$parserOutput->getFileSearchOptions() as $dbk => $data ) {
1795  $this->mImageTimeKeys[$dbk] = $data;
1796  }
1797 
1798  // Hooks registered in the object
1799  $parserOutputHooks = $this->getConfig()->get( 'ParserOutputHooks' );
1800  foreach ( $parserOutput->getOutputHooks() as $hookInfo ) {
1801  list( $hookName, $data ) = $hookInfo;
1802  if ( isset( $parserOutputHooks[$hookName] ) ) {
1803  call_user_func( $parserOutputHooks[$hookName], $this, $parserOutput, $data );
1804  }
1805  }
1806 
1807  // enable OOUI if requested via ParserOutput
1808  if ( $parserOutput->getEnableOOUI() ) {
1809  $this->enableOOUI();
1810  }
1811 
1812  // Link flags are ignored for now, but may in the future be
1813  // used to mark individual language links.
1814  $linkFlags = [];
1815  // Avoid PHP 7.1 warning of passing $this by reference
1816  $outputPage = $this;
1817  Hooks::run( 'LanguageLinks', [ $this->getTitle(), &$this->mLanguageLinks, &$linkFlags ] );
1818  Hooks::run( 'OutputPageParserOutput', [ &$outputPage, $parserOutput ] );
1819  }
1820 
1830 
1831  $this->addModules( $parserOutput->getModules() );
1832  $this->addModuleScripts( $parserOutput->getModuleScripts() );
1833  $this->addModuleStyles( $parserOutput->getModuleStyles() );
1834 
1835  $this->addJsConfigVars( $parserOutput->getJsConfigVars() );
1836  }
1837 
1844  public function addParserOutputText( $parserOutput ) {
1845  $text = $parserOutput->getText();
1846  // Avoid PHP 7.1 warning of passing $this by reference
1847  $outputPage = $this;
1848  Hooks::run( 'OutputPageBeforeHTML', [ &$outputPage, &$text ] );
1849  $this->addHTML( $text );
1850  }
1851 
1859  $parserOutput->setTOCEnabled( $this->mEnableTOC );
1860 
1861  // Touch section edit links only if not previously disabled
1862  if ( $parserOutput->getEditSectionTokens() ) {
1863  $parserOutput->setEditSectionTokens( $this->mEnableSectionEditLinks );
1864  }
1865 
1867  }
1868 
1874  public function addTemplate( &$template ) {
1875  $this->addHTML( $template->getHTML() );
1876  }
1877 
1890  public function parse( $text, $linestart = true, $interface = false, $language = null ) {
1891  global $wgParser;
1892 
1893  if ( is_null( $this->getTitle() ) ) {
1894  throw new MWException( 'Empty $mTitle in ' . __METHOD__ );
1895  }
1896 
1897  $popts = $this->parserOptions();
1898  if ( $interface ) {
1899  $popts->setInterfaceMessage( true );
1900  }
1901  if ( $language !== null ) {
1902  $oldLang = $popts->setTargetLanguage( $language );
1903  }
1904 
1905  $parserOutput = $wgParser->getFreshParser()->parse(
1906  $text, $this->getTitle(), $popts,
1907  $linestart, true, $this->mRevisionId
1908  );
1909 
1910  if ( $interface ) {
1911  $popts->setInterfaceMessage( false );
1912  }
1913  if ( $language !== null ) {
1914  $popts->setTargetLanguage( $oldLang );
1915  }
1916 
1917  return $parserOutput->getText();
1918  }
1919 
1930  public function parseInline( $text, $linestart = true, $interface = false ) {
1931  $parsed = $this->parse( $text, $linestart, $interface );
1932  return Parser::stripOuterParagraph( $parsed );
1933  }
1934 
1939  public function setSquidMaxage( $maxage ) {
1940  $this->setCdnMaxage( $maxage );
1941  }
1942 
1948  public function setCdnMaxage( $maxage ) {
1949  $this->mCdnMaxage = min( $maxage, $this->mCdnMaxageLimit );
1950  }
1951 
1958  public function lowerCdnMaxage( $maxage ) {
1959  $this->mCdnMaxageLimit = min( $maxage, $this->mCdnMaxageLimit );
1960  $this->setCdnMaxage( $this->mCdnMaxage );
1961  }
1962 
1970  public function enableClientCache( $state ) {
1971  return wfSetVar( $this->mEnableClientCache, $state );
1972  }
1973 
1979  function getCacheVaryCookies() {
1980  static $cookies;
1981  if ( $cookies === null ) {
1982  $config = $this->getConfig();
1983  $cookies = array_merge(
1984  SessionManager::singleton()->getVaryCookies(),
1985  [
1986  'forceHTTPS',
1987  ],
1988  $config->get( 'CacheVaryCookies' )
1989  );
1990  Hooks::run( 'GetCacheVaryCookies', [ $this, &$cookies ] );
1991  }
1992  return $cookies;
1993  }
1994 
2002  $request = $this->getRequest();
2003  foreach ( $this->getCacheVaryCookies() as $cookieName ) {
2004  if ( $request->getCookie( $cookieName, '', '' ) !== '' ) {
2005  wfDebug( __METHOD__ . ": found $cookieName\n" );
2006  return true;
2007  }
2008  }
2009  wfDebug( __METHOD__ . ": no cache-varying cookies found\n" );
2010  return false;
2011  }
2012 
2021  public function addVaryHeader( $header, array $option = null ) {
2022  if ( !array_key_exists( $header, $this->mVaryHeader ) ) {
2023  $this->mVaryHeader[$header] = [];
2024  }
2025  if ( !is_array( $option ) ) {
2026  $option = [];
2027  }
2028  $this->mVaryHeader[$header] = array_unique( array_merge( $this->mVaryHeader[$header], $option ) );
2029  }
2030 
2037  public function getVaryHeader() {
2038  // If we vary on cookies, let's make sure it's always included here too.
2039  if ( $this->getCacheVaryCookies() ) {
2040  $this->addVaryHeader( 'Cookie' );
2041  }
2042 
2043  foreach ( SessionManager::singleton()->getVaryHeaders() as $header => $options ) {
2044  $this->addVaryHeader( $header, $options );
2045  }
2046  return 'Vary: ' . implode( ', ', array_keys( $this->mVaryHeader ) );
2047  }
2048 
2054  public function getKeyHeader() {
2055  $cvCookies = $this->getCacheVaryCookies();
2056 
2057  $cookiesOption = [];
2058  foreach ( $cvCookies as $cookieName ) {
2059  $cookiesOption[] = 'param=' . $cookieName;
2060  }
2061  $this->addVaryHeader( 'Cookie', $cookiesOption );
2062 
2063  foreach ( SessionManager::singleton()->getVaryHeaders() as $header => $options ) {
2064  $this->addVaryHeader( $header, $options );
2065  }
2066 
2067  $headers = [];
2068  foreach ( $this->mVaryHeader as $header => $option ) {
2069  $newheader = $header;
2070  if ( is_array( $option ) && count( $option ) > 0 ) {
2071  $newheader .= ';' . implode( ';', $option );
2072  }
2073  $headers[] = $newheader;
2074  }
2075  $key = 'Key: ' . implode( ',', $headers );
2076 
2077  return $key;
2078  }
2079 
2088  function addAcceptLanguage() {
2089  $title = $this->getTitle();
2090  if ( !$title instanceof Title ) {
2091  return;
2092  }
2093 
2094  $lang = $title->getPageLanguage();
2095  if ( !$this->getRequest()->getCheck( 'variant' ) && $lang->hasVariants() ) {
2096  $variants = $lang->getVariants();
2097  $aloption = [];
2098  foreach ( $variants as $variant ) {
2099  if ( $variant === $lang->getCode() ) {
2100  continue;
2101  } else {
2102  $aloption[] = 'substr=' . $variant;
2103 
2104  // IE and some other browsers use BCP 47 standards in
2105  // their Accept-Language header, like "zh-CN" or "zh-Hant".
2106  // We should handle these too.
2107  $variantBCP47 = wfBCP47( $variant );
2108  if ( $variantBCP47 !== $variant ) {
2109  $aloption[] = 'substr=' . $variantBCP47;
2110  }
2111  }
2112  }
2113  $this->addVaryHeader( 'Accept-Language', $aloption );
2114  }
2115  }
2116 
2127  public function preventClickjacking( $enable = true ) {
2128  $this->mPreventClickjacking = $enable;
2129  }
2130 
2136  public function allowClickjacking() {
2137  $this->mPreventClickjacking = false;
2138  }
2139 
2146  public function getPreventClickjacking() {
2148  }
2149 
2157  public function getFrameOptions() {
2158  $config = $this->getConfig();
2159  if ( $config->get( 'BreakFrames' ) ) {
2160  return 'DENY';
2161  } elseif ( $this->mPreventClickjacking && $config->get( 'EditPageFrameOptions' ) ) {
2162  return $config->get( 'EditPageFrameOptions' );
2163  }
2164  return false;
2165  }
2166 
2170  public function sendCacheControl() {
2171  $response = $this->getRequest()->response();
2172  $config = $this->getConfig();
2173  if ( $config->get( 'UseETag' ) && $this->mETag ) {
2174  $response->header( "ETag: $this->mETag" );
2175  }
2176 
2177  $this->addVaryHeader( 'Cookie' );
2178  $this->addAcceptLanguage();
2179 
2180  # don't serve compressed data to clients who can't handle it
2181  # maintain different caches for logged-in users and non-logged in ones
2182  $response->header( $this->getVaryHeader() );
2183 
2184  if ( $config->get( 'UseKeyHeader' ) ) {
2185  $response->header( $this->getKeyHeader() );
2186  }
2187 
2188  if ( $this->mEnableClientCache ) {
2189  if (
2190  $config->get( 'UseSquid' ) &&
2191  !$response->hasCookies() &&
2192  !SessionManager::getGlobalSession()->isPersistent() &&
2193  !$this->isPrintable() &&
2194  $this->mCdnMaxage != 0 &&
2195  !$this->haveCacheVaryCookies()
2196  ) {
2197  if ( $config->get( 'UseESI' ) ) {
2198  # We'll purge the proxy cache explicitly, but require end user agents
2199  # to revalidate against the proxy on each visit.
2200  # Surrogate-Control controls our CDN, Cache-Control downstream caches
2201  wfDebug( __METHOD__ . ": proxy caching with ESI; {$this->mLastModified} **", 'private' );
2202  # start with a shorter timeout for initial testing
2203  # header( 'Surrogate-Control: max-age=2678400+2678400, content="ESI/1.0"');
2204  $response->header( 'Surrogate-Control: max-age=' . $config->get( 'SquidMaxage' )
2205  . '+' . $this->mCdnMaxage . ', content="ESI/1.0"' );
2206  $response->header( 'Cache-Control: s-maxage=0, must-revalidate, max-age=0' );
2207  } else {
2208  # We'll purge the proxy cache for anons explicitly, but require end user agents
2209  # to revalidate against the proxy on each visit.
2210  # IMPORTANT! The CDN needs to replace the Cache-Control header with
2211  # Cache-Control: s-maxage=0, must-revalidate, max-age=0
2212  wfDebug( __METHOD__ . ": local proxy caching; {$this->mLastModified} **", 'private' );
2213  # start with a shorter timeout for initial testing
2214  # header( "Cache-Control: s-maxage=2678400, must-revalidate, max-age=0" );
2215  $response->header( 'Cache-Control: s-maxage=' . $this->mCdnMaxage
2216  . ', must-revalidate, max-age=0' );
2217  }
2218  } else {
2219  # We do want clients to cache if they can, but they *must* check for updates
2220  # on revisiting the page.
2221  wfDebug( __METHOD__ . ": private caching; {$this->mLastModified} **", 'private' );
2222  $response->header( 'Expires: ' . gmdate( 'D, d M Y H:i:s', 0 ) . ' GMT' );
2223  $response->header( "Cache-Control: private, must-revalidate, max-age=0" );
2224  }
2225  if ( $this->mLastModified ) {
2226  $response->header( "Last-Modified: {$this->mLastModified}" );
2227  }
2228  } else {
2229  wfDebug( __METHOD__ . ": no caching **", 'private' );
2230 
2231  # In general, the absence of a last modified header should be enough to prevent
2232  # the client from using its cache. We send a few other things just to make sure.
2233  $response->header( 'Expires: ' . gmdate( 'D, d M Y H:i:s', 0 ) . ' GMT' );
2234  $response->header( 'Cache-Control: no-cache, no-store, max-age=0, must-revalidate' );
2235  $response->header( 'Pragma: no-cache' );
2236  }
2237  }
2238 
2243  public function output() {
2244  if ( $this->mDoNothing ) {
2245  return;
2246  }
2247 
2248  $response = $this->getRequest()->response();
2249  $config = $this->getConfig();
2250 
2251  if ( $this->mRedirect != '' ) {
2252  # Standards require redirect URLs to be absolute
2253  $this->mRedirect = wfExpandUrl( $this->mRedirect, PROTO_CURRENT );
2254 
2255  $redirect = $this->mRedirect;
2257 
2258  if ( Hooks::run( "BeforePageRedirect", [ $this, &$redirect, &$code ] ) ) {
2259  if ( $code == '301' || $code == '303' ) {
2260  if ( !$config->get( 'DebugRedirects' ) ) {
2261  $response->statusHeader( $code );
2262  }
2263  $this->mLastModified = wfTimestamp( TS_RFC2822 );
2264  }
2265  if ( $config->get( 'VaryOnXFP' ) ) {
2266  $this->addVaryHeader( 'X-Forwarded-Proto' );
2267  }
2268  $this->sendCacheControl();
2269 
2270  $response->header( "Content-Type: text/html; charset=utf-8" );
2271  if ( $config->get( 'DebugRedirects' ) ) {
2272  $url = htmlspecialchars( $redirect );
2273  print "<html>\n<head>\n<title>Redirect</title>\n</head>\n<body>\n";
2274  print "<p>Location: <a href=\"$url\">$url</a></p>\n";
2275  print "</body>\n</html>\n";
2276  } else {
2277  $response->header( 'Location: ' . $redirect );
2278  }
2279  }
2280 
2281  return;
2282  } elseif ( $this->mStatusCode ) {
2283  $response->statusHeader( $this->mStatusCode );
2284  }
2285 
2286  # Buffer output; final headers may depend on later processing
2287  ob_start();
2288 
2289  $response->header( 'Content-type: ' . $config->get( 'MimeType' ) . '; charset=UTF-8' );
2290  $response->header( 'Content-language: ' . $config->get( 'LanguageCode' ) );
2291 
2292  // Avoid Internet Explorer "compatibility view" in IE 8-10, so that
2293  // jQuery etc. can work correctly.
2294  $response->header( 'X-UA-Compatible: IE=Edge' );
2295 
2296  // Prevent framing, if requested
2297  $frameOptions = $this->getFrameOptions();
2298  if ( $frameOptions ) {
2299  $response->header( "X-Frame-Options: $frameOptions" );
2300  }
2301 
2302  if ( $this->mArticleBodyOnly ) {
2303  echo $this->mBodytext;
2304  } else {
2305  $sk = $this->getSkin();
2306  // add skin specific modules
2307  $modules = $sk->getDefaultModules();
2308 
2309  // Enforce various default modules for all skins
2310  $coreModules = [
2311  // Keep this list as small as possible
2312  'site',
2313  'mediawiki.page.startup',
2314  'mediawiki.user',
2315  ];
2316 
2317  // Support for high-density display images if enabled
2318  if ( $config->get( 'ResponsiveImages' ) ) {
2319  $coreModules[] = 'mediawiki.hidpi';
2320  }
2321 
2322  $this->addModules( $coreModules );
2323  foreach ( $modules as $group ) {
2324  $this->addModules( $group );
2325  }
2326  MWDebug::addModules( $this );
2327 
2328  // Avoid PHP 7.1 warning of passing $this by reference
2329  $outputPage = $this;
2330  // Hook that allows last minute changes to the output page, e.g.
2331  // adding of CSS or Javascript by extensions.
2332  Hooks::run( 'BeforePageDisplay', [ &$outputPage, &$sk ] );
2333 
2334  try {
2335  $sk->outputPage();
2336  } catch ( Exception $e ) {
2337  ob_end_clean(); // bug T129657
2338  throw $e;
2339  }
2340  }
2341 
2342  try {
2343  // This hook allows last minute changes to final overall output by modifying output buffer
2344  Hooks::run( 'AfterFinalPageOutput', [ $this ] );
2345  } catch ( Exception $e ) {
2346  ob_end_clean(); // bug T129657
2347  throw $e;
2348  }
2349 
2350  $this->sendCacheControl();
2351 
2352  ob_end_flush();
2353 
2354  }
2355 
2366  public function prepareErrorPage( $pageTitle, $htmlTitle = false ) {
2367  $this->setPageTitle( $pageTitle );
2368  if ( $htmlTitle !== false ) {
2369  $this->setHTMLTitle( $htmlTitle );
2370  }
2371  $this->setRobotPolicy( 'noindex,nofollow' );
2372  $this->setArticleRelated( false );
2373  $this->enableClientCache( false );
2374  $this->mRedirect = '';
2375  $this->clearSubtitle();
2376  $this->clearHTML();
2377  }
2378 
2391  public function showErrorPage( $title, $msg, $params = [] ) {
2392  if ( !$title instanceof Message ) {
2393  $title = $this->msg( $title );
2394  }
2395 
2396  $this->prepareErrorPage( $title );
2397 
2398  if ( $msg instanceof Message ) {
2399  if ( $params !== [] ) {
2400  trigger_error( 'Argument ignored: $params. The message parameters argument '
2401  . 'is discarded when the $msg argument is a Message object instead of '
2402  . 'a string.', E_USER_NOTICE );
2403  }
2404  $this->addHTML( $msg->parseAsBlock() );
2405  } else {
2406  $this->addWikiMsgArray( $msg, $params );
2407  }
2408 
2409  $this->returnToMain();
2410  }
2411 
2418  public function showPermissionsErrorPage( array $errors, $action = null ) {
2419  // For some action (read, edit, create and upload), display a "login to do this action"
2420  // error if all of the following conditions are met:
2421  // 1. the user is not logged in
2422  // 2. the only error is insufficient permissions (i.e. no block or something else)
2423  // 3. the error can be avoided simply by logging in
2424  if ( in_array( $action, [ 'read', 'edit', 'createpage', 'createtalk', 'upload' ] )
2425  && $this->getUser()->isAnon() && count( $errors ) == 1 && isset( $errors[0][0] )
2426  && ( $errors[0][0] == 'badaccess-groups' || $errors[0][0] == 'badaccess-group0' )
2427  && ( User::groupHasPermission( 'user', $action )
2428  || User::groupHasPermission( 'autoconfirmed', $action ) )
2429  ) {
2430  $displayReturnto = null;
2431 
2432  # Due to bug 32276, if a user does not have read permissions,
2433  # $this->getTitle() will just give Special:Badtitle, which is
2434  # not especially useful as a returnto parameter. Use the title
2435  # from the request instead, if there was one.
2436  $request = $this->getRequest();
2437  $returnto = Title::newFromText( $request->getVal( 'title', '' ) );
2438  if ( $action == 'edit' ) {
2439  $msg = 'whitelistedittext';
2440  $displayReturnto = $returnto;
2441  } elseif ( $action == 'createpage' || $action == 'createtalk' ) {
2442  $msg = 'nocreatetext';
2443  } elseif ( $action == 'upload' ) {
2444  $msg = 'uploadnologintext';
2445  } else { # Read
2446  $msg = 'loginreqpagetext';
2447  $displayReturnto = Title::newMainPage();
2448  }
2449 
2450  $query = [];
2451 
2452  if ( $returnto ) {
2453  $query['returnto'] = $returnto->getPrefixedText();
2454 
2455  if ( !$request->wasPosted() ) {
2456  $returntoquery = $request->getValues();
2457  unset( $returntoquery['title'] );
2458  unset( $returntoquery['returnto'] );
2459  unset( $returntoquery['returntoquery'] );
2460  $query['returntoquery'] = wfArrayToCgi( $returntoquery );
2461  }
2462  }
2463  $loginLink = Linker::linkKnown(
2464  SpecialPage::getTitleFor( 'Userlogin' ),
2465  $this->msg( 'loginreqlink' )->escaped(),
2466  [],
2467  $query
2468  );
2469 
2470  $this->prepareErrorPage( $this->msg( 'loginreqtitle' ) );
2471  $this->addHTML( $this->msg( $msg )->rawParams( $loginLink )->parse() );
2472 
2473  # Don't return to a page the user can't read otherwise
2474  # we'll end up in a pointless loop
2475  if ( $displayReturnto && $displayReturnto->userCan( 'read', $this->getUser() ) ) {
2476  $this->returnToMain( null, $displayReturnto );
2477  }
2478  } else {
2479  $this->prepareErrorPage( $this->msg( 'permissionserrors' ) );
2480  $this->addWikiText( $this->formatPermissionsErrorMessage( $errors, $action ) );
2481  }
2482  }
2483 
2490  public function versionRequired( $version ) {
2491  $this->prepareErrorPage( $this->msg( 'versionrequired', $version ) );
2492 
2493  $this->addWikiMsg( 'versionrequiredtext', $version );
2494  $this->returnToMain();
2495  }
2496 
2504  public function formatPermissionsErrorMessage( array $errors, $action = null ) {
2505  if ( $action == null ) {
2506  $text = $this->msg( 'permissionserrorstext', count( $errors ) )->plain() . "\n\n";
2507  } else {
2508  $action_desc = $this->msg( "action-$action" )->plain();
2509  $text = $this->msg(
2510  'permissionserrorstext-withaction',
2511  count( $errors ),
2512  $action_desc
2513  )->plain() . "\n\n";
2514  }
2515 
2516  if ( count( $errors ) > 1 ) {
2517  $text .= '<ul class="permissions-errors">' . "\n";
2518 
2519  foreach ( $errors as $error ) {
2520  $text .= '<li>';
2521  $text .= call_user_func_array( [ $this, 'msg' ], $error )->plain();
2522  $text .= "</li>\n";
2523  }
2524  $text .= '</ul>';
2525  } else {
2526  $text .= "<div class=\"permissions-errors\">\n" .
2527  call_user_func_array( [ $this, 'msg' ], reset( $errors ) )->plain() .
2528  "\n</div>";
2529  }
2530 
2531  return $text;
2532  }
2533 
2545  public function readOnlyPage() {
2546  if ( func_num_args() > 0 ) {
2547  throw new MWException( __METHOD__ . ' no longer accepts arguments since 1.25.' );
2548  }
2549 
2550  throw new ReadOnlyError;
2551  }
2552 
2559  public function rateLimited() {
2560  wfDeprecated( __METHOD__, '1.25' );
2561  throw new ThrottledError;
2562  }
2563 
2573  public function showLagWarning( $lag ) {
2574  $config = $this->getConfig();
2575  if ( $lag >= $config->get( 'SlaveLagWarning' ) ) {
2576  $message = $lag < $config->get( 'SlaveLagCritical' )
2577  ? 'lag-warn-normal'
2578  : 'lag-warn-high';
2579  $wrap = Html::rawElement( 'div', [ 'class' => "mw-{$message}" ], "\n$1\n" );
2580  $this->wrapWikiMsg( "$wrap\n", [ $message, $this->getLanguage()->formatNum( $lag ) ] );
2581  }
2582  }
2583 
2584  public function showFatalError( $message ) {
2585  $this->prepareErrorPage( $this->msg( 'internalerror' ) );
2586 
2587  $this->addHTML( $message );
2588  }
2589 
2590  public function showUnexpectedValueError( $name, $val ) {
2591  $this->showFatalError( $this->msg( 'unexpected', $name, $val )->text() );
2592  }
2593 
2594  public function showFileCopyError( $old, $new ) {
2595  $this->showFatalError( $this->msg( 'filecopyerror', $old, $new )->text() );
2596  }
2597 
2598  public function showFileRenameError( $old, $new ) {
2599  $this->showFatalError( $this->msg( 'filerenameerror', $old, $new )->text() );
2600  }
2601 
2602  public function showFileDeleteError( $name ) {
2603  $this->showFatalError( $this->msg( 'filedeleteerror', $name )->text() );
2604  }
2605 
2606  public function showFileNotFoundError( $name ) {
2607  $this->showFatalError( $this->msg( 'filenotfound', $name )->text() );
2608  }
2609 
2618  public function addReturnTo( $title, array $query = [], $text = null, $options = [] ) {
2619  $link = $this->msg( 'returnto' )->rawParams(
2620  Linker::link( $title, $text, [], $query, $options ) )->escaped();
2621  $this->addHTML( "<p id=\"mw-returnto\">{$link}</p>\n" );
2622  }
2623 
2632  public function returnToMain( $unused = null, $returnto = null, $returntoquery = null ) {
2633  if ( $returnto == null ) {
2634  $returnto = $this->getRequest()->getText( 'returnto' );
2635  }
2636 
2637  if ( $returntoquery == null ) {
2638  $returntoquery = $this->getRequest()->getText( 'returntoquery' );
2639  }
2640 
2641  if ( $returnto === '' ) {
2642  $returnto = Title::newMainPage();
2643  }
2644 
2645  if ( is_object( $returnto ) ) {
2646  $titleObj = $returnto;
2647  } else {
2648  $titleObj = Title::newFromText( $returnto );
2649  }
2650  // We don't want people to return to external interwiki. That
2651  // might potentially be used as part of a phishing scheme
2652  if ( !is_object( $titleObj ) || $titleObj->isExternal() ) {
2653  $titleObj = Title::newMainPage();
2654  }
2655 
2656  $this->addReturnTo( $titleObj, wfCgiToArray( $returntoquery ) );
2657  }
2658 
2664  public function headElement( Skin $sk, $includeStyle = true ) {
2666 
2667  $userdir = $this->getLanguage()->getDir();
2668  $sitedir = $wgContLang->getDir();
2669 
2671 
2672  if ( $this->getHTMLTitle() == '' ) {
2673  $this->setHTMLTitle( $this->msg( 'pagetitle', $this->getPageTitle() )->inContentLanguage() );
2674  }
2675 
2676  $openHead = Html::openElement( 'head' );
2677  if ( $openHead ) {
2678  # Don't bother with the newline if $head == ''
2679  $ret .= "$openHead\n";
2680  }
2681 
2682  if ( !Html::isXmlMimeType( $this->getConfig()->get( 'MimeType' ) ) ) {
2683  // Add <meta charset="UTF-8">
2684  // This should be before <title> since it defines the charset used by
2685  // text including the text inside <title>.
2686  // The spec recommends defining XHTML5's charset using the XML declaration
2687  // instead of meta.
2688  // Our XML declaration is output by Html::htmlHeader.
2689  // http://www.whatwg.org/html/semantics.html#attr-meta-http-equiv-content-type
2690  // http://www.whatwg.org/html/semantics.html#charset
2691  $ret .= Html::element( 'meta', [ 'charset' => 'UTF-8' ] ) . "\n";
2692  }
2693 
2694  $ret .= Html::element( 'title', null, $this->getHTMLTitle() ) . "\n";
2695  $ret .= $this->getInlineHeadScripts() . "\n";
2696  $ret .= $this->buildCssLinks() . "\n";
2697  $ret .= $this->getExternalHeadScripts() . "\n";
2698 
2699  foreach ( $this->getHeadLinksArray() as $item ) {
2700  $ret .= $item . "\n";
2701  }
2702 
2703  foreach ( $this->mHeadItems as $item ) {
2704  $ret .= $item . "\n";
2705  }
2706 
2707  $closeHead = Html::closeElement( 'head' );
2708  if ( $closeHead ) {
2709  $ret .= "$closeHead\n";
2710  }
2711 
2712  $bodyClasses = [];
2713  $bodyClasses[] = 'mediawiki';
2714 
2715  # Classes for LTR/RTL directionality support
2716  $bodyClasses[] = $userdir;
2717  $bodyClasses[] = "sitedir-$sitedir";
2718 
2719  if ( $this->getLanguage()->capitalizeAllNouns() ) {
2720  # A <body> class is probably not the best way to do this . . .
2721  $bodyClasses[] = 'capitalize-all-nouns';
2722  }
2723 
2724  $bodyClasses[] = $sk->getPageClasses( $this->getTitle() );
2725  $bodyClasses[] = 'skin-' . Sanitizer::escapeClass( $sk->getSkinName() );
2726  $bodyClasses[] =
2727  'action-' . Sanitizer::escapeClass( Action::getActionName( $this->getContext() ) );
2728 
2729  $bodyAttrs = [];
2730  // While the implode() is not strictly needed, it's used for backwards compatibility
2731  // (this used to be built as a string and hooks likely still expect that).
2732  $bodyAttrs['class'] = implode( ' ', $bodyClasses );
2733 
2734  // Allow skins and extensions to add body attributes they need
2735  $sk->addToBodyAttributes( $this, $bodyAttrs );
2736  Hooks::run( 'OutputPageBodyAttributes', [ $this, $sk, &$bodyAttrs ] );
2737 
2738  $ret .= Html::openElement( 'body', $bodyAttrs ) . "\n";
2739 
2740  return $ret;
2741  }
2742 
2748  public function getResourceLoader() {
2749  if ( is_null( $this->mResourceLoader ) ) {
2750  $this->mResourceLoader = new ResourceLoader(
2751  $this->getConfig(),
2752  LoggerFactory::getInstance( 'resourceloader' )
2753  );
2754  }
2755  return $this->mResourceLoader;
2756  }
2757 
2768  public function makeResourceLoaderLink( $modules, $only, array $extraQuery = [] ) {
2769  $modules = (array)$modules;
2770 
2771  $links = [
2772  // List of html strings
2773  'html' => [],
2774  // Associative array of module names and their states
2775  'states' => [],
2776  ];
2777 
2778  if ( !count( $modules ) ) {
2779  return $links;
2780  }
2781 
2782  if ( count( $modules ) > 1 ) {
2783  // Remove duplicate module requests
2784  $modules = array_unique( $modules );
2785  // Sort module names so requests are more uniform
2786  sort( $modules );
2787 
2788  if ( ResourceLoader::inDebugMode() ) {
2789  // Recursively call us for every item
2790  foreach ( $modules as $name ) {
2791  $link = $this->makeResourceLoaderLink( $name, $only, $extraQuery );
2792  $links['html'] = array_merge( $links['html'], $link['html'] );
2793  $links['states'] += $link['states'];
2794  }
2795  return $links;
2796  }
2797  }
2798 
2799  if ( !is_null( $this->mTarget ) ) {
2800  $extraQuery['target'] = $this->mTarget;
2801  }
2802 
2803  // Create keyed-by-source and then keyed-by-group list of module objects from modules list
2804  $sortedModules = [];
2806  foreach ( $modules as $name ) {
2807  $module = $resourceLoader->getModule( $name );
2808  # Check that we're allowed to include this module on this page
2809  if ( !$module
2810  || ( $module->getOrigin() > $this->getAllowedModules( ResourceLoaderModule::TYPE_SCRIPTS )
2812  || ( $module->getOrigin() > $this->getAllowedModules( ResourceLoaderModule::TYPE_STYLES )
2813  && $only == ResourceLoaderModule::TYPE_STYLES )
2814  || ( $module->getOrigin() > $this->getAllowedModules( ResourceLoaderModule::TYPE_COMBINED )
2816  || ( $this->mTarget && !in_array( $this->mTarget, $module->getTargets() ) )
2817  ) {
2818  continue;
2819  }
2820 
2821  $sortedModules[$module->getSource()][$module->getGroup()][$name] = $module;
2822  }
2823 
2824  foreach ( $sortedModules as $source => $groups ) {
2825  foreach ( $groups as $group => $grpModules ) {
2826  // Special handling for user-specific groups
2827  $user = null;
2828  if ( ( $group === 'user' || $group === 'private' ) && $this->getUser()->isLoggedIn() ) {
2829  $user = $this->getUser()->getName();
2830  }
2831 
2832  // Create a fake request based on the one we are about to make so modules return
2833  // correct timestamp and emptiness data
2835  [], // modules; not determined yet
2836  $this->getLanguage()->getCode(),
2837  $this->getSkin()->getSkinName(),
2838  $user,
2839  null, // version; not determined yet
2841  $only === ResourceLoaderModule::TYPE_COMBINED ? null : $only,
2842  $this->isPrintable(),
2843  $this->getRequest()->getBool( 'handheld' ),
2844  $extraQuery
2845  );
2847 
2848  // Extract modules that know they're empty and see if we have one or more
2849  // raw modules
2850  $isRaw = false;
2851  foreach ( $grpModules as $key => $module ) {
2852  // Inline empty modules: since they're empty, just mark them as 'ready' (bug 46857)
2853  // If we're only getting the styles, we don't need to do anything for empty modules.
2854  if ( $module->isKnownEmpty( $context ) ) {
2855  unset( $grpModules[$key] );
2856  if ( $only !== ResourceLoaderModule::TYPE_STYLES ) {
2857  $links['states'][$key] = 'ready';
2858  }
2859  }
2860 
2861  $isRaw |= $module->isRaw();
2862  }
2863 
2864  // If there are no non-empty modules, skip this group
2865  if ( count( $grpModules ) === 0 ) {
2866  continue;
2867  }
2868 
2869  // Inline private modules. These can't be loaded through load.php for security
2870  // reasons, see bug 34907. Note that these modules should be loaded from
2871  // getExternalHeadScripts() before the first loader call. Otherwise other modules can't
2872  // properly use them as dependencies (bug 30914)
2873  if ( $group === 'private' ) {
2874  if ( $only == ResourceLoaderModule::TYPE_STYLES ) {
2875  $links['html'][] = Html::inlineStyle(
2876  $resourceLoader->makeModuleResponse( $context, $grpModules )
2877  );
2878  } else {
2879  $links['html'][] = ResourceLoader::makeInlineScript(
2880  $resourceLoader->makeModuleResponse( $context, $grpModules )
2881  );
2882  }
2883  continue;
2884  }
2885 
2886  // Special handling for the user group; because users might change their stuff
2887  // on-wiki like user pages, or user preferences; we need to find the highest
2888  // timestamp of these user-changeable modules so we can ensure cache misses on change
2889  // This should NOT be done for the site group (bug 27564) because anons get that too
2890  // and we shouldn't be putting timestamps in CDN-cached HTML
2891  $version = null;
2892  if ( $group === 'user' ) {
2893  $query['version'] = $resourceLoader->getCombinedVersion( $context, array_keys( $grpModules ) );
2894  }
2895 
2896  $query['modules'] = ResourceLoader::makePackedModulesString( array_keys( $grpModules ) );
2897  $moduleContext = new ResourceLoaderContext( $resourceLoader, new FauxRequest( $query ) );
2898  $url = $resourceLoader->createLoaderURL( $source, $moduleContext, $extraQuery );
2899 
2900  // Automatically select style/script elements
2901  if ( $only === ResourceLoaderModule::TYPE_STYLES ) {
2902  $link = Html::linkedStyle( $url );
2903  } else {
2904  if ( $context->getRaw() || $isRaw ) {
2905  // Startup module can't load itself, needs to use <script> instead of mw.loader.load
2906  $link = Html::element( 'script', [
2907  // In SpecialJavaScriptTest, QUnit must load synchronous
2908  'async' => !isset( $extraQuery['sync'] ),
2909  'src' => $url
2910  ] );
2911  } else {
2913  Xml::encodeJsCall( 'mw.loader.load', [ $url ] )
2914  );
2915  }
2916 
2917  // For modules requested directly in the html via <script> or mw.loader.load
2918  // tell mw.loader they are being loading to prevent duplicate requests.
2919  foreach ( $grpModules as $key => $module ) {
2920  // Don't output state=loading for the startup module.
2921  if ( $key !== 'startup' ) {
2922  $links['states'][$key] = 'loading';
2923  }
2924  }
2925  }
2926 
2927  if ( $group == 'noscript' ) {
2928  $links['html'][] = Html::rawElement( 'noscript', [], $link );
2929  } else {
2930  $links['html'][] = $link;
2931  }
2932  }
2933  }
2934 
2935  return $links;
2936  }
2937 
2943  protected static function getHtmlFromLoaderLinks( array $links ) {
2944  $html = [];
2945  $states = [];
2946  foreach ( $links as $link ) {
2947  if ( !is_array( $link ) ) {
2948  $html[] = $link;
2949  } else {
2950  $html = array_merge( $html, $link['html'] );
2951  $states += $link['states'];
2952  }
2953  }
2954  // Filter out empty values
2955  $html = array_filter( $html, 'strlen' );
2956 
2957  if ( count( $states ) ) {
2958  array_unshift( $html, ResourceLoader::makeInlineScript(
2960  ) );
2961  }
2962 
2963  return WrappedString::join( "\n", $html );
2964  }
2965 
2972  function getHeadScripts() {
2973  return $this->getInlineHeadScripts() . $this->getExternalHeadScripts();
2974  }
2975 
2983  $links = [];
2984 
2985  // Startup - this provides the client with the module
2986  // manifest and loads jquery and mediawiki base modules
2987  $links[] = $this->makeResourceLoaderLink( 'startup', ResourceLoaderModule::TYPE_SCRIPTS );
2988 
2989  return self::getHtmlFromLoaderLinks( $links );
2990  }
2991 
2998  $links = [];
2999 
3000  // Client profile classes for <html>. Allows for easy hiding/showing of UI components.
3001  // Must be done synchronously on every page to avoid flashes of wrong content.
3002  // Note: This class distinguishes MediaWiki-supported JavaScript from the rest.
3003  // The "rest" includes browsers that support JavaScript but not supported by our runtime.
3004  // For the performance benefit of the majority, this is added unconditionally here and is
3005  // then fixed up by the startup module for unsupported browsers.
3006  $links[] = Html::inlineScript(
3007  'document.documentElement.className = document.documentElement.className'
3008  . '.replace( /(^|\s)client-nojs(\s|$)/, "$1client-js$2" );'
3009  );
3010 
3011  // Load config before anything else
3014  );
3015 
3016  // Load embeddable private modules before any loader links
3017  // This needs to be TYPE_COMBINED so these modules are properly wrapped
3018  // in mw.loader.implement() calls and deferred until mw.user is available
3019  $embedScripts = [ 'user.options' ];
3020  $links[] = $this->makeResourceLoaderLink(
3021  $embedScripts,
3023  );
3024  // Separate user.tokens as otherwise caching will be allowed (T84960)
3025  $links[] = $this->makeResourceLoaderLink(
3026  'user.tokens',
3028  );
3029 
3030  // Modules requests - let the client calculate dependencies and batch requests as it likes
3031  // Only load modules that have marked themselves for loading at the top
3032  $modules = $this->getModules( true, 'top' );
3033  if ( $modules ) {
3035  Xml::encodeJsCall( 'mw.loader.load', [ $modules ] )
3036  );
3037  }
3038 
3039  // "Scripts only" modules marked for top inclusion
3040  $links[] = $this->makeResourceLoaderLink(
3041  $this->getModuleScripts( true, 'top' ),
3043  );
3044 
3045  return self::getHtmlFromLoaderLinks( $links );
3046  }
3047 
3057  function getScriptsForBottomQueue( $unused = null ) {
3058  // Scripts "only" requests marked for bottom inclusion
3059  // If we're in the <head>, use load() calls rather than <script src="..."> tags
3060  $links = [];
3061 
3062  $links[] = $this->makeResourceLoaderLink( $this->getModuleScripts( true, 'bottom' ),
3064  );
3065 
3066  // Modules requests - let the client calculate dependencies and batch requests as it likes
3067  // Only load modules that have marked themselves for loading at the bottom
3068  $modules = $this->getModules( true, 'bottom' );
3069  if ( $modules ) {
3071  Xml::encodeJsCall( 'mw.loader.load', [ $modules ] )
3072  );
3073  }
3074 
3075  // Legacy Scripts
3076  $links[] = $this->mScripts;
3077 
3078  // Add user JS if enabled
3079  // This must use TYPE_COMBINED instead of only=scripts so that its request is handled by
3080  // mw.loader.implement() which ensures that execution is scheduled after the "site" module.
3081  if ( $this->getConfig()->get( 'AllowUserJs' )
3082  && $this->getTitle()
3083  && $this->getTitle()->isJsSubpage()
3084  && $this->userCanPreview()
3085  ) {
3086  // We're on a preview of a JS subpage. Exclude this page from the user module (T28283)
3087  // and include the draft contents as a raw script instead.
3089  [ 'excludepage' => $this->getTitle()->getPrefixedDBkey() ]
3090  );
3091  // Load the previewed JS
3093  Xml::encodeJsCall( 'mw.loader.using', [
3094  [ 'user', 'site' ],
3095  new XmlJsCode(
3096  'function () {'
3097  . Xml::encodeJsCall( '$.globalEval', [
3098  $this->getRequest()->getText( 'wpTextbox1' )
3099  ] )
3100  . '}'
3101  )
3102  ] )
3103  );
3104 
3105  // FIXME: If the user is previewing, say, ./vector.js, his ./common.js will be loaded
3106  // asynchronously and may arrive *after* the inline script here. So the previewed code
3107  // may execute before ./common.js runs. Normally, ./common.js runs before ./vector.js.
3108  // Similarly, when previewing ./common.js and the user module does arrive first,
3109  // it will arrive without common.js and the inline script runs after.
3110  // Thus running common after the excluded subpage.
3111  } else {
3112  // Include the user module normally, i.e., raw to avoid it being wrapped in a closure.
3113  $links[] = $this->makeResourceLoaderLink( 'user', ResourceLoaderModule::TYPE_COMBINED );
3114  }
3115 
3116  // Group JS is only enabled if site JS is enabled.
3117  $links[] = $this->makeResourceLoaderLink(
3118  'user.groups',
3120  );
3121 
3122  return self::getHtmlFromLoaderLinks( $links );
3123  }
3124 
3129  function getBottomScripts() {
3130  return $this->getScriptsForBottomQueue();
3131  }
3132 
3139  public function getJsConfigVars() {
3140  return $this->mJsConfigVars;
3141  }
3142 
3149  public function addJsConfigVars( $keys, $value = null ) {
3150  if ( is_array( $keys ) ) {
3151  foreach ( $keys as $key => $value ) {
3152  $this->mJsConfigVars[$key] = $value;
3153  }
3154  return;
3155  }
3156 
3157  $this->mJsConfigVars[$keys] = $value;
3158  }
3159 
3169  public function getJSVars() {
3171 
3172  $curRevisionId = 0;
3173  $articleId = 0;
3174  $canonicalSpecialPageName = false; # bug 21115
3175 
3176  $title = $this->getTitle();
3177  $ns = $title->getNamespace();
3178  $canonicalNamespace = MWNamespace::exists( $ns )
3180  : $title->getNsText();
3181 
3182  $sk = $this->getSkin();
3183  // Get the relevant title so that AJAX features can use the correct page name
3184  // when making API requests from certain special pages (bug 34972).
3185  $relevantTitle = $sk->getRelevantTitle();
3186  $relevantUser = $sk->getRelevantUser();
3187 
3188  if ( $ns == NS_SPECIAL ) {
3189  list( $canonicalSpecialPageName, /*...*/ ) =
3190  SpecialPageFactory::resolveAlias( $title->getDBkey() );
3191  } elseif ( $this->canUseWikiPage() ) {
3192  $wikiPage = $this->getWikiPage();
3193  $curRevisionId = $wikiPage->getLatest();
3194  $articleId = $wikiPage->getId();
3195  }
3196 
3197  $lang = $title->getPageViewLanguage();
3198 
3199  // Pre-process information
3200  $separatorTransTable = $lang->separatorTransformTable();
3201  $separatorTransTable = $separatorTransTable ? $separatorTransTable : [];
3202  $compactSeparatorTransTable = [
3203  implode( "\t", array_keys( $separatorTransTable ) ),
3204  implode( "\t", $separatorTransTable ),
3205  ];
3206  $digitTransTable = $lang->digitTransformTable();
3207  $digitTransTable = $digitTransTable ? $digitTransTable : [];
3208  $compactDigitTransTable = [
3209  implode( "\t", array_keys( $digitTransTable ) ),
3210  implode( "\t", $digitTransTable ),
3211  ];
3212 
3213  $user = $this->getUser();
3214 
3215  $vars = [
3216  'wgCanonicalNamespace' => $canonicalNamespace,
3217  'wgCanonicalSpecialPageName' => $canonicalSpecialPageName,
3218  'wgNamespaceNumber' => $title->getNamespace(),
3219  'wgPageName' => $title->getPrefixedDBkey(),
3220  'wgTitle' => $title->getText(),
3221  'wgCurRevisionId' => $curRevisionId,
3222  'wgRevisionId' => (int)$this->getRevisionId(),
3223  'wgArticleId' => $articleId,
3224  'wgIsArticle' => $this->isArticle(),
3225  'wgIsRedirect' => $title->isRedirect(),
3226  'wgAction' => Action::getActionName( $this->getContext() ),
3227  'wgUserName' => $user->isAnon() ? null : $user->getName(),
3228  'wgUserGroups' => $user->getEffectiveGroups(),
3229  'wgCategories' => $this->getCategories(),
3230  'wgBreakFrames' => $this->getFrameOptions() == 'DENY',
3231  'wgPageContentLanguage' => $lang->getCode(),
3232  'wgPageContentModel' => $title->getContentModel(),
3233  'wgSeparatorTransformTable' => $compactSeparatorTransTable,
3234  'wgDigitTransformTable' => $compactDigitTransTable,
3235  'wgDefaultDateFormat' => $lang->getDefaultDateFormat(),
3236  'wgMonthNames' => $lang->getMonthNamesArray(),
3237  'wgMonthNamesShort' => $lang->getMonthAbbreviationsArray(),
3238  'wgRelevantPageName' => $relevantTitle->getPrefixedDBkey(),
3239  'wgRelevantArticleId' => $relevantTitle->getArticleID(),
3240  'wgRequestId' => WebRequest::getRequestId(),
3241  ];
3242 
3243  if ( $user->isLoggedIn() ) {
3244  $vars['wgUserId'] = $user->getId();
3245  $vars['wgUserEditCount'] = $user->getEditCount();
3246  $userReg = wfTimestampOrNull( TS_UNIX, $user->getRegistration() );
3247  $vars['wgUserRegistration'] = $userReg !== null ? ( $userReg * 1000 ) : null;
3248  // Get the revision ID of the oldest new message on the user's talk
3249  // page. This can be used for constructing new message alerts on
3250  // the client side.
3251  $vars['wgUserNewMsgRevisionId'] = $user->getNewMessageRevisionId();
3252  }
3253 
3254  if ( $wgContLang->hasVariants() ) {
3255  $vars['wgUserVariant'] = $wgContLang->getPreferredVariant();
3256  }
3257  // Same test as SkinTemplate
3258  $vars['wgIsProbablyEditable'] = $title->quickUserCan( 'edit', $user )
3259  && ( $title->exists() || $title->quickUserCan( 'create', $user ) );
3260 
3261  foreach ( $title->getRestrictionTypes() as $type ) {
3262  $vars['wgRestriction' . ucfirst( $type )] = $title->getRestrictions( $type );
3263  }
3264 
3265  if ( $title->isMainPage() ) {
3266  $vars['wgIsMainPage'] = true;
3267  }
3268 
3269  if ( $this->mRedirectedFrom ) {
3270  $vars['wgRedirectedFrom'] = $this->mRedirectedFrom->getPrefixedDBkey();
3271  }
3272 
3273  if ( $relevantUser ) {
3274  $vars['wgRelevantUserName'] = $relevantUser->getName();
3275  }
3276 
3277  // Allow extensions to add their custom variables to the mw.config map.
3278  // Use the 'ResourceLoaderGetConfigVars' hook if the variable is not
3279  // page-dependant but site-wide (without state).
3280  // Alternatively, you may want to use OutputPage->addJsConfigVars() instead.
3281  Hooks::run( 'MakeGlobalVariablesScript', [ &$vars, $this ] );
3282 
3283  // Merge in variables from addJsConfigVars last
3284  return array_merge( $vars, $this->getJsConfigVars() );
3285  }
3286 
3296  public function userCanPreview() {
3297  $request = $this->getRequest();
3298  if (
3299  $request->getVal( 'action' ) !== 'submit' ||
3300  !$request->getCheck( 'wpPreview' ) ||
3301  !$request->wasPosted()
3302  ) {
3303  return false;
3304  }
3305 
3306  $user = $this->getUser();
3307 
3308  if ( !$this->getUser()->isLoggedIn() ) {
3309  // Anons have predictable edit tokens
3310  return false;
3311  }
3312  if ( !$user->matchEditToken( $request->getVal( 'wpEditToken' ) ) ) {
3313  return false;
3314  }
3315 
3316  $title = $this->getTitle();
3317  if ( !$title->isJsSubpage() && !$title->isCssSubpage() ) {
3318  return false;
3319  }
3320  if ( !$title->isSubpageOf( $user->getUserPage() ) ) {
3321  // Don't execute another user's CSS or JS on preview (T85855)
3322  return false;
3323  }
3324 
3325  $errors = $title->getUserPermissionsErrors( 'edit', $user );
3326  if ( count( $errors ) !== 0 ) {
3327  return false;
3328  }
3329 
3330  return true;
3331  }
3332 
3336  public function getHeadLinksArray() {
3338 
3339  $tags = [];
3340  $config = $this->getConfig();
3341 
3342  $canonicalUrl = $this->mCanonicalUrl;
3343 
3344  $tags['meta-generator'] = Html::element( 'meta', [
3345  'name' => 'generator',
3346  'content' => "MediaWiki $wgVersion",
3347  ] );
3348 
3349  if ( $config->get( 'ReferrerPolicy' ) !== false ) {
3350  $tags['meta-referrer'] = Html::element( 'meta', [
3351  'name' => 'referrer',
3352  'content' => $config->get( 'ReferrerPolicy' )
3353  ] );
3354  }
3355 
3356  $p = "{$this->mIndexPolicy},{$this->mFollowPolicy}";
3357  if ( $p !== 'index,follow' ) {
3358  // http://www.robotstxt.org/wc/meta-user.html
3359  // Only show if it's different from the default robots policy
3360  $tags['meta-robots'] = Html::element( 'meta', [
3361  'name' => 'robots',
3362  'content' => $p,
3363  ] );
3364  }
3365 
3366  foreach ( $this->mMetatags as $tag ) {
3367  if ( 0 == strcasecmp( 'http:', substr( $tag[0], 0, 5 ) ) ) {
3368  $a = 'http-equiv';
3369  $tag[0] = substr( $tag[0], 5 );
3370  } else {
3371  $a = 'name';
3372  }
3373  $tagName = "meta-{$tag[0]}";
3374  if ( isset( $tags[$tagName] ) ) {
3375  $tagName .= $tag[1];
3376  }
3377  $tags[$tagName] = Html::element( 'meta',
3378  [
3379  $a => $tag[0],
3380  'content' => $tag[1]
3381  ]
3382  );
3383  }
3384 
3385  foreach ( $this->mLinktags as $tag ) {
3386  $tags[] = Html::element( 'link', $tag );
3387  }
3388 
3389  # Universal edit button
3390  if ( $config->get( 'UniversalEditButton' ) && $this->isArticleRelated() ) {
3391  $user = $this->getUser();
3392  if ( $this->getTitle()->quickUserCan( 'edit', $user )
3393  && ( $this->getTitle()->exists() ||
3394  $this->getTitle()->quickUserCan( 'create', $user ) )
3395  ) {
3396  // Original UniversalEditButton
3397  $msg = $this->msg( 'edit' )->text();
3398  $tags['universal-edit-button'] = Html::element( 'link', [
3399  'rel' => 'alternate',
3400  'type' => 'application/x-wiki',
3401  'title' => $msg,
3402  'href' => $this->getTitle()->getEditURL(),
3403  ] );
3404  // Alternate edit link
3405  $tags['alternative-edit'] = Html::element( 'link', [
3406  'rel' => 'edit',
3407  'title' => $msg,
3408  'href' => $this->getTitle()->getEditURL(),
3409  ] );
3410  }
3411  }
3412 
3413  # Generally the order of the favicon and apple-touch-icon links
3414  # should not matter, but Konqueror (3.5.9 at least) incorrectly
3415  # uses whichever one appears later in the HTML source. Make sure
3416  # apple-touch-icon is specified first to avoid this.
3417  if ( $config->get( 'AppleTouchIcon' ) !== false ) {
3418  $tags['apple-touch-icon'] = Html::element( 'link', [
3419  'rel' => 'apple-touch-icon',
3420  'href' => $config->get( 'AppleTouchIcon' )
3421  ] );
3422  }
3423 
3424  if ( $config->get( 'Favicon' ) !== false ) {
3425  $tags['favicon'] = Html::element( 'link', [
3426  'rel' => 'shortcut icon',
3427  'href' => $config->get( 'Favicon' )
3428  ] );
3429  }
3430 
3431  # OpenSearch description link
3432  $tags['opensearch'] = Html::element( 'link', [
3433  'rel' => 'search',
3434  'type' => 'application/opensearchdescription+xml',
3435  'href' => wfScript( 'opensearch_desc' ),
3436  'title' => $this->msg( 'opensearch-desc' )->inContentLanguage()->text(),
3437  ] );
3438 
3439  if ( $config->get( 'EnableAPI' ) ) {
3440  # Real Simple Discovery link, provides auto-discovery information
3441  # for the MediaWiki API (and potentially additional custom API
3442  # support such as WordPress or Twitter-compatible APIs for a
3443  # blogging extension, etc)
3444  $tags['rsd'] = Html::element( 'link', [
3445  'rel' => 'EditURI',
3446  'type' => 'application/rsd+xml',
3447  // Output a protocol-relative URL here if $wgServer is protocol-relative.
3448  // Whether RSD accepts relative or protocol-relative URLs is completely
3449  // undocumented, though.
3450  'href' => wfExpandUrl( wfAppendQuery(
3451  wfScript( 'api' ),
3452  [ 'action' => 'rsd' ] ),
3454  ),
3455  ] );
3456  }
3457 
3458  # Language variants
3459  if ( !$config->get( 'DisableLangConversion' ) ) {
3460  $lang = $this->getTitle()->getPageLanguage();
3461  if ( $lang->hasVariants() ) {
3462  $variants = $lang->getVariants();
3463  foreach ( $variants as $variant ) {
3464  $tags["variant-$variant"] = Html::element( 'link', [
3465  'rel' => 'alternate',
3466  'hreflang' => wfBCP47( $variant ),
3467  'href' => $this->getTitle()->getLocalURL(
3468  [ 'variant' => $variant ] )
3469  ]
3470  );
3471  }
3472  # x-default link per https://support.google.com/webmasters/answer/189077?hl=en
3473  $tags["variant-x-default"] = Html::element( 'link', [
3474  'rel' => 'alternate',
3475  'hreflang' => 'x-default',
3476  'href' => $this->getTitle()->getLocalURL() ] );
3477  }
3478  }
3479 
3480  # Copyright
3481  if ( $this->copyrightUrl !== null ) {
3482  $copyright = $this->copyrightUrl;
3483  } else {
3484  $copyright = '';
3485  if ( $config->get( 'RightsPage' ) ) {
3486  $copy = Title::newFromText( $config->get( 'RightsPage' ) );
3487 
3488  if ( $copy ) {
3489  $copyright = $copy->getLocalURL();
3490  }
3491  }
3492 
3493  if ( !$copyright && $config->get( 'RightsUrl' ) ) {
3494  $copyright = $config->get( 'RightsUrl' );
3495  }
3496  }
3497 
3498  if ( $copyright ) {
3499  $tags['copyright'] = Html::element( 'link', [
3500  'rel' => 'copyright',
3501  'href' => $copyright ]
3502  );
3503  }
3504 
3505  # Feeds
3506  if ( $config->get( 'Feed' ) ) {
3507  $feedLinks = [];
3508 
3509  foreach ( $this->getSyndicationLinks() as $format => $link ) {
3510  # Use the page name for the title. In principle, this could
3511  # lead to issues with having the same name for different feeds
3512  # corresponding to the same page, but we can't avoid that at
3513  # this low a level.
3514 
3515  $feedLinks[] = $this->feedLink(
3516  $format,
3517  $link,
3518  # Used messages: 'page-rss-feed' and 'page-atom-feed' (for an easier grep)
3519  $this->msg(
3520  "page-{$format}-feed", $this->getTitle()->getPrefixedText()
3521  )->text()
3522  );
3523  }
3524 
3525  # Recent changes feed should appear on every page (except recentchanges,
3526  # that would be redundant). Put it after the per-page feed to avoid
3527  # changing existing behavior. It's still available, probably via a
3528  # menu in your browser. Some sites might have a different feed they'd
3529  # like to promote instead of the RC feed (maybe like a "Recent New Articles"
3530  # or "Breaking news" one). For this, we see if $wgOverrideSiteFeed is defined.
3531  # If so, use it instead.
3532  $sitename = $config->get( 'Sitename' );
3533  if ( $config->get( 'OverrideSiteFeed' ) ) {
3534  foreach ( $config->get( 'OverrideSiteFeed' ) as $type => $feedUrl ) {
3535  // Note, this->feedLink escapes the url.
3536  $feedLinks[] = $this->feedLink(
3537  $type,
3538  $feedUrl,
3539  $this->msg( "site-{$type}-feed", $sitename )->text()
3540  );
3541  }
3542  } elseif ( !$this->getTitle()->isSpecial( 'Recentchanges' ) ) {
3543  $rctitle = SpecialPage::getTitleFor( 'Recentchanges' );
3544  foreach ( $config->get( 'AdvertisedFeedTypes' ) as $format ) {
3545  $feedLinks[] = $this->feedLink(
3546  $format,
3547  $rctitle->getLocalURL( [ 'feed' => $format ] ),
3548  # For grep: 'site-rss-feed', 'site-atom-feed'
3549  $this->msg( "site-{$format}-feed", $sitename )->text()
3550  );
3551  }
3552  }
3553 
3554  # Allow extensions to change the list pf feeds. This hook is primarily for changing,
3555  # manipulating or removing existing feed tags. If you want to add new feeds, you should
3556  # use OutputPage::addFeedLink() instead.
3557  Hooks::run( 'AfterBuildFeedLinks', [ &$feedLinks ] );
3558 
3559  $tags += $feedLinks;
3560  }
3561 
3562  # Canonical URL
3563  if ( $config->get( 'EnableCanonicalServerLink' ) ) {
3564  if ( $canonicalUrl !== false ) {
3565  $canonicalUrl = wfExpandUrl( $canonicalUrl, PROTO_CANONICAL );
3566  } else {
3567  if ( $this->isArticleRelated() ) {
3568  // This affects all requests where "setArticleRelated" is true. This is
3569  // typically all requests that show content (query title, curid, oldid, diff),
3570  // and all wikipage actions (edit, delete, purge, info, history etc.).
3571  // It does not apply to File pages and Special pages.
3572  // 'history' and 'info' actions address page metadata rather than the page
3573  // content itself, so they may not be canonicalized to the view page url.
3574  // TODO: this ought to be better encapsulated in the Action class.
3575  $action = Action::getActionName( $this->getContext() );
3576  if ( in_array( $action, [ 'history', 'info' ] ) ) {
3577  $query = "action={$action}";
3578  } else {
3579  $query = '';
3580  }
3581  $canonicalUrl = $this->getTitle()->getCanonicalURL( $query );
3582  } else {
3583  $reqUrl = $this->getRequest()->getRequestURL();
3584  $canonicalUrl = wfExpandUrl( $reqUrl, PROTO_CANONICAL );
3585  }
3586  }
3587  }
3588  if ( $canonicalUrl !== false ) {
3589  $tags[] = Html::element( 'link', [
3590  'rel' => 'canonical',
3591  'href' => $canonicalUrl
3592  ] );
3593  }
3594 
3595  return $tags;
3596  }
3597 
3603  public function getHeadLinks() {
3604  wfDeprecated( __METHOD__, '1.24' );
3605  return implode( "\n", $this->getHeadLinksArray() );
3606  }
3607 
3616  private function feedLink( $type, $url, $text ) {
3617  return Html::element( 'link', [
3618  'rel' => 'alternate',
3619  'type' => "application/$type+xml",
3620  'title' => $text,
3621  'href' => $url ]
3622  );
3623  }
3624 
3634  public function addStyle( $style, $media = '', $condition = '', $dir = '' ) {
3635  $options = [];
3636  if ( $media ) {
3637  $options['media'] = $media;
3638  }
3639  if ( $condition ) {
3640  $options['condition'] = $condition;
3641  }
3642  if ( $dir ) {
3643  $options['dir'] = $dir;
3644  }
3645  $this->styles[$style] = $options;
3646  }
3647 
3655  public function addInlineStyle( $style_css, $flip = 'noflip' ) {
3656  if ( $flip === 'flip' && $this->getLanguage()->isRTL() ) {
3657  # If wanted, and the interface is right-to-left, flip the CSS
3658  $style_css = CSSJanus::transform( $style_css, true, false );
3659  }
3660  $this->mInlineStyles .= Html::inlineStyle( $style_css );
3661  }
3662 
3669  public function buildCssLinks() {
3671 
3672  $this->getSkin()->setupSkinUserCss( $this );
3673 
3674  // Add ResourceLoader styles
3675  // Split the styles into these groups
3676  $styles = [
3677  'other' => [],
3678  'user' => [],
3679  'site' => [],
3680  'private' => [],
3681  'noscript' => []
3682  ];
3683  $links = [];
3684  $otherTags = []; // Tags to append after the normal <link> tags
3686 
3687  $moduleStyles = $this->getModuleStyles();
3688 
3689  // Per-site custom styles
3690  $moduleStyles[] = 'site';
3691  $moduleStyles[] = 'noscript';
3692  $moduleStyles[] = 'user.groups';
3693 
3694  // Per-user custom styles
3695  if ( $this->getConfig()->get( 'AllowUserCss' ) && $this->getTitle()->isCssSubpage()
3696  && $this->userCanPreview()
3697  ) {
3698  // We're on a preview of a CSS subpage
3699  // Exclude this page from the user module in case it's in there (bug 26283)
3701  [ 'excludepage' => $this->getTitle()->getPrefixedDBkey() ]
3702  );
3703  $otherTags = array_merge( $otherTags, $link['html'] );
3704 
3705  // Load the previewed CSS
3706  // If needed, Janus it first. This is user-supplied CSS, so it's
3707  // assumed to be right for the content language directionality.
3708  $previewedCSS = $this->getRequest()->getText( 'wpTextbox1' );
3709  if ( $this->getLanguage()->getDir() !== $wgContLang->getDir() ) {
3710  $previewedCSS = CSSJanus::transform( $previewedCSS, true, false );
3711  }
3712  $otherTags[] = Html::inlineStyle( $previewedCSS );
3713  } else {
3714  // Load the user styles normally
3715  $moduleStyles[] = 'user';
3716  }
3717 
3718  // Per-user preference styles
3719  $moduleStyles[] = 'user.cssprefs';
3720 
3721  foreach ( $moduleStyles as $name ) {
3722  $module = $resourceLoader->getModule( $name );
3723  if ( !$module ) {
3724  continue;
3725  }
3726  if ( $name === 'site' ) {
3727  // HACK: The site module shouldn't be fragmented with a cache group and
3728  // http request. But in order to ensure its styles are separated and after the
3729  // ResourceLoaderDynamicStyles marker, pretend it is in a group called 'site'.
3730  // The scripts remain ungrouped and rides the bottom queue.
3731  $styles['site'][] = $name;
3732  continue;
3733  }
3734  $group = $module->getGroup();
3735  // Modules in groups other than the ones needing special treatment
3736  // (see $styles assignment)
3737  // will be placed in the "other" style category.
3738  $styles[isset( $styles[$group] ) ? $group : 'other'][] = $name;
3739  }
3740 
3741  // We want site, private and user styles to override dynamically added
3742  // styles from modules, but we want dynamically added styles to override
3743  // statically added styles from other modules. So the order has to be
3744  // other, dynamic, site, private, user. Add statically added styles for
3745  // other modules
3746  $links[] = $this->makeResourceLoaderLink(
3747  $styles['other'],
3749  );
3750  // Add normal styles added through addStyle()/addInlineStyle() here
3751  $links[] = implode( '', $this->buildCssLinksArray() ) . $this->mInlineStyles;
3752  // Add marker tag to mark the place where the client-side
3753  // loader should inject dynamic styles
3754  // We use a <meta> tag with a made-up name for this because that's valid HTML
3755  $links[] = Html::element(
3756  'meta',
3757  [ 'name' => 'ResourceLoaderDynamicStyles', 'content' => '' ]
3758  );
3759 
3760  // Add site-specific and user-specific styles
3761  // 'private' at present only contains user.options, so put that before 'user'
3762  // Any future private modules will likely have a similar user-specific character
3763  foreach ( [ 'site', 'noscript', 'private', 'user' ] as $group ) {
3764  $links[] = $this->makeResourceLoaderLink( $styles[$group],
3766  );
3767  }
3768 
3769  // Add stuff in $otherTags (previewed user CSS if applicable)
3770  return self::getHtmlFromLoaderLinks( $links ) . implode( '', $otherTags );
3771  }
3772 
3776  public function buildCssLinksArray() {
3777  $links = [];
3778 
3779  // Add any extension CSS
3780  foreach ( $this->mExtStyles as $url ) {
3781  $this->addStyle( $url );
3782  }
3783  $this->mExtStyles = [];
3784 
3785  foreach ( $this->styles as $file => $options ) {
3786  $link = $this->styleLink( $file, $options );
3787  if ( $link ) {
3788  $links[$file] = $link;
3789  }
3790  }
3791  return $links;
3792  }
3793 
3801  protected function styleLink( $style, array $options ) {
3802  if ( isset( $options['dir'] ) ) {
3803  if ( $this->getLanguage()->getDir() != $options['dir'] ) {
3804  return '';
3805  }
3806  }
3807 
3808  if ( isset( $options['media'] ) ) {
3809  $media = self::transformCssMedia( $options['media'] );
3810  if ( is_null( $media ) ) {
3811  return '';
3812  }
3813  } else {
3814  $media = 'all';
3815  }
3816 
3817  if ( substr( $style, 0, 1 ) == '/' ||
3818  substr( $style, 0, 5 ) == 'http:' ||
3819  substr( $style, 0, 6 ) == 'https:' ) {
3820  $url = $style;
3821  } else {
3822  $config = $this->getConfig();
3823  $url = $config->get( 'StylePath' ) . '/' . $style . '?' .
3824  $config->get( 'StyleVersion' );
3825  }
3826 
3827  $link = Html::linkedStyle( $url, $media );
3828 
3829  if ( isset( $options['condition'] ) ) {
3830  $condition = htmlspecialchars( $options['condition'] );
3831  $link = "<!--[if $condition]>$link<![endif]-->";
3832  }
3833  return $link;
3834  }
3835 
3857  public static function transformResourcePath( Config $config, $path ) {
3858  global $IP;
3859  $remotePathPrefix = $config->get( 'ResourceBasePath' );
3860  if ( $remotePathPrefix === '' ) {
3861  // The configured base path is required to be empty string for
3862  // wikis in the domain root
3863  $remotePath = '/';
3864  } else {
3865  $remotePath = $remotePathPrefix;
3866  }
3867  if ( strpos( $path, $remotePath ) !== 0 ) {
3868  // Path is outside wgResourceBasePath, ignore.
3869  return $path;
3870  }
3871  $path = RelPath\getRelativePath( $path, $remotePath );
3872  return self::transformFilePath( $remotePathPrefix, $IP, $path );
3873  }
3874 
3886  public static function transformFilePath( $remotePathPrefix, $localPath, $file ) {
3887  $hash = md5_file( "$localPath/$file" );
3888  if ( $hash === false ) {
3889  wfLogWarning( __METHOD__ . ": Failed to hash $localPath/$file" );
3890  $hash = '';
3891  }
3892  return "$remotePathPrefix/$file?" . substr( $hash, 0, 5 );
3893  }
3894 
3902  public static function transformCssMedia( $media ) {
3904 
3905  // http://www.w3.org/TR/css3-mediaqueries/#syntax
3906  $screenMediaQueryRegex = '/^(?:only\s+)?screen\b/i';
3907 
3908  // Switch in on-screen display for media testing
3909  $switches = [
3910  'printable' => 'print',
3911  'handheld' => 'handheld',
3912  ];
3913  foreach ( $switches as $switch => $targetMedia ) {
3914  if ( $wgRequest->getBool( $switch ) ) {
3915  if ( $media == $targetMedia ) {
3916  $media = '';
3917  } elseif ( preg_match( $screenMediaQueryRegex, $media ) === 1 ) {
3918  /* This regex will not attempt to understand a comma-separated media_query_list
3919  *
3920  * Example supported values for $media:
3921  * 'screen', 'only screen', 'screen and (min-width: 982px)' ),
3922  * Example NOT supported value for $media:
3923  * '3d-glasses, screen, print and resolution > 90dpi'
3924  *
3925  * If it's a print request, we never want any kind of screen stylesheets
3926  * If it's a handheld request (currently the only other choice with a switch),
3927  * we don't want simple 'screen' but we might want screen queries that
3928  * have a max-width or something, so we'll pass all others on and let the
3929  * client do the query.
3930  */
3931  if ( $targetMedia == 'print' || $media == 'screen' ) {
3932  return null;
3933  }
3934  }
3935  }
3936  }
3937 
3938  return $media;
3939  }
3940 
3947  public function addWikiMsg( /*...*/ ) {
3948  $args = func_get_args();
3949  $name = array_shift( $args );
3950  $this->addWikiMsgArray( $name, $args );
3951  }
3952 
3961  public function addWikiMsgArray( $name, $args ) {
3962  $this->addHTML( $this->msg( $name, $args )->parseAsBlock() );
3963  }
3964 
3990  public function wrapWikiMsg( $wrap /*, ...*/ ) {
3991  $msgSpecs = func_get_args();
3992  array_shift( $msgSpecs );
3993  $msgSpecs = array_values( $msgSpecs );
3994  $s = $wrap;
3995  foreach ( $msgSpecs as $n => $spec ) {
3996  if ( is_array( $spec ) ) {
3997  $args = $spec;
3998  $name = array_shift( $args );
3999  if ( isset( $args['options'] ) ) {
4000  unset( $args['options'] );
4001  wfDeprecated(
4002  'Adding "options" to ' . __METHOD__ . ' is no longer supported',
4003  '1.20'
4004  );
4005  }
4006  } else {
4007  $args = [];
4008  $name = $spec;
4009  }
4010  $s = str_replace( '$' . ( $n + 1 ), $this->msg( $name, $args )->plain(), $s );
4011  }
4012  $this->addWikiText( $s );
4013  }
4014 
4020  public function enableTOC( $flag = true ) {
4021  $this->mEnableTOC = $flag;
4022  }
4023 
4028  public function isTOCEnabled() {
4029  return $this->mEnableTOC;
4030  }
4031 
4037  public function enableSectionEditLinks( $flag = true ) {
4038  $this->mEnableSectionEditLinks = $flag;
4039  }
4040 
4045  public function sectionEditLinksEnabled() {
4047  }
4048 
4056  public static function setupOOUI( $skinName = '', $dir = 'ltr' ) {
4057  $themes = ExtensionRegistry::getInstance()->getAttribute( 'SkinOOUIThemes' );
4058  // Make keys (skin names) lowercase for case-insensitive matching.
4059  $themes = array_change_key_case( $themes, CASE_LOWER );
4060  $theme = isset( $themes[$skinName] ) ? $themes[$skinName] : 'MediaWiki';
4061  // For example, 'OOUI\MediaWikiTheme'.
4062  $themeClass = "OOUI\\{$theme}Theme";
4063  OOUI\Theme::setSingleton( new $themeClass() );
4064  OOUI\Element::setDefaultDir( $dir );
4065  }
4066 
4073  public function enableOOUI() {
4074  self::setupOOUI(
4075  strtolower( $this->getSkin()->getSkinName() ),
4076  $this->getLanguage()->getDir()
4077  );
4078  $this->addModuleStyles( [
4079  'oojs-ui-core.styles',
4080  'oojs-ui.styles.icons',
4081  'oojs-ui.styles.indicators',
4082  'oojs-ui.styles.textures',
4083  'mediawiki.widgets.styles',
4084  ] );
4085  // Used by 'skipFunction' of the four 'oojs-ui.styles.*' modules. Please don't treat this as a
4086  // public API or you'll be severely disappointed when T87871 is fixed and it disappears.
4087  $this->addMeta( 'X-OOUI-PHP', '1' );
4088  }
4089 }
getPreventClickjacking()
Get the prevent-clickjacking flag.
setContext(IContextSource $context)
Set the IContextSource object.
addInlineStyle($style_css, $flip= 'noflip')
Adds inline CSS styles Internal use only.
const TS_RFC2822
RFC 2822 format, for E-mail and HTTP headers.
prependHTML($text)
Prepend $text to the body HTML.
isDisabled()
Return whether the output will be completely disabled.
static closeElement($element)
Returns "".
Definition: Html.php:306
showFileRenameError($old, $new)
static newFromContext(IContextSource $context)
Get a ParserOptions object from a IContextSource object.
ResourceLoader $mResourceLoader
Definition: OutputPage.php:165
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 & $html
Definition: hooks.txt:1802
array $mTemplateIds
Definition: OutputPage.php:171
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
Interface for objects which can provide a MediaWiki context on request.
wfGetDB($db, $groups=[], $wiki=false)
Get a Database object.
getPageTitleActionText()
Get the value of the "action text".
Definition: OutputPage.php:915
getMetadataAttribute()
Get the value of the "rel" attribute for metadata links.
Definition: OutputPage.php:444
getHeadItemsArray()
Get an array of head items.
Definition: OutputPage.php:666
static inlineScript($contents)
Output a "".
Definition: Html.php:614
string null $mTarget
ResourceLoader target for load.php links.
Definition: OutputPage.php:291
getArticleBodyOnly()
Return whether the output will contain only the body of the article.
Definition: OutputPage.php:721
static makeConfigSetScript(array $configuration)
Returns JS code which will set the MediaWiki configuration array to the given value.
static escapeClass($class)
Given a value, escape it so that it can be used as a CSS class and return it.
Definition: Sanitizer.php:1209
addHelpLink($to, $overrideBaseUrl=false)
Adds help link with an icon via page indicators.
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:530
string $mPageLinkTitle
Used by skin template.
Definition: OutputPage.php:150
addParserOutputContent($parserOutput)
Add the HTML and enhancements for it (like ResourceLoader modules) associated with a ParserOutput obj...
userCanPreview()
To make it harder for someone to slip a user a fake user-JavaScript or user-CSS preview, a random token is associated with the login session.
addParserOutputText($parserOutput)
Add the HTML associated with a ParserOutput object, without any metadata.
setPrintable()
Set the page as printable, i.e.
string null $copyrightUrl
The URL to send in a element with rel=copyright.
Definition: OutputPage.php:306
disable()
Disable output completely, i.e.
static exists($index)
Returns whether the specified namespace exists.
wfUrlencode($s)
We want some things to be included as literal characters in our title URLs for prettiness, which urlencode encodes by default.
setStatusCode($statusCode)
Set the HTTP status code to send with the output.
Definition: OutputPage.php:361
static newFromText($text, $defaultNamespace=NS_MAIN)
Create a new Title from text, such as what one would find in a link.
Definition: Title.php:277
this hook is for auditing only $response
Definition: hooks.txt:766
Represents a title within MediaWiki.
Definition: Title.php:34
addExtensionStyle($url)
Register and add a stylesheet from an extension directory.
Definition: OutputPage.php:475
static stripAllTags($text)
Take a fragment of (potentially invalid) HTML and return a version with any tags removed, encoded as plain text.
Definition: Sanitizer.php:1785
when a variable name is used in a it is silently declared as a new local masking the global
Definition: design.txt:93
wfExpandUrl($url, $defaultProto=PROTO_CURRENT)
Expand a potentially local URL to a fully-qualified URL.
formatPermissionsErrorMessage(array $errors, $action=null)
Format a list of error messages.
string $mRevisionTimestamp
Definition: OutputPage.php:249
array $mLanguageLinks
Array of Interwiki Prefixed (non DB key) Titles (e.g.
Definition: OutputPage.php:133
IContextSource $context
getFileSearchOptions()
Get the files used on this page.
setCategoryLinks(array $categories)
Reset the category links (but not the category list) and add $categories.
isSyndicated()
Should we output feed links for this page?
array $styles
An array of stylesheet filenames (relative from skins path), with options for CSS media...
Definition: OutputPage.php:262
isPrintable()
Return whether the page is "printable".
getTitle()
Get the Title object.
prepareErrorPage($pageTitle, $htmlTitle=false)
Prepare this object to display an error page; disable caching and indexing, clear the current text an...
$mProperties
Additional key => value data.
Definition: OutputPage.php:286
get($name)
Get a configuration variable such as "Sitename" or "UploadMaintenance.".
getAllowedModules($type)
Show what level of JavaScript / CSS untrustworthiness is allowed on this page.
addElement($element, array $attribs=[], $contents= '')
Shortcut for adding an Html::element via addHTML.
array bool $mDoNothing
Whether output is disabled.
Definition: OutputPage.php:191
addModules($modules)
Add one or more modules recognized by ResourceLoader.
Definition: OutputPage.php:570
wfDebug($text, $dest= 'all', array $context=[])
Sends a line to the debug log if enabled or, optionally, to a comment in output.
reduceAllowedModules($type, $level)
Limit the highest level of CSS/JS untrustworthiness allowed.
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:906
bool $mPreventClickjacking
Controls if anti-clickjacking / frame-breaking headers will be sent.
Definition: OutputPage.php:243
addMetadataLink(array $linkarr)
Add a new \ with "rel" attribute set to "meta".
Definition: OutputPage.php:414
if($line===false) $args
Definition: cdb.php:64
the value to return A Title object or null for latest to be modified or replaced by the hook handler or if authentication is not possible after cache objects are set for highlighting & $link
Definition: hooks.txt:2585
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:766
preventClickjacking($enable=true)
Set a flag which will cause an X-Frame-Options header appropriate for edit pages to be sent...
enableClientCache($state)
Use enableClientCache(false) to force it to send nocache headers.
getCategories()
Get the list of category names this page belongs to.
array $mJsConfigVars
Definition: OutputPage.php:168
getJsConfigVars()
Get the javascript config vars to include on this page.
enableOOUI()
Add ResourceLoader module styles for OOUI and set up the PHP implementation of it for use with MediaW...
addParserOutput($parserOutput)
Add everything from a ParserOutput object.
bool $mPrintable
We have to set isPrintable().
Definition: OutputPage.php:92
static makeLoaderStateScript($name, $state=null)
Returns a JS call to mw.loader.state, which sets the state of a module or modules to a given value...
clearSubtitle()
Clear the subtitles.
Class representing a list of titles The execute() method checks them all for existence and adds them ...
Definition: LinkBatch.php:31
wfTimestamp($outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
getRequest()
Get the WebRequest object.
addWikiTextWithTitle($text, &$title, $linestart=true)
Add wikitext with a custom Title object.
getHeadScripts()
JS stuff to put in the "".
bool $mIsArticleRelated
Stores "article flag" toggle.
Definition: OutputPage.php:86
canUseWikiPage()
Check whether a WikiPage object can be get with getWikiPage().
getExternalHeadScripts()
tags to put in "".
addTemplate(&$template)
Add the output of a QuickTemplate to the output buffer.
clearHTML()
Clear the body HTML.
getFrameOptions()
Get the X-Frame-Options header value (without the name part), or false if there isn't one...
A wrapper class which causes Xml::encodeJsVar() and Xml::encodeJsCall() to interpret a given string a...
Definition: Xml.php:884
setCdnMaxage($maxage)
Set the value of the "s-maxage" part of the "Cache-control" HTTP header.
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 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 unsetoffset-wrap String Wrap the message in html(usually something like"&lt
enableSectionEditLinks($flag=true)
Enables/disables section edit links, doesn't override NOEDITSECTION
getIndicators()
Get the indicators associated with this page.
getContext()
Get the base IContextSource object.
addWikiMsg()
Add a wikitext-formatted message to the output.
static makePackedModulesString($modules)
Convert an array of module names to a packed query string.
$params
showNewSectionLink()
Show an "add new section" link?
const NS_CATEGORY
Definition: Defines.php:84
Title $mRedirectedFrom
If the current page was reached through a redirect, $mRedirectedFrom contains the Title of the redire...
Definition: OutputPage.php:281
and(b) You must cause any modified files to carry prominent notices stating that You changed the files
wfDeprecated($function, $version=false, $component=false, $callerOffset=2)
Throws a warning that $function is deprecated.
string $mHTMLtitle
Stores contents of "" tag. </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l00077">OutputPage.php:77</a></div></div> <div class="ttc" id="classOutputPage_html_a3feffe321006a7b9c5eab9ac2c023bb5"><div class="ttname"><a href="classOutputPage.html#a3feffe321006a7b9c5eab9ac2c023bb5">OutputPage\$mHideNewSectionLink</a></div><div class="ttdeci">bool $mHideNewSectionLink</div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l00221">OutputPage.php:221</a></div></div> <div class="ttc" id="classOutputPage_html_a905182025f38e9304a183457c997e764"><div class="ttname"><a href="classOutputPage.html#a905182025f38e9304a183457c997e764">OutputPage\$mBodytext</a></div><div class="ttdeci">string $mBodytext</div><div class="ttdoc">Contains all of the "<body>" content. </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l00067">OutputPage.php:67</a></div></div> <div class="ttc" id="classTitle_html_acd8c320154e49f2bc750102b2219e55c"><div class="ttname"><a href="classTitle.html#acd8c320154e49f2bc750102b2219e55c">Title\makeTitleSafe</a></div><div class="ttdeci">static makeTitleSafe($ns, $title, $fragment= '', $interwiki= '')</div><div class="ttdoc">Create a new Title from a namespace index and a DB key. </div><div class="ttdef"><b>Definition:</b> <a href="Title_8php_source.html#l00548">Title.php:548</a></div></div> <div class="ttc" id="classOutputPage_html_ad0d7ef039708dd0d3cdc83ad3bd6f23e"><div class="ttname"><a href="classOutputPage.html#ad0d7ef039708dd0d3cdc83ad3bd6f23e">OutputPage\buildCssLinksArray</a></div><div class="ttdeci">buildCssLinksArray()</div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l03776">OutputPage.php:3776</a></div></div> <div class="ttc" id="classOutputPage_html_a50507820b7fb637b0f4924f31d98600c"><div class="ttname"><a href="classOutputPage.html#a50507820b7fb637b0f4924f31d98600c">OutputPage\getModuleStyles</a></div><div class="ttdeci">getModuleStyles($filter=false, $position=null)</div><div class="ttdoc">Get the list of module CSS to include on this page. </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l00605">OutputPage.php:605</a></div></div> <div class="ttc" id="classOutputPage_html_aaa1c0ae62fd0a36703d1736b7ecc8c7c"><div class="ttname"><a href="classOutputPage.html#aaa1c0ae62fd0a36703d1736b7ecc8c7c">OutputPage\parseInline</a></div><div class="ttdeci">parseInline($text, $linestart=true, $interface=false)</div><div class="ttdoc">Parse wikitext, strip paragraphs, and return the HTML. </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l01930">OutputPage.php:1930</a></div></div> <div class="ttc" id="group__Constants_html_gaf9a09ab91a9583e960a610723f5f4330"><div class="ttname"><a href="group__Constants.html#gaf9a09ab91a9583e960a610723f5f4330">DB_SLAVE</a></div><div class="ttdeci">const DB_SLAVE</div><div class="ttdef"><b>Definition:</b> <a href="Defines_8php_source.html#l00047">Defines.php:47</a></div></div> <div class="ttc" id="classOutputPage_html_a0acf51550b84db556540479b7cc4fba5"><div class="ttname"><a href="classOutputPage.html#a0acf51550b84db556540479b7cc4fba5">OutputPage\styleLink</a></div><div class="ttdeci">styleLink($style, array $options)</div><div class="ttdoc">Generate \<link\> tags for stylesheets. </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l03801">OutputPage.php:3801</a></div></div> <div class="ttc" id="classResourceLoader_html_a5e720bc042a40216b017b18ccf4af321"><div class="ttname"><a href="classResourceLoader.html#a5e720bc042a40216b017b18ccf4af321">ResourceLoader\makeInlineScript</a></div><div class="ttdeci">static makeInlineScript($script)</div><div class="ttdoc">Construct an inline script tag with given JS code. </div><div class="ttdef"><b>Definition:</b> <a href="ResourceLoader_8php_source.html#l01381">ResourceLoader.php:1381</a></div></div> <div class="ttc" id="classOutputPage_html_af355e999b051480b75e0ea4a334b5508"><div class="ttname"><a href="classOutputPage.html#af355e999b051480b75e0ea4a334b5508">OutputPage\$mETag</a></div><div class="ttdeci">$mETag</div><div class="ttdoc">Contains an HTTP Entity Tags (see RFC 2616 section 3.13) which is used as a unique identifier for the...</div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l00121">OutputPage.php:121</a></div></div> <div class="ttc" id="classSkin_html_a490d80986a84dc6cc98a9f389bb6f670"><div class="ttname"><a href="classSkin.html#a490d80986a84dc6cc98a9f389bb6f670">Skin\getHtmlElementAttributes</a></div><div class="ttdeci">getHtmlElementAttributes()</div><div class="ttdoc">Return values for <html> element. </div><div class="ttdef"><b>Definition:</b> <a href="Skin_8php_source.html#l00399">Skin.php:399</a></div></div> <div class="ttc" id="GlobalFunctions_8php_html_a8fc068abfbf5ce2e9ac658781b8e8659"><div class="ttname"><a href="GlobalFunctions_8php.html#a8fc068abfbf5ce2e9ac658781b8e8659">wfBCP47</a></div><div class="ttdeci">wfBCP47($code)</div><div class="ttdoc">Get the normalised IETF language tag See unit test for examples. </div><div class="ttdef"><b>Definition:</b> <a href="GlobalFunctions_8php_source.html#l03452">GlobalFunctions.php:3452</a></div></div> <div class="ttc" id="hooks_8txt_html_a82840e2424b6b7e1b1bfe79de4db9b00"><div class="ttname"><a href="hooks_8txt.html#a82840e2424b6b7e1b1bfe79de4db9b00">$title</a></div><div class="ttdeci">namespace and then decline to actually register it file or subcat img or subcat $title</div><div class="ttdef"><b>Definition:</b> <a href="hooks_8txt_source.html#l00916">hooks.txt:916</a></div></div> <div class="ttc" id="classMWDebug_html_a3538a8910feb064f85dc40a74ab19ec5"><div class="ttname"><a href="classMWDebug.html#a3538a8910feb064f85dc40a74ab19ec5">MWDebug\addModules</a></div><div class="ttdeci">static addModules(OutputPage $out)</div><div class="ttdoc">Add ResourceLoader modules to the OutputPage object if debugging is enabled. </div><div class="ttdef"><b>Definition:</b> <a href="MWDebug_8php_source.html#l00085">MWDebug.php:85</a></div></div> <div class="ttc" id="classOutputPage_html_a0a5a13c217ca4eed7a88945bd63ec730"><div class="ttname"><a href="classOutputPage.html#a0a5a13c217ca4eed7a88945bd63ec730">OutputPage\addLink</a></div><div class="ttdeci">addLink(array $linkarr)</div><div class="ttdoc">Add a new \<link\> tag to the page header. </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l00393">OutputPage.php:393</a></div></div> <div class="ttc" id="classOutputPage_html_a7a1e5451f23d157679422576a666912c"><div class="ttname"><a href="classOutputPage.html#a7a1e5451f23d157679422576a666912c">OutputPage\addStyle</a></div><div class="ttdeci">addStyle($style, $media= '', $condition= '', $dir= '')</div><div class="ttdoc">Add a local or specified stylesheet, with the given media options. </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l03634">OutputPage.php:3634</a></div></div> <div class="ttc" id="classHtml_html_a7d66939a3f3ee87a5775e6de49939cf5"><div class="ttname"><a href="classHtml.html#a7d66939a3f3ee87a5775e6de49939cf5">Html\inlineStyle</a></div><div class="ttdeci">static inlineStyle($contents, $media= 'all')</div><div class="ttdoc">Output a "<style>" tag with the given contents for the given media type (if any). ...</div><div class="ttdef"><b>Definition:</b> <a href="Html_8php_source.html#l00628">Html.php:628</a></div></div> <div class="ttc" id="classHooks_html_a4d65939e05d81fe900cab2edf720040c"><div class="ttname"><a href="classHooks.html#a4d65939e05d81fe900cab2edf720040c">Hooks\run</a></div><div class="ttdeci">static run($event, array $args=[], $deprecatedVersion=null)</div><div class="ttdoc">Call hook functions defined in Hooks::register and $wgHooks. </div><div class="ttdef"><b>Definition:</b> <a href="Hooks_8php_source.html#l00131">Hooks.php:131</a></div></div> <div class="ttc" id="group__Constants_html_gabdf7fe8fc0c2bc5c556aebeccdd6c230"><div class="ttname"><a href="group__Constants.html#gabdf7fe8fc0c2bc5c556aebeccdd6c230">PROTO_RELATIVE</a></div><div class="ttdeci">const PROTO_RELATIVE</div><div class="ttdef"><b>Definition:</b> <a href="Defines_8php_source.html#l00264">Defines.php:264</a></div></div> <div class="ttc" id="design_8txt_html_aaa89c2ef41e614c0ab4f3149ebafe385"><div class="ttname"><a href="design_8txt.html#aaa89c2ef41e614c0ab4f3149ebafe385">text</a></div><div class="ttdeci">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</div><div class="ttdef"><b>Definition:</b> <a href="design_8txt_source.html#l00012">design.txt:12</a></div></div> <div class="ttc" id="classOutputPage_html_af511b1bb037b8e436645fe15d3d3269a"><div class="ttname"><a href="classOutputPage.html#af511b1bb037b8e436645fe15d3d3269a">OutputPage\$mCategories</a></div><div class="ttdeci">array $mCategories</div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l00127">OutputPage.php:127</a></div></div> <div class="ttc" id="classAction_html_abdc62032f952f5976e6b43b8c6c47cc9"><div class="ttname"><a href="classAction.html#abdc62032f952f5976e6b43b8c6c47cc9">Action\getActionName</a></div><div class="ttdeci">static getActionName(IContextSource $context)</div><div class="ttdoc">Get the action that will be executed, not necessarily the one passed passed through the "action" requ...</div><div class="ttdef"><b>Definition:</b> <a href="Action_8php_source.html#l00122">Action.php:122</a></div></div> <div class="ttc" id="hooks_8txt_html_aa5c3decea0436db81bfd52a0ebcb3c22"><div class="ttname"><a href="hooks_8txt.html#aa5c3decea0436db81bfd52a0ebcb3c22">$tag</a></div><div class="ttdeci">this hook is for auditing only RecentChangesLinked and Watchlist RecentChangesLinked and Watchlist e g Watchlist removed from all revisions and log entries to which it was applied This gives extensions a chance to take it off their books $tag</div><div class="ttdef"><b>Definition:</b> <a href="hooks_8txt_source.html#l00969">hooks.txt:969</a></div></div> <div class="ttc" id="classOutputPage_html_abdbd64e6df0ad5f5691bd0d63e5e32da"><div class="ttname"><a href="classOutputPage.html#abdbd64e6df0ad5f5691bd0d63e5e32da">OutputPage\showFileNotFoundError</a></div><div class="ttdeci">showFileNotFoundError($name)</div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l02606">OutputPage.php:2606</a></div></div> <div class="ttc" id="classOutputPage_html_a6a3d84be750825d461e862b69f3c0857"><div class="ttname"><a href="classOutputPage.html#a6a3d84be750825d461e862b69f3c0857">OutputPage\setFollowPolicy</a></div><div class="ttdeci">setFollowPolicy($policy)</div><div class="ttdoc">Set the follow policy for the page, but leave the index policy un- touched. </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l00893">OutputPage.php:893</a></div></div> <div class="ttc" id="classOutputPage_html_a21a60c27ebc894ac4cb14919da84dc20"><div class="ttname"><a href="classOutputPage.html#a21a60c27ebc894ac4cb14919da84dc20">OutputPage\$mNewSectionLink</a></div><div class="ttdeci">bool $mNewSectionLink</div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l00218">OutputPage.php:218</a></div></div> <div class="ttc" id="classHtml_html_a575ca79447ccfad0975d02a77895e9aa"><div class="ttname"><a href="classHtml.html#a575ca79447ccfad0975d02a77895e9aa">Html\htmlHeader</a></div><div class="ttdeci">static htmlHeader(array $attribs=[])</div><div class="ttdoc">Constructs the opening html-tag with necessary doctypes depending on global variables. </div><div class="ttdef"><b>Definition:</b> <a href="Html_8php_source.html#l00920">Html.php:920</a></div></div> <div class="ttc" id="namespaceFauxRequest_html"><div class="ttname"><a href="namespaceFauxRequest.html">FauxRequest</a></div></div> <div class="ttc" id="classOutputPage_html_a671be7cc33f16ff0eb6c456c20227c6e"><div class="ttname"><a href="classOutputPage.html#a671be7cc33f16ff0eb6c456c20227c6e">OutputPage\$mVaryHeader</a></div><div class="ttdeci">$mVaryHeader</div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l00271">OutputPage.php:271</a></div></div> <div class="ttc" id="classSkin_html_af826daedb40661be82b88cf839aac9d1"><div class="ttname"><a href="classSkin.html#af826daedb40661be82b88cf839aac9d1">Skin\getPageClasses</a></div><div class="ttdeci">getPageClasses($title)</div><div class="ttdoc">TODO: document. </div><div class="ttdef"><b>Definition:</b> <a href="Skin_8php_source.html#l00371">Skin.php:371</a></div></div> <div class="ttc" id="distributors_8txt_html_a7b0adad6be9193b56d3beaec2672f963"><div class="ttname"><a href="distributors_8txt.html#a7b0adad6be9193b56d3beaec2672f963">as</a></div><div class="ttdeci">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</div><div class="ttdef"><b>Definition:</b> <a href="distributors_8txt_source.html#l00009">distributors.txt:9</a></div></div> <div class="ttc" id="classOutputPage_html_aa5e61919db9bcc577162509d3a4ecbad"><div class="ttname"><a href="classOutputPage.html#aa5e61919db9bcc577162509d3a4ecbad">OutputPage\addVaryHeader</a></div><div class="ttdeci">addVaryHeader($header, array $option=null)</div><div class="ttdoc">Add an HTTP header that will influence on the cache. </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l02021">OutputPage.php:2021</a></div></div> <div class="ttc" id="hooks_8txt_html_aff741ced333f22e57bcc68c2c3adcc7e"><div class="ttname"><a href="hooks_8txt.html#aff741ced333f22e57bcc68c2c3adcc7e">$code</a></div><div class="ttdeci">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</div><div class="ttdef"><b>Definition:</b> <a href="hooks_8txt_source.html#l00766">hooks.txt:766</a></div></div> <div class="ttc" id="classOutputPage_html"><div class="ttname"><a href="classOutputPage.html">OutputPage</a></div><div class="ttdoc">This class should be covered by a general architecture document which does not exist as of January 20...</div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l00042">OutputPage.php:42</a></div></div> <div class="ttc" id="classOutputPage_html_a8035589ca29e2a598e57cf1b4cc56d42"><div class="ttname"><a href="classOutputPage.html#a8035589ca29e2a598e57cf1b4cc56d42">OutputPage\parse</a></div><div class="ttdeci">parse($text, $linestart=true, $interface=false, $language=null)</div><div class="ttdoc">Parse wikitext and return the HTML. </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l01890">OutputPage.php:1890</a></div></div> <div class="ttc" id="classParserOptions_html_abbb45f7fd3d62e75fdeb1bd96f817abc"><div class="ttname"><a href="classParserOptions.html#abbb45f7fd3d62e75fdeb1bd96f817abc">ParserOptions\newFromAnon</a></div><div class="ttdeci">static newFromAnon()</div><div class="ttdoc">Get a ParserOptions object for an anonymous user. </div><div class="ttdef"><b>Definition:</b> <a href="ParserOptions_8php_source.html#l00639">ParserOptions.php:639</a></div></div> <div class="ttc" id="hooks_8txt_html_a25ba9c89b51c3382b9b86a7a63fd4405"><div class="ttname"><a href="hooks_8txt.html#a25ba9c89b51c3382b9b86a7a63fd4405">$user</a></div><div class="ttdeci">please add to it if you re going to add events to the MediaWiki code where normally authentication against an external auth plugin would be creating a local account $user</div><div class="ttdef"><b>Definition:</b> <a href="hooks_8txt_source.html#l00246">hooks.txt:246</a></div></div> <div class="ttc" id="classLinker_html_ad97e40cfea2343c5cae8307cf1fe47a4"><div class="ttname"><a href="classLinker.html#ad97e40cfea2343c5cae8307cf1fe47a4">Linker\link</a></div><div class="ttdeci">static link($target, $html=null, $customAttribs=[], $query=[], $options=[])</div><div class="ttdoc">This function returns an HTML link to the given target. </div><div class="ttdef"><b>Definition:</b> <a href="Linker_8php_source.html#l00195">Linker.php:195</a></div></div> <div class="ttc" id="classOutputPage_html_a5f860e2d3f13ff6790cf164a8127da2d"><div class="ttname"><a href="classOutputPage.html#a5f860e2d3f13ff6790cf164a8127da2d">OutputPage\getFeedAppendQuery</a></div><div class="ttdeci">getFeedAppendQuery()</div><div class="ttdoc">Will currently always return null. </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l01182">OutputPage.php:1182</a></div></div> <div class="ttc" id="classOutputPage_html_ae6a23b2345a86cf28131f4b4c8de891b"><div class="ttname"><a href="classOutputPage.html#ae6a23b2345a86cf28131f4b4c8de891b">OutputPage\$mCategoryLinks</a></div><div class="ttdeci">array $mCategoryLinks</div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l00124">OutputPage.php:124</a></div></div> <div class="ttc" id="classOutputPage_html_aed7f95440b43b300d7d5fab3403c1866"><div class="ttname"><a href="classOutputPage.html#aed7f95440b43b300d7d5fab3403c1866">OutputPage\setTarget</a></div><div class="ttdeci">setTarget($target)</div><div class="ttdoc">Sets ResourceLoader target for load.php links. </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l00657">OutputPage.php:657</a></div></div> <div class="ttc" id="classOutputPage_html_a3b0569a781829829e0875fe5969f6426"><div class="ttname"><a href="classOutputPage.html#a3b0569a781829829e0875fe5969f6426">OutputPage\setTitle</a></div><div class="ttdeci">setTitle(Title $t)</div><div class="ttdoc">Set the Title object to use. </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l00992">OutputPage.php:992</a></div></div> <div class="ttc" id="classOutputPage_html_ad13e795771bbce676a6841998abb09df"><div class="ttname"><a href="classOutputPage.html#ad13e795771bbce676a6841998abb09df">OutputPage\addBacklinkSubtitle</a></div><div class="ttdeci">addBacklinkSubtitle(Title $title, $query=[])</div><div class="ttdoc">Add a subtitle containing a backlink to a page. </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l01041">OutputPage.php:1041</a></div></div> <div class="ttc" id="classOutputPage_html_a1275bc698729b5f15e687b7ec49bd611"><div class="ttname"><a href="classOutputPage.html#a1275bc698729b5f15e687b7ec49bd611">OutputPage\$mStatusCode</a></div><div class="ttdeci">int $mStatusCode</div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l00104">OutputPage.php:104</a></div></div> <div class="ttc" id="classOutputPage_html_a030c036f1938af782222d925b21be9a5"><div class="ttname"><a href="classOutputPage.html#a030c036f1938af782222d925b21be9a5">OutputPage\$mCanonicalUrl</a></div><div class="ttdeci">bool $mCanonicalUrl</div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l00050">OutputPage.php:50</a></div></div> <div class="ttc" id="classOutputPage_html_a294d125150b7a095cf5529e1fc75fd54"><div class="ttname"><a href="classOutputPage.html#a294d125150b7a095cf5529e1fc75fd54">OutputPage\$mLinktags</a></div><div class="ttdeci">array $mLinktags</div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l00047">OutputPage.php:47</a></div></div> <div class="ttc" id="classOutputPage_html_a0b492edfed8cf9eafc32580008e26027"><div class="ttname"><a href="classOutputPage.html#a0b492edfed8cf9eafc32580008e26027">OutputPage\addMeta</a></div><div class="ttdeci">addMeta($name, $val)</div><div class="ttdoc">Add a new "<meta>" tag To add an http-equiv meta tag, precede the name with "http:". </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l00372">OutputPage.php:372</a></div></div> <div class="ttc" id="GlobalFunctions_8php_html_abfeadc51b922aa4f32f1c5f6a3c2f5f2"><div class="ttname"><a href="GlobalFunctions_8php.html#abfeadc51b922aa4f32f1c5f6a3c2f5f2">TS_MW</a></div><div class="ttdeci">const TS_MW</div><div class="ttdoc">MediaWiki concatenated string timestamp (YYYYMMDDHHMMSS) </div><div class="ttdef"><b>Definition:</b> <a href="GlobalFunctions_8php_source.html#l01999">GlobalFunctions.php:1999</a></div></div> <div class="ttc" id="classOutputPage_html_add837040d9e9601c9ad7fd4855399b0b"><div class="ttname"><a href="classOutputPage.html#add837040d9e9601c9ad7fd4855399b0b">OutputPage\addLanguageLinks</a></div><div class="ttdeci">addLanguageLinks(array $newLinkArray)</div><div class="ttdoc">Add new language links. </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l01238">OutputPage.php:1238</a></div></div> <div class="ttc" id="classOutputPage_html_af352fd56bac015bc8277aad6072f5a27"><div class="ttname"><a href="classOutputPage.html#af352fd56bac015bc8277aad6072f5a27">OutputPage\getTarget</a></div><div class="ttdeci">getTarget()</div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l00648">OutputPage.php:648</a></div></div> <div class="ttc" id="GlobalFunctions_8php_html_a3767c8d03afbee6be3231add01d62ca1"><div class="ttname"><a href="GlobalFunctions_8php.html#a3767c8d03afbee6be3231add01d62ca1">wfGetAllCallers</a></div><div class="ttdeci">wfGetAllCallers($limit=3)</div><div class="ttdoc">Return a string consisting of callers in the stack. </div><div class="ttdef"><b>Definition:</b> <a href="GlobalFunctions_8php_source.html#l01587">GlobalFunctions.php:1587</a></div></div> <div class="ttc" id="hooks_8txt_html_a83cf8b3d1cb79bd9d116941793fb7964"><div class="ttname"><a href="hooks_8txt.html#a83cf8b3d1cb79bd9d116941793fb7964">messages</a></div><div class="ttdeci">this hook is for auditing only RecentChangesLinked and Watchlist RecentChangesLinked and Watchlist e g Watchlist removed from all revisions and log entries to which it was applied This gives extensions a chance to take it off their books as the deletion has already been partly carried out by this point or something similar the user will be unable to create the tag set and then return false from the hook function Ensure you consume the ChangeTagAfterDelete hook to carry out custom deletion actions as context called by AbstractContent::getParserOutput May be used to override the normal model specific rendering of page content as context as context the output can only depend on parameters provided to this hook not on global state indicating whether full HTML should be generated If generation of HTML may be but other information should still be present in the ParserOutput object to manipulate or replace but no entry for that model exists in $wgContentHandlers if desired whether it is OK to use $contentModel on $title Handler functions that modify $ok should generally return false to prevent further hooks from further modifying $ok inclusive false for true for descending in case the handler function wants to provide a converted Content object Note that $result getContentModel() must return $toModel. 'CustomEditor'you ll need to handle error messages</div><div class="ttdef"><b>Definition:</b> <a href="hooks_8txt_source.html#l01103">hooks.txt:1103</a></div></div> <div class="ttc" id="classOutputPage_html_ac59084e3de662e92cff290d230b3fdce"><div class="ttname"><a href="classOutputPage.html#ac59084e3de662e92cff290d230b3fdce">OutputPage\$mLastModified</a></div><div class="ttdeci">string $mLastModified</div><div class="ttdoc">Variable mLastModified and mEtag are used for sending cache control. </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l00110">OutputPage.php:110</a></div></div> <div class="ttc" id="injection_8txt_html_a9be135e7ed50352b0681046d2258704d"><div class="ttname"><a href="injection_8txt.html#a9be135e7ed50352b0681046d2258704d">php</a></div><div class="ttdeci">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</div><div class="ttdef"><b>Definition:</b> <a href="injection_8txt_source.html#l00035">injection.txt:35</a></div></div> <div class="ttc" id="GlobalFunctions_8php_html_a79db634652da5a2541f9c1c69c73f20f"><div class="ttname"><a href="GlobalFunctions_8php.html#a79db634652da5a2541f9c1c69c73f20f">wfSetVar</a></div><div class="ttdeci">wfSetVar(&$dest, $source, $force=false)</div><div class="ttdoc">Sets dest to source and returns the original value of dest If source is NULL, it just returns the val...</div><div class="ttdef"><b>Definition:</b> <a href="GlobalFunctions_8php_source.html#l01717">GlobalFunctions.php:1717</a></div></div> <div class="ttc" id="classResourceLoaderModule_html_a52bc16ee3a7bd5ab6f9dce699ae0ba04"><div class="ttname"><a href="classResourceLoaderModule.html#a52bc16ee3a7bd5ab6f9dce699ae0ba04">ResourceLoaderModule\TYPE_STYLES</a></div><div class="ttdeci">const TYPE_STYLES</div><div class="ttdef"><b>Definition:</b> <a href="ResourceLoaderModule_8php_source.html#l00035">ResourceLoaderModule.php:35</a></div></div> <div class="ttc" id="classResourceLoader_html_a337cdcaa27834db6a2180bb7a8e5c754"><div class="ttname"><a href="classResourceLoader.html#a337cdcaa27834db6a2180bb7a8e5c754">ResourceLoader\inDebugMode</a></div><div class="ttdeci">static inDebugMode()</div><div class="ttdoc">Determine whether debug mode was requested Order of priority is 1) request param, 2) cookie...</div><div class="ttdef"><b>Definition:</b> <a href="ResourceLoader_8php_source.html#l01436">ResourceLoader.php:1436</a></div></div> <div class="ttc" id="opensearch__desc_8php_html_a3ad3a4240c0f97c7e85aff5c52a454d4"><div class="ttname"><a href="opensearch__desc_8php.html#a3ad3a4240c0f97c7e85aff5c52a454d4">print</a></div><div class="ttdeci">print</div><div class="ttdef"><b>Definition:</b> <a href="opensearch__desc_8php_source.html#l00041">opensearch_desc.php:41</a></div></div> <div class="ttc" id="classOutputPage_html_a3a5bf26cb814f42796b03302c2b1b4ad"><div class="ttname"><a href="classOutputPage.html#a3a5bf26cb814f42796b03302c2b1b4ad">OutputPage\addParserOutputNoText</a></div><div class="ttdeci">addParserOutputNoText($parserOutput)</div><div class="ttdoc">Add a ParserOutput object, but without Html. </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l01753">OutputPage.php:1753</a></div></div> <div class="ttc" id="group__Constants_html_ga1dfb07ffcecaf8578d3ea3b0784b9a0b"><div class="ttname"><a href="group__Constants.html#ga1dfb07ffcecaf8578d3ea3b0784b9a0b">PROTO_CANONICAL</a></div><div class="ttdeci">const PROTO_CANONICAL</div><div class="ttdef"><b>Definition:</b> <a href="Defines_8php_source.html#l00266">Defines.php:266</a></div></div> <div class="ttc" id="classResourceLoaderModule_html_a5a21480d171b8c5ab7e208c1595496a0"><div class="ttname"><a href="classResourceLoaderModule.html#a5a21480d171b8c5ab7e208c1595496a0">ResourceLoaderModule\TYPE_COMBINED</a></div><div class="ttdeci">const TYPE_COMBINED</div><div class="ttdef"><b>Definition:</b> <a href="ResourceLoaderModule_8php_source.html#l00036">ResourceLoaderModule.php:36</a></div></div> <div class="ttc" id="classOutputPage_html_af89070ecdf543e1e68be7918378ea6b4"><div class="ttname"><a href="classOutputPage.html#af89070ecdf543e1e68be7918378ea6b4">OutputPage\getHeadLinks</a></div><div class="ttdeci">getHeadLinks()</div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l03603">OutputPage.php:3603</a></div></div> <div class="ttc" id="hooks_8txt_html_a9a91825f641ae063ec98b842676f4510"><div class="ttname"><a href="hooks_8txt.html#a9a91825f641ae063ec98b842676f4510">$request</a></div><div class="ttdeci">error also a ContextSource you ll probably need to make sure the header is varied on $request</div><div class="ttdef"><b>Definition:</b> <a href="hooks_8txt_source.html#l02422">hooks.txt:2422</a></div></div> <div class="ttc" id="classOutputPage_html_a433b8859b4eb6e96f46a9dbb8f5b21ec"><div class="ttname"><a href="classOutputPage.html#a433b8859b4eb6e96f46a9dbb8f5b21ec">OutputPage\$mRevisionId</a></div><div class="ttdeci">int $mRevisionId</div><div class="ttdoc">To include the variable {{REVISIONID}}. </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l00246">OutputPage.php:246</a></div></div> <div class="ttc" id="classOutputPage_html_af6953b51223474d812a669df88dc9dfd"><div class="ttname"><a href="classOutputPage.html#af6953b51223474d812a669df88dc9dfd">OutputPage\setSquidMaxage</a></div><div class="ttdeci">setSquidMaxage($maxage)</div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l01939">OutputPage.php:1939</a></div></div> <div class="ttc" id="classOutputPage_html_add6cc41891d878d9067c72b328e1de2f"><div class="ttname"><a href="classOutputPage.html#add6cc41891d878d9067c72b328e1de2f">OutputPage\setRevisionTimestamp</a></div><div class="ttdeci">setRevisionTimestamp($timestamp)</div><div class="ttdoc">Set the timestamp of the revision which will be displayed. </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l01610">OutputPage.php:1610</a></div></div> <div class="ttc" id="classOutputPage_html_a8a610730ab03ac9c6c711871b7363cbe"><div class="ttname"><a href="classOutputPage.html#a8a610730ab03ac9c6c711871b7363cbe">OutputPage\showFileCopyError</a></div><div class="ttdeci">showFileCopyError($old, $new)</div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l02594">OutputPage.php:2594</a></div></div> <div class="ttc" id="classOutputPage_html_a1a35b75f40e8ee3e94ba08d1228f853a"><div class="ttname"><a href="classOutputPage.html#a1a35b75f40e8ee3e94ba08d1228f853a">OutputPage\getSyndicationLinks</a></div><div class="ttdeci">getSyndicationLinks()</div><div class="ttdoc">Return URLs for each supported syndication format for this page. </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l01173">OutputPage.php:1173</a></div></div> <div class="ttc" id="namespaceWrappedString_1_1WrappedString_html"><div class="ttname"><a href="namespaceWrappedString_1_1WrappedString.html">WrappedString</a></div></div> <div class="ttc" id="classOutputPage_html_a6de9ff4af88bdff421144b7c165c05c2"><div class="ttname"><a href="classOutputPage.html#a6de9ff4af88bdff421144b7c165c05c2">OutputPage\versionRequired</a></div><div class="ttdeci">versionRequired($version)</div><div class="ttdoc">Display an error page indicating that a given version of MediaWiki is required to use it...</div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l02490">OutputPage.php:2490</a></div></div> <div class="ttc" id="classSpecialPageFactory_html_adcf9ed88afa106ddce0dcc7c8a8ef8ea"><div class="ttname"><a href="classSpecialPageFactory.html#adcf9ed88afa106ddce0dcc7c8a8ef8ea">SpecialPageFactory\resolveAlias</a></div><div class="ttdeci">static resolveAlias($alias)</div><div class="ttdoc">Given a special page name with a possible subpage, return an array where the first element is the spe...</div><div class="ttdef"><b>Definition:</b> <a href="SpecialPageFactory_8php_source.html#l00339">SpecialPageFactory.php:339</a></div></div> <div class="ttc" id="classOutputPage_html_a64723d91c439f469a1b4029f9aa4e221"><div class="ttname"><a href="classOutputPage.html#a64723d91c439f469a1b4029f9aa4e221">OutputPage\enableTOC</a></div><div class="ttdeci">enableTOC($flag=true)</div><div class="ttdoc">Enables/disables TOC, doesn't override NOTOC </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l04020">OutputPage.php:4020</a></div></div> <div class="ttc" id="classOutputPage_html_a25ce0e4633bcf074279838b727a67ff0"><div class="ttname"><a href="classOutputPage.html#a25ce0e4633bcf074279838b727a67ff0">OutputPage\transformCssMedia</a></div><div class="ttdeci">static transformCssMedia($media)</div><div class="ttdoc">Transform "media" attribute based on request parameters. </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l03902">OutputPage.php:3902</a></div></div> <div class="ttc" id="classSanitizer_html_a7e83e99163ef9b2640ea5dbe82841a77"><div class="ttname"><a href="classSanitizer.html#a7e83e99163ef9b2640ea5dbe82841a77">Sanitizer\normalizeCharReferences</a></div><div class="ttdeci">static normalizeCharReferences($text)</div><div class="ttdoc">Ensure that any entities and character references are legal for XML and XHTML specifically. </div><div class="ttdef"><b>Definition:</b> <a href="Sanitizer_8php_source.html#l01362">Sanitizer.php:1362</a></div></div> <div class="ttc" id="classOutputPage_html_a2670a987a71116a9da67e0fff5aadc9b"><div class="ttname"><a href="classOutputPage.html#a2670a987a71116a9da67e0fff5aadc9b">OutputPage\setArticleBodyOnly</a></div><div class="ttdeci">setArticleBodyOnly($only)</div><div class="ttdoc">Set whether the output should only contain the body of the article, without any skin, sidebar, etc. </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l00712">OutputPage.php:712</a></div></div> <div class="ttc" id="classOutputPage_html_ad3c1c4a4229f4c06f5eaaa0fa7e6d5be"><div class="ttname"><a href="classOutputPage.html#ad3c1c4a4229f4c06f5eaaa0fa7e6d5be">OutputPage\getProperty</a></div><div class="ttdeci">getProperty($name)</div><div class="ttdoc">Get an additional output property. </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l00743">OutputPage.php:743</a></div></div> <div class="ttc" id="classOutputPage_html_ad5c85109e32f2955deef1c77f125bc51"><div class="ttname"><a href="classOutputPage.html#ad5c85109e32f2955deef1c77f125bc51">OutputPage\addModuleMessages</a></div><div class="ttdeci">addModuleMessages($modules)</div><div class="ttdoc">Load messages of one or more ResourceLoader modules. </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l00641">OutputPage.php:641</a></div></div> <div class="ttc" id="classOutputPage_html_ad37dc926166096712154a6e2e3ca33d8"><div class="ttname"><a href="classOutputPage.html#ad37dc926166096712154a6e2e3ca33d8">OutputPage\addHeadItem</a></div><div class="ttdeci">addHeadItem($name, $value)</div><div class="ttdoc">Add or replace an header item to the output. </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l00682">OutputPage.php:682</a></div></div> <div class="ttc" id="classOutputPage_html_a362b04977e72809c8ad671a801669fef"><div class="ttname"><a href="classOutputPage.html#a362b04977e72809c8ad671a801669fef">OutputPage\output</a></div><div class="ttdeci">output()</div><div class="ttdoc">Finally, all the text has been munged and accumulated into the object, let's actually output it: ...</div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l02243">OutputPage.php:2243</a></div></div> <div class="ttc" id="classHtml_html_ada5267488ca8c4f1965d3539944059e5"><div class="ttname"><a href="classHtml.html#ada5267488ca8c4f1965d3539944059e5">Html\isXmlMimeType</a></div><div class="ttdeci">static isXmlMimeType($mimetype)</div><div class="ttdoc">Determines if the given MIME type is xml. </div><div class="ttdef"><b>Definition:</b> <a href="Html_8php_source.html#l00965">Html.php:965</a></div></div> <div class="ttc" id="classFile_html_a4487966efdadb09d367edeb6fe08a9c3"><div class="ttname"><a href="classFile.html#a4487966efdadb09d367edeb6fe08a9c3">File\exists</a></div><div class="ttdeci">exists()</div><div class="ttdoc">Returns true if file exists in the repository. </div><div class="ttdef"><b>Definition:</b> <a href="File_8php_source.html#l00876">File.php:876</a></div></div> <div class="ttc" id="GlobalFunctions_8php_html_aa1d453df706a70f66abdf47b6c0a221c"><div class="ttname"><a href="GlobalFunctions_8php.html#aa1d453df706a70f66abdf47b6c0a221c">wfArrayToCgi</a></div><div class="ttdeci">wfArrayToCgi($array1, $array2=null, $prefix= '')</div><div class="ttdoc">This function takes one or two arrays as input, and returns a CGI-style string, e.g. </div><div class="ttdef"><b>Definition:</b> <a href="GlobalFunctions_8php_source.html#l00405">GlobalFunctions.php:405</a></div></div> <div class="ttc" id="classOutputPage_html_ae3443d128fef247f051519ab4c4a7f6a"><div class="ttname"><a href="classOutputPage.html#ae3443d128fef247f051519ab4c4a7f6a">OutputPage\$mRedirectCode</a></div><div class="ttdeci">string $mRedirectCode</div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l00177">OutputPage.php:177</a></div></div> <div class="ttc" id="classOutputPage_html_a6c81739da3b9bc50554a7eda0e3ab042"><div class="ttname"><a href="classOutputPage.html#a6c81739da3b9bc50554a7eda0e3ab042">OutputPage\__construct</a></div><div class="ttdeci">__construct(IContextSource $context=null)</div><div class="ttdoc">Constructor for OutputPage. </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l00314">OutputPage.php:314</a></div></div> <div class="ttc" id="classOutputPage_html_a195b2f7c4021cadc450bf99fc20fb378"><div class="ttname"><a href="classOutputPage.html#a195b2f7c4021cadc450bf99fc20fb378">OutputPage\$mImageTimeKeys</a></div><div class="ttdeci">array $mImageTimeKeys</div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l00174">OutputPage.php:174</a></div></div> <div class="ttc" id="classOutputPage_html_a9585cc35248eda7efe8a8792ecf248dc"><div class="ttname"><a href="classOutputPage.html#a9585cc35248eda7efe8a8792ecf248dc">OutputPage\getResourceLoader</a></div><div class="ttdeci">getResourceLoader()</div><div class="ttdoc">Get a ResourceLoader object associated with this OutputPage. </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l02748">OutputPage.php:2748</a></div></div> <div class="ttc" id="classOutputPage_html_acaa0afb71bf33d0aa188407794516c70"><div class="ttname"><a href="classOutputPage.html#acaa0afb71bf33d0aa188407794516c70">OutputPage\getRevisionId</a></div><div class="ttdeci">getRevisionId()</div><div class="ttdoc">Get the displayed revision ID. </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l01599">OutputPage.php:1599</a></div></div> <div class="ttc" id="classOutputPage_html_a25af79e53d58536bd343061ecc5398b7"><div class="ttname"><a href="classOutputPage.html#a25af79e53d58536bd343061ecc5398b7">OutputPage\setupOOUI</a></div><div class="ttdeci">static setupOOUI($skinName= '', $dir= 'ltr')</div><div class="ttdoc">Helper function to setup the PHP implementation of OOUI to use in this request. </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l04056">OutputPage.php:4056</a></div></div> <div class="ttc" id="GlobalFunctions_8php_html_aa7ec0fc303580abed6ac798349db580c"><div class="ttname"><a href="GlobalFunctions_8php.html#aa7ec0fc303580abed6ac798349db580c">wfClearOutputBuffers</a></div><div class="ttdeci">wfClearOutputBuffers()</div><div class="ttdoc">More legible than passing a 'false' parameter to wfResetOutputBuffers(): </div><div class="ttdef"><b>Definition:</b> <a href="GlobalFunctions_8php_source.html#l01859">GlobalFunctions.php:1859</a></div></div> <div class="ttc" id="classOutputPage_html_a3e3c33a8aeff2ca5c1f48d97605259e7"><div class="ttname"><a href="classOutputPage.html#a3e3c33a8aeff2ca5c1f48d97605259e7">OutputPage\getFileVersion</a></div><div class="ttdeci">getFileVersion()</div><div class="ttdoc">Get the displayed file version. </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l01643">OutputPage.php:1643</a></div></div> <div class="ttc" id="design_8txt_html_a151e6372335f583233d859073a2aa100"><div class="ttname"><a href="design_8txt.html#a151e6372335f583233d859073a2aa100">$wgContLang</a></div><div class="ttdeci">this class mediates it Skin Encapsulates a look and feel for the wiki All of the functions that render HTML and make choices about how to render it are here and are called from various other places when and is meant to be subclassed with other skins that may override some of its functions The User object contains a reference to a and so rather than having a global skin object we just rely on the global User and get the skin with $wgUser and also has some character encoding functions and other locale stuff The current user interface language is instantiated as and the local content language as $wgContLang</div><div class="ttdef"><b>Definition:</b> <a href="design_8txt_source.html#l00056">design.txt:56</a></div></div> <div class="ttc" id="classOutputPage_html_afb8cc09f33554842914ddeb78639aeed"><div class="ttname"><a href="classOutputPage.html#afb8cc09f33554842914ddeb78639aeed">OutputPage\setIndexPolicy</a></div><div class="ttdeci">setIndexPolicy($policy)</div><div class="ttdoc">Set the index policy for the page, but leave the follow policy un- touched. </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l00879">OutputPage.php:879</a></div></div> <div class="ttc" id="classOutputPage_html_aa1d24ab42262f8c082cffd01f4933102"><div class="ttname"><a href="classOutputPage.html#aa1d24ab42262f8c082cffd01f4933102">OutputPage\getScriptsForBottomQueue</a></div><div class="ttdeci">getScriptsForBottomQueue($unused=null)</div><div class="ttdoc">JS stuff to put at the 'bottom', which goes at the bottom of the <body>. </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l03057">OutputPage.php:3057</a></div></div> <div class="ttc" id="classOutputPage_html_a2b5e49a97e61d2fee5c92c9524bf92ca"><div class="ttname"><a href="classOutputPage.html#a2b5e49a97e61d2fee5c92c9524bf92ca">OutputPage\setProperty</a></div><div class="ttdeci">setProperty($name, $value)</div><div class="ttdoc">Set an additional output property. </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l00732">OutputPage.php:732</a></div></div> <div class="ttc" id="classOutputPage_html_acec518bad61fc88f0c3deca963d855d8"><div class="ttname"><a href="classOutputPage.html#acec518bad61fc88f0c3deca963d855d8">OutputPage\forceHideNewSectionLink</a></div><div class="ttdeci">forceHideNewSectionLink()</div><div class="ttdoc">Forcibly hide the new section link? </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l01108">OutputPage.php:1108</a></div></div> <div class="ttc" id="logger_8txt_html_a2d4dcfb81a3319f223f49e727b603cd8"><div class="ttname"><a href="logger_8txt.html#a2d4dcfb81a3319f223f49e727b603cd8">LoggerFactory</a></div><div class="ttdeci">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</div><div class="ttdef"><b>Definition:</b> <a href="logger_8txt_source.html#l00005">logger.txt:5</a></div></div> <div class="ttc" id="classOutputPage_html_ac5edd2167a9f85e4d2257af9662652d2"><div class="ttname"><a href="classOutputPage.html#ac5edd2167a9f85e4d2257af9662652d2">OutputPage\wrapWikiMsg</a></div><div class="ttdeci">wrapWikiMsg($wrap)</div><div class="ttdoc">This function takes a number of message/argument specifications, wraps them in some overall structure...</div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l03990">OutputPage.php:3990</a></div></div> <div class="ttc" id="classOutputPage_html_a1dbd46a260249138845ccb6bce086090"><div class="ttname"><a href="classOutputPage.html#a1dbd46a260249138845ccb6bce086090">OutputPage\$mIsarticle</a></div><div class="ttdeci">bool $mIsarticle</div><div class="ttdoc">Is the displayed content related to the source of the corresponding wiki article. ...</div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l00083">OutputPage.php:83</a></div></div> <div class="ttc" id="namespaceConfig_html"><div class="ttname"><a href="namespaceConfig.html">Config</a></div></div> <div class="ttc" id="classOutputPage_html_aebd9a6e15140d9129190b3143baa4fdf"><div class="ttname"><a href="classOutputPage.html#aebd9a6e15140d9129190b3143baa4fdf">OutputPage\getBottomScripts</a></div><div class="ttdeci">getBottomScripts()</div><div class="ttdoc">JS stuff to put at the bottom of the "<body>". </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l03129">OutputPage.php:3129</a></div></div> <div class="ttc" id="classOutputPage_html_a0f8a850bc9376a121f746edd3f90351f"><div class="ttname"><a href="classOutputPage.html#a0f8a850bc9376a121f746edd3f90351f">OutputPage\setFileVersion</a></div><div class="ttdeci">setFileVersion($file)</div><div class="ttdoc">Set the displayed file version. </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l01630">OutputPage.php:1630</a></div></div> <div class="ttc" id="classOutputPage_html_a32357beb62615652b97f2c416d805715"><div class="ttname"><a href="classOutputPage.html#a32357beb62615652b97f2c416d805715">OutputPage\getRedirect</a></div><div class="ttdeci">getRedirect()</div><div class="ttdoc">Get the URL to redirect to, or an empty string if not redirect URL set. </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l00340">OutputPage.php:340</a></div></div> <div class="ttc" id="classOutputPage_html_a73bd96a7dfd5ee922f734f5874caaf19"><div class="ttname"><a href="classOutputPage.html#a73bd96a7dfd5ee922f734f5874caaf19">OutputPage\addReturnTo</a></div><div class="ttdeci">addReturnTo($title, array $query=[], $text=null, $options=[])</div><div class="ttdoc">Add a "return to" link pointing to a specified title. </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l02618">OutputPage.php:2618</a></div></div> <div class="ttc" id="classResourceLoader_html_a15b0fb203d740d80f7a8d9aa1996e052"><div class="ttname"><a href="classResourceLoader.html#a15b0fb203d740d80f7a8d9aa1996e052">ResourceLoader\makeLoaderQuery</a></div><div class="ttdeci">static makeLoaderQuery($modules, $lang, $skin, $user=null, $version=null, $debug=false, $only=null, $printable=false, $handheld=false, $extraQuery=[])</div><div class="ttdoc">Build a query array (array representation of query string) for load.php. </div><div class="ttdef"><b>Definition:</b> <a href="ResourceLoader_8php_source.html#l01544">ResourceLoader.php:1544</a></div></div> <div class="ttc" id="classOutputPage_html_ad836d88e679e1812c4a3d501377e5963"><div class="ttname"><a href="classOutputPage.html#ad836d88e679e1812c4a3d501377e5963">OutputPage\$mIndexPolicy</a></div><div class="ttdeci">$mIndexPolicy</div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l00269">OutputPage.php:269</a></div></div> <div class="ttc" id="classOutputPage_html_a8a195beaa4f23a362fc942b107d5a1a9"><div class="ttname"><a href="classOutputPage.html#a8a195beaa4f23a362fc942b107d5a1a9">OutputPage\setRevisionId</a></div><div class="ttdeci">setRevisionId($revid)</div><div class="ttdoc">Set the revision ID which will be seen by the wiki text parser for things such as embedded {{REVISION...</div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l01589">OutputPage.php:1589</a></div></div> <div class="ttc" id="classOutputPage_html_af0ba3170ef41dfefee04683f704944d8"><div class="ttname"><a href="classOutputPage.html#af0ba3170ef41dfefee04683f704944d8">OutputPage\getKeyHeader</a></div><div class="ttdeci">getKeyHeader()</div><div class="ttdoc">Get a complete Key header. </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l02054">OutputPage.php:2054</a></div></div> <div class="ttc" id="parserTests_8php_html_a17c8948c68aa44fa9961ae169b6a8961"><div class="ttname"><a href="parserTests_8php.html#a17c8948c68aa44fa9961ae169b6a8961">$version</a></div><div class="ttdeci">$version</div><div class="ttdef"><b>Definition:</b> <a href="parserTests_8php_source.html#l00085">parserTests.php:85</a></div></div> <div class="ttc" id="classLinkBatch_html_af729dcb9268abd17b2948550ce3a21b9"><div class="ttname"><a href="classLinkBatch.html#af729dcb9268abd17b2948550ce3a21b9">LinkBatch\setArray</a></div><div class="ttdeci">setArray($array)</div><div class="ttdoc">Set the link list to a given 2-d array First key is the namespace, second is the DB key...</div><div class="ttdef"><b>Definition:</b> <a href="LinkBatch_8php_source.html#l00091">LinkBatch.php:91</a></div></div> <div class="ttc" id="classSanitizer_html_ade17d9e33f209a075f0f75ef91121f37"><div class="ttname"><a href="classSanitizer.html#ade17d9e33f209a075f0f75ef91121f37">Sanitizer\removeHTMLtags</a></div><div class="ttdeci">static removeHTMLtags($text, $processCallback=null, $args=[], $extratags=[], $removetags=[])</div><div class="ttdoc">Cleans up HTML, removes dangerous tags and attributes, and removes HTML comments. ...</div><div class="ttdef"><b>Definition:</b> <a href="Sanitizer_8php_source.html#l00455">Sanitizer.php:455</a></div></div> <div class="ttc" id="classOutputPage_html_aaaed566db54e8402875b9c83facb64c8"><div class="ttname"><a href="classOutputPage.html#aaaed566db54e8402875b9c83facb64c8">OutputPage\showUnexpectedValueError</a></div><div class="ttdeci">showUnexpectedValueError($name, $val)</div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l02590">OutputPage.php:2590</a></div></div> <div class="ttc" id="GlobalFunctions_8php_html_ad0015ddead36d67a7eedcd20edb3474b"><div class="ttname"><a href="GlobalFunctions_8php.html#ad0015ddead36d67a7eedcd20edb3474b">wfLogWarning</a></div><div class="ttdeci">wfLogWarning($msg, $callerOffset=1, $level=E_USER_WARNING)</div><div class="ttdoc">Send a warning as a PHP error and the debug log. </div><div class="ttdef"><b>Definition:</b> <a href="GlobalFunctions_8php_source.html#l01152">GlobalFunctions.php:1152</a></div></div> <div class="ttc" id="GlobalFunctions_8php_html_ab463bbe9cfff3247e113ceec3fde2c63"><div class="ttname"><a href="GlobalFunctions_8php.html#ab463bbe9cfff3247e113ceec3fde2c63">TS_UNIX</a></div><div class="ttdeci">const TS_UNIX</div><div class="ttdoc">Unix time - the number of seconds since 1970-01-01 00:00:00 UTC. </div><div class="ttdef"><b>Definition:</b> <a href="GlobalFunctions_8php_source.html#l01994">GlobalFunctions.php:1994</a></div></div> <div class="ttc" id="classOutputPage_html_a925bb60cb941e1b5db0f0af194a19703"><div class="ttname"><a href="classOutputPage.html#a925bb60cb941e1b5db0f0af194a19703">OutputPage\$mSubtitle</a></div><div class="ttdeci">array $mSubtitle</div><div class="ttdoc">Contains the page subtitle. </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l00098">OutputPage.php:98</a></div></div> <div class="ttc" id="classOutputPage_html_a232bb330000336185e67afd7416ca284"><div class="ttname"><a href="classOutputPage.html#a232bb330000336185e67afd7416ca284">OutputPage\redirect</a></div><div class="ttdeci">redirect($url, $responsecode= '302')</div><div class="ttdoc">Redirect to $url rather than displaying the normal page. </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l00329">OutputPage.php:329</a></div></div> <div class="ttc" id="classOutputPage_html_a8156613bf23495bc76f27a88d6e63fa5"><div class="ttname"><a href="classOutputPage.html#a8156613bf23495bc76f27a88d6e63fa5">OutputPage\$mPagetitle</a></div><div class="ttdeci">string $mPagetitle</div><div class="ttdoc">Should be private - has getter and setter. </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l00061">OutputPage.php:61</a></div></div> <div class="ttc" id="classResourceLoaderModule_html_ad3f8b6431503c33669f565128495639e"><div class="ttname"><a href="classResourceLoaderModule.html#ad3f8b6431503c33669f565128495639e">ResourceLoaderModule\TYPE_SCRIPTS</a></div><div class="ttdeci">const TYPE_SCRIPTS</div><div class="ttdef"><b>Definition:</b> <a href="ResourceLoaderModule_8php_source.html#l00034">ResourceLoaderModule.php:34</a></div></div> <div class="ttc" id="classOutputPage_html_a4c104c224e6ee6fdc0760624f9ce7f72"><div class="ttname"><a href="classOutputPage.html#a4c104c224e6ee6fdc0760624f9ce7f72">OutputPage\getHtmlFromLoaderLinks</a></div><div class="ttdeci">static getHtmlFromLoaderLinks(array $links)</div><div class="ttdoc">Build html output from an array of links from makeResourceLoaderLink. </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l02943">OutputPage.php:2943</a></div></div> <div class="ttc" id="NoLocalSettings_8php_html_a0a4baf0b22973c07685c3981f0d17fc4"><div class="ttname"><a href="NoLocalSettings_8php.html#a0a4baf0b22973c07685c3981f0d17fc4">$path</a></div><div class="ttdeci">$path</div><div class="ttdef"><b>Definition:</b> <a href="NoLocalSettings_8php_source.html#l00026">NoLocalSettings.php:26</a></div></div> <div class="ttc" id="classOutputPage_html_a7b65b571803fab1ddbab17573315a5bc"><div class="ttname"><a href="classOutputPage.html#a7b65b571803fab1ddbab17573315a5bc">OutputPage\showPermissionsErrorPage</a></div><div class="ttdeci">showPermissionsErrorPage(array $errors, $action=null)</div><div class="ttdoc">Output a standard permission error page. </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l02418">OutputPage.php:2418</a></div></div> <div class="ttc" id="classOutputPage_html_abcd6bfe25a20e4f0a56126fc6efa51cf"><div class="ttname"><a href="classOutputPage.html#abcd6bfe25a20e4f0a56126fc6efa51cf">OutputPage\getCacheVaryCookies</a></div><div class="ttdeci">getCacheVaryCookies()</div><div class="ttdoc">Get the list of cookies that will influence on the cache. </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l01979">OutputPage.php:1979</a></div></div> <div class="ttc" id="classOutputPage_html_acc1fec08f2f1a2de0911f05cb64972b7"><div class="ttname"><a href="classOutputPage.html#acc1fec08f2f1a2de0911f05cb64972b7">OutputPage\getModuleMessages</a></div><div class="ttdeci">getModuleMessages($filter=false, $position=null)</div><div class="ttdoc">Get the list of module messages to include on this page. </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l00630">OutputPage.php:630</a></div></div> <div class="ttc" id="GlobalFunctions_8php_html_a0edae2a1c2224298a143303f97a1ea5c"><div class="ttname"><a href="GlobalFunctions_8php.html#a0edae2a1c2224298a143303f97a1ea5c">wfTimestampOrNull</a></div><div class="ttdeci">wfTimestampOrNull($outputtype=TS_UNIX, $ts=null)</div><div class="ttdoc">Return a formatted timestamp, or null if input is null. </div><div class="ttdef"><b>Definition:</b> <a href="GlobalFunctions_8php_source.html#l02068">GlobalFunctions.php:2068</a></div></div> <div class="ttc" id="classOutputPage_html_a7fa6a137980265694e6aa84198a0d8f5"><div class="ttname"><a href="classOutputPage.html#a7fa6a137980265694e6aa84198a0d8f5">OutputPage\setArticleFlag</a></div><div class="ttdeci">setArticleFlag($v)</div><div class="ttdoc">Set whether the displayed content is related to the source of the corresponding article on the wiki S...</div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l01193">OutputPage.php:1193</a></div></div> <div class="ttc" id="classOutputPage_html_ad843efcec1f915688d2a4d6c79b17e5c"><div class="ttname"><a href="classOutputPage.html#ad843efcec1f915688d2a4d6c79b17e5c">OutputPage\showFileDeleteError</a></div><div class="ttdeci">showFileDeleteError($name)</div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l02602">OutputPage.php:2602</a></div></div> <div class="ttc" id="classXml_html_a60640cfebaa2daf82f1dfb70b846e040"><div class="ttname"><a href="classXml.html#a60640cfebaa2daf82f1dfb70b846e040">Xml\encodeJsCall</a></div><div class="ttdeci">static encodeJsCall($name, $args, $pretty=false)</div><div class="ttdoc">Create a call to a JavaScript function. </div><div class="ttdef"><b>Definition:</b> <a href="Xml_8php_source.html#l00682">Xml.php:682</a></div></div> <div class="ttc" id="classFile_html"><div class="ttname"><a href="classFile.html">File</a></div><div class="ttdoc">Implements some public methods and some protected utility functions which are required by multiple ch...</div><div class="ttdef"><b>Definition:</b> <a href="File_8php_source.html#l00050">File.php:50</a></div></div> <div class="ttc" id="classOutputPage_html_aa93ad6de2db94d9c22705906584893c5"><div class="ttname"><a href="classOutputPage.html#aa93ad6de2db94d9c22705906584893c5">OutputPage\addWikiTextTidy</a></div><div class="ttdeci">addWikiTextTidy($text, $linestart=true)</div><div class="ttdoc">Add wikitext with tidy enabled. </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l01712">OutputPage.php:1712</a></div></div> <div class="ttc" id="classOutputPage_html_a413856bad81088166dc6da5588895090"><div class="ttname"><a href="classOutputPage.html#a413856bad81088166dc6da5588895090">OutputPage\$mPageTitleActionText</a></div><div class="ttdeci">string $mPageTitleActionText</div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l00231">OutputPage.php:231</a></div></div> <div class="ttc" id="classResourceLoader_html"><div class="ttname"><a href="classResourceLoader.html">ResourceLoader</a></div><div class="ttdoc">Dynamic JavaScript and CSS resource loading system. </div><div class="ttdef"><b>Definition:</b> <a href="ResourceLoader_8php_source.html#l00036">ResourceLoader.php:36</a></div></div> <div class="ttc" id="classContextSource_html_aeec47883940f61b3fc268e8053a0a01a"><div class="ttname"><a href="classContextSource.html#aeec47883940f61b3fc268e8053a0a01a">ContextSource\getWikiPage</a></div><div class="ttdeci">getWikiPage()</div><div class="ttdoc">Get the WikiPage object. </div><div class="ttdef"><b>Definition:</b> <a href="ContextSource_8php_source.html#l00113">ContextSource.php:113</a></div></div> <div class="ttc" id="classSkin_html_a5224a834760245b3187149c58e00d335"><div class="ttname"><a href="classSkin.html#a5224a834760245b3187149c58e00d335">Skin\getSkinName</a></div><div class="ttdeci">getSkinName()</div><div class="ttdef"><b>Definition:</b> <a href="Skin_8php_source.html#l00137">Skin.php:137</a></div></div> <div class="ttc" id="classHtml_html_ae33b3a5c765550abd96775e4e44df7c3"><div class="ttname"><a href="classHtml.html#ae33b3a5c765550abd96775e4e44df7c3">Html\linkedStyle</a></div><div class="ttdeci">static linkedStyle($url, $media= 'all')</div><div class="ttdoc">Output a "<link rel=stylesheet>" linking to the given URL for the given media type (if any)...</div><div class="ttdef"><b>Definition:</b> <a href="Html_8php_source.html#l00657">Html.php:657</a></div></div> <div class="ttc" id="classHtml_html_a1c74fee14762ec4d50e09a94c94327ef"><div class="ttname"><a href="classHtml.html#a1c74fee14762ec4d50e09a94c94327ef">Html\element</a></div><div class="ttdeci">static element($element, $attribs=[], $contents= '')</div><div class="ttdoc">Identical to rawElement(), but HTML-escapes $contents (like Xml::element()). </div><div class="ttdef"><b>Definition:</b> <a href="Html_8php_source.html#l00230">Html.php:230</a></div></div> <div class="ttc" id="classOutputPage_html_acb7603b840f300086ee43e4071775843"><div class="ttname"><a href="classOutputPage.html#acb7603b840f300086ee43e4071775843">OutputPage\setIndicators</a></div><div class="ttdeci">setIndicators(array $indicators)</div><div class="ttdoc">Add an array of indicators, with their identifiers as array keys and HTML contents as values...</div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l01380">OutputPage.php:1380</a></div></div> <div class="ttc" id="classOutputPage_html_aacaccc2e7f9237d87a613f334e5f406e"><div class="ttname"><a href="classOutputPage.html#aacaccc2e7f9237d87a613f334e5f406e">OutputPage\disallowUserJs</a></div><div class="ttdeci">disallowUserJs()</div><div class="ttdoc">Do not allow scripts which can be modified by wiki users to load on this page; only allow scripts bun...</div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l01438">OutputPage.php:1438</a></div></div> <div class="ttc" id="classResourceLoaderModule_html_a913ce5b41905ee75a79435626a9cc4ef"><div class="ttname"><a href="classResourceLoaderModule.html#a913ce5b41905ee75a79435626a9cc4ef">ResourceLoaderModule\getOrigin</a></div><div class="ttdeci">getOrigin()</div><div class="ttdoc">Get this module's origin. </div><div class="ttdef"><b>Definition:</b> <a href="ResourceLoaderModule_8php_source.html#l00113">ResourceLoaderModule.php:113</a></div></div> <div class="ttc" id="testCompression_8php_html_af20635b6c08e03bfee9e3fc036fa80f3"><div class="ttname"><a href="testCompression_8php.html#af20635b6c08e03bfee9e3fc036fa80f3">$keys</a></div><div class="ttdeci">$keys</div><div class="ttdef"><b>Definition:</b> <a href="testCompression_8php_source.html#l00065">testCompression.php:65</a></div></div> <div class="ttc" id="classContextSource_html_a4a84d5f0344e114f266fef48c6558999"><div class="ttname"><a href="classContextSource.html#a4a84d5f0344e114f266fef48c6558999">ContextSource\getUser</a></div><div class="ttdeci">getUser()</div><div class="ttdoc">Get the User object. </div><div class="ttdef"><b>Definition:</b> <a href="ContextSource_8php_source.html#l00133">ContextSource.php:133</a></div></div> <div class="ttc" id="classOutputPage_html_ac43a3cad0175d6088d38af8248223678"><div class="ttname"><a href="classOutputPage.html#ac43a3cad0175d6088d38af8248223678">OutputPage\getVaryHeader</a></div><div class="ttdeci">getVaryHeader()</div><div class="ttdoc">Return a Vary: header on which to vary caches. </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l02037">OutputPage.php:2037</a></div></div> <div class="ttc" id="hooks_8txt_html_a18cb89f02456c7d0191cae3c91e677de"><div class="ttname"><a href="hooks_8txt.html#a18cb89f02456c7d0191cae3c91e677de">$vars</a></div><div class="ttdeci">static configuration should be added through ResourceLoaderGetConfigVars instead & $vars</div><div class="ttdef"><b>Definition:</b> <a href="hooks_8txt_source.html#l02000">hooks.txt:2000</a></div></div> <div class="ttc" id="classOutputPage_html_a2a51d70a197223dd7ed9a288cc91ba85"><div class="ttname"><a href="classOutputPage.html#a2a51d70a197223dd7ed9a288cc91ba85">OutputPage\getModules</a></div><div class="ttdeci">getModules($filter=false, $position=null, $param= 'mModules')</div><div class="ttdoc">Get the list of modules to include on this page. </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l00556">OutputPage.php:556</a></div></div> <div class="ttc" id="Setup_8php_html_ae73859032483e19f0ee2b2e781b6ecbf"><div class="ttname"><a href="Setup_8php.html#ae73859032483e19f0ee2b2e781b6ecbf">$wgRequest</a></div><div class="ttdeci">if(is_null($wgLocalTZoffset)) if(!$wgDBerrorLogTZ) $wgRequest</div><div class="ttdef"><b>Definition:</b> <a href="Setup_8php_source.html#l00657">Setup.php:657</a></div></div> <div class="ttc" id="classThrottledError_html"><div class="ttname"><a href="classThrottledError.html">ThrottledError</a></div><div class="ttdoc">Show an error when the user hits a rate limit. </div><div class="ttdef"><b>Definition:</b> <a href="ThrottledError_8php_source.html#l00027">ThrottledError.php:27</a></div></div> <div class="ttc" id="hooks_8txt_html_a7f3af9b6dc4889b59c9971064987d675"><div class="ttname"><a href="hooks_8txt.html#a7f3af9b6dc4889b59c9971064987d675">$type</a></div><div class="ttdeci">do that in ParserLimitReportFormat instead use this to modify the parameters of the image and a DIV can begin in one section and end in another Make sure your code can handle that case gracefully See the EditSectionClearerLink extension for an example zero but section is usually empty its values are the globals values before the output is cached one of or reset my talk my contributions etc etc otherwise the built in rate limiting checks are if enabled allows for interception of redirect as a string mapping parameter names to values & $type</div><div class="ttdef"><b>Definition:</b> <a href="hooks_8txt_source.html#l02342">hooks.txt:2342</a></div></div> <div class="ttc" id="classOutputPage_html_a4829fa8b52d3e210d3d2214d4025e5ca"><div class="ttname"><a href="classOutputPage.html#a4829fa8b52d3e210d3d2214d4025e5ca">OutputPage\addModuleStyles</a></div><div class="ttdeci">addModuleStyles($modules)</div><div class="ttdoc">Add only CSS of one or more modules recognized by ResourceLoader. </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l00618">OutputPage.php:618</a></div></div> <div class="ttc" id="namespaceMWException_html"><div class="ttname"><a href="namespaceMWException.html">MWException</a></div></div> <div class="ttc" id="classOutputPage_html_a74be7ed873b6f223ab26c7619216eb7c"><div class="ttname"><a href="classOutputPage.html#a74be7ed873b6f223ab26c7619216eb7c">OutputPage\$mRedirect</a></div><div class="ttdeci">string $mRedirect</div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l00101">OutputPage.php:101</a></div></div> <div class="ttc" id="classOutputPage_html_a5c16e383a4603aa4b10a3d850d220f64"><div class="ttname"><a href="classOutputPage.html#a5c16e383a4603aa4b10a3d850d220f64">OutputPage\addModuleScripts</a></div><div class="ttdeci">addModuleScripts($modules)</div><div class="ttdoc">Add only JS of one or more modules recognized by ResourceLoader. </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l00593">OutputPage.php:593</a></div></div> <div class="ttc" id="classOutputPage_html_ac1ef46b27a8983bb52715b491dbff9ad"><div class="ttname"><a href="classOutputPage.html#ac1ef46b27a8983bb52715b491dbff9ad">OutputPage\setCanonicalUrl</a></div><div class="ttdeci">setCanonicalUrl($url)</div><div class="ttdoc">Set the URL to be used for the <link rel="canonical">. </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l00424">OutputPage.php:424</a></div></div> <div class="ttc" id="classOutputPage_html_a78717094923ded7d7f41340e0522c189"><div class="ttname"><a href="classOutputPage.html#a78717094923ded7d7f41340e0522c189">OutputPage\setLastModified</a></div><div class="ttdeci">setLastModified($timestamp)</div><div class="ttdoc">Override the last modified timestamp. </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l00849">OutputPage.php:849</a></div></div> <div class="ttc" id="hooks_8txt_html_a2d6f8f7fee75194210501c68760b4125"><div class="ttname"><a href="hooks_8txt.html#a2d6f8f7fee75194210501c68760b4125">$attribs</a></div><div class="ttdeci">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</div><div class="ttdef"><b>Definition:</b> <a href="hooks_8txt_source.html#l01802">hooks.txt:1802</a></div></div> <div class="ttc" id="classOutputPage_html_af1c117c7597a9d09ccb84cee9232b64c"><div class="ttname"><a href="classOutputPage.html#af1c117c7597a9d09ccb84cee9232b64c">OutputPage\setSyndicated</a></div><div class="ttdeci">setSyndicated($show=true)</div><div class="ttdoc">Add or remove feed links in the page header This is mainly kept for backward compatibility, see OutputPage::addFeedLink() for the new version. </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l01120">OutputPage.php:1120</a></div></div> <div class="ttc" id="classOutputPage_html_a54d111eb0e932e01a083f6c55a8804e3"><div class="ttname"><a href="classOutputPage.html#a54d111eb0e932e01a083f6c55a8804e3">OutputPage\getRevisionTimestamp</a></div><div class="ttdeci">getRevisionTimestamp()</div><div class="ttdoc">Get the timestamp of displayed revision. </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l01620">OutputPage.php:1620</a></div></div> <div class="ttc" id="classOutputPage_html_abfea8e505f0a8d95dc8beb316c4579d5"><div class="ttname"><a href="classOutputPage.html#abfea8e505f0a8d95dc8beb316c4579d5">OutputPage\getLinkTags</a></div><div class="ttdeci">getLinkTags()</div><div class="ttdoc">Returns the current <link> tags. </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l00403">OutputPage.php:403</a></div></div> <div class="ttc" id="classOutputPage_html_a009756705931a3399dbe89b257517730"><div class="ttname"><a href="classOutputPage.html#a009756705931a3399dbe89b257517730">OutputPage\isArticle</a></div><div class="ttdeci">isArticle()</div><div class="ttdoc">Return whether the content displayed page is related to the source of the corresponding article on th...</div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l01206">OutputPage.php:1206</a></div></div> <div class="ttc" id="classResourceLoaderContext_html"><div class="ttname"><a href="classResourceLoaderContext.html">ResourceLoaderContext</a></div><div class="ttdoc">Object passed around to modules which contains information about the state of a specific loader reque...</div><div class="ttdef"><b>Definition:</b> <a href="ResourceLoaderContext_8php_source.html#l00031">ResourceLoaderContext.php:31</a></div></div> <div class="ttc" id="classOutputPage_html_aaf8b7eebb1212345cd8b3b5fe77f2ba1"><div class="ttname"><a href="classOutputPage.html#aaf8b7eebb1212345cd8b3b5fe77f2ba1">OutputPage\$mParserOptions</a></div><div class="ttdeci">ParserOptions $mParserOptions</div><div class="ttdoc">lazy initialised, use parserOptions() </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l00202">OutputPage.php:202</a></div></div> <div class="ttc" id="namespaceException_html"><div class="ttname"><a href="namespaceException.html">Exception</a></div></div> <div class="ttc" id="classOutputPage_html_a81c86f0fc996076ed05467f63b3fb154"><div class="ttname"><a href="classOutputPage.html#a81c86f0fc996076ed05467f63b3fb154">OutputPage\addJsConfigVars</a></div><div class="ttdeci">addJsConfigVars($keys, $value=null)</div><div class="ttdoc">Add one or more variables to be set in mw.config in JavaScript. </div><div class="ttdef"><b>Definition:</b> <a href="OutputPage_8php_source.html#l03149">OutputPage.php:3149</a></div></div> <div class="ttc" id="hooks_8txt_html_ae2d36f45856c4960c998f6c76c83b7a8"><div class="ttname"><a href="hooks_8txt.html#ae2d36f45856c4960c998f6c76c83b7a8">$name</a></div><div class="ttdeci">Allows to change the fields on the form that will be generated $name</div><div class="ttdef"><b>Definition:</b> <a href="hooks_8txt_source.html#l00314">hooks.txt:314</a></div></div> <div class="ttc" id="classContextSource_html_a42220e4622a75fd36e754b0e632fdc09"><div class="ttname"><a href="classContextSource.html#a42220e4622a75fd36e754b0e632fdc09">ContextSource\getSkin</a></div><div class="ttdeci">getSkin()</div><div class="ttdoc">Get the Skin object. </div><div class="ttdef"><b>Definition:</b> <a href="ContextSource_8php_source.html#l00153">ContextSource.php:153</a></div></div> <div class="ttc" id="classArticle_html_a7d076b903fbfec072c74038be0b53a47"><div class="ttname"><a href="classArticle.html#a7d076b903fbfec072c74038be0b53a47">Article\formatRobotPolicy</a></div><div class="ttdeci">static formatRobotPolicy($policy)</div><div class="ttdoc">Converts a String robot policy into an associative array, to allow merging of several policies using ...</div><div class="ttdef"><b>Definition:</b> <a href="Article_8php_source.html#l00930">Article.php:930</a></div></div> </div><!-- fragment --></div><!-- contents --> </div><!-- doc-content --> <!-- start footer part --> <div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> <ul> <li class="navelem"><a class="el" href="dir_8a18e807163faa1f0c426c97f3962518.html">includes</a></li><li class="navelem"><a class="el" href="OutputPage_8php.html">OutputPage.php</a></li> <li class="footer">Generated on Wed Nov 15 2017 21:46:35 for MediaWiki by <a href="http://www.doxygen.org/index.html"> <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.8 </li> </ul> </div> </body> </html>