MediaWiki  1.27.2
Skin.php
Go to the documentation of this file.
1 <?php
34 abstract class Skin extends ContextSource {
35  protected $skinname = null;
36  protected $mRelevantTitle = null;
37  protected $mRelevantUser = null;
38 
43  public $stylename = null;
44 
49  static function getSkinNames() {
50  return SkinFactory::getDefaultInstance()->getSkinNames();
51  }
52 
57  static function getSkinNameMessages() {
58  $messages = [];
59  foreach ( self::getSkinNames() as $skinKey => $skinName ) {
60  $messages[] = "skinname-$skinKey";
61  }
62  return $messages;
63  }
64 
72  public static function getAllowedSkins() {
74 
75  $allowedSkins = self::getSkinNames();
76 
77  foreach ( $wgSkipSkins as $skip ) {
78  unset( $allowedSkins[$skip] );
79  }
80 
81  return $allowedSkins;
82  }
83 
93  static function normalizeKey( $key ) {
95 
96  $skinNames = Skin::getSkinNames();
97 
98  // Make keys lowercase for case-insensitive matching.
99  $skinNames = array_change_key_case( $skinNames, CASE_LOWER );
100  $key = strtolower( $key );
101  $defaultSkin = strtolower( $wgDefaultSkin );
102  $fallbackSkin = strtolower( $wgFallbackSkin );
103 
104  if ( $key == '' || $key == 'default' ) {
105  // Don't return the default immediately;
106  // in a misconfiguration we need to fall back.
107  $key = $defaultSkin;
108  }
109 
110  if ( isset( $skinNames[$key] ) ) {
111  return $key;
112  }
113 
114  // Older versions of the software used a numeric setting
115  // in the user preferences.
116  $fallback = [
117  0 => $defaultSkin,
118  2 => 'cologneblue'
119  ];
120 
121  if ( isset( $fallback[$key] ) ) {
122  $key = $fallback[$key];
123  }
124 
125  if ( isset( $skinNames[$key] ) ) {
126  return $key;
127  } elseif ( isset( $skinNames[$defaultSkin] ) ) {
128  return $defaultSkin;
129  } else {
130  return $fallbackSkin;
131  }
132  }
133 
137  public function getSkinName() {
138  return $this->skinname;
139  }
140 
144  function initPage( OutputPage $out ) {
145 
146  $this->preloadExistence();
147 
148  }
149 
156  public function getDefaultModules() {
157  global $wgUseAjax, $wgEnableAPI, $wgEnableWriteAPI;
158 
159  $out = $this->getOutput();
160  $user = $out->getUser();
161  $modules = [
162  // modules that enhance the page content in some way
163  'content' => [
164  'mediawiki.page.ready',
165  ],
166  // modules that exist for legacy reasons
168  // modules relating to search functionality
169  'search' => [],
170  // modules relating to functionality relating to watching an article
171  'watch' => [],
172  // modules which relate to the current users preferences
173  'user' => [],
174  ];
175 
176  // Add various resources if required
177  if ( $wgUseAjax && $wgEnableAPI ) {
178  if ( $wgEnableWriteAPI && $user->isLoggedIn()
179  && $user->isAllowedAll( 'writeapi', 'viewmywatchlist', 'editmywatchlist' )
180  && $this->getRelevantTitle()->canExist()
181  ) {
182  $modules['watch'][] = 'mediawiki.page.watch.ajax';
183  }
184 
185  $modules['search'][] = 'mediawiki.searchSuggest';
186  }
187 
188  if ( $user->getBoolOption( 'editsectiononrightclick' ) ) {
189  $modules['user'][] = 'mediawiki.action.view.rightClickEdit';
190  }
191 
192  // Crazy edit-on-double-click stuff
193  if ( $out->isArticle() && $user->getOption( 'editondblclick' ) ) {
194  $modules['user'][] = 'mediawiki.action.view.dblClickEdit';
195  }
196  return $modules;
197  }
198 
202  function preloadExistence() {
203  $titles = [];
204 
205  $user = $this->getUser();
206  $title = $this->getRelevantTitle();
207 
208  // User/talk link
209  if ( $user->isLoggedIn() ) {
210  $titles[] = $user->getUserPage();
211  $titles[] = $user->getTalkPage();
212  }
213 
214  // Check, if the page can hold some kind of content, otherwise do nothing
215  if ( !$title->canExist() ) {
216  // nothing
217  } elseif ( $title->isTalkPage() ) {
218  $titles[] = $title->getSubjectPage();
219  } else {
220  $titles[] = $title->getTalkPage();
221  }
222 
223  Hooks::run( 'SkinPreloadExistence', [ &$titles, $this ] );
224 
225  if ( count( $titles ) ) {
226  $lb = new LinkBatch( $titles );
227  $lb->setCaller( __METHOD__ );
228  $lb->execute();
229  }
230  }
231 
237  public function getRevisionId() {
238  return $this->getOutput()->getRevisionId();
239  }
240 
246  public function isRevisionCurrent() {
247  $revID = $this->getRevisionId();
248  return $revID == 0 || $revID == $this->getTitle()->getLatestRevID();
249  }
250 
256  public function setRelevantTitle( $t ) {
257  $this->mRelevantTitle = $t;
258  }
259 
270  public function getRelevantTitle() {
271  if ( isset( $this->mRelevantTitle ) ) {
272  return $this->mRelevantTitle;
273  }
274  return $this->getTitle();
275  }
276 
282  public function setRelevantUser( $u ) {
283  $this->mRelevantUser = $u;
284  }
285 
294  public function getRelevantUser() {
295  if ( isset( $this->mRelevantUser ) ) {
296  return $this->mRelevantUser;
297  }
298  $title = $this->getRelevantTitle();
299  if ( $title->hasSubjectNamespace( NS_USER ) ) {
300  $rootUser = $title->getRootText();
301  if ( User::isIP( $rootUser ) ) {
302  $this->mRelevantUser = User::newFromName( $rootUser, false );
303  } else {
304  $user = User::newFromName( $rootUser, false );
305 
306  if ( $user ) {
307  $user->load( User::READ_NORMAL );
308 
309  if ( $user->isLoggedIn() ) {
310  $this->mRelevantUser = $user;
311  }
312  }
313  }
314  return $this->mRelevantUser;
315  }
316  return null;
317  }
318 
323  abstract function outputPage( OutputPage $out = null );
324 
329  static function makeVariablesScript( $data ) {
330  if ( $data ) {
333  );
334  } else {
335  return '';
336  }
337  }
338 
344  public static function getDynamicStylesheetQuery() {
346 
347  return [
348  'action' => 'raw',
349  'maxage' => $wgSquidMaxage,
350  'usemsgcache' => 'yes',
351  'ctype' => 'text/css',
352  'smaxage' => $wgSquidMaxage,
353  ];
354  }
355 
364  abstract function setupSkinUserCss( OutputPage $out );
365 
371  function getPageClasses( $title ) {
372  $numeric = 'ns-' . $title->getNamespace();
373 
374  if ( $title->isSpecialPage() ) {
375  $type = 'ns-special';
376  // bug 23315: provide a class based on the canonical special page name without subpages
377  list( $canonicalName ) = SpecialPageFactory::resolveAlias( $title->getDBkey() );
378  if ( $canonicalName ) {
379  $type .= ' ' . Sanitizer::escapeClass( "mw-special-$canonicalName" );
380  } else {
381  $type .= ' mw-invalidspecialpage';
382  }
383  } elseif ( $title->isTalkPage() ) {
384  $type = 'ns-talk';
385  } else {
386  $type = 'ns-subject';
387  }
388 
389  $name = Sanitizer::escapeClass( 'page-' . $title->getPrefixedText() );
390  $root = Sanitizer::escapeClass( 'rootpage-' . $title->getRootTitle()->getPrefixedText() );
391 
392  return "$numeric $type $name $root";
393  }
394 
399  public function getHtmlElementAttributes() {
400  $lang = $this->getLanguage();
401  return [
402  'lang' => $lang->getHtmlCode(),
403  'dir' => $lang->getDir(),
404  'class' => 'client-nojs',
405  ];
406  }
407 
415  function addToBodyAttributes( $out, &$bodyAttrs ) {
416  // does nothing by default
417  }
418 
423  function getLogo() {
424  global $wgLogo;
425  return $wgLogo;
426  }
427 
431  function getCategoryLinks() {
432  global $wgUseCategoryBrowser;
433 
434  $out = $this->getOutput();
435  $allCats = $out->getCategoryLinks();
436 
437  if ( !count( $allCats ) ) {
438  return '';
439  }
440 
441  $embed = "<li>";
442  $pop = "</li>";
443 
444  $s = '';
445  $colon = $this->msg( 'colon-separator' )->escaped();
446 
447  if ( !empty( $allCats['normal'] ) ) {
448  $t = $embed . implode( "{$pop}{$embed}", $allCats['normal'] ) . $pop;
449 
450  $msg = $this->msg( 'pagecategories' )->numParams( count( $allCats['normal'] ) )->escaped();
451  $linkPage = wfMessage( 'pagecategorieslink' )->inContentLanguage()->text();
452  $title = Title::newFromText( $linkPage );
453  $link = $title ? Linker::link( $title, $msg ) : $msg;
454  $s .= '<div id="mw-normal-catlinks" class="mw-normal-catlinks">' .
455  $link . $colon . '<ul>' . $t . '</ul>' . '</div>';
456  }
457 
458  # Hidden categories
459  if ( isset( $allCats['hidden'] ) ) {
460  if ( $this->getUser()->getBoolOption( 'showhiddencats' ) ) {
461  $class = ' mw-hidden-cats-user-shown';
462  } elseif ( $this->getTitle()->getNamespace() == NS_CATEGORY ) {
463  $class = ' mw-hidden-cats-ns-shown';
464  } else {
465  $class = ' mw-hidden-cats-hidden';
466  }
467 
468  $s .= "<div id=\"mw-hidden-catlinks\" class=\"mw-hidden-catlinks$class\">" .
469  $this->msg( 'hidden-categories' )->numParams( count( $allCats['hidden'] ) )->escaped() .
470  $colon . '<ul>' . $embed . implode( "{$pop}{$embed}", $allCats['hidden'] ) . $pop . '</ul>' .
471  '</div>';
472  }
473 
474  # optional 'dmoz-like' category browser. Will be shown under the list
475  # of categories an article belong to
476  if ( $wgUseCategoryBrowser ) {
477  $s .= '<br /><hr />';
478 
479  # get a big array of the parents tree
480  $parenttree = $this->getTitle()->getParentCategoryTree();
481  # Skin object passed by reference cause it can not be
482  # accessed under the method subfunction drawCategoryBrowser
483  $tempout = explode( "\n", $this->drawCategoryBrowser( $parenttree ) );
484  # Clean out bogus first entry and sort them
485  unset( $tempout[0] );
486  asort( $tempout );
487  # Output one per line
488  $s .= implode( "<br />\n", $tempout );
489  }
490 
491  return $s;
492  }
493 
499  function drawCategoryBrowser( $tree ) {
500  $return = '';
501 
502  foreach ( $tree as $element => $parent ) {
503  if ( empty( $parent ) ) {
504  # element start a new list
505  $return .= "\n";
506  } else {
507  # grab the others elements
508  $return .= $this->drawCategoryBrowser( $parent ) . ' &gt; ';
509  }
510 
511  # add our current element to the list
512  $eltitle = Title::newFromText( $element );
513  $return .= Linker::link( $eltitle, htmlspecialchars( $eltitle->getText() ) );
514  }
515 
516  return $return;
517  }
518 
522  function getCategories() {
523  $out = $this->getOutput();
524  $catlinks = $this->getCategoryLinks();
525 
526  // Check what we're showing
527  $allCats = $out->getCategoryLinks();
528  $showHidden = $this->getUser()->getBoolOption( 'showhiddencats' ) ||
529  $this->getTitle()->getNamespace() == NS_CATEGORY;
530 
531  $classes = [ 'catlinks' ];
532  if ( empty( $allCats['normal'] ) && !( !empty( $allCats['hidden'] ) && $showHidden ) ) {
533  $classes[] = 'catlinks-allhidden';
534  }
535 
536  return Html::rawElement(
537  'div',
538  [ 'id' => 'catlinks', 'class' => $classes, 'data-mw' => 'interface' ],
539  $catlinks
540  );
541  }
542 
557  protected function afterContentHook() {
558  $data = '';
559 
560  if ( Hooks::run( 'SkinAfterContent', [ &$data, $this ] ) ) {
561  // adding just some spaces shouldn't toggle the output
562  // of the whole <div/>, so we use trim() here
563  if ( trim( $data ) != '' ) {
564  // Doing this here instead of in the skins to
565  // ensure that the div has the same ID in all
566  // skins
567  $data = "<div id='mw-data-after-content'>\n" .
568  "\t$data\n" .
569  "</div>\n";
570  }
571  } else {
572  wfDebug( "Hook SkinAfterContent changed output processing.\n" );
573  }
574 
575  return $data;
576  }
577 
583  protected function generateDebugHTML() {
584  return MWDebug::getHTMLDebugLog();
585  }
586 
592  function bottomScripts() {
593  // TODO and the suckage continues. This function is really just a wrapper around
594  // OutputPage::getBottomScripts() which takes a Skin param. This should be cleaned
595  // up at some point
596  $bottomScriptText = $this->getOutput()->getBottomScripts();
597  Hooks::run( 'SkinAfterBottomScripts', [ $this, &$bottomScriptText ] );
598 
599  return $bottomScriptText;
600  }
601 
608  function printSource() {
609  $oldid = $this->getRevisionId();
610  if ( $oldid ) {
611  $canonicalUrl = $this->getTitle()->getCanonicalURL( 'oldid=' . $oldid );
612  $url = htmlspecialchars( wfExpandIRI( $canonicalUrl ) );
613  } else {
614  // oldid not available for non existing pages
615  $url = htmlspecialchars( wfExpandIRI( $this->getTitle()->getCanonicalURL() ) );
616  }
617 
618  return $this->msg( 'retrievedfrom' )
619  ->rawParams( '<a dir="ltr" href="' . $url . '">' . $url . '</a>' )
620  ->parse();
621  }
622 
626  function getUndeleteLink() {
627  $action = $this->getRequest()->getVal( 'action', 'view' );
628 
629  if ( $this->getTitle()->userCan( 'deletedhistory', $this->getUser() ) &&
630  ( !$this->getTitle()->exists() || $action == 'history' ) ) {
631  $n = $this->getTitle()->isDeleted();
632 
633  if ( $n ) {
634  if ( $this->getTitle()->quickUserCan( 'undelete', $this->getUser() ) ) {
635  $msg = 'thisisdeleted';
636  } else {
637  $msg = 'viewdeleted';
638  }
639 
640  return $this->msg( $msg )->rawParams(
642  SpecialPage::getTitleFor( 'Undelete', $this->getTitle()->getPrefixedDBkey() ),
643  $this->msg( 'restorelink' )->numParams( $n )->escaped() )
644  )->escaped();
645  }
646  }
647 
648  return '';
649  }
650 
654  function subPageSubtitle() {
655  $out = $this->getOutput();
656  $subpages = '';
657 
658  if ( !Hooks::run( 'SkinSubPageSubtitle', [ &$subpages, $this, $out ] ) ) {
659  return $subpages;
660  }
661 
662  if ( $out->isArticle() && MWNamespace::hasSubpages( $out->getTitle()->getNamespace() ) ) {
663  $ptext = $this->getTitle()->getPrefixedText();
664  if ( preg_match( '/\//', $ptext ) ) {
665  $links = explode( '/', $ptext );
666  array_pop( $links );
667  $c = 0;
668  $growinglink = '';
669  $display = '';
670  $lang = $this->getLanguage();
671 
672  foreach ( $links as $link ) {
673  $growinglink .= $link;
674  $display .= $link;
675  $linkObj = Title::newFromText( $growinglink );
676 
677  if ( is_object( $linkObj ) && $linkObj->isKnown() ) {
678  $getlink = Linker::linkKnown(
679  $linkObj,
680  htmlspecialchars( $display )
681  );
682 
683  $c++;
684 
685  if ( $c > 1 ) {
686  $subpages .= $lang->getDirMarkEntity() . $this->msg( 'pipe-separator' )->escaped();
687  } else {
688  $subpages .= '&lt; ';
689  }
690 
691  $subpages .= $getlink;
692  $display = '';
693  } else {
694  $display .= '/';
695  }
696  $growinglink .= '/';
697  }
698  }
699  }
700 
701  return $subpages;
702  }
703 
708  function showIPinHeader() {
709  wfDeprecated( __METHOD__, '1.27' );
710  return false;
711  }
712 
716  function getSearchLink() {
718  return $searchPage->getLocalURL();
719  }
720 
724  function escapeSearchLink() {
725  return htmlspecialchars( $this->getSearchLink() );
726  }
727 
732  function getCopyright( $type = 'detect' ) {
733  global $wgRightsPage, $wgRightsUrl, $wgRightsText;
734 
735  if ( $type == 'detect' ) {
736  if ( !$this->isRevisionCurrent()
737  && !$this->msg( 'history_copyright' )->inContentLanguage()->isDisabled()
738  ) {
739  $type = 'history';
740  } else {
741  $type = 'normal';
742  }
743  }
744 
745  if ( $type == 'history' ) {
746  $msg = 'history_copyright';
747  } else {
748  $msg = 'copyright';
749  }
750 
751  if ( $wgRightsPage ) {
752  $title = Title::newFromText( $wgRightsPage );
753  $link = Linker::linkKnown( $title, $wgRightsText );
754  } elseif ( $wgRightsUrl ) {
755  $link = Linker::makeExternalLink( $wgRightsUrl, $wgRightsText );
756  } elseif ( $wgRightsText ) {
757  $link = $wgRightsText;
758  } else {
759  # Give up now
760  return '';
761  }
762 
763  // Allow for site and per-namespace customization of copyright notice.
764  // @todo Remove deprecated $forContent param from hook handlers and then remove here.
765  $forContent = true;
766 
767  Hooks::run(
768  'SkinCopyrightFooter',
769  [ $this->getTitle(), $type, &$msg, &$link, &$forContent ]
770  );
771 
772  return $this->msg( $msg )->rawParams( $link )->text();
773  }
774 
778  function getCopyrightIcon() {
779  global $wgRightsUrl, $wgRightsText, $wgRightsIcon, $wgFooterIcons;
780 
781  $out = '';
782 
783  if ( $wgFooterIcons['copyright']['copyright'] ) {
784  $out = $wgFooterIcons['copyright']['copyright'];
785  } elseif ( $wgRightsIcon ) {
786  $icon = htmlspecialchars( $wgRightsIcon );
787 
788  if ( $wgRightsUrl ) {
789  $url = htmlspecialchars( $wgRightsUrl );
790  $out .= '<a href="' . $url . '">';
791  }
792 
793  $text = htmlspecialchars( $wgRightsText );
794  $out .= "<img src=\"$icon\" alt=\"$text\" width=\"88\" height=\"31\" />";
795 
796  if ( $wgRightsUrl ) {
797  $out .= '</a>';
798  }
799  }
800 
801  return $out;
802  }
803 
808  function getPoweredBy() {
810 
811  $url1 = htmlspecialchars(
812  "$wgResourceBasePath/resources/assets/poweredby_mediawiki_88x31.png"
813  );
814  $url1_5 = htmlspecialchars(
815  "$wgResourceBasePath/resources/assets/poweredby_mediawiki_132x47.png"
816  );
817  $url2 = htmlspecialchars(
818  "$wgResourceBasePath/resources/assets/poweredby_mediawiki_176x62.png"
819  );
820  $text = '<a href="//www.mediawiki.org/"><img src="' . $url1
821  . '" srcset="' . $url1_5 . ' 1.5x, ' . $url2 . ' 2x" '
822  . 'height="31" width="88" alt="Powered by MediaWiki" /></a>';
823  Hooks::run( 'SkinGetPoweredBy', [ &$text, $this ] );
824  return $text;
825  }
826 
832  protected function lastModified() {
833  $timestamp = $this->getOutput()->getRevisionTimestamp();
834 
835  # No cached timestamp, load it from the database
836  if ( $timestamp === null ) {
838  }
839 
840  if ( $timestamp ) {
841  $d = $this->getLanguage()->userDate( $timestamp, $this->getUser() );
842  $t = $this->getLanguage()->userTime( $timestamp, $this->getUser() );
843  $s = ' ' . $this->msg( 'lastmodifiedat', $d, $t )->parse();
844  } else {
845  $s = '';
846  }
847 
848  if ( wfGetLB()->getLaggedSlaveMode() ) {
849  $s .= ' <strong>' . $this->msg( 'laggedslavemode' )->parse() . '</strong>';
850  }
851 
852  return $s;
853  }
854 
859  function logoText( $align = '' ) {
860  if ( $align != '' ) {
861  $a = " style='float: {$align};'";
862  } else {
863  $a = '';
864  }
865 
866  $mp = $this->msg( 'mainpage' )->escaped();
867  $mptitle = Title::newMainPage();
868  $url = ( is_object( $mptitle ) ? htmlspecialchars( $mptitle->getLocalURL() ) : '' );
869 
870  $logourl = $this->getLogo();
871  $s = "<a href='{$url}'><img{$a} src='{$logourl}' alt='[{$mp}]' /></a>";
872 
873  return $s;
874  }
875 
884  function makeFooterIcon( $icon, $withImage = 'withImage' ) {
885  if ( is_string( $icon ) ) {
886  $html = $icon;
887  } else { // Assuming array
888  $url = isset( $icon["url"] ) ? $icon["url"] : null;
889  unset( $icon["url"] );
890  if ( isset( $icon["src"] ) && $withImage === 'withImage' ) {
891  // do this the lazy way, just pass icon data as an attribute array
892  $html = Html::element( 'img', $icon );
893  } else {
894  $html = htmlspecialchars( $icon["alt"] );
895  }
896  if ( $url ) {
897  $html = Html::rawElement( 'a', [ "href" => $url ], $html );
898  }
899  }
900  return $html;
901  }
902 
907  function mainPageLink() {
910  $this->msg( 'mainpage' )->escaped()
911  );
912 
913  return $s;
914  }
915 
922  public function footerLink( $desc, $page ) {
923  // if the link description has been set to "-" in the default language,
924  if ( $this->msg( $desc )->inContentLanguage()->isDisabled() ) {
925  // then it is disabled, for all languages.
926  return '';
927  } else {
928  // Otherwise, we display the link for the user, described in their
929  // language (which may or may not be the same as the default language),
930  // but we make the link target be the one site-wide page.
931  $title = Title::newFromText( $this->msg( $page )->inContentLanguage()->text() );
932 
933  if ( !$title ) {
934  return '';
935  }
936 
937  return Linker::linkKnown(
938  $title,
939  $this->msg( $desc )->escaped()
940  );
941  }
942  }
943 
948  function privacyLink() {
949  return $this->footerLink( 'privacy', 'privacypage' );
950  }
951 
956  function aboutLink() {
957  return $this->footerLink( 'aboutsite', 'aboutpage' );
958  }
959 
964  function disclaimerLink() {
965  return $this->footerLink( 'disclaimers', 'disclaimerpage' );
966  }
967 
975  function editUrlOptions() {
976  $options = [ 'action' => 'edit' ];
977 
978  if ( !$this->isRevisionCurrent() ) {
979  $options['oldid'] = intval( $this->getRevisionId() );
980  }
981 
982  return $options;
983  }
984 
989  function showEmailUser( $id ) {
990  if ( $id instanceof User ) {
991  $targetUser = $id;
992  } else {
993  $targetUser = User::newFromId( $id );
994  }
995 
996  # The sending user must have a confirmed email address and the target
997  # user must have a confirmed email address and allow emails from users.
998  return $this->getUser()->canSendEmail() &&
999  $targetUser->canReceiveEmail();
1000  }
1001 
1013  function getSkinStylePath( $name ) {
1015 
1016  if ( $this->stylename === null ) {
1017  $class = get_class( $this );
1018  throw new MWException( "$class::\$stylename must be set to use getSkinStylePath()" );
1019  }
1020 
1021  return "$wgStylePath/{$this->stylename}/$name?$wgStyleVersion";
1022  }
1023 
1024  /* these are used extensively in SkinTemplate, but also some other places */
1025 
1030  static function makeMainPageUrl( $urlaction = '' ) {
1032  self::checkTitle( $title, '' );
1033 
1034  return $title->getLocalURL( $urlaction );
1035  }
1036 
1048  static function makeSpecialUrl( $name, $urlaction = '', $proto = null ) {
1050  if ( is_null( $proto ) ) {
1051  return $title->getLocalURL( $urlaction );
1052  } else {
1053  return $title->getFullURL( $urlaction, false, $proto );
1054  }
1055  }
1056 
1063  static function makeSpecialUrlSubpage( $name, $subpage, $urlaction = '' ) {
1064  $title = SpecialPage::getSafeTitleFor( $name, $subpage );
1065  return $title->getLocalURL( $urlaction );
1066  }
1067 
1073  static function makeI18nUrl( $name, $urlaction = '' ) {
1074  $title = Title::newFromText( wfMessage( $name )->inContentLanguage()->text() );
1075  self::checkTitle( $title, $name );
1076  return $title->getLocalURL( $urlaction );
1077  }
1078 
1084  static function makeUrl( $name, $urlaction = '' ) {
1086  self::checkTitle( $title, $name );
1087 
1088  return $title->getLocalURL( $urlaction );
1089  }
1090 
1097  static function makeInternalOrExternalUrl( $name ) {
1098  if ( preg_match( '/^(?i:' . wfUrlProtocols() . ')/', $name ) ) {
1099  return $name;
1100  } else {
1101  return self::makeUrl( $name );
1102  }
1103  }
1104 
1112  static function makeNSUrl( $name, $urlaction = '', $namespace = NS_MAIN ) {
1113  $title = Title::makeTitleSafe( $namespace, $name );
1114  self::checkTitle( $title, $name );
1115 
1116  return $title->getLocalURL( $urlaction );
1117  }
1118 
1125  static function makeUrlDetails( $name, $urlaction = '' ) {
1127  self::checkTitle( $title, $name );
1128 
1129  return [
1130  'href' => $title->getLocalURL( $urlaction ),
1131  'exists' => $title->isKnown(),
1132  ];
1133  }
1134 
1141  static function makeKnownUrlDetails( $name, $urlaction = '' ) {
1143  self::checkTitle( $title, $name );
1144 
1145  return [
1146  'href' => $title->getLocalURL( $urlaction ),
1147  'exists' => true
1148  ];
1149  }
1150 
1157  static function checkTitle( &$title, $name ) {
1158  if ( !is_object( $title ) ) {
1160  if ( !is_object( $title ) ) {
1161  $title = Title::newFromText( '--error: link target missing--' );
1162  }
1163  }
1164  }
1165 
1187  function buildSidebar() {
1189 
1190  $that = $this;
1191  $callback = function () use ( $that ) {
1192  $bar = [];
1193  $that->addToSidebar( $bar, 'sidebar' );
1194  Hooks::run( 'SkinBuildSidebar', [ $that, &$bar ] );
1195 
1196  return $bar;
1197  };
1198 
1199  if ( $wgEnableSidebarCache ) {
1201  $sidebar = $cache->getWithSetCallback(
1202  $cache->makeKey( 'sidebar', $this->getLanguage()->getCode() ),
1203  MessageCache::singleton()->isDisabled()
1204  ? $cache::TTL_UNCACHEABLE // bug T133069
1206  $callback,
1207  [ 'lockTSE' => 30 ]
1208  );
1209  } else {
1210  $sidebar = $callback();
1211  }
1212 
1213  // Apply post-processing to the cached value
1214  Hooks::run( 'SidebarBeforeOutput', [ $this, &$sidebar ] );
1215 
1216  return $sidebar;
1217  }
1218 
1228  public function addToSidebar( &$bar, $message ) {
1229  $this->addToSidebarPlain( $bar, wfMessage( $message )->inContentLanguage()->plain() );
1230  }
1231 
1239  function addToSidebarPlain( &$bar, $text ) {
1240  $lines = explode( "\n", $text );
1241 
1242  $heading = '';
1243 
1244  foreach ( $lines as $line ) {
1245  if ( strpos( $line, '*' ) !== 0 ) {
1246  continue;
1247  }
1248  $line = rtrim( $line, "\r" ); // for Windows compat
1249 
1250  if ( strpos( $line, '**' ) !== 0 ) {
1251  $heading = trim( $line, '* ' );
1252  if ( !array_key_exists( $heading, $bar ) ) {
1253  $bar[$heading] = [];
1254  }
1255  } else {
1256  $line = trim( $line, '* ' );
1257 
1258  if ( strpos( $line, '|' ) !== false ) { // sanity check
1259  $line = MessageCache::singleton()->transform( $line, false, null, $this->getTitle() );
1260  $line = array_map( 'trim', explode( '|', $line, 2 ) );
1261  if ( count( $line ) !== 2 ) {
1262  // Second sanity check, could be hit by people doing
1263  // funky stuff with parserfuncs... (bug 33321)
1264  continue;
1265  }
1266 
1267  $extraAttribs = [];
1268 
1269  $msgLink = $this->msg( $line[0] )->inContentLanguage();
1270  if ( $msgLink->exists() ) {
1271  $link = $msgLink->text();
1272  if ( $link == '-' ) {
1273  continue;
1274  }
1275  } else {
1276  $link = $line[0];
1277  }
1278  $msgText = $this->msg( $line[1] );
1279  if ( $msgText->exists() ) {
1280  $text = $msgText->text();
1281  } else {
1282  $text = $line[1];
1283  }
1284 
1285  if ( preg_match( '/^(?i:' . wfUrlProtocols() . ')/', $link ) ) {
1286  $href = $link;
1287 
1288  // Parser::getExternalLinkAttribs won't work here because of the Namespace things
1289  global $wgNoFollowLinks, $wgNoFollowDomainExceptions;
1290  if ( $wgNoFollowLinks && !wfMatchesDomainList( $href, $wgNoFollowDomainExceptions ) ) {
1291  $extraAttribs['rel'] = 'nofollow';
1292  }
1293 
1294  global $wgExternalLinkTarget;
1295  if ( $wgExternalLinkTarget ) {
1296  $extraAttribs['target'] = $wgExternalLinkTarget;
1297  }
1298  } else {
1300 
1301  if ( $title ) {
1302  $title = $title->fixSpecialName();
1303  $href = $title->getLinkURL();
1304  } else {
1305  $href = 'INVALID-TITLE';
1306  }
1307  }
1308 
1309  $bar[$heading][] = array_merge( [
1310  'text' => $text,
1311  'href' => $href,
1312  'id' => 'n-' . Sanitizer::escapeId( strtr( $line[1], ' ', '-' ), 'noninitial' ),
1313  'active' => false
1314  ], $extraAttribs );
1315  } else {
1316  continue;
1317  }
1318  }
1319  }
1320 
1321  return $bar;
1322  }
1323 
1329  function getNewtalks() {
1330 
1331  $newMessagesAlert = '';
1332  $user = $this->getUser();
1333  $newtalks = $user->getNewMessageLinks();
1334  $out = $this->getOutput();
1335 
1336  // Allow extensions to disable or modify the new messages alert
1337  if ( !Hooks::run( 'GetNewMessagesAlert', [ &$newMessagesAlert, $newtalks, $user, $out ] ) ) {
1338  return '';
1339  }
1340  if ( $newMessagesAlert ) {
1341  return $newMessagesAlert;
1342  }
1343 
1344  if ( count( $newtalks ) == 1 && $newtalks[0]['wiki'] === wfWikiID() ) {
1345  $uTalkTitle = $user->getTalkPage();
1346  $lastSeenRev = isset( $newtalks[0]['rev'] ) ? $newtalks[0]['rev'] : null;
1347  $nofAuthors = 0;
1348  if ( $lastSeenRev !== null ) {
1349  $plural = true; // Default if we have a last seen revision: if unknown, use plural
1350  $latestRev = Revision::newFromTitle( $uTalkTitle, false, Revision::READ_NORMAL );
1351  if ( $latestRev !== null ) {
1352  // Singular if only 1 unseen revision, plural if several unseen revisions.
1353  $plural = $latestRev->getParentId() !== $lastSeenRev->getId();
1354  $nofAuthors = $uTalkTitle->countAuthorsBetween(
1355  $lastSeenRev, $latestRev, 10, 'include_new' );
1356  }
1357  } else {
1358  // Singular if no revision -> diff link will show latest change only in any case
1359  $plural = false;
1360  }
1361  $plural = $plural ? 999 : 1;
1362  // 999 signifies "more than one revision". We don't know how many, and even if we did,
1363  // the number of revisions or authors is not necessarily the same as the number of
1364  // "messages".
1365  $newMessagesLink = Linker::linkKnown(
1366  $uTalkTitle,
1367  $this->msg( 'newmessageslinkplural' )->params( $plural )->escaped(),
1368  [],
1369  [ 'redirect' => 'no' ]
1370  );
1371 
1372  $newMessagesDiffLink = Linker::linkKnown(
1373  $uTalkTitle,
1374  $this->msg( 'newmessagesdifflinkplural' )->params( $plural )->escaped(),
1375  [],
1376  $lastSeenRev !== null
1377  ? [ 'oldid' => $lastSeenRev->getId(), 'diff' => 'cur' ]
1378  : [ 'diff' => 'cur' ]
1379  );
1380 
1381  if ( $nofAuthors >= 1 && $nofAuthors <= 10 ) {
1382  $newMessagesAlert = $this->msg(
1383  'youhavenewmessagesfromusers',
1384  $newMessagesLink,
1385  $newMessagesDiffLink
1386  )->numParams( $nofAuthors, $plural );
1387  } else {
1388  // $nofAuthors === 11 signifies "11 or more" ("more than 10")
1389  $newMessagesAlert = $this->msg(
1390  $nofAuthors > 10 ? 'youhavenewmessagesmanyusers' : 'youhavenewmessages',
1391  $newMessagesLink,
1392  $newMessagesDiffLink
1393  )->numParams( $plural );
1394  }
1395  $newMessagesAlert = $newMessagesAlert->text();
1396  # Disable CDN cache
1397  $out->setCdnMaxage( 0 );
1398  } elseif ( count( $newtalks ) ) {
1399  $sep = $this->msg( 'newtalkseparator' )->escaped();
1400  $msgs = [];
1401 
1402  foreach ( $newtalks as $newtalk ) {
1403  $msgs[] = Xml::element(
1404  'a',
1405  [ 'href' => $newtalk['link'] ], $newtalk['wiki']
1406  );
1407  }
1408  $parts = implode( $sep, $msgs );
1409  $newMessagesAlert = $this->msg( 'youhavenewmessagesmulti' )->rawParams( $parts )->escaped();
1410  $out->setCdnMaxage( 0 );
1411  }
1412 
1413  return $newMessagesAlert;
1414  }
1415 
1423  private function getCachedNotice( $name ) {
1425 
1426  $needParse = false;
1427 
1428  if ( $name === 'default' ) {
1429  // special case
1431  $notice = $wgSiteNotice;
1432  if ( empty( $notice ) ) {
1433  return false;
1434  }
1435  } else {
1436  $msg = $this->msg( $name )->inContentLanguage();
1437  if ( $msg->isBlank() ) {
1438  return '';
1439  } elseif ( $msg->isDisabled() ) {
1440  return false;
1441  }
1442  $notice = $msg->plain();
1443  }
1444 
1445  // Use the extra hash appender to let eg SSL variants separately cache.
1446  $key = wfMemcKey( $name . $wgRenderHashAppend );
1447  $cachedNotice = $parserMemc->get( $key );
1448  if ( is_array( $cachedNotice ) ) {
1449  if ( md5( $notice ) == $cachedNotice['hash'] ) {
1450  $notice = $cachedNotice['html'];
1451  } else {
1452  $needParse = true;
1453  }
1454  } else {
1455  $needParse = true;
1456  }
1457 
1458  if ( $needParse ) {
1459  $parsed = $this->getOutput()->parse( $notice );
1460  $parserMemc->set( $key, [ 'html' => $parsed, 'hash' => md5( $notice ) ], 600 );
1461  $notice = $parsed;
1462  }
1463 
1464  $notice = Html::rawElement( 'div', [ 'id' => 'localNotice',
1465  'lang' => $wgContLang->getHtmlCode(), 'dir' => $wgContLang->getDir() ], $notice );
1466  return $notice;
1467  }
1468 
1474  function getSiteNotice() {
1475  $siteNotice = '';
1476 
1477  if ( Hooks::run( 'SiteNoticeBefore', [ &$siteNotice, $this ] ) ) {
1478  if ( is_object( $this->getUser() ) && $this->getUser()->isLoggedIn() ) {
1479  $siteNotice = $this->getCachedNotice( 'sitenotice' );
1480  } else {
1481  $anonNotice = $this->getCachedNotice( 'anonnotice' );
1482  if ( $anonNotice === false ) {
1483  $siteNotice = $this->getCachedNotice( 'sitenotice' );
1484  } else {
1485  $siteNotice = $anonNotice;
1486  }
1487  }
1488  if ( $siteNotice === false ) {
1489  $siteNotice = $this->getCachedNotice( 'default' );
1490  }
1491  }
1492 
1493  Hooks::run( 'SiteNoticeAfter', [ &$siteNotice, $this ] );
1494  return $siteNotice;
1495  }
1496 
1510  public function doEditSectionLink( Title $nt, $section, $tooltip = null, $lang = false ) {
1511  // HTML generated here should probably have userlangattributes
1512  // added to it for LTR text on RTL pages
1513 
1514  $lang = wfGetLangObj( $lang );
1515 
1516  $attribs = [];
1517  if ( !is_null( $tooltip ) ) {
1518  # Bug 25462: undo double-escaping.
1519  $tooltip = Sanitizer::decodeCharReferences( $tooltip );
1520  $attribs['title'] = wfMessage( 'editsectionhint' )->rawParams( $tooltip )
1521  ->inLanguage( $lang )->text();
1522  }
1523 
1524  $links = [
1525  'editsection' => [
1526  'text' => wfMessage( 'editsection' )->inLanguage( $lang )->escaped(),
1527  'targetTitle' => $nt,
1528  'attribs' => $attribs,
1529  'query' => [ 'action' => 'edit', 'section' => $section ],
1530  'options' => [ 'noclasses', 'known' ]
1531  ]
1532  ];
1533 
1534  Hooks::run( 'SkinEditSectionLinks', [ $this, $nt, $section, $tooltip, &$links, $lang ] );
1535 
1536  $result = '<span class="mw-editsection"><span class="mw-editsection-bracket">[</span>';
1537 
1538  $linksHtml = [];
1539  foreach ( $links as $k => $linkDetails ) {
1540  $linksHtml[] = Linker::link(
1541  $linkDetails['targetTitle'],
1542  $linkDetails['text'],
1543  $linkDetails['attribs'],
1544  $linkDetails['query'],
1545  $linkDetails['options']
1546  );
1547  }
1548 
1549  $result .= implode(
1550  '<span class="mw-editsection-divider">'
1551  . wfMessage( 'pipe-separator' )->inLanguage( $lang )->text()
1552  . '</span>',
1553  $linksHtml
1554  );
1555 
1556  $result .= '<span class="mw-editsection-bracket">]</span></span>';
1557  // Deprecated, use SkinEditSectionLinks hook instead
1558  Hooks::run(
1559  'DoEditSectionLink',
1560  [ $this, $nt, $section, $tooltip, &$result, $lang ],
1561  '1.25'
1562  );
1563  return $result;
1564  }
1565 
1567  public function commentBlock( $comment, $title = null, $local = false, $wikiId = null ) {
1568  wfDeprecated( __METHOD__, '1.21' );
1569  return Linker::commentBlock( $comment, $title, $local, $wikiId );
1570  }
1571 
1573  public function generateRollback(
1574  $rev,
1575  IContextSource $context = null,
1576  $options = [ 'verify' ]
1577  ) {
1578  wfDeprecated( __METHOD__, '1.21' );
1580  }
1581 
1583  public function link( $target, $html = null, $customAttribs = [], $query = [], $options = [] ) {
1584  wfDeprecated( __METHOD__, '1.21' );
1585  return Linker::link( $target, $html, $customAttribs, $query, $options );
1586  }
1587 
1589  public function linkKnown(
1590  $target,
1591  $html = null,
1592  $customAttribs = [],
1593  $query = [],
1594  $options = [ 'known', 'noclasses' ]
1595  ) {
1596  wfDeprecated( __METHOD__, '1.21' );
1597  return Linker::linkKnown( $target, $html, $customAttribs, $query, $options );
1598  }
1599 
1601  public function userLink( $userId, $userName, $altUserName = false ) {
1602  wfDeprecated( __METHOD__, '1.21' );
1603  return Linker::userLink( $userId, $userName, $altUserName );
1604  }
1605 
1607  public function userToolLinks(
1608  $userId,
1609  $userText,
1610  $redContribsWhenNoEdits = false,
1611  $flags = 0,
1612  $edits = null
1613  ) {
1614  wfDeprecated( __METHOD__, '1.21' );
1615  return Linker::userToolLinks( $userId, $userText, $redContribsWhenNoEdits, $flags, $edits );
1616  }
1617 
1618 }
static newFromName($name, $validate= 'valid')
Static factory method for creation from username.
Definition: User.php:568
static getMainWANInstance()
Get the main WAN cache object.
$wgFooterIcons
Abstract list of footer icons for skins in place of old copyrightico and poweredbyico code You can ad...
$wgSquidMaxage
Cache TTL for the CDN sent as s-maxage (without ESI) or Surrogate-Control (with ESI).
lastModified()
Get the timestamp of the latest revision, formatted in user language.
Definition: Skin.php:832
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:1798
Interface for objects which can provide a MediaWiki context on request.
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
logoText($align= '')
Definition: Skin.php:859
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:762
null for the local wiki Added should default to null in handler for backwards compatibility add a value to it if you want to add a cookie that have to vary cache options can modify $query
Definition: hooks.txt:1418
getLanguage()
Get the Language object.
afterContentHook()
This runs a hook to allow extensions placing their stuff after content and article metadata (e...
Definition: Skin.php:557
static linkKnown($target, $html=null, $customAttribs=[], $query=[], $options=[ 'known', 'noclasses'])
Identical to link(), except $options defaults to 'known'.
Definition: Linker.php:264
setRelevantUser($u)
Set the "relevant" user.
Definition: Skin.php:282
magic word the default is to use $key to get the and $key value or $key value text $key value html to format the value $key
Definition: hooks.txt:2321
The main skin class which provides methods and properties for all other skins.
Definition: Skin.php:34
getCachedNotice($name)
Get a cached notice.
Definition: Skin.php:1423
subPageSubtitle()
Definition: Skin.php:654
addToBodyAttributes($out, &$bodyAttrs)
This will be called by OutputPage::headElement when it is creating the "" tag, skins can override it if they have a need to add in any body attributes or classes of their own.
Definition: Skin.php:415
getPoweredBy()
Gets the powered by MediaWiki icon.
Definition: Skin.php:808
static makeMainPageUrl($urlaction= '')
Definition: Skin.php:1030
getNewtalks()
Gets new talk page messages for the current user and returns an appropriate alert message (or an empt...
Definition: Skin.php:1329
const NS_MAIN
Definition: Defines.php:69
static element($element, $attribs=null, $contents= '', $allowShortTag=true)
Format an XML element with given attributes and, optionally, text content.
Definition: Xml.php:39
static newMainPage()
Create a new Title for the Main Page.
Definition: Title.php:569
static makeUrl($name, $urlaction= '')
Definition: Skin.php:1084
static makeNSUrl($name, $urlaction= '', $namespace=NS_MAIN)
this can be passed the NS number as defined in Language.php
Definition: Skin.php:1112
Apache License January AND DISTRIBUTION Definitions License shall mean the terms and conditions for use
static getTitleFor($name, $subpage=false, $fragment= '')
Get a localised Title object for a specified special page name.
Definition: SpecialPage.php:75
buildSidebar()
Build an array that represents the sidebar(s), the navigation bar among them.
Definition: Skin.php:1187
The simplest way of implementing IContextSource is to hold a RequestContext as a member variable and ...
privacyLink()
Gets the link to the wiki's privacy policy page.
Definition: Skin.php:948
static rawElement($element, $attribs=[], $contents= '')
Returns an HTML element in a string.
Definition: Html.php:210
static getTimestampFromId($title, $id, $flags=0)
Get rev_timestamp from rev_id, without loading the rest of the row.
Definition: Revision.php:1751
if(!isset($args[0])) $lang
initPage(OutputPage $out)
Definition: Skin.php:144
editUrlOptions()
Return URL options for the 'edit page' link.
Definition: Skin.php:975
getLogo()
URL to the logo.
Definition: Skin.php:423
$comment
static getSkinNames()
Fetch the set of available skins.
Definition: Skin.php:49
static newFromId($id)
Static factory method for creation from a given user ID.
Definition: User.php:591
getCopyrightIcon()
Definition: Skin.php:778
static makeConfigSetScript(array $configuration)
Returns JS code which will set the MediaWiki configuration array to the given value.
it s the revision text itself In either if gzip is the revision text is gzipped $flags
Definition: hooks.txt:2548
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
$wgSidebarCacheExpiry
Expiry time for the sidebar cache, in seconds.
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
userToolLinks($userId, $userText, $redContribsWhenNoEdits=false, $flags=0, $edits=null)
Definition: Skin.php:1607
Represents a title within MediaWiki.
Definition: Title.php:34
when a variable name is used in a it is silently declared as a new local masking the global
Definition: design.txt:93
footerLink($desc, $page)
Returns an HTML link for use in the footer.
Definition: Skin.php:922
setRelevantTitle($t)
Set the "relevant" title.
Definition: Skin.php:256
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:117
$wgStyleVersion
Bump this number when changing the global style sheets and JavaScript.
IContextSource $context
wfExpandIRI($url)
Take a URL, make sure it's expanded to fully qualified, and replace any encoded non-ASCII Unicode cha...
generateRollback($rev, IContextSource $context=null, $options=[ 'verify'])
Definition: Skin.php:1573
getCategories()
Definition: Skin.php:522
getTitle()
Get the Title object.
static makeVariablesScript($data)
Definition: Skin.php:329
getSiteNotice()
Get the site notice.
Definition: Skin.php:1474
static getHTMLDebugLog()
Generate debug log in HTML for displaying at the bottom of the main content area. ...
Definition: MWDebug.php:460
wfDebug($text, $dest= 'all', array $context=[])
Sends a line to the debug log if enabled or, optionally, to a comment in output.
link($target, $html=null, $customAttribs=[], $query=[], $options=[])
Definition: Skin.php:1583
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. '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 '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:Associative array mapping language codes to prefixed links of the form"language:title".&$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':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:1796
static getSafeTitleFor($name, $subpage=false)
Get a localised Title object for a page name with a possibly unvalidated subpage. ...
Definition: SpecialPage.php:88
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:2581
showIPinHeader()
Definition: Skin.php:708
static decodeCharReferences($text)
Decode any character references, numeric or named entities, in the text and return a UTF-8 string...
Definition: Sanitizer.php:1462
Class representing a list of titles The execute() method checks them all for existence and adds them ...
Definition: LinkBatch.php:31
getRequest()
Get the WebRequest object.
null means default & $customAttribs
Definition: hooks.txt:1798
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:1798
linkKnown($target, $html=null, $customAttribs=[], $query=[], $options=[ 'known', 'noclasses'])
Definition: Skin.php:1589
$wgRenderHashAppend
Append a configured value to the parser cache and the sitenotice key so that they can be kept separat...
msg()
Get a Message object with context set Parameters are the same as wfMessage()
getCopyright($type= 'detect')
Definition: Skin.php:732
preloadExistence()
Preload the existence of three commonly-requested pages in a single query.
Definition: Skin.php:202
$wgStylePath
The URL path of the skins directory.
wfGetLB($wiki=false)
Get a load balancer object.
static makeI18nUrl($name, $urlaction= '')
Definition: Skin.php:1073
$mRelevantTitle
Definition: Skin.php:36
static checkTitle(&$title, $name)
make sure we have some title to operate on
Definition: Skin.php:1157
if($limit) $timestamp
mainPageLink()
Gets the link to the wiki's main page.
Definition: Skin.php:907
this hook is for auditing only RecentChangesLinked and Watchlist RecentChangesLinked and Watchlist e g Watchlist removed from all revisions and log entries to which it was applied This gives extensions a chance to take it off their books as the deletion has already been partly carried out by this point or something similar the user will be unable to create the tag set and then return false from the hook function Ensure you consume the ChangeTagAfterDelete hook to carry out custom deletion actions as context called by AbstractContent::getParserOutput May be used to override the normal model specific rendering of page content as context as context $options
Definition: hooks.txt:1004
getRelevantTitle()
Return the "relevant" title.
Definition: Skin.php:270
getCategoryLinks()
Definition: Skin.php:431
wfMatchesDomainList($url, $domains)
Check whether a given URL has a domain that occurs in a given set of domains.
controlled by $wgMainCacheType * $parserMemc
Definition: memcached.txt:78
disclaimerLink()
Gets the link to the wiki's general disclaimers page.
Definition: Skin.php:964
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
$cache
Definition: mcc.php:33
getSearchLink()
Definition: Skin.php:716
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 or change the value of $siteNotice and return false to alter it & $siteNotice
Definition: hooks.txt:2581
static makeSpecialUrl($name, $urlaction= '', $proto=null)
Make a URL for a Special Page using the given query and protocol.
Definition: Skin.php:1048
$mRelevantUser
Definition: Skin.php:37
const NS_CATEGORY
Definition: Defines.php:83
$wgResourceBasePath
The default 'remoteBasePath' value for instances of ResourceLoaderFileModule.
wfDeprecated($function, $version=false, $component=false, $callerOffset=2)
Throws a warning that $function is deprecated.
static makeTitleSafe($ns, $title, $fragment= '', $interwiki= '')
Create a new Title from a namespace index and a DB key.
Definition: Title.php:548
generateDebugHTML()
Generate debug data HTML for displaying at the bottom of the main content area.
Definition: Skin.php:583
static isIP($name)
Does the string match an anonymous IPv4 address?
Definition: User.php:830
static makeInlineScript($script)
Construct an inline script tag with given JS code.
getHtmlElementAttributes()
Return values for element.
Definition: Skin.php:399
namespace and then decline to actually register it file or subcat img or subcat $title
Definition: hooks.txt:912
static hasSubpages($index)
Does the namespace allow subpages?
showEmailUser($id)
Definition: Skin.php:989
getRelevantUser()
Return the "relevant" user.
Definition: Skin.php:294
static run($event, array $args=[], $deprecatedVersion=null)
Call hook functions defined in Hooks::register and $wgHooks.
Definition: Hooks.php:131
design txt This is a brief overview of the new design More thorough and up to date information is available on the documentation wiki at etc Handles the details of getting and saving to the user table of the and dealing with sessions and cookies OutputPage Encapsulates the entire HTML page that will be sent in response to any server request It is used by calling its functions to add text
Definition: design.txt:12
aboutLink()
Gets the link to the wiki's about page.
Definition: Skin.php:956
addToSidebarPlain(&$bar, $text)
Add content from plain text.
Definition: Skin.php:1239
wfWikiID()
Get an ASCII string identifying this wiki This is used as a prefix in memcached keys.
addToSidebar(&$bar, $message)
Add content from a sidebar system message Currently only used for MediaWiki:Sidebar (but may be used ...
Definition: Skin.php:1228
outputPage(OutputPage $out=null)
Outputs the HTML generated by other functions.
presenting them properly to the user as errors is done by the caller return true use this to change the list i e etc $rev
Definition: hooks.txt:1584
getPageClasses($title)
TODO: document.
Definition: Skin.php:371
This document is intended to provide useful advice for parties seeking to redistribute MediaWiki to end users It s targeted particularly at maintainers for Linux since it s been observed that distribution packages of MediaWiki often break We ve consistently had to recommend that users seeking support use official tarballs instead of their distribution s and this often solves whatever problem the user is having It would be nice if this could such as
Definition: distributors.txt:9
This class should be covered by a general architecture document which does not exist as of January 20...
Definition: OutputPage.php:42
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:2715
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
Definition: hooks.txt:242
static link($target, $html=null, $customAttribs=[], $query=[], $options=[])
This function returns an HTML link to the given target.
Definition: Linker.php:195
static normalizeKey($key)
Normalize a skin preference value to a form that can be loaded.
Definition: Skin.php:93
getDefaultModules()
Defines the ResourceLoader modules that should be added to the skin It is recommended that skins wish...
Definition: Skin.php:156
static escapeId($id, $options=[])
Given a value, escape it so that it can be used in an id attribute and return it. ...
Definition: Sanitizer.php:1132
drawCategoryBrowser($tree)
Render the array as a series of links.
Definition: Skin.php:499
static userLink($userId, $userName, $altUserName=false)
Make user link (or user contributions for unregistered users)
Definition: Linker.php:1102
wfUrlProtocols($includeProtocolRelative=true)
Returns a regular expression of url protocols.
static makeExternalLink($url, $text, $escape=true, $linktype= '', $attribs=[], $title=null)
Make an external link.
Definition: Linker.php:1052
$skinname
Definition: Skin.php:35
printSource()
Text with the permalink to the source page, usually shown on the footer of a printed page...
Definition: Skin.php:608
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency which acts as the top level factory for services in MediaWiki which can be used to gain access to default instances of various services MediaWikiServices however also allows new services to be defined and default services to be redefined Services are defined or redefined by providing a callback the instantiator that will return a new instance of the service When it will create an instance of MediaWikiServices and populate it with the services defined in the files listed by thereby bootstrapping the DI framework Per $wgServiceWiringFiles lists includes ServiceWiring php
Definition: injection.txt:35
string $stylename
Stylesheets set to use.
Definition: Skin.php:43
$fallback
Definition: MessagesAb.php:11
$lines
Definition: router.php:66
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
static resolveAlias($alias)
Given a special page name with a possible subpage, return an array where the first element is the spe...
isRevisionCurrent()
Whether the revision displayed is the latest revision of the page.
Definition: Skin.php:246
static generateRollback($rev, IContextSource $context=null, $options=[ 'verify'])
Generate a rollback link for a given revision.
Definition: Linker.php:1857
$wgDefaultSkin
Default skin, for new users and anonymous visitors.
$wgSkipSkins
Specify the names of skins that should not be presented in the list of available skins in user prefer...
$line
Definition: cdb.php:59
static getSkinNameMessages()
Fetch the skinname messages for available skins.
Definition: Skin.php:57
makeFooterIcon($icon, $withImage= 'withImage')
Renders a $wgFooterIcons icon according to the method's arguments.
Definition: Skin.php:884
static userToolLinks($userId, $userText, $redContribsWhenNoEdits=false, $flags=0, $edits=null)
Generate standard user tool links (talk, contributions, block link, etc.)
Definition: Linker.php:1133
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
Definition: design.txt:56
$wgLogo
The URL path of the wiki logo.
$wgFallbackSkin
Fallback skin used when the skin defined by $wgDefaultSkin can't be found.
$wgSiteNotice
Site notice shown at the top of each page.
static makeInternalOrExternalUrl($name)
If url string starts with http, consider as external URL, else internal.
Definition: Skin.php:1097
getUndeleteLink()
Definition: Skin.php:626
commentBlock($comment, $title=null, $local=false, $wikiId=null)
Definition: Skin.php:1567
$messages
wfMemcKey()
Make a cache key for the local wiki.
doEditSectionLink(Title $nt, $section, $tooltip=null, $lang=false)
Create a section edit link.
Definition: Skin.php:1510
static getDynamicStylesheetQuery()
Get the query to generate a dynamic stylesheet.
Definition: Skin.php:344
static commentBlock($comment, $title=null, $local=false, $wikiId=null)
Wrap a comment in standard punctuation and formatting if it's non-empty, otherwise return empty strin...
Definition: Linker.php:1632
setupSkinUserCss(OutputPage $out)
Add skin specific stylesheets Calling this method with an $out of anything but the same OutputPage in...
$searchPage
getRevisionId()
Get the current revision ID.
Definition: Skin.php:237
escapeSearchLink()
Definition: Skin.php:724
getSkinName()
Definition: Skin.php:137
static getAllowedSkins()
Fetch the list of user-selectable skins in regards to $wgSkipSkins.
Definition: Skin.php:72
if the prop value should be in the metadata multi language array can modify can modify 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:1473
static getDefaultInstance()
Definition: SkinFactory.php:50
static element($element, $attribs=[], $contents= '')
Identical to rawElement(), but HTML-escapes $contents (like Xml::element()).
Definition: Html.php:230
getUser()
Get the User object.
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
Definition: hooks.txt:2338
bottomScripts()
This gets called shortly before the "" tag.
Definition: Skin.php:592
getSkinStylePath($name)
Return a fully resolved style path url to images or styles stored in the current skins's folder...
Definition: Skin.php:1013
static makeUrlDetails($name, $urlaction= '')
these return an array with the 'href' and boolean 'exists'
Definition: Skin.php:1125
static makeKnownUrlDetails($name, $urlaction= '')
Make URL details where the article exists (or at least it's convenient to think so) ...
Definition: Skin.php:1141
static singleton()
Get the signleton instance of this class.
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:1798
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 $page
Definition: hooks.txt:2338
wfGetLangObj($langcode=false)
Return a Language object from $langcode.
static makeSpecialUrlSubpage($name, $subpage, $urlaction= '')
Definition: Skin.php:1063
$wgEnableSidebarCache
If on, the sidebar navigation links are cached for users with the current language set...
userLink($userId, $userName, $altUserName=false)
Definition: Skin.php:1601
getOutput()
Get the OutputPage object.
Allows to change the fields on the form that will be generated $name
Definition: hooks.txt:310