minor usability enhancement
[mediawiki.git] / includes / Skin.php
blob2ea643d7ca7655ec4509adc083222bdc20bc34a8
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 wfProfileIn( "Skin::initPage" );
75 $wgOut->addLink( "shortcut icon", "", "/favicon.ico" );
76 if ( $wgOut->isPrintable() ) { $ss = "wikiprintable.css"; }
77 else { $ss = $this->getStylesheet(); }
78 $wgOut->addLink( "stylesheet", "", "{$wgStyleSheetPath}/{$ss}" );
79 wfProfileOut();
82 function outputPage( &$out ) {
83 $this->initPage();
84 $out->out( $out->headElement() );
86 $out->out( "\n<body" );
87 $ops = $this->getBodyOptions();
88 foreach ( $ops as $name => $val ) {
89 $out->out( " $name='$val'" );
91 $out->out( ">\n" );
92 if ( $wgDebugComments ) {
93 $out->out( "<!-- Wiki debugging output:\n" .
94 $out->mDebugtext . "-->\n" );
96 $out->out( $this->beforeContent() );
98 $out->out( $out->mBodytext );
100 $out->out( $this->afterContent() );
101 wfProfileOut();
103 wfProfileOut(); # A hack - we can't report after here
104 $out->out( $out->reportTime() );
106 $out->out( "\n</body></html>" );
109 function getHeadScripts() {
110 global $wgStyleSheetPath;
111 $r = "<script type=\"text/javascript\" src=\"{$wgStyleSheetPath}/wikibits.js\"></script>\n";
112 return $r;
115 function getUserStyles()
117 $s = "<style type='text/css'><!--\n";
118 $s .= $this->doGetUserStyles();
119 $s .= "//--></style>\n";
120 return $s;
123 function doGetUserStyles()
125 global $wgUser;
127 $s = "";
128 if ( 1 == $wgUser->getOption( "underline" ) ) {
129 # Don't override browser settings
130 } else {
131 # Force no underline
132 $s .= "a.stub, a.new, a.internal, a.external { " .
133 "text-decoration: none; }\n";
135 if ( 1 == $wgUser->getOption( "highlightbroken" ) ) {
136 $s .= "a.new, #quickbar a.new { color: #CC2200; }\n";
138 if ( 1 == $wgUser->getOption( "justify" ) ) {
139 $s .= "#article { text-align: justify; }\n";
141 return $s;
144 function getBodyOptions()
146 global $wgUser, $wgTitle, $wgNamespaceBackgrounds, $wgOut, $oldid, $redirect, $diff,$action;
148 if ( 0 != $wgTitle->getNamespace() ) {
149 $a = array( "bgcolor" => "#ffffec" );
151 else $a = array( "bgcolor" => "#FFFFFF" );
152 if($wgOut->isArticle() && $wgUser->getOption("editondblclick")
154 (!$wgTitle->isProtected() || $wgUser->isSysop())
157 $n = $wgTitle->getPrefixedURL();
158 $t = wfMsg( "editthispage" );
159 $oid = $red = "";
160 if ( $redirect ) { $red = "&redirect={$redirect}"; }
161 if ( $oldid && ! isset( $diff ) ) {
162 $oid = "&oldid={$oldid}";
164 $s = wfLocalUrlE($n,"action=edit{$oid}{$red}");
165 $s = "document.location = \"" .$s ."\";";
166 $a += array ("ondblclick" => $s);
169 if($action=="edit") { # set focus in edit box
170 $foc = "document.editform.wpTextbox1.focus()";
171 if($a['onload']) {
172 $a['onload'] .= ";$foc";
173 } else {
174 $a['onload'] = $foc;
177 return $a;
180 function getExternalLinkAttributes( $link, $text )
182 global $wgUser, $wgOut, $wgLang;
184 $link = urldecode( $link );
185 $link = $wgLang->checkTitleEncoding( $link );
186 $link = str_replace( "_", " ", $link );
187 $link = wfEscapeHTML( $link );
189 if ( $wgOut->isPrintable() ) { $r = " class='printable'"; }
190 else { $r = " class='external'"; }
192 if ( 1 == $wgUser->getOption( "hover" ) ) {
193 $r .= " title=\"{$link}\"";
195 return $r;
198 function getInternalLinkAttributes( $link, $text, $broken = false )
200 global $wgUser, $wgOut;
202 $link = urldecode( $link );
203 $link = str_replace( "_", " ", $link );
204 $link = wfEscapeHTML( $link );
206 if ( $wgOut->isPrintable() ) { $r = " class='printable'"; }
207 else if ( $broken == "stub" ) { $r = " class='stub'"; }
208 else if ( $broken == "yes" ) { $r = " class='new'"; }
209 else { $r = " class='internal'"; }
211 if ( 1 == $wgUser->getOption( "hover" ) ) {
212 $r .= " title=\"{$link}\"";
214 return $r;
217 function getLogo()
219 global $wgLogo;
220 return $wgLogo;
223 # This will be called immediately after the <body> tag. Split into
224 # two functions to make it easier to subclass.
226 function beforeContent()
228 global $wgUser, $wgOut;
230 if ( $wgOut->isPrintable() ) {
231 $s = $this->pageTitle() . $this->pageSubtitle() . "\n";
232 $s .= "\n<div class='bodytext'>";
233 return $s;
235 return $this->doBeforeContent();
238 function doBeforeContent()
240 global $wgUser, $wgOut, $wgTitle, $wgLang;
241 wfProfileIn( "Skin::doBeforeContent" );
243 $s = "";
244 $qb = $this->qbSetting();
246 if( $langlinks = $this->otherLanguages() ) {
247 $rows = 2;
248 $borderhack = "";
249 } else {
250 $rows = 1;
251 $langlinks = false;
252 $borderhack = "class='top'";
255 $s .= "\n<div id='content'>\n<div id='topbar'>" .
256 "<table width='98%' border=0 cellspacing=0><tr>";
258 $shove = ($qb != 0);
259 $left = ($qb == 1 || $qb == 3);
260 if($wgLang->isRTL()) $left = !$left;
262 if ( !$shove ) {
263 $s .= "<td class='top' align=left valign=top rowspan='{$rows}'>" .
264 $this->logoText() . "</td>";
265 } elseif( $left ) {
266 $s .= $this->getQuickbarCompensator( $rows );
268 $l = $wgLang->isRTL() ? "right" : "left";
269 $s .= "<td {$borderhack} align='$l' valign='top'>";
271 $s .= $this->topLinks() ;
272 $s .= "<p class='subtitle'>" . $this->pageTitleLinks();
274 $r = $wgLang->isRTL() ? "left" : "right";
275 $s .= "</td>\n<td {$borderhack} valign='top' align='$r' nowrap>";
276 $s .= $this->nameAndLogin();
277 $s .= "\n<br>" . $this->searchForm() . "</td>";
279 if ( $langlinks ) {
280 $s .= "</tr>\n<tr><td class='top' colspan=\"2\">$langlinks</td>";
283 if ( $shove && !$left ) { # Right
284 $s .= $this->getQuickbarCompensator( $rows );
286 $s .= "</tr></table>\n</div>\n";
287 $s .= "\n<div id='article'>";
289 $s .= $this->pageTitle();
290 $s .= $this->pageSubtitle() ;
291 $s .= getCategories(); // For some odd reason, zhis can't be a function of the object
292 $s .= "\n<p>";
293 wfProfileOut();
294 return $s;
297 function getQuickbarCompensator( $rows = 1 )
299 return "<td width='152' rowspan='{$rows}'>&nbsp;</td>";
302 # This gets called immediately before the </body> tag.
304 function afterContent()
306 global $wgUser, $wgOut, $wgServer, $HTTP_SERVER_VARS;
307 global $wgTitle;
309 if ( $wgOut->isPrintable() ) {
310 $s = "\n</div>\n";
312 $u = $wgServer . $wgTitle->getFullURL();
313 $rf = wfMsg( "retrievedfrom", $u );
315 if ( $wgOut->isArticle() ) {
316 $lm = "<br>" . $this->lastModified();
317 } else { $lm = ""; }
319 $cr = wfMsg( "gnunote" );
320 $s .= "<p><em>{$rf}{$lm} {$cr}</em>\n";
321 return $s;
323 return $this->doAfterContent();
326 function doAfterContent()
328 global $wgUser, $wgOut, $wgLang;
329 wfProfileIn( "Skin::doAfterContent" );
331 $s = "\n</div><br clear=all>\n";
333 $s .= "\n<div id='footer'>";
334 $s .= "<table width='98%' border=0 cellspacing=0><tr>";
336 $qb = $this->qbSetting();
337 $shove = ($qb != 0);
338 $left = ($qb == 1 || $qb == 3);
339 if($wgLang->isRTL()) $left = !$left;
341 if ( $shove && $left ) { # Left
342 $s .= $this->getQuickbarCompensator();
344 $l = $wgLang->isRTL() ? "right" : "left";
345 $s .= "<td class='bottom' align='$l' valign='top'>";
347 $s .= $this->bottomLinks();
348 $s .= "\n<br>" . $this->mainPageLink()
349 . " | " . $this->aboutLink()
350 . " | " . $this->specialLink( "recentchanges" )
351 . " | " . $this->searchForm()
352 . "<br>" . $this->pageStats();
354 $s .= "</td>";
355 if ( $shove && !$left ) { # Right
356 $s .= $this->getQuickbarCompensator();
358 $s .= "</tr></table>\n</div>\n</div>\n";
360 if ( 0 != $qb ) { $s .= $this->quickBar(); }
361 wfProfileOut();
362 return $s;
365 function pageTitleLinks()
367 global $wgOut, $wgTitle, $oldid, $action, $diff, $wgUser, $wgLang, $wgUseApproval ;
369 $s = $this->printableLink();
371 if ( $wgOut->isArticle() ) {
372 if ( $wgTitle->getNamespace() == Namespace::getImage() ) {
373 $name = $wgTitle->getDBkey();
374 $link = wfEscapeHTML( wfImageUrl( $name ) );
375 $style = $this->getInternalLinkAttributes( $link, $name );
376 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>";
378 # This will show the "Approve" link if $wgUseApproval=true;
379 if ( isset ( $wgUseApproval ) && $wgUseApproval )
381 $t = $wgTitle->getDBkey();
382 $name = "Approve this article" ;
383 $link = "http://test.wikipedia.org/w/magnus/wiki.phtml?title={$t}&action=submit&doit=1" ;
384 #wfEscapeHTML( wfImageUrl( $name ) );
385 $style = $this->getExternalLinkAttributes( $link, $name );
386 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>" ;
388 if ( "history" == $action || isset( $diff ) || isset( $oldid ) ) {
389 $s .= " | " . $this->makeKnownLink( $wgTitle->getPrefixedText(),
390 wfMsg( "currentrev" ) );
393 if ( $wgUser->getNewtalk() ) {
394 # do not show "You have new messages" text when we are viewing our
395 # own talk page
397 if(!(strcmp($wgTitle->getText(),$wgUser->getName()) == 0 &&
398 $wgTitle->getNamespace()==Namespace::getTalk(Namespace::getUser()))) {
399 $n =$wgUser->getName();
400 $tl = $this->makeKnownLink( $wgLang->getNsText(
401 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
402 wfMsg("newmessageslink") );
403 $s.=" | <strong>". str_replace( "$1", $tl, wfMsg("newmessages") ) . "</strong>";
406 if( $wgUser->isSysop() &&
407 (($wgTitle->getArticleId() == 0) || ($action == "history")) &&
408 ($n = $wgTitle->isDeleted() ) ) {
409 $s .= " | " . wfMsg( "thisisdeleted",
410 $this->makeKnownLink(
411 $wgLang->SpecialPage( "Undelete/" . $wgTitle->getPrefixedDBkey() ),
412 wfMsg( "restorelink", $n ) ) );
414 return $s;
417 function printableLink()
419 global $wgOut, $wgTitle, $oldid, $action;
421 if ( "history" == $action ) { $q = "action=history&"; }
422 else { $q = ""; }
424 $s = $this->makeKnownLink( $wgTitle->getPrefixedText(),
425 WfMsg( "printableversion" ), "{$q}printable=yes" );
426 return $s;
429 function pageTitle()
431 global $wgOut, $wgTitle, $wgUser;
433 $s = "<h1 class='pagetitle'>" . $wgOut->getPageTitle() . "</h1>";
434 if($wgUser->getOption("editsectiononrightclick") && $wgTitle->userCanEdit()) { $s=$this->editSectionScript(0,$s);}
435 return $s;
438 function pageSubtitle()
440 global $wgOut,$wgTitle,$wgNamespacesWithSubpages;
442 $sub = $wgOut->getSubtitle();
443 if ( "" == $sub ) { $sub = wfMsg( "fromwikipedia" ); }
444 if($wgOut->isArticle() && $wgNamespacesWithSubpages[$wgTitle->getNamespace()]) {
445 $ptext=$wgTitle->getPrefixedText();
446 if(preg_match("/\//",$ptext)) {
447 $sub.="</p><p class='subpages'>";
448 $links=explode("/",$ptext);
449 $c=0;
450 $growinglink="";
451 foreach($links as $link) {
452 $c++;
453 if ($c<count($links)) {
454 $growinglink.=$link;
455 $getlink=$this->makeLink($growinglink,$link);
456 if(preg_match("/class='new'/i",$getlink)) { break; } # this is a hack, but it saves time
457 if ($c>1) {
458 $sub .= " | ";
459 } else {
460 $sub .="&lt; ";
462 $sub .= $getlink;
463 $growinglink.="/";
469 $s = "<p class='subtitle'>{$sub}\n";
470 return $s;
473 function nameAndLogin()
475 global $wgUser, $wgTitle, $wgLang, $wgShowIPinHeader;
477 $li = $wgLang->specialPage( "Userlogin" );
478 $lo = $wgLang->specialPage( "Userlogout" );
480 $s = "";
481 if ( 0 == $wgUser->getID() ) {
482 if( $wgShowIPinHeader ) {
483 $n = getenv( "REMOTE_ADDR" );
485 $tl = $this->makeKnownLink( $wgLang->getNsText(
486 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
487 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
489 $s .= $n . " (".$tl.")";
490 } else {
491 $s .= wfMsg("notloggedin");
494 $rt = $wgTitle->getPrefixedURL();
495 if ( 0 == strcasecmp( urlencode( $lo ), $rt ) ) {
496 $q = "";
497 } else { $q = "returnto={$rt}"; }
499 $s .= "\n<br>" . $this->makeKnownLink( $li,
500 wfMsg( "login" ), $q );
501 } else {
502 $n = $wgUser->getName();
503 $rt = $wgTitle->getPrefixedURL();
504 $tl = $this->makeKnownLink( $wgLang->getNsText(
505 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
506 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
508 $tl = " ({$tl})";
510 $s .= $this->makeKnownLink( $wgLang->getNsText(
511 Namespace::getUser() ) . ":{$n}", $n ) . "{$tl}<br>" .
512 $this->makeKnownLink( $lo, wfMsg( "logout" ),
513 "returnto={$rt}" ) . " | " .
514 $this->specialLink( "preferences" );
516 $s .= " | " . $this->makeKnownLink( wfMsg( "helppage" ),
517 wfMsg( "help" ) );
519 return $s;
522 function searchForm()
524 global $search;
526 $s = "<form name='search' class='inline' method=get action=\""
527 . wfLocalUrl( "" ) . "\">"
528 . "<input type=text name=\"search\" size=19 value=\""
529 . htmlspecialchars(substr($search,0,256)) . "\">\n"
530 . "<input type=submit name=\"go\" value=\"" . wfMsg ("go") . "\">&nbsp;"
531 . "<input type=submit value=\"" . wfMsg ("search") . "\"></form>";
533 return $s;
536 function topLinks()
538 global $wgOut;
539 $sep = " |\n";
541 $s = $this->mainPageLink() . $sep
542 . $this->specialLink( "recentchanges" );
544 if ( $wgOut->isArticle() ) {
545 $s .= $sep . $this->editThisPage()
546 . $sep . $this->historyLink();
548 # Many people don't like this dropdown box
549 #$s .= $sep . $this->specialPagesList();
551 return $s;
554 function bottomLinks()
556 global $wgOut, $wgUser, $wgTitle;
557 $sep = " |\n";
559 $s = "";
560 if ( $wgOut->isArticle() ) {
561 $s .= "<strong>" . $this->editThisPage() . "</strong>";
562 if ( 0 != $wgUser->getID() ) {
563 $s .= $sep . $this->watchThisPage();
565 $s .= $sep . $this->talkLink()
566 . $sep . $this->historyLink()
567 . $sep . $this->whatLinksHere()
568 . $sep . $this->watchPageLinksLink();
570 if ( $wgTitle->getNamespace() == Namespace::getUser()
571 || $wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser()) )
574 $id=User::idFromName($wgTitle->getText());
575 $ip=User::isIP($wgTitle->getText());
577 if($id || $ip) { # both anons and non-anons have contri list
578 $s .= $sep . $this->userContribsLink();
580 if ( 0 != $wgUser->getID() ) { # show only to signed in users
581 if($id) { # can only email non-anons
582 $s .= $sep . $this->emailUserLink();
586 if ( $wgUser->isSysop() && $wgTitle->getArticleId() ) {
587 $s .= "\n<br>" . $this->deleteThisPage() .
588 $sep . $this->protectThisPage() .
589 $sep . $this->moveThisPage();
591 $s .= "<br>\n" . $this->otherLanguages();
593 return $s;
596 function pageStats()
598 global $wgOut, $wgLang, $wgArticle;
599 global $oldid, $diff, $wgDisableCounters;
601 if ( ! $wgOut->isArticle() ) { return ""; }
602 if ( isset( $oldid ) || isset( $diff ) ) { return ""; }
603 if ( 0 == $wgArticle->getID() ) { return ""; }
605 if ( $wgDisableCounters ) {
606 $s = "";
607 } else {
608 $count = $wgArticle->getCount();
609 $s = str_replace( "$1", $count, wfMsg( "viewcount" ) );
611 $s .= $this->lastModified();
612 $s .= " " . wfMsg( "gnunote" );
613 return "<span id='pagestats'>{$s}</span>";
616 function lastModified()
618 global $wgLang, $wgArticle;
620 $d = $wgLang->timeanddate( $wgArticle->getTimestamp(), true );
621 $s = " " . str_replace( "$1", $d, wfMsg( "lastmodified" ) );
622 return $s;
625 function logoText( $align = "" )
627 if ( "" != $align ) { $a = " align='{$align}'"; }
628 else { $a = ""; }
630 $mp = wfMsg( "mainpage" );
631 $s = "<a href=\"" . wfLocalUrlE( urlencode( $mp ) )
632 . "\"><img{$a} border=0 src=\""
633 . $this->getLogo() . "\" alt=\"" . "[{$mp}]\"></a>";
634 return $s;
637 function quickBar()
639 global $wgOut, $wgTitle, $wgUser, $action, $wgLang;
640 global $wpPreview;
641 wfProfileIn( "Skin::quickBar" );
642 $tns=$wgTitle->getNamespace();
644 $s = "\n<div id='quickbar'>";
645 $s .= "\n" . $this->logoText() . "\n<hr class='sep'>";
647 $sep = "\n<br>";
648 $s .= $this->mainPageLink()
649 . $sep . $this->specialLink( "recentchanges" )
650 . $sep . $this->specialLink( "randompage" );
651 if ($wgUser->getID()) {
652 $s.= $sep . $this->specialLink( "watchlist" ) ;
653 $s .= $sep .$this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
654 wfMsg( "mycontris" ), "target=" . wfUrlencode($wgUser->getName() ) );
657 // only show watchlist link if logged in
658 if ( wfMsg ( "currentevents" ) != "-" ) $s .= $sep . $this->makeKnownLink( wfMsg( "currentevents" ), "" ) ;
659 $s .= "\n<br><hr class='sep'>";
660 $articleExists = $wgTitle->getArticleId();
661 if ( $wgOut->isArticle() || $action =="edit" || $action =="history" || $wpPreview) {
663 if($wgOut->isArticle()) {
664 $s .= "<strong>" . $this->editThisPage() . "</strong>";
665 } else { # backlink to the article in edit or history mode
666 if($articleExists){ # no backlink if no article
667 switch($tns) {
668 case 0:
669 $text = wfMsg("articlepage");
670 break;
671 case 1:
672 $text = wfMsg("viewtalkpage");
673 break;
674 case 2:
675 $text = wfMsg("userpage");
676 break;
677 case 3:
678 $text = wfMsg("viewtalkpage");
679 break;
680 case 4:
681 $text = wfMsg("wikipediapage");
682 break;
683 case 5:
684 $text = wfMsg("viewtalkpage");
685 break;
686 case 6:
687 $text = wfMsg("imagepage");
688 break;
689 case 7:
690 $text = wfMsg("viewtalkpage");
691 break;
692 default:
693 $text= wfMsg("articlepage");
696 $link = $wgTitle->getText();
697 if ($nstext = $wgLang->getNsText($tns) ) { # add namespace if necessary
698 $link = $nstext . ":" . $link ;
700 $s .= $this->makeLink($link, $text );
701 } elseif( $wgTitle->getNamespace() != Namespace::getSpecial() ) {
702 # we just throw in a "New page" text to tell the user that he's in edit mode,
703 # and to avoid messing with the separator that is prepended to the next item
704 $s .= "<strong>" . wfMsg("newpage") . "</strong>";
710 if( $tns%2 && $action!="edit" && !$wpPreview) {
711 $s.="<br>".$this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg("postcomment"),"action=edit&section=new");
715 watching could cause problems in edit mode:
716 if user edits article, then loads "watch this article" in background and then saves
717 article with "Watch this article" checkbox disabled, the article is transparently
718 unwatched. Therefore we do not show the "Watch this page" link in edit mode
720 if ( 0 != $wgUser->getID() && $articleExists) {
721 if($action!="edit" && $action!="history" &&
722 $action != "submit" )
723 {$s .= $sep . $this->watchThisPage(); }
724 if ( $wgTitle->userCanEdit() ) $s .= $sep . $this->moveThisPage();
726 if ( $wgUser->isSysop() and $articleExists ) {
727 $s .= $sep . $this->deleteThisPage() .
728 $sep . $this->protectThisPage();
730 $s .= $sep . $this->talkLink();
731 if ($articleExists && $action !="history") { $s .= $sep . $this->historyLink();}
732 $s.=$sep . $this->whatLinksHere();
734 if($wgOut->isArticle()) {
735 $s .= $sep . $this->watchPageLinksLink();
738 if ( Namespace::getUser() == $wgTitle->getNamespace()
739 || $wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser())
742 $id=User::idFromName($wgTitle->getText());
743 $ip=User::isIP($wgTitle->getText());
745 if($id||$ip) {
746 $s .= $sep . $this->userContribsLink();
748 if ( 0 != $wgUser->getID() ) {
749 if($id) { # can only email real users
750 $s .= $sep . $this->emailUserLink();
754 $s .= "\n<br><hr class='sep'>";
757 if ( 0 != $wgUser->getID() ) {
758 $s .= $this->specialLink( "upload" ) . $sep;
760 $s .= $this->specialLink( "specialpages" )
761 . $sep . $this->bugReportsLink();
763 $s .= "\n<br></div>\n";
764 wfProfileOut();
765 return $s;
768 function specialPagesList()
770 global $wgUser, $wgOut, $wgLang, $wgServer, $wgRedirectScript;
771 $a = array();
773 $validSP = $wgLang->getValidSpecialPages();
775 foreach ( $validSP as $name => $desc ) {
776 if ( "" == $desc ) { continue; }
777 $a[$name] = $desc;
779 if ( $wgUser->isSysop() )
781 $sysopSP = $wgLang->getSysopSpecialPages();
783 foreach ( $sysopSP as $name => $desc ) {
784 if ( "" == $desc ) { continue; }
785 $a[$name] = $desc ;
788 if ( $wgUser->isDeveloper() )
790 $devSP = $wgLang->getDeveloperSpecialPages();
792 foreach ( $devSP as $name => $desc ) {
793 if ( "" == $desc ) { continue; }
794 $a[$name] = $desc ;
797 $go = wfMsg( "go" );
798 $sp = wfMsg( "specialpages" );
799 $spp = $wgLang->specialPage( "Specialpages" );
801 $s = "<form id=\"specialpages\" method=\"get\" class=\"inline\" " .
802 "action=\"{$wgServer}{$wgRedirectScript}\">\n";
803 $s .= "<select name=\"wpDropdown\">\n";
804 $s .= "<option value=\"{$spp}\">{$sp}</option>\n";
806 foreach ( $a as $name => $desc ) {
807 $p = $wgLang->specialPage( $name );
808 $s .= "<option value=\"{$p}\">{$desc}</option>\n";
810 $s .= "</select>\n";
811 $s .= "<input type=submit value=\"{$go}\" name=redirect>\n";
812 $s .= "</form>\n";
813 return $s;
816 function mainPageLink()
818 $mp = wfMsg( "mainpage" );
819 $s = $this->makeKnownLink( $mp, $mp );
820 return $s;
823 function copyrightLink()
825 $s = $this->makeKnownLink( wfMsg( "copyrightpage" ),
826 wfMsg( "copyrightpagename" ) );
827 return $s;
830 function aboutLink()
832 $s = $this->makeKnownLink( wfMsg( "aboutpage" ),
833 wfMsg( "aboutwikipedia" ) );
834 return $s;
837 function editThisPage()
839 global $wgOut, $wgTitle, $oldid, $redirect, $diff;
841 if ( ! $wgOut->isArticle() || $diff ) {
842 $s = wfMsg( "protectedpage" );
843 } else if ( $wgTitle->userCanEdit() ) {
844 $n = $wgTitle->getPrefixedText();
845 $t = wfMsg( "editthispage" );
846 $oid = $red = "";
848 if ( $redirect ) { $red = "&redirect={$redirect}"; }
849 if ( $oldid && ! isset( $diff ) ) {
850 $oid = "&oldid={$oldid}";
852 $s = $this->makeKnownLink( $n, $t, "action=edit{$oid}{$red}" );
853 } else {
854 $s = wfMsg( "protectedpage" );
856 return $s;
859 function deleteThisPage()
861 global $wgUser, $wgOut, $wgTitle, $diff;
863 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
864 $n = $wgTitle->getPrefixedText();
865 $t = wfMsg( "deletethispage" );
867 $s = $this->makeKnownLink( $n, $t, "action=delete" );
868 } else {
869 $s = wfMsg( "error" );
871 return $s;
874 function protectThisPage()
876 global $wgUser, $wgOut, $wgTitle, $diff;
878 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
879 $n = $wgTitle->getPrefixedText();
881 if ( $wgTitle->isProtected() ) {
882 $t = wfMsg( "unprotectthispage" );
883 $q = "action=unprotect";
884 } else {
885 $t = wfMsg( "protectthispage" );
886 $q = "action=protect";
888 $s = $this->makeKnownLink( $n, $t, $q );
889 } else {
890 $s = wfMsg( "error" );
892 return $s;
895 function watchThisPage()
897 global $wgUser, $wgOut, $wgTitle, $diff;
899 if ( $wgOut->isArticle() && ( ! $diff ) ) {
900 $n = $wgTitle->getPrefixedText();
902 if ( $wgTitle->userIsWatching() ) {
903 $t = wfMsg( "unwatchthispage" );
904 $q = "action=unwatch";
905 } else {
906 $t = wfMsg( "watchthispage" );
907 $q = "action=watch";
909 $s = $this->makeKnownLink( $n, $t, $q );
910 } else {
911 $s = wfMsg( "notanarticle" );
913 return $s;
916 function moveThisPage()
918 global $wgTitle, $wgLang;
920 if ( $wgTitle->userCanEdit() ) {
921 $s = $this->makeKnownLink( $wgLang->specialPage( "Movepage" ),
922 wfMsg( "movethispage" ), "target=" . $wgTitle->getPrefixedURL() );
923 } // no message if page is protected - would be redundant
924 return $s;
927 function historyLink()
929 global $wgTitle;
931 $s = $this->makeKnownLink( $wgTitle->getPrefixedText(),
932 wfMsg( "history" ), "action=history" );
933 return $s;
936 function whatLinksHere()
938 global $wgTitle, $wgLang;
940 $s = $this->makeKnownLink( $wgLang->specialPage( "Whatlinkshere" ),
941 wfMsg( "whatlinkshere" ), "target=" . $wgTitle->getPrefixedURL() );
942 return $s;
945 function userContribsLink()
947 global $wgTitle, $wgLang;
949 $s = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
950 wfMsg( "contributions" ), "target=" . $wgTitle->getURL() );
951 return $s;
954 function emailUserLink()
956 global $wgTitle, $wgLang;
958 $s = $this->makeKnownLink( $wgLang->specialPage( "Emailuser" ),
959 wfMsg( "emailuser" ), "target=" . $wgTitle->getURL() );
960 return $s;
963 function watchPageLinksLink()
965 global $wgOut, $wgTitle, $wgLang;
967 if ( ! $wgOut->isArticle() ) {
968 $s = "(" . wfMsg( "notanarticle" ) . ")";
969 } else {
970 $s = $this->makeKnownLink( $wgLang->specialPage(
971 "Recentchangeslinked" ), wfMsg( "recentchangeslinked" ),
972 "target=" . $wgTitle->getPrefixedURL() );
974 return $s;
977 function otherLanguages()
979 global $wgOut, $wgLang, $wgTitle , $wgUseNewInterlanguage ;
981 $a = $wgOut->getLanguageLinks();
982 if ( 0 == count( $a ) ) {
983 if ( !$wgUseNewInterlanguage ) return "";
984 $ns = $wgLang->getNsIndex ( $wgTitle->getNamespace () ) ;
985 if ( $ns != 0 AND $ns != 1 ) return "" ;
986 $pn = "Intl" ;
987 $x = "mode=addlink&xt=".$wgTitle->getDBkey() ;
988 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
989 wfMsg( "intl" ) , $x );
992 if ( !$wgUseNewInterlanguage ) {
993 $s = wfMsg( "otherlanguages" ) . ": ";
994 } else {
995 global $wgLanguageCode ;
996 $x = "mode=zoom&xt=".$wgTitle->getDBkey() ;
997 $x .= "&xl=".$wgLanguageCode ;
998 $s = $this->makeKnownLink( $wgLang->specialPage( "Intl" ),
999 wfMsg( "otherlanguages" ) , $x ) . ": " ;
1002 $first = true;
1003 if($wgLang->isRTL()) $s .= "<span dir='LTR'>";
1004 foreach( $a as $l ) {
1005 if ( ! $first ) { $s .= " | "; }
1006 $first = false;
1008 $nt = Title::newFromText( $l );
1009 $url = $nt->getFullURL();
1010 $text = $wgLang->getLanguageName( $nt->getInterwiki() );
1012 if ( "" == $text ) { $text = $l; }
1013 $style = $this->getExternalLinkAttributes( $l, $text );
1014 $s .= "<a href=\"{$url}\"{$style}>{$text}</a>";
1016 if($wgLang->isRTL()) $s .= "</span>";
1017 return $s;
1020 function bugReportsLink()
1022 $s = $this->makeKnownLink( wfMsg( "bugreportspage" ),
1023 wfMsg( "bugreports" ) );
1024 return $s;
1027 function dateLink()
1029 global $wgLinkCache;
1030 $t1 = Title::newFromText( gmdate( "F j" ) );
1031 $t2 = Title::newFromText( gmdate( "Y" ) );
1033 $wgLinkCache->suspend();
1034 $id = $t1->getArticleID();
1035 $wgLinkCache->resume();
1037 if ( 0 == $id ) {
1038 $s = $this->makeBrokenLink( $t1->getText() );
1039 } else {
1040 $s = $this->makeKnownLink( $t1->getText() );
1042 $s .= ", ";
1044 $wgLinkCache->suspend();
1045 $id = $t2->getArticleID();
1046 $wgLinkCache->resume();
1048 if ( 0 == $id ) {
1049 $s .= $this->makeBrokenLink( $t2->getText() );
1050 } else {
1051 $s .= $this->makeKnownLink( $t2->getText() );
1053 return $s;
1056 function talkLink()
1058 global $wgLang, $wgTitle, $wgLinkCache;
1060 $tns = $wgTitle->getNamespace();
1061 if ( -1 == $tns ) { return ""; }
1063 $pn = $wgTitle->getText();
1064 $tp = wfMsg( "talkpage" );
1065 if ( Namespace::isTalk( $tns ) ) {
1066 $lns = Namespace::getSubject( $tns );
1067 switch($tns) {
1068 case 1:
1069 $text = wfMsg("articlepage");
1070 break;
1071 case 3:
1072 $text = wfMsg("userpage");
1073 break;
1074 case 5:
1075 $text = wfMsg("wikipediapage");
1076 break;
1077 case 7:
1078 $text = wfMsg("imagepage");
1079 break;
1080 default:
1081 $text= wfMsg("articlepage");
1083 } else {
1085 $lns = Namespace::getTalk( $tns );
1086 $text=$tp;
1088 $n = $wgLang->getNsText( $lns );
1089 if ( "" == $n ) { $link = $pn; }
1090 else { $link = "{$n}:{$pn}"; }
1092 $wgLinkCache->suspend();
1093 $s = $this->makeLink( $link, $text );
1094 $wgLinkCache->resume();
1096 return $s;
1099 # After all the page content is transformed into HTML, it makes
1100 # a final pass through here for things like table backgrounds.
1102 function transformContent( $text )
1104 return $text;
1107 # Note: This function MUST call getArticleID() on the link,
1108 # otherwise the cache won't get updated properly. See LINKCACHE.DOC.
1110 function makeLink( $title, $text= "", $query = "", $trail = "" )
1112 global $wgOut, $wgUser;
1114 $nt = Title::newFromText( $title );
1116 if ( $nt->isExternal() ) {
1117 $u = $nt->getFullURL();
1118 if ( "" == $text ) { $text = $nt->getPrefixedText(); }
1119 $style = $this->getExternalLinkAttributes( $link, $text );
1121 $inside = "";
1122 if ( "" != $trail ) {
1123 if ( preg_match( "/^([a-z]+)(.*)$$/sD", $trail, $m ) ) {
1124 $inside = $m[1];
1125 $trail = $m[2];
1128 return "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1130 if ( 0 == $nt->getNamespace() && "" == $nt->getText() ) {
1131 return $this->makeKnownLink( $title, $text, $query, $trail );
1133 if ( ( -1 == $nt->getNamespace() ) ||
1134 ( Namespace::getImage() == $nt->getNamespace() ) ) {
1135 return $this->makeKnownLink( $title, $text, $query, $trail );
1137 $aid = $nt->getArticleID() ;
1138 if ( 0 == $aid ) {
1139 return $this->makeBrokenLink( $title, $text, $query, $trail );
1140 } else {
1141 $threshold = $wgUser->getOption("stubthreshold") ;
1142 if ( $threshold > 0 ) {
1143 $res = wfQuery ( "SELECT HIGH_PRIORITY length(cur_text) AS x, cur_namespace, cur_is_redirect FROM cur WHERE cur_id='{$aid}'", DB_READ ) ;
1145 if ( wfNumRows( $res ) > 0 ) {
1146 $s = wfFetchObject( $res );
1147 $size = $s->x;
1148 if ( $s->cur_is_redirect OR $s->cur_namespace != 0 )
1149 $size = $threshold*2 ; # Really big
1150 wfFreeResult( $res );
1151 } else $size = $threshold*2 ; # Really big
1152 } else $size = 1 ;
1154 if ( $size < $threshold )
1155 return $this->makeStubLink( $title, $text, $query, $trail );
1156 return $this->makeKnownLink( $title, $text, $query, $trail );
1160 function makeKnownLink( $title, $text = "", $query = "", $trail = "" )
1162 global $wgOut, $wgTitle;
1164 $nt = Title::newFromText( $title );
1165 $link = $nt->getPrefixedURL();
1167 if ( "" == $link ) {
1168 $u = "";
1169 if ( "" == $text ) { $text = $nt->getFragment(); }
1170 } else {
1171 $u = wfLocalUrlE( $link, $query );
1173 if ( "" != $nt->getFragment() ) {
1174 $u .= "#" . wfEscapeHTML( $nt->getFragment() );
1176 if ( "" == $text ) { $text = $nt->getPrefixedText(); }
1177 $style = $this->getInternalLinkAttributes( $link, $text );
1179 $inside = "";
1180 if ( "" != $trail ) {
1181 if ( preg_match( wfMsg("linktrail"), $trail, $m ) ) {
1182 $inside = $m[1];
1183 $trail = $m[2];
1186 $r = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1187 return $r;
1190 function makeBrokenLink( $title, $text = "", $query = "", $trail = "" )
1192 global $wgOut, $wgUser;
1194 $nt = Title::newFromText( $title );
1195 $link = $nt->getPrefixedURL();
1197 if ( "" == $query ) { $q = "action=edit"; }
1198 else { $q = "action=edit&{$query}"; }
1199 $u = wfLocalUrlE( $link, $q );
1201 if ( "" == $text ) { $text = $nt->getPrefixedText(); }
1202 $style = $this->getInternalLinkAttributes( $link, $text, "yes" );
1204 $inside = "";
1205 if ( "" != $trail ) {
1206 if ( preg_match( wfMsg("linktrail"), $trail, $m ) ) {
1207 $inside = $m[1];
1208 $trail = $m[2];
1211 if ( $wgOut->isPrintable() ||
1212 ( 1 == $wgUser->getOption( "highlightbroken" ) ) ) {
1213 $s = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1214 } else {
1215 $s = "{$text}{$inside}<a href=\"{$u}\"{$style}>?</a>{$trail}";
1217 return $s;
1220 function makeStubLink( $title, $text = "", $query = "", $trail = "" )
1222 global $wgOut, $wgUser;
1224 $nt = Title::newFromText( $title );
1225 $link = $nt->getPrefixedURL();
1227 $u = wfLocalUrlE( $link, $query );
1229 if ( "" == $text ) { $text = $nt->getPrefixedText(); }
1230 $style = $this->getInternalLinkAttributes( $link, $text, "stub" );
1232 $inside = "";
1233 if ( "" != $trail ) {
1234 if ( preg_match( wfMsg("linktrail"), $trail, $m ) ) {
1235 $inside = $m[1];
1236 $trail = $m[2];
1239 if ( $wgOut->isPrintable() ||
1240 ( 1 == $wgUser->getOption( "highlightbroken" ) ) ) {
1241 $s = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1242 } else {
1243 $s = "{$text}{$inside}<a href=\"{$u}\"{$style}>!</a>{$trail}";
1245 return $s;
1248 function fnamePart( $url )
1250 $basename = strrchr( $url, "/" );
1251 if ( false === $basename ) { $basename = $url; }
1252 else { $basename = substr( $basename, 1 ); }
1253 return wfEscapeHTML( $basename );
1256 function makeImage( $url, $alt = "" )
1258 global $wgOut;
1260 if ( "" == $alt ) { $alt = $this->fnamePart( $url ); }
1261 $s = "<img src=\"{$url}\" alt=\"{$alt}\">";
1262 return $s;
1265 function makeImageLink( $name, $url, $alt = "" )
1267 global $wgOut, $wgTitle, $wgLang;
1269 $nt = Title::newFromText( $wgLang->getNsText(
1270 Namespace::getImage() ) . ":{$name}" );
1271 $link = $nt->getPrefixedURL();
1272 if ( "" == $alt ) { $alt = $name; }
1274 $u = wfLocalUrlE( $link );
1275 $s = "<a href=\"{$u}\" class='image' title=\"{$alt}\">" .
1276 "<img border=0 src=\"{$url}\" alt=\"{$alt}\"></a>";
1277 return $s;
1280 function makeMediaLink( $name, $url, $alt = "" )
1282 global $wgOut, $wgTitle;
1284 if ( "" == $alt ) { $alt = $name; }
1285 $u = wfEscapeHTML( $url );
1286 $s = "<a href=\"{$u}\" class='internal' title=\"{$alt}\">{$alt}</a>";
1287 return $s;
1290 function specialLink( $name, $key = "" )
1292 global $wgLang;
1294 if ( "" == $key ) { $key = strtolower( $name ); }
1295 $pn = $wgLang->ucfirst( $name );
1296 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1297 wfMsg( $key ) );
1300 # Called by history lists and recent changes
1303 function beginRecentChangesList()
1305 $rc_cache = array() ;
1306 $rccc = 0 ;
1307 $this->lastdate = "";
1308 return "";
1311 function beginHistoryList()
1313 $this->lastdate = $this->lastline = "";
1314 $s = "\n<p>" . wfMsg( "histlegend" ) . "\n<ul>";
1315 return $s;
1318 function beginImageHistoryList()
1320 $s = "\n<h2>" . wfMsg( "imghistory" ) . "</h2>\n" .
1321 "<p>" . wfMsg( "imghistlegend" ) . "\n<ul>";
1322 return $s;
1325 function endRecentChangesList()
1327 $s = $this->recentChangesBlock() ;
1328 $s .= "</ul>\n";
1329 return $s;
1332 function endHistoryList()
1334 $last = wfMsg( "last" );
1336 $s = preg_replace( "/!OLDID![0-9]+!/", $last, $this->lastline );
1337 $s .= "</ul>\n";
1338 return $s;
1341 function endImageHistoryList()
1343 $s = "</ul>\n";
1344 return $s;
1347 function historyLine( $ts, $u, $ut, $ns, $ttl, $oid, $c, $isminor )
1349 global $wgLang;
1351 $artname = Title::makeName( $ns, $ttl );
1352 $last = wfMsg( "last" );
1353 $cur = wfMsg( "cur" );
1354 $cr = wfMsg( "currentrev" );
1356 if ( $oid && $this->lastline ) {
1357 $ret = preg_replace( "/!OLDID!([0-9]+)!/", $this->makeKnownLink(
1358 $artname, $last, "diff=\\1&oldid={$oid}" ), $this->lastline );
1359 } else {
1360 $ret = "";
1362 $dt = $wgLang->timeanddate( $ts, true );
1364 if ( $oid ) { $q = "oldid={$oid}"; }
1365 else { $q = ""; }
1366 $link = $this->makeKnownLink( $artname, $dt, $q );
1368 if ( 0 == $u ) {
1369 $ul = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
1370 $ut, "target=" . $ut );
1371 } else { $ul = $this->makeLink( $wgLang->getNsText(
1372 Namespace::getUser() ) . ":{$ut}", $ut ); }
1374 $s = "<li>";
1375 if ( $oid ) {
1376 $curlink = $this->makeKnownLink( $artname, $cur,
1377 "diff=0&oldid={$oid}" );
1378 } else {
1379 $curlink = $cur;
1381 $s .= "({$curlink}) (!OLDID!{$oid}!) . .";
1383 $M = wfMsg( "minoreditletter" );
1384 if ( $isminor ) { $s .= " <strong>{$M}</strong>"; }
1385 $s .= " {$link} . . {$ul}";
1387 if ( "" != $c && "*" != $c ) { $s .= " <em>(" . wfEscapeHTML($c) . ")</em>"; }
1388 $s .= "</li>\n";
1390 $this->lastline = $s;
1391 return $ret;
1394 function recentChangesBlockLine ( $y ) {
1395 global $wgUploadPath ;
1397 $M = wfMsg( "minoreditletter" );
1398 $N = wfMsg( "newpageletter" );
1399 $r = "" ;
1400 $r .= "<img src='{$wgUploadPath}/Arr_.png' width=12 height=12 border=0>" ;
1401 $r .= "<tt>" ;
1402 if ( $y->isnew ) $r .= $N ;
1403 else $r .= "&nbsp;" ;
1404 if ( $y->isminor ) $r .= $M ;
1405 else $r .= "&nbsp;" ;
1406 $r .= " ".$y->timestamp." " ;
1407 $r .= "</tt>" ;
1408 $link = $y->link ;
1409 if ( $y->watched ) $link = "<strong>{$link}</strong>" ;
1410 $r .= $link ;
1412 $r .= " (" ;
1413 $r .= $y->curlink ;
1414 $r .= "; " ;
1415 $r .= $this->makeKnownLink( $y->secureName, wfMsg( "hist" ), "action=history" );
1417 $r .= ") . . ".$y->userlink ;
1418 $r .= $y->usertalklink ;
1419 if ( $y->usercomment != "" )
1420 $r .= " <em>(".wfEscapeHTML($y->usercomment).")</em>" ;
1421 $r .= "<br>\n" ;
1422 return $r ;
1425 function recentChangesBlockGroup ( $y ) {
1426 global $wgUploadPath ;
1428 $r = "" ;
1429 $M = wfMsg( "minoreditletter" );
1430 $N = wfMsg( "newpageletter" );
1431 $isnew = false ;
1432 $userlinks = array () ;
1433 foreach ( $y AS $x ) {
1434 $oldid = $x->diffid ;
1435 if ( $x->isnew ) $isnew = true ;
1436 $u = $x->userlink ;
1437 if ( !isset ( $userlinks[$u] ) ) $userlinks[$u] = 0 ;
1438 $userlinks[$u]++ ;
1441 krsort ( $userlinks ) ;
1442 asort ( $userlinks ) ;
1443 $users = array () ;
1444 $u = array_keys ( $userlinks ) ;
1445 foreach ( $u as $x ) {
1446 $z = $x ;
1447 if ( $userlinks[$x] > 1 ) $z .= " ({$userlinks[$x]}&times;)" ;
1448 array_push ( $users , $z ) ;
1450 $users = " <font size='-1'>[".implode("; ",$users)."]</font>" ;
1452 $e = $y ;
1453 $e = array_shift ( $e ) ;
1455 # Arrow
1456 $rci = "RCI{$this->rccc}" ;
1457 $rcl = "RCL{$this->rccc}" ;
1458 $rcm = "RCM{$this->rccc}" ;
1459 $tl = "<a href='javascript:toggleVisibility(\"{$rci}\",\"{$rcm}\",\"{$rcl}\")'>" ;
1460 $tl .= "<span id='{$rcm}'><img src='{$wgUploadPath}/Arr_r.png' width=12 height=12 border=0></span>" ;
1461 $tl .= "<span id='{$rcl}' style='display:none'><img src='{$wgUploadPath}/Arr_d.png' width=12 height=12 border=0></span>" ;
1462 $tl .= "</a>" ;
1463 $r .= $tl ;
1465 # Main line
1466 $r .= "<tt>" ;
1467 if ( $isnew ) $r .= $N ;
1468 else $r .= "&nbsp;" ;
1469 $r .= "&nbsp;" ; # Minor
1470 $r .= " ".$e->timestamp." " ;
1471 $r .= "</tt>" ;
1473 $link = $e->link ;
1474 if ( $e->watched ) $link = "<strong>{$link}</strong>" ;
1475 $r .= $link ;
1477 if ( !$e->islog ) {
1478 $r .= " (".count($y)." " ;
1479 if ( $isnew ) $r .= wfMsg("changes");
1480 else $r .= $this->makeKnownLink( $e->secureName , wfMsg("changes") , "diff=0&oldid=".$oldid ) ;
1481 $r .= "; " ;
1482 $r .= $this->makeKnownLink( $e->secureName, wfMsg( "history" ), "action=history" );
1483 $r .= ")" ;
1486 $r .= $users ;
1487 $r .= "<br>\n" ;
1489 # Sub-entries
1490 $r .= "<div id='{$rci}' style='display:none'>" ;
1491 foreach ( $y AS $x )
1493 $r .= "<img src='{$wgUploadPath}/Arr_.png' width=12 height=12 border=0>";
1494 $r .= "<tt>&nbsp; &nbsp; &nbsp; &nbsp;" ;
1495 if ( $x->isnew ) $r .= $N ;
1496 else $r .= "&nbsp;" ;
1497 if ( $x->isminor ) $r .= $M ;
1498 else $r .= "&nbsp;" ;
1499 $r .= "</tt>" ;
1501 $o = "" ;
1502 if ( $x->oldid != 0 ) $o = "oldid=".$x->oldid ;
1503 if ( $x->islog ) $link = $x->timestamp ;
1504 else $link = $this->makeKnownLink( $x->secureName, $x->timestamp , $o ) ;
1505 $link = "<tt>{$link}</tt>" ;
1508 $r .= $link ;
1509 $r .= " (" ;
1510 $r .= $x->curlink ;
1511 $r .= "; " ;
1512 $r .= $x->lastlink ;
1513 $r .= ") . . ".$x->userlink ;
1514 $r .= $x->usertalklink ;
1515 if ( $x->usercomment != "" )
1516 $r .= " <em>(".wfEscapeHTML($x->usercomment).")</em>" ;
1517 $r .= "<br>\n" ;
1519 $r .= "</div>\n" ;
1521 $this->rccc++ ;
1522 return $r ;
1525 function recentChangesBlock ()
1527 global $wgUploadPath ;
1528 if ( count ( $this->rc_cache ) == 0 ) return "" ;
1529 $k = array_keys ( $this->rc_cache ) ;
1530 foreach ( $k AS $x )
1532 $y = $this->rc_cache[$x] ;
1533 if ( count ( $y ) < 2 ) {
1534 $r .= $this->recentChangesBlockLine ( array_shift ( $y ) ) ;
1535 } else {
1536 $r .= $this->recentChangesBlockGroup ( $y ) ;
1540 return "<div align=left>{$r}</div>" ;
1543 function recentChangesLine( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched = false, $oldid = 0 , $diffid = 0 )
1545 global $wgUser ;
1546 $usenew = $wgUser->getOption( "usenewrc" );
1547 if ( $usenew )
1548 $r = $this->recentChangesLineNew ( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched , $oldid , $diffid ) ;
1549 else
1550 $r = $this->recentChangesLineOld ( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched , $oldid , $diffid ) ;
1551 return $r ;
1554 function recentChangesLineOld( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched = false, $oldid = 0, $diffid = 0 )
1556 global $wgTitle, $wgLang, $wgUser;
1558 $d = $wgLang->date( $ts, true);
1559 $s = "";
1560 if ( $d != $this->lastdate ) {
1561 if ( "" != $this->lastdate ) { $s .= "</ul>\n"; }
1562 $s .= "<h4>{$d}</h4>\n<ul>";
1563 $this->lastdate = $d;
1565 $h = $wgLang->time( $ts, true );
1566 $t = Title::makeName( $ns, $ttl );
1567 $clink = $this->makeKnownLink( $t , "" );
1568 $nt = Title::newFromText( $t );
1570 if ( $watched ) {
1571 $clink = "<strong>{$clink}</strong>";
1573 $hlink = $this->makeKnownLink( $t, wfMsg( "hist" ), "action=history" );
1574 if ( $isnew || $nt->isLog() ) {
1575 $dlink = wfMsg( "diff" );
1576 } else {
1577 $dlink = $this->makeKnownLink( $t, wfMsg( "diff" ),
1578 "diff={$oldid}&oldid={$diffid}" ); # Finagle's law
1580 if ( 0 == $u ) {
1581 $ul = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
1582 $ut, "target=" . $ut );
1583 } else { $ul = $this->makeLink( $wgLang->getNsText(
1584 Namespace::getUser() ) . ":{$ut}", $ut ); }
1586 $utns=$wgLang->getNsText(Namespace::getTalk(Namespace::getUser()));
1587 $talkname=$wgLang->getNsText(Namespace::getTalk(0)); # use the shorter name
1588 $utl= $this->makeLink($utns . ":{$ut}", $talkname );
1589 $cr = wfMsg( "currentrev" );
1591 $s .= "<li> ({$dlink}) ({$hlink}) . .";
1592 $M = wfMsg( "minoreditletter" );
1593 $N = wfMsg( "newpageletter" );
1594 if ( $isminor ) { $s .= " <strong>{$M}</strong>"; }
1595 if ( $isnew ) { $s .= "<strong>{$N}</strong>"; }
1596 $s .= " {$clink}; {$h} . . {$ul}";
1598 $blink="";
1599 if ( ( 0 == $u ) && $wgUser->isSysop() ) {
1600 $blink = $this->makeKnownLink( $wgLang->specialPage(
1601 "Blockip" ), wfMsg( "blocklink" ), "ip={$ut}" );
1604 if(!$blink) {
1605 $utl = "({$utl})";
1606 } else {
1607 $utl = "({$utl} | {$blink})";
1609 $s.=" {$utl}";
1611 if ( "" != $c && "*" != $c ) {
1612 $s .= " <em>(" . wfEscapeHTML( $c ) . ")</em>";
1614 $s .= "</li>\n";
1616 return $s;
1619 function recentChangesLineNew( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched = false, $oldid = 0 , $diffid = 0 )
1621 global $wgTitle, $wgLang, $wgUser;
1623 $rc = new RecentChangesClass ;
1625 $d = $wgLang->date( $ts, true);
1626 $s = "";
1627 $ret = "" ;
1628 if ( $d != $this->lastdate ) {
1629 $ret = $this->recentChangesBlock () ;
1630 $this->rc_cache = array() ;
1631 $ret .= "<h4>{$d}</h4>\n";
1632 $this->lastdate = $d;
1634 $h = $wgLang->time( $ts, true );
1635 $t = Title::makeName( $ns, $ttl );
1636 $clink = $this->makeKnownLink( $t, "" ) ;
1637 if ( $oldid == 0 ) $c2link = $clink ;
1638 else $c2link = $this->makeKnownLink( $t, "" , "oldid={$oldid}" );
1639 $nt = Title::newFromText( $t );
1641 $rc->timestamp = $h ;
1642 $rc->oldid = $oldid ;
1643 $rc->diffid = $diffid ;
1644 $rc->watched = $watched ;
1645 $rc->isnew = $isnew ;
1646 $rc->isminor = $isminor ;
1647 $rc->secureName = $t ;
1648 $rc->displayName = $nt ;
1649 $rc->link = $clink ;
1650 $rc->usercomment = $c ;
1651 $rc->islog = $nt->isLog() ;
1653 if ( ( $isnew && $oldid == 0 ) || $nt->isLog() ) {
1654 $dlink = wfMsg( "cur" );
1655 } else {
1656 $dlink = $this->makeKnownLink( $t, wfMsg( "cur" ),
1657 "diff=0&oldid={$oldid}" );
1660 if ( $diffid == 0 || $nt->isLog() ) {
1661 $plink = wfMsg( "last" );
1662 } else {
1663 $plink = $this->makeKnownLink( $t, wfMsg( "last" ),
1664 "diff={$oldid}&oldid={$diffid}" );
1667 if ( 0 == $u ) {
1668 $ul = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
1669 $ut, "target=" . $ut );
1670 } else { $ul = $this->makeLink( $wgLang->getNsText(
1671 Namespace::getUser() ) . ":{$ut}", $ut ); }
1673 $rc->userlink = $ul ;
1674 $rc->lastlink = $plink ;
1675 $rc->curlink = $dlink ;
1677 $utns=$wgLang->getNsText(Namespace::getTalk(Namespace::getUser()));
1678 $talkname=$wgLang->getNsText(Namespace::getTalk(0)); # use the shorter name
1679 $utl= $this->makeLink($utns . ":{$ut}", $talkname );
1681 if ( ( 0 == $u ) && $wgUser->isSysop() ) {
1682 $blink = $this->makeKnownLink( $wgLang->specialPage(
1683 "Blockip" ), wfMsg( "blocklink" ), "ip={$ut}" );
1684 $rc->usertalklink= " ({$utl} | {$blink})";
1685 } else {
1686 $rc->usertalklink=" ({$utl})";
1689 if ( !isset ( $this->rc_cache[$t] ) ) $this->rc_cache[$t] = array() ;
1690 array_push ( $this->rc_cache[$t] , $rc ) ;
1691 return $ret;
1695 function imageHistoryLine( $iscur, $ts, $img, $u, $ut, $size, $c )
1697 global $wgUser, $wgLang, $wgTitle;
1699 $dt = $wgLang->timeanddate( $ts, true );
1700 $del = wfMsg( "deleteimg" );
1701 $cur = wfMsg( "cur" );
1703 if ( $iscur ) {
1704 $url = wfImageUrl( $img );
1705 $rlink = $cur;
1706 if ( $wgUser->isSysop() ) {
1707 $link = wfLocalUrlE( $wgTitle->getPrefixedText(), "image=" . $wgTitle->getURL() .
1708 "&action=delete" );
1709 $style = $this->getInternalLinkAttributes( $link, $del );
1711 $dlink = "<a href=\"{$link}\"{$style}>{$del}</a>";
1712 } else {
1713 $dlink = $del;
1715 } else {
1716 $url = wfEscapeHTML( wfImageArchiveUrl( $img ) );
1717 if( $wgUser->getID() != 0 ) {
1718 $rlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
1719 wfMsg( "revertimg" ), "action=revert&oldimage=" .
1720 urlencode( $img ) );
1721 $dlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
1722 $del, "action=delete&oldimage=" . urlencode( $img ) );
1723 } else {
1724 # Having live active links for non-logged in users
1725 # means that bots and spiders crawling our site can
1726 # inadvertently change content. Baaaad idea.
1727 $rlink = wfMsg( "revertimg" );
1728 $dlink = $del;
1731 if ( 0 == $u ) { $ul = $ut; }
1732 else { $ul = $this->makeLink( $wgLang->getNsText(
1733 Namespace::getUser() ) . ":{$ut}", $ut ); }
1735 $nb = str_replace( "$1", $size, wfMsg( "nbytes" ) );
1736 $style = $this->getInternalLinkAttributes( $url, $dt );
1738 $s = "<li> ({$dlink}) ({$rlink}) <a href=\"{$url}\"{$style}>{$dt}</a>"
1739 . " . . {$ul} ({$nb})";
1741 if ( "" != $c && "*" != $c ) {
1742 $s .= " <em>(" . wfEscapeHTML( $c ) . ")</em>";
1744 $s .= "</li>\n";
1745 return $s;
1748 function tocIndent($level) {
1750 while($level-->0) $rv.="<div style=\"margin-left:2em;\">\n";
1751 return $rv;
1755 function tocUnindent($level) {
1756 while($level-->0) $rv.="</div>\n";
1757 return $rv;
1760 // parameter level defines if we are on an indentation level
1761 function tocLine($anchor,$tocline,$level) {
1763 if($level) {
1765 return "<A CLASS=\"internal\" HREF=\"#".$anchor."\">".$tocline."</A><BR>\n";
1766 } else {
1768 return "<div style=\"margin-bottom:0px;\">\n".
1769 "<A CLASS=\"internal\" HREF=\"#".$anchor."\">".$tocline."</A><BR>\n".
1770 "</div>\n";
1775 function tocTable($toc) {
1776 // note to CSS fanatics: putting this in a div does not work -- div won't auto-expand
1777 global $printable;
1779 if (!$printable) {
1780 $hideline = " <script type='text/javascript'>showTocToggle(\"" . wfMsg("showtoc") . "\",\"" . wfMsg("hidetoc") . "\")</script>";
1782 return
1783 "<p><table border=\"0\" id=\"toc\"><tr><td align=\"center\">\n".
1784 "<b>".wfMsg("toc")."</b>" .
1785 $hideline .
1786 "</td></tr><tr id='tocinside'><td align=\"left\">\n".
1787 $toc."</td></tr></table><P>\n";
1790 # These two do not check for permissions: check $wgTitle->userCanEdit before calling them
1791 function editSectionScript($section,$head) {
1793 global $wgTitle,$wgUser,$oldid;
1794 if($oldid) return $head;
1795 $url = wfLocalUrlE(urlencode($wgTitle->getPrefixedText()),"action=edit&section=$section");
1796 return "<span onContextMenu='document.location=\"".$url."\";return false;'>{$head}</span>";
1799 function editSectionLink($section) {
1801 global $printable;
1802 global $wgTitle,$wgUser,$oldid;
1803 if($oldid) return "";
1804 if ($printable) return "";
1805 $editurl="&section={$section}";
1806 $url=$this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg("editsection"),"action=edit".$editurl);
1807 return "<div style=\"float:right;margin-left:5px;\"><small>[".$url."]</small></div>";
1812 include_once( "SkinStandard.php" );
1813 include_once( "SkinNostalgia.php" );
1814 include_once( "SkinCologneBlue.php" );
1816 #include_once( "SkinSmarty.php" );