MediaWiki  REL1_31
Skin.php
Go to the documentation of this file.
1 <?php
24 
36 abstract class Skin extends ContextSource {
40  protected $skinname = null;
41 
42  protected $mRelevantTitle = null;
43  protected $mRelevantUser = null;
44 
49  public $stylename = null;
50 
55  static function getSkinNames() {
56  return SkinFactory::getDefaultInstance()->getSkinNames();
57  }
58 
63  static function getSkinNameMessages() {
64  $messages = [];
65  foreach ( self::getSkinNames() as $skinKey => $skinName ) {
66  $messages[] = "skinname-$skinKey";
67  }
68  return $messages;
69  }
70 
78  public static function getAllowedSkins() {
80 
81  $allowedSkins = self::getSkinNames();
82 
83  foreach ( $wgSkipSkins as $skip ) {
84  unset( $allowedSkins[$skip] );
85  }
86 
87  return $allowedSkins;
88  }
89 
99  static function normalizeKey( $key ) {
101 
102  $skinNames = self::getSkinNames();
103 
104  // Make keys lowercase for case-insensitive matching.
105  $skinNames = array_change_key_case( $skinNames, CASE_LOWER );
106  $key = strtolower( $key );
107  $defaultSkin = strtolower( $wgDefaultSkin );
108  $fallbackSkin = strtolower( $wgFallbackSkin );
109 
110  if ( $key == '' || $key == 'default' ) {
111  // Don't return the default immediately;
112  // in a misconfiguration we need to fall back.
113  $key = $defaultSkin;
114  }
115 
116  if ( isset( $skinNames[$key] ) ) {
117  return $key;
118  }
119 
120  // Older versions of the software used a numeric setting
121  // in the user preferences.
122  $fallback = [
123  0 => $defaultSkin,
124  2 => 'cologneblue'
125  ];
126 
127  if ( isset( $fallback[$key] ) ) {
128  $key = $fallback[$key];
129  }
130 
131  if ( isset( $skinNames[$key] ) ) {
132  return $key;
133  } elseif ( isset( $skinNames[$defaultSkin] ) ) {
134  return $defaultSkin;
135  } else {
136  return $fallbackSkin;
137  }
138  }
139 
144  public function __construct( $skinname = null ) {
145  if ( is_string( $skinname ) ) {
146  $this->skinname = $skinname;
147  }
148  }
149 
153  public function getSkinName() {
154  return $this->skinname;
155  }
156 
160  public function initPage( OutputPage $out ) {
161  $this->preloadExistence();
162  }
163 
173  public function getDefaultModules() {
175 
176  $out = $this->getOutput();
177  $config = $this->getConfig();
178  $user = $out->getUser();
179  $modules = [
180  // modules not specific to any specific skin or page
181  'core' => [
182  // Enforce various default modules for all pages and all skins
183  // Keep this list as small as possible
184  'site',
185  'mediawiki.page.startup',
186  'mediawiki.user',
187  ],
188  // modules that enhance the page content in some way
189  'content' => [
190  'mediawiki.page.ready',
191  ],
192  // modules relating to search functionality
193  'search' => [],
194  // modules relating to functionality relating to watching an article
195  'watch' => [],
196  // modules which relate to the current users preferences
197  'user' => [],
198  ];
199 
200  // Support for high-density display images if enabled
201  if ( $config->get( 'ResponsiveImages' ) ) {
202  $modules['core'][] = 'mediawiki.hidpi';
203  }
204 
205  // Preload jquery.tablesorter for mediawiki.page.ready
206  if ( strpos( $out->getHTML(), 'sortable' ) !== false ) {
207  $modules['content'][] = 'jquery.tablesorter';
208  }
209 
210  // Preload jquery.makeCollapsible for mediawiki.page.ready
211  if ( strpos( $out->getHTML(), 'mw-collapsible' ) !== false ) {
212  $modules['content'][] = 'jquery.makeCollapsible';
213  }
214 
215  if ( $out->isTOCEnabled() ) {
216  $modules['content'][] = 'mediawiki.toc';
217  }
218 
219  // Add various resources if required
220  if ( $wgUseAjax && $wgEnableAPI ) {
221  if ( $wgEnableWriteAPI && $user->isLoggedIn()
222  && $user->isAllowedAll( 'writeapi', 'viewmywatchlist', 'editmywatchlist' )
223  && $this->getRelevantTitle()->canExist()
224  ) {
225  $modules['watch'][] = 'mediawiki.page.watch.ajax';
226  }
227 
228  $modules['search'][] = 'mediawiki.searchSuggest';
229  }
230 
231  if ( $user->getBoolOption( 'editsectiononrightclick' ) ) {
232  $modules['user'][] = 'mediawiki.action.view.rightClickEdit';
233  }
234 
235  // Crazy edit-on-double-click stuff
236  if ( $out->isArticle() && $user->getOption( 'editondblclick' ) ) {
237  $modules['user'][] = 'mediawiki.action.view.dblClickEdit';
238  }
239  return $modules;
240  }
241 
245  protected function preloadExistence() {
246  $titles = [];
247 
248  // User/talk link
249  $user = $this->getUser();
250  if ( $user->isLoggedIn() ) {
251  $titles[] = $user->getUserPage();
252  $titles[] = $user->getTalkPage();
253  }
254 
255  // Check, if the page can hold some kind of content, otherwise do nothing
256  $title = $this->getRelevantTitle();
257  if ( $title->canExist() ) {
258  if ( $title->isTalkPage() ) {
259  $titles[] = $title->getSubjectPage();
260  } else {
261  $titles[] = $title->getTalkPage();
262  }
263  }
264 
265  // Footer links (used by SkinTemplate::prepareQuickTemplate)
266  foreach ( [
267  $this->footerLinkTitle( 'privacy', 'privacypage' ),
268  $this->footerLinkTitle( 'aboutsite', 'aboutpage' ),
269  $this->footerLinkTitle( 'disclaimers', 'disclaimerpage' ),
270  ] as $title ) {
271  if ( $title ) {
272  $titles[] = $title;
273  }
274  }
275 
276  Hooks::run( 'SkinPreloadExistence', [ &$titles, $this ] );
277 
278  if ( $titles ) {
279  $lb = new LinkBatch( $titles );
280  $lb->setCaller( __METHOD__ );
281  $lb->execute();
282  }
283  }
284 
290  public function getRevisionId() {
291  return $this->getOutput()->getRevisionId();
292  }
293 
299  public function isRevisionCurrent() {
300  $revID = $this->getRevisionId();
301  return $revID == 0 || $revID == $this->getTitle()->getLatestRevID();
302  }
303 
309  public function setRelevantTitle( $t ) {
310  $this->mRelevantTitle = $t;
311  }
312 
323  public function getRelevantTitle() {
324  if ( isset( $this->mRelevantTitle ) ) {
325  return $this->mRelevantTitle;
326  }
327  return $this->getTitle();
328  }
329 
335  public function setRelevantUser( $u ) {
336  $this->mRelevantUser = $u;
337  }
338 
347  public function getRelevantUser() {
348  if ( isset( $this->mRelevantUser ) ) {
349  return $this->mRelevantUser;
350  }
351  $title = $this->getRelevantTitle();
352  if ( $title->hasSubjectNamespace( NS_USER ) ) {
353  $rootUser = $title->getRootText();
354  if ( User::isIP( $rootUser ) ) {
355  $this->mRelevantUser = User::newFromName( $rootUser, false );
356  } else {
357  $user = User::newFromName( $rootUser, false );
358 
359  if ( $user ) {
360  $user->load( User::READ_NORMAL );
361 
362  if ( $user->isLoggedIn() ) {
363  $this->mRelevantUser = $user;
364  }
365  }
366  }
367  return $this->mRelevantUser;
368  }
369  return null;
370  }
371 
376  abstract function outputPage( OutputPage $out = null );
377 
382  static function makeVariablesScript( $data ) {
383  if ( $data ) {
386  );
387  } else {
388  return '';
389  }
390  }
391 
397  public static function getDynamicStylesheetQuery() {
399 
400  return [
401  'action' => 'raw',
402  'maxage' => $wgSquidMaxage,
403  'usemsgcache' => 'yes',
404  'ctype' => 'text/css',
405  'smaxage' => $wgSquidMaxage,
406  ];
407  }
408 
417  abstract function setupSkinUserCss( OutputPage $out );
418 
424  function getPageClasses( $title ) {
425  $numeric = 'ns-' . $title->getNamespace();
426 
427  if ( $title->isSpecialPage() ) {
428  $type = 'ns-special';
429  // T25315: provide a class based on the canonical special page name without subpages
430  list( $canonicalName ) = SpecialPageFactory::resolveAlias( $title->getDBkey() );
431  if ( $canonicalName ) {
432  $type .= ' ' . Sanitizer::escapeClass( "mw-special-$canonicalName" );
433  } else {
434  $type .= ' mw-invalidspecialpage';
435  }
436  } elseif ( $title->isTalkPage() ) {
437  $type = 'ns-talk';
438  } else {
439  $type = 'ns-subject';
440  }
441 
442  $name = Sanitizer::escapeClass( 'page-' . $title->getPrefixedText() );
443  $root = Sanitizer::escapeClass( 'rootpage-' . $title->getRootTitle()->getPrefixedText() );
444 
445  return "$numeric $type $name $root";
446  }
447 
452  public function getHtmlElementAttributes() {
453  $lang = $this->getLanguage();
454  return [
455  'lang' => $lang->getHtmlCode(),
456  'dir' => $lang->getDir(),
457  'class' => 'client-nojs',
458  ];
459  }
460 
468  function addToBodyAttributes( $out, &$bodyAttrs ) {
469  // does nothing by default
470  }
471 
476  function getLogo() {
477  global $wgLogo;
478  return $wgLogo;
479  }
480 
486  public function shouldPreloadLogo() {
487  return false;
488  }
489 
493  function getCategoryLinks() {
495 
496  $out = $this->getOutput();
497  $allCats = $out->getCategoryLinks();
498 
499  if ( !count( $allCats ) ) {
500  return '';
501  }
502 
503  $embed = "<li>";
504  $pop = "</li>";
505 
506  $s = '';
507  $colon = $this->msg( 'colon-separator' )->escaped();
508 
509  if ( !empty( $allCats['normal'] ) ) {
510  $t = $embed . implode( "{$pop}{$embed}", $allCats['normal'] ) . $pop;
511 
512  $msg = $this->msg( 'pagecategories' )->numParams( count( $allCats['normal'] ) )->escaped();
513  $linkPage = wfMessage( 'pagecategorieslink' )->inContentLanguage()->text();
514  $title = Title::newFromText( $linkPage );
515  $link = $title ? Linker::link( $title, $msg ) : $msg;
516  $s .= '<div id="mw-normal-catlinks" class="mw-normal-catlinks">' .
517  $link . $colon . '<ul>' . $t . '</ul>' . '</div>';
518  }
519 
520  # Hidden categories
521  if ( isset( $allCats['hidden'] ) ) {
522  if ( $this->getUser()->getBoolOption( 'showhiddencats' ) ) {
523  $class = ' mw-hidden-cats-user-shown';
524  } elseif ( $this->getTitle()->getNamespace() == NS_CATEGORY ) {
525  $class = ' mw-hidden-cats-ns-shown';
526  } else {
527  $class = ' mw-hidden-cats-hidden';
528  }
529 
530  $s .= "<div id=\"mw-hidden-catlinks\" class=\"mw-hidden-catlinks$class\">" .
531  $this->msg( 'hidden-categories' )->numParams( count( $allCats['hidden'] ) )->escaped() .
532  $colon . '<ul>' . $embed . implode( "{$pop}{$embed}", $allCats['hidden'] ) . $pop . '</ul>' .
533  '</div>';
534  }
535 
536  # optional 'dmoz-like' category browser. Will be shown under the list
537  # of categories an article belong to
538  if ( $wgUseCategoryBrowser ) {
539  $s .= '<br /><hr />';
540 
541  # get a big array of the parents tree
542  $parenttree = $this->getTitle()->getParentCategoryTree();
543  # Skin object passed by reference cause it can not be
544  # accessed under the method subfunction drawCategoryBrowser
545  $tempout = explode( "\n", $this->drawCategoryBrowser( $parenttree ) );
546  # Clean out bogus first entry and sort them
547  unset( $tempout[0] );
548  asort( $tempout );
549  # Output one per line
550  $s .= implode( "<br />\n", $tempout );
551  }
552 
553  return $s;
554  }
555 
561  function drawCategoryBrowser( $tree ) {
562  $return = '';
563 
564  foreach ( $tree as $element => $parent ) {
565  if ( empty( $parent ) ) {
566  # element start a new list
567  $return .= "\n";
568  } else {
569  # grab the others elements
570  $return .= $this->drawCategoryBrowser( $parent ) . ' &gt; ';
571  }
572 
573  # add our current element to the list
574  $eltitle = Title::newFromText( $element );
575  $return .= Linker::link( $eltitle, htmlspecialchars( $eltitle->getText() ) );
576  }
577 
578  return $return;
579  }
580 
584  function getCategories() {
585  $out = $this->getOutput();
586  $catlinks = $this->getCategoryLinks();
587 
588  // Check what we're showing
589  $allCats = $out->getCategoryLinks();
590  $showHidden = $this->getUser()->getBoolOption( 'showhiddencats' ) ||
591  $this->getTitle()->getNamespace() == NS_CATEGORY;
592 
593  $classes = [ 'catlinks' ];
594  if ( empty( $allCats['normal'] ) && !( !empty( $allCats['hidden'] ) && $showHidden ) ) {
595  $classes[] = 'catlinks-allhidden';
596  }
597 
598  return Html::rawElement(
599  'div',
600  [ 'id' => 'catlinks', 'class' => $classes, 'data-mw' => 'interface' ],
601  $catlinks
602  );
603  }
604 
619  protected function afterContentHook() {
620  $data = '';
621 
622  if ( Hooks::run( 'SkinAfterContent', [ &$data, $this ] ) ) {
623  // adding just some spaces shouldn't toggle the output
624  // of the whole <div/>, so we use trim() here
625  if ( trim( $data ) != '' ) {
626  // Doing this here instead of in the skins to
627  // ensure that the div has the same ID in all
628  // skins
629  $data = "<div id='mw-data-after-content'>\n" .
630  "\t$data\n" .
631  "</div>\n";
632  }
633  } else {
634  wfDebug( "Hook SkinAfterContent changed output processing.\n" );
635  }
636 
637  return $data;
638  }
639 
645  protected function generateDebugHTML() {
646  return MWDebug::getHTMLDebugLog();
647  }
648 
654  function bottomScripts() {
655  // TODO and the suckage continues. This function is really just a wrapper around
656  // OutputPage::getBottomScripts() which takes a Skin param. This should be cleaned
657  // up at some point
658  $bottomScriptText = $this->getOutput()->getBottomScripts();
659  Hooks::run( 'SkinAfterBottomScripts', [ $this, &$bottomScriptText ] );
660 
661  return $bottomScriptText;
662  }
663 
670  function printSource() {
671  $oldid = $this->getRevisionId();
672  if ( $oldid ) {
673  $canonicalUrl = $this->getTitle()->getCanonicalURL( 'oldid=' . $oldid );
674  $url = htmlspecialchars( wfExpandIRI( $canonicalUrl ) );
675  } else {
676  // oldid not available for non existing pages
677  $url = htmlspecialchars( wfExpandIRI( $this->getTitle()->getCanonicalURL() ) );
678  }
679 
680  return $this->msg( 'retrievedfrom' )
681  ->rawParams( '<a dir="ltr" href="' . $url . '">' . $url . '</a>' )
682  ->parse();
683  }
684 
688  function getUndeleteLink() {
689  $action = $this->getRequest()->getVal( 'action', 'view' );
690 
691  if ( $this->getTitle()->userCan( 'deletedhistory', $this->getUser() ) &&
692  ( !$this->getTitle()->exists() || $action == 'history' ) ) {
693  $n = $this->getTitle()->isDeleted();
694 
695  if ( $n ) {
696  if ( $this->getTitle()->quickUserCan( 'undelete', $this->getUser() ) ) {
697  $msg = 'thisisdeleted';
698  } else {
699  $msg = 'viewdeleted';
700  }
701 
702  return $this->msg( $msg )->rawParams(
704  SpecialPage::getTitleFor( 'Undelete', $this->getTitle()->getPrefixedDBkey() ),
705  $this->msg( 'restorelink' )->numParams( $n )->escaped() )
706  )->escaped();
707  }
708  }
709 
710  return '';
711  }
712 
717  function subPageSubtitle( $out = null ) {
718  if ( $out === null ) {
719  $out = $this->getOutput();
720  }
721  $title = $out->getTitle();
722  $subpages = '';
723 
724  if ( !Hooks::run( 'SkinSubPageSubtitle', [ &$subpages, $this, $out ] ) ) {
725  return $subpages;
726  }
727 
728  if ( $out->isArticle() && MWNamespace::hasSubpages( $title->getNamespace() ) ) {
729  $ptext = $title->getPrefixedText();
730  if ( strpos( $ptext, '/' ) !== false ) {
731  $links = explode( '/', $ptext );
732  array_pop( $links );
733  $c = 0;
734  $growinglink = '';
735  $display = '';
736  $lang = $this->getLanguage();
737 
738  foreach ( $links as $link ) {
739  $growinglink .= $link;
740  $display .= $link;
741  $linkObj = Title::newFromText( $growinglink );
742 
743  if ( is_object( $linkObj ) && $linkObj->isKnown() ) {
744  $getlink = Linker::linkKnown(
745  $linkObj,
746  htmlspecialchars( $display )
747  );
748 
749  $c++;
750 
751  if ( $c > 1 ) {
752  $subpages .= $lang->getDirMarkEntity() . $this->msg( 'pipe-separator' )->escaped();
753  } else {
754  $subpages .= '&lt; ';
755  }
756 
757  $subpages .= $getlink;
758  $display = '';
759  } else {
760  $display .= '/';
761  }
762  $growinglink .= '/';
763  }
764  }
765  }
766 
767  return $subpages;
768  }
769 
773  function getSearchLink() {
775  return $searchPage->getLocalURL();
776  }
777 
781  function escapeSearchLink() {
782  return htmlspecialchars( $this->getSearchLink() );
783  }
784 
789  function getCopyright( $type = 'detect' ) {
791 
792  if ( $type == 'detect' ) {
793  if ( !$this->isRevisionCurrent()
794  && !$this->msg( 'history_copyright' )->inContentLanguage()->isDisabled()
795  ) {
796  $type = 'history';
797  } else {
798  $type = 'normal';
799  }
800  }
801 
802  if ( $type == 'history' ) {
803  $msg = 'history_copyright';
804  } else {
805  $msg = 'copyright';
806  }
807 
808  if ( $wgRightsPage ) {
811  } elseif ( $wgRightsUrl ) {
813  } elseif ( $wgRightsText ) {
815  } else {
816  # Give up now
817  return '';
818  }
819 
820  // Allow for site and per-namespace customization of copyright notice.
821  // @todo Remove deprecated $forContent param from hook handlers and then remove here.
822  $forContent = true;
823 
824  Hooks::run(
825  'SkinCopyrightFooter',
826  [ $this->getTitle(), $type, &$msg, &$link, &$forContent ]
827  );
828 
829  return $this->msg( $msg )->rawParams( $link )->text();
830  }
831 
835  function getCopyrightIcon() {
837 
838  $out = '';
839 
840  if ( $wgFooterIcons['copyright']['copyright'] ) {
841  $out = $wgFooterIcons['copyright']['copyright'];
842  } elseif ( $wgRightsIcon ) {
843  $icon = htmlspecialchars( $wgRightsIcon );
844 
845  if ( $wgRightsUrl ) {
846  $url = htmlspecialchars( $wgRightsUrl );
847  $out .= '<a href="' . $url . '">';
848  }
849 
850  $text = htmlspecialchars( $wgRightsText );
851  $out .= "<img src=\"$icon\" alt=\"$text\" width=\"88\" height=\"31\" />";
852 
853  if ( $wgRightsUrl ) {
854  $out .= '</a>';
855  }
856  }
857 
858  return $out;
859  }
860 
865  function getPoweredBy() {
867 
868  $url1 = htmlspecialchars(
869  "$wgResourceBasePath/resources/assets/poweredby_mediawiki_88x31.png"
870  );
871  $url1_5 = htmlspecialchars(
872  "$wgResourceBasePath/resources/assets/poweredby_mediawiki_132x47.png"
873  );
874  $url2 = htmlspecialchars(
875  "$wgResourceBasePath/resources/assets/poweredby_mediawiki_176x62.png"
876  );
877  $text = '<a href="//www.mediawiki.org/"><img src="' . $url1
878  . '" srcset="' . $url1_5 . ' 1.5x, ' . $url2 . ' 2x" '
879  . 'height="31" width="88" alt="Powered by MediaWiki" /></a>';
880  Hooks::run( 'SkinGetPoweredBy', [ &$text, $this ] );
881  return $text;
882  }
883 
889  protected function lastModified() {
890  $timestamp = $this->getOutput()->getRevisionTimestamp();
891 
892  # No cached timestamp, load it from the database
893  if ( $timestamp === null ) {
894  $timestamp = Revision::getTimestampFromId( $this->getTitle(), $this->getRevisionId() );
895  }
896 
897  if ( $timestamp ) {
898  $d = $this->getLanguage()->userDate( $timestamp, $this->getUser() );
899  $t = $this->getLanguage()->userTime( $timestamp, $this->getUser() );
900  $s = ' ' . $this->msg( 'lastmodifiedat', $d, $t )->parse();
901  } else {
902  $s = '';
903  }
904 
905  if ( MediaWikiServices::getInstance()->getDBLoadBalancer()->getLaggedReplicaMode() ) {
906  $s .= ' <strong>' . $this->msg( 'laggedslavemode' )->parse() . '</strong>';
907  }
908 
909  return $s;
910  }
911 
916  function logoText( $align = '' ) {
917  if ( $align != '' ) {
918  $a = " style='float: {$align};'";
919  } else {
920  $a = '';
921  }
922 
923  $mp = $this->msg( 'mainpage' )->escaped();
924  $mptitle = Title::newMainPage();
925  $url = ( is_object( $mptitle ) ? htmlspecialchars( $mptitle->getLocalURL() ) : '' );
926 
927  $logourl = $this->getLogo();
928  $s = "<a href='{$url}'><img{$a} src='{$logourl}' alt='[{$mp}]' /></a>";
929 
930  return $s;
931  }
932 
941  function makeFooterIcon( $icon, $withImage = 'withImage' ) {
942  if ( is_string( $icon ) ) {
943  $html = $icon;
944  } else { // Assuming array
945  $url = isset( $icon["url"] ) ? $icon["url"] : null;
946  unset( $icon["url"] );
947  if ( isset( $icon["src"] ) && $withImage === 'withImage' ) {
948  // do this the lazy way, just pass icon data as an attribute array
949  $html = Html::element( 'img', $icon );
950  } else {
951  $html = htmlspecialchars( $icon["alt"] );
952  }
953  if ( $url ) {
955  $html = Html::rawElement( 'a',
956  [ "href" => $url, "target" => $wgExternalLinkTarget ],
957  $html );
958  }
959  }
960  return $html;
961  }
962 
967  function mainPageLink() {
970  $this->msg( 'mainpage' )->escaped()
971  );
972 
973  return $s;
974  }
975 
982  public function footerLink( $desc, $page ) {
983  $title = $this->footerLinkTitle( $desc, $page );
984  if ( !$title ) {
985  return '';
986  }
987 
988  return Linker::linkKnown(
989  $title,
990  $this->msg( $desc )->escaped()
991  );
992  }
993 
999  private function footerLinkTitle( $desc, $page ) {
1000  // If the link description has been set to "-" in the default language,
1001  if ( $this->msg( $desc )->inContentLanguage()->isDisabled() ) {
1002  // then it is disabled, for all languages.
1003  return null;
1004  }
1005  // Otherwise, we display the link for the user, described in their
1006  // language (which may or may not be the same as the default language),
1007  // but we make the link target be the one site-wide page.
1008  $title = Title::newFromText( $this->msg( $page )->inContentLanguage()->text() );
1009 
1010  return $title ?: null;
1011  }
1012 
1017  function privacyLink() {
1018  return $this->footerLink( 'privacy', 'privacypage' );
1019  }
1020 
1025  function aboutLink() {
1026  return $this->footerLink( 'aboutsite', 'aboutpage' );
1027  }
1028 
1033  function disclaimerLink() {
1034  return $this->footerLink( 'disclaimers', 'disclaimerpage' );
1035  }
1036 
1044  function editUrlOptions() {
1045  $options = [ 'action' => 'edit' ];
1046 
1047  if ( !$this->isRevisionCurrent() ) {
1048  $options['oldid'] = intval( $this->getRevisionId() );
1049  }
1050 
1051  return $options;
1052  }
1053 
1058  function showEmailUser( $id ) {
1059  if ( $id instanceof User ) {
1060  $targetUser = $id;
1061  } else {
1062  $targetUser = User::newFromId( $id );
1063  }
1064 
1065  # The sending user must have a confirmed email address and the receiving
1066  # user must accept emails from the sender.
1067  return $this->getUser()->canSendEmail()
1068  && SpecialEmailUser::validateTarget( $targetUser, $this->getUser() ) === '';
1069  }
1070 
1082  function getSkinStylePath( $name ) {
1084 
1085  if ( $this->stylename === null ) {
1086  $class = static::class;
1087  throw new MWException( "$class::\$stylename must be set to use getSkinStylePath()" );
1088  }
1089 
1090  return "$wgStylePath/{$this->stylename}/$name?$wgStyleVersion";
1091  }
1092 
1093  /* these are used extensively in SkinTemplate, but also some other places */
1094 
1099  static function makeMainPageUrl( $urlaction = '' ) {
1101  self::checkTitle( $title, '' );
1102 
1103  return $title->getLinkURL( $urlaction );
1104  }
1105 
1117  static function makeSpecialUrl( $name, $urlaction = '', $proto = null ) {
1119  if ( is_null( $proto ) ) {
1120  return $title->getLocalURL( $urlaction );
1121  } else {
1122  return $title->getFullURL( $urlaction, false, $proto );
1123  }
1124  }
1125 
1132  static function makeSpecialUrlSubpage( $name, $subpage, $urlaction = '' ) {
1133  $title = SpecialPage::getSafeTitleFor( $name, $subpage );
1134  return $title->getLocalURL( $urlaction );
1135  }
1136 
1142  static function makeI18nUrl( $name, $urlaction = '' ) {
1143  $title = Title::newFromText( wfMessage( $name )->inContentLanguage()->text() );
1145  return $title->getLocalURL( $urlaction );
1146  }
1147 
1153  static function makeUrl( $name, $urlaction = '' ) {
1156 
1157  return $title->getLocalURL( $urlaction );
1158  }
1159 
1166  static function makeInternalOrExternalUrl( $name ) {
1167  if ( preg_match( '/^(?i:' . wfUrlProtocols() . ')/', $name ) ) {
1168  return $name;
1169  } else {
1170  return self::makeUrl( $name );
1171  }
1172  }
1173 
1181  static function makeNSUrl( $name, $urlaction = '', $namespace = NS_MAIN ) {
1182  $title = Title::makeTitleSafe( $namespace, $name );
1184 
1185  return $title->getLocalURL( $urlaction );
1186  }
1187 
1194  static function makeUrlDetails( $name, $urlaction = '' ) {
1197 
1198  return [
1199  'href' => $title->getLocalURL( $urlaction ),
1200  'exists' => $title->isKnown(),
1201  ];
1202  }
1203 
1210  static function makeKnownUrlDetails( $name, $urlaction = '' ) {
1213 
1214  return [
1215  'href' => $title->getLocalURL( $urlaction ),
1216  'exists' => true
1217  ];
1218  }
1219 
1226  static function checkTitle( &$title, $name ) {
1227  if ( !is_object( $title ) ) {
1229  if ( !is_object( $title ) ) {
1230  $title = Title::newFromText( '--error: link target missing--' );
1231  }
1232  }
1233  }
1234 
1256  public function buildSidebar() {
1258 
1259  $callback = function ( $old = null, &$ttl = null ) {
1260  $bar = [];
1261  $this->addToSidebar( $bar, 'sidebar' );
1262  Hooks::run( 'SkinBuildSidebar', [ $this, &$bar ] );
1263  if ( MessageCache::singleton()->isDisabled() ) {
1264  $ttl = WANObjectCache::TTL_UNCACHEABLE; // bug T133069
1265  }
1266 
1267  return $bar;
1268  };
1269 
1270  $msgCache = MessageCache::singleton();
1271  $wanCache = MediaWikiServices::getInstance()->getMainWANObjectCache();
1272 
1273  $sidebar = $wgEnableSidebarCache
1274  ? $wanCache->getWithSetCallback(
1275  $wanCache->makeKey( 'sidebar', $this->getLanguage()->getCode() ),
1277  $callback,
1278  [
1279  'checkKeys' => [
1280  // Unless there is both no exact $code override nor an i18n definition
1281  // in the the software, the only MediaWiki page to check is for $code.
1282  $msgCache->getCheckKey( $this->getLanguage()->getCode() )
1283  ],
1284  'lockTSE' => 30
1285  ]
1286  )
1287  : $callback();
1288 
1289  // Apply post-processing to the cached value
1290  Hooks::run( 'SidebarBeforeOutput', [ $this, &$sidebar ] );
1291 
1292  return $sidebar;
1293  }
1294 
1304  public function addToSidebar( &$bar, $message ) {
1305  $this->addToSidebarPlain( $bar, wfMessage( $message )->inContentLanguage()->plain() );
1306  }
1307 
1315  function addToSidebarPlain( &$bar, $text ) {
1316  $lines = explode( "\n", $text );
1317 
1318  $heading = '';
1319  $messageTitle = $this->getConfig()->get( 'EnableSidebarCache' )
1320  ? Title::newMainPage() : $this->getTitle();
1321 
1322  foreach ( $lines as $line ) {
1323  if ( strpos( $line, '*' ) !== 0 ) {
1324  continue;
1325  }
1326  $line = rtrim( $line, "\r" ); // for Windows compat
1327 
1328  if ( strpos( $line, '**' ) !== 0 ) {
1329  $heading = trim( $line, '* ' );
1330  if ( !array_key_exists( $heading, $bar ) ) {
1331  $bar[$heading] = [];
1332  }
1333  } else {
1334  $line = trim( $line, '* ' );
1335 
1336  if ( strpos( $line, '|' ) !== false ) { // sanity check
1337  $line = MessageCache::singleton()->transform( $line, false, null, $messageTitle );
1338  $line = array_map( 'trim', explode( '|', $line, 2 ) );
1339  if ( count( $line ) !== 2 ) {
1340  // Second sanity check, could be hit by people doing
1341  // funky stuff with parserfuncs... (T35321)
1342  continue;
1343  }
1344 
1345  $extraAttribs = [];
1346 
1347  $msgLink = $this->msg( $line[0] )->title( $messageTitle )->inContentLanguage();
1348  if ( $msgLink->exists() ) {
1349  $link = $msgLink->text();
1350  if ( $link == '-' ) {
1351  continue;
1352  }
1353  } else {
1354  $link = $line[0];
1355  }
1356  $msgText = $this->msg( $line[1] )->title( $messageTitle );
1357  if ( $msgText->exists() ) {
1358  $text = $msgText->text();
1359  } else {
1360  $text = $line[1];
1361  }
1362 
1363  if ( preg_match( '/^(?i:' . wfUrlProtocols() . ')/', $link ) ) {
1364  $href = $link;
1365 
1366  // Parser::getExternalLinkAttribs won't work here because of the Namespace things
1369  $extraAttribs['rel'] = 'nofollow';
1370  }
1371 
1373  if ( $wgExternalLinkTarget ) {
1374  $extraAttribs['target'] = $wgExternalLinkTarget;
1375  }
1376  } else {
1378 
1379  if ( $title ) {
1380  $title = $title->fixSpecialName();
1381  $href = $title->getLinkURL();
1382  } else {
1383  $href = 'INVALID-TITLE';
1384  }
1385  }
1386 
1387  $bar[$heading][] = array_merge( [
1388  'text' => $text,
1389  'href' => $href,
1390  'id' => Sanitizer::escapeIdForAttribute( 'n-' . strtr( $line[1], ' ', '-' ) ),
1391  'active' => false,
1392  ], $extraAttribs );
1393  } else {
1394  continue;
1395  }
1396  }
1397  }
1398 
1399  return $bar;
1400  }
1401 
1407  function getNewtalks() {
1408  $newMessagesAlert = '';
1409  $user = $this->getUser();
1410  $newtalks = $user->getNewMessageLinks();
1411  $out = $this->getOutput();
1412 
1413  // Allow extensions to disable or modify the new messages alert
1414  if ( !Hooks::run( 'GetNewMessagesAlert', [ &$newMessagesAlert, $newtalks, $user, $out ] ) ) {
1415  return '';
1416  }
1417  if ( $newMessagesAlert ) {
1418  return $newMessagesAlert;
1419  }
1420 
1421  if ( count( $newtalks ) == 1 && $newtalks[0]['wiki'] === wfWikiID() ) {
1422  $uTalkTitle = $user->getTalkPage();
1423  $lastSeenRev = isset( $newtalks[0]['rev'] ) ? $newtalks[0]['rev'] : null;
1424  $nofAuthors = 0;
1425  if ( $lastSeenRev !== null ) {
1426  $plural = true; // Default if we have a last seen revision: if unknown, use plural
1427  $latestRev = Revision::newFromTitle( $uTalkTitle, false, Revision::READ_NORMAL );
1428  if ( $latestRev !== null ) {
1429  // Singular if only 1 unseen revision, plural if several unseen revisions.
1430  $plural = $latestRev->getParentId() !== $lastSeenRev->getId();
1431  $nofAuthors = $uTalkTitle->countAuthorsBetween(
1432  $lastSeenRev, $latestRev, 10, 'include_new' );
1433  }
1434  } else {
1435  // Singular if no revision -> diff link will show latest change only in any case
1436  $plural = false;
1437  }
1438  $plural = $plural ? 999 : 1;
1439  // 999 signifies "more than one revision". We don't know how many, and even if we did,
1440  // the number of revisions or authors is not necessarily the same as the number of
1441  // "messages".
1442  $newMessagesLink = Linker::linkKnown(
1443  $uTalkTitle,
1444  $this->msg( 'newmessageslinkplural' )->params( $plural )->escaped(),
1445  [],
1446  [ 'redirect' => 'no' ]
1447  );
1448 
1449  $newMessagesDiffLink = Linker::linkKnown(
1450  $uTalkTitle,
1451  $this->msg( 'newmessagesdifflinkplural' )->params( $plural )->escaped(),
1452  [],
1453  $lastSeenRev !== null
1454  ? [ 'oldid' => $lastSeenRev->getId(), 'diff' => 'cur' ]
1455  : [ 'diff' => 'cur' ]
1456  );
1457 
1458  if ( $nofAuthors >= 1 && $nofAuthors <= 10 ) {
1459  $newMessagesAlert = $this->msg(
1460  'youhavenewmessagesfromusers',
1461  $newMessagesLink,
1462  $newMessagesDiffLink
1463  )->numParams( $nofAuthors, $plural );
1464  } else {
1465  // $nofAuthors === 11 signifies "11 or more" ("more than 10")
1466  $newMessagesAlert = $this->msg(
1467  $nofAuthors > 10 ? 'youhavenewmessagesmanyusers' : 'youhavenewmessages',
1468  $newMessagesLink,
1469  $newMessagesDiffLink
1470  )->numParams( $plural );
1471  }
1472  $newMessagesAlert = $newMessagesAlert->text();
1473  # Disable CDN cache
1474  $out->setCdnMaxage( 0 );
1475  } elseif ( count( $newtalks ) ) {
1476  $sep = $this->msg( 'newtalkseparator' )->escaped();
1477  $msgs = [];
1478 
1479  foreach ( $newtalks as $newtalk ) {
1480  $msgs[] = Xml::element(
1481  'a',
1482  [ 'href' => $newtalk['link'] ], $newtalk['wiki']
1483  );
1484  }
1485  $parts = implode( $sep, $msgs );
1486  $newMessagesAlert = $this->msg( 'youhavenewmessagesmulti' )->rawParams( $parts )->escaped();
1487  $out->setCdnMaxage( 0 );
1488  }
1489 
1490  return $newMessagesAlert;
1491  }
1492 
1500  private function getCachedNotice( $name ) {
1502 
1503  $needParse = false;
1504 
1505  if ( $name === 'default' ) {
1506  // special case
1508  $notice = $wgSiteNotice;
1509  if ( empty( $notice ) ) {
1510  return false;
1511  }
1512  } else {
1513  $msg = $this->msg( $name )->inContentLanguage();
1514  if ( $msg->isBlank() ) {
1515  return '';
1516  } elseif ( $msg->isDisabled() ) {
1517  return false;
1518  }
1519  $notice = $msg->plain();
1520  }
1521 
1522  $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
1523  $parsed = $cache->getWithSetCallback(
1524  // Use the extra hash appender to let eg SSL variants separately cache
1525  // Key is verified with md5 hash of unparsed wikitext
1526  $cache->makeKey( $name, $wgRenderHashAppend, md5( $notice ) ),
1527  // TTL in seconds
1528  600,
1529  function () use ( $notice ) {
1530  return $this->getOutput()->parse( $notice );
1531  }
1532  );
1533 
1534  return Html::rawElement(
1535  'div',
1536  [
1537  'id' => 'localNotice',
1538  'lang' => $wgContLang->getHtmlCode(),
1539  'dir' => $wgContLang->getDir()
1540  ],
1541  $parsed
1542  );
1543  }
1544 
1550  function getSiteNotice() {
1551  $siteNotice = '';
1552 
1553  if ( Hooks::run( 'SiteNoticeBefore', [ &$siteNotice, $this ] ) ) {
1554  if ( is_object( $this->getUser() ) && $this->getUser()->isLoggedIn() ) {
1555  $siteNotice = $this->getCachedNotice( 'sitenotice' );
1556  } else {
1557  $anonNotice = $this->getCachedNotice( 'anonnotice' );
1558  if ( $anonNotice === false ) {
1559  $siteNotice = $this->getCachedNotice( 'sitenotice' );
1560  } else {
1561  $siteNotice = $anonNotice;
1562  }
1563  }
1564  if ( $siteNotice === false ) {
1565  $siteNotice = $this->getCachedNotice( 'default' );
1566  }
1567  }
1568 
1569  Hooks::run( 'SiteNoticeAfter', [ &$siteNotice, $this ] );
1570  return $siteNotice;
1571  }
1572 
1586  public function doEditSectionLink( Title $nt, $section, $tooltip = null, $lang = false ) {
1587  // HTML generated here should probably have userlangattributes
1588  // added to it for LTR text on RTL pages
1589 
1590  $lang = wfGetLangObj( $lang );
1591 
1592  $attribs = [];
1593  if ( !is_null( $tooltip ) ) {
1594  $attribs['title'] = wfMessage( 'editsectionhint' )->rawParams( $tooltip )
1595  ->inLanguage( $lang )->text();
1596  }
1597 
1598  $links = [
1599  'editsection' => [
1600  'text' => wfMessage( 'editsection' )->inLanguage( $lang )->escaped(),
1601  'targetTitle' => $nt,
1602  'attribs' => $attribs,
1603  'query' => [ 'action' => 'edit', 'section' => $section ],
1604  'options' => [ 'noclasses', 'known' ]
1605  ]
1606  ];
1607 
1608  Hooks::run( 'SkinEditSectionLinks', [ $this, $nt, $section, $tooltip, &$links, $lang ] );
1609 
1610  $result = '<span class="mw-editsection"><span class="mw-editsection-bracket">[</span>';
1611 
1612  $linksHtml = [];
1613  foreach ( $links as $k => $linkDetails ) {
1614  $linksHtml[] = Linker::link(
1615  $linkDetails['targetTitle'],
1616  $linkDetails['text'],
1617  $linkDetails['attribs'],
1618  $linkDetails['query'],
1619  $linkDetails['options']
1620  );
1621  }
1622 
1623  $result .= implode(
1624  '<span class="mw-editsection-divider">'
1625  . wfMessage( 'pipe-separator' )->inLanguage( $lang )->escaped()
1626  . '</span>',
1627  $linksHtml
1628  );
1629 
1630  $result .= '<span class="mw-editsection-bracket">]</span></span>';
1631  // Deprecated, use SkinEditSectionLinks hook instead
1632  Hooks::run(
1633  'DoEditSectionLink',
1634  [ $this, $nt, $section, $tooltip, &$result, $lang ],
1635  '1.25'
1636  );
1637  return $result;
1638  }
1639 
1640 }
$user
please add to it if you re going to add events to the MediaWiki code where normally authentication against an external auth plugin would be creating a account $user
Definition: hooks.txt:247
Skin\shouldPreloadLogo
shouldPreloadLogo()
Whether the logo should be preloaded with an HTTP link header or not.
Definition: Skin.php:486
Skin\$skinname
string null $skinname
Definition: Skin.php:40
ContextSource\getConfig
getConfig()
Definition: ContextSource.php:63
Skin\editUrlOptions
editUrlOptions()
Return URL options for the 'edit page' link.
Definition: Skin.php:1044
Skin\showEmailUser
showEmailUser( $id)
Definition: Skin.php:1058
User\newFromId
static newFromId( $id)
Static factory method for creation from a given user ID.
Definition: User.php:614
Title\newFromText
static newFromText( $text, $defaultNamespace=NS_MAIN)
Create a new Title from text, such as what one would find in a link.
Definition: Title.php:273
Skin\makeUrlDetails
static makeUrlDetails( $name, $urlaction='')
these return an array with the 'href' and boolean 'exists'
Definition: Skin.php:1194
Skin\getSiteNotice
getSiteNotice()
Get the site notice.
Definition: Skin.php:1550
$searchPage
$searchPage
Definition: opensearch_desc.php:81
WANObjectCache\TTL_UNCACHEABLE
const TTL_UNCACHEABLE
Idiom for getWithSetCallback() callbacks to avoid calling set()
Definition: WANObjectCache.php:151
ResourceLoader\makeConfigSetScript
static makeConfigSetScript(array $configuration)
Returns JS code which will set the MediaWiki configuration array to the given value.
Definition: ResourceLoader.php:1522
use
Apache License January AND DISTRIBUTION Definitions License shall mean the terms and conditions for use
Definition: APACHE-LICENSE-2.0.txt:10
$html
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:2013
Skin\footerLinkTitle
footerLinkTitle( $desc, $page)
Definition: Skin.php:999
LinkBatch
Class representing a list of titles The execute() method checks them all for existence and adds them ...
Definition: LinkBatch.php:34
Skin\doEditSectionLink
doEditSectionLink(Title $nt, $section, $tooltip=null, $lang=false)
Create a section edit link.
Definition: Skin.php:1586
$wgRightsText
$wgRightsText
If either $wgRightsUrl or $wgRightsPage is specified then this variable gives the text for the link.
Definition: DefaultSettings.php:7116
Skin\getPoweredBy
getPoweredBy()
Gets the powered by MediaWiki icon.
Definition: Skin.php:865
wfMessage
either a unescaped string or a HtmlArmor object after in associative array form externallinks including delete and has completed for all link tables whether this was an auto creation default is conds Array Extra conditions for the No matching items in log is displayed if loglist is empty msgKey Array If you want a nice box with a set this to the key of the message First element is the message additional optional elements are parameters for the key that are processed with wfMessage() -> params() ->parseAsBlock() - offset Set to overwrite offset parameter in $wgRequest set to '' to unset offset - wrap String Wrap the message in html(usually something like "&lt
plain
either a plain
Definition: hooks.txt:2056
$lang
if(!isset( $args[0])) $lang
Definition: testCompression.php:33
text
design txt This is a brief overview of the new design More thorough and up to date information is available on the documentation wiki at etc Handles the details of getting and saving to the user table of the and dealing with sessions and cookies OutputPage Encapsulates the entire HTML page that will be sent in response to any server request It is used by calling its functions to add text
Definition: design.txt:18
Sanitizer\escapeIdForAttribute
static escapeIdForAttribute( $id, $mode=self::ID_PRIMARY)
Given a section name or other user-generated or otherwise unsafe string, escapes it to be a valid HTM...
Definition: Sanitizer.php:1261
ContextSource\msg
msg( $key)
Get a Message object with context set Parameters are the same as wfMessage()
Definition: ContextSource.php:168
Title\newMainPage
static newMainPage()
Create a new Title for the Main Page.
Definition: Title.php:586
$fallback
$fallback
Definition: MessagesAb.php:11
Skin\lastModified
lastModified()
Get the timestamp of the latest revision, formatted in user language.
Definition: Skin.php:889
$wgNoFollowDomainExceptions
$wgNoFollowDomainExceptions
If this is set to an array of domains, external links to these domain names (or any subdomains) will ...
Definition: DefaultSettings.php:4380
Skin\checkTitle
static checkTitle(&$title, $name)
make sure we have some title to operate on
Definition: Skin.php:1226
$out
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 $out
Definition: hooks.txt:864
MWDebug\getHTMLDebugLog
static getHTMLDebugLog()
Generate debug log in HTML for displaying at the bottom of the main content area.
Definition: MWDebug.php:455
Skin\makeSpecialUrl
static makeSpecialUrl( $name, $urlaction='', $proto=null)
Make a URL for a Special Page using the given query and protocol.
Definition: Skin.php:1117
Skin\getCategoryLinks
getCategoryLinks()
Definition: Skin.php:493
Skin\aboutLink
aboutLink()
Gets the link to the wiki's about page.
Definition: Skin.php:1025
Skin\getDynamicStylesheetQuery
static getDynamicStylesheetQuery()
Get the query to generate a dynamic stylesheet.
Definition: Skin.php:397
Skin\makeSpecialUrlSubpage
static makeSpecialUrlSubpage( $name, $subpage, $urlaction='')
Definition: Skin.php:1132
User\newFromName
static newFromName( $name, $validate='valid')
Static factory method for creation from username.
Definition: User.php:591
Skin\addToBodyAttributes
addToBodyAttributes( $out, &$bodyAttrs)
This will be called by OutputPage::headElement when it is creating the "<body>" tag,...
Definition: Skin.php:468
Linker\linkKnown
static linkKnown( $target, $html=null, $customAttribs=[], $query=[], $options=[ 'known'])
Identical to link(), except $options defaults to 'known'.
Definition: Linker.php:164
$s
$s
Definition: mergeMessageFileList.php:187
SpecialPage\getTitleFor
static getTitleFor( $name, $subpage=false, $fragment='')
Get a localised Title object for a specified special page name If you don't need a full Title object,...
Definition: SpecialPage.php:82
Sanitizer\escapeClass
static escapeClass( $class)
Given a value, escape it so that it can be used as a CSS class and return it.
Definition: Sanitizer.php:1402
ContextSource\getRequest
getRequest()
Definition: ContextSource.php:71
$wgSidebarCacheExpiry
$wgSidebarCacheExpiry
Expiry time for the sidebar cache, in seconds.
Definition: DefaultSettings.php:2616
Skin\$mRelevantUser
$mRelevantUser
Definition: Skin.php:43
$result
The index of the header message $result[1]=The index of the body text message $result[2 through n]=Parameters passed to body text message. Please note the header message cannot receive/use parameters. 'ImgAuthModifyHeaders':Executed just before a file is streamed to a user via img_auth.php, allowing headers to be modified beforehand. $title:LinkTarget object & $headers:HTTP headers(name=> value, names are case insensitive). Two headers get special handling:If-Modified-Since(value must be a valid HTTP date) and Range(must be of the form "bytes=(\d*-\d*)") will be honored when streaming the file. 'ImportHandleLogItemXMLTag':When parsing a XML tag in a log item. Return false to stop further processing of the tag $reader:XMLReader object $logInfo:Array of information 'ImportHandlePageXMLTag':When parsing a XML tag in a page. Return false to stop further processing of the tag $reader:XMLReader object & $pageInfo:Array of information 'ImportHandleRevisionXMLTag':When parsing a XML tag in a page revision. Return false to stop further processing of the tag $reader:XMLReader object $pageInfo:Array of page information $revisionInfo:Array of revision information 'ImportHandleToplevelXMLTag':When parsing a top level XML tag. Return false to stop further processing of the tag $reader:XMLReader object 'ImportHandleUnknownUser':When a user doesn 't exist locally, this hook is called to give extensions an opportunity to auto-create it. If the auto-creation is successful, return false. $name:User name 'ImportHandleUploadXMLTag':When parsing a XML tag in a file upload. Return false to stop further processing of the tag $reader:XMLReader object $revisionInfo:Array of information 'ImportLogInterwikiLink':Hook to change the interwiki link used in log entries and edit summaries for transwiki imports. & $fullInterwikiPrefix:Interwiki prefix, may contain colons. & $pageTitle:String that contains page title. 'ImportSources':Called when reading from the $wgImportSources configuration variable. Can be used to lazy-load the import sources list. & $importSources:The value of $wgImportSources. Modify as necessary. See the comment in DefaultSettings.php for the detail of how to structure this array. 'InfoAction':When building information to display on the action=info page. $context:IContextSource object & $pageInfo:Array of information 'InitializeArticleMaybeRedirect':MediaWiki check to see if title is a redirect. & $title:Title object for the current page & $request:WebRequest & $ignoreRedirect:boolean to skip redirect check & $target:Title/string of redirect target & $article:Article object 'InternalParseBeforeLinks':during Parser 's internalParse method before links but after nowiki/noinclude/includeonly/onlyinclude and other processings. & $parser:Parser object & $text:string containing partially parsed text & $stripState:Parser 's internal StripState object 'InternalParseBeforeSanitize':during Parser 's internalParse method just before the parser removes unwanted/dangerous HTML tags and after nowiki/noinclude/includeonly/onlyinclude and other processings. Ideal for syntax-extensions after template/parser function execution which respect nowiki and HTML-comments. & $parser:Parser object & $text:string containing partially parsed text & $stripState:Parser 's internal StripState object 'InterwikiLoadPrefix':When resolving if a given prefix is an interwiki or not. Return true without providing an interwiki to continue interwiki search. $prefix:interwiki prefix we are looking for. & $iwData:output array describing the interwiki with keys iw_url, iw_local, iw_trans and optionally iw_api and iw_wikiid. 'InvalidateEmailComplete':Called after a user 's email has been invalidated successfully. $user:user(object) whose email is being invalidated 'IRCLineURL':When constructing the URL to use in an IRC notification. Callee may modify $url and $query, URL will be constructed as $url . $query & $url:URL to index.php & $query:Query string $rc:RecentChange object that triggered url generation 'IsFileCacheable':Override the result of Article::isFileCacheable()(if true) & $article:article(object) being checked 'IsTrustedProxy':Override the result of IP::isTrustedProxy() & $ip:IP being check & $result:Change this value to override the result of IP::isTrustedProxy() 'IsUploadAllowedFromUrl':Override the result of UploadFromUrl::isAllowedUrl() $url:URL used to upload from & $allowed:Boolean indicating if uploading is allowed for given URL 'isValidEmailAddr':Override the result of Sanitizer::validateEmail(), for instance to return false if the domain name doesn 't match your organization. $addr:The e-mail address entered by the user & $result:Set this and return false to override the internal checks 'isValidPassword':Override the result of User::isValidPassword() $password:The password entered by the user & $result:Set this and return false to override the internal checks $user:User the password is being validated for 'Language::getMessagesFileName':$code:The language code or the language we 're looking for a messages file for & $file:The messages file path, you can override this to change the location. 'LanguageGetMagic':DEPRECATED! Use $magicWords in a file listed in $wgExtensionMessagesFiles instead. Use this to define synonyms of magic words depending of the language & $magicExtensions:associative array of magic words synonyms $lang:language code(string) 'LanguageGetNamespaces':Provide custom ordering for namespaces or remove namespaces. Do not use this hook to add namespaces. Use CanonicalNamespaces for that. & $namespaces:Array of namespaces indexed by their numbers 'LanguageGetSpecialPageAliases':DEPRECATED! Use $specialPageAliases in a file listed in $wgExtensionMessagesFiles instead. Use to define aliases of special pages names depending of the language & $specialPageAliases:associative array of magic words synonyms $lang:language code(string) 'LanguageGetTranslatedLanguageNames':Provide translated language names. & $names:array of language code=> language name $code:language of the preferred translations 'LanguageLinks':Manipulate a page 's language links. This is called in various places to allow extensions to define the effective language links for a page. $title:The page 's Title. & $links:Array with elements of the form "language:title" in the order that they will be output. & $linkFlags:Associative array mapping prefixed links to arrays of flags. Currently unused, but planned to provide support for marking individual language links in the UI, e.g. for featured articles. 'LanguageSelector':Hook to change the language selector available on a page. $out:The output page. $cssClassName:CSS class name of the language selector. 'LinkBegin':DEPRECATED! Use HtmlPageLinkRendererBegin instead. Used when generating internal and interwiki links in Linker::link(), before processing starts. Return false to skip default processing and return $ret. See documentation for Linker::link() for details on the expected meanings of parameters. $skin:the Skin object $target:the Title that the link is pointing to & $html:the contents that the< a > tag should have(raw HTML) $result
Definition: hooks.txt:1993
ContextSource\getUser
getUser()
Definition: ContextSource.php:120
ContextSource\getTitle
getTitle()
Definition: ContextSource.php:79
wfExpandIRI
wfExpandIRI( $url)
Take a URL, make sure it's expanded to fully qualified, and replace any encoded non-ASCII Unicode cha...
Definition: GlobalFunctions.php:883
$wgLogo
$wgLogo
The URL path of the wiki logo.
Definition: DefaultSettings.php:282
Skin\makeI18nUrl
static makeI18nUrl( $name, $urlaction='')
Definition: Skin.php:1142
Skin\getHtmlElementAttributes
getHtmlElementAttributes()
Return values for <html> element.
Definition: Skin.php:452
true
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 true
Definition: hooks.txt:2006
$wgStylePath
$wgStylePath
The URL path of the skins directory.
Definition: DefaultSettings.php:221
php
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency which acts as the top level factory for services in MediaWiki which can be used to gain access to default instances of various services MediaWikiServices however also allows new services to be defined and default services to be redefined Services are defined or redefined by providing a callback the instantiator that will return a new instance of the service When it will create an instance of MediaWikiServices and populate it with the services defined in the files listed by thereby bootstrapping the DI framework Per $wgServiceWiringFiles lists includes ServiceWiring php
Definition: injection.txt:37
Skin\bottomScripts
bottomScripts()
This gets called shortly before the "</body>" tag.
Definition: Skin.php:654
Skin\mainPageLink
mainPageLink()
Gets the link to the wiki's main page.
Definition: Skin.php:967
Skin\getSkinNames
static getSkinNames()
Fetch the set of available skins.
Definition: Skin.php:55
Skin\afterContentHook
afterContentHook()
This runs a hook to allow extensions placing their stuff after content and article metadata (e....
Definition: Skin.php:619
ContextSource\getLanguage
getLanguage()
Definition: ContextSource.php:128
SpecialPage\getSafeTitleFor
static getSafeTitleFor( $name, $subpage=false)
Get a localised Title object for a page name with a possibly unvalidated subpage.
Definition: SpecialPage.php:110
NS_MAIN
const NS_MAIN
Definition: Defines.php:74
Skin\getCachedNotice
getCachedNotice( $name)
Get a cached notice.
Definition: Skin.php:1500
Revision\newFromTitle
static newFromTitle(LinkTarget $linkTarget, $id=0, $flags=0)
Load either the current, or a specified, revision that's attached to a given link target.
Definition: Revision.php:133
$newtalks
the value of this variable comes from LanguageConverter indexed by page_id indexed by prefixed DB keys can modify can modify can modify this should be populated with an alert message to that effect $newtalks
Definition: hooks.txt:1729
$wgRightsPage
$wgRightsPage
Override for copyright metadata.
Definition: DefaultSettings.php:7101
MWException
MediaWiki exception.
Definition: MWException.php:26
Skin\buildSidebar
buildSidebar()
Build an array that represents the sidebar(s), the navigation bar among them.
Definition: Skin.php:1256
Skin\privacyLink
privacyLink()
Gets the link to the wiki's privacy policy page.
Definition: Skin.php:1017
$titles
linkcache txt The LinkCache class maintains a list of article titles and the information about whether or not the article exists in the database This is used to mark up links when displaying a page If the same link appears more than once on any page then it only has to be looked up once In most cases link lookups are done in batches with the LinkBatch class or the equivalent in so the link cache is mostly useful for short snippets of parsed and for links in the navigation areas of the skin The link cache was formerly used to track links used in a document for the purposes of updating the link tables This application is now deprecated To create a you can use the following $titles
Definition: linkcache.txt:17
$wgFooterIcons
$wgFooterIcons
Abstract list of footer icons for skins in place of old copyrightico and poweredbyico code You can ad...
Definition: DefaultSettings.php:3457
Skin\getSkinNameMessages
static getSkinNameMessages()
Fetch the skinname messages for available skins.
Definition: Skin.php:63
Skin\normalizeKey
static normalizeKey( $key)
Normalize a skin preference value to a form that can be loaded.
Definition: Skin.php:99
Skin\footerLink
footerLink( $desc, $page)
Returns an HTML link for use in the footer.
Definition: Skin.php:982
Skin\generateDebugHTML
generateDebugHTML()
Generate debug data HTML for displaying at the bottom of the main content area.
Definition: Skin.php:645
Revision\getTimestampFromId
static getTimestampFromId( $title, $id, $flags=0)
Get rev_timestamp from rev_id, without loading the rest of the row.
Definition: Revision.php:1225
$wgFallbackSkin
$wgFallbackSkin
Fallback skin used when the skin defined by $wgDefaultSkin can't be found.
Definition: DefaultSettings.php:3286
Skin\$stylename
string $stylename
Stylesheets set to use.
Definition: Skin.php:49
Skin\getCategories
getCategories()
Definition: Skin.php:584
Skin\setRelevantUser
setRelevantUser( $u)
Set the "relevant" user.
Definition: Skin.php:335
$wgEnableSidebarCache
$wgEnableSidebarCache
If on, the sidebar navigation links are cached for users with the current language set.
Definition: DefaultSettings.php:2611
ContextSource\getOutput
getOutput()
Definition: ContextSource.php:112
$wgStyleVersion
$wgStyleVersion
Bump this number when changing the global style sheets and JavaScript.
Definition: DefaultSettings.php:2573
ContextSource
The simplest way of implementing IContextSource is to hold a RequestContext as a member variable and ...
Definition: ContextSource.php:29
$modules
$modules
Definition: HTMLFormElement.php:12
Skin\addToSidebar
addToSidebar(&$bar, $message)
Add content from a sidebar system message Currently only used for MediaWiki:Sidebar (but may be used ...
Definition: Skin.php:1304
Xml\element
static element( $element, $attribs=null, $contents='', $allowShortTag=true)
Format an XML element with given attributes and, optionally, text content.
Definition: Xml.php:39
User\isIP
static isIP( $name)
Does the string match an anonymous IP address?
Definition: User.php:943
Skin\isRevisionCurrent
isRevisionCurrent()
Whether the revision displayed is the latest revision of the page.
Definition: Skin.php:299
wfGetLangObj
wfGetLangObj( $langcode=false)
Return a Language object from $langcode.
Definition: GlobalFunctions.php:1306
MWNamespace\hasSubpages
static hasSubpages( $index)
Does the namespace allow subpages?
Definition: MWNamespace.php:368
Skin\drawCategoryBrowser
drawCategoryBrowser( $tree)
Render the array as a series of links.
Definition: Skin.php:561
Skin\makeNSUrl
static makeNSUrl( $name, $urlaction='', $namespace=NS_MAIN)
this can be passed the NS number as defined in Language.php
Definition: Skin.php:1181
$lines
$lines
Definition: router.php:61
$link
usually copyright or history_copyright This message must be in HTML not wikitext & $link
Definition: hooks.txt:3021
Skin\preloadExistence
preloadExistence()
Preload the existence of three commonly-requested pages in a single query.
Definition: Skin.php:245
$title
namespace and then decline to actually register it file or subcat img or subcat $title
Definition: hooks.txt:964
Linker\makeExternalLink
static makeExternalLink( $url, $text, $escape=true, $linktype='', $attribs=[], $title=null)
Make an external link.
Definition: Linker.php:843
$wgUseCategoryBrowser
$wgUseCategoryBrowser
Use experimental, DMOZ-like category browser.
Definition: DefaultSettings.php:7599
$wgDefaultSkin
$wgDefaultSkin
Default skin, for new users and anonymous visitors.
Definition: DefaultSettings.php:3279
global
when a variable name is used in a it is silently declared as a new masking the global
Definition: design.txt:95
NS_CATEGORY
const NS_CATEGORY
Definition: Defines.php:88
Skin\disclaimerLink
disclaimerLink()
Gets the link to the wiki's general disclaimers page.
Definition: Skin.php:1033
$wgExternalLinkTarget
$wgExternalLinkTarget
Set a default target for external links, e.g.
Definition: DefaultSettings.php:4351
Skin\getLogo
getLogo()
URL to the logo.
Definition: Skin.php:476
wfDebug
wfDebug( $text, $dest='all', array $context=[])
Sends a line to the debug log if enabled or, optionally, to a comment in output.
Definition: GlobalFunctions.php:994
OutputPage
This class should be covered by a general architecture document which does not exist as of January 20...
Definition: OutputPage.php:45
list
deferred txt A few of the database updates required by various functions here can be deferred until after the result page is displayed to the user For updating the view updating the linked to tables after a etc PHP does not yet have any way to tell the server to actually return and disconnect while still running these but it might have such a feature in the future We handle these by creating a deferred update object and putting those objects on a global list
Definition: deferred.txt:11
Skin\outputPage
outputPage(OutputPage $out=null)
Outputs the HTML generated by other functions.
MessageCache\singleton
static singleton()
Get the signleton instance of this class.
Definition: MessageCache.php:113
Skin\$mRelevantTitle
$mRelevantTitle
Definition: Skin.php:42
$options
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped & $options
Definition: hooks.txt:2001
wfUrlProtocols
wfUrlProtocols( $includeProtocolRelative=true)
Returns a regular expression of url protocols.
Definition: GlobalFunctions.php:727
$line
$line
Definition: cdb.php:59
$attribs
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped noclasses just before the function returns a value If you return an< a > element with HTML attributes $attribs and contents $html will be returned If you return $ret will be returned and may include noclasses after processing & $attribs
Definition: hooks.txt:2014
Title\makeTitleSafe
static makeTitleSafe( $ns, $title, $fragment='', $interwiki='')
Create a new Title from a namespace index and a DB key.
Definition: Title.php:562
wfWikiID
wfWikiID()
Get an ASCII string identifying this wiki This is used as a prefix in memcached keys.
Definition: GlobalFunctions.php:2763
Skin\getRelevantTitle
getRelevantTitle()
Return the "relevant" title.
Definition: Skin.php:323
Skin\getSkinStylePath
getSkinStylePath( $name)
Return a fully resolved style path url to images or styles stored in the current skins's folder.
Definition: Skin.php:1082
Skin\getPageClasses
getPageClasses( $title)
TODO: document.
Definition: Skin.php:424
$wgNoFollowLinks
$wgNoFollowLinks
If true, external URL links in wiki text will be given the rel="nofollow" attribute as a hint to sear...
Definition: DefaultSettings.php:4359
Skin\getDefaultModules
getDefaultModules()
Defines the ResourceLoader modules that should be added to the skin It is recommended that skins wish...
Definition: Skin.php:173
Skin\getSearchLink
getSearchLink()
Definition: Skin.php:773
SpecialEmailUser\validateTarget
static validateTarget( $target, User $sender=null)
Validate target User.
Definition: SpecialEmailuser.php:218
Linker\link
static link( $target, $html=null, $customAttribs=[], $query=[], $options=[])
This function returns an HTML link to the given target.
Definition: Linker.php:107
Skin\printSource
printSource()
Text with the permalink to the source page, usually shown on the footer of a printed page.
Definition: Skin.php:670
$wgRightsIcon
$wgRightsIcon
Override for copyright metadata.
Definition: DefaultSettings.php:7121
SpecialPageFactory\resolveAlias
static resolveAlias( $alias)
Given a special page name with a possible subpage, return an array where the first element is the spe...
Definition: SpecialPageFactory.php:328
Skin\makeVariablesScript
static makeVariablesScript( $data)
Definition: Skin.php:382
$wgResourceBasePath
$wgResourceBasePath
The default 'remoteBasePath' value for instances of ResourceLoaderFileModule.
Definition: DefaultSettings.php:3660
Skin\logoText
logoText( $align='')
Definition: Skin.php:916
Skin\getNewtalks
getNewtalks()
Gets new talk page messages for the current user and returns an appropriate alert message (or an empt...
Definition: Skin.php:1407
Title
Represents a title within MediaWiki.
Definition: Title.php:39
$name
Allows to change the fields on the form that will be generated $name
Definition: hooks.txt:302
Skin\makeUrl
static makeUrl( $name, $urlaction='')
Definition: Skin.php:1153
wfMatchesDomainList
wfMatchesDomainList( $url, $domains)
Check whether a given URL has a domain that occurs in a given set of domains.
Definition: GlobalFunctions.php:960
$cache
$cache
Definition: mcc.php:33
$section
usually copyright or history_copyright This message must be in HTML not wikitext if the section is included from a template $section
Definition: hooks.txt:3022
Skin\escapeSearchLink
escapeSearchLink()
Definition: Skin.php:781
$wgEnableWriteAPI
$wgEnableWriteAPI
Allow the API to be used to perform write operations (page edits, rollback, etc.) when an authorised ...
Definition: DefaultSettings.php:8047
as
This document is intended to provide useful advice for parties seeking to redistribute MediaWiki to end users It s targeted particularly at maintainers for Linux since it s been observed that distribution packages of MediaWiki often break We ve consistently had to recommend that users seeking support use official tarballs instead of their distribution s and this often solves whatever problem the user is having It would be nice if this could such as
Definition: distributors.txt:22
Skin\getCopyright
getCopyright( $type='detect')
Definition: Skin.php:789
Html\rawElement
static rawElement( $element, $attribs=[], $contents='')
Returns an HTML element in a string.
Definition: Html.php:209
$wgSiteNotice
$wgSiteNotice
Site notice shown at the top of each page.
Definition: DefaultSettings.php:3268
Skin\getRelevantUser
getRelevantUser()
Return the "relevant" user.
Definition: Skin.php:347
Skin\subPageSubtitle
subPageSubtitle( $out=null)
Definition: Skin.php:717
$wgRenderHashAppend
$wgRenderHashAppend
Append a configured value to the parser cache and the sitenotice key so that they can be kept separat...
Definition: DefaultSettings.php:2600
NS_USER
const NS_USER
Definition: Defines.php:76
Skin\getUndeleteLink
getUndeleteLink()
Definition: Skin.php:688
Skin\makeKnownUrlDetails
static makeKnownUrlDetails( $name, $urlaction='')
Make URL details where the article exists (or at least it's convenient to think so)
Definition: Skin.php:1210
$wgSkipSkins
$wgSkipSkins
Specify the names of skins that should not be presented in the list of available skins in user prefer...
Definition: DefaultSettings.php:3293
Skin\setupSkinUserCss
setupSkinUserCss(OutputPage $out)
Add skin specific stylesheets Calling this method with an $out of anything but the same OutputPage in...
Skin\makeMainPageUrl
static makeMainPageUrl( $urlaction='')
Definition: Skin.php:1099
class
you have access to all of the normal MediaWiki so you can get a DB use the etc For full docs on the Maintenance class
Definition: maintenance.txt:56
$t
$t
Definition: testCompression.php:69
Skin\getCopyrightIcon
getCopyrightIcon()
Definition: Skin.php:835
Html\element
static element( $element, $attribs=[], $contents='')
Identical to rawElement(), but HTML-escapes $contents (like Xml::element()).
Definition: Html.php:231
Skin\getSkinName
getSkinName()
Definition: Skin.php:153
MediaWikiServices
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency MediaWikiServices
Definition: injection.txt:25
Skin\getAllowedSkins
static getAllowedSkins()
Fetch the list of user-selectable skins in regards to $wgSkipSkins.
Definition: Skin.php:78
Skin
The main skin class which provides methods and properties for all other skins.
Definition: Skin.php:36
$wgEnableAPI
$wgEnableAPI
Enable the MediaWiki API for convenient access to machine-readable data via api.php.
Definition: DefaultSettings.php:8038
Skin\initPage
initPage(OutputPage $out)
Definition: Skin.php:160
Skin\setRelevantTitle
setRelevantTitle( $t)
Set the "relevant" title.
Definition: Skin.php:309
User
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
Definition: User.php:53
$wgUseAjax
$wgUseAjax
Enable AJAX framework.
Definition: DefaultSettings.php:8190
Hooks\run
static run( $event, array $args=[], $deprecatedVersion=null)
Call hook functions defined in Hooks::register and $wgHooks.
Definition: Hooks.php:203
Skin\getRevisionId
getRevisionId()
Get the current revision ID.
Definition: Skin.php:290
Skin\addToSidebarPlain
addToSidebarPlain(&$bar, $text)
Add content from plain text.
Definition: Skin.php:1315
$messages
$messages
Definition: LogTests.i18n.php:8
SkinFactory\getDefaultInstance
static getDefaultInstance()
Definition: SkinFactory.php:50
ResourceLoader\makeInlineScript
static makeInlineScript( $script)
Returns an HTML script tag that runs given JS code after startup and base modules.
Definition: ResourceLoader.php:1506
Skin\__construct
__construct( $skinname=null)
Definition: Skin.php:144
$wgSquidMaxage
$wgSquidMaxage
Cache TTL for the CDN sent as s-maxage (without ESI) or Surrogate-Control (with ESI).
Definition: DefaultSettings.php:2722
Skin\makeInternalOrExternalUrl
static makeInternalOrExternalUrl( $name)
If url string starts with http, consider as external URL, else internal.
Definition: Skin.php:1166
$wgRightsUrl
$wgRightsUrl
Set this to specify an external URL containing details about the content license used on your wiki.
Definition: DefaultSettings.php:7108
$wgContLang
this class mediates it Skin Encapsulates a look and feel for the wiki All of the functions that render HTML and make choices about how to render it are here and are called from various other places when and is meant to be subclassed with other skins that may override some of its functions The User object contains a reference to a and so rather than having a global skin object we just rely on the global User and get the skin with $wgUser and also has some character encoding functions and other locale stuff The current user interface language is instantiated as and the content language as $wgContLang
Definition: design.txt:57
Skin\makeFooterIcon
makeFooterIcon( $icon, $withImage='withImage')
Renders a $wgFooterIcons icon according to the method's arguments.
Definition: Skin.php:941
$type
$type
Definition: testCompression.php:48