Merge several bits into wlshowlast
[mediawiki.git] / includes / Skin.php
blob1b4db0401fce091af0ca76202e5f35ab79dff639
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 wfProfileIn( "Skin::outputPage" );
85 $this->initPage();
86 $out->out( $out->headElement() );
88 $out->out( "\n<body" );
89 $ops = $this->getBodyOptions();
90 foreach ( $ops as $name => $val ) {
91 $out->out( " $name='$val'" );
93 $out->out( ">\n" );
94 if ( $wgDebugComments ) {
95 $out->out( "<!-- Wiki debugging output:\n" .
96 $out->mDebugtext . "-->\n" );
98 $out->out( $this->beforeContent() );
100 $out->out( $out->mBodytext );
102 $out->out( $this->afterContent() );
104 wfProfileClose();
105 $out->out( $out->reportTime() );
107 $out->out( "\n</body></html>" );
110 function getHeadScripts() {
111 global $wgStyleSheetPath;
112 $r = "<script type=\"text/javascript\" src=\"{$wgStyleSheetPath}/wikibits.js\"></script>\n";
113 return $r;
116 function getUserStyles()
118 $s = "<style type='text/css'><!--\n";
119 $s .= $this->doGetUserStyles();
120 $s .= "//--></style>\n";
121 return $s;
124 function doGetUserStyles()
126 global $wgUser;
128 $s = "";
129 if ( 1 == $wgUser->getOption( "underline" ) ) {
130 # Don't override browser settings
131 } else {
132 # CHECK MERGE @@@
133 # Force no underline
134 $s .= "a.stub, a.new, a.internal, a.external { " .
135 "text-decoration: none; }\n";
137 if ( 1 == $wgUser->getOption( "highlightbroken" ) ) {
138 $s .= "a.new, #quickbar a.new { color: #CC2200; }\n";
140 if ( 1 == $wgUser->getOption( "justify" ) ) {
141 $s .= "#article { text-align: justify; }\n";
143 return $s;
146 function getBodyOptions()
148 global $wgUser, $wgTitle, $wgNamespaceBackgrounds, $wgOut, $oldid, $redirect, $diff,$action;
150 if ( 0 != $wgTitle->getNamespace() ) {
151 $a = array( "bgcolor" => "#ffffec" );
153 else $a = array( "bgcolor" => "#FFFFFF" );
154 if($wgOut->isArticle() && $wgUser->getOption("editondblclick")
156 (!$wgTitle->isProtected() || $wgUser->isSysop())
159 $n = $wgTitle->getPrefixedURL();
160 $t = wfMsg( "editthispage" );
161 $oid = $red = "";
162 if ( $redirect ) { $red = "&redirect={$redirect}"; }
163 if ( $oldid && ! isset( $diff ) ) {
164 $oid = "&oldid={$oldid}";
166 $s = wfLocalUrlE($n,"action=edit{$oid}{$red}");
167 $s = "document.location = \"" .$s ."\";";
168 $a += array ("ondblclick" => $s);
171 if($action=="edit") { # set focus in edit box
172 $foc = "document.editform.wpTextbox1.focus()";
173 if($a['onload']) {
174 $a['onload'] .= ";$foc";
175 } else {
176 $a['onload'] = $foc;
179 return $a;
182 function getExternalLinkAttributes( $link, $text )
184 global $wgUser, $wgOut, $wgLang;
186 $link = urldecode( $link );
187 $link = $wgLang->checkTitleEncoding( $link );
188 $link = str_replace( "_", " ", $link );
189 $link = wfEscapeHTML( $link );
191 if ( $wgOut->isPrintable() ) { $r = " class='printable'"; }
192 else { $r = " class='external'"; }
194 if ( 1 == $wgUser->getOption( "hover" ) ) {
195 $r .= " title=\"{$link}\"";
197 return $r;
200 function getInternalLinkAttributes( $link, $text, $broken = false )
202 global $wgUser, $wgOut;
204 $link = urldecode( $link );
205 $link = str_replace( "_", " ", $link );
206 $link = wfEscapeHTML( $link );
208 if ( $wgOut->isPrintable() ) {
209 $r = " class='printable'";
210 } else if ( $broken == "stub" ) {
211 $r = " class='stub'";
212 } else if ( $broken == "yes" ) {
213 $r = " class='new'";
214 } else {
215 $r = "";
218 if ( 1 == $wgUser->getOption( "hover" ) ) {
219 $r .= " title=\"{$link}\"";
221 return $r;
224 function getInternalLinkAttributesObj( &$nt, $text, $broken = false )
226 global $wgUser, $wgOut;
228 if ( $wgOut->isPrintable() ) {
229 $r = " class='printable'";
230 } else if ( $broken == "stub" ) {
231 $r = " class='stub'";
232 } else if ( $broken == "yes" ) {
233 $r = " class='new'";
234 } else {
235 $r = "";
238 if ( 1 == $wgUser->getOption( "hover" ) ) {
239 $r .= ' title ="' . $nt->getEscapedText() . '"';
241 return $r;
244 function getLogo()
246 global $wgLogo;
247 return $wgLogo;
250 # This will be called immediately after the <body> tag. Split into
251 # two functions to make it easier to subclass.
253 function beforeContent()
255 global $wgUser, $wgOut;
257 if ( $wgOut->isPrintable() ) {
258 $s = $this->pageTitle() . $this->pageSubtitle() . "\n";
259 $s .= "\n<div class='bodytext'>";
260 return $s;
262 return $this->doBeforeContent();
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 = $wgServer . $wgTitle->getFullURL();
341 $rf = wfMsg( "retrievedfrom", $u );
343 if ( $wgOut->isArticle() ) {
344 $lm = "<br>" . $this->lastModified();
345 } else { $lm = ""; }
347 $cr = wfMsg( "gnunote" );
348 $s .= "<p><em>{$rf}{$lm} {$cr}</em>\n";
349 return $s;
351 return $this->doAfterContent();
354 function doAfterContent()
356 global $wgUser, $wgOut, $wgLang;
357 $fname = "Skin::doAfterContent";
358 wfProfileIn( $fname );
359 wfProfileIn( "$fname-1" );
361 $s = "\n</div><br clear=all>\n";
362 $s .= "\n<div id='footer'>";
363 $s .= "<table width='98%' border=0 cellspacing=0><tr>";
365 wfProfileOut( "$fname-1" );
366 wfProfileIn( "$fname-2" );
368 $qb = $this->qbSetting();
369 $shove = ($qb != 0);
370 $left = ($qb == 1 || $qb == 3);
371 if($wgLang->isRTL()) $left = !$left;
373 if ( $shove && $left ) { # Left
374 $s .= $this->getQuickbarCompensator();
376 wfProfileOut( "$fname-2" );
377 wfProfileIn( "$fname-3" );
378 $l = $wgLang->isRTL() ? "right" : "left";
379 $s .= "<td class='bottom' align='$l' valign='top'>";
381 $s .= $this->bottomLinks();
382 $s .= "\n<br>" . $this->mainPageLink()
383 . " | " . $this->aboutLink()
384 . " | " . $this->specialLink( "recentchanges" )
385 . " | " . $this->searchForm()
386 . "<br>" . $this->pageStats();
388 $s .= "</td>";
389 if ( $shove && !$left ) { # Right
390 $s .= $this->getQuickbarCompensator();
392 $s .= "</tr></table>\n</div>\n</div>\n";
394 wfProfileOut( "$fname-3" );
395 wfProfileIn( "$fname-4" );
396 if ( 0 != $qb ) { $s .= $this->quickBar(); }
397 wfProfileOut( "$fname-4" );
398 wfProfileOut( $fname );
399 return $s;
402 function pageTitleLinks()
404 global $wgOut, $wgTitle, $oldid, $action, $diff, $wgUser, $wgLang, $wgUseApproval ;
406 $s = $this->printableLink();
408 if ( $wgOut->isArticle() ) {
409 if ( $wgTitle->getNamespace() == Namespace::getImage() ) {
410 $name = $wgTitle->getDBkey();
411 $link = wfEscapeHTML( wfImageUrl( $name ) );
412 $style = $this->getInternalLinkAttributes( $link, $name );
413 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>";
415 # This will show the "Approve" link if $wgUseApproval=true;
416 if ( isset ( $wgUseApproval ) && $wgUseApproval )
418 $t = $wgTitle->getDBkey();
419 $name = "Approve this article" ;
420 $link = "http://test.wikipedia.org/w/magnus/wiki.phtml?title={$t}&action=submit&doit=1" ;
421 #wfEscapeHTML( wfImageUrl( $name ) );
422 $style = $this->getExternalLinkAttributes( $link, $name );
423 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>" ;
425 if ( "history" == $action || isset( $diff ) || isset( $oldid ) ) {
426 $s .= " | " . $this->makeKnownLink( $wgTitle->getPrefixedText(),
427 wfMsg( "currentrev" ) );
430 if ( $wgUser->getNewtalk() ) {
431 # do not show "You have new messages" text when we are viewing our
432 # own talk page
434 if(!(strcmp($wgTitle->getText(),$wgUser->getName()) == 0 &&
435 $wgTitle->getNamespace()==Namespace::getTalk(Namespace::getUser()))) {
436 $n =$wgUser->getName();
437 $tl = $this->makeKnownLink( $wgLang->getNsText(
438 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
439 wfMsg("newmessageslink") );
440 $s.=" | <strong>". wfMsg( "newmessages", $tl ) . "</strong>";
443 if( $wgUser->isSysop() &&
444 (($wgTitle->getArticleId() == 0) || ($action == "history")) &&
445 ($n = $wgTitle->isDeleted() ) ) {
446 $s .= " | " . wfMsg( "thisisdeleted",
447 $this->makeKnownLink(
448 $wgLang->SpecialPage( "Undelete/" . $wgTitle->getPrefixedDBkey() ),
449 wfMsg( "restorelink", $n ) ) );
451 return $s;
454 function printableLink()
456 global $wgOut, $wgTitle, $oldid, $action;
458 if ( "history" == $action ) { $q = "action=history&"; }
459 else { $q = ""; }
461 $s = $this->makeKnownLink( $wgTitle->getPrefixedText(),
462 WfMsg( "printableversion" ), "{$q}printable=yes" );
463 return $s;
466 function pageTitle()
468 global $wgOut, $wgTitle, $wgUser;
470 $s = "<h1 class='pagetitle'>" . $wgOut->getPageTitle() . "</h1>";
471 if($wgUser->getOption("editsectiononrightclick") && $wgTitle->userCanEdit()) { $s=$this->editSectionScript(0,$s);}
472 return $s;
475 function pageSubtitle()
477 global $wgOut,$wgTitle,$wgNamespacesWithSubpages;
479 $sub = $wgOut->getSubtitle();
480 if ( "" == $sub ) {
481 global $wgExtraSubtitle;
482 $sub = wfMsg( "fromwikipedia" ) . $wgExtraSubtitle;
484 if($wgOut->isArticle() && $wgNamespacesWithSubpages[$wgTitle->getNamespace()]) {
485 $ptext=$wgTitle->getPrefixedText();
486 if(preg_match("/\//",$ptext)) {
487 $sub.="</p><p class='subpages'>";
488 $links=explode("/",$ptext);
489 $c=0;
490 $growinglink="";
491 foreach($links as $link) {
492 $c++;
493 if ($c<count($links)) {
494 $growinglink.=$link;
495 $getlink=$this->makeLink( $growingLink, $link);
496 if(preg_match("/class='new'/i",$getlink)) { break; } # this is a hack, but it saves time
497 if ($c>1) {
498 $sub .= " | ";
499 } else {
500 $sub .="&lt; ";
502 $sub .= $getlink;
503 $growinglink.="/";
509 $s = "<p class='subtitle'>{$sub}\n";
510 return $s;
513 function nameAndLogin()
515 global $wgUser, $wgTitle, $wgLang, $wgShowIPinHeader;
517 $li = $wgLang->specialPage( "Userlogin" );
518 $lo = $wgLang->specialPage( "Userlogout" );
520 $s = "";
521 if ( 0 == $wgUser->getID() ) {
522 if( $wgShowIPinHeader ) {
523 $n = getenv( "REMOTE_ADDR" );
525 $tl = $this->makeKnownLink( $wgLang->getNsText(
526 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
527 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
529 $s .= $n . " (".$tl.")";
530 } else {
531 $s .= wfMsg("notloggedin");
534 $rt = $wgTitle->getPrefixedURL();
535 if ( 0 == strcasecmp( urlencode( $lo ), $rt ) ) {
536 $q = "";
537 } else { $q = "returnto={$rt}"; }
539 $s .= "\n<br>" . $this->makeKnownLink( $li,
540 wfMsg( "login" ), $q );
541 } else {
542 $n = $wgUser->getName();
543 $rt = $wgTitle->getPrefixedURL();
544 $tl = $this->makeKnownLink( $wgLang->getNsText(
545 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
546 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
548 $tl = " ({$tl})";
550 $s .= $this->makeKnownLink( $wgLang->getNsText(
551 Namespace::getUser() ) . ":{$n}", $n ) . "{$tl}<br>" .
552 $this->makeKnownLink( $lo, wfMsg( "logout" ),
553 "returnto={$rt}" ) . " | " .
554 $this->specialLink( "preferences" );
556 $s .= " | " . $this->makeKnownLink( wfMsg( "helppage" ),
557 wfMsg( "help" ) );
559 return $s;
562 function searchForm()
564 global $search;
566 $s = "<form name='search' class='inline' method=get action=\""
567 . wfLocalUrl( "" ) . "\">"
568 . "<input type=text name=\"search\" size=19 value=\""
569 . htmlspecialchars(substr($search,0,256)) . "\">\n"
570 . "<input type=submit name=\"go\" value=\"" . wfMsg ("go") . "\">&nbsp;"
571 . "<input type=submit value=\"" . wfMsg ("search") . "\"></form>";
573 return $s;
576 function topLinks()
578 global $wgOut;
579 $sep = " |\n";
581 $s = $this->mainPageLink() . $sep
582 . $this->specialLink( "recentchanges" );
584 if ( $wgOut->isArticle() ) {
585 $s .= $sep . $this->editThisPage()
586 . $sep . $this->historyLink();
588 # Many people don't like this dropdown box
589 #$s .= $sep . $this->specialPagesList();
591 return $s;
594 function bottomLinks()
596 global $wgOut, $wgUser, $wgTitle;
597 $sep = " |\n";
599 $s = "";
600 if ( $wgOut->isArticle() ) {
601 $s .= "<strong>" . $this->editThisPage() . "</strong>";
602 if ( 0 != $wgUser->getID() ) {
603 $s .= $sep . $this->watchThisPage();
605 $s .= $sep . $this->talkLink()
606 . $sep . $this->historyLink()
607 . $sep . $this->whatLinksHere()
608 . $sep . $this->watchPageLinksLink();
610 if ( $wgTitle->getNamespace() == Namespace::getUser()
611 || $wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser()) )
614 $id=User::idFromName($wgTitle->getText());
615 $ip=User::isIP($wgTitle->getText());
617 if($id || $ip) { # both anons and non-anons have contri list
618 $s .= $sep . $this->userContribsLink();
620 if ( 0 != $wgUser->getID() ) { # show only to signed in users
621 if($id) { # can only email non-anons
622 $s .= $sep . $this->emailUserLink();
626 if ( $wgUser->isSysop() && $wgTitle->getArticleId() ) {
627 $s .= "\n<br>" . $this->deleteThisPage() .
628 $sep . $this->protectThisPage() .
629 $sep . $this->moveThisPage();
631 $s .= "<br>\n" . $this->otherLanguages();
633 return $s;
636 function pageStats()
638 global $wgOut, $wgLang, $wgArticle;
639 global $oldid, $diff, $wgDisableCounters;
641 if ( ! $wgOut->isArticle() ) { return ""; }
642 if ( isset( $oldid ) || isset( $diff ) ) { return ""; }
643 if ( 0 == $wgArticle->getID() ) { return ""; }
645 if ( $wgDisableCounters ) {
646 $s = "";
647 } else {
648 $count = $wgArticle->getCount();
649 $s = wfMsg( "viewcount", $count );
651 $s .= $this->lastModified();
652 $s .= " " . wfMsg( "gnunote" );
653 return "<span id='pagestats'>{$s}</span>";
656 function lastModified()
658 global $wgLang, $wgArticle;
660 $d = $wgLang->timeanddate( $wgArticle->getTimestamp(), true );
661 $s = " " . wfMsg( "lastmodified", $d );
662 return $s;
665 function logoText( $align = "" )
667 if ( "" != $align ) { $a = " align='{$align}'"; }
668 else { $a = ""; }
670 $mp = wfMsg( "mainpage" );
671 $s = "<a href=\"" . wfLocalUrlE( urlencode( $mp ) )
672 . "\"><img{$a} border=0 src=\""
673 . $this->getLogo() . "\" alt=\"" . "[{$mp}]\"></a>";
674 return $s;
677 function quickBar()
679 global $wgOut, $wgTitle, $wgUser, $action, $wgLang;
680 global $wpPreview;
681 $fname = "Skin::quickBar";
682 wfProfileIn( $fname );
684 $tns=$wgTitle->getNamespace();
686 $s = "\n<div id='quickbar'>";
687 $s .= "\n" . $this->logoText() . "\n<hr class='sep'>";
689 $sep = "\n<br>";
690 $s .= $this->mainPageLink()
691 . $sep . $this->specialLink( "recentchanges" )
692 . $sep . $this->specialLink( "randompage" );
693 if ($wgUser->getID()) {
694 $s.= $sep . $this->specialLink( "watchlist" ) ;
695 $s .= $sep .$this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
696 wfMsg( "mycontris" ), "target=" . wfUrlencode($wgUser->getName() ) );
699 // only show watchlist link if logged in
700 if ( wfMsg ( "currentevents" ) != "-" ) $s .= $sep . $this->makeKnownLink( wfMsg( "currentevents" ), "" ) ;
701 $s .= "\n<br><hr class='sep'>";
702 $articleExists = $wgTitle->getArticleId();
703 if ( $wgOut->isArticle() || $action =="edit" || $action =="history" || $wpPreview) {
704 if($wgOut->isArticle()) {
705 $s .= "<strong>" . $this->editThisPage() . "</strong>";
706 } else { # backlink to the article in edit or history mode
707 if($articleExists){ # no backlink if no article
708 switch($tns) {
709 case 0:
710 $text = wfMsg("articlepage");
711 break;
712 case 1:
713 $text = wfMsg("viewtalkpage");
714 break;
715 case 2:
716 $text = wfMsg("userpage");
717 break;
718 case 3:
719 $text = wfMsg("viewtalkpage");
720 break;
721 case 4:
722 $text = wfMsg("wikipediapage");
723 break;
724 case 5:
725 $text = wfMsg("viewtalkpage");
726 break;
727 case 6:
728 $text = wfMsg("imagepage");
729 break;
730 case 7:
731 $text = wfMsg("viewtalkpage");
732 break;
733 default:
734 $text= wfMsg("articlepage");
737 $link = $wgTitle->getText();
738 if ($nstext = $wgLang->getNsText($tns) ) { # add namespace if necessary
739 $link = $nstext . ":" . $link ;
742 $s .= $this->makeLink( $link, $text );
743 } elseif( $wgTitle->getNamespace() != Namespace::getSpecial() ) {
744 # we just throw in a "New page" text to tell the user that he's in edit mode,
745 # and to avoid messing with the separator that is prepended to the next item
746 $s .= "<strong>" . wfMsg("newpage") . "</strong>";
752 if( $tns%2 && $action!="edit" && !$wpPreview) {
753 $s.="<br>".$this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg("postcomment"),"action=edit&section=new");
757 watching could cause problems in edit mode:
758 if user edits article, then loads "watch this article" in background and then saves
759 article with "Watch this article" checkbox disabled, the article is transparently
760 unwatched. Therefore we do not show the "Watch this page" link in edit mode
762 if ( 0 != $wgUser->getID() && $articleExists) {
763 if($action!="edit" && $action!="history" &&
764 $action != "submit" )
765 {$s .= $sep . $this->watchThisPage(); }
766 if ( $wgTitle->userCanEdit() ) $s .= $sep . $this->moveThisPage();
768 if ( $wgUser->isSysop() and $articleExists ) {
769 $s .= $sep . $this->deleteThisPage() .
770 $sep . $this->protectThisPage();
772 $s .= $sep . $this->talkLink();
773 if ($articleExists && $action !="history") { $s .= $sep . $this->historyLink();}
774 $s.=$sep . $this->whatLinksHere();
776 if($wgOut->isArticle()) {
777 $s .= $sep . $this->watchPageLinksLink();
780 if ( Namespace::getUser() == $wgTitle->getNamespace()
781 || $wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser())
784 $id=User::idFromName($wgTitle->getText());
785 $ip=User::isIP($wgTitle->getText());
787 if($id||$ip) {
788 $s .= $sep . $this->userContribsLink();
790 if ( 0 != $wgUser->getID() ) {
791 if($id) { # can only email real users
792 $s .= $sep . $this->emailUserLink();
796 $s .= "\n<br><hr class='sep'>";
799 if ( 0 != $wgUser->getID() ) {
800 $s .= $this->specialLink( "upload" ) . $sep;
802 $s .= $this->specialLink( "specialpages" )
803 . $sep . $this->bugReportsLink();
805 global $wgSiteSupportPage;
806 if( $wgSiteSupportPage ) {
807 $s .= "\n<br><a href=\"" . htmlspecialchars( $wgSiteSupportPage ) .
808 "\">" . wfMsg( "sitesupport" ) . "</a>";
811 $s .= "\n<br></div>\n";
812 wfProfileOut( $fname );
813 return $s;
816 function specialPagesList()
818 global $wgUser, $wgOut, $wgLang, $wgServer, $wgRedirectScript;
819 $a = array();
821 $validSP = $wgLang->getValidSpecialPages();
823 foreach ( $validSP as $name => $desc ) {
824 if ( "" == $desc ) { continue; }
825 $a[$name] = $desc;
827 if ( $wgUser->isSysop() )
829 $sysopSP = $wgLang->getSysopSpecialPages();
831 foreach ( $sysopSP as $name => $desc ) {
832 if ( "" == $desc ) { continue; }
833 $a[$name] = $desc ;
836 if ( $wgUser->isDeveloper() )
838 $devSP = $wgLang->getDeveloperSpecialPages();
840 foreach ( $devSP as $name => $desc ) {
841 if ( "" == $desc ) { continue; }
842 $a[$name] = $desc ;
845 $go = wfMsg( "go" );
846 $sp = wfMsg( "specialpages" );
847 $spp = $wgLang->specialPage( "Specialpages" );
849 $s = "<form id=\"specialpages\" method=\"get\" class=\"inline\" " .
850 "action=\"{$wgServer}{$wgRedirectScript}\">\n";
851 $s .= "<select name=\"wpDropdown\">\n";
852 $s .= "<option value=\"{$spp}\">{$sp}</option>\n";
854 foreach ( $a as $name => $desc ) {
855 $p = $wgLang->specialPage( $name );
856 $s .= "<option value=\"{$p}\">{$desc}</option>\n";
858 $s .= "</select>\n";
859 $s .= "<input type=submit value=\"{$go}\" name=redirect>\n";
860 $s .= "</form>\n";
861 return $s;
864 function mainPageLink()
866 $mp = wfMsg( "mainpage" );
867 $s = $this->makeKnownLink( $mp, $mp );
868 return $s;
871 function copyrightLink()
873 $s = $this->makeKnownLink( wfMsg( "copyrightpage" ),
874 wfMsg( "copyrightpagename" ) );
875 return $s;
878 function aboutLink()
880 $s = $this->makeKnownLink( wfMsg( "aboutpage" ),
881 wfMsg( "aboutwikipedia" ) );
882 return $s;
885 function editThisPage()
887 global $wgOut, $wgTitle, $oldid, $redirect, $diff;
889 if ( ! $wgOut->isArticle() || $diff ) {
890 $s = wfMsg( "protectedpage" );
891 } else if ( $wgTitle->userCanEdit() ) {
892 $n = $wgTitle->getPrefixedText();
893 $t = wfMsg( "editthispage" );
894 $oid = $red = "";
896 if ( $redirect ) { $red = "&redirect={$redirect}"; }
897 if ( $oldid && ! isset( $diff ) ) {
898 $oid = "&oldid={$oldid}";
900 $s = $this->makeKnownLink( $n, $t, "action=edit{$oid}{$red}" );
901 } else {
902 $s = wfMsg( "protectedpage" );
904 return $s;
907 function deleteThisPage()
909 global $wgUser, $wgOut, $wgTitle, $diff;
911 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
912 $n = $wgTitle->getPrefixedText();
913 $t = wfMsg( "deletethispage" );
915 $s = $this->makeKnownLink( $n, $t, "action=delete" );
916 } else {
917 $s = wfMsg( "error" );
919 return $s;
922 function protectThisPage()
924 global $wgUser, $wgOut, $wgTitle, $diff;
926 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
927 $n = $wgTitle->getPrefixedText();
929 if ( $wgTitle->isProtected() ) {
930 $t = wfMsg( "unprotectthispage" );
931 $q = "action=unprotect";
932 } else {
933 $t = wfMsg( "protectthispage" );
934 $q = "action=protect";
936 $s = $this->makeKnownLink( $n, $t, $q );
937 } else {
938 $s = wfMsg( "error" );
940 return $s;
943 function watchThisPage()
945 global $wgUser, $wgOut, $wgTitle, $diff;
947 if ( $wgOut->isArticle() && ( ! $diff ) ) {
948 $n = $wgTitle->getPrefixedText();
950 if ( $wgTitle->userIsWatching() ) {
951 $t = wfMsg( "unwatchthispage" );
952 $q = "action=unwatch";
953 } else {
954 $t = wfMsg( "watchthispage" );
955 $q = "action=watch";
957 $s = $this->makeKnownLink( $n, $t, $q );
958 } else {
959 $s = wfMsg( "notanarticle" );
961 return $s;
964 function moveThisPage()
966 global $wgTitle, $wgLang;
968 if ( $wgTitle->userCanEdit() ) {
969 $s = $this->makeKnownLink( $wgLang->specialPage( "Movepage" ),
970 wfMsg( "movethispage" ), "target=" . $wgTitle->getPrefixedURL() );
971 } // no message if page is protected - would be redundant
972 return $s;
975 function historyLink()
977 global $wgTitle;
979 $s = $this->makeKnownLink( $wgTitle->getPrefixedText(),
980 wfMsg( "history" ), "action=history" );
981 return $s;
984 function whatLinksHere()
986 global $wgTitle, $wgLang;
988 $s = $this->makeKnownLink( $wgLang->specialPage( "Whatlinkshere" ),
989 wfMsg( "whatlinkshere" ), "target=" . $wgTitle->getPrefixedURL() );
990 return $s;
993 function userContribsLink()
995 global $wgTitle, $wgLang;
997 $s = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
998 wfMsg( "contributions" ), "target=" . $wgTitle->getURL() );
999 return $s;
1002 function emailUserLink()
1004 global $wgTitle, $wgLang;
1006 $s = $this->makeKnownLink( $wgLang->specialPage( "Emailuser" ),
1007 wfMsg( "emailuser" ), "target=" . $wgTitle->getURL() );
1008 return $s;
1011 function watchPageLinksLink()
1013 global $wgOut, $wgTitle, $wgLang;
1015 if ( ! $wgOut->isArticle() ) {
1016 $s = "(" . wfMsg( "notanarticle" ) . ")";
1017 } else {
1018 $s = $this->makeKnownLink( $wgLang->specialPage(
1019 "Recentchangeslinked" ), wfMsg( "recentchangeslinked" ),
1020 "target=" . $wgTitle->getPrefixedURL() );
1022 return $s;
1025 function otherLanguages()
1027 global $wgOut, $wgLang, $wgTitle;
1029 $a = $wgOut->getLanguageLinks();
1030 # TEST THIS @@@
1031 if ( 0 == count( $a ) ) {
1032 if ( !$wgUseNewInterlanguage ) return "";
1033 $ns = $wgLang->getNsIndex ( $wgTitle->getNamespace () ) ;
1034 if ( $ns != 0 AND $ns != 1 ) return "" ;
1035 $pn = "Intl" ;
1036 $x = "mode=addlink&xt=".$wgTitle->getDBkey() ;
1037 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1038 wfMsg( "intl" ) , $x );
1041 if ( !$wgUseNewInterlanguage ) {
1042 $s = wfMsg( "otherlanguages" ) . ": ";
1043 } else {
1044 global $wgLanguageCode ;
1045 $x = "mode=zoom&xt=".$wgTitle->getDBkey() ;
1046 $x .= "&xl=".$wgLanguageCode ;
1047 $s = $this->makeKnownLink( $wgLang->specialPage( "Intl" ),
1048 wfMsg( "otherlanguages" ) , $x ) . ": " ;
1051 $s = wfMsg( "otherlanguages" ) . ": ";
1052 $first = true;
1053 if($wgLang->isRTL()) $s .= "<span dir='LTR'>";
1054 foreach( $a as $l ) {
1055 if ( ! $first ) { $s .= " | "; }
1056 $first = false;
1058 $nt = Title::newFromText( $l );
1059 $url = $nt->getFullURL();
1060 $text = $wgLang->getLanguageName( $nt->getInterwiki() );
1062 if ( "" == $text ) { $text = $l; }
1063 $style = $this->getExternalLinkAttributes( $l, $text );
1064 $s .= "<a href=\"{$url}\"{$style}>{$text}</a>";
1066 if($wgLang->isRTL()) $s .= "</span>";
1067 return $s;
1070 function bugReportsLink()
1072 $s = $this->makeKnownLink( wfMsg( "bugreportspage" ),
1073 wfMsg( "bugreports" ) );
1074 return $s;
1077 function dateLink()
1079 global $wgLinkCache;
1080 $t1 = Title::newFromText( gmdate( "F j" ) );
1081 $t2 = Title::newFromText( gmdate( "Y" ) );
1083 $wgLinkCache->suspend();
1084 $id = $t1->getArticleID();
1085 $wgLinkCache->resume();
1087 if ( 0 == $id ) {
1088 $s = $this->makeBrokenLink( $t1->getText() );
1089 } else {
1090 $s = $this->makeKnownLink( $t1->getText() );
1092 $s .= ", ";
1094 $wgLinkCache->suspend();
1095 $id = $t2->getArticleID();
1096 $wgLinkCache->resume();
1098 if ( 0 == $id ) {
1099 $s .= $this->makeBrokenLink( $t2->getText() );
1100 } else {
1101 $s .= $this->makeKnownLink( $t2->getText() );
1103 return $s;
1106 function talkLink()
1108 global $wgLang, $wgTitle, $wgLinkCache;
1110 $tns = $wgTitle->getNamespace();
1111 if ( -1 == $tns ) { return ""; }
1113 $pn = $wgTitle->getText();
1114 $tp = wfMsg( "talkpage" );
1115 if ( Namespace::isTalk( $tns ) ) {
1116 $lns = Namespace::getSubject( $tns );
1117 switch($tns) {
1118 case 1:
1119 $text = wfMsg("articlepage");
1120 break;
1121 case 3:
1122 $text = wfMsg("userpage");
1123 break;
1124 case 5:
1125 $text = wfMsg("wikipediapage");
1126 break;
1127 case 7:
1128 $text = wfMsg("imagepage");
1129 break;
1130 default:
1131 $text= wfMsg("articlepage");
1133 } else {
1135 $lns = Namespace::getTalk( $tns );
1136 $text=$tp;
1138 $n = $wgLang->getNsText( $lns );
1139 if ( "" == $n ) { $link = $pn; }
1140 else { $link = "{$n}:{$pn}"; }
1142 $wgLinkCache->suspend();
1143 $s = $this->makeLink( $link, $text );
1144 $wgLinkCache->resume();
1146 return $s;
1149 # After all the page content is transformed into HTML, it makes
1150 # a final pass through here for things like table backgrounds.
1152 function transformContent( $text )
1154 return $text;
1157 # Note: This function MUST call getArticleID() on the link,
1158 # otherwise the cache won't get updated properly. See LINKCACHE.DOC.
1160 function makeLink( $title, $text = "", $query = "", $trail = "" ) {
1161 wfProfileIn( "Skin::makeLink" );
1162 $result = $this->makeLinkObj( Title::newFromText( $title ), $text, $query, $trail );
1163 wfProfileOut( "Skin::makeLink" );
1164 return $result;
1167 function makeKnownLink( $title, $text = "", $query = "", $trail = "" ) {
1168 return $this->makeKnownLinkObj( Title::newFromText( $title ), $text, $query, $trail );
1171 function makeBrokenLink( $title, $text = "", $query = "", $trail = "" ) {
1172 return $this->makeBrokenLinkObj( Title::newFromText( $title ), $text, $query, $trail );
1175 function makeStubLink( $title, $text = "", $query = "", $trail = "" ) {
1176 return $this->makeStubLinkObj( Title::newFromText( $title ), $text, $query, $trail );
1179 # Pass a title object, not a title string
1180 function makeLinkObj( &$nt, $text= "", $query = "", $trail = "" )
1182 global $wgOut, $wgUser;
1183 if ( $nt->isExternal() ) {
1184 $u = $nt->getFullURL();
1185 if ( "" == $text ) { $text = $nt->getPrefixedText(); }
1186 $style = $this->getExternalLinkAttributes( $link, $text );
1188 $inside = "";
1189 if ( "" != $trail ) {
1190 if ( preg_match( "/^([a-z]+)(.*)$$/sD", $trail, $m ) ) {
1191 $inside = $m[1];
1192 $trail = $m[2];
1195 $retVal = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1196 } elseif ( 0 == $nt->getNamespace() && "" == $nt->getText() ) {
1197 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail );
1198 } elseif ( ( -1 == $nt->getNamespace() ) ||
1199 ( Namespace::getImage() == $nt->getNamespace() ) ) {
1200 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail );
1201 } else {
1202 $aid = $nt->getArticleID() ;
1203 if ( 0 == $aid ) {
1204 $retVal = $this->makeBrokenLinkObj( $nt, $text, $query, $trail );
1205 } else {
1206 $threshold = $wgUser->getOption("stubthreshold") ;
1207 if ( $threshold > 0 ) {
1208 $res = wfQuery ( "SELECT HIGH_PRIORITY length(cur_text) AS x, cur_namespace, cur_is_redirect FROM cur WHERE cur_id='{$aid}'", DB_READ ) ;
1210 if ( wfNumRows( $res ) > 0 ) {
1211 $s = wfFetchObject( $res );
1212 $size = $s->x;
1213 if ( $s->cur_is_redirect OR $s->cur_namespace != 0 ) {
1214 $size = $threshold*2 ; # Really big
1216 wfFreeResult( $res );
1217 } else {
1218 $size = $threshold*2 ; # Really big
1220 } else {
1221 $size = 1 ;
1223 if ( $size < $threshold ) {
1224 $retVal = $this->makeStubLinkObj( $nt, $text, $query, $trail );
1225 } else {
1226 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail );
1230 return $retVal;
1233 # Pass a title object, not a title string
1234 function makeKnownLinkObj( &$nt, $text = "", $query = "", $trail = "" )
1236 global $wgOut, $wgTitle;
1238 $fname = "Skin::makeKnownLinkObj";
1239 wfProfileIn( $fname );
1241 $link = $nt->getPrefixedURL();
1243 if ( "" == $link ) {
1244 $u = "";
1245 if ( "" == $text ) { $text = $nt->getFragment(); }
1246 } else {
1247 $u = wfLocalUrlE( $link, $query );
1249 if ( "" != $nt->getFragment() ) {
1250 $u .= "#" . wfEscapeHTML( $nt->getFragment() );
1252 if ( "" == $text ) { $text = $nt->getPrefixedText(); }
1253 $style = $this->getInternalLinkAttributesObj( $nt, $text );
1255 $inside = "";
1256 if ( "" != $trail ) {
1257 if ( preg_match( wfMsg("linktrail"), $trail, $m ) ) {
1258 $inside = $m[1];
1259 $trail = $m[2];
1262 $r = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1263 wfProfileOut( $fname );
1264 return $r;
1267 # Pass a title object, not a title string
1268 function makeBrokenLinkObj( &$nt, $text = "", $query = "", $trail = "" )
1270 global $wgOut, $wgUser;
1272 $fname = "Skin::makeBrokenLinkObj";
1273 wfProfileIn( $fname );
1275 $link = $nt->getPrefixedURL();
1277 if ( "" == $query ) { $q = "action=edit"; }
1278 else { $q = "action=edit&{$query}"; }
1279 $u = wfLocalUrlE( $link, $q );
1281 if ( "" == $text ) { $text = $nt->getPrefixedText(); }
1282 $style = $this->getInternalLinkAttributesObj( $nt, $text, "yes" );
1284 $inside = "";
1285 if ( "" != $trail ) {
1286 if ( preg_match( wfMsg("linktrail"), $trail, $m ) ) {
1287 $inside = $m[1];
1288 $trail = $m[2];
1291 if ( $wgOut->isPrintable() ||
1292 ( 1 == $wgUser->getOption( "highlightbroken" ) ) ) {
1293 $s = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1294 } else {
1295 $s = "{$text}{$inside}<a href=\"{$u}\"{$style}>?</a>{$trail}";
1298 wfProfileOut( $fname );
1299 return $s;
1302 # Pass a title object, not a title string
1303 function makeStubLinkObj( &$nt, $text = "", $query = "", $trail = "" )
1305 global $wgOut, $wgUser;
1307 $link = $nt->getPrefixedURL();
1309 $u = wfLocalUrlE( $link, $query );
1311 if ( "" == $text ) { $text = $nt->getPrefixedText(); }
1312 $style = $this->getInternalLinkAttributesObj( $nt, $text, "stub" );
1314 $inside = "";
1315 if ( "" != $trail ) {
1316 if ( preg_match( wfMsg("linktrail"), $trail, $m ) ) {
1317 $inside = $m[1];
1318 $trail = $m[2];
1321 if ( $wgOut->isPrintable() ||
1322 ( 1 == $wgUser->getOption( "highlightbroken" ) ) ) {
1323 $s = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1324 } else {
1325 $s = "{$text}{$inside}<a href=\"{$u}\"{$style}>!</a>{$trail}";
1327 return $s;
1330 function fnamePart( $url )
1332 $basename = strrchr( $url, "/" );
1333 if ( false === $basename ) { $basename = $url; }
1334 else { $basename = substr( $basename, 1 ); }
1335 return wfEscapeHTML( $basename );
1338 function makeImage( $url, $alt = "" )
1340 global $wgOut;
1342 if ( "" == $alt ) { $alt = $this->fnamePart( $url ); }
1343 $s = "<img src=\"{$url}\" alt=\"{$alt}\">";
1344 return $s;
1347 function makeImageLink( $name, $url, $alt = "" ) {
1348 $nt = Title::makeTitle( Namespace::getImage(), $name );
1349 return $this->makeImageLinkObj( $nt, $alt );
1352 function makeImageLinkObj( $nt, $alt = "" ) {
1353 $link = $nt->getPrefixedURL();
1354 $name = $nt->getDBKey();
1355 $url = wfImageUrl( $name );
1356 if ( empty( $alt ) ) {
1357 $alt = preg_replace( '/\.(.+?)^/', '', $name );
1359 $alt = htmlspecialchars( $alt );
1361 $u = wfLocalUrlE( $link );
1362 $s = "<a href=\"{$u}\" class='image' title=\"{$alt}\">" .
1363 "<img border=\"0\" src=\"{$url}\" alt=\"{$alt}\"></a>";
1364 return $s;
1367 function makeMediaLink( $name, $url, $alt = "" ) {
1368 $nt = Title::makeTitle( Namespace::getMedia(), $name );
1369 return $this->makeMediaLinkObj( $nt, $alt );
1372 function makeMediaLinkObj( $nt, $alt = "" )
1374 $name = $nt->getDBKey();
1375 $url = wfImageUrl( $name );
1376 if ( empty( $alt ) ) {
1377 $alt = preg_replace( '/\.(.+?)^/', '', $name );
1380 $u = htmlspecialchars( $url );
1381 $s = "<a href=\"{$u}\" class='internal' title=\"{$alt}\">{$alt}</a>";
1382 return $s;
1385 function specialLink( $name, $key = "" )
1387 global $wgLang;
1389 if ( "" == $key ) { $key = strtolower( $name ); }
1390 $pn = $wgLang->ucfirst( $name );
1391 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1392 wfMsg( $key ) );
1395 # Called by history lists and recent changes
1398 function beginRecentChangesList()
1400 $rc_cache = array() ;
1401 $rccc = 0 ;
1402 $this->lastdate = "";
1403 return "";
1406 function beginHistoryList()
1408 $this->lastdate = $this->lastline = "";
1409 $s = "\n<p>" . wfMsg( "histlegend" ) . "\n<ul>";
1410 return $s;
1413 function beginImageHistoryList()
1415 $s = "\n<h2>" . wfMsg( "imghistory" ) . "</h2>\n" .
1416 "<p>" . wfMsg( "imghistlegend" ) . "\n<ul>";
1417 return $s;
1420 function endRecentChangesList()
1422 $s = $this->recentChangesBlock() ;
1423 $s .= "</ul>\n";
1424 return $s;
1427 function endHistoryList()
1429 $last = wfMsg( "last" );
1431 $s = preg_replace( "/!OLDID![0-9]+!/", $last, $this->lastline );
1432 $s .= "</ul>\n";
1433 return $s;
1436 function endImageHistoryList()
1438 $s = "</ul>\n";
1439 return $s;
1442 function historyLine( $ts, $u, $ut, $ns, $ttl, $oid, $c, $isminor )
1444 global $wgLang;
1446 $artname = Title::makeName( $ns, $ttl );
1447 $last = wfMsg( "last" );
1448 $cur = wfMsg( "cur" );
1449 $cr = wfMsg( "currentrev" );
1451 if ( $oid && $this->lastline ) {
1452 $ret = preg_replace( "/!OLDID!([0-9]+)!/", $this->makeKnownLink(
1453 $artname, $last, "diff=\\1&oldid={$oid}" ), $this->lastline );
1454 } else {
1455 $ret = "";
1457 $dt = $wgLang->timeanddate( $ts, true );
1459 if ( $oid ) { $q = "oldid={$oid}"; }
1460 else { $q = ""; }
1461 $link = $this->makeKnownLink( $artname, $dt, $q );
1463 if ( 0 == $u ) {
1464 $ul = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
1465 $ut, "target=" . $ut );
1466 } else {
1467 $ul = $this->makeLink( $wgLang->getNsText(
1468 Namespace::getUser() ) . ":{$ut}", $ut ); }
1470 $s = "<li>";
1471 if ( $oid ) {
1472 $curlink = $this->makeKnownLink( $artname, $cur,
1473 "diff=0&oldid={$oid}" );
1474 } else {
1475 $curlink = $cur;
1477 $s .= "({$curlink}) (!OLDID!{$oid}!) . .";
1479 $M = wfMsg( "minoreditletter" );
1480 if ( $isminor ) { $s .= " <strong>{$M}</strong>"; }
1481 $s .= " {$link} . . {$ul}";
1483 if ( "" != $c && "*" != $c ) { $s .= " <em>(" . wfEscapeHTML($c) . ")</em>"; }
1484 $s .= "</li>\n";
1486 $this->lastline = $s;
1487 return $ret;
1490 function recentChangesBlockLine ( $y ) {
1491 global $wgUploadPath ;
1493 $M = wfMsg( "minoreditletter" );
1494 $N = wfMsg( "newpageletter" );
1495 $r = "" ;
1496 $r .= "<img src='{$wgUploadPath}/Arr_.png' width=12 height=12 border=0>" ;
1497 $r .= "<tt>" ;
1498 if ( $y->isnew ) $r .= $N ;
1499 else $r .= "&nbsp;" ;
1500 if ( $y->isminor ) $r .= $M ;
1501 else $r .= "&nbsp;" ;
1502 $r .= " ".$y->timestamp." " ;
1503 $r .= "</tt>" ;
1504 $link = $y->link ;
1505 if ( $y->watched ) $link = "<strong>{$link}</strong>" ;
1506 $r .= $link ;
1508 $r .= " (" ;
1509 $r .= $y->curlink ;
1510 $r .= "; " ;
1511 $r .= $this->makeKnownLink( $y->secureName, wfMsg( "hist" ), "action=history" );
1513 $r .= ") . . ".$y->userlink ;
1514 $r .= $y->usertalklink ;
1515 if ( $y->usercomment != "" )
1516 $r .= " <em>(".wfEscapeHTML($y->usercomment).")</em>" ;
1517 $r .= "<br>\n" ;
1518 return $r ;
1521 function recentChangesBlockGroup ( $y ) {
1522 global $wgUploadPath ;
1524 $r = "" ;
1525 $M = wfMsg( "minoreditletter" );
1526 $N = wfMsg( "newpageletter" );
1527 $isnew = false ;
1528 $userlinks = array () ;
1529 foreach ( $y AS $x ) {
1530 $oldid = $x->diffid ;
1531 if ( $x->isnew ) $isnew = true ;
1532 $u = $x->userlink ;
1533 if ( !isset ( $userlinks[$u] ) ) $userlinks[$u] = 0 ;
1534 $userlinks[$u]++ ;
1537 krsort ( $userlinks ) ;
1538 asort ( $userlinks ) ;
1539 $users = array () ;
1540 $u = array_keys ( $userlinks ) ;
1541 foreach ( $u as $x ) {
1542 $z = $x ;
1543 if ( $userlinks[$x] > 1 ) $z .= " ({$userlinks[$x]}&times;)" ;
1544 array_push ( $users , $z ) ;
1546 $users = " <font size='-1'>[".implode("; ",$users)."]</font>" ;
1548 $e = $y ;
1549 $e = array_shift ( $e ) ;
1551 # Arrow
1552 $rci = "RCI{$this->rccc}" ;
1553 $rcl = "RCL{$this->rccc}" ;
1554 $rcm = "RCM{$this->rccc}" ;
1555 $tl = "<a href='javascript:toggleVisibility(\"{$rci}\",\"{$rcm}\",\"{$rcl}\")'>" ;
1556 $tl .= "<span id='{$rcm}'><img src='{$wgUploadPath}/Arr_r.png' width=12 height=12 border=0></span>" ;
1557 $tl .= "<span id='{$rcl}' style='display:none'><img src='{$wgUploadPath}/Arr_d.png' width=12 height=12 border=0></span>" ;
1558 $tl .= "</a>" ;
1559 $r .= $tl ;
1561 # Main line
1562 $r .= "<tt>" ;
1563 if ( $isnew ) $r .= $N ;
1564 else $r .= "&nbsp;" ;
1565 $r .= "&nbsp;" ; # Minor
1566 $r .= " ".$e->timestamp." " ;
1567 $r .= "</tt>" ;
1569 $link = $e->link ;
1570 if ( $e->watched ) $link = "<strong>{$link}</strong>" ;
1571 $r .= $link ;
1573 if ( !$e->islog ) {
1574 $r .= " (".count($y)." " ;
1575 if ( $isnew ) $r .= wfMsg("changes");
1576 else $r .= $this->makeKnownLink( $e->secureName , wfMsg("changes") , "diff=0&oldid=".$oldid ) ;
1577 $r .= "; " ;
1578 $r .= $this->makeKnownLink( $e->secureName, wfMsg( "history" ), "action=history" );
1579 $r .= ")" ;
1582 $r .= $users ;
1583 $r .= "<br>\n" ;
1585 # Sub-entries
1586 $r .= "<div id='{$rci}' style='display:none'>" ;
1587 foreach ( $y AS $x )
1589 $r .= "<img src='{$wgUploadPath}/Arr_.png' width=12 height=12 border=0>";
1590 $r .= "<tt>&nbsp; &nbsp; &nbsp; &nbsp;" ;
1591 if ( $x->isnew ) $r .= $N ;
1592 else $r .= "&nbsp;" ;
1593 if ( $x->isminor ) $r .= $M ;
1594 else $r .= "&nbsp;" ;
1595 $r .= "</tt>" ;
1597 $o = "" ;
1598 if ( $x->oldid != 0 ) $o = "oldid=".$x->oldid ;
1599 if ( $x->islog ) $link = $x->timestamp ;
1600 else $link = $this->makeKnownLink( $x->secureName, $x->timestamp , $o ) ;
1601 $link = "<tt>{$link}</tt>" ;
1604 $r .= $link ;
1605 $r .= " (" ;
1606 $r .= $x->curlink ;
1607 $r .= "; " ;
1608 $r .= $x->lastlink ;
1609 $r .= ") . . ".$x->userlink ;
1610 $r .= $x->usertalklink ;
1611 if ( $x->usercomment != "" )
1612 $r .= " <em>(".wfEscapeHTML($x->usercomment).")</em>" ;
1613 $r .= "<br>\n" ;
1615 $r .= "</div>\n" ;
1617 $this->rccc++ ;
1618 return $r ;
1621 function recentChangesBlock ()
1623 global $wgUploadPath ;
1624 if ( count ( $this->rc_cache ) == 0 ) return "" ;
1625 $k = array_keys ( $this->rc_cache ) ;
1626 foreach ( $k AS $x )
1628 $y = $this->rc_cache[$x] ;
1629 if ( count ( $y ) < 2 ) {
1630 $r .= $this->recentChangesBlockLine ( array_shift ( $y ) ) ;
1631 } else {
1632 $r .= $this->recentChangesBlockGroup ( $y ) ;
1636 return "<div align=left>{$r}</div>" ;
1639 function recentChangesLine( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched = false, $oldid = 0 , $diffid = 0 )
1641 global $wgUser ;
1642 $usenew = $wgUser->getOption( "usenewrc" );
1643 if ( $usenew )
1644 $r = $this->recentChangesLineNew ( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched , $oldid , $diffid ) ;
1645 else
1646 $r = $this->recentChangesLineOld ( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched , $oldid , $diffid ) ;
1647 return $r ;
1650 function recentChangesLineOld( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched = false, $oldid = 0, $diffid = 0 )
1652 global $wgTitle, $wgLang, $wgUser;
1654 $d = $wgLang->date( $ts, true);
1655 $s = "";
1656 if ( $d != $this->lastdate ) {
1657 if ( "" != $this->lastdate ) { $s .= "</ul>\n"; }
1658 $s .= "<h4>{$d}</h4>\n<ul>";
1659 $this->lastdate = $d;
1661 $h = $wgLang->time( $ts, true );
1662 $t = Title::makeName( $ns, $ttl );
1663 $clink = $this->makeKnownLink( $t , "" );
1664 $nt = Title::newFromText( $t );
1666 if ( $watched ) {
1667 $clink = "<strong>{$clink}</strong>";
1669 $hlink = $this->makeKnownLink( $t, wfMsg( "hist" ), "action=history" );
1670 if ( $isnew || $nt->isLog() ) {
1671 $dlink = wfMsg( "diff" );
1672 } else {
1673 $dlink = $this->makeKnownLink( $t, wfMsg( "diff" ),
1674 "diff={$oldid}&oldid={$diffid}" ); # Finagle's law
1676 if ( 0 == $u ) {
1677 $ul = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
1678 $ut, "target=" . $ut );
1679 } else {
1680 $ul = $this->makeLink( $wgLang->getNsText( Namespace::getUser() ) . ":{$ut}", $ut );
1683 $talkname=$wgLang->getNsText(Namespace::getTalk(0)); # use the shorter name
1684 global $wgDisableAnonTalk;
1685 if( 0 == $u && $wgDisableAnonTalk ) {
1686 $utl = "";
1687 } else {
1688 $utns=$wgLang->getNsText(Namespace::getTalk(Namespace::getUser()));
1689 $utl= $this->makeLink($utns . ":{$ut}", $talkname );
1691 $cr = wfMsg( "currentrev" );
1693 $s .= "<li> ({$dlink}) ({$hlink}) . .";
1694 $M = wfMsg( "minoreditletter" );
1695 $N = wfMsg( "newpageletter" );
1696 if ( $isminor ) { $s .= " <strong>{$M}</strong>"; }
1697 if ( $isnew ) { $s .= "<strong>{$N}</strong>"; }
1698 $s .= " {$clink}; {$h} . . {$ul}";
1700 $blink="";
1701 if ( ( 0 == $u ) && $wgUser->isSysop() ) {
1702 $blink = $this->makeKnownLink( $wgLang->specialPage(
1703 "Blockip" ), wfMsg( "blocklink" ), "ip={$ut}" );
1706 if($blink) {
1707 if($utl) $utl .= " | ";
1708 $utl .= $blink;
1710 if($utl) $s.=" ({$utl})";
1712 if ( "" != $c && "*" != $c ) {
1713 $s .= " <em>(" . wfEscapeHTML( $c ) . ")</em>";
1715 $s .= "</li>\n";
1717 return $s;
1720 function recentChangesLineNew( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched = false, $oldid = 0 , $diffid = 0 )
1722 global $wgTitle, $wgLang, $wgUser;
1724 $rc = new RecentChangesClass ;
1726 $d = $wgLang->date( $ts, true);
1727 $s = "";
1728 $ret = "" ;
1729 if ( $d != $this->lastdate ) {
1730 $ret = $this->recentChangesBlock () ;
1731 $this->rc_cache = array() ;
1732 $ret .= "<h4>{$d}</h4>\n";
1733 $this->lastdate = $d;
1735 $h = $wgLang->time( $ts, true );
1736 $t = Title::makeName( $ns, $ttl );
1737 $clink = $this->makeKnownLink( $t, "" ) ;
1738 if ( $oldid == 0 ) $c2link = $clink ;
1739 else $c2link = $this->makeKnownLink( $t, "" , "oldid={$oldid}" );
1740 $nt = Title::newFromText( $t );
1742 $rc->timestamp = $h ;
1743 $rc->oldid = $oldid ;
1744 $rc->diffid = $diffid ;
1745 $rc->watched = $watched ;
1746 $rc->isnew = $isnew ;
1747 $rc->isminor = $isminor ;
1748 $rc->secureName = $t ;
1749 $rc->displayName = $nt ;
1750 $rc->link = $clink ;
1751 $rc->usercomment = $c ;
1752 $rc->islog = $nt->isLog() ;
1754 if ( ( $isnew && $oldid == 0 ) || $nt->isLog() ) {
1755 $dlink = wfMsg( "cur" );
1756 } else {
1757 $dlink = $this->makeKnownLink( $t, wfMsg( "cur" ),
1758 "diff=0&oldid={$oldid}" );
1761 if ( $diffid == 0 || $nt->isLog() ) {
1762 $plink = wfMsg( "last" );
1763 } else {
1764 $plink = $this->makeKnownLink( $t, wfMsg( "last" ),
1765 "diff={$oldid}&oldid={$diffid}" );
1768 if ( 0 == $u ) {
1769 $ul = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
1770 $ut, "target=" . $ut );
1771 } else { $ul = $this->makeLink( $wgLang->getNsText(
1772 Namespace::getUser() ) . ":{$ut}", $ut ); }
1774 $rc->userlink = $ul ;
1775 $rc->lastlink = $plink ;
1776 $rc->curlink = $dlink ;
1778 $utns=$wgLang->getNsText(Namespace::getTalk(Namespace::getUser()));
1779 $talkname=$wgLang->getNsText(Namespace::getTalk(0)); # use the shorter name
1780 $utl= $this->makeLink($utns . ":{$ut}", $talkname );
1782 global $wgDisableAnonTalk;
1783 if ( ( 0 == $u ) && $wgUser->isSysop() ) {
1784 $blink = $this->makeKnownLink( $wgLang->specialPage(
1785 "Blockip" ), wfMsg( "blocklink" ), "ip={$ut}" );
1786 if( $wgDisableAnonTalk )
1787 $rc->usertalklink = " ({$blink})";
1788 else
1789 $rc->usertalklink = " ({$utl} | {$blink})";
1790 } else {
1791 if( $wgDisableAnonTalk && ($u == 0) )
1792 $rc->usertalklink = "";
1793 else
1794 $rc->usertalklink = " ({$utl})";
1797 if ( !isset ( $this->rc_cache[$t] ) ) $this->rc_cache[$t] = array() ;
1798 array_push ( $this->rc_cache[$t] , $rc ) ;
1799 return $ret;
1803 function imageHistoryLine( $iscur, $ts, $img, $u, $ut, $size, $c )
1805 global $wgUser, $wgLang, $wgTitle;
1807 $dt = $wgLang->timeanddate( $ts, true );
1808 $del = wfMsg( "deleteimg" );
1809 $cur = wfMsg( "cur" );
1811 if ( $iscur ) {
1812 $url = wfImageUrl( $img );
1813 $rlink = $cur;
1814 if ( $wgUser->isSysop() ) {
1815 $link = wfLocalUrlE( $wgTitle->getPrefixedText(), "image=" . $wgTitle->getURL() .
1816 "&action=delete" );
1817 $style = $this->getInternalLinkAttributes( $link, $del );
1819 $dlink = "<a href=\"{$link}\"{$style}>{$del}</a>";
1820 } else {
1821 $dlink = $del;
1823 } else {
1824 $url = wfEscapeHTML( wfImageArchiveUrl( $img ) );
1825 if( $wgUser->getID() != 0 ) {
1826 $rlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
1827 wfMsg( "revertimg" ), "action=revert&oldimage=" .
1828 urlencode( $img ) );
1829 $dlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
1830 $del, "action=delete&oldimage=" . urlencode( $img ) );
1831 } else {
1832 # Having live active links for non-logged in users
1833 # means that bots and spiders crawling our site can
1834 # inadvertently change content. Baaaad idea.
1835 $rlink = wfMsg( "revertimg" );
1836 $dlink = $del;
1839 if ( 0 == $u ) { $ul = $ut; }
1840 else { $ul = $this->makeLink( $wgLang->getNsText(
1841 Namespace::getUser() ) . ":{$ut}", $ut ); }
1843 $nb = wfMsg( "nbytes", $size );
1844 $style = $this->getInternalLinkAttributes( $url, $dt );
1846 $s = "<li> ({$dlink}) ({$rlink}) <a href=\"{$url}\"{$style}>{$dt}</a>"
1847 . " . . {$ul} ({$nb})";
1849 if ( "" != $c && "*" != $c ) {
1850 $s .= " <em>(" . wfEscapeHTML( $c ) . ")</em>";
1852 $s .= "</li>\n";
1853 return $s;
1856 function tocIndent($level) {
1858 while($level-->0) $rv.="<div style=\"margin-left:2em;\">\n";
1859 return $rv;
1863 function tocUnindent($level) {
1864 while($level-->0) $rv.="</div>\n";
1865 return $rv;
1868 // parameter level defines if we are on an indentation level
1869 function tocLine($anchor,$tocline,$level) {
1871 if($level) {
1873 return "<A CLASS=\"internal\" HREF=\"#".$anchor."\">".$tocline."</A><BR>\n";
1874 } else {
1876 return "<div style=\"margin-bottom:0px;\">\n".
1877 "<A CLASS=\"internal\" HREF=\"#".$anchor."\">".$tocline."</A><BR>\n".
1878 "</div>\n";
1883 function tocTable($toc) {
1884 // note to CSS fanatics: putting this in a div does not work -- div won't auto-expand
1885 global $printable;
1887 if (!$printable) {
1888 $hideline = " <script type='text/javascript'>showTocToggle(\"" . wfMsg("showtoc") . "\",\"" . wfMsg("hidetoc") . "\")</script>";
1890 return
1891 "<p><table border=\"0\" id=\"toc\"><tr><td align=\"center\">\n".
1892 "<b>".wfMsg("toc")."</b>" .
1893 $hideline .
1894 "</td></tr><tr id='tocinside'><td align=\"left\">\n".
1895 $toc."</td></tr></table><P>\n";
1898 # These two do not check for permissions: check $wgTitle->userCanEdit before calling them
1899 function editSectionScript($section,$head) {
1901 global $wgTitle,$wgUser,$oldid;
1902 if($oldid) return $head;
1903 $url = wfLocalUrlE(urlencode($wgTitle->getPrefixedText()),"action=edit&section=$section");
1904 return "<span onContextMenu='document.location=\"".$url."\";return false;'>{$head}</span>";
1907 function editSectionLink($section) {
1909 global $printable;
1910 global $wgTitle,$wgUser,$oldid;
1911 if($oldid) return "";
1912 if ($printable) return "";
1913 $editurl="&section={$section}";
1914 $url=$this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg("editsection"),"action=edit".$editurl);
1915 return "<div style=\"float:right;margin-left:5px;\"><small>[".$url."]</small></div>";
1920 include_once( "SkinStandard.php" );
1921 include_once( "SkinNostalgia.php" );
1922 include_once( "SkinCologneBlue.php" );
1924 #include_once( "SkinSmarty.php" );