Only emit the javascript to set editbox focus when we're really editing
[mediawiki.git] / includes / Skin.php
blob4853b2a4f63268e172d4775d272ec656fbc77b2e
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 $a['onload'] = $wgOut->getOnloadHandler();
172 return $a;
175 function getExternalLinkAttributes( $link, $text )
177 global $wgUser, $wgOut, $wgLang;
179 $link = urldecode( $link );
180 $link = $wgLang->checkTitleEncoding( $link );
181 $link = str_replace( "_", " ", $link );
182 $link = wfEscapeHTML( $link );
184 if ( $wgOut->isPrintable() ) { $r = " class='printable'"; }
185 else { $r = " class='external'"; }
187 if ( 1 == $wgUser->getOption( "hover" ) ) {
188 $r .= " title=\"{$link}\"";
190 return $r;
193 function getInternalLinkAttributes( $link, $text, $broken = false )
195 global $wgUser, $wgOut;
197 $link = urldecode( $link );
198 $link = str_replace( "_", " ", $link );
199 $link = wfEscapeHTML( $link );
201 if ( $wgOut->isPrintable() ) {
202 $r = " class='printable'";
203 } else if ( $broken == "stub" ) {
204 $r = " class='stub'";
205 } else if ( $broken == "yes" ) {
206 $r = " class='new'";
207 } else {
208 $r = " class='internal'";
211 if ( 1 == $wgUser->getOption( "hover" ) ) {
212 $r .= " title=\"{$link}\"";
214 return $r;
217 function getInternalLinkAttributesObj( &$nt, $text, $broken = false )
219 global $wgUser, $wgOut;
221 if ( $wgOut->isPrintable() ) {
222 $r = " class='printable'";
223 } else if ( $broken == "stub" ) {
224 $r = " class='stub'";
225 } else if ( $broken == "yes" ) {
226 $r = " class='new'";
227 } else {
228 $r = " class='internal'";
231 if ( 1 == $wgUser->getOption( "hover" ) ) {
232 $r .= ' title ="' . $nt->getEscapedText() . '"';
234 return $r;
237 function getLogo()
239 global $wgLogo;
240 return $wgLogo;
243 # This will be called immediately after the <body> tag. Split into
244 # two functions to make it easier to subclass.
246 function beforeContent()
248 global $wgUser, $wgOut;
250 if ( $wgOut->isPrintable() ) {
251 $s = $this->pageTitle() . $this->pageSubtitle() . "\n";
252 $s .= "\n<div class='bodytext'>";
253 return $s;
255 return $this->doBeforeContent();
258 function doBeforeContent()
260 global $wgUser, $wgOut, $wgTitle, $wgLang;
261 $fname = "Skin::doBeforeContent";
262 wfProfileIn( $fname );
264 $s = "";
265 $qb = $this->qbSetting();
267 if( $langlinks = $this->otherLanguages() ) {
268 $rows = 2;
269 $borderhack = "";
270 } else {
271 $rows = 1;
272 $langlinks = false;
273 $borderhack = "class='top'";
276 $s .= "\n<div id='content'>\n<div id='topbar'>" .
277 "<table width='98%' border=0 cellspacing=0><tr>";
279 $shove = ($qb != 0);
280 $left = ($qb == 1 || $qb == 3);
281 if($wgLang->isRTL()) $left = !$left;
283 if ( !$shove ) {
284 $s .= "<td class='top' align=left valign=top rowspan='{$rows}'>" .
285 $this->logoText() . "</td>";
286 } elseif( $left ) {
287 $s .= $this->getQuickbarCompensator( $rows );
289 $l = $wgLang->isRTL() ? "right" : "left";
290 $s .= "<td {$borderhack} align='$l' valign='top'>";
292 $s .= $this->topLinks() ;
293 $s .= "<p class='subtitle'>" . $this->pageTitleLinks();
295 $r = $wgLang->isRTL() ? "left" : "right";
296 $s .= "</td>\n<td {$borderhack} valign='top' align='$r' nowrap>";
297 $s .= $this->nameAndLogin();
298 $s .= "\n<br>" . $this->searchForm() . "</td>";
300 if ( $langlinks ) {
301 $s .= "</tr>\n<tr><td class='top' colspan=\"2\">$langlinks</td>";
304 if ( $shove && !$left ) { # Right
305 $s .= $this->getQuickbarCompensator( $rows );
307 $s .= "</tr></table>\n</div>\n";
308 $s .= "\n<div id='article'>";
310 $s .= $this->pageTitle();
311 $s .= $this->pageSubtitle() ;
312 $s .= getCategories(); // For some odd reason, zhis can't be a function of the object
313 $s .= "\n<p>";
314 wfProfileOut( $fname );
315 return $s;
318 function getQuickbarCompensator( $rows = 1 )
320 return "<td width='152' rowspan='{$rows}'>&nbsp;</td>";
323 # This gets called immediately before the </body> tag.
325 function afterContent()
327 global $wgUser, $wgOut, $wgServer;
328 global $wgTitle;
330 if ( $wgOut->isPrintable() ) {
331 $s = "\n</div>\n";
333 $u = htmlspecialchars( $wgServer . $wgTitle->getFullURL() );
334 $u = "<a href=\"$u\">$u</a>";
335 $rf = wfMsg( "retrievedfrom", $u );
337 if ( $wgOut->isArticle() ) {
338 $lm = "<br>" . $this->lastModified();
339 } else { $lm = ""; }
341 $cr = wfMsg( "gnunote" );
342 $s .= "<p><em>{$rf}{$lm} {$cr}</em>\n";
343 return $s;
345 return $this->doAfterContent();
348 function doAfterContent()
350 global $wgUser, $wgOut, $wgLang;
351 $fname = "Skin::doAfterContent";
352 wfProfileIn( $fname );
353 wfProfileIn( "$fname-1" );
355 $s = "\n</div><br clear=all>\n";
356 $s .= "\n<div id='footer'>";
357 $s .= "<table width='98%' border=0 cellspacing=0><tr>";
359 wfProfileOut( "$fname-1" );
360 wfProfileIn( "$fname-2" );
362 $qb = $this->qbSetting();
363 $shove = ($qb != 0);
364 $left = ($qb == 1 || $qb == 3);
365 if($wgLang->isRTL()) $left = !$left;
367 if ( $shove && $left ) { # Left
368 $s .= $this->getQuickbarCompensator();
370 wfProfileOut( "$fname-2" );
371 wfProfileIn( "$fname-3" );
372 $l = $wgLang->isRTL() ? "right" : "left";
373 $s .= "<td class='bottom' align='$l' valign='top'>";
375 $s .= $this->bottomLinks();
376 $s .= "\n<br>" . $this->mainPageLink()
377 . " | " . $this->aboutLink()
378 . " | " . $this->specialLink( "recentchanges" )
379 . " | " . $this->searchForm()
380 . "<br>" . $this->pageStats();
382 $s .= "</td>";
383 if ( $shove && !$left ) { # Right
384 $s .= $this->getQuickbarCompensator();
386 $s .= "</tr></table>\n</div>\n</div>\n";
388 wfProfileOut( "$fname-3" );
389 wfProfileIn( "$fname-4" );
390 if ( 0 != $qb ) { $s .= $this->quickBar(); }
391 wfProfileOut( "$fname-4" );
392 wfProfileOut( $fname );
393 return $s;
396 function pageTitleLinks()
398 global $wgOut, $wgTitle, $oldid, $action, $diff, $wgUser, $wgLang, $wgUseApproval ;
400 $s = $this->printableLink();
402 if ( $wgOut->isArticle() ) {
403 if ( $wgTitle->getNamespace() == Namespace::getImage() ) {
404 $name = $wgTitle->getDBkey();
405 $link = wfEscapeHTML( wfImageUrl( $name ) );
406 $style = $this->getInternalLinkAttributes( $link, $name );
407 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>";
409 # This will show the "Approve" link if $wgUseApproval=true;
410 if ( isset ( $wgUseApproval ) && $wgUseApproval )
412 $t = $wgTitle->getDBkey();
413 $name = "Approve this article" ;
414 $link = "http://test.wikipedia.org/w/magnus/wiki.phtml?title={$t}&action=submit&doit=1" ;
415 #wfEscapeHTML( wfImageUrl( $name ) );
416 $style = $this->getExternalLinkAttributes( $link, $name );
417 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>" ;
419 if ( "history" == $action || isset( $diff ) || isset( $oldid ) ) {
420 $s .= " | " . $this->makeKnownLink( $wgTitle->getPrefixedText(),
421 wfMsg( "currentrev" ) );
424 if ( $wgUser->getNewtalk() ) {
425 # do not show "You have new messages" text when we are viewing our
426 # own talk page
428 if(!(strcmp($wgTitle->getText(),$wgUser->getName()) == 0 &&
429 $wgTitle->getNamespace()==Namespace::getTalk(Namespace::getUser()))) {
430 $n =$wgUser->getName();
431 $tl = $this->makeKnownLink( $wgLang->getNsText(
432 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
433 wfMsg("newmessageslink") );
434 $s.=" | <strong>". wfMsg( "newmessages", $tl ) . "</strong>";
437 if( $wgUser->isSysop() &&
438 (($wgTitle->getArticleId() == 0) || ($action == "history")) &&
439 ($n = $wgTitle->isDeleted() ) ) {
440 $s .= " | " . wfMsg( "thisisdeleted",
441 $this->makeKnownLink(
442 $wgLang->SpecialPage( "Undelete/" . $wgTitle->getPrefixedDBkey() ),
443 wfMsg( "restorelink", $n ) ) );
445 return $s;
448 function printableLink()
450 global $wgOut, $wgTitle, $oldid, $action;
452 $q = "";
453 foreach( $_GET as $var => $val ) {
454 if( $var != "title" && $var != "printable" )
455 $q .= urlencode( $var ) . "=" . urlencode( $val );
457 if( !empty( $q ) ) $q .= "&";
459 $s = $this->makeKnownLink( $wgTitle->getPrefixedText(),
460 WfMsg( "printableversion" ), "{$q}printable=yes" );
461 return $s;
464 function pageTitle()
466 global $wgOut, $wgTitle, $wgUser;
468 $s = "<h1 class='pagetitle'>" . $wgOut->getPageTitle() . "</h1>";
469 if($wgUser->getOption("editsectiononrightclick") && $wgTitle->userCanEdit()) { $s=$this->editSectionScript(0,$s);}
470 return $s;
473 function pageSubtitle()
475 global $wgOut,$wgTitle,$wgNamespacesWithSubpages;
477 $sub = $wgOut->getSubtitle();
478 if ( "" == $sub ) {
479 global $wgExtraSubtitle;
480 $sub = wfMsg( "fromwikipedia" ) . $wgExtraSubtitle;
482 if($wgOut->isArticle() && $wgNamespacesWithSubpages[$wgTitle->getNamespace()]) {
483 $ptext=$wgTitle->getPrefixedText();
484 if(preg_match("/\//",$ptext)) {
485 $sub.="</p><p class='subpages'>";
486 $links=explode("/",$ptext);
487 $c=0;
488 $growinglink="";
489 foreach($links as $link) {
490 $c++;
491 if ($c<count($links)) {
492 $growinglink .= $link;
493 $getlink = $this->makeLink( $growinglink, $link );
494 if(preg_match("/class='new'/i",$getlink)) { break; } # this is a hack, but it saves time
495 if ($c>1) {
496 $sub .= " | ";
497 } else {
498 $sub .="&lt; ";
500 $sub .= $getlink;
501 $growinglink.="/";
507 $s = "<p class='subtitle'>{$sub}\n";
508 return $s;
511 function nameAndLogin()
513 global $wgUser, $wgTitle, $wgLang, $wgShowIPinHeader;
515 $li = $wgLang->specialPage( "Userlogin" );
516 $lo = $wgLang->specialPage( "Userlogout" );
518 $s = "";
519 if ( 0 == $wgUser->getID() ) {
520 if( $wgShowIPinHeader ) {
521 $n = getenv( "REMOTE_ADDR" );
523 $tl = $this->makeKnownLink( $wgLang->getNsText(
524 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
525 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
527 $s .= $n . " (".$tl.")";
528 } else {
529 $s .= wfMsg("notloggedin");
532 $rt = $wgTitle->getPrefixedURL();
533 if ( 0 == strcasecmp( urlencode( $lo ), $rt ) ) {
534 $q = "";
535 } else { $q = "returnto={$rt}"; }
537 $s .= "\n<br>" . $this->makeKnownLink( $li,
538 wfMsg( "login" ), $q );
539 } else {
540 $n = $wgUser->getName();
541 $rt = $wgTitle->getPrefixedURL();
542 $tl = $this->makeKnownLink( $wgLang->getNsText(
543 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
544 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
546 $tl = " ({$tl})";
548 $s .= $this->makeKnownLink( $wgLang->getNsText(
549 Namespace::getUser() ) . ":{$n}", $n ) . "{$tl}<br>" .
550 $this->makeKnownLink( $lo, wfMsg( "logout" ),
551 "returnto={$rt}" ) . " | " .
552 $this->specialLink( "preferences" );
554 $s .= " | " . $this->makeKnownLink( wfMsg( "helppage" ),
555 wfMsg( "help" ) );
557 return $s;
560 function searchForm()
562 global $search;
564 $s = "<form name='search' class='inline' method=get action=\""
565 . wfLocalUrl( "" ) . "\">"
566 . "<input type=text name=\"search\" size=19 value=\""
567 . htmlspecialchars(substr($search,0,256)) . "\">\n"
568 . "<input type=submit name=\"go\" value=\"" . wfMsg ("go") . "\">&nbsp;"
569 . "<input type=submit value=\"" . wfMsg ("search") . "\"></form>";
571 return $s;
574 function topLinks()
576 global $wgOut;
577 $sep = " |\n";
579 $s = $this->mainPageLink() . $sep
580 . $this->specialLink( "recentchanges" );
582 if ( $wgOut->isArticle() ) {
583 $s .= $sep . $this->editThisPage()
584 . $sep . $this->historyLink();
586 # Many people don't like this dropdown box
587 #$s .= $sep . $this->specialPagesList();
589 return $s;
592 function bottomLinks()
594 global $wgOut, $wgUser, $wgTitle;
595 $sep = " |\n";
597 $s = "";
598 if ( $wgOut->isArticle() ) {
599 $s .= "<strong>" . $this->editThisPage() . "</strong>";
600 if ( 0 != $wgUser->getID() ) {
601 $s .= $sep . $this->watchThisPage();
603 $s .= $sep . $this->talkLink()
604 . $sep . $this->historyLink()
605 . $sep . $this->whatLinksHere()
606 . $sep . $this->watchPageLinksLink();
608 if ( $wgTitle->getNamespace() == Namespace::getUser()
609 || $wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser()) )
612 $id=User::idFromName($wgTitle->getText());
613 $ip=User::isIP($wgTitle->getText());
615 if($id || $ip) { # both anons and non-anons have contri list
616 $s .= $sep . $this->userContribsLink();
618 if ( 0 != $wgUser->getID() ) { # show only to signed in users
619 if($id) { # can only email non-anons
620 $s .= $sep . $this->emailUserLink();
624 if ( $wgUser->isSysop() && $wgTitle->getArticleId() ) {
625 $s .= "\n<br>" . $this->deleteThisPage() .
626 $sep . $this->protectThisPage() .
627 $sep . $this->moveThisPage();
629 $s .= "<br>\n" . $this->otherLanguages();
631 return $s;
634 function pageStats()
636 global $wgOut, $wgLang, $wgArticle;
637 global $oldid, $diff, $wgDisableCounters;
639 if ( ! $wgOut->isArticle() ) { return ""; }
640 if ( isset( $oldid ) || isset( $diff ) ) { return ""; }
641 if ( 0 == $wgArticle->getID() ) { return ""; }
643 if ( $wgDisableCounters ) {
644 $s = "";
645 } else {
646 $count = $wgArticle->getCount();
647 $s = wfMsg( "viewcount", $count );
649 $s .= $this->lastModified();
650 $s .= " " . wfMsg( "gnunote" );
651 return "<span id='pagestats'>{$s}</span>";
654 function lastModified()
656 global $wgLang, $wgArticle;
658 $d = $wgLang->timeanddate( $wgArticle->getTimestamp(), true );
659 $s = " " . wfMsg( "lastmodified", $d );
660 return $s;
663 function logoText( $align = "" )
665 if ( "" != $align ) { $a = " align='{$align}'"; }
666 else { $a = ""; }
668 $mp = wfMsg( "mainpage" );
669 $s = "<a href=\"" . wfLocalUrlE( urlencode( $mp ) )
670 . "\"><img{$a} border=0 src=\""
671 . $this->getLogo() . "\" alt=\"" . "[{$mp}]\"></a>";
672 return $s;
675 function quickBar()
677 global $wgOut, $wgTitle, $wgUser, $action, $wgLang;
678 global $wpPreview;
679 $fname = "Skin::quickBar";
680 wfProfileIn( $fname );
682 $tns=$wgTitle->getNamespace();
684 $s = "\n<div id='quickbar'>";
685 $s .= "\n" . $this->logoText() . "\n<hr class='sep'>";
687 $sep = "\n<br>";
688 $s .= $this->mainPageLink()
689 . $sep . $this->specialLink( "recentchanges" )
690 . $sep . $this->specialLink( "randompage" );
691 if ($wgUser->getID()) {
692 $s.= $sep . $this->specialLink( "watchlist" ) ;
693 $s .= $sep .$this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
694 wfMsg( "mycontris" ), "target=" . wfUrlencode($wgUser->getName() ) );
697 // only show watchlist link if logged in
698 if ( wfMsg ( "currentevents" ) != "-" ) $s .= $sep . $this->makeKnownLink( wfMsg( "currentevents" ), "" ) ;
699 $s .= "\n<br><hr class='sep'>";
700 $articleExists = $wgTitle->getArticleId();
701 if ( $wgOut->isArticle() || $action =="edit" || $action =="history" || $wpPreview) {
702 if($wgOut->isArticle()) {
703 $s .= "<strong>" . $this->editThisPage() . "</strong>";
704 } else { # backlink to the article in edit or history mode
705 if($articleExists){ # no backlink if no article
706 switch($tns) {
707 case 0:
708 $text = wfMsg("articlepage");
709 break;
710 case 1:
711 $text = wfMsg("viewtalkpage");
712 break;
713 case 2:
714 $text = wfMsg("userpage");
715 break;
716 case 3:
717 $text = wfMsg("viewtalkpage");
718 break;
719 case 4:
720 $text = wfMsg("wikipediapage");
721 break;
722 case 5:
723 $text = wfMsg("viewtalkpage");
724 break;
725 case 6:
726 $text = wfMsg("imagepage");
727 break;
728 case 7:
729 $text = wfMsg("viewtalkpage");
730 break;
731 default:
732 $text= wfMsg("articlepage");
735 $link = $wgTitle->getText();
736 if ($nstext = $wgLang->getNsText($tns) ) { # add namespace if necessary
737 $link = $nstext . ":" . $link ;
740 $s .= $this->makeLink( $link, $text );
741 } elseif( $wgTitle->getNamespace() != Namespace::getSpecial() ) {
742 # we just throw in a "New page" text to tell the user that he's in edit mode,
743 # and to avoid messing with the separator that is prepended to the next item
744 $s .= "<strong>" . wfMsg("newpage") . "</strong>";
750 if( $tns%2 && $action!="edit" && !$wpPreview) {
751 $s.="<br>".$this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg("postcomment"),"action=edit&section=new");
755 watching could cause problems in edit mode:
756 if user edits article, then loads "watch this article" in background and then saves
757 article with "Watch this article" checkbox disabled, the article is transparently
758 unwatched. Therefore we do not show the "Watch this page" link in edit mode
760 if ( 0 != $wgUser->getID() && $articleExists) {
761 if($action!="edit" && $action!="history" &&
762 $action != "submit" )
764 $s .= $sep . $this->watchThisPage();
766 if ( $wgTitle->userCanEdit() )
767 $s .= $sep . $this->moveThisPage();
769 if ( $wgUser->isSysop() and $articleExists ) {
770 $s .= $sep . $this->deleteThisPage() .
771 $sep . $this->protectThisPage();
773 $s .= $sep . $this->talkLink();
774 if ($articleExists && $action !="history") {
775 $s .= $sep . $this->historyLink();
777 $s.=$sep . $this->whatLinksHere();
779 if($wgOut->isArticle()) {
780 $s .= $sep . $this->watchPageLinksLink();
783 if ( Namespace::getUser() == $wgTitle->getNamespace()
784 || $wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser())
787 $id=User::idFromName($wgTitle->getText());
788 $ip=User::isIP($wgTitle->getText());
790 if($id||$ip) {
791 $s .= $sep . $this->userContribsLink();
793 if ( 0 != $wgUser->getID() ) {
794 if($id) { # can only email real users
795 $s .= $sep . $this->emailUserLink();
799 $s .= "\n<br><hr class='sep'>";
802 if ( 0 != $wgUser->getID() ) {
803 $s .= $this->specialLink( "upload" ) . $sep;
805 $s .= $this->specialLink( "specialpages" )
806 . $sep . $this->bugReportsLink();
808 global $wgSiteSupportPage;
809 if( $wgSiteSupportPage ) {
810 $s .= "\n<br><a href=\"" . htmlspecialchars( $wgSiteSupportPage ) .
811 "\" class=\"internal\">" . wfMsg( "sitesupport" ) . "</a>";
814 $s .= "\n<br></div>\n";
815 wfProfileOut( $fname );
816 return $s;
819 function specialPagesList()
821 global $wgUser, $wgOut, $wgLang, $wgServer, $wgRedirectScript;
822 $a = array();
824 $validSP = $wgLang->getValidSpecialPages();
826 foreach ( $validSP as $name => $desc ) {
827 if ( "" == $desc ) { continue; }
828 $a[$name] = $desc;
830 if ( $wgUser->isSysop() )
832 $sysopSP = $wgLang->getSysopSpecialPages();
834 foreach ( $sysopSP as $name => $desc ) {
835 if ( "" == $desc ) { continue; }
836 $a[$name] = $desc ;
839 if ( $wgUser->isDeveloper() )
841 $devSP = $wgLang->getDeveloperSpecialPages();
843 foreach ( $devSP as $name => $desc ) {
844 if ( "" == $desc ) { continue; }
845 $a[$name] = $desc ;
848 $go = wfMsg( "go" );
849 $sp = wfMsg( "specialpages" );
850 $spp = $wgLang->specialPage( "Specialpages" );
852 $s = "<form id=\"specialpages\" method=\"get\" class=\"inline\" " .
853 "action=\"{$wgServer}{$wgRedirectScript}\">\n";
854 $s .= "<select name=\"wpDropdown\">\n";
855 $s .= "<option value=\"{$spp}\">{$sp}</option>\n";
857 foreach ( $a as $name => $desc ) {
858 $p = $wgLang->specialPage( $name );
859 $s .= "<option value=\"{$p}\">{$desc}</option>\n";
861 $s .= "</select>\n";
862 $s .= "<input type=submit value=\"{$go}\" name=redirect>\n";
863 $s .= "</form>\n";
864 return $s;
867 function mainPageLink()
869 $mp = wfMsg( "mainpage" );
870 $s = $this->makeKnownLink( $mp, $mp );
871 return $s;
874 function copyrightLink()
876 $s = $this->makeKnownLink( wfMsg( "copyrightpage" ),
877 wfMsg( "copyrightpagename" ) );
878 return $s;
881 function aboutLink()
883 $s = $this->makeKnownLink( wfMsg( "aboutpage" ),
884 wfMsg( "aboutwikipedia" ) );
885 return $s;
888 function editThisPage()
890 global $wgOut, $wgTitle, $oldid, $redirect, $diff;
892 if ( ! $wgOut->isArticle() || $diff ) {
893 $s = wfMsg( "protectedpage" );
894 } else if ( $wgTitle->userCanEdit() ) {
895 $n = $wgTitle->getPrefixedText();
896 $t = wfMsg( "editthispage" );
897 $oid = $red = "";
899 if ( $redirect ) { $red = "&redirect={$redirect}"; }
900 if ( $oldid && ! isset( $diff ) ) {
901 $oid = "&oldid={$oldid}";
903 $s = $this->makeKnownLink( $n, $t, "action=edit{$oid}{$red}" );
904 } else {
905 $s = wfMsg( "protectedpage" );
907 return $s;
910 function deleteThisPage()
912 global $wgUser, $wgOut, $wgTitle, $diff;
914 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
915 $n = $wgTitle->getPrefixedText();
916 $t = wfMsg( "deletethispage" );
918 $s = $this->makeKnownLink( $n, $t, "action=delete" );
919 } else {
920 $s = "";
922 return $s;
925 function protectThisPage()
927 global $wgUser, $wgOut, $wgTitle, $diff;
929 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
930 $n = $wgTitle->getPrefixedText();
932 if ( $wgTitle->isProtected() ) {
933 $t = wfMsg( "unprotectthispage" );
934 $q = "action=unprotect";
935 } else {
936 $t = wfMsg( "protectthispage" );
937 $q = "action=protect";
939 $s = $this->makeKnownLink( $n, $t, $q );
940 } else {
941 $s = "";
943 return $s;
946 function watchThisPage()
948 global $wgUser, $wgOut, $wgTitle, $diff;
950 if ( $wgOut->isArticle() && ( ! $diff ) ) {
951 $n = $wgTitle->getPrefixedText();
953 if ( $wgTitle->userIsWatching() ) {
954 $t = wfMsg( "unwatchthispage" );
955 $q = "action=unwatch";
956 } else {
957 $t = wfMsg( "watchthispage" );
958 $q = "action=watch";
960 $s = $this->makeKnownLink( $n, $t, $q );
961 } else {
962 $s = wfMsg( "notanarticle" );
964 return $s;
967 function moveThisPage()
969 global $wgTitle, $wgLang;
971 if ( $wgTitle->userCanEdit() ) {
972 $s = $this->makeKnownLink( $wgLang->specialPage( "Movepage" ),
973 wfMsg( "movethispage" ), "target=" . $wgTitle->getPrefixedURL() );
974 } // no message if page is protected - would be redundant
975 return $s;
978 function historyLink()
980 global $wgTitle;
982 $s = $this->makeKnownLink( $wgTitle->getPrefixedText(),
983 wfMsg( "history" ), "action=history" );
984 return $s;
987 function whatLinksHere()
989 global $wgTitle, $wgLang;
991 $s = $this->makeKnownLink( $wgLang->specialPage( "Whatlinkshere" ),
992 wfMsg( "whatlinkshere" ), "target=" . $wgTitle->getPrefixedURL() );
993 return $s;
996 function userContribsLink()
998 global $wgTitle, $wgLang;
1000 $s = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
1001 wfMsg( "contributions" ), "target=" . $wgTitle->getURL() );
1002 return $s;
1005 function emailUserLink()
1007 global $wgTitle, $wgLang;
1009 $s = $this->makeKnownLink( $wgLang->specialPage( "Emailuser" ),
1010 wfMsg( "emailuser" ), "target=" . $wgTitle->getURL() );
1011 return $s;
1014 function watchPageLinksLink()
1016 global $wgOut, $wgTitle, $wgLang;
1018 if ( ! $wgOut->isArticle() ) {
1019 $s = "(" . wfMsg( "notanarticle" ) . ")";
1020 } else {
1021 $s = $this->makeKnownLink( $wgLang->specialPage(
1022 "Recentchangeslinked" ), wfMsg( "recentchangeslinked" ),
1023 "target=" . $wgTitle->getPrefixedURL() );
1025 return $s;
1028 function otherLanguages()
1030 global $wgOut, $wgLang, $wgTitle;
1032 $a = $wgOut->getLanguageLinks();
1033 # TEST THIS @@@
1034 if ( 0 == count( $a ) ) {
1035 if ( !$wgUseNewInterlanguage ) return "";
1036 $ns = $wgLang->getNsIndex ( $wgTitle->getNamespace () ) ;
1037 if ( $ns != 0 AND $ns != 1 ) return "" ;
1038 $pn = "Intl" ;
1039 $x = "mode=addlink&xt=".$wgTitle->getDBkey() ;
1040 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1041 wfMsg( "intl" ) , $x );
1044 if ( !$wgUseNewInterlanguage ) {
1045 $s = wfMsg( "otherlanguages" ) . ": ";
1046 } else {
1047 global $wgLanguageCode ;
1048 $x = "mode=zoom&xt=".$wgTitle->getDBkey() ;
1049 $x .= "&xl=".$wgLanguageCode ;
1050 $s = $this->makeKnownLink( $wgLang->specialPage( "Intl" ),
1051 wfMsg( "otherlanguages" ) , $x ) . ": " ;
1054 $s = wfMsg( "otherlanguages" ) . ": ";
1055 $first = true;
1056 if($wgLang->isRTL()) $s .= "<span dir='LTR'>";
1057 foreach( $a as $l ) {
1058 if ( ! $first ) { $s .= " | "; }
1059 $first = false;
1061 $nt = Title::newFromText( $l );
1062 $url = $nt->getFullURL();
1063 $text = $wgLang->getLanguageName( $nt->getInterwiki() );
1065 if ( "" == $text ) { $text = $l; }
1066 $style = $this->getExternalLinkAttributes( $l, $text );
1067 $s .= "<a href=\"{$url}\"{$style}>{$text}</a>";
1069 if($wgLang->isRTL()) $s .= "</span>";
1070 return $s;
1073 function bugReportsLink()
1075 $s = $this->makeKnownLink( wfMsg( "bugreportspage" ),
1076 wfMsg( "bugreports" ) );
1077 return $s;
1080 function dateLink()
1082 global $wgLinkCache;
1083 $t1 = Title::newFromText( gmdate( "F j" ) );
1084 $t2 = Title::newFromText( gmdate( "Y" ) );
1086 $wgLinkCache->suspend();
1087 $id = $t1->getArticleID();
1088 $wgLinkCache->resume();
1090 if ( 0 == $id ) {
1091 $s = $this->makeBrokenLink( $t1->getText() );
1092 } else {
1093 $s = $this->makeKnownLink( $t1->getText() );
1095 $s .= ", ";
1097 $wgLinkCache->suspend();
1098 $id = $t2->getArticleID();
1099 $wgLinkCache->resume();
1101 if ( 0 == $id ) {
1102 $s .= $this->makeBrokenLink( $t2->getText() );
1103 } else {
1104 $s .= $this->makeKnownLink( $t2->getText() );
1106 return $s;
1109 function talkLink()
1111 global $wgLang, $wgTitle, $wgLinkCache;
1113 $tns = $wgTitle->getNamespace();
1114 if ( -1 == $tns ) { return ""; }
1116 $pn = $wgTitle->getText();
1117 $tp = wfMsg( "talkpage" );
1118 if ( Namespace::isTalk( $tns ) ) {
1119 $lns = Namespace::getSubject( $tns );
1120 switch($tns) {
1121 case 1:
1122 $text = wfMsg("articlepage");
1123 break;
1124 case 3:
1125 $text = wfMsg("userpage");
1126 break;
1127 case 5:
1128 $text = wfMsg("wikipediapage");
1129 break;
1130 case 7:
1131 $text = wfMsg("imagepage");
1132 break;
1133 default:
1134 $text= wfMsg("articlepage");
1136 } else {
1138 $lns = Namespace::getTalk( $tns );
1139 $text=$tp;
1141 $n = $wgLang->getNsText( $lns );
1142 if ( "" == $n ) { $link = $pn; }
1143 else { $link = "{$n}:{$pn}"; }
1145 $wgLinkCache->suspend();
1146 $s = $this->makeLink( $link, $text );
1147 $wgLinkCache->resume();
1149 return $s;
1152 function commentLink()
1154 global $wgLang, $wgTitle, $wgLinkCache;
1156 $tns = $wgTitle->getNamespace();
1157 if ( -1 == $tns ) { return ""; }
1159 $lns = ( Namespace::isTalk( $tns ) ) ? $tns : Namespace::getTalk( $tns );
1161 # assert Namespace::isTalk( $lns )
1163 $n = $wgLang->getNsText( $lns );
1164 $pn = $wgTitle->getText();
1166 $link = "{$n}:{$pn}";
1168 $wgLinkCache->suspend();
1169 $s = $this->makeKnownLink($link, wfMsg("postcomment"), "action=edit&section=new");
1170 $wgLinkCache->resume();
1172 return $s;
1175 # After all the page content is transformed into HTML, it makes
1176 # a final pass through here for things like table backgrounds.
1178 function transformContent( $text )
1180 return $text;
1183 # Note: This function MUST call getArticleID() on the link,
1184 # otherwise the cache won't get updated properly. See LINKCACHE.DOC.
1186 function makeLink( $title, $text = "", $query = "", $trail = "" ) {
1187 wfProfileIn( "Skin::makeLink" );
1188 $nt = Title::newFromText( $title );
1189 if ($nt) {
1190 $result = $this->makeLinkObj( Title::newFromText( $title ), $text, $query, $trail );
1191 } else {
1192 wfDebug( "Invalid title passed to Skin::makeLink(): \"$title\"\n" );
1193 $result = $text == "" ? $title : $text;
1196 wfProfileOut( "Skin::makeLink" );
1197 return $result;
1200 function makeKnownLink( $title, $text = "", $query = "", $trail = "" ) {
1201 $nt = Title::newFromText( $title );
1202 if ($nt) {
1203 return $this->makeKnownLinkObj( Title::newFromText( $title ), $text, $query, $trail );
1204 } else {
1205 wfDebug( "Invalid title passed to Skin::makeKnownLink(): \"$title\"\n" );
1206 return $text == "" ? $title : $text;
1210 function makeBrokenLink( $title, $text = "", $query = "", $trail = "" ) {
1211 $nt = Title::newFromText( $title );
1212 if ($nt) {
1213 return $this->makeBrokenLinkObj( Title::newFromText( $title ), $text, $query, $trail );
1214 } else {
1215 wfDebug( "Invalid title passed to Skin::makeBrokenLink(): \"$title\"\n" );
1216 return $text == "" ? $title : $text;
1220 function makeStubLink( $title, $text = "", $query = "", $trail = "" ) {
1221 $nt = Title::newFromText( $title );
1222 if ($nt) {
1223 return $this->makeStubLinkObj( Title::newFromText( $title ), $text, $query, $trail );
1224 } else {
1225 wfDebug( "Invalid title passed to Skin::makeStubLink(): \"$title\"\n" );
1226 return $text == "" ? $title : $text;
1230 # Pass a title object, not a title string
1231 function makeLinkObj( &$nt, $text= "", $query = "", $trail = "" )
1233 global $wgOut, $wgUser;
1234 if ( $nt->isExternal() ) {
1235 $u = $nt->getFullURL();
1236 if ( "" == $text ) { $text = $nt->getPrefixedText(); }
1237 $style = $this->getExternalLinkAttributes( $link, $text );
1239 $inside = "";
1240 if ( "" != $trail ) {
1241 if ( preg_match( "/^([a-z]+)(.*)$$/sD", $trail, $m ) ) {
1242 $inside = $m[1];
1243 $trail = $m[2];
1246 $retVal = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1247 } elseif ( 0 == $nt->getNamespace() && "" == $nt->getText() ) {
1248 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail );
1249 } elseif ( ( -1 == $nt->getNamespace() ) ||
1250 ( Namespace::getImage() == $nt->getNamespace() ) ) {
1251 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail );
1252 } else {
1253 $aid = $nt->getArticleID() ;
1254 if ( 0 == $aid ) {
1255 $retVal = $this->makeBrokenLinkObj( $nt, $text, $query, $trail );
1256 } else {
1257 $threshold = $wgUser->getOption("stubthreshold") ;
1258 if ( $threshold > 0 ) {
1259 $res = wfQuery ( "SELECT HIGH_PRIORITY length(cur_text) AS x, cur_namespace, cur_is_redirect FROM cur WHERE cur_id='{$aid}'", DB_READ ) ;
1261 if ( wfNumRows( $res ) > 0 ) {
1262 $s = wfFetchObject( $res );
1263 $size = $s->x;
1264 if ( $s->cur_is_redirect OR $s->cur_namespace != 0 ) {
1265 $size = $threshold*2 ; # Really big
1267 wfFreeResult( $res );
1268 } else {
1269 $size = $threshold*2 ; # Really big
1271 } else {
1272 $size = 1 ;
1274 if ( $size < $threshold ) {
1275 $retVal = $this->makeStubLinkObj( $nt, $text, $query, $trail );
1276 } else {
1277 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail );
1281 return $retVal;
1284 # Pass a title object, not a title string
1285 function makeKnownLinkObj( &$nt, $text = "", $query = "", $trail = "" )
1287 global $wgOut, $wgTitle;
1289 $fname = "Skin::makeKnownLinkObj";
1290 wfProfileIn( $fname );
1292 $link = $nt->getPrefixedURL();
1294 if ( "" == $link ) {
1295 $u = "";
1296 if ( "" == $text ) { $text = $nt->getFragment(); }
1297 } else {
1298 $u = wfLocalUrlE( $link, $query );
1300 if ( "" != $nt->getFragment() ) {
1301 $u .= "#" . wfEscapeHTML( $nt->getFragment() );
1303 if ( "" == $text ) { $text = $nt->getPrefixedText(); }
1304 $style = $this->getInternalLinkAttributesObj( $nt, $text );
1306 $inside = "";
1307 if ( "" != $trail ) {
1308 if ( preg_match( wfMsg("linktrail"), $trail, $m ) ) {
1309 $inside = $m[1];
1310 $trail = $m[2];
1313 $r = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1314 wfProfileOut( $fname );
1315 return $r;
1318 # Pass a title object, not a title string
1319 function makeBrokenLinkObj( &$nt, $text = "", $query = "", $trail = "" )
1321 global $wgOut, $wgUser;
1323 $fname = "Skin::makeBrokenLinkObj";
1324 wfProfileIn( $fname );
1326 $link = $nt->getPrefixedURL();
1328 if ( "" == $query ) { $q = "action=edit"; }
1329 else { $q = "action=edit&{$query}"; }
1330 $u = wfLocalUrlE( $link, $q );
1332 if ( "" == $text ) { $text = $nt->getPrefixedText(); }
1333 $style = $this->getInternalLinkAttributesObj( $nt, $text, "yes" );
1335 $inside = "";
1336 if ( "" != $trail ) {
1337 if ( preg_match( wfMsg("linktrail"), $trail, $m ) ) {
1338 $inside = $m[1];
1339 $trail = $m[2];
1342 if ( $wgOut->isPrintable() ||
1343 ( 1 == $wgUser->getOption( "highlightbroken" ) ) ) {
1344 $s = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1345 } else {
1346 $s = "{$text}{$inside}<a href=\"{$u}\"{$style}>?</a>{$trail}";
1349 wfProfileOut( $fname );
1350 return $s;
1353 # Pass a title object, not a title string
1354 function makeStubLinkObj( &$nt, $text = "", $query = "", $trail = "" )
1356 global $wgOut, $wgUser;
1358 $link = $nt->getPrefixedURL();
1360 $u = wfLocalUrlE( $link, $query );
1362 if ( "" == $text ) { $text = $nt->getPrefixedText(); }
1363 $style = $this->getInternalLinkAttributesObj( $nt, $text, "stub" );
1365 $inside = "";
1366 if ( "" != $trail ) {
1367 if ( preg_match( wfMsg("linktrail"), $trail, $m ) ) {
1368 $inside = $m[1];
1369 $trail = $m[2];
1372 if ( $wgOut->isPrintable() ||
1373 ( 1 == $wgUser->getOption( "highlightbroken" ) ) ) {
1374 $s = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1375 } else {
1376 $s = "{$text}{$inside}<a href=\"{$u}\"{$style}>!</a>{$trail}";
1378 return $s;
1381 function fnamePart( $url )
1383 $basename = strrchr( $url, "/" );
1384 if ( false === $basename ) { $basename = $url; }
1385 else { $basename = substr( $basename, 1 ); }
1386 return wfEscapeHTML( $basename );
1389 function makeImage( $url, $alt = "" )
1391 global $wgOut;
1393 if ( "" == $alt ) { $alt = $this->fnamePart( $url ); }
1394 $s = "<img src=\"{$url}\" alt=\"{$alt}\">";
1395 return $s;
1398 function makeImageLink( $name, $url, $alt = "" ) {
1399 $nt = Title::makeTitle( Namespace::getImage(), $name );
1400 return $this->makeImageLinkObj( $nt, $alt );
1403 function makeImageLinkObj( $nt, $alt = "" ) {
1404 $link = $nt->getPrefixedURL();
1405 $name = $nt->getDBKey();
1406 $url = wfImageUrl( $name );
1407 if ( empty( $alt ) ) {
1408 $alt = preg_replace( '/\.(.+?)^/', '', $name );
1410 $alt = htmlspecialchars( $alt );
1412 $u = wfLocalUrlE( $link );
1413 $s = "<a href=\"{$u}\" class='image' title=\"{$alt}\">" .
1414 "<img border=\"0\" src=\"{$url}\" alt=\"{$alt}\"></a>";
1415 return $s;
1418 function makeMediaLink( $name, $url, $alt = "" ) {
1419 $nt = Title::makeTitle( Namespace::getMedia(), $name );
1420 return $this->makeMediaLinkObj( $nt, $alt );
1423 function makeMediaLinkObj( $nt, $alt = "" )
1425 $name = $nt->getDBKey();
1426 $url = wfImageUrl( $name );
1427 if ( empty( $alt ) ) {
1428 $alt = preg_replace( '/\.(.+?)^/', '', $name );
1431 $u = htmlspecialchars( $url );
1432 $s = "<a href=\"{$u}\" class='internal' title=\"{$alt}\">{$alt}</a>";
1433 return $s;
1436 function specialLink( $name, $key = "" )
1438 global $wgLang;
1440 if ( "" == $key ) { $key = strtolower( $name ); }
1441 $pn = $wgLang->ucfirst( $name );
1442 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1443 wfMsg( $key ) );
1446 # Called by history lists and recent changes
1449 function beginRecentChangesList()
1451 $rc_cache = array() ;
1452 $rccc = 0 ;
1453 $this->lastdate = "";
1454 return "";
1457 function beginHistoryList()
1459 $this->lastdate = $this->lastline = "";
1460 $s = "\n<p>" . wfMsg( "histlegend" ) . "\n<ul>";
1461 return $s;
1464 function beginImageHistoryList()
1466 $s = "\n<h2>" . wfMsg( "imghistory" ) . "</h2>\n" .
1467 "<p>" . wfMsg( "imghistlegend" ) . "\n<ul>";
1468 return $s;
1471 function endRecentChangesList()
1473 $s = $this->recentChangesBlock() ;
1474 $s .= "</ul>\n";
1475 return $s;
1478 function endHistoryList()
1480 $last = wfMsg( "last" );
1482 $s = preg_replace( "/!OLDID![0-9]+!/", $last, $this->lastline );
1483 $s .= "</ul>\n";
1484 return $s;
1487 function endImageHistoryList()
1489 $s = "</ul>\n";
1490 return $s;
1493 function historyLine( $ts, $u, $ut, $ns, $ttl, $oid, $c, $isminor )
1495 global $wgLang;
1497 $artname = Title::makeName( $ns, $ttl );
1498 $last = wfMsg( "last" );
1499 $cur = wfMsg( "cur" );
1500 $cr = wfMsg( "currentrev" );
1502 if ( $oid && $this->lastline ) {
1503 $ret = preg_replace( "/!OLDID!([0-9]+)!/", $this->makeKnownLink(
1504 $artname, $last, "diff=\\1&oldid={$oid}" ), $this->lastline );
1505 } else {
1506 $ret = "";
1508 $dt = $wgLang->timeanddate( $ts, true );
1510 if ( $oid ) { $q = "oldid={$oid}"; }
1511 else { $q = ""; }
1512 $link = $this->makeKnownLink( $artname, $dt, $q );
1514 if ( 0 == $u ) {
1515 $ul = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
1516 $ut, "target=" . $ut );
1517 } else {
1518 $ul = $this->makeLink( $wgLang->getNsText(
1519 Namespace::getUser() ) . ":{$ut}", $ut ); }
1521 $s = "<li>";
1522 if ( $oid ) {
1523 $curlink = $this->makeKnownLink( $artname, $cur,
1524 "diff=0&oldid={$oid}" );
1525 } else {
1526 $curlink = $cur;
1528 $s .= "({$curlink}) (!OLDID!{$oid}!) . .";
1530 $M = wfMsg( "minoreditletter" );
1531 if ( $isminor ) { $s .= " <strong>{$M}</strong>"; }
1532 $s .= " {$link} . . {$ul}";
1534 if ( "" != $c && "*" != $c ) { $s .= " <em>(" . wfEscapeHTML($c) . ")</em>"; }
1535 $s .= "</li>\n";
1537 $this->lastline = $s;
1538 return $ret;
1541 function recentChangesBlockLine ( $y ) {
1542 global $wgUploadPath ;
1544 $M = wfMsg( "minoreditletter" );
1545 $N = wfMsg( "newpageletter" );
1546 $r = "" ;
1547 $r .= "<img src='{$wgUploadPath}/Arr_.png' width=12 height=12 border=0>" ;
1548 $r .= "<tt>" ;
1549 if ( $y->isnew ) $r .= $N ;
1550 else $r .= "&nbsp;" ;
1551 if ( $y->isminor ) $r .= $M ;
1552 else $r .= "&nbsp;" ;
1553 $r .= " ".$y->timestamp." " ;
1554 $r .= "</tt>" ;
1555 $link = $y->link ;
1556 if ( $y->watched ) $link = "<strong>{$link}</strong>" ;
1557 $r .= $link ;
1559 $r .= " (" ;
1560 $r .= $y->curlink ;
1561 $r .= "; " ;
1562 $r .= $this->makeKnownLink( $y->secureName, wfMsg( "hist" ), "action=history" );
1564 $r .= ") . . ".$y->userlink ;
1565 $r .= $y->usertalklink ;
1566 if ( $y->usercomment != "" )
1567 $r .= " <em>(".wfEscapeHTML($y->usercomment).")</em>" ;
1568 $r .= "<br>\n" ;
1569 return $r ;
1572 function recentChangesBlockGroup ( $y ) {
1573 global $wgUploadPath ;
1575 $r = "" ;
1576 $M = wfMsg( "minoreditletter" );
1577 $N = wfMsg( "newpageletter" );
1578 $isnew = false ;
1579 $userlinks = array () ;
1580 foreach ( $y AS $x ) {
1581 $oldid = $x->diffid ;
1582 if ( $x->isnew ) $isnew = true ;
1583 $u = $x->userlink ;
1584 if ( !isset ( $userlinks[$u] ) ) $userlinks[$u] = 0 ;
1585 $userlinks[$u]++ ;
1588 krsort ( $userlinks ) ;
1589 asort ( $userlinks ) ;
1590 $users = array () ;
1591 $u = array_keys ( $userlinks ) ;
1592 foreach ( $u as $x ) {
1593 $z = $x ;
1594 if ( $userlinks[$x] > 1 ) $z .= " ({$userlinks[$x]}&times;)" ;
1595 array_push ( $users , $z ) ;
1597 $users = " <font size='-1'>[".implode("; ",$users)."]</font>" ;
1599 $e = $y ;
1600 $e = array_shift ( $e ) ;
1602 # Arrow
1603 $rci = "RCI{$this->rccc}" ;
1604 $rcl = "RCL{$this->rccc}" ;
1605 $rcm = "RCM{$this->rccc}" ;
1606 $tl = "<a href='javascript:toggleVisibility(\"{$rci}\",\"{$rcm}\",\"{$rcl}\")'>" ;
1607 $tl .= "<span id='{$rcm}'><img src='{$wgUploadPath}/Arr_r.png' width=12 height=12 border=0></span>" ;
1608 $tl .= "<span id='{$rcl}' style='display:none'><img src='{$wgUploadPath}/Arr_d.png' width=12 height=12 border=0></span>" ;
1609 $tl .= "</a>" ;
1610 $r .= $tl ;
1612 # Main line
1613 $r .= "<tt>" ;
1614 if ( $isnew ) $r .= $N ;
1615 else $r .= "&nbsp;" ;
1616 $r .= "&nbsp;" ; # Minor
1617 $r .= " ".$e->timestamp." " ;
1618 $r .= "</tt>" ;
1620 $link = $e->link ;
1621 if ( $e->watched ) $link = "<strong>{$link}</strong>" ;
1622 $r .= $link ;
1624 if ( !$e->islog ) {
1625 $r .= " (".count($y)." " ;
1626 if ( $isnew ) $r .= wfMsg("changes");
1627 else $r .= $this->makeKnownLink( $e->secureName , wfMsg("changes") , "diff=0&oldid=".$oldid ) ;
1628 $r .= "; " ;
1629 $r .= $this->makeKnownLink( $e->secureName, wfMsg( "history" ), "action=history" );
1630 $r .= ")" ;
1633 $r .= $users ;
1634 $r .= "<br>\n" ;
1636 # Sub-entries
1637 $r .= "<div id='{$rci}' style='display:none'>" ;
1638 foreach ( $y AS $x )
1640 $r .= "<img src='{$wgUploadPath}/Arr_.png' width=12 height=12 border=0>";
1641 $r .= "<tt>&nbsp; &nbsp; &nbsp; &nbsp;" ;
1642 if ( $x->isnew ) $r .= $N ;
1643 else $r .= "&nbsp;" ;
1644 if ( $x->isminor ) $r .= $M ;
1645 else $r .= "&nbsp;" ;
1646 $r .= "</tt>" ;
1648 $o = "" ;
1649 if ( $x->oldid != 0 ) $o = "oldid=".$x->oldid ;
1650 if ( $x->islog ) $link = $x->timestamp ;
1651 else $link = $this->makeKnownLink( $x->secureName, $x->timestamp , $o ) ;
1652 $link = "<tt>{$link}</tt>" ;
1655 $r .= $link ;
1656 $r .= " (" ;
1657 $r .= $x->curlink ;
1658 $r .= "; " ;
1659 $r .= $x->lastlink ;
1660 $r .= ") . . ".$x->userlink ;
1661 $r .= $x->usertalklink ;
1662 if ( $x->usercomment != "" )
1663 $r .= " <em>(".wfEscapeHTML($x->usercomment).")</em>" ;
1664 $r .= "<br>\n" ;
1666 $r .= "</div>\n" ;
1668 $this->rccc++ ;
1669 return $r ;
1672 function recentChangesBlock ()
1674 global $wgUploadPath ;
1675 if ( count ( $this->rc_cache ) == 0 ) return "" ;
1676 $k = array_keys ( $this->rc_cache ) ;
1677 foreach ( $k AS $x )
1679 $y = $this->rc_cache[$x] ;
1680 if ( count ( $y ) < 2 ) {
1681 $r .= $this->recentChangesBlockLine ( array_shift ( $y ) ) ;
1682 } else {
1683 $r .= $this->recentChangesBlockGroup ( $y ) ;
1687 return "<div align=left>{$r}</div>" ;
1690 function recentChangesLine( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched = false, $oldid = 0 , $diffid = 0 )
1692 global $wgUser ;
1693 $usenew = $wgUser->getOption( "usenewrc" );
1694 if ( $usenew )
1695 $r = $this->recentChangesLineNew ( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched , $oldid , $diffid ) ;
1696 else
1697 $r = $this->recentChangesLineOld ( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched , $oldid , $diffid ) ;
1698 return $r ;
1701 function recentChangesLineOld( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched = false, $oldid = 0, $diffid = 0 )
1703 global $wgTitle, $wgLang, $wgUser;
1705 $d = $wgLang->date( $ts, true);
1706 $s = "";
1707 if ( $d != $this->lastdate ) {
1708 if ( "" != $this->lastdate ) { $s .= "</ul>\n"; }
1709 $s .= "<h4>{$d}</h4>\n<ul>";
1710 $this->lastdate = $d;
1712 $h = $wgLang->time( $ts, true );
1713 $t = Title::makeName( $ns, $ttl );
1714 $clink = $this->makeKnownLink( $t , "" );
1715 $nt = Title::newFromText( $t );
1717 if ( $watched ) {
1718 $clink = "<strong>{$clink}</strong>";
1720 $hlink = $this->makeKnownLink( $t, wfMsg( "hist" ), "action=history" );
1721 if ( $isnew || $nt->isLog() ) {
1722 $dlink = wfMsg( "diff" );
1723 } else {
1724 $dlink = $this->makeKnownLink( $t, wfMsg( "diff" ),
1725 "diff={$oldid}&oldid={$diffid}" ); # Finagle's law
1727 if ( 0 == $u ) {
1728 $ul = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
1729 $ut, "target=" . $ut );
1730 } else {
1731 $ul = $this->makeLink( $wgLang->getNsText( Namespace::getUser() ) . ":{$ut}", $ut );
1734 $talkname=$wgLang->getNsText(Namespace::getTalk(0)); # use the shorter name
1735 global $wgDisableAnonTalk;
1736 if( 0 == $u && $wgDisableAnonTalk ) {
1737 $utl = "";
1738 } else {
1739 $utns=$wgLang->getNsText(Namespace::getTalk(Namespace::getUser()));
1740 $utl= $this->makeLink($utns . ":{$ut}", $talkname );
1742 $cr = wfMsg( "currentrev" );
1744 $s .= "<li> ({$dlink}) ({$hlink}) . .";
1745 $M = wfMsg( "minoreditletter" );
1746 $N = wfMsg( "newpageletter" );
1747 if ( $isminor ) { $s .= " <strong>{$M}</strong>"; }
1748 if ( $isnew ) { $s .= "<strong>{$N}</strong>"; }
1749 $s .= " {$clink}; {$h} . . {$ul}";
1751 $blink="";
1752 if ( ( 0 == $u ) && $wgUser->isSysop() ) {
1753 $blink = $this->makeKnownLink( $wgLang->specialPage(
1754 "Blockip" ), wfMsg( "blocklink" ), "ip={$ut}" );
1757 if($blink) {
1758 if($utl) $utl .= " | ";
1759 $utl .= $blink;
1761 if($utl) $s.=" ({$utl})";
1763 if ( "" != $c && "*" != $c ) {
1764 $s .= " <em>(" . wfEscapeHTML( $c ) . ")</em>";
1766 $s .= "</li>\n";
1768 return $s;
1771 function recentChangesLineNew( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched = false, $oldid = 0 , $diffid = 0 )
1773 global $wgTitle, $wgLang, $wgUser;
1775 $rc = new RecentChangesClass ;
1777 $d = $wgLang->date( $ts, true);
1778 $s = "";
1779 $ret = "" ;
1780 if ( $d != $this->lastdate ) {
1781 $ret = $this->recentChangesBlock () ;
1782 $this->rc_cache = array() ;
1783 $ret .= "<h4>{$d}</h4>\n";
1784 $this->lastdate = $d;
1786 $h = $wgLang->time( $ts, true );
1787 $t = Title::makeName( $ns, $ttl );
1788 $clink = $this->makeKnownLink( $t, "" ) ;
1789 if ( $oldid == 0 ) $c2link = $clink ;
1790 else $c2link = $this->makeKnownLink( $t, "" , "oldid={$oldid}" );
1791 $nt = Title::newFromText( $t );
1793 $rc->timestamp = $h ;
1794 $rc->oldid = $oldid ;
1795 $rc->diffid = $diffid ;
1796 $rc->watched = $watched ;
1797 $rc->isnew = $isnew ;
1798 $rc->isminor = $isminor ;
1799 $rc->secureName = $t ;
1800 $rc->displayName = $nt ;
1801 $rc->link = $clink ;
1802 $rc->usercomment = $c ;
1803 $rc->islog = $nt->isLog() ;
1805 if ( ( $isnew && $oldid == 0 ) || $nt->isLog() ) {
1806 $dlink = wfMsg( "cur" );
1807 } else {
1808 $dlink = $this->makeKnownLink( $t, wfMsg( "cur" ),
1809 "diff=0&oldid={$oldid}" );
1812 if ( $diffid == 0 || $nt->isLog() ) {
1813 $plink = wfMsg( "last" );
1814 } else {
1815 $plink = $this->makeKnownLink( $t, wfMsg( "last" ),
1816 "diff={$oldid}&oldid={$diffid}" );
1819 if ( 0 == $u ) {
1820 $ul = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
1821 $ut, "target=" . $ut );
1822 } else { $ul = $this->makeLink( $wgLang->getNsText(
1823 Namespace::getUser() ) . ":{$ut}", $ut ); }
1825 $rc->userlink = $ul ;
1826 $rc->lastlink = $plink ;
1827 $rc->curlink = $dlink ;
1829 $utns=$wgLang->getNsText(Namespace::getTalk(Namespace::getUser()));
1830 $talkname=$wgLang->getNsText(Namespace::getTalk(0)); # use the shorter name
1831 $utl= $this->makeLink($utns . ":{$ut}", $talkname );
1833 global $wgDisableAnonTalk;
1834 if ( ( 0 == $u ) && $wgUser->isSysop() ) {
1835 $blink = $this->makeKnownLink( $wgLang->specialPage(
1836 "Blockip" ), wfMsg( "blocklink" ), "ip={$ut}" );
1837 if( $wgDisableAnonTalk )
1838 $rc->usertalklink = " ({$blink})";
1839 else
1840 $rc->usertalklink = " ({$utl} | {$blink})";
1841 } else {
1842 if( $wgDisableAnonTalk && ($u == 0) )
1843 $rc->usertalklink = "";
1844 else
1845 $rc->usertalklink = " ({$utl})";
1848 if ( !isset ( $this->rc_cache[$t] ) ) $this->rc_cache[$t] = array() ;
1849 array_push ( $this->rc_cache[$t] , $rc ) ;
1850 return $ret;
1854 function imageHistoryLine( $iscur, $ts, $img, $u, $ut, $size, $c )
1856 global $wgUser, $wgLang, $wgTitle;
1858 $dt = $wgLang->timeanddate( $ts, true );
1859 $del = wfMsg( "deleteimg" );
1860 $cur = wfMsg( "cur" );
1862 if ( $iscur ) {
1863 $url = wfImageUrl( $img );
1864 $rlink = $cur;
1865 if ( $wgUser->isSysop() ) {
1866 $link = wfLocalUrlE( $wgTitle->getPrefixedText(), "image=" . $wgTitle->getURL() .
1867 "&action=delete" );
1868 $style = $this->getInternalLinkAttributes( $link, $del );
1870 $dlink = "<a href=\"{$link}\"{$style}>{$del}</a>";
1871 } else {
1872 $dlink = $del;
1874 } else {
1875 $url = wfEscapeHTML( wfImageArchiveUrl( $img ) );
1876 if( $wgUser->getID() != 0 ) {
1877 $rlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
1878 wfMsg( "revertimg" ), "action=revert&oldimage=" .
1879 urlencode( $img ) );
1880 $dlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
1881 $del, "action=delete&oldimage=" . urlencode( $img ) );
1882 } else {
1883 # Having live active links for non-logged in users
1884 # means that bots and spiders crawling our site can
1885 # inadvertently change content. Baaaad idea.
1886 $rlink = wfMsg( "revertimg" );
1887 $dlink = $del;
1890 if ( 0 == $u ) { $ul = $ut; }
1891 else { $ul = $this->makeLink( $wgLang->getNsText(
1892 Namespace::getUser() ) . ":{$ut}", $ut ); }
1894 $nb = wfMsg( "nbytes", $size );
1895 $style = $this->getInternalLinkAttributes( $url, $dt );
1897 $s = "<li> ({$dlink}) ({$rlink}) <a href=\"{$url}\"{$style}>{$dt}</a>"
1898 . " . . {$ul} ({$nb})";
1900 if ( "" != $c && "*" != $c ) {
1901 $s .= " <em>(" . wfEscapeHTML( $c ) . ")</em>";
1903 $s .= "</li>\n";
1904 return $s;
1907 function tocIndent($level) {
1909 while($level-->0) $rv.="<div style=\"margin-left:2em;\">\n";
1910 return $rv;
1914 function tocUnindent($level) {
1915 while($level-->0) $rv.="</div>\n";
1916 return $rv;
1919 // parameter level defines if we are on an indentation level
1920 function tocLine($anchor,$tocline,$level) {
1922 if($level) {
1924 return "<A CLASS=\"internal\" HREF=\"#".$anchor."\">".$tocline."</A><BR>\n";
1925 } else {
1927 return "<div style=\"margin-bottom:0px;\">\n".
1928 "<A CLASS=\"internal\" HREF=\"#".$anchor."\">".$tocline."</A><BR>\n".
1929 "</div>\n";
1934 function tocTable($toc) {
1935 // note to CSS fanatics: putting this in a div does not work -- div won't auto-expand
1936 global $printable;
1938 if (!$printable) {
1939 $hideline = " <script type='text/javascript'>showTocToggle(\"" . wfMsg("showtoc") . "\",\"" . wfMsg("hidetoc") . "\")</script>";
1941 return
1942 "<p><table border=\"0\" id=\"toc\"><tr><td align=\"center\">\n".
1943 "<b>".wfMsg("toc")."</b>" .
1944 $hideline .
1945 "</td></tr><tr id='tocinside'><td align=\"left\">\n".
1946 $toc."</td></tr></table><P>\n";
1949 # These two do not check for permissions: check $wgTitle->userCanEdit before calling them
1950 function editSectionScript($section,$head) {
1952 global $wgTitle,$wgUser,$oldid;
1953 if($oldid) return $head;
1954 $url = wfLocalUrlE(urlencode($wgTitle->getPrefixedText()),"action=edit&section=$section");
1955 return "<span onContextMenu='document.location=\"".$url."\";return false;'>{$head}</span>";
1958 function editSectionLink($section) {
1960 global $printable;
1961 global $wgTitle,$wgUser,$oldid;
1962 if($oldid) return "";
1963 if ($printable) return "";
1964 $editurl="&section={$section}";
1965 $url=$this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg("editsection"),"action=edit".$editurl);
1966 return "<div style=\"float:right;margin-left:5px;\"><small>[".$url."]</small></div>";
1971 include_once( "SkinStandard.php" );
1972 include_once( "SkinNostalgia.php" );
1973 include_once( "SkinCologneBlue.php" );
1975 #include_once( "SkinSmarty.php" );