Standardize skin
[mediawiki.git] / includes / Skin.php
blob7af2d63090fa3ddf0b2be8419890a292cf4df54a
1 <?
2 # See skin.doc
4 # These are the INTERNAL names, which get mapped
5 # directly to class names. For display purposes, the
6 # Language class has internationalized names
8 /* private */ $wgValidSkinNames = array(
9 "Standard", "Nostalgia", "CologneBlue" #, "Smarty", "Montparnasse"
12 # For some odd PHP bug, this function can't be part of a class
13 function getCategories ()
15 global $wgOut , $wgTitle , $wgUseCategoryMagic , $wgUser ;
16 if ( !isset ( $wgUseCategoryMagic ) || !$wgUseCategoryMagic ) return "" ;
17 if ( count ( $wgOut->mCategoryLinks ) == 0 ) return "" ;
18 if ( !$wgOut->isArticle() ) return "" ;
19 $sk = $wgUser->getSkin() ;
20 $s = "" ;
21 $s .= "\n<br>\n";
22 $s .= $sk->makeKnownLink ( "Special:Categories" , "Categories" , "article=".$wgTitle->getDBkey() ) ;
23 $t = implode ( " | " , $wgOut->mCategoryLinks ) ;
24 if ( $t != "" ) $s .= " : " ;
25 $s .= $t ;
26 return $s ;
30 class RecentChangesClass {
31 var $secureName , $displayName , $link , $namespace ;
32 var $oldid , $diffid , $timestamp , $curlink , $lastlink , $usertalklink , $versionlink ;
33 var $usercomment , $userlink ;
34 var $isminor , $isnew , $watched , $islog ;
35 } ;
37 class Skin {
39 /* private */ var $lastdate, $lastline;
41 var $rc_cache ; # Cache for Enhanced Recent Changes
42 var $rccc ; # Recent Changes Cache Counter for visibility toggle
45 function Skin()
49 function getSkinNames()
51 global $wgValidSkinNames;
52 return $wgValidSkinNames;
55 function getStylesheet()
57 return "wikistandard.css";
60 function qbSetting()
62 global $wgOut, $wgUser;
64 if ( $wgOut->isQuickbarSupressed() ) { return 0; }
65 $q = $wgUser->getOption( "quickbar" );
66 if ( "" == $q ) { $q = 0; }
67 return $q;
70 function initPage()
72 global $wgOut, $wgStyleSheetPath;
73 $fname = "Skin::initPage";
74 wfProfileIn( $fname );
76 $wgOut->addLink( "shortcut icon", "", "/favicon.ico" );
77 if ( $wgOut->isPrintable() ) { $ss = "wikiprintable.css"; }
78 else { $ss = $this->getStylesheet(); }
79 $wgOut->addLink( "stylesheet", "", "{$wgStyleSheetPath}/{$ss}" );
80 wfProfileOut( $fname );
83 function outputPage( &$out ) {
84 global $wgDebugComments;
86 wfProfileIn( "Skin::outputPage" );
87 $this->initPage();
88 $out->out( $out->headElement() );
90 $out->out( "\n<body" );
91 $ops = $this->getBodyOptions();
92 foreach ( $ops as $name => $val ) {
93 $out->out( " $name='$val'" );
95 $out->out( ">\n" );
96 if ( $wgDebugComments ) {
97 $out->out( "<!-- Wiki debugging output:\n" .
98 $out->mDebugtext . "-->\n" );
100 $out->out( $this->beforeContent() );
102 $out->out( $out->mBodytext );
104 $out->out( $this->afterContent() );
106 wfProfileClose();
107 $out->out( $out->reportTime() );
109 $out->out( "\n</body></html>" );
112 function getHeadScripts() {
113 global $wgStyleSheetPath;
114 $r = "<script type=\"text/javascript\" src=\"{$wgStyleSheetPath}/wikibits.js\"></script>\n";
115 return $r;
118 function getUserStyles()
120 $s = "<style type='text/css'><!--\n";
121 $s .= $this->doGetUserStyles();
122 $s .= "//--></style>\n";
123 return $s;
126 function doGetUserStyles()
128 global $wgUser;
130 $s = "";
131 if ( 1 == $wgUser->getOption( "underline" ) ) {
132 # Don't override browser settings
133 } else {
134 # CHECK MERGE @@@
135 # Force no underline
136 $s .= "a.stub, a.new, a.internal, a.external { " .
137 "text-decoration: none; }\n";
139 if ( 1 == $wgUser->getOption( "highlightbroken" ) ) {
140 $s .= "a.new, #quickbar a.new { color: #CC2200; }\n";
142 if ( 1 == $wgUser->getOption( "justify" ) ) {
143 $s .= "#article { text-align: justify; }\n";
145 return $s;
148 function getBodyOptions()
150 global $wgUser, $wgTitle, $wgNamespaceBackgrounds, $wgOut, $oldid, $redirect, $diff,$action;
152 if ( 0 != $wgTitle->getNamespace() ) {
153 $a = array( "bgcolor" => "#ffffec" );
155 else $a = array( "bgcolor" => "#FFFFFF" );
156 if($wgOut->isArticle() && $wgUser->getOption("editondblclick")
158 (!$wgTitle->isProtected() || $wgUser->isSysop())
161 $n = $wgTitle->getPrefixedURL();
162 $t = wfMsg( "editthispage" );
163 $oid = $red = "";
164 if ( $redirect ) { $red = "&redirect={$redirect}"; }
165 if ( $oldid && ! isset( $diff ) ) {
166 $oid = "&oldid={$oldid}";
168 $s = wfLocalUrlE($n,"action=edit{$oid}{$red}");
169 $s = "document.location = \"" .$s ."\";";
170 $a += array ("ondblclick" => $s);
173 $a['onload'] = $wgOut->getOnloadHandler();
174 return $a;
177 function getExternalLinkAttributes( $link, $text )
179 global $wgUser, $wgOut, $wgLang;
181 $link = urldecode( $link );
182 $link = $wgLang->checkTitleEncoding( $link );
183 $link = str_replace( "_", " ", $link );
184 $link = wfEscapeHTML( $link );
186 if ( $wgOut->isPrintable() ) { $r = " class='printable'"; }
187 else { $r = " class='external'"; }
189 if ( 1 == $wgUser->getOption( "hover" ) ) {
190 $r .= " title=\"{$link}\"";
192 return $r;
195 function getInternalLinkAttributes( $link, $text, $broken = false )
197 global $wgUser, $wgOut;
199 $link = urldecode( $link );
200 $link = str_replace( "_", " ", $link );
201 $link = wfEscapeHTML( $link );
203 if ( $wgOut->isPrintable() ) {
204 $r = " class='printable'";
205 } else if ( $broken == "stub" ) {
206 $r = " class='stub'";
207 } else if ( $broken == "yes" ) {
208 $r = " class='new'";
209 } else {
210 $r = " class='internal'";
213 if ( 1 == $wgUser->getOption( "hover" ) ) {
214 $r .= " title=\"{$link}\"";
216 return $r;
219 function getInternalLinkAttributesObj( &$nt, $text, $broken = false )
221 global $wgUser, $wgOut;
223 if ( $wgOut->isPrintable() ) {
224 $r = " class='printable'";
225 } else if ( $broken == "stub" ) {
226 $r = " class='stub'";
227 } else if ( $broken == "yes" ) {
228 $r = " class='new'";
229 } else {
230 $r = " class='internal'";
233 if ( 1 == $wgUser->getOption( "hover" ) ) {
234 $r .= ' title ="' . $nt->getEscapedText() . '"';
236 return $r;
239 function getLogo()
241 global $wgLogo;
242 return $wgLogo;
245 # This will be called immediately after the <body> tag. Split into
246 # two functions to make it easier to subclass.
248 function beforeContent()
250 global $wgUser, $wgOut, $wgSiteNotice;
252 if ( $wgOut->isPrintable() ) {
253 $s = $this->pageTitle() . $this->pageSubtitle() . "\n";
254 $s .= "\n<div class='bodytext'>";
255 return $s;
257 if( $wgSiteNotice ) {
258 $note = "\n<div id='notice' style='font-weight: bold; color: red; text-align: center'>$wgSiteNotice</div>\n";
259 } else {
260 $note = "";
262 return $this->doBeforeContent() . $note;
265 function doBeforeContent()
267 global $wgUser, $wgOut, $wgTitle, $wgLang;
268 $fname = "Skin::doBeforeContent";
269 wfProfileIn( $fname );
271 $s = "";
272 $qb = $this->qbSetting();
274 if( $langlinks = $this->otherLanguages() ) {
275 $rows = 2;
276 $borderhack = "";
277 } else {
278 $rows = 1;
279 $langlinks = false;
280 $borderhack = "class='top'";
283 $s .= "\n<div id='content'>\n<div id='topbar'>" .
284 "<table width='98%' border=0 cellspacing=0><tr>";
286 $shove = ($qb != 0);
287 $left = ($qb == 1 || $qb == 3);
288 if($wgLang->isRTL()) $left = !$left;
290 if ( !$shove ) {
291 $s .= "<td class='top' align=left valign=top rowspan='{$rows}'>" .
292 $this->logoText() . "</td>";
293 } elseif( $left ) {
294 $s .= $this->getQuickbarCompensator( $rows );
296 $l = $wgLang->isRTL() ? "right" : "left";
297 $s .= "<td {$borderhack} align='$l' valign='top'>";
299 $s .= $this->topLinks() ;
300 $s .= "<p class='subtitle'>" . $this->pageTitleLinks();
302 $r = $wgLang->isRTL() ? "left" : "right";
303 $s .= "</td>\n<td {$borderhack} valign='top' align='$r' nowrap>";
304 $s .= $this->nameAndLogin();
305 $s .= "\n<br>" . $this->searchForm() . "</td>";
307 if ( $langlinks ) {
308 $s .= "</tr>\n<tr><td class='top' colspan=\"2\">$langlinks</td>";
311 if ( $shove && !$left ) { # Right
312 $s .= $this->getQuickbarCompensator( $rows );
314 $s .= "</tr></table>\n</div>\n";
315 $s .= "\n<div id='article'>";
317 $s .= $this->pageTitle();
318 $s .= $this->pageSubtitle() ;
319 $s .= getCategories(); // For some odd reason, zhis can't be a function of the object
320 $s .= "\n<p>";
321 wfProfileOut( $fname );
322 return $s;
325 function getQuickbarCompensator( $rows = 1 )
327 return "<td width='152' rowspan='{$rows}'>&nbsp;</td>";
330 # This gets called immediately before the </body> tag.
332 function afterContent()
334 global $wgUser, $wgOut, $wgServer;
335 global $wgTitle;
337 if ( $wgOut->isPrintable() ) {
338 $s = "\n</div>\n";
340 $u = htmlspecialchars( $wgServer . $wgTitle->getFullURL() );
341 $u = "<a href=\"$u\">$u</a>";
342 $rf = wfMsg( "retrievedfrom", $u );
344 if ( $wgOut->isArticle() ) {
345 $lm = "<br>" . $this->lastModified();
346 } else { $lm = ""; }
348 $cr = wfMsg( "gnunote" );
349 $s .= "<p><em>{$rf}{$lm} {$cr}</em>\n";
350 return $s;
352 return $this->doAfterContent();
355 function doAfterContent()
357 global $wgUser, $wgOut, $wgLang;
358 $fname = "Skin::doAfterContent";
359 wfProfileIn( $fname );
360 wfProfileIn( "$fname-1" );
362 $s = "\n</div><br clear=all>\n";
363 $s .= "\n<div id='footer'>";
364 $s .= "<table width='98%' border=0 cellspacing=0><tr>";
366 wfProfileOut( "$fname-1" );
367 wfProfileIn( "$fname-2" );
369 $qb = $this->qbSetting();
370 $shove = ($qb != 0);
371 $left = ($qb == 1 || $qb == 3);
372 if($wgLang->isRTL()) $left = !$left;
374 if ( $shove && $left ) { # Left
375 $s .= $this->getQuickbarCompensator();
377 wfProfileOut( "$fname-2" );
378 wfProfileIn( "$fname-3" );
379 $l = $wgLang->isRTL() ? "right" : "left";
380 $s .= "<td class='bottom' align='$l' valign='top'>";
382 $s .= $this->bottomLinks();
383 $s .= "\n<br>" . $this->mainPageLink()
384 . " | " . $this->aboutLink()
385 . " | " . $this->specialLink( "recentchanges" )
386 . " | " . $this->searchForm()
387 . "<br>" . $this->pageStats();
389 $s .= "</td>";
390 if ( $shove && !$left ) { # Right
391 $s .= $this->getQuickbarCompensator();
393 $s .= "</tr></table>\n</div>\n</div>\n";
395 wfProfileOut( "$fname-3" );
396 wfProfileIn( "$fname-4" );
397 if ( 0 != $qb ) { $s .= $this->quickBar(); }
398 wfProfileOut( "$fname-4" );
399 wfProfileOut( $fname );
400 return $s;
403 function pageTitleLinks()
405 global $wgOut, $wgTitle, $oldid, $action, $diff, $wgUser, $wgLang, $wgUseApproval ;
407 $s = $this->printableLink();
408 if ( wfMsg ( "disclaimers" ) != "-" ) $s .= " | " . $this->makeKnownLink( wfMsg( "disclaimerpage" ), wfMsg( "disclaimers" ) ) ;
410 if ( $wgOut->isArticle() ) {
411 if ( $wgTitle->getNamespace() == Namespace::getImage() ) {
412 $name = $wgTitle->getDBkey();
413 $link = wfEscapeHTML( wfImageUrl( $name ) );
414 $style = $this->getInternalLinkAttributes( $link, $name );
415 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>";
417 # This will show the "Approve" link if $wgUseApproval=true;
418 if ( isset ( $wgUseApproval ) && $wgUseApproval )
420 $t = $wgTitle->getDBkey();
421 $name = "Approve this article" ;
422 $link = "http://test.wikipedia.org/w/magnus/wiki.phtml?title={$t}&action=submit&doit=1" ;
423 #wfEscapeHTML( wfImageUrl( $name ) );
424 $style = $this->getExternalLinkAttributes( $link, $name );
425 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>" ;
427 if ( "history" == $action || isset( $diff ) || isset( $oldid ) ) {
428 $s .= " | " . $this->makeKnownLink( $wgTitle->getPrefixedText(),
429 wfMsg( "currentrev" ) );
432 if ( $wgUser->getNewtalk() ) {
433 # do not show "You have new messages" text when we are viewing our
434 # own talk page
436 if(!(strcmp($wgTitle->getText(),$wgUser->getName()) == 0 &&
437 $wgTitle->getNamespace()==Namespace::getTalk(Namespace::getUser()))) {
438 $n =$wgUser->getName();
439 $tl = $this->makeKnownLink( $wgLang->getNsText(
440 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
441 wfMsg("newmessageslink") );
442 $s.=" | <strong>". wfMsg( "newmessages", $tl ) . "</strong>";
445 if( $wgUser->isSysop() &&
446 (($wgTitle->getArticleId() == 0) || ($action == "history")) &&
447 ($n = $wgTitle->isDeleted() ) ) {
448 $s .= " | " . wfMsg( "thisisdeleted",
449 $this->makeKnownLink(
450 $wgLang->SpecialPage( "Undelete/" . $wgTitle->getPrefixedDBkey() ),
451 wfMsg( "restorelink", $n ) ) );
453 return $s;
456 function printableLink()
458 global $wgOut, $wgTitle, $oldid, $action;
460 $q = "";
461 foreach( $_GET as $var => $val ) {
462 if( $var != "title" && $var != "printable" )
463 $q .= urlencode( $var ) . "=" . urlencode( $val );
465 if( !empty( $q ) ) $q .= "&";
467 $s = $this->makeKnownLink( $wgTitle->getPrefixedText(),
468 WfMsg( "printableversion" ), "{$q}printable=yes" );
469 return $s;
472 function pageTitle()
474 global $wgOut, $wgTitle, $wgUser;
476 $s = "<h1 class='pagetitle'>" . $wgOut->getPageTitle() . "</h1>";
477 if($wgUser->getOption("editsectiononrightclick") && $wgTitle->userCanEdit()) { $s=$this->editSectionScript(0,$s);}
478 return $s;
481 function pageSubtitle()
483 global $wgOut,$wgTitle,$wgNamespacesWithSubpages;
485 $sub = $wgOut->getSubtitle();
486 if ( "" == $sub ) {
487 global $wgExtraSubtitle;
488 $sub = wfMsg( "fromwikipedia" ) . $wgExtraSubtitle;
490 if($wgOut->isArticle() && $wgNamespacesWithSubpages[$wgTitle->getNamespace()]) {
491 $ptext=$wgTitle->getPrefixedText();
492 if(preg_match("/\//",$ptext)) {
493 $sub.="</p><p class='subpages'>";
494 $links=explode("/",$ptext);
495 $c=0;
496 $growinglink="";
497 foreach($links as $link) {
498 $c++;
499 if ($c<count($links)) {
500 $growinglink .= $link;
501 $getlink = $this->makeLink( $growinglink, $link );
502 if(preg_match("/class='new'/i",$getlink)) { break; } # this is a hack, but it saves time
503 if ($c>1) {
504 $sub .= " | ";
505 } else {
506 $sub .="&lt; ";
508 $sub .= $getlink;
509 $growinglink.="/";
515 $s = "<p class='subtitle'>{$sub}\n";
516 return $s;
519 function nameAndLogin()
521 global $wgUser, $wgTitle, $wgLang, $wgShowIPinHeader;
523 $li = $wgLang->specialPage( "Userlogin" );
524 $lo = $wgLang->specialPage( "Userlogout" );
526 $s = "";
527 if ( 0 == $wgUser->getID() ) {
528 if( $wgShowIPinHeader ) {
529 $n = getenv( "REMOTE_ADDR" );
531 $tl = $this->makeKnownLink( $wgLang->getNsText(
532 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
533 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
535 $s .= $n . " (".$tl.")";
536 } else {
537 $s .= wfMsg("notloggedin");
540 $rt = $wgTitle->getPrefixedURL();
541 if ( 0 == strcasecmp( urlencode( $lo ), $rt ) ) {
542 $q = "";
543 } else { $q = "returnto={$rt}"; }
545 $s .= "\n<br>" . $this->makeKnownLink( $li,
546 wfMsg( "login" ), $q );
547 } else {
548 $n = $wgUser->getName();
549 $rt = $wgTitle->getPrefixedURL();
550 $tl = $this->makeKnownLink( $wgLang->getNsText(
551 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
552 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
554 $tl = " ({$tl})";
556 $s .= $this->makeKnownLink( $wgLang->getNsText(
557 Namespace::getUser() ) . ":{$n}", $n ) . "{$tl}<br>" .
558 $this->makeKnownLink( $lo, wfMsg( "logout" ),
559 "returnto={$rt}" ) . " | " .
560 $this->specialLink( "preferences" );
562 $s .= " | " . $this->makeKnownLink( wfMsg( "helppage" ),
563 wfMsg( "help" ) );
565 return $s;
568 function searchForm()
570 global $search;
572 $s = "<form name='search' class='inline' method=get action=\""
573 . wfLocalUrl( "" ) . "\">"
574 . "<input type=text name=\"search\" size=19 value=\""
575 . htmlspecialchars(substr($search,0,256)) . "\">\n"
576 . "<input type=submit name=\"go\" value=\"" . wfMsg ("go") . "\">&nbsp;"
577 . "<input type=submit value=\"" . wfMsg ("search") . "\"></form>";
579 return $s;
582 function topLinks()
584 global $wgOut;
585 $sep = " |\n";
587 $s = $this->mainPageLink() . $sep
588 . $this->specialLink( "recentchanges" );
590 if ( $wgOut->isArticle() ) {
591 $s .= $sep . $this->editThisPage()
592 . $sep . $this->historyLink();
594 # Many people don't like this dropdown box
595 #$s .= $sep . $this->specialPagesList();
597 return $s;
600 function bottomLinks()
602 global $wgOut, $wgUser, $wgTitle;
603 $sep = " |\n";
605 $s = "";
606 if ( $wgOut->isArticle() ) {
607 $s .= "<strong>" . $this->editThisPage() . "</strong>";
608 if ( 0 != $wgUser->getID() ) {
609 $s .= $sep . $this->watchThisPage();
611 $s .= $sep . $this->talkLink()
612 . $sep . $this->historyLink()
613 . $sep . $this->whatLinksHere()
614 . $sep . $this->watchPageLinksLink();
616 if ( $wgTitle->getNamespace() == Namespace::getUser()
617 || $wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser()) )
620 $id=User::idFromName($wgTitle->getText());
621 $ip=User::isIP($wgTitle->getText());
623 if($id || $ip) { # both anons and non-anons have contri list
624 $s .= $sep . $this->userContribsLink();
626 if ( 0 != $wgUser->getID() ) { # show only to signed in users
627 if($id) { # can only email non-anons
628 $s .= $sep . $this->emailUserLink();
632 if ( $wgUser->isSysop() && $wgTitle->getArticleId() ) {
633 $s .= "\n<br>" . $this->deleteThisPage() .
634 $sep . $this->protectThisPage() .
635 $sep . $this->moveThisPage();
637 $s .= "<br>\n" . $this->otherLanguages();
639 return $s;
642 function pageStats()
644 global $wgOut, $wgLang, $wgArticle;
645 global $oldid, $diff, $wgDisableCounters;
647 if ( ! $wgOut->isArticle() ) { return ""; }
648 if ( isset( $oldid ) || isset( $diff ) ) { return ""; }
649 if ( 0 == $wgArticle->getID() ) { return ""; }
651 if ( $wgDisableCounters ) {
652 $s = "";
653 } else {
654 $count = $wgArticle->getCount();
655 $s = wfMsg( "viewcount", $count );
657 $s .= $this->lastModified();
658 $s .= " " . wfMsg( "gnunote" );
659 return "<span id='pagestats'>{$s}</span>";
662 function lastModified()
664 global $wgLang, $wgArticle;
666 $d = $wgLang->timeanddate( $wgArticle->getTimestamp(), true );
667 $s = " " . wfMsg( "lastmodified", $d );
668 return $s;
671 function logoText( $align = "" )
673 if ( "" != $align ) { $a = " align='{$align}'"; }
674 else { $a = ""; }
676 $mp = wfMsg( "mainpage" );
677 $s = "<a href=\"" . wfLocalUrlE( urlencode( $mp ) )
678 . "\"><img{$a} border=0 src=\""
679 . $this->getLogo() . "\" alt=\"" . "[{$mp}]\"></a>";
680 return $s;
683 function quickBar()
685 global $wgOut, $wgTitle, $wgUser, $action, $wgLang;
686 global $wpPreview, $wgDisableUploads;
688 $fname = "Skin::quickBar";
689 wfProfileIn( $fname );
691 $tns=$wgTitle->getNamespace();
693 $s = "\n<div id='quickbar'>";
694 $s .= "\n" . $this->logoText() . "\n<hr class='sep'>";
696 $sep = "\n<br>";
697 $s .= $this->mainPageLink()
698 . $sep . $this->specialLink( "recentchanges" )
699 . $sep . $this->specialLink( "randompage" );
700 if ($wgUser->getID()) {
701 $s.= $sep . $this->specialLink( "watchlist" ) ;
702 $s .= $sep .$this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
703 wfMsg( "mycontris" ), "target=" . wfUrlencode($wgUser->getName() ) );
706 // only show watchlist link if logged in
707 if ( wfMsg ( "currentevents" ) != "-" ) $s .= $sep . $this->makeKnownLink( wfMsg( "currentevents" ), "" ) ;
708 $s .= "\n<br><hr class='sep'>";
709 $articleExists = $wgTitle->getArticleId();
710 if ( $wgOut->isArticle() || $action =="edit" || $action =="history" || $wpPreview) {
711 if($wgOut->isArticle()) {
712 $s .= "<strong>" . $this->editThisPage() . "</strong>";
713 } else { # backlink to the article in edit or history mode
714 if($articleExists){ # no backlink if no article
715 switch($tns) {
716 case 0:
717 $text = wfMsg("articlepage");
718 break;
719 case 1:
720 $text = wfMsg("viewtalkpage");
721 break;
722 case 2:
723 $text = wfMsg("userpage");
724 break;
725 case 3:
726 $text = wfMsg("viewtalkpage");
727 break;
728 case 4:
729 $text = wfMsg("wikipediapage");
730 break;
731 case 5:
732 $text = wfMsg("viewtalkpage");
733 break;
734 case 6:
735 $text = wfMsg("imagepage");
736 break;
737 case 7:
738 $text = wfMsg("viewtalkpage");
739 break;
740 default:
741 $text= wfMsg("articlepage");
744 $link = $wgTitle->getText();
745 if ($nstext = $wgLang->getNsText($tns) ) { # add namespace if necessary
746 $link = $nstext . ":" . $link ;
749 $s .= $this->makeLink( $link, $text );
750 } elseif( $wgTitle->getNamespace() != Namespace::getSpecial() ) {
751 # we just throw in a "New page" text to tell the user that he's in edit mode,
752 # and to avoid messing with the separator that is prepended to the next item
753 $s .= "<strong>" . wfMsg("newpage") . "</strong>";
759 if( $tns%2 && $action!="edit" && !$wpPreview) {
760 $s.="<br>".$this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg("postcomment"),"action=edit&section=new");
764 watching could cause problems in edit mode:
765 if user edits article, then loads "watch this article" in background and then saves
766 article with "Watch this article" checkbox disabled, the article is transparently
767 unwatched. Therefore we do not show the "Watch this page" link in edit mode
769 if ( 0 != $wgUser->getID() && $articleExists) {
770 if($action!="edit" && $action!="history" &&
771 $action != "submit" )
773 $s .= $sep . $this->watchThisPage();
775 if ( $wgTitle->userCanEdit() )
776 $s .= $sep . $this->moveThisPage();
778 if ( $wgUser->isSysop() and $articleExists ) {
779 $s .= $sep . $this->deleteThisPage() .
780 $sep . $this->protectThisPage();
782 $s .= $sep . $this->talkLink();
783 if ($articleExists && $action !="history") {
784 $s .= $sep . $this->historyLink();
786 $s.=$sep . $this->whatLinksHere();
788 if($wgOut->isArticle()) {
789 $s .= $sep . $this->watchPageLinksLink();
792 if ( Namespace::getUser() == $wgTitle->getNamespace()
793 || $wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser())
796 $id=User::idFromName($wgTitle->getText());
797 $ip=User::isIP($wgTitle->getText());
799 if($id||$ip) {
800 $s .= $sep . $this->userContribsLink();
802 if ( 0 != $wgUser->getID() ) {
803 if($id) { # can only email real users
804 $s .= $sep . $this->emailUserLink();
808 $s .= "\n<br><hr class='sep'>";
811 if ( 0 != $wgUser->getID() && !$wgDisableUploads ) {
812 $s .= $this->specialLink( "upload" ) . $sep;
814 $s .= $this->specialLink( "specialpages" )
815 . $sep . $this->bugReportsLink();
817 global $wgSiteSupportPage;
818 if( $wgSiteSupportPage ) {
819 $s .= "\n<br><a href=\"" . htmlspecialchars( $wgSiteSupportPage ) .
820 "\" class=\"internal\">" . wfMsg( "sitesupport" ) . "</a>";
823 $s .= "\n<br></div>\n";
824 wfProfileOut( $fname );
825 return $s;
828 function specialPagesList()
830 global $wgUser, $wgOut, $wgLang, $wgServer, $wgRedirectScript;
831 $a = array();
833 $validSP = $wgLang->getValidSpecialPages();
835 foreach ( $validSP as $name => $desc ) {
836 if ( "" == $desc ) { continue; }
837 $a[$name] = $desc;
839 if ( $wgUser->isSysop() )
841 $sysopSP = $wgLang->getSysopSpecialPages();
843 foreach ( $sysopSP as $name => $desc ) {
844 if ( "" == $desc ) { continue; }
845 $a[$name] = $desc ;
848 if ( $wgUser->isDeveloper() )
850 $devSP = $wgLang->getDeveloperSpecialPages();
852 foreach ( $devSP as $name => $desc ) {
853 if ( "" == $desc ) { continue; }
854 $a[$name] = $desc ;
857 $go = wfMsg( "go" );
858 $sp = wfMsg( "specialpages" );
859 $spp = $wgLang->specialPage( "Specialpages" );
861 $s = "<form id=\"specialpages\" method=\"get\" class=\"inline\" " .
862 "action=\"{$wgServer}{$wgRedirectScript}\">\n";
863 $s .= "<select name=\"wpDropdown\">\n";
864 $s .= "<option value=\"{$spp}\">{$sp}</option>\n";
866 foreach ( $a as $name => $desc ) {
867 $p = $wgLang->specialPage( $name );
868 $s .= "<option value=\"{$p}\">{$desc}</option>\n";
870 $s .= "</select>\n";
871 $s .= "<input type=submit value=\"{$go}\" name=redirect>\n";
872 $s .= "</form>\n";
873 return $s;
876 function mainPageLink()
878 $mp = wfMsg( "mainpage" );
879 $s = $this->makeKnownLink( $mp, $mp );
880 return $s;
883 function copyrightLink()
885 $s = $this->makeKnownLink( wfMsg( "copyrightpage" ),
886 wfMsg( "copyrightpagename" ) );
887 return $s;
890 function aboutLink()
892 $s = $this->makeKnownLink( wfMsg( "aboutpage" ),
893 wfMsg( "aboutwikipedia" ) );
894 return $s;
898 function disclaimerLink()
900 $s = $this->makeKnownLink( wfMsg( "disclaimerpage" ),
901 wfMsg( "disclaimers" ) );
902 return $s;
905 function editThisPage()
907 global $wgOut, $wgTitle, $oldid, $redirect, $diff;
909 if ( ! $wgOut->isArticle() || $diff ) {
910 $s = wfMsg( "protectedpage" );
911 } else {
912 $n = $wgTitle->getPrefixedText();
913 if ( $wgTitle->userCanEdit() ) {
914 $t = wfMsg( "editthispage" );
915 } else {
916 #$t = wfMsg( "protectedpage" );
917 $t = wfMsg( "viewsource" );
919 $oid = $red = "";
921 if ( $redirect ) { $red = "&redirect={$redirect}"; }
922 if ( $oldid && ! isset( $diff ) ) {
923 $oid = "&oldid={$oldid}";
925 $s = $this->makeKnownLink( $n, $t, "action=edit{$oid}{$red}" );
927 return $s;
930 function deleteThisPage()
932 global $wgUser, $wgOut, $wgTitle, $diff;
934 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
935 $n = $wgTitle->getPrefixedText();
936 $t = wfMsg( "deletethispage" );
938 $s = $this->makeKnownLink( $n, $t, "action=delete" );
939 } else {
940 $s = "";
942 return $s;
945 function protectThisPage()
947 global $wgUser, $wgOut, $wgTitle, $diff;
949 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
950 $n = $wgTitle->getPrefixedText();
952 if ( $wgTitle->isProtected() ) {
953 $t = wfMsg( "unprotectthispage" );
954 $q = "action=unprotect";
955 } else {
956 $t = wfMsg( "protectthispage" );
957 $q = "action=protect";
959 $s = $this->makeKnownLink( $n, $t, $q );
960 } else {
961 $s = "";
963 return $s;
966 function watchThisPage()
968 global $wgUser, $wgOut, $wgTitle, $diff;
970 if ( $wgOut->isArticle() && ( ! $diff ) ) {
971 $n = $wgTitle->getPrefixedText();
973 if ( $wgTitle->userIsWatching() ) {
974 $t = wfMsg( "unwatchthispage" );
975 $q = "action=unwatch";
976 } else {
977 $t = wfMsg( "watchthispage" );
978 $q = "action=watch";
980 $s = $this->makeKnownLink( $n, $t, $q );
981 } else {
982 $s = wfMsg( "notanarticle" );
984 return $s;
987 function moveThisPage()
989 global $wgTitle, $wgLang;
991 if ( $wgTitle->userCanEdit() ) {
992 $s = $this->makeKnownLink( $wgLang->specialPage( "Movepage" ),
993 wfMsg( "movethispage" ), "target=" . $wgTitle->getPrefixedURL() );
994 } // no message if page is protected - would be redundant
995 return $s;
998 function historyLink()
1000 global $wgTitle;
1002 $s = $this->makeKnownLink( $wgTitle->getPrefixedText(),
1003 wfMsg( "history" ), "action=history" );
1004 return $s;
1007 function whatLinksHere()
1009 global $wgTitle, $wgLang;
1011 $s = $this->makeKnownLink( $wgLang->specialPage( "Whatlinkshere" ),
1012 wfMsg( "whatlinkshere" ), "target=" . $wgTitle->getPrefixedURL() );
1013 return $s;
1016 function userContribsLink()
1018 global $wgTitle, $wgLang;
1020 $s = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
1021 wfMsg( "contributions" ), "target=" . $wgTitle->getURL() );
1022 return $s;
1025 function emailUserLink()
1027 global $wgTitle, $wgLang;
1029 $s = $this->makeKnownLink( $wgLang->specialPage( "Emailuser" ),
1030 wfMsg( "emailuser" ), "target=" . $wgTitle->getURL() );
1031 return $s;
1034 function watchPageLinksLink()
1036 global $wgOut, $wgTitle, $wgLang;
1038 if ( ! $wgOut->isArticle() ) {
1039 $s = "(" . wfMsg( "notanarticle" ) . ")";
1040 } else {
1041 $s = $this->makeKnownLink( $wgLang->specialPage(
1042 "Recentchangeslinked" ), wfMsg( "recentchangeslinked" ),
1043 "target=" . $wgTitle->getPrefixedURL() );
1045 return $s;
1048 function otherLanguages()
1050 global $wgOut, $wgLang, $wgTitle, $wgUseNewInterlanguage;
1052 $a = $wgOut->getLanguageLinks();
1053 # TEST THIS @@@
1054 if ( 0 == count( $a ) ) {
1055 if ( !$wgUseNewInterlanguage ) return "";
1056 $ns = $wgLang->getNsIndex ( $wgTitle->getNamespace () ) ;
1057 if ( $ns != 0 AND $ns != 1 ) return "" ;
1058 $pn = "Intl" ;
1059 $x = "mode=addlink&xt=".$wgTitle->getDBkey() ;
1060 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1061 wfMsg( "intl" ) , $x );
1064 if ( !$wgUseNewInterlanguage ) {
1065 $s = wfMsg( "otherlanguages" ) . ": ";
1066 } else {
1067 global $wgLanguageCode ;
1068 $x = "mode=zoom&xt=".$wgTitle->getDBkey() ;
1069 $x .= "&xl=".$wgLanguageCode ;
1070 $s = $this->makeKnownLink( $wgLang->specialPage( "Intl" ),
1071 wfMsg( "otherlanguages" ) , $x ) . ": " ;
1074 $s = wfMsg( "otherlanguages" ) . ": ";
1075 $first = true;
1076 if($wgLang->isRTL()) $s .= "<span dir='LTR'>";
1077 foreach( $a as $l ) {
1078 if ( ! $first ) { $s .= " | "; }
1079 $first = false;
1081 $nt = Title::newFromText( $l );
1082 $url = $nt->getFullURL();
1083 $text = $wgLang->getLanguageName( $nt->getInterwiki() );
1085 if ( "" == $text ) { $text = $l; }
1086 $style = $this->getExternalLinkAttributes( $l, $text );
1087 $s .= "<a href=\"{$url}\"{$style}>{$text}</a>";
1089 if($wgLang->isRTL()) $s .= "</span>";
1090 return $s;
1093 function bugReportsLink()
1095 $s = $this->makeKnownLink( wfMsg( "bugreportspage" ),
1096 wfMsg( "bugreports" ) );
1097 return $s;
1100 function dateLink()
1102 global $wgLinkCache;
1103 $t1 = Title::newFromText( gmdate( "F j" ) );
1104 $t2 = Title::newFromText( gmdate( "Y" ) );
1106 $wgLinkCache->suspend();
1107 $id = $t1->getArticleID();
1108 $wgLinkCache->resume();
1110 if ( 0 == $id ) {
1111 $s = $this->makeBrokenLink( $t1->getText() );
1112 } else {
1113 $s = $this->makeKnownLink( $t1->getText() );
1115 $s .= ", ";
1117 $wgLinkCache->suspend();
1118 $id = $t2->getArticleID();
1119 $wgLinkCache->resume();
1121 if ( 0 == $id ) {
1122 $s .= $this->makeBrokenLink( $t2->getText() );
1123 } else {
1124 $s .= $this->makeKnownLink( $t2->getText() );
1126 return $s;
1129 function talkLink()
1131 global $wgLang, $wgTitle, $wgLinkCache;
1133 $tns = $wgTitle->getNamespace();
1134 if ( -1 == $tns ) { return ""; }
1136 $pn = $wgTitle->getText();
1137 $tp = wfMsg( "talkpage" );
1138 if ( Namespace::isTalk( $tns ) ) {
1139 $lns = Namespace::getSubject( $tns );
1140 switch($tns) {
1141 case 1:
1142 $text = wfMsg("articlepage");
1143 break;
1144 case 3:
1145 $text = wfMsg("userpage");
1146 break;
1147 case 5:
1148 $text = wfMsg("wikipediapage");
1149 break;
1150 case 7:
1151 $text = wfMsg("imagepage");
1152 break;
1153 default:
1154 $text= wfMsg("articlepage");
1156 } else {
1158 $lns = Namespace::getTalk( $tns );
1159 $text=$tp;
1161 $n = $wgLang->getNsText( $lns );
1162 if ( "" == $n ) { $link = $pn; }
1163 else { $link = "{$n}:{$pn}"; }
1165 $wgLinkCache->suspend();
1166 $s = $this->makeLink( $link, $text );
1167 $wgLinkCache->resume();
1169 return $s;
1172 function commentLink()
1174 global $wgLang, $wgTitle, $wgLinkCache;
1176 $tns = $wgTitle->getNamespace();
1177 if ( -1 == $tns ) { return ""; }
1179 $lns = ( Namespace::isTalk( $tns ) ) ? $tns : Namespace::getTalk( $tns );
1181 # assert Namespace::isTalk( $lns )
1183 $n = $wgLang->getNsText( $lns );
1184 $pn = $wgTitle->getText();
1186 $link = "{$n}:{$pn}";
1188 $wgLinkCache->suspend();
1189 $s = $this->makeKnownLink($link, wfMsg("postcomment"), "action=edit&section=new");
1190 $wgLinkCache->resume();
1192 return $s;
1195 # After all the page content is transformed into HTML, it makes
1196 # a final pass through here for things like table backgrounds.
1198 function transformContent( $text )
1200 return $text;
1203 # Note: This function MUST call getArticleID() on the link,
1204 # otherwise the cache won't get updated properly. See LINKCACHE.DOC.
1206 function makeLink( $title, $text = "", $query = "", $trail = "" ) {
1207 wfProfileIn( "Skin::makeLink" );
1208 $nt = Title::newFromText( $title );
1209 if ($nt) {
1210 $result = $this->makeLinkObj( Title::newFromText( $title ), $text, $query, $trail );
1211 } else {
1212 wfDebug( "Invalid title passed to Skin::makeLink(): \"$title\"\n" );
1213 $result = $text == "" ? $title : $text;
1216 wfProfileOut( "Skin::makeLink" );
1217 return $result;
1220 function makeKnownLink( $title, $text = "", $query = "", $trail = "" ) {
1221 $nt = Title::newFromText( $title );
1222 if ($nt) {
1223 return $this->makeKnownLinkObj( Title::newFromText( $title ), $text, $query, $trail );
1224 } else {
1225 wfDebug( "Invalid title passed to Skin::makeKnownLink(): \"$title\"\n" );
1226 return $text == "" ? $title : $text;
1230 function makeBrokenLink( $title, $text = "", $query = "", $trail = "" ) {
1231 $nt = Title::newFromText( $title );
1232 if ($nt) {
1233 return $this->makeBrokenLinkObj( Title::newFromText( $title ), $text, $query, $trail );
1234 } else {
1235 wfDebug( "Invalid title passed to Skin::makeBrokenLink(): \"$title\"\n" );
1236 return $text == "" ? $title : $text;
1240 function makeStubLink( $title, $text = "", $query = "", $trail = "" ) {
1241 $nt = Title::newFromText( $title );
1242 if ($nt) {
1243 return $this->makeStubLinkObj( Title::newFromText( $title ), $text, $query, $trail );
1244 } else {
1245 wfDebug( "Invalid title passed to Skin::makeStubLink(): \"$title\"\n" );
1246 return $text == "" ? $title : $text;
1250 # Pass a title object, not a title string
1251 function makeLinkObj( &$nt, $text= "", $query = "", $trail = "" )
1253 global $wgOut, $wgUser;
1254 if ( $nt->isExternal() ) {
1255 $u = $nt->getFullURL();
1256 if ( "" == $text ) { $text = $nt->getPrefixedText(); }
1257 $style = $this->getExternalLinkAttributes( $link, $text );
1259 $inside = "";
1260 if ( "" != $trail ) {
1261 if ( preg_match( "/^([a-z]+)(.*)$$/sD", $trail, $m ) ) {
1262 $inside = $m[1];
1263 $trail = $m[2];
1266 $retVal = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1267 } elseif ( 0 == $nt->getNamespace() && "" == $nt->getText() ) {
1268 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail );
1269 } elseif ( ( -1 == $nt->getNamespace() ) ||
1270 ( Namespace::getImage() == $nt->getNamespace() ) ) {
1271 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail );
1272 } else {
1273 $aid = $nt->getArticleID() ;
1274 if ( 0 == $aid ) {
1275 $retVal = $this->makeBrokenLinkObj( $nt, $text, $query, $trail );
1276 } else {
1277 $threshold = $wgUser->getOption("stubthreshold") ;
1278 if ( $threshold > 0 ) {
1279 $res = wfQuery ( "SELECT HIGH_PRIORITY length(cur_text) AS x, cur_namespace, cur_is_redirect FROM cur WHERE cur_id='{$aid}'", DB_READ ) ;
1281 if ( wfNumRows( $res ) > 0 ) {
1282 $s = wfFetchObject( $res );
1283 $size = $s->x;
1284 if ( $s->cur_is_redirect OR $s->cur_namespace != 0 ) {
1285 $size = $threshold*2 ; # Really big
1287 wfFreeResult( $res );
1288 } else {
1289 $size = $threshold*2 ; # Really big
1291 } else {
1292 $size = 1 ;
1294 if ( $size < $threshold ) {
1295 $retVal = $this->makeStubLinkObj( $nt, $text, $query, $trail );
1296 } else {
1297 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail );
1301 return $retVal;
1304 # Pass a title object, not a title string
1305 function makeKnownLinkObj( &$nt, $text = "", $query = "", $trail = "" )
1307 global $wgOut, $wgTitle;
1309 $fname = "Skin::makeKnownLinkObj";
1310 wfProfileIn( $fname );
1312 $link = $nt->getPrefixedURL();
1314 if ( "" == $link ) {
1315 $u = "";
1316 if ( "" == $text ) { $text = $nt->getFragment(); }
1317 } else {
1318 $u = wfLocalUrlE( $link, $query );
1320 if ( "" != $nt->getFragment() ) {
1321 $u .= "#" . wfEscapeHTML( $nt->getFragment() );
1323 if ( "" == $text ) { $text = $nt->getPrefixedText(); }
1324 $style = $this->getInternalLinkAttributesObj( $nt, $text );
1326 $inside = "";
1327 if ( "" != $trail ) {
1328 if ( preg_match( wfMsg("linktrail"), $trail, $m ) ) {
1329 $inside = $m[1];
1330 $trail = $m[2];
1333 $r = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1334 wfProfileOut( $fname );
1335 return $r;
1338 # Pass a title object, not a title string
1339 function makeBrokenLinkObj( &$nt, $text = "", $query = "", $trail = "" )
1341 global $wgOut, $wgUser;
1343 $fname = "Skin::makeBrokenLinkObj";
1344 wfProfileIn( $fname );
1346 $link = $nt->getPrefixedURL();
1348 if ( "" == $query ) { $q = "action=edit"; }
1349 else { $q = "action=edit&{$query}"; }
1350 $u = wfLocalUrlE( $link, $q );
1352 if ( "" == $text ) { $text = $nt->getPrefixedText(); }
1353 $style = $this->getInternalLinkAttributesObj( $nt, $text, "yes" );
1355 $inside = "";
1356 if ( "" != $trail ) {
1357 if ( preg_match( wfMsg("linktrail"), $trail, $m ) ) {
1358 $inside = $m[1];
1359 $trail = $m[2];
1362 if ( $wgOut->isPrintable() ||
1363 ( 1 == $wgUser->getOption( "highlightbroken" ) ) ) {
1364 $s = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1365 } else {
1366 $s = "{$text}{$inside}<a href=\"{$u}\"{$style}>?</a>{$trail}";
1369 wfProfileOut( $fname );
1370 return $s;
1373 # Pass a title object, not a title string
1374 function makeStubLinkObj( &$nt, $text = "", $query = "", $trail = "" )
1376 global $wgOut, $wgUser;
1378 $link = $nt->getPrefixedURL();
1380 $u = wfLocalUrlE( $link, $query );
1382 if ( "" == $text ) { $text = $nt->getPrefixedText(); }
1383 $style = $this->getInternalLinkAttributesObj( $nt, $text, "stub" );
1385 $inside = "";
1386 if ( "" != $trail ) {
1387 if ( preg_match( wfMsg("linktrail"), $trail, $m ) ) {
1388 $inside = $m[1];
1389 $trail = $m[2];
1392 if ( $wgOut->isPrintable() ||
1393 ( 1 == $wgUser->getOption( "highlightbroken" ) ) ) {
1394 $s = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1395 } else {
1396 $s = "{$text}{$inside}<a href=\"{$u}\"{$style}>!</a>{$trail}";
1398 return $s;
1401 function fnamePart( $url )
1403 $basename = strrchr( $url, "/" );
1404 if ( false === $basename ) { $basename = $url; }
1405 else { $basename = substr( $basename, 1 ); }
1406 return wfEscapeHTML( $basename );
1409 function makeImage( $url, $alt = "" )
1411 global $wgOut;
1413 if ( "" == $alt ) { $alt = $this->fnamePart( $url ); }
1414 $s = "<img src=\"{$url}\" alt=\"{$alt}\">";
1415 return $s;
1418 function makeImageLink( $name, $url, $alt = "" ) {
1419 $nt = Title::makeTitle( Namespace::getImage(), $name );
1420 return $this->makeImageLinkObj( $nt, $alt );
1423 function makeImageLinkObj( $nt, $alt = "" ) {
1424 $link = $nt->getPrefixedURL();
1425 $name = $nt->getDBKey();
1426 $url = wfImageUrl( $name );
1427 if ( empty( $alt ) ) {
1428 $alt = preg_replace( '/\.(.+?)^/', '', $name );
1430 $alt = htmlspecialchars( $alt );
1432 $u = wfLocalUrlE( $link );
1433 $s = "<a href=\"{$u}\" class='image' title=\"{$alt}\">" .
1434 "<img border=\"0\" src=\"{$url}\" alt=\"{$alt}\"></a>";
1435 return $s;
1438 function makeMediaLink( $name, $url, $alt = "" ) {
1439 $nt = Title::makeTitle( Namespace::getMedia(), $name );
1440 return $this->makeMediaLinkObj( $nt, $alt );
1443 function makeMediaLinkObj( $nt, $alt = "" )
1445 $name = $nt->getDBKey();
1446 $url = wfImageUrl( $name );
1447 if ( empty( $alt ) ) {
1448 $alt = preg_replace( '/\.(.+?)^/', '', $name );
1451 $u = htmlspecialchars( $url );
1452 $s = "<a href=\"{$u}\" class='internal' title=\"{$alt}\">{$alt}</a>";
1453 return $s;
1456 function specialLink( $name, $key = "" )
1458 global $wgLang;
1460 if ( "" == $key ) { $key = strtolower( $name ); }
1461 $pn = $wgLang->ucfirst( $name );
1462 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1463 wfMsg( $key ) );
1466 # Called by history lists and recent changes
1469 function beginRecentChangesList()
1471 $rc_cache = array() ;
1472 $rccc = 0 ;
1473 $this->lastdate = "";
1474 return "";
1477 function beginImageHistoryList()
1479 $s = "\n<h2>" . wfMsg( "imghistory" ) . "</h2>\n" .
1480 "<p>" . wfMsg( "imghistlegend" ) . "\n<ul>";
1481 return $s;
1484 function endRecentChangesList()
1486 $s = $this->recentChangesBlock() ;
1487 $s .= "</ul>\n";
1488 return $s;
1491 function endImageHistoryList()
1493 $s = "</ul>\n";
1494 return $s;
1497 function recentChangesBlockLine ( $y ) {
1498 global $wgUploadPath ;
1500 $M = wfMsg( "minoreditletter" );
1501 $N = wfMsg( "newpageletter" );
1502 $r = "" ;
1503 $r .= "<img src='{$wgUploadPath}/Arr_.png' width=12 height=12 border=0>" ;
1504 $r .= "<tt>" ;
1505 if ( $y->isnew ) $r .= $N ;
1506 else $r .= "&nbsp;" ;
1507 if ( $y->isminor ) $r .= $M ;
1508 else $r .= "&nbsp;" ;
1509 $r .= " ".$y->timestamp." " ;
1510 $r .= "</tt>" ;
1511 $link = $y->link ;
1512 if ( $y->watched ) $link = "<strong>{$link}</strong>" ;
1513 $r .= $link ;
1515 $r .= " (" ;
1516 $r .= $y->curlink ;
1517 $r .= "; " ;
1518 $r .= $this->makeKnownLink( $y->secureName, wfMsg( "hist" ), "action=history" );
1520 $r .= ") . . ".$y->userlink ;
1521 $r .= $y->usertalklink ;
1522 if ( $y->usercomment != "" )
1523 $r .= " <em>(".wfEscapeHTML($y->usercomment).")</em>" ;
1524 $r .= "<br>\n" ;
1525 return $r ;
1528 function recentChangesBlockGroup ( $y ) {
1529 global $wgUploadPath ;
1531 $r = "" ;
1532 $M = wfMsg( "minoreditletter" );
1533 $N = wfMsg( "newpageletter" );
1534 $isnew = false ;
1535 $userlinks = array () ;
1536 foreach ( $y AS $x ) {
1537 $oldid = $x->diffid ;
1538 if ( $x->isnew ) $isnew = true ;
1539 $u = $x->userlink ;
1540 if ( !isset ( $userlinks[$u] ) ) $userlinks[$u] = 0 ;
1541 $userlinks[$u]++ ;
1544 krsort ( $userlinks ) ;
1545 asort ( $userlinks ) ;
1546 $users = array () ;
1547 $u = array_keys ( $userlinks ) ;
1548 foreach ( $u as $x ) {
1549 $z = $x ;
1550 if ( $userlinks[$x] > 1 ) $z .= " ({$userlinks[$x]}&times;)" ;
1551 array_push ( $users , $z ) ;
1553 $users = " <font size='-1'>[".implode("; ",$users)."]</font>" ;
1555 $e = $y ;
1556 $e = array_shift ( $e ) ;
1558 # Arrow
1559 $rci = "RCI{$this->rccc}" ;
1560 $rcl = "RCL{$this->rccc}" ;
1561 $rcm = "RCM{$this->rccc}" ;
1562 $tl = "<a href='javascript:toggleVisibility(\"{$rci}\",\"{$rcm}\",\"{$rcl}\")'>" ;
1563 $tl .= "<span id='{$rcm}'><img src='{$wgUploadPath}/Arr_r.png' width=12 height=12 border=0></span>" ;
1564 $tl .= "<span id='{$rcl}' style='display:none'><img src='{$wgUploadPath}/Arr_d.png' width=12 height=12 border=0></span>" ;
1565 $tl .= "</a>" ;
1566 $r .= $tl ;
1568 # Main line
1569 $r .= "<tt>" ;
1570 if ( $isnew ) $r .= $N ;
1571 else $r .= "&nbsp;" ;
1572 $r .= "&nbsp;" ; # Minor
1573 $r .= " ".$e->timestamp." " ;
1574 $r .= "</tt>" ;
1576 $link = $e->link ;
1577 if ( $e->watched ) $link = "<strong>{$link}</strong>" ;
1578 $r .= $link ;
1580 if ( !$e->islog ) {
1581 $r .= " (".count($y)." " ;
1582 if ( $isnew ) $r .= wfMsg("changes");
1583 else $r .= $this->makeKnownLink( $e->secureName , wfMsg("changes") , "diff=0&oldid=".$oldid ) ;
1584 $r .= "; " ;
1585 $r .= $this->makeKnownLink( $e->secureName, wfMsg( "history" ), "action=history" );
1586 $r .= ")" ;
1589 $r .= $users ;
1590 $r .= "<br>\n" ;
1592 # Sub-entries
1593 $r .= "<div id='{$rci}' style='display:none'>" ;
1594 foreach ( $y AS $x )
1596 $r .= "<img src='{$wgUploadPath}/Arr_.png' width=12 height=12 border=0>";
1597 $r .= "<tt>&nbsp; &nbsp; &nbsp; &nbsp;" ;
1598 if ( $x->isnew ) $r .= $N ;
1599 else $r .= "&nbsp;" ;
1600 if ( $x->isminor ) $r .= $M ;
1601 else $r .= "&nbsp;" ;
1602 $r .= "</tt>" ;
1604 $o = "" ;
1605 if ( $x->oldid != 0 ) $o = "oldid=".$x->oldid ;
1606 if ( $x->islog ) $link = $x->timestamp ;
1607 else $link = $this->makeKnownLink( $x->secureName, $x->timestamp , $o ) ;
1608 $link = "<tt>{$link}</tt>" ;
1611 $r .= $link ;
1612 $r .= " (" ;
1613 $r .= $x->curlink ;
1614 $r .= "; " ;
1615 $r .= $x->lastlink ;
1616 $r .= ") . . ".$x->userlink ;
1617 $r .= $x->usertalklink ;
1618 if ( $x->usercomment != "" )
1619 $r .= " <em>(".wfEscapeHTML($x->usercomment).")</em>" ;
1620 $r .= "<br>\n" ;
1622 $r .= "</div>\n" ;
1624 $this->rccc++ ;
1625 return $r ;
1628 function recentChangesBlock ()
1630 global $wgUploadPath ;
1631 if ( count ( $this->rc_cache ) == 0 ) return "" ;
1632 $k = array_keys ( $this->rc_cache ) ;
1633 foreach ( $k AS $x )
1635 $y = $this->rc_cache[$x] ;
1636 if ( count ( $y ) < 2 ) {
1637 $r .= $this->recentChangesBlockLine ( array_shift ( $y ) ) ;
1638 } else {
1639 $r .= $this->recentChangesBlockGroup ( $y ) ;
1643 return "<div align=left>{$r}</div>" ;
1646 function recentChangesLine( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched = false, $oldid = 0 , $diffid = 0 )
1648 global $wgUser ;
1649 $usenew = $wgUser->getOption( "usenewrc" );
1650 if ( $usenew )
1651 $r = $this->recentChangesLineNew ( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched , $oldid , $diffid ) ;
1652 else
1653 $r = $this->recentChangesLineOld ( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched , $oldid , $diffid ) ;
1654 return $r ;
1657 function recentChangesLineOld( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched = false, $oldid = 0, $diffid = 0 )
1659 global $wgTitle, $wgLang, $wgUser;
1661 $d = $wgLang->date( $ts, true);
1662 $s = "";
1663 if ( $d != $this->lastdate ) {
1664 if ( "" != $this->lastdate ) { $s .= "</ul>\n"; }
1665 $s .= "<h4>{$d}</h4>\n<ul>";
1666 $this->lastdate = $d;
1668 $h = $wgLang->time( $ts, true );
1669 $t = Title::makeName( $ns, $ttl );
1670 $clink = $this->makeKnownLink( $t , "" );
1671 $nt = Title::newFromText( $t );
1673 if ( $watched ) {
1674 $clink = "<strong>{$clink}</strong>";
1676 $hlink = $this->makeKnownLink( $t, wfMsg( "hist" ), "action=history" );
1677 if ( $isnew || $nt->isLog() ) {
1678 $dlink = wfMsg( "diff" );
1679 } else {
1680 $dlink = $this->makeKnownLink( $t, wfMsg( "diff" ),
1681 "diff={$oldid}&oldid={$diffid}" ); # Finagle's law
1683 if ( 0 == $u ) {
1684 $ul = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
1685 $ut, "target=" . $ut );
1686 } else {
1687 $ul = $this->makeLink( $wgLang->getNsText( Namespace::getUser() ) . ":{$ut}", $ut );
1690 $talkname=$wgLang->getNsText(Namespace::getTalk(0)); # use the shorter name
1691 global $wgDisableAnonTalk;
1692 if( 0 == $u && $wgDisableAnonTalk ) {
1693 $utl = "";
1694 } else {
1695 $utns=$wgLang->getNsText(Namespace::getTalk(Namespace::getUser()));
1696 $utl= $this->makeLink($utns . ":{$ut}", $talkname );
1698 $cr = wfMsg( "currentrev" );
1700 $s .= "<li> ({$dlink}) ({$hlink}) . .";
1701 $M = wfMsg( "minoreditletter" );
1702 $N = wfMsg( "newpageletter" );
1703 if ( $isminor ) { $s .= " <strong>{$M}</strong>"; }
1704 if ( $isnew ) { $s .= "<strong>{$N}</strong>"; }
1705 $s .= " {$clink}; {$h} . . {$ul}";
1707 $blink="";
1708 if ( ( 0 == $u ) && $wgUser->isSysop() ) {
1709 $blink = $this->makeKnownLink( $wgLang->specialPage(
1710 "Blockip" ), wfMsg( "blocklink" ), "ip={$ut}" );
1713 if($blink) {
1714 if($utl) $utl .= " | ";
1715 $utl .= $blink;
1717 if($utl) $s.=" ({$utl})";
1719 if ( "" != $c && "*" != $c ) {
1720 $s .= " <em>(" . wfEscapeHTML( $c ) . ")</em>";
1722 $s .= "</li>\n";
1724 return $s;
1727 function recentChangesLineNew( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched = false, $oldid = 0 , $diffid = 0 )
1729 global $wgTitle, $wgLang, $wgUser;
1731 $rc = new RecentChangesClass ;
1733 $d = $wgLang->date( $ts, true);
1734 $s = "";
1735 $ret = "" ;
1736 if ( $d != $this->lastdate ) {
1737 $ret = $this->recentChangesBlock () ;
1738 $this->rc_cache = array() ;
1739 $ret .= "<h4>{$d}</h4>\n";
1740 $this->lastdate = $d;
1742 $h = $wgLang->time( $ts, true );
1743 $t = Title::makeName( $ns, $ttl );
1744 $clink = $this->makeKnownLink( $t, "" ) ;
1745 if ( $oldid == 0 ) $c2link = $clink ;
1746 else $c2link = $this->makeKnownLink( $t, "" , "oldid={$oldid}" );
1747 $nt = Title::newFromText( $t );
1749 $rc->timestamp = $h ;
1750 $rc->oldid = $oldid ;
1751 $rc->diffid = $diffid ;
1752 $rc->watched = $watched ;
1753 $rc->isnew = $isnew ;
1754 $rc->isminor = $isminor ;
1755 $rc->secureName = $t ;
1756 $rc->displayName = $nt ;
1757 $rc->link = $clink ;
1758 $rc->usercomment = $c ;
1759 $rc->islog = $nt->isLog() ;
1761 if ( ( $isnew && $oldid == 0 ) || $nt->isLog() ) {
1762 $dlink = wfMsg( "cur" );
1763 } else {
1764 $dlink = $this->makeKnownLink( $t, wfMsg( "cur" ),
1765 "diff=0&oldid={$oldid}" );
1768 if ( $diffid == 0 || $nt->isLog() ) {
1769 $plink = wfMsg( "last" );
1770 } else {
1771 $plink = $this->makeKnownLink( $t, wfMsg( "last" ),
1772 "diff={$oldid}&oldid={$diffid}" );
1775 if ( 0 == $u ) {
1776 $ul = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
1777 $ut, "target=" . $ut );
1778 } else { $ul = $this->makeLink( $wgLang->getNsText(
1779 Namespace::getUser() ) . ":{$ut}", $ut ); }
1781 $rc->userlink = $ul ;
1782 $rc->lastlink = $plink ;
1783 $rc->curlink = $dlink ;
1785 $utns=$wgLang->getNsText(Namespace::getTalk(Namespace::getUser()));
1786 $talkname=$wgLang->getNsText(Namespace::getTalk(0)); # use the shorter name
1787 $utl= $this->makeLink($utns . ":{$ut}", $talkname );
1789 global $wgDisableAnonTalk;
1790 if ( ( 0 == $u ) && $wgUser->isSysop() ) {
1791 $blink = $this->makeKnownLink( $wgLang->specialPage(
1792 "Blockip" ), wfMsg( "blocklink" ), "ip={$ut}" );
1793 if( $wgDisableAnonTalk )
1794 $rc->usertalklink = " ({$blink})";
1795 else
1796 $rc->usertalklink = " ({$utl} | {$blink})";
1797 } else {
1798 if( $wgDisableAnonTalk && ($u == 0) )
1799 $rc->usertalklink = "";
1800 else
1801 $rc->usertalklink = " ({$utl})";
1804 if ( !isset ( $this->rc_cache[$t] ) ) $this->rc_cache[$t] = array() ;
1805 array_push ( $this->rc_cache[$t] , $rc ) ;
1806 return $ret;
1810 function imageHistoryLine( $iscur, $ts, $img, $u, $ut, $size, $c )
1812 global $wgUser, $wgLang, $wgTitle;
1814 $dt = $wgLang->timeanddate( $ts, true );
1815 $del = wfMsg( "deleteimg" );
1816 $cur = wfMsg( "cur" );
1818 if ( $iscur ) {
1819 $url = wfImageUrl( $img );
1820 $rlink = $cur;
1821 if ( $wgUser->isSysop() ) {
1822 $link = wfLocalUrlE( $wgTitle->getPrefixedText(), "image=" . $wgTitle->getURL() .
1823 "&action=delete" );
1824 $style = $this->getInternalLinkAttributes( $link, $del );
1826 $dlink = "<a href=\"{$link}\"{$style}>{$del}</a>";
1827 } else {
1828 $dlink = $del;
1830 } else {
1831 $url = wfEscapeHTML( wfImageArchiveUrl( $img ) );
1832 if( $wgUser->getID() != 0 ) {
1833 $rlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
1834 wfMsg( "revertimg" ), "action=revert&oldimage=" .
1835 urlencode( $img ) );
1836 $dlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
1837 $del, "action=delete&oldimage=" . urlencode( $img ) );
1838 } else {
1839 # Having live active links for non-logged in users
1840 # means that bots and spiders crawling our site can
1841 # inadvertently change content. Baaaad idea.
1842 $rlink = wfMsg( "revertimg" );
1843 $dlink = $del;
1846 if ( 0 == $u ) { $ul = $ut; }
1847 else { $ul = $this->makeLink( $wgLang->getNsText(
1848 Namespace::getUser() ) . ":{$ut}", $ut ); }
1850 $nb = wfMsg( "nbytes", $size );
1851 $style = $this->getInternalLinkAttributes( $url, $dt );
1853 $s = "<li> ({$dlink}) ({$rlink}) <a href=\"{$url}\"{$style}>{$dt}</a>"
1854 . " . . {$ul} ({$nb})";
1856 if ( "" != $c && "*" != $c ) {
1857 $s .= " <em>(" . wfEscapeHTML( $c ) . ")</em>";
1859 $s .= "</li>\n";
1860 return $s;
1863 function tocIndent($level) {
1865 while($level-->0) $rv.="<div style=\"margin-left:2em;\">\n";
1866 return $rv;
1870 function tocUnindent($level) {
1871 $rv = "";
1872 while($level-->0) $rv.="</div>\n";
1873 return $rv;
1876 // parameter level defines if we are on an indentation level
1877 function tocLine($anchor,$tocline,$level) {
1879 if($level) {
1881 return "<A CLASS=\"internal\" HREF=\"#".$anchor."\">".$tocline."</A><BR>\n";
1882 } else {
1884 return "<div style=\"margin-bottom:0px;\">\n".
1885 "<A CLASS=\"internal\" HREF=\"#".$anchor."\">".$tocline."</A><BR>\n".
1886 "</div>\n";
1891 function tocTable($toc) {
1892 // note to CSS fanatics: putting this in a div does not work -- div won't auto-expand
1893 global $printable;
1895 if (!$printable) {
1896 $hideline = " <script type='text/javascript'>showTocToggle(\"" . wfMsg("showtoc") . "\",\"" . wfMsg("hidetoc") . "\")</script>";
1898 return
1899 "<p><table border=\"0\" id=\"toc\"><tr><td align=\"center\">\n".
1900 "<b>".wfMsg("toc")."</b>" .
1901 $hideline .
1902 "</td></tr><tr id='tocinside'><td align=\"left\">\n".
1903 $toc."</td></tr></table><P>\n";
1906 # These two do not check for permissions: check $wgTitle->userCanEdit before calling them
1907 function editSectionScript($section,$head) {
1909 global $wgTitle,$wgUser,$oldid;
1910 if($oldid) return $head;
1911 $url = wfLocalUrlE(urlencode($wgTitle->getPrefixedText()),"action=edit&section=$section");
1912 return "<span onContextMenu='document.location=\"".$url."\";return false;'>{$head}</span>";
1915 function editSectionLink($section) {
1917 global $printable;
1918 global $wgTitle,$wgUser,$oldid;
1919 if($oldid) return "";
1920 if ($printable) return "";
1921 $editurl="&section={$section}";
1922 $url=$this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg("editsection"),"action=edit".$editurl);
1923 return "<div style=\"float:right;margin-left:5px;\"><small>[".$url."]</small></div>";
1927 // This function is called by EditPage.php and shows a bulletin board style
1928 // toolbar for common editing functions. It can be disabled in the user preferences.
1929 // The necsesary JavaScript code can be found in style/wikibits.js.
1930 function getEditToolbar() {
1932 global $wgUploadPath;
1934 // toolarray an array of arrays which each include the filename of
1935 // the button image (without path), the opening tag, the closing tag,
1936 // and optionally a sample text that is inserted between the two when no
1937 // selection is highlighted.
1938 // The tip text is shown when the user moves the mouse over the button.
1939 $toolarray=array(
1940 array( "image"=>"button_bold.gif",
1941 "open"=>"\\'\\'\\'",
1942 "close"=>"\\'\\'\\'",
1943 "sample"=>wfMsg("bold_sample"),
1944 "tip"=>wfMsg("bold_tip")),
1945 array( "image"=>"button_italic.gif",
1946 "open"=>"\\'\\'",
1947 "close"=>"\\'\\'",
1948 "sample"=>wfMsg("italic_sample"),
1949 "tip"=>wfMsg("italic_tip")),
1950 array( "image"=>"button_link.gif",
1951 "open"=>"[[",
1952 "close"=>"]]",
1953 "sample"=>wfMsg("link_sample"),
1954 "tip"=>wfMsg("link_tip")),
1955 array( "image"=>"button_extlink.gif",
1956 "open"=>"[",
1957 "close"=>"]",
1958 "sample"=>wfMsg("extlink_sample"),
1959 "tip"=>wfMsg("extlink_tip")),
1960 array( "image"=>"button_headline.gif",
1961 "open"=>"\\n== ",
1962 "close"=>" ==\\n",
1963 "sample"=>wfMsg("headline_sample"),
1964 "tip"=>wfMsg("headline_tip")),
1965 array( "image"=>"button_math.gif",
1966 "open"=>"\\<math\\>",
1967 "close"=>"\\</math\\>",
1968 "sample"=>wfMsg("math_sample"),
1969 "tip"=>wfMsg("math_tip")),
1970 array( "image"=>"button_image.gif",
1971 "open"=>"[[Image:",
1972 "close"=>"]]",
1973 "sample"=>wfMsg("image_sample"),
1974 "tip"=>wfMsg("image_tip")),
1975 array( "image"=>"button_media.gif",
1976 "open"=>"[[Media:",
1977 "close"=>"]]",
1978 "sample"=>wfMsg("media_sample"),
1979 "tip"=>wfMsg("media_tip")),
1980 array( "image"=>"button_sig.gif",
1981 "open"=>"--~~~~",
1982 "close"=>"",
1983 "sample"=>"",
1984 "tip"=>wfMsg("sig_tip")),
1985 array( "image"=>"button_hr.gif",
1986 "open"=>"\\n----\\n",
1987 "close"=>"",
1988 "sample"=>"",
1989 "tip"=>wfMsg("hr_tip"))
1991 $toolbar.="
1992 <div id=\"toolbar\">";
1993 foreach($toolarray as $tool) {
1995 $image=$tool["image"];
1996 $open=$tool["open"];
1997 $close=$tool["close"];
1998 $sample=$tool["sample"];
2000 // Note that we use the tip both for the ALT tag and the TITLE tag of the image.
2001 // Older browsers show a "speedtip" type message only for ALT.
2002 // Ideally these should be different, realistically they
2003 // probably don't need to be.
2004 $tip=$tool["tip"];
2006 $toolbar.=
2007 "<a href=\"#\"".
2008 "onclick=\"javascript:insertTags('$open','$close','$sample');\">".
2009 "<img src=\"$wgUploadPath/$image\" border=\"0\" ALT=\"$tip\" TITLE=\"$tip\">".
2010 "</a>";
2014 $toolbar.="</div>";
2015 return $toolbar;
2020 include_once( "SkinStandard.php" );
2021 include_once( "SkinNostalgia.php" );
2022 include_once( "SkinCologneBlue.php" );
2024 #include_once( "SkinSmarty.php" );