New date formatter
[mediawiki.git] / includes / Skin.php
blob47a4ee849e10182722b70a058c6f8413229535d8
1 <?
2 # See skin.doc
4 # These are the INTERNAL names, which get mapped
5 # directly to class names. For display purposes, the
6 # Language class has internationalized names
8 /* private */ $wgValidSkinNames = array(
9 "Standard", "Nostalgia", "CologneBlue" #, "Smarty", "Montparnasse"
12 # For some odd PHP bug, this function can't be part of a class
13 function getCategories ()
15 global $wgOut , $wgTitle , $wgUseCategoryMagic , $wgUser ;
16 if ( !isset ( $wgUseCategoryMagic ) || !$wgUseCategoryMagic ) return "" ;
17 if ( count ( $wgOut->mCategoryLinks ) == 0 ) return "" ;
18 if ( !$wgOut->isArticle() ) return "" ;
19 $sk = $wgUser->getSkin() ;
20 $s = "" ;
21 $s .= "\n<br>\n";
22 $s .= $sk->makeKnownLink ( "Special:Categories" , "Categories" , "article=".$wgTitle->getDBkey() ) ;
23 $t = implode ( " | " , $wgOut->mCategoryLinks ) ;
24 if ( $t != "" ) $s .= " : " ;
25 $s .= $t ;
26 return $s ;
30 class RecentChangesClass {
31 var $secureName , $displayName , $link , $namespace ;
32 var $oldid , $diffid , $timestamp , $curlink , $lastlink , $usertalklink , $versionlink ;
33 var $usercomment , $userlink ;
34 var $isminor , $isnew , $watched , $islog ;
35 } ;
37 class Skin {
39 /* private */ var $lastdate, $lastline;
41 var $rc_cache ; # Cache for Enhanced Recent Changes
42 var $rccc ; # Recent Changes Cache Counter for visibility toggle
45 function Skin()
49 function getSkinNames()
51 global $wgValidSkinNames;
52 return $wgValidSkinNames;
55 function getStylesheet()
57 return "wikistandard.css";
60 function qbSetting()
62 global $wgOut, $wgUser;
64 if ( $wgOut->isQuickbarSupressed() ) { return 0; }
65 $q = $wgUser->getOption( "quickbar" );
66 if ( "" == $q ) { $q = 0; }
67 return $q;
70 function initPage()
72 global $wgOut, $wgStyleSheetPath;
73 $fname = "Skin::initPage";
74 wfProfileIn( $fname );
76 $wgOut->addLink( "shortcut icon", "", "/favicon.ico" );
77 if ( $wgOut->isPrintable() ) { $ss = "wikiprintable.css"; }
78 else { $ss = $this->getStylesheet(); }
79 $wgOut->addLink( "stylesheet", "", "{$wgStyleSheetPath}/{$ss}" );
80 wfProfileOut( $fname );
83 function outputPage( &$out ) {
84 wfProfileIn( "Skin::outputPage" );
85 $this->initPage();
86 $out->out( $out->headElement() );
88 $out->out( "\n<body" );
89 $ops = $this->getBodyOptions();
90 foreach ( $ops as $name => $val ) {
91 $out->out( " $name='$val'" );
93 $out->out( ">\n" );
94 if ( $wgDebugComments ) {
95 $out->out( "<!-- Wiki debugging output:\n" .
96 $out->mDebugtext . "-->\n" );
98 $out->out( $this->beforeContent() );
100 $out->out( $out->mBodytext );
102 $out->out( $this->afterContent() );
104 wfProfileClose();
105 $out->out( $out->reportTime() );
107 $out->out( "\n</body></html>" );
110 function getHeadScripts() {
111 global $wgStyleSheetPath;
112 $r = "<script type=\"text/javascript\" src=\"{$wgStyleSheetPath}/wikibits.js\"></script>\n";
113 return $r;
116 function getUserStyles()
118 $s = "<style type='text/css'><!--\n";
119 $s .= $this->doGetUserStyles();
120 $s .= "//--></style>\n";
121 return $s;
124 function doGetUserStyles()
126 global $wgUser;
128 $s = "";
129 if ( 1 == $wgUser->getOption( "underline" ) ) {
130 # Don't override browser settings
131 } else {
132 # CHECK MERGE @@@
133 # Force no underline
134 $s .= "a.stub, a.new, a.internal, a.external { " .
135 "text-decoration: none; }\n";
137 if ( 1 == $wgUser->getOption( "highlightbroken" ) ) {
138 $s .= "a.new, #quickbar a.new { color: #CC2200; }\n";
140 if ( 1 == $wgUser->getOption( "justify" ) ) {
141 $s .= "#article { text-align: justify; }\n";
143 return $s;
146 function getBodyOptions()
148 global $wgUser, $wgTitle, $wgNamespaceBackgrounds, $wgOut, $oldid, $redirect, $diff,$action;
150 if ( 0 != $wgTitle->getNamespace() ) {
151 $a = array( "bgcolor" => "#ffffec" );
153 else $a = array( "bgcolor" => "#FFFFFF" );
154 if($wgOut->isArticle() && $wgUser->getOption("editondblclick")
156 (!$wgTitle->isProtected() || $wgUser->isSysop())
159 $n = $wgTitle->getPrefixedURL();
160 $t = wfMsg( "editthispage" );
161 $oid = $red = "";
162 if ( $redirect ) { $red = "&redirect={$redirect}"; }
163 if ( $oldid && ! isset( $diff ) ) {
164 $oid = "&oldid={$oldid}";
166 $s = wfLocalUrlE($n,"action=edit{$oid}{$red}");
167 $s = "document.location = \"" .$s ."\";";
168 $a += array ("ondblclick" => $s);
171 if($action=="edit") { # set focus in edit box
172 $foc = "document.editform.wpTextbox1.focus()";
173 if($a['onload']) {
174 $a['onload'] .= ";$foc";
175 } else {
176 $a['onload'] = $foc;
179 return $a;
182 function getExternalLinkAttributes( $link, $text )
184 global $wgUser, $wgOut, $wgLang;
186 $link = urldecode( $link );
187 $link = $wgLang->checkTitleEncoding( $link );
188 $link = str_replace( "_", " ", $link );
189 $link = wfEscapeHTML( $link );
191 if ( $wgOut->isPrintable() ) { $r = " class='printable'"; }
192 else { $r = " class='external'"; }
194 if ( 1 == $wgUser->getOption( "hover" ) ) {
195 $r .= " title=\"{$link}\"";
197 return $r;
200 function getInternalLinkAttributes( $link, $text, $broken = false )
202 global $wgUser, $wgOut;
204 $link = urldecode( $link );
205 $link = str_replace( "_", " ", $link );
206 $link = wfEscapeHTML( $link );
208 if ( $wgOut->isPrintable() ) {
209 $r = " class='printable'";
210 } else if ( $broken == "stub" ) {
211 $r = " class='stub'";
212 } else if ( $broken == "yes" ) {
213 $r = " class='new'";
214 } else {
215 $r = "";
218 if ( 1 == $wgUser->getOption( "hover" ) ) {
219 $r .= " title=\"{$link}\"";
221 return $r;
224 function getInternalLinkAttributesObj( &$nt, $text, $broken = false )
226 global $wgUser, $wgOut;
228 if ( $wgOut->isPrintable() ) {
229 $r = " class='printable'";
230 } else if ( $broken == "stub" ) {
231 $r = " class='stub'";
232 } else if ( $broken == "yes" ) {
233 $r = " class='new'";
234 } else {
235 $r = "";
238 if ( 1 == $wgUser->getOption( "hover" ) ) {
239 $r .= ' title ="' . $nt->getEscapedText() . '"';
241 return $r;
244 function getLogo()
246 global $wgLogo;
247 return $wgLogo;
250 # This will be called immediately after the <body> tag. Split into
251 # two functions to make it easier to subclass.
253 function beforeContent()
255 global $wgUser, $wgOut;
257 if ( $wgOut->isPrintable() ) {
258 $s = $this->pageTitle() . $this->pageSubtitle() . "\n";
259 $s .= "\n<div class='bodytext'>";
260 return $s;
262 return $this->doBeforeContent();
265 function doBeforeContent()
267 global $wgUser, $wgOut, $wgTitle, $wgLang;
268 $fname = "Skin::doBeforeContent";
269 wfProfileIn( $fname );
271 $s = "";
272 $qb = $this->qbSetting();
274 if( $langlinks = $this->otherLanguages() ) {
275 $rows = 2;
276 $borderhack = "";
277 } else {
278 $rows = 1;
279 $langlinks = false;
280 $borderhack = "class='top'";
283 $s .= "\n<div id='content'>\n<div id='topbar'>" .
284 "<table width='98%' border=0 cellspacing=0><tr>";
286 $shove = ($qb != 0);
287 $left = ($qb == 1 || $qb == 3);
288 if($wgLang->isRTL()) $left = !$left;
290 if ( !$shove ) {
291 $s .= "<td class='top' align=left valign=top rowspan='{$rows}'>" .
292 $this->logoText() . "</td>";
293 } elseif( $left ) {
294 $s .= $this->getQuickbarCompensator( $rows );
296 $l = $wgLang->isRTL() ? "right" : "left";
297 $s .= "<td {$borderhack} align='$l' valign='top'>";
299 $s .= $this->topLinks() ;
300 $s .= "<p class='subtitle'>" . $this->pageTitleLinks();
302 $r = $wgLang->isRTL() ? "left" : "right";
303 $s .= "</td>\n<td {$borderhack} valign='top' align='$r' nowrap>";
304 $s .= $this->nameAndLogin();
305 $s .= "\n<br>" . $this->searchForm() . "</td>";
307 if ( $langlinks ) {
308 $s .= "</tr>\n<tr><td class='top' colspan=\"2\">$langlinks</td>";
311 if ( $shove && !$left ) { # Right
312 $s .= $this->getQuickbarCompensator( $rows );
314 $s .= "</tr></table>\n</div>\n";
315 $s .= "\n<div id='article'>";
317 $s .= $this->pageTitle();
318 $s .= $this->pageSubtitle() ;
319 $s .= getCategories(); // For some odd reason, zhis can't be a function of the object
320 $s .= "\n<p>";
321 wfProfileOut( $fname );
322 return $s;
325 function getQuickbarCompensator( $rows = 1 )
327 return "<td width='152' rowspan='{$rows}'>&nbsp;</td>";
330 # This gets called immediately before the </body> tag.
332 function afterContent()
334 global $wgUser, $wgOut, $wgServer;
335 global $wgTitle;
337 if ( $wgOut->isPrintable() ) {
338 $s = "\n</div>\n";
340 $u = htmlspecialchars( $wgServer . $wgTitle->getFullURL() );
341 $u = "<a href=\"$u\">$u</a>";
342 $rf = wfMsg( "retrievedfrom", $u );
344 if ( $wgOut->isArticle() ) {
345 $lm = "<br>" . $this->lastModified();
346 } else { $lm = ""; }
348 $cr = wfMsg( "gnunote" );
349 $s .= "<p><em>{$rf}{$lm} {$cr}</em>\n";
350 return $s;
352 return $this->doAfterContent();
355 function doAfterContent()
357 global $wgUser, $wgOut, $wgLang;
358 $fname = "Skin::doAfterContent";
359 wfProfileIn( $fname );
360 wfProfileIn( "$fname-1" );
362 $s = "\n</div><br clear=all>\n";
363 $s .= "\n<div id='footer'>";
364 $s .= "<table width='98%' border=0 cellspacing=0><tr>";
366 wfProfileOut( "$fname-1" );
367 wfProfileIn( "$fname-2" );
369 $qb = $this->qbSetting();
370 $shove = ($qb != 0);
371 $left = ($qb == 1 || $qb == 3);
372 if($wgLang->isRTL()) $left = !$left;
374 if ( $shove && $left ) { # Left
375 $s .= $this->getQuickbarCompensator();
377 wfProfileOut( "$fname-2" );
378 wfProfileIn( "$fname-3" );
379 $l = $wgLang->isRTL() ? "right" : "left";
380 $s .= "<td class='bottom' align='$l' valign='top'>";
382 $s .= $this->bottomLinks();
383 $s .= "\n<br>" . $this->mainPageLink()
384 . " | " . $this->aboutLink()
385 . " | " . $this->specialLink( "recentchanges" )
386 . " | " . $this->searchForm()
387 . "<br>" . $this->pageStats();
389 $s .= "</td>";
390 if ( $shove && !$left ) { # Right
391 $s .= $this->getQuickbarCompensator();
393 $s .= "</tr></table>\n</div>\n</div>\n";
395 wfProfileOut( "$fname-3" );
396 wfProfileIn( "$fname-4" );
397 if ( 0 != $qb ) { $s .= $this->quickBar(); }
398 wfProfileOut( "$fname-4" );
399 wfProfileOut( $fname );
400 return $s;
403 function pageTitleLinks()
405 global $wgOut, $wgTitle, $oldid, $action, $diff, $wgUser, $wgLang, $wgUseApproval ;
407 $s = $this->printableLink();
409 if ( $wgOut->isArticle() ) {
410 if ( $wgTitle->getNamespace() == Namespace::getImage() ) {
411 $name = $wgTitle->getDBkey();
412 $link = wfEscapeHTML( wfImageUrl( $name ) );
413 $style = $this->getInternalLinkAttributes( $link, $name );
414 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>";
416 # This will show the "Approve" link if $wgUseApproval=true;
417 if ( isset ( $wgUseApproval ) && $wgUseApproval )
419 $t = $wgTitle->getDBkey();
420 $name = "Approve this article" ;
421 $link = "http://test.wikipedia.org/w/magnus/wiki.phtml?title={$t}&action=submit&doit=1" ;
422 #wfEscapeHTML( wfImageUrl( $name ) );
423 $style = $this->getExternalLinkAttributes( $link, $name );
424 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>" ;
426 if ( "history" == $action || isset( $diff ) || isset( $oldid ) ) {
427 $s .= " | " . $this->makeKnownLink( $wgTitle->getPrefixedText(),
428 wfMsg( "currentrev" ) );
431 if ( $wgUser->getNewtalk() ) {
432 # do not show "You have new messages" text when we are viewing our
433 # own talk page
435 if(!(strcmp($wgTitle->getText(),$wgUser->getName()) == 0 &&
436 $wgTitle->getNamespace()==Namespace::getTalk(Namespace::getUser()))) {
437 $n =$wgUser->getName();
438 $tl = $this->makeKnownLink( $wgLang->getNsText(
439 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
440 wfMsg("newmessageslink") );
441 $s.=" | <strong>". wfMsg( "newmessages", $tl ) . "</strong>";
444 if( $wgUser->isSysop() &&
445 (($wgTitle->getArticleId() == 0) || ($action == "history")) &&
446 ($n = $wgTitle->isDeleted() ) ) {
447 $s .= " | " . wfMsg( "thisisdeleted",
448 $this->makeKnownLink(
449 $wgLang->SpecialPage( "Undelete/" . $wgTitle->getPrefixedDBkey() ),
450 wfMsg( "restorelink", $n ) ) );
452 return $s;
455 function printableLink()
457 global $wgOut, $wgTitle, $oldid, $action;
459 $q = "";
460 foreach( $_GET as $var => $val ) {
461 if( $var != "title" && $var != "printable" )
462 $q .= urlencode( $var ) . "=" . urlencode( $val );
464 if( !empty( $q ) ) $q .= "&";
466 $s = $this->makeKnownLink( $wgTitle->getPrefixedText(),
467 WfMsg( "printableversion" ), "{$q}printable=yes" );
468 return $s;
471 function pageTitle()
473 global $wgOut, $wgTitle, $wgUser;
475 $s = "<h1 class='pagetitle'>" . $wgOut->getPageTitle() . "</h1>";
476 if($wgUser->getOption("editsectiononrightclick") && $wgTitle->userCanEdit()) { $s=$this->editSectionScript(0,$s);}
477 return $s;
480 function pageSubtitle()
482 global $wgOut,$wgTitle,$wgNamespacesWithSubpages;
484 $sub = $wgOut->getSubtitle();
485 if ( "" == $sub ) {
486 global $wgExtraSubtitle;
487 $sub = wfMsg( "fromwikipedia" ) . $wgExtraSubtitle;
489 if($wgOut->isArticle() && $wgNamespacesWithSubpages[$wgTitle->getNamespace()]) {
490 $ptext=$wgTitle->getPrefixedText();
491 if(preg_match("/\//",$ptext)) {
492 $sub.="</p><p class='subpages'>";
493 $links=explode("/",$ptext);
494 $c=0;
495 $growinglink="";
496 foreach($links as $link) {
497 $c++;
498 if ($c<count($links)) {
499 $growinglink.=$link;
500 $getlink=$this->makeLink( $growingLink, $link);
501 if(preg_match("/class='new'/i",$getlink)) { break; } # this is a hack, but it saves time
502 if ($c>1) {
503 $sub .= " | ";
504 } else {
505 $sub .="&lt; ";
507 $sub .= $getlink;
508 $growinglink.="/";
514 $s = "<p class='subtitle'>{$sub}\n";
515 return $s;
518 function nameAndLogin()
520 global $wgUser, $wgTitle, $wgLang, $wgShowIPinHeader;
522 $li = $wgLang->specialPage( "Userlogin" );
523 $lo = $wgLang->specialPage( "Userlogout" );
525 $s = "";
526 if ( 0 == $wgUser->getID() ) {
527 if( $wgShowIPinHeader ) {
528 $n = getenv( "REMOTE_ADDR" );
530 $tl = $this->makeKnownLink( $wgLang->getNsText(
531 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
532 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
534 $s .= $n . " (".$tl.")";
535 } else {
536 $s .= wfMsg("notloggedin");
539 $rt = $wgTitle->getPrefixedURL();
540 if ( 0 == strcasecmp( urlencode( $lo ), $rt ) ) {
541 $q = "";
542 } else { $q = "returnto={$rt}"; }
544 $s .= "\n<br>" . $this->makeKnownLink( $li,
545 wfMsg( "login" ), $q );
546 } else {
547 $n = $wgUser->getName();
548 $rt = $wgTitle->getPrefixedURL();
549 $tl = $this->makeKnownLink( $wgLang->getNsText(
550 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
551 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
553 $tl = " ({$tl})";
555 $s .= $this->makeKnownLink( $wgLang->getNsText(
556 Namespace::getUser() ) . ":{$n}", $n ) . "{$tl}<br>" .
557 $this->makeKnownLink( $lo, wfMsg( "logout" ),
558 "returnto={$rt}" ) . " | " .
559 $this->specialLink( "preferences" );
561 $s .= " | " . $this->makeKnownLink( wfMsg( "helppage" ),
562 wfMsg( "help" ) );
564 return $s;
567 function searchForm()
569 global $search;
571 $s = "<form name='search' class='inline' method=get action=\""
572 . wfLocalUrl( "" ) . "\">"
573 . "<input type=text name=\"search\" size=19 value=\""
574 . htmlspecialchars(substr($search,0,256)) . "\">\n"
575 . "<input type=submit name=\"go\" value=\"" . wfMsg ("go") . "\">&nbsp;"
576 . "<input type=submit value=\"" . wfMsg ("search") . "\"></form>";
578 return $s;
581 function topLinks()
583 global $wgOut;
584 $sep = " |\n";
586 $s = $this->mainPageLink() . $sep
587 . $this->specialLink( "recentchanges" );
589 if ( $wgOut->isArticle() ) {
590 $s .= $sep . $this->editThisPage()
591 . $sep . $this->historyLink();
593 # Many people don't like this dropdown box
594 #$s .= $sep . $this->specialPagesList();
596 return $s;
599 function bottomLinks()
601 global $wgOut, $wgUser, $wgTitle;
602 $sep = " |\n";
604 $s = "";
605 if ( $wgOut->isArticle() ) {
606 $s .= "<strong>" . $this->editThisPage() . "</strong>";
607 if ( 0 != $wgUser->getID() ) {
608 $s .= $sep . $this->watchThisPage();
610 $s .= $sep . $this->talkLink()
611 . $sep . $this->historyLink()
612 . $sep . $this->whatLinksHere()
613 . $sep . $this->watchPageLinksLink();
615 if ( $wgTitle->getNamespace() == Namespace::getUser()
616 || $wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser()) )
619 $id=User::idFromName($wgTitle->getText());
620 $ip=User::isIP($wgTitle->getText());
622 if($id || $ip) { # both anons and non-anons have contri list
623 $s .= $sep . $this->userContribsLink();
625 if ( 0 != $wgUser->getID() ) { # show only to signed in users
626 if($id) { # can only email non-anons
627 $s .= $sep . $this->emailUserLink();
631 if ( $wgUser->isSysop() && $wgTitle->getArticleId() ) {
632 $s .= "\n<br>" . $this->deleteThisPage() .
633 $sep . $this->protectThisPage() .
634 $sep . $this->moveThisPage();
636 $s .= "<br>\n" . $this->otherLanguages();
638 return $s;
641 function pageStats()
643 global $wgOut, $wgLang, $wgArticle;
644 global $oldid, $diff, $wgDisableCounters;
646 if ( ! $wgOut->isArticle() ) { return ""; }
647 if ( isset( $oldid ) || isset( $diff ) ) { return ""; }
648 if ( 0 == $wgArticle->getID() ) { return ""; }
650 if ( $wgDisableCounters ) {
651 $s = "";
652 } else {
653 $count = $wgArticle->getCount();
654 $s = wfMsg( "viewcount", $count );
656 $s .= $this->lastModified();
657 $s .= " " . wfMsg( "gnunote" );
658 return "<span id='pagestats'>{$s}</span>";
661 function lastModified()
663 global $wgLang, $wgArticle;
665 $d = $wgLang->timeanddate( $wgArticle->getTimestamp(), true );
666 $s = " " . wfMsg( "lastmodified", $d );
667 return $s;
670 function logoText( $align = "" )
672 if ( "" != $align ) { $a = " align='{$align}'"; }
673 else { $a = ""; }
675 $mp = wfMsg( "mainpage" );
676 $s = "<a href=\"" . wfLocalUrlE( urlencode( $mp ) )
677 . "\"><img{$a} border=0 src=\""
678 . $this->getLogo() . "\" alt=\"" . "[{$mp}]\"></a>";
679 return $s;
682 function quickBar()
684 global $wgOut, $wgTitle, $wgUser, $action, $wgLang;
685 global $wpPreview;
686 $fname = "Skin::quickBar";
687 wfProfileIn( $fname );
689 $tns=$wgTitle->getNamespace();
691 $s = "\n<div id='quickbar'>";
692 $s .= "\n" . $this->logoText() . "\n<hr class='sep'>";
694 $sep = "\n<br>";
695 $s .= $this->mainPageLink()
696 . $sep . $this->specialLink( "recentchanges" )
697 . $sep . $this->specialLink( "randompage" );
698 if ($wgUser->getID()) {
699 $s.= $sep . $this->specialLink( "watchlist" ) ;
700 $s .= $sep .$this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
701 wfMsg( "mycontris" ), "target=" . wfUrlencode($wgUser->getName() ) );
704 // only show watchlist link if logged in
705 if ( wfMsg ( "currentevents" ) != "-" ) $s .= $sep . $this->makeKnownLink( wfMsg( "currentevents" ), "" ) ;
706 $s .= "\n<br><hr class='sep'>";
707 $articleExists = $wgTitle->getArticleId();
708 if ( $wgOut->isArticle() || $action =="edit" || $action =="history" || $wpPreview) {
709 if($wgOut->isArticle()) {
710 $s .= "<strong>" . $this->editThisPage() . "</strong>";
711 } else { # backlink to the article in edit or history mode
712 if($articleExists){ # no backlink if no article
713 switch($tns) {
714 case 0:
715 $text = wfMsg("articlepage");
716 break;
717 case 1:
718 $text = wfMsg("viewtalkpage");
719 break;
720 case 2:
721 $text = wfMsg("userpage");
722 break;
723 case 3:
724 $text = wfMsg("viewtalkpage");
725 break;
726 case 4:
727 $text = wfMsg("wikipediapage");
728 break;
729 case 5:
730 $text = wfMsg("viewtalkpage");
731 break;
732 case 6:
733 $text = wfMsg("imagepage");
734 break;
735 case 7:
736 $text = wfMsg("viewtalkpage");
737 break;
738 default:
739 $text= wfMsg("articlepage");
742 $link = $wgTitle->getText();
743 if ($nstext = $wgLang->getNsText($tns) ) { # add namespace if necessary
744 $link = $nstext . ":" . $link ;
747 $s .= $this->makeLink( $link, $text );
748 } elseif( $wgTitle->getNamespace() != Namespace::getSpecial() ) {
749 # we just throw in a "New page" text to tell the user that he's in edit mode,
750 # and to avoid messing with the separator that is prepended to the next item
751 $s .= "<strong>" . wfMsg("newpage") . "</strong>";
757 if( $tns%2 && $action!="edit" && !$wpPreview) {
758 $s.="<br>".$this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg("postcomment"),"action=edit&section=new");
762 watching could cause problems in edit mode:
763 if user edits article, then loads "watch this article" in background and then saves
764 article with "Watch this article" checkbox disabled, the article is transparently
765 unwatched. Therefore we do not show the "Watch this page" link in edit mode
767 if ( 0 != $wgUser->getID() && $articleExists) {
768 if($action!="edit" && $action!="history" &&
769 $action != "submit" )
770 {$s .= $sep . $this->watchThisPage(); }
771 if ( $wgTitle->userCanEdit() ) $s .= $sep . $this->moveThisPage();
773 if ( $wgUser->isSysop() and $articleExists ) {
774 $s .= $sep . $this->deleteThisPage() .
775 $sep . $this->protectThisPage();
777 $s .= $sep . $this->talkLink();
778 if ($articleExists && $action !="history") { $s .= $sep . $this->historyLink();}
779 $s.=$sep . $this->whatLinksHere();
781 if($wgOut->isArticle()) {
782 $s .= $sep . $this->watchPageLinksLink();
785 if ( Namespace::getUser() == $wgTitle->getNamespace()
786 || $wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser())
789 $id=User::idFromName($wgTitle->getText());
790 $ip=User::isIP($wgTitle->getText());
792 if($id||$ip) {
793 $s .= $sep . $this->userContribsLink();
795 if ( 0 != $wgUser->getID() ) {
796 if($id) { # can only email real users
797 $s .= $sep . $this->emailUserLink();
801 $s .= "\n<br><hr class='sep'>";
804 if ( 0 != $wgUser->getID() ) {
805 $s .= $this->specialLink( "upload" ) . $sep;
807 $s .= $this->specialLink( "specialpages" )
808 . $sep . $this->bugReportsLink();
810 global $wgSiteSupportPage;
811 if( $wgSiteSupportPage ) {
812 $s .= "\n<br><a href=\"" . htmlspecialchars( $wgSiteSupportPage ) .
813 "\">" . wfMsg( "sitesupport" ) . "</a>";
816 $s .= "\n<br></div>\n";
817 wfProfileOut( $fname );
818 return $s;
821 function specialPagesList()
823 global $wgUser, $wgOut, $wgLang, $wgServer, $wgRedirectScript;
824 $a = array();
826 $validSP = $wgLang->getValidSpecialPages();
828 foreach ( $validSP as $name => $desc ) {
829 if ( "" == $desc ) { continue; }
830 $a[$name] = $desc;
832 if ( $wgUser->isSysop() )
834 $sysopSP = $wgLang->getSysopSpecialPages();
836 foreach ( $sysopSP as $name => $desc ) {
837 if ( "" == $desc ) { continue; }
838 $a[$name] = $desc ;
841 if ( $wgUser->isDeveloper() )
843 $devSP = $wgLang->getDeveloperSpecialPages();
845 foreach ( $devSP as $name => $desc ) {
846 if ( "" == $desc ) { continue; }
847 $a[$name] = $desc ;
850 $go = wfMsg( "go" );
851 $sp = wfMsg( "specialpages" );
852 $spp = $wgLang->specialPage( "Specialpages" );
854 $s = "<form id=\"specialpages\" method=\"get\" class=\"inline\" " .
855 "action=\"{$wgServer}{$wgRedirectScript}\">\n";
856 $s .= "<select name=\"wpDropdown\">\n";
857 $s .= "<option value=\"{$spp}\">{$sp}</option>\n";
859 foreach ( $a as $name => $desc ) {
860 $p = $wgLang->specialPage( $name );
861 $s .= "<option value=\"{$p}\">{$desc}</option>\n";
863 $s .= "</select>\n";
864 $s .= "<input type=submit value=\"{$go}\" name=redirect>\n";
865 $s .= "</form>\n";
866 return $s;
869 function mainPageLink()
871 $mp = wfMsg( "mainpage" );
872 $s = $this->makeKnownLink( $mp, $mp );
873 return $s;
876 function copyrightLink()
878 $s = $this->makeKnownLink( wfMsg( "copyrightpage" ),
879 wfMsg( "copyrightpagename" ) );
880 return $s;
883 function aboutLink()
885 $s = $this->makeKnownLink( wfMsg( "aboutpage" ),
886 wfMsg( "aboutwikipedia" ) );
887 return $s;
890 function editThisPage()
892 global $wgOut, $wgTitle, $oldid, $redirect, $diff;
894 if ( ! $wgOut->isArticle() || $diff ) {
895 $s = wfMsg( "protectedpage" );
896 } else if ( $wgTitle->userCanEdit() ) {
897 $n = $wgTitle->getPrefixedText();
898 $t = wfMsg( "editthispage" );
899 $oid = $red = "";
901 if ( $redirect ) { $red = "&redirect={$redirect}"; }
902 if ( $oldid && ! isset( $diff ) ) {
903 $oid = "&oldid={$oldid}";
905 $s = $this->makeKnownLink( $n, $t, "action=edit{$oid}{$red}" );
906 } else {
907 $s = wfMsg( "protectedpage" );
909 return $s;
912 function deleteThisPage()
914 global $wgUser, $wgOut, $wgTitle, $diff;
916 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
917 $n = $wgTitle->getPrefixedText();
918 $t = wfMsg( "deletethispage" );
920 $s = $this->makeKnownLink( $n, $t, "action=delete" );
921 } else {
922 $s = wfMsg( "error" );
924 return $s;
927 function protectThisPage()
929 global $wgUser, $wgOut, $wgTitle, $diff;
931 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
932 $n = $wgTitle->getPrefixedText();
934 if ( $wgTitle->isProtected() ) {
935 $t = wfMsg( "unprotectthispage" );
936 $q = "action=unprotect";
937 } else {
938 $t = wfMsg( "protectthispage" );
939 $q = "action=protect";
941 $s = $this->makeKnownLink( $n, $t, $q );
942 } else {
943 $s = wfMsg( "error" );
945 return $s;
948 function watchThisPage()
950 global $wgUser, $wgOut, $wgTitle, $diff;
952 if ( $wgOut->isArticle() && ( ! $diff ) ) {
953 $n = $wgTitle->getPrefixedText();
955 if ( $wgTitle->userIsWatching() ) {
956 $t = wfMsg( "unwatchthispage" );
957 $q = "action=unwatch";
958 } else {
959 $t = wfMsg( "watchthispage" );
960 $q = "action=watch";
962 $s = $this->makeKnownLink( $n, $t, $q );
963 } else {
964 $s = wfMsg( "notanarticle" );
966 return $s;
969 function moveThisPage()
971 global $wgTitle, $wgLang;
973 if ( $wgTitle->userCanEdit() ) {
974 $s = $this->makeKnownLink( $wgLang->specialPage( "Movepage" ),
975 wfMsg( "movethispage" ), "target=" . $wgTitle->getPrefixedURL() );
976 } // no message if page is protected - would be redundant
977 return $s;
980 function historyLink()
982 global $wgTitle;
984 $s = $this->makeKnownLink( $wgTitle->getPrefixedText(),
985 wfMsg( "history" ), "action=history" );
986 return $s;
989 function whatLinksHere()
991 global $wgTitle, $wgLang;
993 $s = $this->makeKnownLink( $wgLang->specialPage( "Whatlinkshere" ),
994 wfMsg( "whatlinkshere" ), "target=" . $wgTitle->getPrefixedURL() );
995 return $s;
998 function userContribsLink()
1000 global $wgTitle, $wgLang;
1002 $s = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
1003 wfMsg( "contributions" ), "target=" . $wgTitle->getURL() );
1004 return $s;
1007 function emailUserLink()
1009 global $wgTitle, $wgLang;
1011 $s = $this->makeKnownLink( $wgLang->specialPage( "Emailuser" ),
1012 wfMsg( "emailuser" ), "target=" . $wgTitle->getURL() );
1013 return $s;
1016 function watchPageLinksLink()
1018 global $wgOut, $wgTitle, $wgLang;
1020 if ( ! $wgOut->isArticle() ) {
1021 $s = "(" . wfMsg( "notanarticle" ) . ")";
1022 } else {
1023 $s = $this->makeKnownLink( $wgLang->specialPage(
1024 "Recentchangeslinked" ), wfMsg( "recentchangeslinked" ),
1025 "target=" . $wgTitle->getPrefixedURL() );
1027 return $s;
1030 function otherLanguages()
1032 global $wgOut, $wgLang, $wgTitle;
1034 $a = $wgOut->getLanguageLinks();
1035 # TEST THIS @@@
1036 if ( 0 == count( $a ) ) {
1037 if ( !$wgUseNewInterlanguage ) return "";
1038 $ns = $wgLang->getNsIndex ( $wgTitle->getNamespace () ) ;
1039 if ( $ns != 0 AND $ns != 1 ) return "" ;
1040 $pn = "Intl" ;
1041 $x = "mode=addlink&xt=".$wgTitle->getDBkey() ;
1042 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1043 wfMsg( "intl" ) , $x );
1046 if ( !$wgUseNewInterlanguage ) {
1047 $s = wfMsg( "otherlanguages" ) . ": ";
1048 } else {
1049 global $wgLanguageCode ;
1050 $x = "mode=zoom&xt=".$wgTitle->getDBkey() ;
1051 $x .= "&xl=".$wgLanguageCode ;
1052 $s = $this->makeKnownLink( $wgLang->specialPage( "Intl" ),
1053 wfMsg( "otherlanguages" ) , $x ) . ": " ;
1056 $s = wfMsg( "otherlanguages" ) . ": ";
1057 $first = true;
1058 if($wgLang->isRTL()) $s .= "<span dir='LTR'>";
1059 foreach( $a as $l ) {
1060 if ( ! $first ) { $s .= " | "; }
1061 $first = false;
1063 $nt = Title::newFromText( $l );
1064 $url = $nt->getFullURL();
1065 $text = $wgLang->getLanguageName( $nt->getInterwiki() );
1067 if ( "" == $text ) { $text = $l; }
1068 $style = $this->getExternalLinkAttributes( $l, $text );
1069 $s .= "<a href=\"{$url}\"{$style}>{$text}</a>";
1071 if($wgLang->isRTL()) $s .= "</span>";
1072 return $s;
1075 function bugReportsLink()
1077 $s = $this->makeKnownLink( wfMsg( "bugreportspage" ),
1078 wfMsg( "bugreports" ) );
1079 return $s;
1082 function dateLink()
1084 global $wgLinkCache;
1085 $t1 = Title::newFromText( gmdate( "F j" ) );
1086 $t2 = Title::newFromText( gmdate( "Y" ) );
1088 $wgLinkCache->suspend();
1089 $id = $t1->getArticleID();
1090 $wgLinkCache->resume();
1092 if ( 0 == $id ) {
1093 $s = $this->makeBrokenLink( $t1->getText() );
1094 } else {
1095 $s = $this->makeKnownLink( $t1->getText() );
1097 $s .= ", ";
1099 $wgLinkCache->suspend();
1100 $id = $t2->getArticleID();
1101 $wgLinkCache->resume();
1103 if ( 0 == $id ) {
1104 $s .= $this->makeBrokenLink( $t2->getText() );
1105 } else {
1106 $s .= $this->makeKnownLink( $t2->getText() );
1108 return $s;
1111 function talkLink()
1113 global $wgLang, $wgTitle, $wgLinkCache;
1115 $tns = $wgTitle->getNamespace();
1116 if ( -1 == $tns ) { return ""; }
1118 $pn = $wgTitle->getText();
1119 $tp = wfMsg( "talkpage" );
1120 if ( Namespace::isTalk( $tns ) ) {
1121 $lns = Namespace::getSubject( $tns );
1122 switch($tns) {
1123 case 1:
1124 $text = wfMsg("articlepage");
1125 break;
1126 case 3:
1127 $text = wfMsg("userpage");
1128 break;
1129 case 5:
1130 $text = wfMsg("wikipediapage");
1131 break;
1132 case 7:
1133 $text = wfMsg("imagepage");
1134 break;
1135 default:
1136 $text= wfMsg("articlepage");
1138 } else {
1140 $lns = Namespace::getTalk( $tns );
1141 $text=$tp;
1143 $n = $wgLang->getNsText( $lns );
1144 if ( "" == $n ) { $link = $pn; }
1145 else { $link = "{$n}:{$pn}"; }
1147 $wgLinkCache->suspend();
1148 $s = $this->makeLink( $link, $text );
1149 $wgLinkCache->resume();
1151 return $s;
1154 # After all the page content is transformed into HTML, it makes
1155 # a final pass through here for things like table backgrounds.
1157 function transformContent( $text )
1159 return $text;
1162 # Note: This function MUST call getArticleID() on the link,
1163 # otherwise the cache won't get updated properly. See LINKCACHE.DOC.
1165 function makeLink( $title, $text = "", $query = "", $trail = "" ) {
1166 wfProfileIn( "Skin::makeLink" );
1167 $result = $this->makeLinkObj( Title::newFromText( $title ), $text, $query, $trail );
1168 wfProfileOut( "Skin::makeLink" );
1169 return $result;
1172 function makeKnownLink( $title, $text = "", $query = "", $trail = "" ) {
1173 return $this->makeKnownLinkObj( Title::newFromText( $title ), $text, $query, $trail );
1176 function makeBrokenLink( $title, $text = "", $query = "", $trail = "" ) {
1177 return $this->makeBrokenLinkObj( Title::newFromText( $title ), $text, $query, $trail );
1180 function makeStubLink( $title, $text = "", $query = "", $trail = "" ) {
1181 return $this->makeStubLinkObj( Title::newFromText( $title ), $text, $query, $trail );
1184 # Pass a title object, not a title string
1185 function makeLinkObj( &$nt, $text= "", $query = "", $trail = "" )
1187 global $wgOut, $wgUser;
1188 if ( $nt->isExternal() ) {
1189 $u = $nt->getFullURL();
1190 if ( "" == $text ) { $text = $nt->getPrefixedText(); }
1191 $style = $this->getExternalLinkAttributes( $link, $text );
1193 $inside = "";
1194 if ( "" != $trail ) {
1195 if ( preg_match( "/^([a-z]+)(.*)$$/sD", $trail, $m ) ) {
1196 $inside = $m[1];
1197 $trail = $m[2];
1200 $retVal = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1201 } elseif ( 0 == $nt->getNamespace() && "" == $nt->getText() ) {
1202 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail );
1203 } elseif ( ( -1 == $nt->getNamespace() ) ||
1204 ( Namespace::getImage() == $nt->getNamespace() ) ) {
1205 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail );
1206 } else {
1207 $aid = $nt->getArticleID() ;
1208 if ( 0 == $aid ) {
1209 $retVal = $this->makeBrokenLinkObj( $nt, $text, $query, $trail );
1210 } else {
1211 $threshold = $wgUser->getOption("stubthreshold") ;
1212 if ( $threshold > 0 ) {
1213 $res = wfQuery ( "SELECT HIGH_PRIORITY length(cur_text) AS x, cur_namespace, cur_is_redirect FROM cur WHERE cur_id='{$aid}'", DB_READ ) ;
1215 if ( wfNumRows( $res ) > 0 ) {
1216 $s = wfFetchObject( $res );
1217 $size = $s->x;
1218 if ( $s->cur_is_redirect OR $s->cur_namespace != 0 ) {
1219 $size = $threshold*2 ; # Really big
1221 wfFreeResult( $res );
1222 } else {
1223 $size = $threshold*2 ; # Really big
1225 } else {
1226 $size = 1 ;
1228 if ( $size < $threshold ) {
1229 $retVal = $this->makeStubLinkObj( $nt, $text, $query, $trail );
1230 } else {
1231 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail );
1235 return $retVal;
1238 # Pass a title object, not a title string
1239 function makeKnownLinkObj( &$nt, $text = "", $query = "", $trail = "" )
1241 global $wgOut, $wgTitle;
1243 $fname = "Skin::makeKnownLinkObj";
1244 wfProfileIn( $fname );
1246 $link = $nt->getPrefixedURL();
1248 if ( "" == $link ) {
1249 $u = "";
1250 if ( "" == $text ) { $text = $nt->getFragment(); }
1251 } else {
1252 $u = wfLocalUrlE( $link, $query );
1254 if ( "" != $nt->getFragment() ) {
1255 $u .= "#" . wfEscapeHTML( $nt->getFragment() );
1257 if ( "" == $text ) { $text = $nt->getPrefixedText(); }
1258 $style = $this->getInternalLinkAttributesObj( $nt, $text );
1260 $inside = "";
1261 if ( "" != $trail ) {
1262 if ( preg_match( wfMsg("linktrail"), $trail, $m ) ) {
1263 $inside = $m[1];
1264 $trail = $m[2];
1267 $r = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1268 wfProfileOut( $fname );
1269 return $r;
1272 # Pass a title object, not a title string
1273 function makeBrokenLinkObj( &$nt, $text = "", $query = "", $trail = "" )
1275 global $wgOut, $wgUser;
1277 $fname = "Skin::makeBrokenLinkObj";
1278 wfProfileIn( $fname );
1280 $link = $nt->getPrefixedURL();
1282 if ( "" == $query ) { $q = "action=edit"; }
1283 else { $q = "action=edit&{$query}"; }
1284 $u = wfLocalUrlE( $link, $q );
1286 if ( "" == $text ) { $text = $nt->getPrefixedText(); }
1287 $style = $this->getInternalLinkAttributesObj( $nt, $text, "yes" );
1289 $inside = "";
1290 if ( "" != $trail ) {
1291 if ( preg_match( wfMsg("linktrail"), $trail, $m ) ) {
1292 $inside = $m[1];
1293 $trail = $m[2];
1296 if ( $wgOut->isPrintable() ||
1297 ( 1 == $wgUser->getOption( "highlightbroken" ) ) ) {
1298 $s = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1299 } else {
1300 $s = "{$text}{$inside}<a href=\"{$u}\"{$style}>?</a>{$trail}";
1303 wfProfileOut( $fname );
1304 return $s;
1307 # Pass a title object, not a title string
1308 function makeStubLinkObj( &$nt, $text = "", $query = "", $trail = "" )
1310 global $wgOut, $wgUser;
1312 $link = $nt->getPrefixedURL();
1314 $u = wfLocalUrlE( $link, $query );
1316 if ( "" == $text ) { $text = $nt->getPrefixedText(); }
1317 $style = $this->getInternalLinkAttributesObj( $nt, $text, "stub" );
1319 $inside = "";
1320 if ( "" != $trail ) {
1321 if ( preg_match( wfMsg("linktrail"), $trail, $m ) ) {
1322 $inside = $m[1];
1323 $trail = $m[2];
1326 if ( $wgOut->isPrintable() ||
1327 ( 1 == $wgUser->getOption( "highlightbroken" ) ) ) {
1328 $s = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1329 } else {
1330 $s = "{$text}{$inside}<a href=\"{$u}\"{$style}>!</a>{$trail}";
1332 return $s;
1335 function fnamePart( $url )
1337 $basename = strrchr( $url, "/" );
1338 if ( false === $basename ) { $basename = $url; }
1339 else { $basename = substr( $basename, 1 ); }
1340 return wfEscapeHTML( $basename );
1343 function makeImage( $url, $alt = "" )
1345 global $wgOut;
1347 if ( "" == $alt ) { $alt = $this->fnamePart( $url ); }
1348 $s = "<img src=\"{$url}\" alt=\"{$alt}\">";
1349 return $s;
1352 function makeImageLink( $name, $url, $alt = "" ) {
1353 $nt = Title::makeTitle( Namespace::getImage(), $name );
1354 return $this->makeImageLinkObj( $nt, $alt );
1357 function makeImageLinkObj( $nt, $alt = "" ) {
1358 $link = $nt->getPrefixedURL();
1359 $name = $nt->getDBKey();
1360 $url = wfImageUrl( $name );
1361 if ( empty( $alt ) ) {
1362 $alt = preg_replace( '/\.(.+?)^/', '', $name );
1364 $alt = htmlspecialchars( $alt );
1366 $u = wfLocalUrlE( $link );
1367 $s = "<a href=\"{$u}\" class='image' title=\"{$alt}\">" .
1368 "<img border=\"0\" src=\"{$url}\" alt=\"{$alt}\"></a>";
1369 return $s;
1372 function makeMediaLink( $name, $url, $alt = "" ) {
1373 $nt = Title::makeTitle( Namespace::getMedia(), $name );
1374 return $this->makeMediaLinkObj( $nt, $alt );
1377 function makeMediaLinkObj( $nt, $alt = "" )
1379 $name = $nt->getDBKey();
1380 $url = wfImageUrl( $name );
1381 if ( empty( $alt ) ) {
1382 $alt = preg_replace( '/\.(.+?)^/', '', $name );
1385 $u = htmlspecialchars( $url );
1386 $s = "<a href=\"{$u}\" class='internal' title=\"{$alt}\">{$alt}</a>";
1387 return $s;
1390 function specialLink( $name, $key = "" )
1392 global $wgLang;
1394 if ( "" == $key ) { $key = strtolower( $name ); }
1395 $pn = $wgLang->ucfirst( $name );
1396 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1397 wfMsg( $key ) );
1400 # Called by history lists and recent changes
1403 function beginRecentChangesList()
1405 $rc_cache = array() ;
1406 $rccc = 0 ;
1407 $this->lastdate = "";
1408 return "";
1411 function beginHistoryList()
1413 $this->lastdate = $this->lastline = "";
1414 $s = "\n<p>" . wfMsg( "histlegend" ) . "\n<ul>";
1415 return $s;
1418 function beginImageHistoryList()
1420 $s = "\n<h2>" . wfMsg( "imghistory" ) . "</h2>\n" .
1421 "<p>" . wfMsg( "imghistlegend" ) . "\n<ul>";
1422 return $s;
1425 function endRecentChangesList()
1427 $s = $this->recentChangesBlock() ;
1428 $s .= "</ul>\n";
1429 return $s;
1432 function endHistoryList()
1434 $last = wfMsg( "last" );
1436 $s = preg_replace( "/!OLDID![0-9]+!/", $last, $this->lastline );
1437 $s .= "</ul>\n";
1438 return $s;
1441 function endImageHistoryList()
1443 $s = "</ul>\n";
1444 return $s;
1447 function historyLine( $ts, $u, $ut, $ns, $ttl, $oid, $c, $isminor )
1449 global $wgLang;
1451 $artname = Title::makeName( $ns, $ttl );
1452 $last = wfMsg( "last" );
1453 $cur = wfMsg( "cur" );
1454 $cr = wfMsg( "currentrev" );
1456 if ( $oid && $this->lastline ) {
1457 $ret = preg_replace( "/!OLDID!([0-9]+)!/", $this->makeKnownLink(
1458 $artname, $last, "diff=\\1&oldid={$oid}" ), $this->lastline );
1459 } else {
1460 $ret = "";
1462 $dt = $wgLang->timeanddate( $ts, true );
1464 if ( $oid ) { $q = "oldid={$oid}"; }
1465 else { $q = ""; }
1466 $link = $this->makeKnownLink( $artname, $dt, $q );
1468 if ( 0 == $u ) {
1469 $ul = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
1470 $ut, "target=" . $ut );
1471 } else {
1472 $ul = $this->makeLink( $wgLang->getNsText(
1473 Namespace::getUser() ) . ":{$ut}", $ut ); }
1475 $s = "<li>";
1476 if ( $oid ) {
1477 $curlink = $this->makeKnownLink( $artname, $cur,
1478 "diff=0&oldid={$oid}" );
1479 } else {
1480 $curlink = $cur;
1482 $s .= "({$curlink}) (!OLDID!{$oid}!) . .";
1484 $M = wfMsg( "minoreditletter" );
1485 if ( $isminor ) { $s .= " <strong>{$M}</strong>"; }
1486 $s .= " {$link} . . {$ul}";
1488 if ( "" != $c && "*" != $c ) { $s .= " <em>(" . wfEscapeHTML($c) . ")</em>"; }
1489 $s .= "</li>\n";
1491 $this->lastline = $s;
1492 return $ret;
1495 function recentChangesBlockLine ( $y ) {
1496 global $wgUploadPath ;
1498 $M = wfMsg( "minoreditletter" );
1499 $N = wfMsg( "newpageletter" );
1500 $r = "" ;
1501 $r .= "<img src='{$wgUploadPath}/Arr_.png' width=12 height=12 border=0>" ;
1502 $r .= "<tt>" ;
1503 if ( $y->isnew ) $r .= $N ;
1504 else $r .= "&nbsp;" ;
1505 if ( $y->isminor ) $r .= $M ;
1506 else $r .= "&nbsp;" ;
1507 $r .= " ".$y->timestamp." " ;
1508 $r .= "</tt>" ;
1509 $link = $y->link ;
1510 if ( $y->watched ) $link = "<strong>{$link}</strong>" ;
1511 $r .= $link ;
1513 $r .= " (" ;
1514 $r .= $y->curlink ;
1515 $r .= "; " ;
1516 $r .= $this->makeKnownLink( $y->secureName, wfMsg( "hist" ), "action=history" );
1518 $r .= ") . . ".$y->userlink ;
1519 $r .= $y->usertalklink ;
1520 if ( $y->usercomment != "" )
1521 $r .= " <em>(".wfEscapeHTML($y->usercomment).")</em>" ;
1522 $r .= "<br>\n" ;
1523 return $r ;
1526 function recentChangesBlockGroup ( $y ) {
1527 global $wgUploadPath ;
1529 $r = "" ;
1530 $M = wfMsg( "minoreditletter" );
1531 $N = wfMsg( "newpageletter" );
1532 $isnew = false ;
1533 $userlinks = array () ;
1534 foreach ( $y AS $x ) {
1535 $oldid = $x->diffid ;
1536 if ( $x->isnew ) $isnew = true ;
1537 $u = $x->userlink ;
1538 if ( !isset ( $userlinks[$u] ) ) $userlinks[$u] = 0 ;
1539 $userlinks[$u]++ ;
1542 krsort ( $userlinks ) ;
1543 asort ( $userlinks ) ;
1544 $users = array () ;
1545 $u = array_keys ( $userlinks ) ;
1546 foreach ( $u as $x ) {
1547 $z = $x ;
1548 if ( $userlinks[$x] > 1 ) $z .= " ({$userlinks[$x]}&times;)" ;
1549 array_push ( $users , $z ) ;
1551 $users = " <font size='-1'>[".implode("; ",$users)."]</font>" ;
1553 $e = $y ;
1554 $e = array_shift ( $e ) ;
1556 # Arrow
1557 $rci = "RCI{$this->rccc}" ;
1558 $rcl = "RCL{$this->rccc}" ;
1559 $rcm = "RCM{$this->rccc}" ;
1560 $tl = "<a href='javascript:toggleVisibility(\"{$rci}\",\"{$rcm}\",\"{$rcl}\")'>" ;
1561 $tl .= "<span id='{$rcm}'><img src='{$wgUploadPath}/Arr_r.png' width=12 height=12 border=0></span>" ;
1562 $tl .= "<span id='{$rcl}' style='display:none'><img src='{$wgUploadPath}/Arr_d.png' width=12 height=12 border=0></span>" ;
1563 $tl .= "</a>" ;
1564 $r .= $tl ;
1566 # Main line
1567 $r .= "<tt>" ;
1568 if ( $isnew ) $r .= $N ;
1569 else $r .= "&nbsp;" ;
1570 $r .= "&nbsp;" ; # Minor
1571 $r .= " ".$e->timestamp." " ;
1572 $r .= "</tt>" ;
1574 $link = $e->link ;
1575 if ( $e->watched ) $link = "<strong>{$link}</strong>" ;
1576 $r .= $link ;
1578 if ( !$e->islog ) {
1579 $r .= " (".count($y)." " ;
1580 if ( $isnew ) $r .= wfMsg("changes");
1581 else $r .= $this->makeKnownLink( $e->secureName , wfMsg("changes") , "diff=0&oldid=".$oldid ) ;
1582 $r .= "; " ;
1583 $r .= $this->makeKnownLink( $e->secureName, wfMsg( "history" ), "action=history" );
1584 $r .= ")" ;
1587 $r .= $users ;
1588 $r .= "<br>\n" ;
1590 # Sub-entries
1591 $r .= "<div id='{$rci}' style='display:none'>" ;
1592 foreach ( $y AS $x )
1594 $r .= "<img src='{$wgUploadPath}/Arr_.png' width=12 height=12 border=0>";
1595 $r .= "<tt>&nbsp; &nbsp; &nbsp; &nbsp;" ;
1596 if ( $x->isnew ) $r .= $N ;
1597 else $r .= "&nbsp;" ;
1598 if ( $x->isminor ) $r .= $M ;
1599 else $r .= "&nbsp;" ;
1600 $r .= "</tt>" ;
1602 $o = "" ;
1603 if ( $x->oldid != 0 ) $o = "oldid=".$x->oldid ;
1604 if ( $x->islog ) $link = $x->timestamp ;
1605 else $link = $this->makeKnownLink( $x->secureName, $x->timestamp , $o ) ;
1606 $link = "<tt>{$link}</tt>" ;
1609 $r .= $link ;
1610 $r .= " (" ;
1611 $r .= $x->curlink ;
1612 $r .= "; " ;
1613 $r .= $x->lastlink ;
1614 $r .= ") . . ".$x->userlink ;
1615 $r .= $x->usertalklink ;
1616 if ( $x->usercomment != "" )
1617 $r .= " <em>(".wfEscapeHTML($x->usercomment).")</em>" ;
1618 $r .= "<br>\n" ;
1620 $r .= "</div>\n" ;
1622 $this->rccc++ ;
1623 return $r ;
1626 function recentChangesBlock ()
1628 global $wgUploadPath ;
1629 if ( count ( $this->rc_cache ) == 0 ) return "" ;
1630 $k = array_keys ( $this->rc_cache ) ;
1631 foreach ( $k AS $x )
1633 $y = $this->rc_cache[$x] ;
1634 if ( count ( $y ) < 2 ) {
1635 $r .= $this->recentChangesBlockLine ( array_shift ( $y ) ) ;
1636 } else {
1637 $r .= $this->recentChangesBlockGroup ( $y ) ;
1641 return "<div align=left>{$r}</div>" ;
1644 function recentChangesLine( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched = false, $oldid = 0 , $diffid = 0 )
1646 global $wgUser ;
1647 $usenew = $wgUser->getOption( "usenewrc" );
1648 if ( $usenew )
1649 $r = $this->recentChangesLineNew ( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched , $oldid , $diffid ) ;
1650 else
1651 $r = $this->recentChangesLineOld ( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched , $oldid , $diffid ) ;
1652 return $r ;
1655 function recentChangesLineOld( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched = false, $oldid = 0, $diffid = 0 )
1657 global $wgTitle, $wgLang, $wgUser;
1659 $d = $wgLang->date( $ts, true);
1660 $s = "";
1661 if ( $d != $this->lastdate ) {
1662 if ( "" != $this->lastdate ) { $s .= "</ul>\n"; }
1663 $s .= "<h4>{$d}</h4>\n<ul>";
1664 $this->lastdate = $d;
1666 $h = $wgLang->time( $ts, true );
1667 $t = Title::makeName( $ns, $ttl );
1668 $clink = $this->makeKnownLink( $t , "" );
1669 $nt = Title::newFromText( $t );
1671 if ( $watched ) {
1672 $clink = "<strong>{$clink}</strong>";
1674 $hlink = $this->makeKnownLink( $t, wfMsg( "hist" ), "action=history" );
1675 if ( $isnew || $nt->isLog() ) {
1676 $dlink = wfMsg( "diff" );
1677 } else {
1678 $dlink = $this->makeKnownLink( $t, wfMsg( "diff" ),
1679 "diff={$oldid}&oldid={$diffid}" ); # Finagle's law
1681 if ( 0 == $u ) {
1682 $ul = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
1683 $ut, "target=" . $ut );
1684 } else {
1685 $ul = $this->makeLink( $wgLang->getNsText( Namespace::getUser() ) . ":{$ut}", $ut );
1688 $talkname=$wgLang->getNsText(Namespace::getTalk(0)); # use the shorter name
1689 global $wgDisableAnonTalk;
1690 if( 0 == $u && $wgDisableAnonTalk ) {
1691 $utl = "";
1692 } else {
1693 $utns=$wgLang->getNsText(Namespace::getTalk(Namespace::getUser()));
1694 $utl= $this->makeLink($utns . ":{$ut}", $talkname );
1696 $cr = wfMsg( "currentrev" );
1698 $s .= "<li> ({$dlink}) ({$hlink}) . .";
1699 $M = wfMsg( "minoreditletter" );
1700 $N = wfMsg( "newpageletter" );
1701 if ( $isminor ) { $s .= " <strong>{$M}</strong>"; }
1702 if ( $isnew ) { $s .= "<strong>{$N}</strong>"; }
1703 $s .= " {$clink}; {$h} . . {$ul}";
1705 $blink="";
1706 if ( ( 0 == $u ) && $wgUser->isSysop() ) {
1707 $blink = $this->makeKnownLink( $wgLang->specialPage(
1708 "Blockip" ), wfMsg( "blocklink" ), "ip={$ut}" );
1711 if($blink) {
1712 if($utl) $utl .= " | ";
1713 $utl .= $blink;
1715 if($utl) $s.=" ({$utl})";
1717 if ( "" != $c && "*" != $c ) {
1718 $s .= " <em>(" . wfEscapeHTML( $c ) . ")</em>";
1720 $s .= "</li>\n";
1722 return $s;
1725 function recentChangesLineNew( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched = false, $oldid = 0 , $diffid = 0 )
1727 global $wgTitle, $wgLang, $wgUser;
1729 $rc = new RecentChangesClass ;
1731 $d = $wgLang->date( $ts, true);
1732 $s = "";
1733 $ret = "" ;
1734 if ( $d != $this->lastdate ) {
1735 $ret = $this->recentChangesBlock () ;
1736 $this->rc_cache = array() ;
1737 $ret .= "<h4>{$d}</h4>\n";
1738 $this->lastdate = $d;
1740 $h = $wgLang->time( $ts, true );
1741 $t = Title::makeName( $ns, $ttl );
1742 $clink = $this->makeKnownLink( $t, "" ) ;
1743 if ( $oldid == 0 ) $c2link = $clink ;
1744 else $c2link = $this->makeKnownLink( $t, "" , "oldid={$oldid}" );
1745 $nt = Title::newFromText( $t );
1747 $rc->timestamp = $h ;
1748 $rc->oldid = $oldid ;
1749 $rc->diffid = $diffid ;
1750 $rc->watched = $watched ;
1751 $rc->isnew = $isnew ;
1752 $rc->isminor = $isminor ;
1753 $rc->secureName = $t ;
1754 $rc->displayName = $nt ;
1755 $rc->link = $clink ;
1756 $rc->usercomment = $c ;
1757 $rc->islog = $nt->isLog() ;
1759 if ( ( $isnew && $oldid == 0 ) || $nt->isLog() ) {
1760 $dlink = wfMsg( "cur" );
1761 } else {
1762 $dlink = $this->makeKnownLink( $t, wfMsg( "cur" ),
1763 "diff=0&oldid={$oldid}" );
1766 if ( $diffid == 0 || $nt->isLog() ) {
1767 $plink = wfMsg( "last" );
1768 } else {
1769 $plink = $this->makeKnownLink( $t, wfMsg( "last" ),
1770 "diff={$oldid}&oldid={$diffid}" );
1773 if ( 0 == $u ) {
1774 $ul = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
1775 $ut, "target=" . $ut );
1776 } else { $ul = $this->makeLink( $wgLang->getNsText(
1777 Namespace::getUser() ) . ":{$ut}", $ut ); }
1779 $rc->userlink = $ul ;
1780 $rc->lastlink = $plink ;
1781 $rc->curlink = $dlink ;
1783 $utns=$wgLang->getNsText(Namespace::getTalk(Namespace::getUser()));
1784 $talkname=$wgLang->getNsText(Namespace::getTalk(0)); # use the shorter name
1785 $utl= $this->makeLink($utns . ":{$ut}", $talkname );
1787 global $wgDisableAnonTalk;
1788 if ( ( 0 == $u ) && $wgUser->isSysop() ) {
1789 $blink = $this->makeKnownLink( $wgLang->specialPage(
1790 "Blockip" ), wfMsg( "blocklink" ), "ip={$ut}" );
1791 if( $wgDisableAnonTalk )
1792 $rc->usertalklink = " ({$blink})";
1793 else
1794 $rc->usertalklink = " ({$utl} | {$blink})";
1795 } else {
1796 if( $wgDisableAnonTalk && ($u == 0) )
1797 $rc->usertalklink = "";
1798 else
1799 $rc->usertalklink = " ({$utl})";
1802 if ( !isset ( $this->rc_cache[$t] ) ) $this->rc_cache[$t] = array() ;
1803 array_push ( $this->rc_cache[$t] , $rc ) ;
1804 return $ret;
1808 function imageHistoryLine( $iscur, $ts, $img, $u, $ut, $size, $c )
1810 global $wgUser, $wgLang, $wgTitle;
1812 $dt = $wgLang->timeanddate( $ts, true );
1813 $del = wfMsg( "deleteimg" );
1814 $cur = wfMsg( "cur" );
1816 if ( $iscur ) {
1817 $url = wfImageUrl( $img );
1818 $rlink = $cur;
1819 if ( $wgUser->isSysop() ) {
1820 $link = wfLocalUrlE( $wgTitle->getPrefixedText(), "image=" . $wgTitle->getURL() .
1821 "&action=delete" );
1822 $style = $this->getInternalLinkAttributes( $link, $del );
1824 $dlink = "<a href=\"{$link}\"{$style}>{$del}</a>";
1825 } else {
1826 $dlink = $del;
1828 } else {
1829 $url = wfEscapeHTML( wfImageArchiveUrl( $img ) );
1830 if( $wgUser->getID() != 0 ) {
1831 $rlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
1832 wfMsg( "revertimg" ), "action=revert&oldimage=" .
1833 urlencode( $img ) );
1834 $dlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
1835 $del, "action=delete&oldimage=" . urlencode( $img ) );
1836 } else {
1837 # Having live active links for non-logged in users
1838 # means that bots and spiders crawling our site can
1839 # inadvertently change content. Baaaad idea.
1840 $rlink = wfMsg( "revertimg" );
1841 $dlink = $del;
1844 if ( 0 == $u ) { $ul = $ut; }
1845 else { $ul = $this->makeLink( $wgLang->getNsText(
1846 Namespace::getUser() ) . ":{$ut}", $ut ); }
1848 $nb = wfMsg( "nbytes", $size );
1849 $style = $this->getInternalLinkAttributes( $url, $dt );
1851 $s = "<li> ({$dlink}) ({$rlink}) <a href=\"{$url}\"{$style}>{$dt}</a>"
1852 . " . . {$ul} ({$nb})";
1854 if ( "" != $c && "*" != $c ) {
1855 $s .= " <em>(" . wfEscapeHTML( $c ) . ")</em>";
1857 $s .= "</li>\n";
1858 return $s;
1861 function tocIndent($level) {
1863 while($level-->0) $rv.="<div style=\"margin-left:2em;\">\n";
1864 return $rv;
1868 function tocUnindent($level) {
1869 while($level-->0) $rv.="</div>\n";
1870 return $rv;
1873 // parameter level defines if we are on an indentation level
1874 function tocLine($anchor,$tocline,$level) {
1876 if($level) {
1878 return "<A CLASS=\"internal\" HREF=\"#".$anchor."\">".$tocline."</A><BR>\n";
1879 } else {
1881 return "<div style=\"margin-bottom:0px;\">\n".
1882 "<A CLASS=\"internal\" HREF=\"#".$anchor."\">".$tocline."</A><BR>\n".
1883 "</div>\n";
1888 function tocTable($toc) {
1889 // note to CSS fanatics: putting this in a div does not work -- div won't auto-expand
1890 global $printable;
1892 if (!$printable) {
1893 $hideline = " <script type='text/javascript'>showTocToggle(\"" . wfMsg("showtoc") . "\",\"" . wfMsg("hidetoc") . "\")</script>";
1895 return
1896 "<p><table border=\"0\" id=\"toc\"><tr><td align=\"center\">\n".
1897 "<b>".wfMsg("toc")."</b>" .
1898 $hideline .
1899 "</td></tr><tr id='tocinside'><td align=\"left\">\n".
1900 $toc."</td></tr></table><P>\n";
1903 # These two do not check for permissions: check $wgTitle->userCanEdit before calling them
1904 function editSectionScript($section,$head) {
1906 global $wgTitle,$wgUser,$oldid;
1907 if($oldid) return $head;
1908 $url = wfLocalUrlE(urlencode($wgTitle->getPrefixedText()),"action=edit&section=$section");
1909 return "<span onContextMenu='document.location=\"".$url."\";return false;'>{$head}</span>";
1912 function editSectionLink($section) {
1914 global $printable;
1915 global $wgTitle,$wgUser,$oldid;
1916 if($oldid) return "";
1917 if ($printable) return "";
1918 $editurl="&section={$section}";
1919 $url=$this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg("editsection"),"action=edit".$editurl);
1920 return "<div style=\"float:right;margin-left:5px;\"><small>[".$url."]</small></div>";
1925 include_once( "SkinStandard.php" );
1926 include_once( "SkinNostalgia.php" );
1927 include_once( "SkinCologneBlue.php" );
1929 #include_once( "SkinSmarty.php" );