MediaWiki REL1_33
Skin.php
Go to the documentation of this file.
1<?php
26
38abstract class Skin extends ContextSource {
42 protected $skinname = null;
43
44 protected $mRelevantTitle = null;
45 protected $mRelevantUser = null;
46
51 public $stylename = null;
52
57 static function getSkinNames() {
58 return SkinFactory::getDefaultInstance()->getSkinNames();
59 }
60
65 static function getSkinNameMessages() {
66 $messages = [];
67 foreach ( self::getSkinNames() as $skinKey => $skinName ) {
68 $messages[] = "skinname-$skinKey";
69 }
70 return $messages;
71 }
72
80 public static function getAllowedSkins() {
81 global $wgSkipSkins;
82
83 $allowedSkins = self::getSkinNames();
84
85 foreach ( $wgSkipSkins as $skip ) {
86 unset( $allowedSkins[$skip] );
87 }
88
89 return $allowedSkins;
90 }
91
101 static function normalizeKey( $key ) {
103
104 $skinNames = self::getSkinNames();
105
106 // Make keys lowercase for case-insensitive matching.
107 $skinNames = array_change_key_case( $skinNames, CASE_LOWER );
108 $key = strtolower( $key );
109 $defaultSkin = strtolower( $wgDefaultSkin );
110 $fallbackSkin = strtolower( $wgFallbackSkin );
111
112 if ( $key == '' || $key == 'default' ) {
113 // Don't return the default immediately;
114 // in a misconfiguration we need to fall back.
115 $key = $defaultSkin;
116 }
117
118 if ( isset( $skinNames[$key] ) ) {
119 return $key;
120 }
121
122 // Older versions of the software used a numeric setting
123 // in the user preferences.
124 $fallback = [
125 0 => $defaultSkin,
126 2 => 'cologneblue'
127 ];
128
129 if ( isset( $fallback[$key] ) ) {
130 $key = $fallback[$key];
131 }
132
133 if ( isset( $skinNames[$key] ) ) {
134 return $key;
135 } elseif ( isset( $skinNames[$defaultSkin] ) ) {
136 return $defaultSkin;
137 } else {
138 return $fallbackSkin;
139 }
140 }
141
146 public function __construct( $skinname = null ) {
147 if ( is_string( $skinname ) ) {
148 $this->skinname = $skinname;
149 }
150 }
151
155 public function getSkinName() {
156 return $this->skinname;
157 }
158
162 public function initPage( OutputPage $out ) {
163 $this->preloadExistence();
164 }
165
176 public function getDefaultModules() {
177 $out = $this->getOutput();
178 $user = $this->getUser();
179
180 // Modules declared in the $modules literal are loaded
181 // for ALL users, on ALL pages, in ALL skins.
182 // Keep this list as small as possible!
183 $modules = [
184 'styles' => [
185 // The 'styles' key sets render-blocking style modules
186 // Unlike other keys in $modules, this is an associative array
187 // where each key is its own group pointing to a list of modules
188 'core' => [
189 'mediawiki.legacy.shared',
190 'mediawiki.legacy.commonPrint',
191 ],
192 'content' => [],
193 'syndicate' => [],
194 ],
195 'core' => [
196 'site',
197 'mediawiki.page.startup',
198 ],
199 // modules that enhance the content in some way
200 'content' => [
201 'mediawiki.page.ready',
202 ],
203 // modules relating to search functionality
204 'search' => [
205 'mediawiki.searchSuggest',
206 ],
207 // modules relating to functionality relating to watching an article
208 'watch' => [],
209 // modules which relate to the current users preferences
210 'user' => [],
211 // modules relating to RSS/Atom Feeds
212 'syndicate' => [],
213 ];
214
215 // Preload jquery.tablesorter for mediawiki.page.ready
216 if ( strpos( $out->getHTML(), 'sortable' ) !== false ) {
217 $modules['content'][] = 'jquery.tablesorter';
218 }
219
220 // Preload jquery.makeCollapsible for mediawiki.page.ready
221 if ( strpos( $out->getHTML(), 'mw-collapsible' ) !== false ) {
222 $modules['content'][] = 'jquery.makeCollapsible';
223 $modules['styles']['content'][] = 'jquery.makeCollapsible.styles';
224 }
225
226 // Deprecated since 1.26: Unconditional loading of mediawiki.ui.button
227 // on every page is deprecated. Express a dependency instead.
228 if ( strpos( $out->getHTML(), 'mw-ui-button' ) !== false ) {
229 $modules['styles']['content'][] = 'mediawiki.ui.button';
230 }
231
232 if ( $out->isTOCEnabled() ) {
233 $modules['content'][] = 'mediawiki.toc';
234 $modules['styles']['content'][] = 'mediawiki.toc.styles';
235 }
236
237 // Add various resources if required
238 if ( $user->isLoggedIn()
239 && $user->isAllowedAll( 'writeapi', 'viewmywatchlist', 'editmywatchlist' )
240 && $this->getRelevantTitle()->canExist()
241 ) {
242 $modules['watch'][] = 'mediawiki.page.watch.ajax';
243 }
244
245 if ( $user->getBoolOption( 'editsectiononrightclick' ) ) {
246 $modules['user'][] = 'mediawiki.action.view.rightClickEdit';
247 }
248
249 // Crazy edit-on-double-click stuff
250 if ( $out->isArticle() && $user->getOption( 'editondblclick' ) ) {
251 $modules['user'][] = 'mediawiki.action.view.dblClickEdit';
252 }
253
254 if ( $out->isSyndicated() ) {
255 $modules['styles']['syndicate'][] = 'mediawiki.feedlink';
256 }
257
258 return $modules;
259 }
260
264 protected function preloadExistence() {
265 $titles = [];
266
267 // User/talk link
268 $user = $this->getUser();
269 if ( $user->isLoggedIn() ) {
270 $titles[] = $user->getUserPage();
271 $titles[] = $user->getTalkPage();
272 }
273
274 // Check, if the page can hold some kind of content, otherwise do nothing
275 $title = $this->getRelevantTitle();
276 if ( $title->canExist() ) {
277 if ( $title->isTalkPage() ) {
278 $titles[] = $title->getSubjectPage();
279 } else {
280 $titles[] = $title->getTalkPage();
281 }
282 }
283
284 // Footer links (used by SkinTemplate::prepareQuickTemplate)
285 foreach ( [
286 $this->footerLinkTitle( 'privacy', 'privacypage' ),
287 $this->footerLinkTitle( 'aboutsite', 'aboutpage' ),
288 $this->footerLinkTitle( 'disclaimers', 'disclaimerpage' ),
289 ] as $title ) {
290 if ( $title ) {
291 $titles[] = $title;
292 }
293 }
294
295 Hooks::run( 'SkinPreloadExistence', [ &$titles, $this ] );
296
297 if ( $titles ) {
298 $lb = new LinkBatch( $titles );
299 $lb->setCaller( __METHOD__ );
300 $lb->execute();
301 }
302 }
303
309 public function getRevisionId() {
310 return $this->getOutput()->getRevisionId();
311 }
312
318 public function isRevisionCurrent() {
319 $revID = $this->getRevisionId();
320 return $revID == 0 || $revID == $this->getTitle()->getLatestRevID();
321 }
322
328 public function setRelevantTitle( $t ) {
329 $this->mRelevantTitle = $t;
330 }
331
342 public function getRelevantTitle() {
343 return $this->mRelevantTitle ?? $this->getTitle();
344 }
345
351 public function setRelevantUser( $u ) {
352 $this->mRelevantUser = $u;
353 }
354
363 public function getRelevantUser() {
364 if ( isset( $this->mRelevantUser ) ) {
365 return $this->mRelevantUser;
366 }
367 $title = $this->getRelevantTitle();
368 if ( $title->hasSubjectNamespace( NS_USER ) ) {
369 $rootUser = $title->getRootText();
370 if ( User::isIP( $rootUser ) ) {
371 $this->mRelevantUser = User::newFromName( $rootUser, false );
372 } else {
373 $user = User::newFromName( $rootUser, false );
374
375 if ( $user ) {
376 $user->load( User::READ_NORMAL );
377
378 if ( $user->isLoggedIn() ) {
379 $this->mRelevantUser = $user;
380 }
381 }
382 }
383 return $this->mRelevantUser;
384 }
385 return null;
386 }
387
392 abstract function outputPage( OutputPage $out = null );
393
399 public static function makeVariablesScript( $data, $nonce = null ) {
400 if ( $data ) {
401 return ResourceLoader::makeInlineScript(
402 ResourceLoader::makeConfigSetScript( $data ),
403 $nonce
404 );
405 }
406 return '';
407 }
408
415 public static function getDynamicStylesheetQuery() {
416 return [
417 'action' => 'raw',
418 'ctype' => 'text/css',
419 ];
420 }
421
428 public function setupSkinUserCss( OutputPage $out ) {
429 // Stub.
430 }
431
437 function getPageClasses( $title ) {
438 $numeric = 'ns-' . $title->getNamespace();
439 $user = $this->getUser();
440
441 if ( $title->isSpecialPage() ) {
442 $type = 'ns-special';
443 // T25315: provide a class based on the canonical special page name without subpages
444 list( $canonicalName ) = MediaWikiServices::getInstance()->getSpecialPageFactory()->
445 resolveAlias( $title->getDBkey() );
446 if ( $canonicalName ) {
447 $type .= ' ' . Sanitizer::escapeClass( "mw-special-$canonicalName" );
448 } else {
449 $type .= ' mw-invalidspecialpage';
450 }
451 } else {
452 if ( $title->isTalkPage() ) {
453 $type = 'ns-talk';
454 } else {
455 $type = 'ns-subject';
456 }
457 // T208315: add HTML class when the user can edit the page
458 if ( $title->quickUserCan( 'edit', $user ) ) {
459 $type .= ' mw-editable';
460 }
461 }
462
463 $name = Sanitizer::escapeClass( 'page-' . $title->getPrefixedText() );
464 $root = Sanitizer::escapeClass( 'rootpage-' . $title->getRootTitle()->getPrefixedText() );
465
466 return "$numeric $type $name $root";
467 }
468
473 public function getHtmlElementAttributes() {
474 $lang = $this->getLanguage();
475 return [
476 'lang' => $lang->getHtmlCode(),
477 'dir' => $lang->getDir(),
478 'class' => 'client-nojs',
479 ];
480 }
481
489 function addToBodyAttributes( $out, &$bodyAttrs ) {
490 // does nothing by default
491 }
492
497 function getLogo() {
498 return $this->getConfig()->get( 'Logo' );
499 }
500
510 public function shouldPreloadLogo() {
511 return false;
512 }
513
517 function getCategoryLinks() {
518 $out = $this->getOutput();
519 $allCats = $out->getCategoryLinks();
520
521 if ( $allCats === [] ) {
522 return '';
523 }
524
525 $embed = "<li>";
526 $pop = "</li>";
527
528 $s = '';
529 $colon = $this->msg( 'colon-separator' )->escaped();
530
531 if ( !empty( $allCats['normal'] ) ) {
532 $t = $embed . implode( $pop . $embed, $allCats['normal'] ) . $pop;
533
534 $msg = $this->msg( 'pagecategories' )->numParams( count( $allCats['normal'] ) )->escaped();
535 $linkPage = $this->msg( 'pagecategorieslink' )->inContentLanguage()->text();
536 $title = Title::newFromText( $linkPage );
537 $link = $title ? Linker::link( $title, $msg ) : $msg;
538 $s .= '<div id="mw-normal-catlinks" class="mw-normal-catlinks">' .
539 $link . $colon . '<ul>' . $t . '</ul></div>';
540 }
541
542 # Hidden categories
543 if ( isset( $allCats['hidden'] ) ) {
544 if ( $this->getUser()->getBoolOption( 'showhiddencats' ) ) {
545 $class = ' mw-hidden-cats-user-shown';
546 } elseif ( $this->getTitle()->getNamespace() == NS_CATEGORY ) {
547 $class = ' mw-hidden-cats-ns-shown';
548 } else {
549 $class = ' mw-hidden-cats-hidden';
550 }
551
552 $s .= "<div id=\"mw-hidden-catlinks\" class=\"mw-hidden-catlinks$class\">" .
553 $this->msg( 'hidden-categories' )->numParams( count( $allCats['hidden'] ) )->escaped() .
554 $colon . '<ul>' . $embed . implode( $pop . $embed, $allCats['hidden'] ) . $pop . '</ul>' .
555 '</div>';
556 }
557
558 # optional 'dmoz-like' category browser. Will be shown under the list
559 # of categories an article belong to
560 if ( $this->getConfig()->get( 'UseCategoryBrowser' ) ) {
561 $s .= '<br /><hr />';
562
563 # get a big array of the parents tree
564 $parenttree = $this->getTitle()->getParentCategoryTree();
565 # Skin object passed by reference cause it can not be
566 # accessed under the method subfunction drawCategoryBrowser
567 $tempout = explode( "\n", $this->drawCategoryBrowser( $parenttree ) );
568 # Clean out bogus first entry and sort them
569 unset( $tempout[0] );
570 asort( $tempout );
571 # Output one per line
572 $s .= implode( "<br />\n", $tempout );
573 }
574
575 return $s;
576 }
577
583 function drawCategoryBrowser( $tree ) {
584 $return = '';
585
586 foreach ( $tree as $element => $parent ) {
587 if ( empty( $parent ) ) {
588 # element start a new list
589 $return .= "\n";
590 } else {
591 # grab the others elements
592 $return .= $this->drawCategoryBrowser( $parent ) . ' &gt; ';
593 }
594
595 # add our current element to the list
596 $eltitle = Title::newFromText( $element );
597 $return .= Linker::link( $eltitle, htmlspecialchars( $eltitle->getText() ) );
598 }
599
600 return $return;
601 }
602
606 function getCategories() {
607 $out = $this->getOutput();
608 $catlinks = $this->getCategoryLinks();
609
610 // Check what we're showing
611 $allCats = $out->getCategoryLinks();
612 $showHidden = $this->getUser()->getBoolOption( 'showhiddencats' ) ||
613 $this->getTitle()->getNamespace() == NS_CATEGORY;
614
615 $classes = [ 'catlinks' ];
616 if ( empty( $allCats['normal'] ) && !( !empty( $allCats['hidden'] ) && $showHidden ) ) {
617 $classes[] = 'catlinks-allhidden';
618 }
619
620 return Html::rawElement(
621 'div',
622 [ 'id' => 'catlinks', 'class' => $classes, 'data-mw' => 'interface' ],
623 $catlinks
624 );
625 }
626
641 protected function afterContentHook() {
642 $data = '';
643
644 if ( Hooks::run( 'SkinAfterContent', [ &$data, $this ] ) ) {
645 // adding just some spaces shouldn't toggle the output
646 // of the whole <div/>, so we use trim() here
647 if ( trim( $data ) != '' ) {
648 // Doing this here instead of in the skins to
649 // ensure that the div has the same ID in all
650 // skins
651 $data = "<div id='mw-data-after-content'>\n" .
652 "\t$data\n" .
653 "</div>\n";
654 }
655 } else {
656 wfDebug( "Hook SkinAfterContent changed output processing.\n" );
657 }
658
659 return $data;
660 }
661
667 protected function generateDebugHTML() {
668 return MWDebug::getHTMLDebugLog();
669 }
670
676 function bottomScripts() {
677 // TODO and the suckage continues. This function is really just a wrapper around
678 // OutputPage::getBottomScripts() which takes a Skin param. This should be cleaned
679 // up at some point
680 $chunks = [ $this->getOutput()->getBottomScripts() ];
681
682 // Keep the hook appendage separate to preserve WrappedString objects.
683 // This enables BaseTemplate::getTrail() to merge them where possible.
684 $extraHtml = '';
685 Hooks::run( 'SkinAfterBottomScripts', [ $this, &$extraHtml ] );
686 if ( $extraHtml !== '' ) {
687 $chunks[] = $extraHtml;
688 }
689 return WrappedString::join( "\n", $chunks );
690 }
691
698 function printSource() {
699 $oldid = $this->getRevisionId();
700 if ( $oldid ) {
701 $canonicalUrl = $this->getTitle()->getCanonicalURL( 'oldid=' . $oldid );
702 $url = htmlspecialchars( wfExpandIRI( $canonicalUrl ) );
703 } else {
704 // oldid not available for non existing pages
705 $url = htmlspecialchars( wfExpandIRI( $this->getTitle()->getCanonicalURL() ) );
706 }
707
708 return $this->msg( 'retrievedfrom' )
709 ->rawParams( '<a dir="ltr" href="' . $url . '">' . $url . '</a>' )
710 ->parse();
711 }
712
716 function getUndeleteLink() {
717 $action = $this->getRequest()->getVal( 'action', 'view' );
718 $title = $this->getTitle();
719
720 if ( ( !$title->exists() || $action == 'history' ) &&
721 $title->quickUserCan( 'deletedhistory', $this->getUser() )
722 ) {
723 $n = $title->isDeleted();
724
725 if ( $n ) {
726 if ( $this->getTitle()->quickUserCan( 'undelete', $this->getUser() ) ) {
727 $msg = 'thisisdeleted';
728 } else {
729 $msg = 'viewdeleted';
730 }
731
732 return $this->msg( $msg )->rawParams(
734 SpecialPage::getTitleFor( 'Undelete', $this->getTitle()->getPrefixedDBkey() ),
735 $this->msg( 'restorelink' )->numParams( $n )->escaped() )
736 )->escaped();
737 }
738 }
739
740 return '';
741 }
742
747 function subPageSubtitle( $out = null ) {
748 if ( $out === null ) {
749 $out = $this->getOutput();
750 }
751 $title = $out->getTitle();
752 $subpages = '';
753
754 if ( !Hooks::run( 'SkinSubPageSubtitle', [ &$subpages, $this, $out ] ) ) {
755 return $subpages;
756 }
757
758 if ( $out->isArticle() && MWNamespace::hasSubpages( $title->getNamespace() ) ) {
759 $ptext = $title->getPrefixedText();
760 if ( strpos( $ptext, '/' ) !== false ) {
761 $links = explode( '/', $ptext );
762 array_pop( $links );
763 $c = 0;
764 $growinglink = '';
765 $display = '';
766 $lang = $this->getLanguage();
767
768 foreach ( $links as $link ) {
769 $growinglink .= $link;
770 $display .= $link;
771 $linkObj = Title::newFromText( $growinglink );
772
773 if ( is_object( $linkObj ) && $linkObj->isKnown() ) {
774 $getlink = Linker::linkKnown(
775 $linkObj,
776 htmlspecialchars( $display )
777 );
778
779 $c++;
780
781 if ( $c > 1 ) {
782 $subpages .= $lang->getDirMarkEntity() . $this->msg( 'pipe-separator' )->escaped();
783 } else {
784 $subpages .= '&lt; ';
785 }
786
787 $subpages .= $getlink;
788 $display = '';
789 } else {
790 $display .= '/';
791 }
792 $growinglink .= '/';
793 }
794 }
795 }
796
797 return $subpages;
798 }
799
803 function getSearchLink() {
804 $searchPage = SpecialPage::getTitleFor( 'Search' );
805 return $searchPage->getLocalURL();
806 }
807
811 function escapeSearchLink() {
812 return htmlspecialchars( $this->getSearchLink() );
813 }
814
819 function getCopyright( $type = 'detect' ) {
820 if ( $type == 'detect' ) {
821 if ( !$this->isRevisionCurrent()
822 && !$this->msg( 'history_copyright' )->inContentLanguage()->isDisabled()
823 ) {
824 $type = 'history';
825 } else {
826 $type = 'normal';
827 }
828 }
829
830 if ( $type == 'history' ) {
831 $msg = 'history_copyright';
832 } else {
833 $msg = 'copyright';
834 }
835
836 $config = $this->getConfig();
837
838 if ( $config->get( 'RightsPage' ) ) {
839 $title = Title::newFromText( $config->get( 'RightsPage' ) );
840 $link = Linker::linkKnown( $title, $config->get( 'RightsText' ) );
841 } elseif ( $config->get( 'RightsUrl' ) ) {
842 $link = Linker::makeExternalLink( $config->get( 'RightsUrl' ), $config->get( 'RightsText' ) );
843 } elseif ( $config->get( 'RightsText' ) ) {
844 $link = $config->get( 'RightsText' );
845 } else {
846 # Give up now
847 return '';
848 }
849
850 // Allow for site and per-namespace customization of copyright notice.
851 // @todo Remove deprecated $forContent param from hook handlers and then remove here.
852 $forContent = true;
853
854 Hooks::run(
855 'SkinCopyrightFooter',
856 [ $this->getTitle(), $type, &$msg, &$link, &$forContent ]
857 );
858
859 return $this->msg( $msg )->rawParams( $link )->text();
860 }
861
865 function getCopyrightIcon() {
866 $out = '';
867 $config = $this->getConfig();
868
869 $footerIcons = $config->get( 'FooterIcons' );
870 if ( $footerIcons['copyright']['copyright'] ) {
871 $out = $footerIcons['copyright']['copyright'];
872 } elseif ( $config->get( 'RightsIcon' ) ) {
873 $icon = htmlspecialchars( $config->get( 'RightsIcon' ) );
874 $url = $config->get( 'RightsUrl' );
875
876 if ( $url ) {
877 $out .= '<a href="' . htmlspecialchars( $url ) . '">';
878 }
879
880 $text = htmlspecialchars( $config->get( 'RightsText' ) );
881 $out .= "<img src=\"$icon\" alt=\"$text\" width=\"88\" height=\"31\" />";
882
883 if ( $url ) {
884 $out .= '</a>';
885 }
886 }
887
888 return $out;
889 }
890
895 function getPoweredBy() {
896 $resourceBasePath = $this->getConfig()->get( 'ResourceBasePath' );
897 $url1 = htmlspecialchars(
898 "$resourceBasePath/resources/assets/poweredby_mediawiki_88x31.png"
899 );
900 $url1_5 = htmlspecialchars(
901 "$resourceBasePath/resources/assets/poweredby_mediawiki_132x47.png"
902 );
903 $url2 = htmlspecialchars(
904 "$resourceBasePath/resources/assets/poweredby_mediawiki_176x62.png"
905 );
906 $text = '<a href="//www.mediawiki.org/"><img src="' . $url1
907 . '" srcset="' . $url1_5 . ' 1.5x, ' . $url2 . ' 2x" '
908 . 'height="31" width="88" alt="Powered by MediaWiki" /></a>';
909 Hooks::run( 'SkinGetPoweredBy', [ &$text, $this ] );
910 return $text;
911 }
912
918 protected function lastModified() {
919 $timestamp = $this->getOutput()->getRevisionTimestamp();
920
921 # No cached timestamp, load it from the database
922 if ( $timestamp === null ) {
923 $timestamp = Revision::getTimestampFromId( $this->getTitle(), $this->getRevisionId() );
924 }
925
926 if ( $timestamp ) {
927 $d = $this->getLanguage()->userDate( $timestamp, $this->getUser() );
928 $t = $this->getLanguage()->userTime( $timestamp, $this->getUser() );
929 $s = ' ' . $this->msg( 'lastmodifiedat', $d, $t )->parse();
930 } else {
931 $s = '';
932 }
933
934 if ( MediaWikiServices::getInstance()->getDBLoadBalancer()->getLaggedReplicaMode() ) {
935 $s .= ' <strong>' . $this->msg( 'laggedslavemode' )->parse() . '</strong>';
936 }
937
938 return $s;
939 }
940
945 function logoText( $align = '' ) {
946 if ( $align != '' ) {
947 $a = " style='float: {$align};'";
948 } else {
949 $a = '';
950 }
951
952 $mp = $this->msg( 'mainpage' )->escaped();
953 $mptitle = Title::newMainPage();
954 $url = ( is_object( $mptitle ) ? htmlspecialchars( $mptitle->getLocalURL() ) : '' );
955
956 $logourl = $this->getLogo();
957 $s = "<a href='{$url}'><img{$a} src='{$logourl}' alt='[{$mp}]' /></a>";
958
959 return $s;
960 }
961
970 function makeFooterIcon( $icon, $withImage = 'withImage' ) {
971 if ( is_string( $icon ) ) {
972 $html = $icon;
973 } else { // Assuming array
974 $url = $icon["url"] ?? null;
975 unset( $icon["url"] );
976 if ( isset( $icon["src"] ) && $withImage === 'withImage' ) {
977 // do this the lazy way, just pass icon data as an attribute array
978 $html = Html::element( 'img', $icon );
979 } else {
980 $html = htmlspecialchars( $icon["alt"] );
981 }
982 if ( $url ) {
983 $html = Html::rawElement( 'a',
984 [ "href" => $url, "target" => $this->getConfig()->get( 'ExternalLinkTarget' ) ],
985 $html );
986 }
987 }
988 return $html;
989 }
990
995 function mainPageLink() {
997 Title::newMainPage(),
998 $this->msg( 'mainpage' )->escaped()
999 );
1000
1001 return $s;
1002 }
1003
1010 public function footerLink( $desc, $page ) {
1011 $title = $this->footerLinkTitle( $desc, $page );
1012 if ( !$title ) {
1013 return '';
1014 }
1015
1016 return Linker::linkKnown(
1017 $title,
1018 $this->msg( $desc )->escaped()
1019 );
1020 }
1021
1027 private function footerLinkTitle( $desc, $page ) {
1028 // If the link description has been set to "-" in the default language,
1029 if ( $this->msg( $desc )->inContentLanguage()->isDisabled() ) {
1030 // then it is disabled, for all languages.
1031 return null;
1032 }
1033 // Otherwise, we display the link for the user, described in their
1034 // language (which may or may not be the same as the default language),
1035 // but we make the link target be the one site-wide page.
1036 $title = Title::newFromText( $this->msg( $page )->inContentLanguage()->text() );
1037
1038 return $title ?: null;
1039 }
1040
1045 function privacyLink() {
1046 return $this->footerLink( 'privacy', 'privacypage' );
1047 }
1048
1053 function aboutLink() {
1054 return $this->footerLink( 'aboutsite', 'aboutpage' );
1055 }
1056
1061 function disclaimerLink() {
1062 return $this->footerLink( 'disclaimers', 'disclaimerpage' );
1063 }
1064
1072 function editUrlOptions() {
1073 $options = [ 'action' => 'edit' ];
1074
1075 if ( !$this->isRevisionCurrent() ) {
1076 $options['oldid'] = intval( $this->getRevisionId() );
1077 }
1078
1079 return $options;
1080 }
1081
1086 function showEmailUser( $id ) {
1087 if ( $id instanceof User ) {
1088 $targetUser = $id;
1089 } else {
1090 $targetUser = User::newFromId( $id );
1091 }
1092
1093 # The sending user must have a confirmed email address and the receiving
1094 # user must accept emails from the sender.
1095 return $this->getUser()->canSendEmail()
1096 && SpecialEmailUser::validateTarget( $targetUser, $this->getUser() ) === '';
1097 }
1098
1110 function getSkinStylePath( $name ) {
1111 if ( $this->stylename === null ) {
1112 $class = static::class;
1113 throw new MWException( "$class::\$stylename must be set to use getSkinStylePath()" );
1114 }
1115
1116 return $this->getConfig()->get( 'StylePath' ) . "/{$this->stylename}/$name";
1117 }
1118
1119 /* these are used extensively in SkinTemplate, but also some other places */
1120
1125 static function makeMainPageUrl( $urlaction = '' ) {
1126 $title = Title::newMainPage();
1127 self::checkTitle( $title, '' );
1128
1129 return $title->getLinkURL( $urlaction );
1130 }
1131
1143 static function makeSpecialUrl( $name, $urlaction = '', $proto = null ) {
1144 $title = SpecialPage::getSafeTitleFor( $name );
1145 if ( is_null( $proto ) ) {
1146 return $title->getLocalURL( $urlaction );
1147 } else {
1148 return $title->getFullURL( $urlaction, false, $proto );
1149 }
1150 }
1151
1158 static function makeSpecialUrlSubpage( $name, $subpage, $urlaction = '' ) {
1159 $title = SpecialPage::getSafeTitleFor( $name, $subpage );
1160 return $title->getLocalURL( $urlaction );
1161 }
1162
1168 static function makeI18nUrl( $name, $urlaction = '' ) {
1169 $title = Title::newFromText( wfMessage( $name )->inContentLanguage()->text() );
1170 self::checkTitle( $title, $name );
1171 return $title->getLocalURL( $urlaction );
1172 }
1173
1179 static function makeUrl( $name, $urlaction = '' ) {
1180 $title = Title::newFromText( $name );
1181 self::checkTitle( $title, $name );
1182
1183 return $title->getLocalURL( $urlaction );
1184 }
1185
1192 static function makeInternalOrExternalUrl( $name ) {
1193 if ( preg_match( '/^(?i:' . wfUrlProtocols() . ')/', $name ) ) {
1194 return $name;
1195 } else {
1196 return self::makeUrl( $name );
1197 }
1198 }
1199
1207 static function makeNSUrl( $name, $urlaction = '', $namespace = NS_MAIN ) {
1208 $title = Title::makeTitleSafe( $namespace, $name );
1209 self::checkTitle( $title, $name );
1210
1211 return $title->getLocalURL( $urlaction );
1212 }
1213
1220 static function makeUrlDetails( $name, $urlaction = '' ) {
1221 $title = Title::newFromText( $name );
1222 self::checkTitle( $title, $name );
1223
1224 return [
1225 'href' => $title->getLocalURL( $urlaction ),
1226 'exists' => $title->isKnown(),
1227 ];
1228 }
1229
1236 static function makeKnownUrlDetails( $name, $urlaction = '' ) {
1237 $title = Title::newFromText( $name );
1238 self::checkTitle( $title, $name );
1239
1240 return [
1241 'href' => $title->getLocalURL( $urlaction ),
1242 'exists' => true
1243 ];
1244 }
1245
1252 static function checkTitle( &$title, $name ) {
1253 if ( !is_object( $title ) ) {
1254 $title = Title::newFromText( $name );
1255 if ( !is_object( $title ) ) {
1256 $title = Title::newFromText( '--error: link target missing--' );
1257 }
1258 }
1259 }
1260
1282 public function buildSidebar() {
1283 $callback = function ( $old = null, &$ttl = null ) {
1284 $bar = [];
1285 $this->addToSidebar( $bar, 'sidebar' );
1286 Hooks::run( 'SkinBuildSidebar', [ $this, &$bar ] );
1287 if ( MessageCache::singleton()->isDisabled() ) {
1288 $ttl = WANObjectCache::TTL_UNCACHEABLE; // bug T133069
1289 }
1290
1291 return $bar;
1292 };
1293
1294 $msgCache = MessageCache::singleton();
1295 $wanCache = MediaWikiServices::getInstance()->getMainWANObjectCache();
1296 $config = $this->getConfig();
1297
1298 $sidebar = $config->get( 'EnableSidebarCache' )
1299 ? $wanCache->getWithSetCallback(
1300 $wanCache->makeKey( 'sidebar', $this->getLanguage()->getCode() ),
1301 $config->get( 'SidebarCacheExpiry' ),
1302 $callback,
1303 [
1304 'checkKeys' => [
1305 // Unless there is both no exact $code override nor an i18n definition
1306 // in the software, the only MediaWiki page to check is for $code.
1307 $msgCache->getCheckKey( $this->getLanguage()->getCode() )
1308 ],
1309 'lockTSE' => 30
1310 ]
1311 )
1312 : $callback();
1313
1314 // Apply post-processing to the cached value
1315 Hooks::run( 'SidebarBeforeOutput', [ $this, &$sidebar ] );
1316
1317 return $sidebar;
1318 }
1319
1329 public function addToSidebar( &$bar, $message ) {
1330 $this->addToSidebarPlain( $bar, $this->msg( $message )->inContentLanguage()->plain() );
1331 }
1332
1340 function addToSidebarPlain( &$bar, $text ) {
1341 $lines = explode( "\n", $text );
1342
1343 $heading = '';
1344 $config = $this->getConfig();
1345 $messageTitle = $config->get( 'EnableSidebarCache' )
1346 ? Title::newMainPage() : $this->getTitle();
1347
1348 foreach ( $lines as $line ) {
1349 if ( strpos( $line, '*' ) !== 0 ) {
1350 continue;
1351 }
1352 $line = rtrim( $line, "\r" ); // for Windows compat
1353
1354 if ( strpos( $line, '**' ) !== 0 ) {
1355 $heading = trim( $line, '* ' );
1356 if ( !array_key_exists( $heading, $bar ) ) {
1357 $bar[$heading] = [];
1358 }
1359 } else {
1360 $line = trim( $line, '* ' );
1361
1362 if ( strpos( $line, '|' ) !== false ) { // sanity check
1363 $line = MessageCache::singleton()->transform( $line, false, null, $messageTitle );
1364 $line = array_map( 'trim', explode( '|', $line, 2 ) );
1365 if ( count( $line ) !== 2 ) {
1366 // Second sanity check, could be hit by people doing
1367 // funky stuff with parserfuncs... (T35321)
1368 continue;
1369 }
1370
1371 $extraAttribs = [];
1372
1373 $msgLink = $this->msg( $line[0] )->title( $messageTitle )->inContentLanguage();
1374 if ( $msgLink->exists() ) {
1375 $link = $msgLink->text();
1376 if ( $link == '-' ) {
1377 continue;
1378 }
1379 } else {
1380 $link = $line[0];
1381 }
1382 $msgText = $this->msg( $line[1] )->title( $messageTitle );
1383 if ( $msgText->exists() ) {
1384 $text = $msgText->text();
1385 } else {
1386 $text = $line[1];
1387 }
1388
1389 if ( preg_match( '/^(?i:' . wfUrlProtocols() . ')/', $link ) ) {
1390 $href = $link;
1391
1392 // Parser::getExternalLinkAttribs won't work here because of the Namespace things
1393 if ( $config->get( 'NoFollowLinks' ) &&
1394 !wfMatchesDomainList( $href, $config->get( 'NoFollowDomainExceptions' ) )
1395 ) {
1396 $extraAttribs['rel'] = 'nofollow';
1397 }
1398
1399 if ( $config->get( 'ExternalLinkTarget' ) ) {
1400 $extraAttribs['target'] = $config->get( 'ExternalLinkTarget' );
1401 }
1402 } else {
1403 $title = Title::newFromText( $link );
1404
1405 if ( $title ) {
1406 $title = $title->fixSpecialName();
1407 $href = $title->getLinkURL();
1408 } else {
1409 $href = 'INVALID-TITLE';
1410 }
1411 }
1412
1413 $bar[$heading][] = array_merge( [
1414 'text' => $text,
1415 'href' => $href,
1416 'id' => Sanitizer::escapeIdForAttribute( 'n-' . strtr( $line[1], ' ', '-' ) ),
1417 'active' => false,
1418 ], $extraAttribs );
1419 } else {
1420 continue;
1421 }
1422 }
1423 }
1424
1425 return $bar;
1426 }
1427
1433 function getNewtalks() {
1434 $newMessagesAlert = '';
1435 $user = $this->getUser();
1436 $newtalks = $user->getNewMessageLinks();
1437 $out = $this->getOutput();
1438
1439 // Allow extensions to disable or modify the new messages alert
1440 if ( !Hooks::run( 'GetNewMessagesAlert', [ &$newMessagesAlert, $newtalks, $user, $out ] ) ) {
1441 return '';
1442 }
1443 if ( $newMessagesAlert ) {
1444 return $newMessagesAlert;
1445 }
1446
1447 if ( count( $newtalks ) == 1 && WikiMap::isCurrentWikiId( $newtalks[0]['wiki'] ) ) {
1448 $uTalkTitle = $user->getTalkPage();
1449 $lastSeenRev = $newtalks[0]['rev'] ?? null;
1450 $nofAuthors = 0;
1451 if ( $lastSeenRev !== null ) {
1452 $plural = true; // Default if we have a last seen revision: if unknown, use plural
1453 $latestRev = Revision::newFromTitle( $uTalkTitle, false, Revision::READ_NORMAL );
1454 if ( $latestRev !== null ) {
1455 // Singular if only 1 unseen revision, plural if several unseen revisions.
1456 $plural = $latestRev->getParentId() !== $lastSeenRev->getId();
1457 $nofAuthors = $uTalkTitle->countAuthorsBetween(
1458 $lastSeenRev, $latestRev, 10, 'include_new' );
1459 }
1460 } else {
1461 // Singular if no revision -> diff link will show latest change only in any case
1462 $plural = false;
1463 }
1464 $plural = $plural ? 999 : 1;
1465 // 999 signifies "more than one revision". We don't know how many, and even if we did,
1466 // the number of revisions or authors is not necessarily the same as the number of
1467 // "messages".
1468 $newMessagesLink = Linker::linkKnown(
1469 $uTalkTitle,
1470 $this->msg( 'newmessageslinkplural' )->params( $plural )->escaped(),
1471 [],
1472 $uTalkTitle->isRedirect() ? [ 'redirect' => 'no' ] : []
1473 );
1474
1475 $newMessagesDiffLink = Linker::linkKnown(
1476 $uTalkTitle,
1477 $this->msg( 'newmessagesdifflinkplural' )->params( $plural )->escaped(),
1478 [],
1479 $lastSeenRev !== null
1480 ? [ 'oldid' => $lastSeenRev->getId(), 'diff' => 'cur' ]
1481 : [ 'diff' => 'cur' ]
1482 );
1483
1484 if ( $nofAuthors >= 1 && $nofAuthors <= 10 ) {
1485 $newMessagesAlert = $this->msg(
1486 'youhavenewmessagesfromusers',
1487 $newMessagesLink,
1488 $newMessagesDiffLink
1489 )->numParams( $nofAuthors, $plural );
1490 } else {
1491 // $nofAuthors === 11 signifies "11 or more" ("more than 10")
1492 $newMessagesAlert = $this->msg(
1493 $nofAuthors > 10 ? 'youhavenewmessagesmanyusers' : 'youhavenewmessages',
1496 )->numParams( $plural );
1497 }
1498 $newMessagesAlert = $newMessagesAlert->text();
1499 # Disable CDN cache
1500 $out->setCdnMaxage( 0 );
1501 } elseif ( count( $newtalks ) ) {
1502 $sep = $this->msg( 'newtalkseparator' )->escaped();
1503 $msgs = [];
1504
1505 foreach ( $newtalks as $newtalk ) {
1506 $msgs[] = Xml::element(
1507 'a',
1508 [ 'href' => $newtalk['link'] ], $newtalk['wiki']
1509 );
1510 }
1511 $parts = implode( $sep, $msgs );
1512 $newMessagesAlert = $this->msg( 'youhavenewmessagesmulti' )->rawParams( $parts )->escaped();
1513 $out->setCdnMaxage( 0 );
1514 }
1515
1516 return $newMessagesAlert;
1517 }
1518
1526 private function getCachedNotice( $name ) {
1527 $config = $this->getConfig();
1528
1529 if ( $name === 'default' ) {
1530 // special case
1531 $notice = $config->get( 'SiteNotice' );
1532 if ( empty( $notice ) ) {
1533 return false;
1534 }
1535 } else {
1536 $msg = $this->msg( $name )->inContentLanguage();
1537 if ( $msg->isBlank() ) {
1538 return '';
1539 } elseif ( $msg->isDisabled() ) {
1540 return false;
1541 }
1542 $notice = $msg->plain();
1543 }
1544
1545 $services = MediaWikiServices::getInstance();
1546 $cache = $services->getMainWANObjectCache();
1547 $parsed = $cache->getWithSetCallback(
1548 // Use the extra hash appender to let eg SSL variants separately cache
1549 // Key is verified with md5 hash of unparsed wikitext
1550 $cache->makeKey( $name, $config->get( 'RenderHashAppend' ), md5( $notice ) ),
1551 // TTL in seconds
1552 600,
1553 function () use ( $notice ) {
1554 return $this->getOutput()->parseAsInterface( $notice );
1555 }
1556 );
1557
1558 $contLang = $services->getContentLanguage();
1559 return Html::rawElement(
1560 'div',
1561 [
1562 'id' => 'localNotice',
1563 'lang' => $contLang->getHtmlCode(),
1564 'dir' => $contLang->getDir()
1565 ],
1566 $parsed
1567 );
1568 }
1569
1575 function getSiteNotice() {
1576 $siteNotice = '';
1577
1578 if ( Hooks::run( 'SiteNoticeBefore', [ &$siteNotice, $this ] ) ) {
1579 if ( is_object( $this->getUser() ) && $this->getUser()->isLoggedIn() ) {
1580 $siteNotice = $this->getCachedNotice( 'sitenotice' );
1581 } else {
1582 $anonNotice = $this->getCachedNotice( 'anonnotice' );
1583 if ( $anonNotice === false ) {
1584 $siteNotice = $this->getCachedNotice( 'sitenotice' );
1585 } else {
1586 $siteNotice = $anonNotice;
1587 }
1588 }
1589 if ( $siteNotice === false ) {
1590 $siteNotice = $this->getCachedNotice( 'default' );
1591 }
1592 }
1593
1594 Hooks::run( 'SiteNoticeAfter', [ &$siteNotice, $this ] );
1595 return $siteNotice;
1596 }
1597
1611 public function doEditSectionLink( Title $nt, $section, $tooltip, Language $lang ) {
1612 // HTML generated here should probably have userlangattributes
1613 // added to it for LTR text on RTL pages
1614
1615 $attribs = [];
1616 if ( !is_null( $tooltip ) ) {
1617 $attribs['title'] = $this->msg( 'editsectionhint' )->rawParams( $tooltip )
1618 ->inLanguage( $lang )->text();
1619 }
1620
1621 $links = [
1622 'editsection' => [
1623 'text' => $this->msg( 'editsection' )->inLanguage( $lang )->escaped(),
1624 'targetTitle' => $nt,
1625 'attribs' => $attribs,
1626 'query' => [ 'action' => 'edit', 'section' => $section ],
1627 'options' => [ 'noclasses', 'known' ]
1628 ]
1629 ];
1630
1631 Hooks::run( 'SkinEditSectionLinks', [ $this, $nt, $section, $tooltip, &$links, $lang ] );
1632
1633 $result = '<span class="mw-editsection"><span class="mw-editsection-bracket">[</span>';
1634
1635 $linksHtml = [];
1636 foreach ( $links as $k => $linkDetails ) {
1637 $linksHtml[] = Linker::link(
1638 $linkDetails['targetTitle'],
1639 $linkDetails['text'],
1640 $linkDetails['attribs'],
1641 $linkDetails['query'],
1642 $linkDetails['options']
1643 );
1644 }
1645
1646 $result .= implode(
1647 '<span class="mw-editsection-divider">'
1648 . $this->msg( 'pipe-separator' )->inLanguage( $lang )->escaped()
1649 . '</span>',
1650 $linksHtml
1651 );
1652
1653 $result .= '<span class="mw-editsection-bracket">]</span></span>';
1654 return $result;
1655 }
1656
1657}
This list may contain false positives That usually means there is additional text with links below the first Each row contains links to the first and second as well as the first line of the second redirect text
and that you know you can do these things To protect your we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights These restrictions translate to certain responsibilities for you if you distribute copies of the or if you modify it For if you distribute copies of such a whether gratis or for a you must give the recipients all the rights that you have You must make sure that receive or can get the source code And you must show them these terms so they know their rights We protect your rights with two and(2) offer you this license which gives you legal permission to copy
$wgFallbackSkin
Fallback skin used when the skin defined by $wgDefaultSkin can't be found.
$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.
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.
$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()
Internationalisation code.
Definition Language.php:36
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:84
static linkKnown( $target, $html=null, $customAttribs=[], $query=[], $options=[ 'known'])
Identical to link(), except $options defaults to 'known'.
Definition Linker.php:146
static makeExternalLink( $url, $text, $escape=true, $linktype='', $attribs=[], $title=null)
Make an external link.
Definition Linker.php:842
MediaWiki exception.
MediaWikiServices is the service locator for the application scope of MediaWiki.
This class should be covered by a general architecture document which does not exist as of January 20...
static getTimestampFromId( $title, $id, $flags=0)
Get rev_timestamp from rev_id, without loading the rest of the row.
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:137
The main skin class which provides methods and properties for all other skins.
Definition Skin.php:38
aboutLink()
Gets the link to the wiki's about page.
Definition Skin.php:1053
isRevisionCurrent()
Whether the revision displayed is the latest revision of the page.
Definition Skin.php:318
static makeInternalOrExternalUrl( $name)
If url string starts with http, consider as external URL, else internal.
Definition Skin.php:1192
afterContentHook()
This runs a hook to allow extensions placing their stuff after content and article metadata (e....
Definition Skin.php:641
string $stylename
Stylesheets set to use.
Definition Skin.php:51
getNewtalks()
Gets new talk page messages for the current user and returns an appropriate alert message (or an empt...
Definition Skin.php:1433
mainPageLink()
Gets the link to the wiki's main page.
Definition Skin.php:995
static getAllowedSkins()
Fetch the list of user-selectable skins in regards to $wgSkipSkins.
Definition Skin.php:80
doEditSectionLink(Title $nt, $section, $tooltip, Language $lang)
Create a section edit link.
Definition Skin.php:1611
getSkinStylePath( $name)
Return a fully resolved style path URL to images or styles stored in the current skin's folder.
Definition Skin.php:1110
getCachedNotice( $name)
Get a cached notice.
Definition Skin.php:1526
static makeMainPageUrl( $urlaction='')
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:1236
generateDebugHTML()
Generate debug data HTML for displaying at the bottom of the main content area.
Definition Skin.php:667
getCopyrightIcon()
Definition Skin.php:865
privacyLink()
Gets the link to the wiki's privacy policy page.
Definition Skin.php:1045
footerLinkTitle( $desc, $page)
Definition Skin.php:1027
getSiteNotice()
Get the site notice.
Definition Skin.php:1575
getHtmlElementAttributes()
Return values for <html> element.
Definition Skin.php:473
static getSkinNames()
Fetch the set of available skins.
Definition Skin.php:57
static normalizeKey( $key)
Normalize a skin preference value to a form that can be loaded.
Definition Skin.php:101
getSkinName()
Definition Skin.php:155
getUndeleteLink()
Definition Skin.php:716
getPoweredBy()
Gets the powered by MediaWiki icon.
Definition Skin.php:895
getCategoryLinks()
Definition Skin.php:517
escapeSearchLink()
Definition Skin.php:811
static makeUrlDetails( $name, $urlaction='')
these return an array with the 'href' and boolean 'exists'
Definition Skin.php:1220
getLogo()
URL to the logo.
Definition Skin.php:497
$mRelevantTitle
Definition Skin.php:44
addToSidebar(&$bar, $message)
Add content from a sidebar system message Currently only used for MediaWiki:Sidebar (but may be used ...
Definition Skin.php:1329
static makeSpecialUrlSubpage( $name, $subpage, $urlaction='')
Definition Skin.php:1158
getRelevantUser()
Return the "relevant" user.
Definition Skin.php:363
setRelevantTitle( $t)
Set the "relevant" title.
Definition Skin.php:328
logoText( $align='')
Definition Skin.php:945
addToBodyAttributes( $out, &$bodyAttrs)
This will be called by OutputPage::headElement when it is creating the "<body>" tag,...
Definition Skin.php:489
$mRelevantUser
Definition Skin.php:45
drawCategoryBrowser( $tree)
Render the array as a series of links.
Definition Skin.php:583
static checkTitle(&$title, $name)
make sure we have some title to operate on
Definition Skin.php:1252
static makeUrl( $name, $urlaction='')
Definition Skin.php:1179
getPageClasses( $title)
TODO: document.
Definition Skin.php:437
getSearchLink()
Definition Skin.php:803
editUrlOptions()
Return URL options for the 'edit page' link.
Definition Skin.php:1072
showEmailUser( $id)
Definition Skin.php:1086
static makeNSUrl( $name, $urlaction='', $namespace=NS_MAIN)
this can be passed the NS number as defined in Language.php
Definition Skin.php:1207
buildSidebar()
Build an array that represents the sidebar(s), the navigation bar among them.
Definition Skin.php:1282
getCopyright( $type='detect')
Definition Skin.php:819
printSource()
Text with the permalink to the source page, usually shown on the footer of a printed page.
Definition Skin.php:698
shouldPreloadLogo()
Whether the logo should be preloaded with an HTTP link header or not.
Definition Skin.php:510
string null $skinname
Definition Skin.php:42
setRelevantUser( $u)
Set the "relevant" user.
Definition Skin.php:351
setupSkinUserCss(OutputPage $out)
Hook point for adding style modules to OutputPage.
Definition Skin.php:428
static getSkinNameMessages()
Fetch the skinname messages for available skins.
Definition Skin.php:65
makeFooterIcon( $icon, $withImage='withImage')
Renders a $wgFooterIcons icon according to the method's arguments.
Definition Skin.php:970
getRevisionId()
Get the current revision ID.
Definition Skin.php:309
__construct( $skinname=null)
Definition Skin.php:146
preloadExistence()
Preload the existence of three commonly-requested pages in a single query.
Definition Skin.php:264
bottomScripts()
This gets called shortly before the "</body>" tag.
Definition Skin.php:676
outputPage(OutputPage $out=null)
Outputs the HTML generated by other functions.
disclaimerLink()
Gets the link to the wiki's general disclaimers page.
Definition Skin.php:1061
getDefaultModules()
Defines the ResourceLoader modules that should be added to the skin It is recommended that skins wish...
Definition Skin.php:176
static makeSpecialUrl( $name, $urlaction='', $proto=null)
Make a URL for a Special Page using the given query and protocol.
Definition Skin.php:1143
lastModified()
Get the timestamp of the latest revision, formatted in user language.
Definition Skin.php:918
static makeVariablesScript( $data, $nonce=null)
Definition Skin.php:399
initPage(OutputPage $out)
Definition Skin.php:162
static getDynamicStylesheetQuery()
Get the query to generate a dynamic stylesheet.
Definition Skin.php:415
subPageSubtitle( $out=null)
Definition Skin.php:747
addToSidebarPlain(&$bar, $text)
Add content from plain text.
Definition Skin.php:1340
footerLink( $desc, $page)
Returns an HTML link for use in the footer.
Definition Skin.php:1010
static makeI18nUrl( $name, $urlaction='')
Definition Skin.php:1168
getRelevantTitle()
Return the "relevant" title.
Definition Skin.php:342
getCategories()
Definition Skin.php:606
static validateTarget( $target, User $sender=null)
Validate target User.
Represents a title within MediaWiki.
Definition Title.php:40
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
Definition User.php:48
static newFromName( $name, $validate='valid')
Static factory method for creation from username.
Definition User.php:585
static newFromId( $id)
Static factory method for creation from a given user ID.
Definition User.php:609
static isIP( $name)
Does the string match an anonymous IP address?
Definition User.php:967
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
namespace being checked & $result
Definition hooks.txt:2340
this hook is for auditing only or null if authentication failed before getting that far or null if we can t even determine that When $user is not it can be in the form of< username >< more info > e g for bot passwords intended to be added to log contexts Fields it might only if the login was with a bot password 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:855
either a plain
Definition hooks.txt:2054
the value of this variable comes from LanguageConverter indexed by page_id indexed by prefixed DB keys on which the links will be shown can modify can modify can modify this should be populated with an alert message to that effect $newtalks
Definition hooks.txt:1725
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:1999
namespace and then decline to actually register it file or subcat img or subcat $title
Definition hooks.txt:955
this hook is for auditing only or null if authentication failed before getting that far or null if we can t even determine that When $user is not null
Definition hooks.txt:783
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:2004
static configuration should be added through ResourceLoaderGetConfigVars instead can be used to get the real title e g db for database replication lag or jobqueue for job queue size converted to pseudo seconds It is possible to add more fields and they will be returned to the user in the API response after the basic globals have been set but before ordinary actions take place or wrap services the preferred way to define a new service is the $wgServiceWiringFiles array $services
Definition hooks.txt:2290
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 use $formDescriptor instead 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 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:2011
usually copyright or history_copyright This message must be in HTML not wikitext & $link
Definition hooks.txt:3069
Allows to change the fields on the form that will be generated $name
Definition hooks.txt:271
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:2012
return true to allow those checks to and false if checking is done & $user
Definition hooks.txt:1510
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:3070
$data
Utility to generate mapping file used in mw.Title (phpCharToUpper.json)
const NS_MAIN
Definition Defines.php:73
const NS_CATEGORY
Definition Defines.php:87
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
$parent
$lines
Definition router.php:61
if(!isset( $args[0])) $lang