MediaWiki REL1_31
Skin.php
Go to the documentation of this file.
1<?php
24
36abstract 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() {
79 global $wgSkipSkins;
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() {
398 global $wgSquidMaxage;
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() {
774 $searchPage = SpecialPage::getTitleFor( 'Search' );
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 ) {
809 $title = Title::newFromText( $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() {
866 global $wgResourceBasePath;
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() {
969 Title::newMainPage(),
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 = '' ) {
1100 $title = Title::newMainPage();
1101 self::checkTitle( $title, '' );
1102
1103 return $title->getLinkURL( $urlaction );
1104 }
1105
1117 static function makeSpecialUrl( $name, $urlaction = '', $proto = null ) {
1118 $title = SpecialPage::getSafeTitleFor( $name );
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() );
1144 self::checkTitle( $title, $name );
1145 return $title->getLocalURL( $urlaction );
1146 }
1147
1153 static function makeUrl( $name, $urlaction = '' ) {
1154 $title = Title::newFromText( $name );
1155 self::checkTitle( $title, $name );
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 );
1183 self::checkTitle( $title, $name );
1184
1185 return $title->getLocalURL( $urlaction );
1186 }
1187
1194 static function makeUrlDetails( $name, $urlaction = '' ) {
1195 $title = Title::newFromText( $name );
1196 self::checkTitle( $title, $name );
1197
1198 return [
1199 'href' => $title->getLocalURL( $urlaction ),
1200 'exists' => $title->isKnown(),
1201 ];
1202 }
1203
1210 static function makeKnownUrlDetails( $name, $urlaction = '' ) {
1211 $title = Title::newFromText( $name );
1212 self::checkTitle( $title, $name );
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 ) ) {
1228 $title = Title::newFromText( $name );
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
1372 global $wgExternalLinkTarget;
1373 if ( $wgExternalLinkTarget ) {
1374 $extraAttribs['target'] = $wgExternalLinkTarget;
1375 }
1376 } else {
1377 $title = Title::newFromText( $link );
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
1507 global $wgSiteNotice;
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
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}
$wgRightsIcon
Override for copyright metadata.
$wgRightsUrl
Set this to specify an external URL containing details about the content license used on your wiki.
$wgRenderHashAppend
Append a configured value to the parser cache and the sitenotice key so that they can be kept separat...
$wgStyleVersion
Bump this number when changing the global style sheets and JavaScript.
$wgUseAjax
Enable AJAX framework.
$wgFallbackSkin
Fallback skin used when the skin defined by $wgDefaultSkin can't be found.
$wgNoFollowLinks
If true, external URL links in wiki text will be given the rel="nofollow" attribute as a hint to sear...
$wgSiteNotice
Site notice shown at the top of each page.
$wgRightsText
If either $wgRightsUrl or $wgRightsPage is specified then this variable gives the text for the link.
$wgEnableWriteAPI
Allow the API to be used to perform write operations (page edits, rollback, etc.) when an authorised ...
$wgResourceBasePath
The default 'remoteBasePath' value for instances of ResourceLoaderFileModule.
$wgSidebarCacheExpiry
Expiry time for the sidebar cache, in seconds.
$wgFooterIcons
Abstract list of footer icons for skins in place of old copyrightico and poweredbyico code You can ad...
$wgEnableSidebarCache
If on, the sidebar navigation links are cached for users with the current language set.
$wgNoFollowDomainExceptions
If this is set to an array of domains, external links to these domain names (or any subdomains) will ...
$wgSkipSkins
Specify the names of skins that should not be presented in the list of available skins in user prefer...
$wgDefaultSkin
Default skin, for new users and anonymous visitors.
$wgSquidMaxage
Cache TTL for the CDN sent as s-maxage (without ESI) or Surrogate-Control (with ESI).
$wgUseCategoryBrowser
Use experimental, DMOZ-like category browser.
$wgExternalLinkTarget
Set a default target for external links, e.g.
$wgEnableAPI
Enable the MediaWiki API for convenient access to machine-readable data via api.php.
$wgStylePath
The URL path of the skins directory.
$wgLogo
The URL path of the wiki logo.
$wgRightsPage
Override for copyright metadata.
wfGetLangObj( $langcode=false)
Return a Language object from $langcode.
wfDebug( $text, $dest='all', array $context=[])
Sends a line to the debug log if enabled or, optionally, to a comment in output.
wfExpandIRI( $url)
Take a URL, make sure it's expanded to fully qualified, and replace any encoded non-ASCII Unicode cha...
wfUrlProtocols( $includeProtocolRelative=true)
Returns a regular expression of url protocols.
wfMatchesDomainList( $url, $domains)
Check whether a given URL has a domain that occurs in a given set of domains.
wfWikiID()
Get an ASCII string identifying this wiki This is used as a prefix in memcached keys.
$messages
$fallback
$line
Definition cdb.php:59
The simplest way of implementing IContextSource is to hold a RequestContext as a member variable and ...
msg( $key)
Get a Message object with context set Parameters are the same as wfMessage()
Class representing a list of titles The execute() method checks them all for existence and adds them ...
Definition LinkBatch.php:34
static link( $target, $html=null, $customAttribs=[], $query=[], $options=[])
This function returns an HTML link to the given target.
Definition Linker.php:107
static linkKnown( $target, $html=null, $customAttribs=[], $query=[], $options=[ 'known'])
Identical to link(), except $options defaults to 'known'.
Definition Linker.php:164
static makeExternalLink( $url, $text, $escape=true, $linktype='', $attribs=[], $title=null)
Make an external link.
Definition Linker.php:843
MediaWiki exception.
MediaWikiServices is the service locator for the application scope of MediaWiki.
static singleton()
Get the signleton instance of this class.
This class should be covered by a general architecture document which does not exist as of January 20...
static makeConfigSetScript(array $configuration)
Returns JS code which will set the MediaWiki configuration array to the given value.
static makeInlineScript( $script)
Returns an HTML script tag that runs given JS code after startup and base modules.
The main skin class which provides methods and properties for all other skins.
Definition Skin.php:36
aboutLink()
Gets the link to the wiki's about page.
Definition Skin.php:1025
isRevisionCurrent()
Whether the revision displayed is the latest revision of the page.
Definition Skin.php:299
static makeInternalOrExternalUrl( $name)
If url string starts with http, consider as external URL, else internal.
Definition Skin.php:1166
afterContentHook()
This runs a hook to allow extensions placing their stuff after content and article metadata (e....
Definition Skin.php:619
string $stylename
Stylesheets set to use.
Definition Skin.php:49
getNewtalks()
Gets new talk page messages for the current user and returns an appropriate alert message (or an empt...
Definition Skin.php:1407
mainPageLink()
Gets the link to the wiki's main page.
Definition Skin.php:967
static getAllowedSkins()
Fetch the list of user-selectable skins in regards to $wgSkipSkins.
Definition Skin.php:78
getSkinStylePath( $name)
Return a fully resolved style path url to images or styles stored in the current skins's folder.
Definition Skin.php:1082
getCachedNotice( $name)
Get a cached notice.
Definition Skin.php:1500
static makeMainPageUrl( $urlaction='')
Definition Skin.php:1099
static makeKnownUrlDetails( $name, $urlaction='')
Make URL details where the article exists (or at least it's convenient to think so)
Definition Skin.php:1210
generateDebugHTML()
Generate debug data HTML for displaying at the bottom of the main content area.
Definition Skin.php:645
getCopyrightIcon()
Definition Skin.php:835
privacyLink()
Gets the link to the wiki's privacy policy page.
Definition Skin.php:1017
footerLinkTitle( $desc, $page)
Definition Skin.php:999
getSiteNotice()
Get the site notice.
Definition Skin.php:1550
getHtmlElementAttributes()
Return values for <html> element.
Definition Skin.php:452
static getSkinNames()
Fetch the set of available skins.
Definition Skin.php:55
static normalizeKey( $key)
Normalize a skin preference value to a form that can be loaded.
Definition Skin.php:99
getSkinName()
Definition Skin.php:153
getUndeleteLink()
Definition Skin.php:688
getPoweredBy()
Gets the powered by MediaWiki icon.
Definition Skin.php:865
getCategoryLinks()
Definition Skin.php:493
escapeSearchLink()
Definition Skin.php:781
static makeUrlDetails( $name, $urlaction='')
these return an array with the 'href' and boolean 'exists'
Definition Skin.php:1194
getLogo()
URL to the logo.
Definition Skin.php:476
$mRelevantTitle
Definition Skin.php:42
addToSidebar(&$bar, $message)
Add content from a sidebar system message Currently only used for MediaWiki:Sidebar (but may be used ...
Definition Skin.php:1304
static makeSpecialUrlSubpage( $name, $subpage, $urlaction='')
Definition Skin.php:1132
getRelevantUser()
Return the "relevant" user.
Definition Skin.php:347
setRelevantTitle( $t)
Set the "relevant" title.
Definition Skin.php:309
logoText( $align='')
Definition Skin.php:916
addToBodyAttributes( $out, &$bodyAttrs)
This will be called by OutputPage::headElement when it is creating the "<body>" tag,...
Definition Skin.php:468
$mRelevantUser
Definition Skin.php:43
drawCategoryBrowser( $tree)
Render the array as a series of links.
Definition Skin.php:561
static checkTitle(&$title, $name)
make sure we have some title to operate on
Definition Skin.php:1226
static makeUrl( $name, $urlaction='')
Definition Skin.php:1153
getPageClasses( $title)
TODO: document.
Definition Skin.php:424
getSearchLink()
Definition Skin.php:773
editUrlOptions()
Return URL options for the 'edit page' link.
Definition Skin.php:1044
static makeVariablesScript( $data)
Definition Skin.php:382
showEmailUser( $id)
Definition Skin.php:1058
static makeNSUrl( $name, $urlaction='', $namespace=NS_MAIN)
this can be passed the NS number as defined in Language.php
Definition Skin.php:1181
buildSidebar()
Build an array that represents the sidebar(s), the navigation bar among them.
Definition Skin.php:1256
getCopyright( $type='detect')
Definition Skin.php:789
printSource()
Text with the permalink to the source page, usually shown on the footer of a printed page.
Definition Skin.php:670
shouldPreloadLogo()
Whether the logo should be preloaded with an HTTP link header or not.
Definition Skin.php:486
string null $skinname
Definition Skin.php:40
setRelevantUser( $u)
Set the "relevant" user.
Definition Skin.php:335
setupSkinUserCss(OutputPage $out)
Add skin specific stylesheets Calling this method with an $out of anything but the same OutputPage in...
static getSkinNameMessages()
Fetch the skinname messages for available skins.
Definition Skin.php:63
makeFooterIcon( $icon, $withImage='withImage')
Renders a $wgFooterIcons icon according to the method's arguments.
Definition Skin.php:941
getRevisionId()
Get the current revision ID.
Definition Skin.php:290
__construct( $skinname=null)
Definition Skin.php:144
preloadExistence()
Preload the existence of three commonly-requested pages in a single query.
Definition Skin.php:245
bottomScripts()
This gets called shortly before the "</body>" tag.
Definition Skin.php:654
outputPage(OutputPage $out=null)
Outputs the HTML generated by other functions.
doEditSectionLink(Title $nt, $section, $tooltip=null, $lang=false)
Create a section edit link.
Definition Skin.php:1586
disclaimerLink()
Gets the link to the wiki's general disclaimers page.
Definition Skin.php:1033
getDefaultModules()
Defines the ResourceLoader modules that should be added to the skin It is recommended that skins wish...
Definition Skin.php:173
static makeSpecialUrl( $name, $urlaction='', $proto=null)
Make a URL for a Special Page using the given query and protocol.
Definition Skin.php:1117
lastModified()
Get the timestamp of the latest revision, formatted in user language.
Definition Skin.php:889
initPage(OutputPage $out)
Definition Skin.php:160
static getDynamicStylesheetQuery()
Get the query to generate a dynamic stylesheet.
Definition Skin.php:397
subPageSubtitle( $out=null)
Definition Skin.php:717
addToSidebarPlain(&$bar, $text)
Add content from plain text.
Definition Skin.php:1315
footerLink( $desc, $page)
Returns an HTML link for use in the footer.
Definition Skin.php:982
static makeI18nUrl( $name, $urlaction='')
Definition Skin.php:1142
getRelevantTitle()
Return the "relevant" title.
Definition Skin.php:323
getCategories()
Definition Skin.php:584
static validateTarget( $target, User $sender=null)
Validate target User.
static resolveAlias( $alias)
Given a special page name with a possible subpage, return an array where the first element is the spe...
Represents a title within MediaWiki.
Definition Title.php:39
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
Definition User.php:53
static newFromName( $name, $validate='valid')
Static factory method for creation from username.
Definition User.php:591
static newFromId( $id)
Static factory method for creation from a given user ID.
Definition User.php:614
static isIP( $name)
Does the string match an anonymous IP address?
Definition User.php:943
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
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:57
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
namespace being checked & $result
Definition hooks.txt:2323
either a plain
Definition hooks.txt:2056
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
namespace and then decline to actually register it file or subcat img or subcat $title
Definition hooks.txt:964
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;div ...>$1&lt;/div>"). - flags Integer display flags(NO_ACTION_LINK, NO_EXTRA_USER_LINKS) 'LogException':Called before an exception(or PHP error) is logged. This is meant for integration with external error aggregation services
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
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
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
usually copyright or history_copyright This message must be in HTML not wikitext & $link
Definition hooks.txt:3021
Allows to change the fields on the form that will be generated $name
Definition hooks.txt:302
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
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
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
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:247
const NS_MAIN
Definition Defines.php:74
const NS_CATEGORY
Definition Defines.php:88
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
$cache
Definition mcc.php:33
$searchPage
$lines
Definition router.php:61
if(!isset( $args[0])) $lang