Move page not just for sysops in bottomLinks()
[mediawiki.git] / includes / Skin.php
blobc1e51d5b6017630010af4c6e8e3df3bdc02b0cd6
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"
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 getHeadScripts() {
83 global $wgStyleSheetPath;
84 $r = "<script type=\"text/javascript\" src=\"{$wgStyleSheetPath}/wikibits.js\"></script>\n";
85 return $r;
88 function getUserStyles()
90 $s = "<style type='text/css' media='screen'><!--\n";
91 $s .= $this->doGetUserStyles();
92 $s .= "//--></style>\n";
93 return $s;
96 function doGetUserStyles()
98 global $wgUser;
100 $s = "";
101 if ( 1 == $wgUser->getOption( "underline" ) ) {
102 # Don't override browser settings
103 } else {
104 # Force no underline
105 $s .= "a.stub, a.new, a.internal, a.external { " .
106 "text-decoration: none; }\n";
108 if ( 1 == $wgUser->getOption( "highlightbroken" ) ) {
109 $s .= "a.new, #quickbar a.new { color: #CC2200; }\n";
111 if ( 1 == $wgUser->getOption( "justify" ) ) {
112 $s .= "#article { text-align: justify; }\n";
114 return $s;
117 function getBodyOptions()
119 global $wgUser, $wgTitle, $wgNamespaceBackgrounds, $wgOut, $oldid, $redirect, $diff,$action;
121 if ( 0 != $wgTitle->getNamespace() ) {
122 $a = array( "bgcolor" => "#f7f7ff" );
124 else $a = array( "bgcolor" => "#FFFFFF" );
125 if($wgOut->isArticle() && $wgUser->getOption("editondblclick")
127 (!$wgTitle->isProtected() || $wgUser->isSysop())
130 $n = $wgTitle->getPrefixedURL();
131 $t = wfMsg( "editthispage" );
132 $oid = $red = "";
133 if ( $redirect ) { $red = "&redirect={$redirect}"; }
134 if ( $oldid && ! isset( $diff ) ) {
135 $oid = "&oldid={$oldid}";
137 $s = wfLocalUrlE($n,"action=edit{$oid}{$red}");
138 $s = "document.location = \"" .$s ."\";";
139 $a += array ("ondblclick" => $s);
142 if($action=="edit") { # set focus in edit box
143 $foc = "document.editform.wpTextbox1.focus()";
144 if($a['onload']) {
145 $a['onload'] .= ";$foc";
146 } else {
147 $a['onload'] = $foc;
150 return $a;
153 function getExternalLinkAttributes( $link, $text )
155 global $wgUser, $wgOut, $wgLang;
157 $link = urldecode( $link );
158 $link = $wgLang->checkTitleEncoding( $link );
159 $link = str_replace( "_", " ", $link );
160 $link = wfEscapeHTML( $link );
162 if ( $wgOut->isPrintable() ) { $r = " class='printable'"; }
163 else { $r = " class='external'"; }
165 if ( 1 == $wgUser->getOption( "hover" ) ) {
166 $r .= " title=\"{$link}\"";
168 return $r;
171 function getInternalLinkAttributes( $link, $text, $broken = false )
173 global $wgUser, $wgOut;
175 $link = urldecode( $link );
176 $link = str_replace( "_", " ", $link );
177 $link = wfEscapeHTML( $link );
179 if ( $wgOut->isPrintable() ) { $r = " class='printable'"; }
180 else if ( $broken == "stub" ) { $r = " class='stub'"; }
181 else if ( $broken == "yes" ) { $r = " class='new'"; }
182 else { $r = " class='internal'"; }
184 if ( 1 == $wgUser->getOption( "hover" ) ) {
185 $r .= " title=\"{$link}\"";
187 return $r;
190 function getLogo()
192 global $wgLogo;
193 return $wgLogo;
196 # This will be called immediately after the <body> tag. Split into
197 # two functions to make it easier to subclass.
199 function beforeContent()
201 global $wgUser, $wgOut;
203 if ( $wgOut->isPrintable() ) {
204 $s = $this->pageTitle() . $this->pageSubtitle() . "\n";
205 $s .= "\n<div class='bodytext'>";
206 return $s;
208 return $this->doBeforeContent();
211 function doBeforeContent()
213 global $wgUser, $wgOut, $wgTitle, $wgLang;
214 wfProfileIn( "Skin::doBeforeContent" );
216 $s = "";
217 $qb = $this->qbSetting();
219 if( $langlinks = $this->otherLanguages() ) {
220 $rows = 2;
221 $borderhack = "";
222 } else {
223 $rows = 1;
224 $langlinks = false;
225 $borderhack = "class='top'";
228 $s .= "\n<div id='content'>\n<div id='topbar'>" .
229 "<table width='98%' border=0 cellspacing=0><tr>";
231 $shove = ($qb != 0);
232 $left = ($qb == 1 || $qb == 3);
233 if($wgLang->isRTL()) $left = !$left;
235 if ( !$shove ) {
236 $s .= "<td class='top' align=left valign=top rowspan='{$rows}'>" .
237 $this->logoText() . "</td>";
238 } elseif( $left ) {
239 $s .= $this->getQuickbarCompensator( $rows );
241 $l = $wgLang->isRTL() ? "right" : "left";
242 $s .= "<td {$borderhack} align='$l' valign='top'>";
244 $s .= $this->topLinks() ;
245 $s .= "<p class='subtitle'>" . $this->pageTitleLinks();
247 $r = $wgLang->isRTL() ? "left" : "right";
248 $s .= "</td>\n<td {$borderhack} valign='top' align='$r' nowrap>";
249 $s .= $this->nameAndLogin();
250 $s .= "\n<br>" . $this->searchForm() . "</td>";
252 if ( $langlinks ) {
253 $s .= "</tr>\n<tr><td class='top' colspan=\"2\">$langlinks</td>";
256 if ( $shove && !$left ) { # Right
257 $s .= $this->getQuickbarCompensator( $rows );
259 $s .= "</tr></table>\n</div>\n";
260 $s .= "\n<div id='article'>";
262 $s .= $this->pageTitle();
263 $s .= $this->pageSubtitle() ;
264 $s .= getCategories(); // For some odd reason, zhis can't be a function of the object
265 $s .= "\n<p>";
266 wfProfileOut();
267 return $s;
270 function getQuickbarCompensator( $rows = 1 )
272 return "<td width='152' rowspan='{$rows}'>&nbsp;</td>";
275 # This gets called immediately before the </body> tag.
277 function afterContent()
279 global $wgUser, $wgOut, $wgServer, $HTTP_SERVER_VARS;
281 if ( $wgOut->isPrintable() ) {
282 $s = "\n</div>\n";
284 $u = $wgServer . $HTTP_SERVER_VARS['REQUEST_URI'];
285 $u = preg_replace( "/[?&]printable=yes/", "", $u );
286 $rf = str_replace( "$1", $u, wfMsg( "retrievedfrom" ) );
288 if ( $wgOut->isArticle() ) {
289 $lm = "<br>" . $this->lastModified();
290 } else { $lm = ""; }
292 $s .= "<p><em>{$rf}{$lm}</em>\n";
293 return $s;
295 return $this->doAfterContent();
298 function doAfterContent()
300 global $wgUser, $wgOut, $wgLang;
301 wfProfileIn( "Skin::doAfterContent" );
303 $s = "\n</div><br clear=all>\n";
305 $s .= "\n<div id='footer'>";
306 $s .= "<table width='98%' border=0 cellspacing=0><tr>";
308 $qb = $this->qbSetting();
309 $shove = ($qb != 0);
310 $left = ($qb == 1 || $qb == 3);
311 if($wgLang->isRTL()) $left = !$left;
313 if ( $shove && $left ) { # Left
314 $s .= $this->getQuickbarCompensator();
316 $l = $wgLang->isRTL() ? "right" : "left";
317 $s .= "<td class='bottom' align='$l' valign='top'>";
319 $s .= $this->bottomLinks();
320 $s .= "\n<br>" . $this->mainPageLink()
321 . " | " . $this->aboutLink()
322 . " | " . $this->specialLink( "recentchanges" )
323 . " | " . $this->searchForm()
324 . "<br>" . $this->pageStats();
326 $s .= "</td>";
327 if ( $shove && !$left ) { # Right
328 $s .= $this->getQuickbarCompensator();
330 $s .= "</tr></table>\n</div>\n</div>\n";
332 if ( 0 != $qb ) { $s .= $this->quickBar(); }
333 wfProfileOut();
334 return $s;
337 function pageTitleLinks()
339 global $wgOut, $wgTitle, $oldid, $action, $diff, $wgUser, $wgLang;
341 $s = $this->printableLink();
343 if ( $wgOut->isArticle() ) {
344 if ( $wgTitle->getNamespace() == Namespace::getImage() ) {
345 $name = $wgTitle->getDBkey();
346 $link = wfEscapeHTML( wfImageUrl( $name ) );
347 $style = $this->getInternalLinkAttributes( $link, $name );
348 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>";
351 if ( "history" == $action || isset( $diff ) || isset( $oldid ) ) {
352 $s .= " | " . $this->makeKnownLink( $wgTitle->getPrefixedText(),
353 wfMsg( "currentrev" ) );
356 if ( $wgUser->getNewtalk() ) {
357 # do not show "You have new messages" text when we are viewing our
358 # own talk page
360 if(!(strcmp($wgTitle->getText(),$wgUser->getName()) == 0 &&
361 $wgTitle->getNamespace()==Namespace::getTalk(Namespace::getUser()))) {
362 $n =$wgUser->getName();
363 $tl = $this->makeKnownLink( $wgLang->getNsText(
364 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
365 wfMsg("newmessageslink") );
366 $s.=" | <strong>". str_replace( "$1", $tl, wfMsg("newmessages") ) . "</strong>";
369 return $s;
372 function printableLink()
374 global $wgOut, $wgTitle, $oldid, $action;
376 if ( "history" == $action ) { $q = "action=history&"; }
377 else { $q = ""; }
379 $s = $this->makeKnownLink( $wgTitle->getPrefixedText(),
380 WfMsg( "printableversion" ), "{$q}printable=yes" );
381 return $s;
384 function pageTitle()
386 global $wgOut, $wgTitle;
388 $s = "<h1 class='pagetitle'>" . $wgOut->getPageTitle() . "</h1>";
389 return $s;
392 function pageSubtitle()
394 global $wgOut,$wgTitle,$wgNamespacesWithSubpages;
396 $sub = $wgOut->getSubtitle();
397 if ( "" == $sub ) { $sub = wfMsg( "fromwikipedia" ); }
398 if($wgOut->isArticle() && $wgNamespacesWithSubpages[$wgTitle->getNamespace()]) {
399 $ptext=$wgTitle->getPrefixedText();
400 if(preg_match("/\//",$ptext)) {
401 $sub.="</p><p class='subpages'>";
402 $links=explode("/",$ptext);
403 $c=0;
404 $growinglink="";
405 foreach($links as $link) {
406 $c++;
407 if ($c<count($links)) {
408 $growinglink.=$link;
409 $getlink=$this->makeLink($growinglink,$link);
410 if(preg_match("/class='new'/i",$getlink)) { break; } # this is a hack, but it saves time
411 if ($c>1) {
412 $sub .= " | ";
413 } else {
414 $sub .="&lt; ";
416 $sub .= $getlink;
417 $growinglink.="/";
423 $s = "<p class='subtitle'>{$sub}\n";
424 return $s;
427 function nameAndLogin()
429 global $wgUser, $wgTitle, $wgLang, $wgShowIPinHeader;
431 $li = $wgLang->specialPage( "Userlogin" );
432 $lo = $wgLang->specialPage( "Userlogout" );
434 $s = "";
435 if ( 0 == $wgUser->getID() ) {
436 if( $wgShowIPinHeader ) {
437 $n = getenv( "REMOTE_ADDR" );
439 $tl = $this->makeKnownLink( $wgLang->getNsText(
440 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
441 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
443 $s .= $n . " (".$tl.")";
444 } else {
445 $s .= wfMsg("notloggedin");
448 $rt = $wgTitle->getPrefixedURL();
449 if ( 0 == strcasecmp( urlencode( $lo ), $rt ) ) {
450 $q = "";
451 } else { $q = "returnto={$rt}"; }
453 $s .= "\n<br>" . $this->makeKnownLink( $li,
454 wfMsg( "login" ), $q );
455 } else {
456 $n = $wgUser->getName();
457 $rt = $wgTitle->getPrefixedURL();
458 $tl = $this->makeKnownLink( $wgLang->getNsText(
459 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
460 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
462 $tl = " ({$tl})";
464 $s .= $this->makeKnownLink( $wgLang->getNsText(
465 Namespace::getUser() ) . ":{$n}", $n ) . "{$tl}<br>" .
466 $this->makeKnownLink( $lo, wfMsg( "logout" ),
467 "returnto={$rt}" ) . " | " .
468 $this->specialLink( "preferences" );
470 $s .= " | " . $this->makeKnownLink( wfMsg( "helppage" ),
471 wfMsg( "help" ) );
473 return $s;
476 function searchForm()
478 global $search;
480 $s = "<form name='search' class='inline' method=get action=\""
481 . wfLocalUrl( "" ) . "\">"
482 . "<input type=text name=\"search\" size=19 value=\""
483 . htmlspecialchars(substr($search,0,256)) . "\">\n"
484 . "<input type=submit name=\"go\" value=\"" . wfMsg ("go") . "\">&nbsp;"
485 . "<input type=submit value=\"" . wfMsg ("search") . "\"></form>";
487 return $s;
490 function topLinks()
492 global $wgOut;
493 $sep = " |\n";
495 $s = $this->mainPageLink() . $sep
496 . $this->specialLink( "recentchanges" );
498 if ( $wgOut->isArticle() ) {
499 $s .= $sep . $this->editThisPage()
500 . $sep . $this->historyLink();
502 # Many people don't like this dropdown box
503 #$s .= $sep . $this->specialPagesList();
505 return $s;
508 function bottomLinks()
510 global $wgOut, $wgUser, $wgTitle;
511 $sep = " |\n";
513 $s = "";
514 if ( $wgOut->isArticle() ) {
515 $s .= "<strong>" . $this->editThisPage() . "</strong>";
516 if ( 0 != $wgUser->getID() ) {
517 $s .= $sep . $this->watchThisPage() .
518 $sep . $this->moveThisPage();
520 $s .= $sep . $this->talkLink()
521 . $sep . $this->historyLink()
522 . $sep . $this->whatLinksHere()
523 . $sep . $this->watchPageLinksLink();
525 if ( $wgTitle->getNamespace() == Namespace::getUser()
526 || $wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser()) )
529 $id=User::idFromName($wgTitle->getText());
530 $ip=User::isIP($wgTitle->getText());
532 if($id || $ip) { # both anons and non-anons have contri list
533 $s .= $sep . $this->userContribsLink();
535 if ( 0 != $wgUser->getID() ) { # show only to signed in users
536 if($id) { # can only email non-anons
537 $s .= $sep . $this->emailUserLink();
541 if ( $wgUser->isSysop() && $wgTitle->getArticleId() ) {
542 $s .= "\n<br>" . $this->deleteThisPage() .
543 $sep . $this->protectThisPage();
545 $s .= "<br>\n" . $this->otherLanguages();
547 return $s;
550 function pageStats()
552 global $wgOut, $wgLang, $wgArticle;
553 global $oldid, $diff, $wgDisableCounters;
555 if ( ! $wgOut->isArticle() ) { return ""; }
556 if ( isset( $oldid ) || isset( $diff ) ) { return ""; }
557 if ( 0 == $wgArticle->getID() ) { return ""; }
559 if ( $wgDisableCounters ) {
560 $s = "";
561 } else {
562 $count = $wgArticle->getCount();
563 $s = str_replace( "$1", $count, wfMsg( "viewcount" ) );
565 $s .= $this->lastModified();
566 $s .= " " . wfMsg( "gnunote" );
567 return "<span id='pagestats'>{$s}</span>";
570 function lastModified()
572 global $wgLang, $wgArticle;
574 $d = $wgLang->timeanddate( $wgArticle->getTimestamp(), true );
575 $s = " " . str_replace( "$1", $d, wfMsg( "lastmodified" ) );
576 return $s;
579 function logoText( $align = "" )
581 if ( "" != $align ) { $a = " align='{$align}'"; }
582 else { $a = ""; }
584 $mp = wfMsg( "mainpage" );
585 $s = "<a href=\"" . wfLocalUrlE( $mp ) . "\"><img{$a} border=0 src=\""
586 . $this->getLogo() . "\" alt=\"" . "[{$mp}]\"></a>";
587 return $s;
590 function quickBar()
592 global $wgOut, $wgTitle, $wgUser, $action, $wgLang;
593 global $wpPreview;
594 wfProfileIn( "Skin::quickBar" );
595 $tns=$wgTitle->getNamespace();
597 $s = "\n<div id='quickbar'>";
598 $s .= "\n" . $this->logoText() . "\n<hr class='sep'>";
600 $sep = "\n<br>";
601 $s .= $this->mainPageLink()
602 . $sep . $this->specialLink( "recentchanges" )
603 . $sep . $this->specialLink( "randompage" );
604 if ($wgUser->getID()) {
605 $s.= $sep . $this->specialLink( "watchlist" ) ;
606 $s .= $sep .$this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
607 wfMsg( "mycontris" ), "target=" . wfUrlencode($wgUser->getName() ) );
610 // only show watchlist link if logged in
611 if ( wfMsg ( "currentevents" ) != "-" ) $s .= $sep . $this->makeKnownLink( wfMsg( "currentevents" ), "" ) ;
612 $s .= "\n<br><hr class='sep'>";
613 $articleExists = $wgTitle->getArticleId();
614 if ( $wgOut->isArticle() || $action =="edit" || $action =="history" || $wpPreview) {
616 if($wgOut->isArticle()) {
617 $s .= "<strong>" . $this->editThisPage() . "</strong>";
618 } else { # backlink to the article in edit or history mode
619 if($articleExists){ # no backlink if no article
620 switch($tns) {
621 case 0:
622 $text = wfMsg("articlepage");
623 break;
624 case 1:
625 $text = wfMsg("viewtalkpage");
626 break;
627 case 2:
628 $text = wfMsg("userpage");
629 break;
630 case 3:
631 $text = wfMsg("viewtalkpage");
632 break;
633 case 4:
634 $text = wfMsg("wikipediapage");
635 break;
636 case 5:
637 $text = wfMsg("viewtalkpage");
638 break;
639 case 6:
640 $text = wfMsg("imagepage");
641 break;
642 case 7:
643 $text = wfMsg("viewtalkpage");
644 break;
645 default:
646 $text= wfMsg("articlepage");
649 $link = $wgTitle->getText();
650 if ($nstext = $wgLang->getNsText($tns) ) { # add namespace if necessary
651 $link = $nstext . ":" . $link ;
653 $s .= $this->makeLink($link, $text );
654 } elseif( $wgTitle->getNamespace() != Namespace::getSpecial() ) {
655 # we just throw in a "New page" text to tell the user that he's in edit mode,
656 # and to avoid messing with the separator that is prepended to the next item
657 $s .= "<strong>" . wfMsg("newpage") . "</strong>";
663 if( $tns%2 && $action!="edit" && !$wpPreview) {
664 $s.="<br>".$this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg("postcomment"),"action=edit&section=new");
668 watching could cause problems in edit mode:
669 if user edits article, then loads "watch this article" in background and then saves
670 article with "Watch this article" checkbox disabled, the article is transparently
671 unwatched. Therefore we do not show the "Watch this page" link in edit mode
673 if ( 0 != $wgUser->getID() && $articleExists) {
674 if($action!="edit" && $action!="history" &&
675 $action != "submit" )
676 {$s .= $sep . $this->watchThisPage(); }
677 if ( $wgTitle->userCanEdit() ) $s .= $sep . $this->moveThisPage();
679 if ( $wgUser->isSysop() and $articleExists ) {
680 $s .= $sep . $this->deleteThisPage() .
681 $sep . $this->protectThisPage();
683 $s .= $sep . $this->talkLink();
684 if ($articleExists && $action !="history") { $s .= $sep . $this->historyLink();}
685 $s.=$sep . $this->whatLinksHere();
687 if($wgOut->isArticle()) {
688 $s .= $sep . $this->watchPageLinksLink();
691 if ( Namespace::getUser() == $wgTitle->getNamespace()
692 || $wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser())
695 $id=User::idFromName($wgTitle->getText());
696 $ip=User::isIP($wgTitle->getText());
698 if($id||$ip) {
699 $s .= $sep . $this->userContribsLink();
701 if ( 0 != $wgUser->getID() ) {
702 if($id) { # can only email real users
703 $s .= $sep . $this->emailUserLink();
707 $s .= "\n<br><hr class='sep'>";
710 if ( 0 != $wgUser->getID() ) {
711 $s .= $this->specialLink( "upload" ) . $sep;
713 $s .= $this->specialLink( "specialpages" )
714 . $sep . $this->bugReportsLink();
716 $s .= "\n<br></div>\n";
717 wfProfileOut();
718 return $s;
721 function specialPagesList()
723 global $wgUser, $wgOut, $wgLang, $wgServer, $wgRedirectScript;
724 $a = array();
726 $validSP = $wgLang->getValidSpecialPages();
728 foreach ( $validSP as $name => $desc ) {
729 if ( "" == $desc ) { continue; }
730 $a[$name] = $desc;
732 if ( $wgUser->isSysop() )
734 $sysopSP = $wgLang->getSysopSpecialPages();
736 foreach ( $sysopSP as $name => $desc ) {
737 if ( "" == $desc ) { continue; }
738 $a[$name] = $desc ;
741 if ( $wgUser->isDeveloper() )
743 $devSP = $wgLang->getDeveloperSpecialPages();
745 foreach ( $devSP as $name => $desc ) {
746 if ( "" == $desc ) { continue; }
747 $a[$name] = $desc ;
750 $go = wfMsg( "go" );
751 $sp = wfMsg( "specialpages" );
752 $spp = $wgLang->specialPage( "Specialpages" );
754 $s = "<form id=\"specialpages\" method=\"get\" class=\"inline\" " .
755 "action=\"{$wgServer}{$wgRedirectScript}\">\n";
756 $s .= "<select name=\"wpDropdown\">\n";
757 $s .= "<option value=\"{$spp}\">{$sp}</option>\n";
759 foreach ( $a as $name => $desc ) {
760 $p = $wgLang->specialPage( $name );
761 $s .= "<option value=\"{$p}\">{$desc}</option>\n";
763 $s .= "</select>\n";
764 $s .= "<input type=submit value=\"{$go}\" name=redirect>\n";
765 $s .= "</form>\n";
766 return $s;
769 function mainPageLink()
771 $mp = wfMsg( "mainpage" );
772 $s = $this->makeKnownLink( $mp, $mp );
773 return $s;
776 function copyrightLink()
778 $s = $this->makeKnownLink( wfMsg( "copyrightpage" ),
779 wfMsg( "copyrightpagename" ) );
780 return $s;
783 function aboutLink()
785 $s = $this->makeKnownLink( wfMsg( "aboutpage" ),
786 wfMsg( "aboutwikipedia" ) );
787 return $s;
790 function editThisPage()
792 global $wgOut, $wgTitle, $oldid, $redirect, $diff;
794 if ( ! $wgOut->isArticle() || $diff ) {
795 $s = wfMsg( "protectedpage" );
796 } else if ( $wgTitle->userCanEdit() ) {
797 $n = $wgTitle->getPrefixedText();
798 $t = wfMsg( "editthispage" );
799 $oid = $red = "";
801 if ( $redirect ) { $red = "&redirect={$redirect}"; }
802 if ( $oldid && ! isset( $diff ) ) {
803 $oid = "&oldid={$oldid}";
805 $s = $this->makeKnownLink( $n, $t, "action=edit{$oid}{$red}" );
806 } else {
807 $s = wfMsg( "protectedpage" );
809 return $s;
812 function deleteThisPage()
814 global $wgUser, $wgOut, $wgTitle, $diff;
816 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
817 $n = $wgTitle->getPrefixedText();
818 $t = wfMsg( "deletethispage" );
820 $s = $this->makeKnownLink( $n, $t, "action=delete" );
821 } else {
822 $s = wfMsg( "error" );
824 return $s;
827 function protectThisPage()
829 global $wgUser, $wgOut, $wgTitle, $diff;
831 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
832 $n = $wgTitle->getPrefixedText();
834 if ( $wgTitle->isProtected() ) {
835 $t = wfMsg( "unprotectthispage" );
836 $q = "action=unprotect";
837 } else {
838 $t = wfMsg( "protectthispage" );
839 $q = "action=protect";
841 $s = $this->makeKnownLink( $n, $t, $q );
842 } else {
843 $s = wfMsg( "error" );
845 return $s;
848 function watchThisPage()
850 global $wgUser, $wgOut, $wgTitle, $diff;
852 if ( $wgOut->isArticle() && ( ! $diff ) ) {
853 $n = $wgTitle->getPrefixedText();
855 if ( $wgTitle->userIsWatching() ) {
856 $t = wfMsg( "unwatchthispage" );
857 $q = "action=unwatch";
858 } else {
859 $t = wfMsg( "watchthispage" );
860 $q = "action=watch";
862 $s = $this->makeKnownLink( $n, $t, $q );
863 } else {
864 $s = wfMsg( "notanarticle" );
866 return $s;
869 function moveThisPage()
871 global $wgTitle, $wgLang;
873 if ( $wgTitle->userCanEdit() ) {
874 $s = $this->makeKnownLink( $wgLang->specialPage( "Movepage" ),
875 wfMsg( "movethispage" ), "target=" . $wgTitle->getPrefixedURL() );
876 } // no message if page is protected - would be redundant
877 return $s;
880 function historyLink()
882 global $wgTitle;
884 $s = $this->makeKnownLink( $wgTitle->getPrefixedText(),
885 wfMsg( "history" ), "action=history" );
886 return $s;
889 function whatLinksHere()
891 global $wgTitle, $wgLang;
893 $s = $this->makeKnownLink( $wgLang->specialPage( "Whatlinkshere" ),
894 wfMsg( "whatlinkshere" ), "target=" . $wgTitle->getPrefixedURL() );
895 return $s;
898 function userContribsLink()
900 global $wgTitle, $wgLang;
902 $s = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
903 wfMsg( "contributions" ), "target=" . $wgTitle->getURL() );
904 return $s;
907 function emailUserLink()
909 global $wgTitle, $wgLang;
911 $s = $this->makeKnownLink( $wgLang->specialPage( "Emailuser" ),
912 wfMsg( "emailuser" ), "target=" . $wgTitle->getURL() );
913 return $s;
916 function watchPageLinksLink()
918 global $wgOut, $wgTitle, $wgLang;
920 if ( ! $wgOut->isArticle() ) {
921 $s = "(" . wfMsg( "notanarticle" ) . ")";
922 } else {
923 $s = $this->makeKnownLink( $wgLang->specialPage(
924 "Recentchangeslinked" ), wfMsg( "recentchangeslinked" ),
925 "target=" . $wgTitle->getPrefixedURL() );
927 return $s;
930 function otherLanguages()
932 global $wgOut, $wgLang, $wgTitle , $wgUseNewInterlanguage ;
934 $a = $wgOut->getLanguageLinks();
935 if ( 0 == count( $a ) ) {
936 if ( !$wgUseNewInterlanguage ) return "";
937 $ns = $wgLang->getNsIndex ( $wgTitle->getNamespace () ) ;
938 if ( $ns != 0 AND $ns != 1 ) return "" ;
939 $pn = "Intl" ;
940 $x = "mode=addlink&xt=".$wgTitle->getDBkey() ;
941 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
942 wfMsg( "intl" ) , $x );
945 if ( !$wgUseNewInterlanguage ) {
946 $s = wfMsg( "otherlanguages" ) . ": ";
947 } else {
948 global $wgLanguageCode ;
949 $x = "mode=zoom&xt=".$wgTitle->getDBkey() ;
950 $x .= "&xl=".$wgLanguageCode ;
951 $s = $this->makeKnownLink( $wgLang->specialPage( "Intl" ),
952 wfMsg( "otherlanguages" ) , $x ) . ": " ;
955 $first = true;
956 if($wgLang->isRTL()) $s .= "<span dir='LTR'>";
957 foreach( $a as $l ) {
958 if ( ! $first ) { $s .= " | "; }
959 $first = false;
961 $nt = Title::newFromText( $l );
962 $url = $nt->getFullURL();
963 $text = $wgLang->getLanguageName( $nt->getInterwiki() );
965 if ( "" == $text ) { $text = $l; }
966 $style = $this->getExternalLinkAttributes( $l, $text );
967 $s .= "<a href=\"{$url}\"{$style}>{$text}</a>";
969 if($wgLang->isRTL()) $s .= "</span>";
970 return $s;
973 function bugReportsLink()
975 $s = $this->makeKnownLink( wfMsg( "bugreportspage" ),
976 wfMsg( "bugreports" ) );
977 return $s;
980 function dateLink()
982 global $wgLinkCache;
983 $t1 = Title::newFromText( gmdate( "F j" ) );
984 $t2 = Title::newFromText( gmdate( "Y" ) );
986 $wgLinkCache->suspend();
987 $id = $t1->getArticleID();
988 $wgLinkCache->resume();
990 if ( 0 == $id ) {
991 $s = $this->makeBrokenLink( $t1->getText() );
992 } else {
993 $s = $this->makeKnownLink( $t1->getText() );
995 $s .= ", ";
997 $wgLinkCache->suspend();
998 $id = $t2->getArticleID();
999 $wgLinkCache->resume();
1001 if ( 0 == $id ) {
1002 $s .= $this->makeBrokenLink( $t2->getText() );
1003 } else {
1004 $s .= $this->makeKnownLink( $t2->getText() );
1006 return $s;
1009 function talkLink()
1011 global $wgLang, $wgTitle, $wgLinkCache;
1013 $tns = $wgTitle->getNamespace();
1014 if ( -1 == $tns ) { return ""; }
1016 $pn = $wgTitle->getText();
1017 $tp = wfMsg( "talkpage" );
1018 if ( Namespace::isTalk( $tns ) ) {
1019 $lns = Namespace::getSubject( $tns );
1020 switch($tns) {
1021 case 1:
1022 $text = wfMsg("articlepage");
1023 break;
1024 case 3:
1025 $text = wfMsg("userpage");
1026 break;
1027 case 5:
1028 $text = wfMsg("wikipediapage");
1029 break;
1030 case 7:
1031 $text = wfMsg("imagepage");
1032 break;
1033 default:
1034 $text= wfMsg("articlepage");
1036 } else {
1038 $lns = Namespace::getTalk( $tns );
1039 $text=$tp;
1041 $n = $wgLang->getNsText( $lns );
1042 if ( "" == $n ) { $link = $pn; }
1043 else { $link = "{$n}:{$pn}"; }
1045 $wgLinkCache->suspend();
1046 $s = $this->makeLink( $link, $text );
1047 $wgLinkCache->resume();
1049 return $s;
1052 # After all the page content is transformed into HTML, it makes
1053 # a final pass through here for things like table backgrounds.
1055 function transformContent( $text )
1057 return $text;
1060 # Note: This function MUST call getArticleID() on the link,
1061 # otherwise the cache won't get updated properly. See LINKCACHE.DOC.
1063 function makeLink( $title, $text= "", $query = "", $trail = "" )
1065 global $wgOut, $wgUser;
1067 $nt = Title::newFromText( $title );
1069 if ( $nt->isExternal() ) {
1070 $u = $nt->getFullURL();
1071 if ( "" == $text ) { $text = $nt->getPrefixedText(); }
1072 $style = $this->getExternalLinkAttributes( $link, $text );
1074 $inside = "";
1075 if ( "" != $trail ) {
1076 if ( preg_match( "/^([a-z]+)(.*)$$/sD", $trail, $m ) ) {
1077 $inside = $m[1];
1078 $trail = $m[2];
1081 return "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1083 if ( 0 == $nt->getNamespace() && "" == $nt->getText() ) {
1084 return $this->makeKnownLink( $title, $text, $query, $trail );
1086 if ( ( -1 == $nt->getNamespace() ) ||
1087 ( Namespace::getImage() == $nt->getNamespace() ) ) {
1088 return $this->makeKnownLink( $title, $text, $query, $trail );
1090 $aid = $nt->getArticleID() ;
1091 if ( 0 == $aid ) {
1092 return $this->makeBrokenLink( $title, $text, $query, $trail );
1093 } else {
1094 $threshold = $wgUser->getOption("stubthreshold") ;
1095 if ( $threshold > 0 ) {
1096 $res = wfQuery ( "SELECT HIGH_PRIORITY length(cur_text) AS x, cur_namespace, cur_is_redirect FROM cur WHERE cur_id='{$aid}'" ) ;
1098 if ( wfNumRows( $res ) > 0 ) {
1099 $s = wfFetchObject( $res );
1100 $size = $s->x;
1101 if ( $s->cur_is_redirect OR $s->cur_namespace != 0 )
1102 $size = $threshold*2 ; # Really big
1103 wfFreeResult( $res );
1104 } else $size = $threshold*2 ; # Really big
1105 } else $size = 1 ;
1107 if ( $size < $threshold )
1108 return $this->makeStubLink( $title, $text, $query, $trail );
1109 return $this->makeKnownLink( $title, $text, $query, $trail );
1113 function makeKnownLink( $title, $text = "", $query = "", $trail = "" )
1115 global $wgOut, $wgTitle;
1117 $nt = Title::newFromText( $title );
1118 $link = $nt->getPrefixedURL();
1120 if ( "" == $link ) {
1121 $u = "";
1122 if ( "" == $text ) { $text = $nt->getFragment(); }
1123 } else {
1124 $u = wfLocalUrlE( $link, $query );
1126 if ( "" != $nt->getFragment() ) {
1127 $u .= "#" . wfEscapeHTML( $nt->getFragment() );
1129 if ( "" == $text ) { $text = $nt->getPrefixedText(); }
1130 $style = $this->getInternalLinkAttributes( $link, $text );
1132 $inside = "";
1133 if ( "" != $trail ) {
1134 if ( preg_match( wfMsg("linktrail"), $trail, $m ) ) {
1135 $inside = $m[1];
1136 $trail = $m[2];
1139 $r = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1140 return $r;
1143 function makeBrokenLink( $title, $text = "", $query = "", $trail = "" )
1145 global $wgOut, $wgUser;
1147 $nt = Title::newFromText( $title );
1148 $link = $nt->getPrefixedURL();
1150 if ( "" == $query ) { $q = "action=edit"; }
1151 else { $q = "action=edit&{$query}"; }
1152 $u = wfLocalUrlE( $link, $q );
1154 if ( "" == $text ) { $text = $nt->getPrefixedText(); }
1155 $style = $this->getInternalLinkAttributes( $link, $text, "yes" );
1157 $inside = "";
1158 if ( "" != $trail ) {
1159 if ( preg_match( wfMsg("linktrail"), $trail, $m ) ) {
1160 $inside = $m[1];
1161 $trail = $m[2];
1164 if ( $wgOut->isPrintable() ||
1165 ( 1 == $wgUser->getOption( "highlightbroken" ) ) ) {
1166 $s = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1167 } else {
1168 $s = "{$text}{$inside}<a href=\"{$u}\"{$style}>?</a>{$trail}";
1170 return $s;
1173 function makeStubLink( $title, $text = "", $query = "", $trail = "" )
1175 global $wgOut, $wgUser;
1177 $nt = Title::newFromText( $title );
1178 $link = $nt->getPrefixedURL();
1180 $u = wfLocalUrlE( $link, $query );
1182 if ( "" == $text ) { $text = $nt->getPrefixedText(); }
1183 $style = $this->getInternalLinkAttributes( $link, $text, "stub" );
1185 $inside = "";
1186 if ( "" != $trail ) {
1187 if ( preg_match( wfMsg("linktrail"), $trail, $m ) ) {
1188 $inside = $m[1];
1189 $trail = $m[2];
1192 if ( $wgOut->isPrintable() ||
1193 ( 1 == $wgUser->getOption( "highlightbroken" ) ) ) {
1194 $s = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1195 } else {
1196 $s = "{$text}{$inside}<a href=\"{$u}\"{$style}>!</a>{$trail}";
1198 return $s;
1201 function fnamePart( $url )
1203 $basename = strrchr( $url, "/" );
1204 if ( false === $basename ) { $basename = $url; }
1205 else { $basename = substr( $basename, 1 ); }
1206 return wfEscapeHTML( $basename );
1209 function makeImage( $url, $alt = "" )
1211 global $wgOut;
1213 if ( "" == $alt ) { $alt = $this->fnamePart( $url ); }
1214 $s = "<img src=\"{$url}\" alt=\"{$alt}\">";
1215 return $s;
1218 function makeImageLink( $name, $url, $alt = "" )
1220 global $wgOut, $wgTitle, $wgLang;
1222 $nt = Title::newFromText( $wgLang->getNsText(
1223 Namespace::getImage() ) . ":{$name}" );
1224 $link = $nt->getPrefixedURL();
1225 if ( "" == $alt ) { $alt = $name; }
1227 $u = wfLocalUrlE( $link );
1228 $s = "<a href=\"{$u}\" class='image' title=\"{$alt}\">" .
1229 "<img border=0 src=\"{$url}\" alt=\"{$alt}\"></a>";
1230 return $s;
1233 function makeMediaLink( $name, $url, $alt = "" )
1235 global $wgOut, $wgTitle;
1237 if ( "" == $alt ) { $alt = $name; }
1238 $u = wfEscapeHTML( $url );
1239 $s = "<a href=\"{$u}\" class='internal' title=\"{$alt}\">{$alt}</a>";
1240 return $s;
1243 function specialLink( $name, $key = "" )
1245 global $wgLang;
1247 if ( "" == $key ) { $key = strtolower( $name ); }
1248 $pn = $wgLang->ucfirst( $name );
1249 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1250 wfMsg( $key ) );
1253 # Called by history lists and recent changes
1256 function beginRecentChangesList()
1258 $rc_cache = array() ;
1259 $rccc = 0 ;
1260 $this->lastdate = "";
1261 return "";
1264 function beginHistoryList()
1266 $this->lastdate = $this->lastline = "";
1267 $s = "\n<p>" . wfMsg( "histlegend" ) . "\n<ul>";
1268 return $s;
1271 function beginImageHistoryList()
1273 $s = "\n<h2>" . wfMsg( "imghistory" ) . "</h2>\n" .
1274 "<p>" . wfMsg( "imghistlegend" ) . "\n<ul>";
1275 return $s;
1278 function endRecentChangesList()
1280 $s = $this->recentChangesBlock() ;
1281 $s .= "</ul>\n";
1282 return $s;
1285 function endHistoryList()
1287 $last = wfMsg( "last" );
1289 $s = preg_replace( "/!OLDID![0-9]+!/", $last, $this->lastline );
1290 $s .= "</ul>\n";
1291 return $s;
1294 function endImageHistoryList()
1296 $s = "</ul>\n";
1297 return $s;
1300 function historyLine( $ts, $u, $ut, $ns, $ttl, $oid, $c, $isminor )
1302 global $wgLang;
1304 $artname = Title::makeName( $ns, $ttl );
1305 $last = wfMsg( "last" );
1306 $cur = wfMsg( "cur" );
1307 $cr = wfMsg( "currentrev" );
1309 if ( $oid && $this->lastline ) {
1310 $ret = preg_replace( "/!OLDID!([0-9]+)!/", $this->makeKnownLink(
1311 $artname, $last, "diff=\\1&oldid={$oid}" ), $this->lastline );
1312 } else {
1313 $ret = "";
1315 $dt = $wgLang->timeanddate( $ts, true );
1317 if ( $oid ) { $q = "oldid={$oid}"; }
1318 else { $q = ""; }
1319 $link = $this->makeKnownLink( $artname, $dt, $q );
1321 if ( 0 == $u ) {
1322 $ul = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
1323 $ut, "target=" . $ut );
1324 } else { $ul = $this->makeLink( $wgLang->getNsText(
1325 Namespace::getUser() ) . ":{$ut}", $ut ); }
1327 $s = "<li>";
1328 if ( $oid ) {
1329 $curlink = $this->makeKnownLink( $artname, $cur,
1330 "diff=0&oldid={$oid}" );
1331 } else {
1332 $curlink = $cur;
1334 $s .= "({$curlink}) (!OLDID!{$oid}!) . .";
1336 $M = wfMsg( "minoreditletter" );
1337 if ( $isminor ) { $s .= " <strong>{$M}</strong>"; }
1338 $s .= " {$link} . . {$ul}";
1340 if ( "" != $c && "*" != $c ) { $s .= " <em>(" . wfEscapeHTML($c) . ")</em>"; }
1341 $s .= "</li>\n";
1343 $this->lastline = $s;
1344 return $ret;
1347 function recentChangesBlockLine ( $y ) {
1348 global $wgUploadPath ;
1350 $M = wfMsg( "minoreditletter" );
1351 $N = wfMsg( "newpageletter" );
1352 $r = "" ;
1353 $r .= "<img src='{$wgUploadPath}/Arr_.png' width=12 height=12 border=0>" ;
1354 $r .= "<tt>" ;
1355 if ( $y->isnew ) $r .= $N ;
1356 else $r .= "&nbsp;" ;
1357 if ( $y->isminor ) $r .= $M ;
1358 else $r .= "&nbsp;" ;
1359 $r .= " ".$y->timestamp." " ;
1360 $r .= "</tt>" ;
1361 $link = $y->link ;
1362 if ( $y->watched ) $link = "<strong>{$link}</strong>" ;
1363 $r .= $link ;
1365 $r .= " (" ;
1366 $r .= $y->curlink ;
1367 $r .= "; " ;
1368 $r .= $this->makeKnownLink( $y->secureName, wfMsg( "hist" ), "action=history" );
1370 $r .= ") . . ".$y->userlink ;
1371 $r .= $y->usertalklink ;
1372 if ( $y->usercomment != "" )
1373 $r .= " <em>(".wfEscapeHTML($y->usercomment).")</em>" ;
1374 $r .= "<br>\n" ;
1375 return $r ;
1378 function recentChangesBlockGroup ( $y ) {
1379 global $wgUploadPath ;
1381 $r = "" ;
1382 $M = wfMsg( "minoreditletter" );
1383 $N = wfMsg( "newpageletter" );
1384 $isnew = false ;
1385 $userlinks = array () ;
1386 foreach ( $y AS $x ) {
1387 $oldid = $x->diffid ;
1388 if ( $x->isnew ) $isnew = true ;
1389 $u = $x->userlink ;
1390 if ( !isset ( $userlinks[$u] ) ) $userlinks[$u] = 0 ;
1391 $userlinks[$u]++ ;
1394 krsort ( $userlinks ) ;
1395 asort ( $userlinks ) ;
1396 $users = array () ;
1397 $u = array_keys ( $userlinks ) ;
1398 foreach ( $u as $x ) {
1399 $z = $x ;
1400 if ( $userlinks[$x] > 1 ) $z .= " ({$userlinks[$x]}&times;)" ;
1401 array_push ( $users , $z ) ;
1403 $users = " <font size='-1'>[".implode("; ",$users)."]</font>" ;
1405 $e = $y ;
1406 $e = array_shift ( $e ) ;
1408 # Arrow
1409 $rci = "RCI{$this->rccc}" ;
1410 $rcl = "RCL{$this->rccc}" ;
1411 $rcm = "RCM{$this->rccc}" ;
1412 $tl = "<a href='javascript:toggleVisibility(\"{$rci}\",\"{$rcm}\",\"{$rcl}\")'>" ;
1413 $tl .= "<span id='{$rcm}'><img src='{$wgUploadPath}/Arr_r.png' width=12 height=12 border=0></span>" ;
1414 $tl .= "<span id='{$rcl}' style='display:none'><img src='{$wgUploadPath}/Arr_d.png' width=12 height=12 border=0></span>" ;
1415 $tl .= "</a>" ;
1416 $r .= $tl ;
1418 # Main line
1419 $r .= "<tt>" ;
1420 if ( $isnew ) $r .= $N ;
1421 else $r .= "&nbsp;" ;
1422 $r .= "&nbsp;" ; # Minor
1423 $r .= " ".$e->timestamp." " ;
1424 $r .= "</tt>" ;
1426 $link = $e->link ;
1427 if ( $e->watched ) $link = "<strong>{$link}</strong>" ;
1428 $r .= $link ;
1430 if ( !$e->islog ) {
1431 $r .= " (".count($y)." " ;
1432 if ( $isnew ) $r .= wfMsg("changes");
1433 else $r .= $this->makeKnownLink( $e->secureName , wfMsg("changes") , "diff=0&oldid=".$oldid ) ;
1434 $r .= "; " ;
1435 $r .= $this->makeKnownLink( $e->secureName, wfMsg( "history" ), "action=history" );
1436 $r .= ")" ;
1439 $r .= $users ;
1440 $r .= "<br>\n" ;
1442 # Sub-entries
1443 $r .= "<div id='{$rci}' style='display:none'>" ;
1444 foreach ( $y AS $x )
1446 $r .= "<img src='{$wgUploadPath}/Arr_.png' width=12 height=12 border=0>";
1447 $r .= "<tt>&nbsp; &nbsp; &nbsp; &nbsp;" ;
1448 if ( $x->isnew ) $r .= $N ;
1449 else $r .= "&nbsp;" ;
1450 if ( $x->isminor ) $r .= $M ;
1451 else $r .= "&nbsp;" ;
1452 $r .= "</tt>" ;
1454 $o = "" ;
1455 if ( $x->oldid != 0 ) $o = "oldid=".$x->oldid ;
1456 if ( $x->islog ) $link = $x->timestamp ;
1457 else $link = $this->makeKnownLink( $x->secureName, $x->timestamp , $o ) ;
1458 $link = "<tt>{$link}</tt>" ;
1461 $r .= $link ;
1462 $r .= " (" ;
1463 $r .= $x->curlink ;
1464 $r .= "; " ;
1465 $r .= $x->lastlink ;
1466 $r .= ") . . ".$x->userlink ;
1467 $r .= $x->usertalklink ;
1468 if ( $x->usercomment != "" )
1469 $r .= " <em>(".wfEscapeHTML($x->usercomment).")</em>" ;
1470 $r .= "<br>\n" ;
1472 $r .= "</div>\n" ;
1474 $this->rccc++ ;
1475 return $r ;
1478 function recentChangesBlock ()
1480 global $wgUploadPath ;
1481 if ( count ( $this->rc_cache ) == 0 ) return "" ;
1482 $k = array_keys ( $this->rc_cache ) ;
1483 foreach ( $k AS $x )
1485 $y = $this->rc_cache[$x] ;
1486 if ( count ( $y ) < 2 ) {
1487 $r .= $this->recentChangesBlockLine ( array_shift ( $y ) ) ;
1488 } else {
1489 $r .= $this->recentChangesBlockGroup ( $y ) ;
1493 return "<div align=left>{$r}</div>" ;
1496 function recentChangesLine( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched = false, $oldid = 0 , $diffid = 0 )
1498 global $wgUser ;
1499 $usenew = $wgUser->getOption( "usenewrc" );
1500 if ( $usenew )
1501 $r = $this->recentChangesLineNew ( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched , $oldid , $diffid ) ;
1502 else
1503 $r = $this->recentChangesLineOld ( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched , $oldid , $diffid ) ;
1504 return $r ;
1507 function recentChangesLineOld( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched = false, $oldid = 0, $diffid = 0 )
1509 global $wgTitle, $wgLang, $wgUser;
1511 $d = $wgLang->date( $ts, true);
1512 $s = "";
1513 if ( $d != $this->lastdate ) {
1514 if ( "" != $this->lastdate ) { $s .= "</ul>\n"; }
1515 $s .= "<h4>{$d}</h4>\n<ul>";
1516 $this->lastdate = $d;
1518 $h = $wgLang->time( $ts, true );
1519 $t = Title::makeName( $ns, $ttl );
1520 $clink = $this->makeKnownLink( $t , "" );
1521 $nt = Title::newFromText( $t );
1523 if ( $watched ) {
1524 $clink = "<strong>{$clink}</strong>";
1526 $hlink = $this->makeKnownLink( $t, wfMsg( "hist" ), "action=history" );
1527 if ( $isnew || $nt->isLog() ) {
1528 $dlink = wfMsg( "diff" );
1529 } else {
1530 $dlink = $this->makeKnownLink( $t, wfMsg( "diff" ),
1531 "diff={$oldid}&oldid={$diffid}" ); # Finagle's law
1533 if ( 0 == $u ) {
1534 $ul = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
1535 $ut, "target=" . $ut );
1536 } else { $ul = $this->makeLink( $wgLang->getNsText(
1537 Namespace::getUser() ) . ":{$ut}", $ut ); }
1539 $utns=$wgLang->getNsText(Namespace::getTalk(Namespace::getUser()));
1540 $talkname=$wgLang->getNsText(Namespace::getTalk(0)); # use the shorter name
1541 $utl= $this->makeLink($utns . ":{$ut}", $talkname );
1542 $cr = wfMsg( "currentrev" );
1544 $s .= "<li> ({$dlink}) ({$hlink}) . .";
1545 $M = wfMsg( "minoreditletter" );
1546 $N = wfMsg( "newpageletter" );
1547 if ( $isminor ) { $s .= " <strong>{$M}</strong>"; }
1548 if ( $isnew ) { $s .= "<strong>{$N}</strong>"; }
1549 $s .= " {$clink}; {$h} . . {$ul}";
1551 $blink="";
1552 if ( ( 0 == $u ) && $wgUser->isSysop() ) {
1553 $blink = $this->makeKnownLink( $wgLang->specialPage(
1554 "Blockip" ), wfMsg( "blocklink" ), "ip={$ut}" );
1557 if(!$blink) {
1558 $utl = "({$utl})";
1559 } else {
1560 $utl = "({$utl} | {$blink})";
1562 $s.=" {$utl}";
1564 if ( "" != $c && "*" != $c ) {
1565 $s .= " <em>(" . wfEscapeHTML( $c ) . ")</em>";
1567 $s .= "</li>\n";
1569 return $s;
1572 function recentChangesLineNew( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched = false, $oldid = 0 , $diffid = 0 )
1574 global $wgTitle, $wgLang, $wgUser;
1576 $rc = new RecentChangesClass ;
1578 $d = $wgLang->date( $ts, true);
1579 $s = "";
1580 $ret = "" ;
1581 if ( $d != $this->lastdate ) {
1582 $ret = $this->recentChangesBlock () ;
1583 $this->rc_cache = array() ;
1584 $ret .= "<h4>{$d}</h4>\n";
1585 $this->lastdate = $d;
1587 $h = $wgLang->time( $ts, true );
1588 $t = Title::makeName( $ns, $ttl );
1589 $clink = $this->makeKnownLink( $t, "" ) ;
1590 if ( $oldid == 0 ) $c2link = $clink ;
1591 else $c2link = $this->makeKnownLink( $t, "" , "oldid={$oldid}" );
1592 $nt = Title::newFromText( $t );
1594 $rc->timestamp = $h ;
1595 $rc->oldid = $oldid ;
1596 $rc->diffid = $diffid ;
1597 $rc->watched = $watched ;
1598 $rc->isnew = $isnew ;
1599 $rc->isminor = $isminor ;
1600 $rc->secureName = $t ;
1601 $rc->displayName = $nt ;
1602 $rc->link = $clink ;
1603 $rc->usercomment = $c ;
1604 $rc->islog = $nt->isLog() ;
1606 if ( ( $isnew && $oldid == 0 ) || $nt->isLog() ) {
1607 $dlink = wfMsg( "cur" );
1608 } else {
1609 $dlink = $this->makeKnownLink( $t, wfMsg( "cur" ),
1610 "diff=0&oldid={$oldid}" );
1613 if ( $diffid == 0 || $nt->isLog() ) {
1614 $plink = wfMsg( "last" );
1615 } else {
1616 $plink = $this->makeKnownLink( $t, wfMsg( "last" ),
1617 "diff={$oldid}&oldid={$diffid}" );
1620 if ( 0 == $u ) {
1621 $ul = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
1622 $ut, "target=" . $ut );
1623 } else { $ul = $this->makeLink( $wgLang->getNsText(
1624 Namespace::getUser() ) . ":{$ut}", $ut ); }
1626 $rc->userlink = $ul ;
1627 $rc->lastlink = $plink ;
1628 $rc->curlink = $dlink ;
1630 $utns=$wgLang->getNsText(Namespace::getTalk(Namespace::getUser()));
1631 $talkname=$wgLang->getNsText(Namespace::getTalk(0)); # use the shorter name
1632 $utl= $this->makeLink($utns . ":{$ut}", $talkname );
1634 if ( ( 0 == $u ) && $wgUser->isSysop() ) {
1635 $blink = $this->makeKnownLink( $wgLang->specialPage(
1636 "Blockip" ), wfMsg( "blocklink" ), "ip={$ut}" );
1637 $rc->usertalklink= " ({$utl} | {$blink})";
1638 } else {
1639 $rc->usertalklink=" ({$utl})";
1642 if ( !isset ( $this->rc_cache[$t] ) ) $this->rc_cache[$t] = array() ;
1643 array_push ( $this->rc_cache[$t] , $rc ) ;
1644 return $ret;
1648 function imageHistoryLine( $iscur, $ts, $img, $u, $ut, $size, $c )
1650 global $wgUser, $wgLang, $wgTitle;
1652 $dt = $wgLang->timeanddate( $ts, true );
1653 $del = wfMsg( "deleteimg" );
1654 $cur = wfMsg( "cur" );
1656 if ( $iscur ) {
1657 $url = wfImageUrl( $img );
1658 $rlink = $cur;
1659 if ( $wgUser->isSysop() ) {
1660 $link = wfLocalUrlE( "", "image=" . $wgTitle->getURL() .
1661 "&action=delete" );
1662 $style = $this->getInternalLinkAttributes( $link, $del );
1664 $dlink = "<a href=\"{$link}\"{$style}>{$del}</a>";
1665 } else {
1666 $dlink = $del;
1668 } else {
1669 $url = wfEscapeHTML( wfImageArchiveUrl( $img ) );
1670 if( $wgUser->getID() != 0 ) {
1671 $rlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
1672 wfMsg( "revertimg" ), "action=revert&oldimage=" .
1673 urlencode( $img ) );
1674 $dlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
1675 $del, "action=delete&oldimage=" . urlencode( $img ) );
1676 } else {
1677 # Having live active links for non-logged in users
1678 # means that bots and spiders crawling our site can
1679 # inadvertently change content. Baaaad idea.
1680 $rlink = wfMsg( "revertimg" );
1681 $dlink = $del;
1684 if ( 0 == $u ) { $ul = $ut; }
1685 else { $ul = $this->makeLink( $wgLang->getNsText(
1686 Namespace::getUser() ) . ":{$ut}", $ut ); }
1688 $nb = str_replace( "$1", $size, wfMsg( "nbytes" ) );
1689 $style = $this->getInternalLinkAttributes( $url, $dt );
1691 $s = "<li> ({$dlink}) ({$rlink}) <a href=\"{$url}\"{$style}>{$dt}</a>"
1692 . " . . {$ul} ({$nb})";
1694 if ( "" != $c && "*" != $c ) {
1695 $s .= " <em>(" . wfEscapeHTML( $c ) . ")</em>";
1697 $s .= "</li>\n";
1698 return $s;
1701 function tocIndent($level) {
1703 while($level-->0) $rv.="<div style=\"margin-left:2em;\">\n";
1704 return $rv;
1708 function tocUnindent($level) {
1709 while($level-->0) $rv.="</div>\n";
1710 return $rv;
1713 // parameter level defines if we are on an indentation level
1714 function tocLine($anchor,$tocline,$level) {
1716 if($level) {
1718 return "<A CLASS=\"internal\" HREF=\"#".$anchor."\">".$tocline."</A><BR>\n";
1719 } else {
1721 return "<div style=\"margin-bottom:0px;\">\n".
1722 "<A CLASS=\"internal\" HREF=\"#".$anchor."\">".$tocline."</A><BR>\n".
1723 "</div>\n";
1728 function tocTable($toc) {
1729 // note to CSS fanatics: putting this in a div does not works -- div won't auto-expand
1730 return
1731 "<p><table border=\"0\" id=\"toc\"><tr><td align=\"center\">\n".
1732 "<b>".wfMsg("toc")."</b>" .
1733 " <script type='text/javascript'>showTocToggle(\"" . wfMsg("showtoc") . "\",\"" . wfMsg("hidetoc") . "\")</script>" .
1734 "</td></tr><tr id='tocinside'><td align=\"left\">\n".
1735 $toc."</td></tr></table><P>\n";
1738 function editSectionScript($section,$head) {
1740 global $wgTitle,$wgUser,$oldid;
1741 if($wgTitle->isProtected() && !$wgUser->isSysop()) return $head;
1742 if($oldid) return $head;
1743 $url = wfLocalUrlE($wgTitle->getPrefixedText(),"action=edit&section=$section");
1744 return "<span onContextMenu='document.location=\"".$url."\";return false;'>{$head}</span>";
1747 function editSectionLink($section) {
1749 global $wgTitle,$wgUser,$oldid;
1750 if($wgTitle->isProtected() && !$wgUser->isSysop()) return "";
1751 if($oldid) return "";
1752 $editurl="&section={$section}";
1753 $url=$this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg("editsection"),"action=edit".$editurl);
1754 return "<div style=\"float:right;margin-left:5px;\"><small>[".$url."]</small></div>";
1759 include_once( "SkinStandard.php" );
1760 include_once( "SkinNostalgia.php" );
1761 include_once( "SkinCologneBlue.php" );