Change behavior of toolbar in browsers not supporting document.selection:
[mediawiki.git] / includes / Skin.php
blobcd338b7abbcda1c8b948ed7fd7aaed764b2abccf
1 <?php
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"
11 if( $wgUseSmarty ) {
12 $wgValidSkinNames[] = "Smarty";
13 $wgValidSkinNames[] = "Montparnasse";
16 include_once( "RecentChange.php" );
18 # For some odd PHP bug, this function can't be part of a class
19 function getCategories ()
21 global $wgOut , $wgTitle , $wgUseCategoryMagic , $wgUser , $wgParser ;
22 if ( !isset ( $wgUseCategoryMagic ) || !$wgUseCategoryMagic ) return "" ;
23 if ( count ( $wgParser->mCategoryLinks ) == 0 ) return "" ;
24 if ( !$wgOut->isArticle() ) return "" ;
25 $sk = $wgUser->getSkin() ;
26 $s = "" ;
27 $s .= "\n<br>\n";
28 $s .= $sk->makeKnownLink ( "Special:Categories" , "Categories" , "article=".$wgTitle->getDBkey() ) ;
29 $t = implode ( " | " , $wgParser->mCategoryLinks ) ;
30 if ( $t != "" ) $s .= " : " ;
31 $s .= $t ;
32 return $s ;
35 class RCCacheEntry extends RecentChange
37 var $secureName, $link;
38 var $curlink , $lastlink , $usertalklink , $versionlink ;
39 var $userlink, $timestamp, $watched;
41 function newFromParent( $rc )
43 $rc2 = new RCCacheEntry;
44 $rc2->mAttribs = $rc->mAttribs;
45 $rc2->mExtra = $rc->mExtra;
46 return $rc2;
48 } ;
50 class Skin {
52 /* private */ var $lastdate, $lastline;
53 var $linktrail ; # linktrail regexp
54 var $rc_cache ; # Cache for Enhanced Recent Changes
55 var $rcCacheIndex ; # Recent Changes Cache Counter for visibility toggle
56 var $rcMoveIndex;
58 function Skin()
60 $this->linktrail = wfMsg("linktrail");
63 function getSkinNames()
65 global $wgValidSkinNames;
66 return $wgValidSkinNames;
69 function getStylesheet()
71 return "wikistandard.css";
74 function qbSetting()
76 global $wgOut, $wgUser;
78 if ( $wgOut->isQuickbarSuppressed() ) { return 0; }
79 $q = $wgUser->getOption( "quickbar" );
80 if ( "" == $q ) { $q = 0; }
81 return $q;
84 function initPage( &$out )
86 global $wgStyleSheetPath;
87 $fname = "Skin::initPage";
88 wfProfileIn( $fname );
90 $out->addLink( "shortcut icon", "", "/favicon.ico" );
92 wfProfileOut( $fname );
95 function outputPage( &$out ) {
96 global $wgDebugComments;
98 wfProfileIn( "Skin::outputPage" );
99 $this->initPage( $out );
100 $out->out( $out->headElement() );
102 $out->out( "\n<body" );
103 $ops = $this->getBodyOptions();
104 foreach ( $ops as $name => $val ) {
105 $out->out( " $name='$val'" );
107 $out->out( ">\n" );
108 if ( $wgDebugComments ) {
109 $out->out( "<!-- Wiki debugging output:\n" .
110 $out->mDebugtext . "-->\n" );
112 $out->out( $this->beforeContent() );
114 $out->out( $out->mBodytext );
116 $out->out( $this->afterContent() );
118 wfProfileClose();
119 $out->out( $out->reportTime() );
121 $out->out( "\n</body></html>" );
124 function getHeadScripts() {
125 global $wgStyleSheetPath;
126 $r = "<script type=\"text/javascript\" src=\"{$wgStyleSheetPath}/wikibits.js\"></script>\n";
127 return $r;
130 function getUserStyles()
132 global $wgOut, $wgStyleSheetPath;
133 if( $wgOut->isPrintable() ) {
134 $sheet = "wikiprintable.css";
135 } else {
136 $sheet = $this->getStylesheet();
138 $s = "<style type='text/css'><!--\n";
139 $s .= "@import url(\"$wgStyleSheetPath/$sheet\");\n";
140 $s .= "/*/*/\n"; # <-- Hide the styles from Netscape 4 without hiding them from IE/Mac
141 $s .= $this->doGetUserStyles();
142 $s .= "/* */\n";
143 $s .= "//--></style>\n";
144 return $s;
147 function doGetUserStyles()
149 global $wgUser;
151 $s = "";
152 if ( 1 == $wgUser->getOption( "underline" ) ) {
153 # Don't override browser settings
154 } else {
155 # CHECK MERGE @@@
156 # Force no underline
157 $s .= "a.stub, a.new, a.internal, a.external { " .
158 "text-decoration: none; }\n";
160 if ( 1 == $wgUser->getOption( "highlightbroken" ) ) {
161 $s .= "a.new, #quickbar a.new { color: #CC2200; }\n";
163 if ( 1 == $wgUser->getOption( "justify" ) ) {
164 $s .= "#article { text-align: justify; }\n";
166 return $s;
169 function getBodyOptions()
171 global $wgUser, $wgTitle, $wgNamespaceBackgrounds, $wgOut, $oldid, $redirect, $diff,$action;
173 if ( 0 != $wgTitle->getNamespace() ) {
174 $a = array( "bgcolor" => "#ffffec" );
176 else $a = array( "bgcolor" => "#FFFFFF" );
177 if($wgOut->isArticle() && $wgUser->getOption("editondblclick")
179 (!$wgTitle->isProtected() || $wgUser->isSysop())
182 $t = wfMsg( "editthispage" );
183 $oid = $red = "";
184 if ( $redirect ) { $red = "&redirect={$redirect}"; }
185 if ( $oldid && ! isset( $diff ) ) {
186 $oid = "&oldid={$oldid}";
188 $s = $wgTitle->getFullURL( "action=edit{$oid}{$red}" );
189 $s = "document.location = \"" .$s ."\";";
190 $a += array ("ondblclick" => $s);
193 $a['onload'] = $wgOut->getOnloadHandler();
194 return $a;
197 function getExternalLinkAttributes( $link, $text )
199 global $wgUser, $wgOut, $wgLang;
201 $link = urldecode( $link );
202 $link = $wgLang->checkTitleEncoding( $link );
203 $link = str_replace( "_", " ", $link );
204 $link = wfEscapeHTML( $link );
206 if ( $wgOut->isPrintable() ) { $r = " class='printable'"; }
207 else { $r = " class='external'"; }
209 if ( 1 == $wgUser->getOption( "hover" ) ) {
210 $r .= " title=\"{$link}\"";
212 return $r;
215 function getInternalLinkAttributes( $link, $text, $broken = false )
217 global $wgUser, $wgOut;
219 $link = urldecode( $link );
220 $link = str_replace( "_", " ", $link );
221 $link = wfEscapeHTML( $link );
223 if ( $wgOut->isPrintable() ) {
224 $r = " class='printable'";
225 } else if ( $broken == "stub" ) {
226 $r = " class='stub'";
227 } else if ( $broken == "yes" ) {
228 $r = " class='new'";
229 } else {
230 $r = " class='internal'";
233 if ( 1 == $wgUser->getOption( "hover" ) ) {
234 $r .= " title=\"{$link}\"";
236 return $r;
239 function getInternalLinkAttributesObj( &$nt, $text, $broken = false )
241 global $wgUser, $wgOut;
243 if ( $wgOut->isPrintable() ) {
244 $r = " class='printable'";
245 } else if ( $broken == "stub" ) {
246 $r = " class='stub'";
247 } else if ( $broken == "yes" ) {
248 $r = " class='new'";
249 } else {
250 $r = " class='internal'";
253 if ( 1 == $wgUser->getOption( "hover" ) ) {
254 $r .= ' title ="' . $nt->getEscapedText() . '"';
256 return $r;
259 function getLogo()
261 global $wgLogo;
262 return $wgLogo;
265 # This will be called immediately after the <body> tag. Split into
266 # two functions to make it easier to subclass.
268 function beforeContent()
270 global $wgUser, $wgOut, $wgSiteNotice;
272 if ( $wgOut->isPrintable() ) {
273 $s = $this->pageTitle() . $this->pageSubtitle() . "\n";
274 $s .= "\n<div class='bodytext'>";
275 return $s;
277 if( $wgSiteNotice ) {
278 $note = "\n<div id='notice' style='font-weight: bold; color: red; text-align: center'>$wgSiteNotice</div>\n";
279 } else {
280 $note = "";
282 return $this->doBeforeContent() . $note;
285 function doBeforeContent()
287 global $wgUser, $wgOut, $wgTitle, $wgLang;
288 $fname = "Skin::doBeforeContent";
289 wfProfileIn( $fname );
291 $s = "";
292 $qb = $this->qbSetting();
294 if( $langlinks = $this->otherLanguages() ) {
295 $rows = 2;
296 $borderhack = "";
297 } else {
298 $rows = 1;
299 $langlinks = false;
300 $borderhack = "class='top'";
303 $s .= "\n<div id='content'>\n<div id='topbar'>" .
304 "<table width='98%' border=0 cellspacing=0><tr>";
306 $shove = ($qb != 0);
307 $left = ($qb == 1 || $qb == 3);
308 if($wgLang->isRTL()) $left = !$left;
310 if ( !$shove ) {
311 $s .= "<td class='top' align=left valign=top rowspan='{$rows}'>" .
312 $this->logoText() . "</td>";
313 } elseif( $left ) {
314 $s .= $this->getQuickbarCompensator( $rows );
316 $l = $wgLang->isRTL() ? "right" : "left";
317 $s .= "<td {$borderhack} align='$l' valign='top'>";
319 $s .= $this->topLinks() ;
320 $s .= "<p class='subtitle'>" . $this->pageTitleLinks();
322 $r = $wgLang->isRTL() ? "left" : "right";
323 $s .= "</td>\n<td {$borderhack} valign='top' align='$r' nowrap>";
324 $s .= $this->nameAndLogin();
325 $s .= "\n<br>" . $this->searchForm() . "</td>";
327 if ( $langlinks ) {
328 $s .= "</tr>\n<tr><td class='top' colspan=\"2\">$langlinks</td>";
331 if ( $shove && !$left ) { # Right
332 $s .= $this->getQuickbarCompensator( $rows );
334 $s .= "</tr></table>\n</div>\n";
335 $s .= "\n<div id='article'>";
337 $s .= $this->pageTitle();
338 $s .= $this->pageSubtitle() ;
339 $s .= getCategories(); // For some odd reason, zhis can't be a function of the object
340 $s .= "\n<p>";
341 wfProfileOut( $fname );
342 return $s;
345 function getQuickbarCompensator( $rows = 1 )
347 return "<td width='152' rowspan='{$rows}'>&nbsp;</td>";
350 # This gets called immediately before the </body> tag.
352 function afterContent()
354 global $wgUser, $wgOut, $wgServer;
355 global $wgTitle, $wgLang;
357 if ( $wgOut->isPrintable() ) {
358 $s = "\n</div>\n";
360 $u = htmlspecialchars( $wgServer . $wgTitle->getFullURL() );
361 $u = "<a href=\"$u\">$u</a>";
362 $rf = wfMsg( "retrievedfrom", $u );
364 if ( $wgOut->isArticle() ) {
365 $lm = "<br>" . $this->lastModified();
366 } else { $lm = ""; }
368 $cr = wfMsg( "gnunote" );
369 $s .= "<p>" . $wgLang->emphasize("{$rf}{$lm} {$cr}\n");
370 return $s;
372 return $this->doAfterContent();
375 function doAfterContent()
377 global $wgUser, $wgOut, $wgLang;
378 $fname = "Skin::doAfterContent";
379 wfProfileIn( $fname );
380 wfProfileIn( "$fname-1" );
382 $s = "\n</div><br clear=all>\n";
383 $s .= "\n<div id='footer'>";
384 $s .= "<table width='98%' border=0 cellspacing=0><tr>";
386 wfProfileOut( "$fname-1" );
387 wfProfileIn( "$fname-2" );
389 $qb = $this->qbSetting();
390 $shove = ($qb != 0);
391 $left = ($qb == 1 || $qb == 3);
392 if($wgLang->isRTL()) $left = !$left;
394 if ( $shove && $left ) { # Left
395 $s .= $this->getQuickbarCompensator();
397 wfProfileOut( "$fname-2" );
398 wfProfileIn( "$fname-3" );
399 $l = $wgLang->isRTL() ? "right" : "left";
400 $s .= "<td class='bottom' align='$l' valign='top'>";
402 $s .= $this->bottomLinks();
403 $s .= "\n<br>" . $this->mainPageLink()
404 . " | " . $this->aboutLink()
405 . " | " . $this->specialLink( "recentchanges" )
406 . " | " . $this->searchForm()
407 . "<br>" . $this->pageStats();
409 $s .= "</td>";
410 if ( $shove && !$left ) { # Right
411 $s .= $this->getQuickbarCompensator();
413 $s .= "</tr></table>\n</div>\n</div>\n";
415 wfProfileOut( "$fname-3" );
416 wfProfileIn( "$fname-4" );
417 if ( 0 != $qb ) { $s .= $this->quickBar(); }
418 wfProfileOut( "$fname-4" );
419 wfProfileOut( $fname );
420 return $s;
423 function pageTitleLinks()
425 global $wgOut, $wgTitle, $oldid, $action, $diff, $wgUser, $wgLang, $wgUseApproval ;
427 $s = $this->printableLink();
428 if ( wfMsg ( "disclaimers" ) != "-" ) $s .= " | " . $this->makeKnownLink( wfMsg( "disclaimerpage" ), wfMsg( "disclaimers" ) ) ;
430 if ( $wgOut->isArticleRelated() ) {
431 if ( $wgTitle->getNamespace() == Namespace::getImage() ) {
432 $name = $wgTitle->getDBkey();
433 $link = wfEscapeHTML( wfImageUrl( $name ) );
434 $style = $this->getInternalLinkAttributes( $link, $name );
435 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>";
437 # This will show the "Approve" link if $wgUseApproval=true;
438 if ( isset ( $wgUseApproval ) && $wgUseApproval )
440 $t = $wgTitle->getDBkey();
441 $name = "Approve this article" ;
442 $link = "http://test.wikipedia.org/w/magnus/wiki.phtml?title={$t}&action=submit&doit=1" ;
443 #wfEscapeHTML( wfImageUrl( $name ) );
444 $style = $this->getExternalLinkAttributes( $link, $name );
445 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>" ;
448 if ( "history" == $action || isset( $diff ) || isset( $oldid ) ) {
449 $s .= " | " . $this->makeKnownLink( $wgTitle->getPrefixedText(),
450 wfMsg( "currentrev" ) );
453 if ( $wgUser->getNewtalk() ) {
454 # do not show "You have new messages" text when we are viewing our
455 # own talk page
457 if(!(strcmp($wgTitle->getText(),$wgUser->getName()) == 0 &&
458 $wgTitle->getNamespace()==Namespace::getTalk(Namespace::getUser()))) {
459 $n =$wgUser->getName();
460 $tl = $this->makeKnownLink( $wgLang->getNsText(
461 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
462 wfMsg("newmessageslink") );
463 $s.=" | <strong>". wfMsg( "newmessages", $tl ) . "</strong>";
466 if( $wgUser->isSysop() &&
467 (($wgTitle->getArticleId() == 0) || ($action == "history")) &&
468 ($n = $wgTitle->isDeleted() ) ) {
469 $s .= " | " . wfMsg( "thisisdeleted",
470 $this->makeKnownLink(
471 $wgLang->SpecialPage( "Undelete/" . $wgTitle->getPrefixedDBkey() ),
472 wfMsg( "restorelink", $n ) ) );
474 return $s;
477 function printableLink()
479 global $wgOut, $wgTitle, $oldid, $action;
481 $q = "";
482 foreach( $_GET as $var => $val ) {
483 if( $var != "title" && $var != "printable" )
484 $q .= urlencode( $var ) . "=" . urlencode( $val );
486 if( !empty( $q ) ) $q .= "&";
488 $s = $this->makeKnownLink( $wgTitle->getPrefixedText(),
489 WfMsg( "printableversion" ), "{$q}printable=yes" );
490 return $s;
493 function pageTitle()
495 global $wgOut, $wgTitle, $wgUser;
497 $s = "<h1 class='pagetitle'>" . $wgOut->getPageTitle() . "</h1>";
498 if($wgUser->getOption("editsectiononrightclick") && $wgTitle->userCanEdit()) { $s=$this->editSectionScript(0,$s);}
499 return $s;
502 function pageSubtitle()
504 global $wgOut,$wgTitle,$wgNamespacesWithSubpages;
506 $sub = $wgOut->getSubtitle();
507 if ( "" == $sub ) {
508 global $wgExtraSubtitle;
509 $sub = wfMsg( "fromwikipedia" ) . $wgExtraSubtitle;
511 if($wgOut->isArticle() && $wgNamespacesWithSubpages[$wgTitle->getNamespace()]) {
512 $ptext=$wgTitle->getPrefixedText();
513 if(preg_match("/\//",$ptext)) {
514 $sub.="</p><p class='subpages'>";
515 $links=explode("/",$ptext);
516 $c=0;
517 $growinglink="";
518 foreach($links as $link) {
519 $c++;
520 if ($c<count($links)) {
521 $growinglink .= $link;
522 $getlink = $this->makeLink( $growinglink, $link );
523 if(preg_match("/class='new'/i",$getlink)) { break; } # this is a hack, but it saves time
524 if ($c>1) {
525 $sub .= " | ";
526 } else {
527 $sub .="&lt; ";
529 $sub .= $getlink;
530 $growinglink.="/";
536 $s = "<p class='subtitle'>{$sub}\n";
537 return $s;
540 function nameAndLogin()
542 global $wgUser, $wgTitle, $wgLang, $wgShowIPinHeader, $wgIP;
544 $li = $wgLang->specialPage( "Userlogin" );
545 $lo = $wgLang->specialPage( "Userlogout" );
547 $s = "";
548 if ( 0 == $wgUser->getID() ) {
549 if( $wgShowIPinHeader && isset( $_COOKIE[ini_get("session.name")] ) ) {
550 $n = $wgIP;
552 $tl = $this->makeKnownLink( $wgLang->getNsText(
553 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
554 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
556 $s .= $n . " (".$tl.")";
557 } else {
558 $s .= wfMsg("notloggedin");
561 $rt = $wgTitle->getPrefixedURL();
562 if ( 0 == strcasecmp( urlencode( $lo ), $rt ) ) {
563 $q = "";
564 } else { $q = "returnto={$rt}"; }
566 $s .= "\n<br>" . $this->makeKnownLink( $li,
567 wfMsg( "login" ), $q );
568 } else {
569 $n = $wgUser->getName();
570 $rt = $wgTitle->getPrefixedURL();
571 $tl = $this->makeKnownLink( $wgLang->getNsText(
572 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
573 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
575 $tl = " ({$tl})";
577 $s .= $this->makeKnownLink( $wgLang->getNsText(
578 Namespace::getUser() ) . ":{$n}", $n ) . "{$tl}<br>" .
579 $this->makeKnownLink( $lo, wfMsg( "logout" ),
580 "returnto={$rt}" ) . " | " .
581 $this->specialLink( "preferences" );
583 $s .= " | " . $this->makeKnownLink( wfMsg( "helppage" ),
584 wfMsg( "help" ) );
586 return $s;
589 function searchForm()
591 global $search;
593 $s = "<form name='search' class='inline' method=post action=\""
594 . wfLocalUrl( "" ) . "\">"
595 . "<input type=text name=\"search\" size=19 value=\""
596 . htmlspecialchars(substr($search,0,256)) . "\">\n"
597 . "<input type=submit name=\"go\" value=\"" . wfMsg ("go") . "\">&nbsp;"
598 . "<input type=submit name=\"fulltext\" value=\"" . wfMsg ("search") . "\"></form>";
600 return $s;
603 function topLinks()
605 global $wgOut;
606 $sep = " |\n";
608 $s = $this->mainPageLink() . $sep
609 . $this->specialLink( "recentchanges" );
611 if ( $wgOut->isArticleRelated() ) {
612 $s .= $sep . $this->editThisPage()
613 . $sep . $this->historyLink();
615 # Many people don't like this dropdown box
616 #$s .= $sep . $this->specialPagesList();
618 return $s;
621 function bottomLinks()
623 global $wgOut, $wgUser, $wgTitle;
624 $sep = " |\n";
626 $s = "";
627 if ( $wgOut->isArticleRelated() ) {
628 $s .= "<strong>" . $this->editThisPage() . "</strong>";
629 if ( 0 != $wgUser->getID() ) {
630 $s .= $sep . $this->watchThisPage();
632 $s .= $sep . $this->talkLink()
633 . $sep . $this->historyLink()
634 . $sep . $this->whatLinksHere()
635 . $sep . $this->watchPageLinksLink();
637 if ( $wgTitle->getNamespace() == Namespace::getUser()
638 || $wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser()) )
641 $id=User::idFromName($wgTitle->getText());
642 $ip=User::isIP($wgTitle->getText());
644 if($id || $ip) { # both anons and non-anons have contri list
645 $s .= $sep . $this->userContribsLink();
647 if ( 0 != $wgUser->getID() ) { # show only to signed in users
648 if($id) { # can only email non-anons
649 $s .= $sep . $this->emailUserLink();
653 if ( $wgUser->isSysop() && $wgTitle->getArticleId() ) {
654 $s .= "\n<br>" . $this->deleteThisPage() .
655 $sep . $this->protectThisPage() .
656 $sep . $this->moveThisPage();
658 $s .= "<br>\n" . $this->otherLanguages();
660 return $s;
663 function pageStats()
665 global $wgOut, $wgLang, $wgArticle;
666 global $oldid, $diff, $wgDisableCounters;
668 if ( ! $wgOut->isArticle() ) { return ""; }
669 if ( isset( $oldid ) || isset( $diff ) ) { return ""; }
670 if ( 0 == $wgArticle->getID() ) { return ""; }
672 if ( $wgDisableCounters ) {
673 $s = "";
674 } else {
675 $count = $wgLang->formatNum( $wgArticle->getCount() );
676 $s = wfMsg( "viewcount", $count );
678 $s .= $this->lastModified();
679 $s .= " " . wfMsg( "gnunote" );
680 return "<span id='pagestats'>{$s}</span>";
683 function lastModified()
685 global $wgLang, $wgArticle;
687 $d = $wgLang->timeanddate( $wgArticle->getTimestamp(), true );
688 $s = " " . wfMsg( "lastmodified", $d );
689 return $s;
692 function logoText( $align = "" )
694 if ( "" != $align ) { $a = " align='{$align}'"; }
695 else { $a = ""; }
697 $mp = wfMsg( "mainpage" );
698 $titleObj = Title::newFromText( $mp );
699 $s = "<a href=\"" . $titleObj->escapeLocalURL()
700 . "\"><img{$a} border=0 src=\""
701 . $this->getLogo() . "\" alt=\"" . "[{$mp}]\"></a>";
702 return $s;
705 function quickBar()
707 global $wgOut, $wgTitle, $wgUser, $action, $wgLang;
708 global $wpPreview, $wgDisableUploads, $wgRemoteUploads;
710 $fname = "Skin::quickBar";
711 wfProfileIn( $fname );
713 $tns=$wgTitle->getNamespace();
715 $s = "\n<div id='quickbar'>";
716 $s .= "\n" . $this->logoText() . "\n<hr class='sep'>";
718 $sep = "\n<br>";
719 $s .= $this->mainPageLink()
720 . $sep . $this->specialLink( "recentchanges" )
721 . $sep . $this->specialLink( "randompage" );
722 if ($wgUser->getID()) {
723 $s.= $sep . $this->specialLink( "watchlist" ) ;
724 $s .= $sep .$this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
725 wfMsg( "mycontris" ), "target=" . wfUrlencode($wgUser->getName() ) );
728 // only show watchlist link if logged in
729 if ( wfMsg ( "currentevents" ) != "-" ) $s .= $sep . $this->makeKnownLink( wfMsg( "currentevents" ), "" ) ;
730 $s .= "\n<br><hr class='sep'>";
731 $articleExists = $wgTitle->getArticleId();
732 if ( $wgOut->isArticle() || $action =="edit" || $action =="history" || $wpPreview) {
733 if($wgOut->isArticle()) {
734 $s .= "<strong>" . $this->editThisPage() . "</strong>";
735 } else { # backlink to the article in edit or history mode
736 if($articleExists){ # no backlink if no article
737 switch($tns) {
738 case 0:
739 $text = wfMsg("articlepage");
740 break;
741 case 1:
742 $text = wfMsg("viewtalkpage");
743 break;
744 case 2:
745 $text = wfMsg("userpage");
746 break;
747 case 3:
748 $text = wfMsg("viewtalkpage");
749 break;
750 case 4:
751 $text = wfMsg("wikipediapage");
752 break;
753 case 5:
754 $text = wfMsg("viewtalkpage");
755 break;
756 case 6:
757 $text = wfMsg("imagepage");
758 break;
759 case 7:
760 $text = wfMsg("viewtalkpage");
761 break;
762 default:
763 $text= wfMsg("articlepage");
766 $link = $wgTitle->getText();
767 if ($nstext = $wgLang->getNsText($tns) ) { # add namespace if necessary
768 $link = $nstext . ":" . $link ;
771 $s .= $this->makeLink( $link, $text );
772 } elseif( $wgTitle->getNamespace() != Namespace::getSpecial() ) {
773 # we just throw in a "New page" text to tell the user that he's in edit mode,
774 # and to avoid messing with the separator that is prepended to the next item
775 $s .= "<strong>" . wfMsg("newpage") . "</strong>";
781 if( $tns%2 && $action!="edit" && !$wpPreview) {
782 $s.="<br>".$this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg("postcomment"),"action=edit&section=new");
786 watching could cause problems in edit mode:
787 if user edits article, then loads "watch this article" in background and then saves
788 article with "Watch this article" checkbox disabled, the article is transparently
789 unwatched. Therefore we do not show the "Watch this page" link in edit mode
791 if ( 0 != $wgUser->getID() && $articleExists) {
792 if($action!="edit" && $action != "submit" )
794 $s .= $sep . $this->watchThisPage();
796 if ( $wgTitle->userCanEdit() )
797 $s .= $sep . $this->moveThisPage();
799 if ( $wgUser->isSysop() and $articleExists ) {
800 $s .= $sep . $this->deleteThisPage() .
801 $sep . $this->protectThisPage();
803 $s .= $sep . $this->talkLink();
804 if ($articleExists && $action !="history") {
805 $s .= $sep . $this->historyLink();
807 $s.=$sep . $this->whatLinksHere();
809 if($wgOut->isArticleRelated()) {
810 $s .= $sep . $this->watchPageLinksLink();
813 if ( Namespace::getUser() == $wgTitle->getNamespace()
814 || $wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser())
817 $id=User::idFromName($wgTitle->getText());
818 $ip=User::isIP($wgTitle->getText());
820 if($id||$ip) {
821 $s .= $sep . $this->userContribsLink();
823 if ( 0 != $wgUser->getID() ) {
824 if($id) { # can only email real users
825 $s .= $sep . $this->emailUserLink();
829 $s .= "\n<br><hr class='sep'>";
832 if ( 0 != $wgUser->getID() && ( !$wgDisableUploads || $wgRemoteUploads ) ) {
833 $s .= $this->specialLink( "upload" ) . $sep;
835 $s .= $this->specialLink( "specialpages" )
836 . $sep . $this->bugReportsLink();
838 global $wgSiteSupportPage;
839 if( $wgSiteSupportPage ) {
840 $s .= "\n<br><a href=\"" . htmlspecialchars( $wgSiteSupportPage ) .
841 "\" class=\"internal\">" . wfMsg( "sitesupport" ) . "</a>";
844 $s .= "\n<br></div>\n";
845 wfProfileOut( $fname );
846 return $s;
849 function specialPagesList()
851 global $wgUser, $wgOut, $wgLang, $wgServer, $wgRedirectScript;
852 $a = array();
854 $validSP = $wgLang->getValidSpecialPages();
856 foreach ( $validSP as $name => $desc ) {
857 if ( "" == $desc ) { continue; }
858 $a[$name] = $desc;
860 if ( $wgUser->isSysop() )
862 $sysopSP = $wgLang->getSysopSpecialPages();
864 foreach ( $sysopSP as $name => $desc ) {
865 if ( "" == $desc ) { continue; }
866 $a[$name] = $desc ;
869 if ( $wgUser->isDeveloper() )
871 $devSP = $wgLang->getDeveloperSpecialPages();
873 foreach ( $devSP as $name => $desc ) {
874 if ( "" == $desc ) { continue; }
875 $a[$name] = $desc ;
878 $go = wfMsg( "go" );
879 $sp = wfMsg( "specialpages" );
880 $spp = $wgLang->specialPage( "Specialpages" );
882 $s = "<form id=\"specialpages\" method=\"get\" class=\"inline\" " .
883 "action=\"{$wgServer}{$wgRedirectScript}\">\n";
884 $s .= "<select name=\"wpDropdown\">\n";
885 $s .= "<option value=\"{$spp}\">{$sp}</option>\n";
887 foreach ( $a as $name => $desc ) {
888 $p = $wgLang->specialPage( $name );
889 $s .= "<option value=\"{$p}\">{$desc}</option>\n";
891 $s .= "</select>\n";
892 $s .= "<input type=submit value=\"{$go}\" name=redirect>\n";
893 $s .= "</form>\n";
894 return $s;
897 function mainPageLink()
899 $mp = wfMsg( "mainpage" );
900 $s = $this->makeKnownLink( $mp, $mp );
901 return $s;
904 function copyrightLink()
906 $s = $this->makeKnownLink( wfMsg( "copyrightpage" ),
907 wfMsg( "copyrightpagename" ) );
908 return $s;
911 function aboutLink()
913 $s = $this->makeKnownLink( wfMsg( "aboutpage" ),
914 wfMsg( "aboutwikipedia" ) );
915 return $s;
919 function disclaimerLink()
921 $s = $this->makeKnownLink( wfMsg( "disclaimerpage" ),
922 wfMsg( "disclaimers" ) );
923 return $s;
926 function editThisPage()
928 global $wgOut, $wgTitle, $oldid, $redirect, $diff;
930 if ( ! $wgOut->isArticleRelated() ) {
931 $s = wfMsg( "protectedpage" );
932 } else {
933 $n = $wgTitle->getPrefixedText();
934 if ( $wgTitle->userCanEdit() ) {
935 $t = wfMsg( "editthispage" );
936 } else {
937 #$t = wfMsg( "protectedpage" );
938 $t = wfMsg( "viewsource" );
940 $oid = $red = "";
942 if ( $redirect ) { $red = "&redirect={$redirect}"; }
943 if ( $oldid && ! isset( $diff ) ) {
944 $oid = "&oldid={$oldid}";
946 $s = $this->makeKnownLink( $n, $t, "action=edit{$oid}{$red}" );
948 return $s;
951 function deleteThisPage()
953 global $wgUser, $wgOut, $wgTitle, $diff;
955 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
956 $n = $wgTitle->getPrefixedText();
957 $t = wfMsg( "deletethispage" );
959 $s = $this->makeKnownLink( $n, $t, "action=delete" );
960 } else {
961 $s = "";
963 return $s;
966 function protectThisPage()
968 global $wgUser, $wgOut, $wgTitle, $diff;
970 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
971 $n = $wgTitle->getPrefixedText();
973 if ( $wgTitle->isProtected() ) {
974 $t = wfMsg( "unprotectthispage" );
975 $q = "action=unprotect";
976 } else {
977 $t = wfMsg( "protectthispage" );
978 $q = "action=protect";
980 $s = $this->makeKnownLink( $n, $t, $q );
981 } else {
982 $s = "";
984 return $s;
987 function watchThisPage()
989 global $wgUser, $wgOut, $wgTitle, $diff;
991 if ( $wgOut->isArticleRelated() ) {
992 $n = $wgTitle->getPrefixedText();
994 if ( $wgTitle->userIsWatching() ) {
995 $t = wfMsg( "unwatchthispage" );
996 $q = "action=unwatch";
997 } else {
998 $t = wfMsg( "watchthispage" );
999 $q = "action=watch";
1001 $s = $this->makeKnownLink( $n, $t, $q );
1002 } else {
1003 $s = wfMsg( "notanarticle" );
1005 return $s;
1008 function moveThisPage()
1010 global $wgTitle, $wgLang;
1012 if ( $wgTitle->userCanEdit() ) {
1013 $s = $this->makeKnownLink( $wgLang->specialPage( "Movepage" ),
1014 wfMsg( "movethispage" ), "target=" . $wgTitle->getPrefixedURL() );
1015 } // no message if page is protected - would be redundant
1016 return $s;
1019 function historyLink()
1021 global $wgTitle;
1023 $s = $this->makeKnownLink( $wgTitle->getPrefixedText(),
1024 wfMsg( "history" ), "action=history" );
1025 return $s;
1028 function whatLinksHere()
1030 global $wgTitle, $wgLang;
1032 $s = $this->makeKnownLink( $wgLang->specialPage( "Whatlinkshere" ),
1033 wfMsg( "whatlinkshere" ), "target=" . $wgTitle->getPrefixedURL() );
1034 return $s;
1037 function userContribsLink()
1039 global $wgTitle, $wgLang;
1041 $s = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
1042 wfMsg( "contributions" ), "target=" . $wgTitle->getPartialURL() );
1043 return $s;
1046 function emailUserLink()
1048 global $wgTitle, $wgLang;
1050 $s = $this->makeKnownLink( $wgLang->specialPage( "Emailuser" ),
1051 wfMsg( "emailuser" ), "target=" . $wgTitle->getPartialURL() );
1052 return $s;
1055 function watchPageLinksLink()
1057 global $wgOut, $wgTitle, $wgLang;
1059 if ( ! $wgOut->isArticleRelated() ) {
1060 $s = "(" . wfMsg( "notanarticle" ) . ")";
1061 } else {
1062 $s = $this->makeKnownLink( $wgLang->specialPage(
1063 "Recentchangeslinked" ), wfMsg( "recentchangeslinked" ),
1064 "target=" . $wgTitle->getPrefixedURL() );
1066 return $s;
1069 function otherLanguages()
1071 global $wgOut, $wgLang, $wgTitle, $wgUseNewInterlanguage;
1073 $a = $wgOut->getLanguageLinks();
1074 # TEST THIS @@@
1075 if ( 0 == count( $a ) ) {
1076 if ( !$wgUseNewInterlanguage ) return "";
1077 $ns = $wgLang->getNsIndex ( $wgTitle->getNamespace () ) ;
1078 if ( $ns != 0 AND $ns != 1 ) return "" ;
1079 $pn = "Intl" ;
1080 $x = "mode=addlink&xt=".$wgTitle->getDBkey() ;
1081 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1082 wfMsg( "intl" ) , $x );
1085 if ( !$wgUseNewInterlanguage ) {
1086 $s = wfMsg( "otherlanguages" ) . ": ";
1087 } else {
1088 global $wgLanguageCode ;
1089 $x = "mode=zoom&xt=".$wgTitle->getDBkey() ;
1090 $x .= "&xl=".$wgLanguageCode ;
1091 $s = $this->makeKnownLink( $wgLang->specialPage( "Intl" ),
1092 wfMsg( "otherlanguages" ) , $x ) . ": " ;
1095 $s = wfMsg( "otherlanguages" ) . ": ";
1096 $first = true;
1097 if($wgLang->isRTL()) $s .= "<span dir='LTR'>";
1098 foreach( $a as $l ) {
1099 if ( ! $first ) { $s .= " | "; }
1100 $first = false;
1102 $nt = Title::newFromText( $l );
1103 $url = $nt->getFullURL();
1104 $text = $wgLang->getLanguageName( $nt->getInterwiki() );
1106 if ( "" == $text ) { $text = $l; }
1107 $style = $this->getExternalLinkAttributes( $l, $text );
1108 $s .= "<a href=\"{$url}\"{$style}>{$text}</a>";
1110 if($wgLang->isRTL()) $s .= "</span>";
1111 return $s;
1114 function bugReportsLink()
1116 $s = $this->makeKnownLink( wfMsg( "bugreportspage" ),
1117 wfMsg( "bugreports" ) );
1118 return $s;
1121 function dateLink()
1123 global $wgLinkCache;
1124 $t1 = Title::newFromText( gmdate( "F j" ) );
1125 $t2 = Title::newFromText( gmdate( "Y" ) );
1127 $wgLinkCache->suspend();
1128 $id = $t1->getArticleID();
1129 $wgLinkCache->resume();
1131 if ( 0 == $id ) {
1132 $s = $this->makeBrokenLink( $t1->getText() );
1133 } else {
1134 $s = $this->makeKnownLink( $t1->getText() );
1136 $s .= ", ";
1138 $wgLinkCache->suspend();
1139 $id = $t2->getArticleID();
1140 $wgLinkCache->resume();
1142 if ( 0 == $id ) {
1143 $s .= $this->makeBrokenLink( $t2->getText() );
1144 } else {
1145 $s .= $this->makeKnownLink( $t2->getText() );
1147 return $s;
1150 function talkLink()
1152 global $wgLang, $wgTitle, $wgLinkCache;
1154 $tns = $wgTitle->getNamespace();
1155 if ( -1 == $tns ) { return ""; }
1157 $pn = $wgTitle->getText();
1158 $tp = wfMsg( "talkpage" );
1159 if ( Namespace::isTalk( $tns ) ) {
1160 $lns = Namespace::getSubject( $tns );
1161 switch($tns) {
1162 case 1:
1163 $text = wfMsg("articlepage");
1164 break;
1165 case 3:
1166 $text = wfMsg("userpage");
1167 break;
1168 case 5:
1169 $text = wfMsg("wikipediapage");
1170 break;
1171 case 7:
1172 $text = wfMsg("imagepage");
1173 break;
1174 default:
1175 $text= wfMsg("articlepage");
1177 } else {
1179 $lns = Namespace::getTalk( $tns );
1180 $text=$tp;
1182 $n = $wgLang->getNsText( $lns );
1183 if ( "" == $n ) { $link = $pn; }
1184 else { $link = "{$n}:{$pn}"; }
1186 $wgLinkCache->suspend();
1187 $s = $this->makeLink( $link, $text );
1188 $wgLinkCache->resume();
1190 return $s;
1193 function commentLink()
1195 global $wgLang, $wgTitle, $wgLinkCache;
1197 $tns = $wgTitle->getNamespace();
1198 if ( -1 == $tns ) { return ""; }
1200 $lns = ( Namespace::isTalk( $tns ) ) ? $tns : Namespace::getTalk( $tns );
1202 # assert Namespace::isTalk( $lns )
1204 $n = $wgLang->getNsText( $lns );
1205 $pn = $wgTitle->getText();
1207 $link = "{$n}:{$pn}";
1209 $wgLinkCache->suspend();
1210 $s = $this->makeKnownLink($link, wfMsg("postcomment"), "action=edit&section=new");
1211 $wgLinkCache->resume();
1213 return $s;
1216 # After all the page content is transformed into HTML, it makes
1217 # a final pass through here for things like table backgrounds.
1219 function transformContent( $text )
1221 return $text;
1224 # Note: This function MUST call getArticleID() on the link,
1225 # otherwise the cache won't get updated properly. See LINKCACHE.DOC.
1227 function makeLink( $title, $text = "", $query = "", $trail = "" ) {
1228 wfProfileIn( "Skin::makeLink" );
1229 $nt = Title::newFromText( $title );
1230 if ($nt) {
1231 $result = $this->makeLinkObj( Title::newFromText( $title ), $text, $query, $trail );
1232 } else {
1233 wfDebug( "Invalid title passed to Skin::makeLink(): \"$title\"\n" );
1234 $result = $text == "" ? $title : $text;
1237 wfProfileOut( "Skin::makeLink" );
1238 return $result;
1241 function makeKnownLink( $title, $text = "", $query = "", $trail = "" ) {
1242 $nt = Title::newFromText( $title );
1243 if ($nt) {
1244 return $this->makeKnownLinkObj( Title::newFromText( $title ), $text, $query, $trail );
1245 } else {
1246 wfDebug( "Invalid title passed to Skin::makeKnownLink(): \"$title\"\n" );
1247 return $text == "" ? $title : $text;
1251 function makeBrokenLink( $title, $text = "", $query = "", $trail = "" ) {
1252 $nt = Title::newFromText( $title );
1253 if ($nt) {
1254 return $this->makeBrokenLinkObj( Title::newFromText( $title ), $text, $query, $trail );
1255 } else {
1256 wfDebug( "Invalid title passed to Skin::makeBrokenLink(): \"$title\"\n" );
1257 return $text == "" ? $title : $text;
1261 function makeStubLink( $title, $text = "", $query = "", $trail = "" ) {
1262 $nt = Title::newFromText( $title );
1263 if ($nt) {
1264 return $this->makeStubLinkObj( Title::newFromText( $title ), $text, $query, $trail );
1265 } else {
1266 wfDebug( "Invalid title passed to Skin::makeStubLink(): \"$title\"\n" );
1267 return $text == "" ? $title : $text;
1271 # Pass a title object, not a title string
1272 function makeLinkObj( &$nt, $text= "", $query = "", $trail = "", $prefix = "" )
1274 global $wgOut, $wgUser;
1275 if ( $nt->isExternal() ) {
1276 $u = $nt->getFullURL();
1277 if ( "" == $text ) { $text = $nt->getPrefixedText(); }
1278 $style = $this->getExternalLinkAttributes( $link, $text );
1280 $inside = "";
1281 if ( "" != $trail ) {
1282 if ( preg_match( "/^([a-z]+)(.*)$$/sD", $trail, $m ) ) {
1283 $inside = $m[1];
1284 $trail = $m[2];
1287 $retVal = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1288 } elseif ( 0 == $nt->getNamespace() && "" == $nt->getText() ) {
1289 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1290 } elseif ( ( -1 == $nt->getNamespace() ) ||
1291 ( Namespace::getImage() == $nt->getNamespace() ) ) {
1292 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1293 } else {
1294 $aid = $nt->getArticleID() ;
1295 if ( 0 == $aid ) {
1296 $retVal = $this->makeBrokenLinkObj( $nt, $text, $query, $trail, $prefix );
1297 } else {
1298 $threshold = $wgUser->getOption("stubthreshold") ;
1299 if ( $threshold > 0 ) {
1300 $res = wfQuery ( "SELECT LENGTH(cur_text) AS x, cur_namespace, cur_is_redirect FROM cur WHERE cur_id='{$aid}'", DB_READ ) ;
1302 if ( wfNumRows( $res ) > 0 ) {
1303 $s = wfFetchObject( $res );
1304 $size = $s->x;
1305 if ( $s->cur_is_redirect OR $s->cur_namespace != 0 ) {
1306 $size = $threshold*2 ; # Really big
1308 wfFreeResult( $res );
1309 } else {
1310 $size = $threshold*2 ; # Really big
1312 } else {
1313 $size = 1 ;
1315 if ( $size < $threshold ) {
1316 $retVal = $this->makeStubLinkObj( $nt, $text, $query, $trail, $prefix );
1317 } else {
1318 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1322 return $retVal;
1325 # Pass a title object, not a title string
1326 function makeKnownLinkObj( &$nt, $text = "", $query = "", $trail = "", $prefix = "" )
1328 global $wgOut, $wgTitle;
1330 $fname = "Skin::makeKnownLinkObj";
1331 wfProfileIn( $fname );
1333 $link = $nt->getPrefixedURL();
1335 if ( "" == $link ) {
1336 $u = "";
1337 if ( "" == $text ) { $text = $nt->getFragment(); }
1338 } else {
1339 $u = $nt->escapeLocalURL( $query );
1341 if ( "" != $nt->getFragment() ) {
1342 $u .= "#" . wfEscapeHTML( $nt->getFragment() );
1344 if ( "" == $text ) { $text = $nt->getPrefixedText(); }
1345 $style = $this->getInternalLinkAttributesObj( $nt, $text );
1347 $inside = "";
1348 if ( "" != $trail ) {
1349 if ( preg_match( $this->linktrail, $trail, $m ) ) {
1350 $inside = $m[1];
1351 $trail = $m[2];
1354 $r = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1355 wfProfileOut( $fname );
1356 return $r;
1359 # Pass a title object, not a title string
1360 function makeBrokenLinkObj( &$nt, $text = "", $query = "", $trail = "", $prefix = "" )
1362 global $wgOut, $wgUser;
1364 $fname = "Skin::makeBrokenLinkObj";
1365 wfProfileIn( $fname );
1367 if ( "" == $query ) {
1368 $q = "action=edit";
1369 } else {
1370 $q = "action=edit&{$query}";
1372 $u = $nt->escapeLocalURL( $q );
1374 if ( "" == $text ) { $text = $nt->getPrefixedText(); }
1375 $style = $this->getInternalLinkAttributesObj( $nt, $text, "yes" );
1377 $inside = "";
1378 if ( "" != $trail ) {
1379 if ( preg_match( $this->linktrail, $trail, $m ) ) {
1380 $inside = $m[1];
1381 $trail = $m[2];
1384 if ( $wgOut->isPrintable() ||
1385 ( 1 == $wgUser->getOption( "highlightbroken" ) ) ) {
1386 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1387 } else {
1388 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>?</a>{$trail}";
1391 wfProfileOut( $fname );
1392 return $s;
1395 # Pass a title object, not a title string
1396 function makeStubLinkObj( &$nt, $text = "", $query = "", $trail = "", $prefix = "" )
1398 global $wgOut, $wgUser;
1400 $link = $nt->getPrefixedURL();
1402 $u = $nt->escapeLocalURL( $query );
1404 if ( "" == $text ) { $text = $nt->getPrefixedText(); }
1405 $style = $this->getInternalLinkAttributesObj( $nt, $text, "stub" );
1407 $inside = "";
1408 if ( "" != $trail ) {
1409 if ( preg_match( $this->linktrail, $trail, $m ) ) {
1410 $inside = $m[1];
1411 $trail = $m[2];
1414 if ( $wgOut->isPrintable() ||
1415 ( 1 == $wgUser->getOption( "highlightbroken" ) ) ) {
1416 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1417 } else {
1418 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>!</a>{$trail}";
1420 return $s;
1423 function fnamePart( $url )
1425 $basename = strrchr( $url, "/" );
1426 if ( false === $basename ) { $basename = $url; }
1427 else { $basename = substr( $basename, 1 ); }
1428 return wfEscapeHTML( $basename );
1431 function makeImage( $url, $alt = "" )
1433 global $wgOut;
1435 if ( "" == $alt ) { $alt = $this->fnamePart( $url ); }
1436 $s = "<img src=\"{$url}\" alt=\"{$alt}\">";
1437 return $s;
1440 function makeImageLink( $name, $url, $alt = "" ) {
1441 $nt = Title::makeTitle( Namespace::getImage(), $name );
1442 return $this->makeImageLinkObj( $nt, $alt );
1445 function makeImageLinkObj( $nt, $alt = "" ) {
1446 global $wgLang, $wgUseImageResize;
1447 $name = $nt->getDBKey();
1448 $url = wfImageUrl( $name );
1449 $align = "";
1450 $prefix = $postfix = "";
1452 if ( $wgUseImageResize ) {
1453 # Check if the alt text is of the form "options|alt text"
1454 # Options are:
1455 # * thumbnail make a thumbnail with enlarge-icon and caption, alignment depends on lang
1456 # * left no resizing, just left align. label is used for alt= only
1457 # * right same, but right aligned
1458 # * none same, but not aligned
1459 # * ___px scale to ___ pixels width, no aligning. e.g. use in taxobox
1461 $part = explode( "|", $alt);
1463 $mwThumb =& MagicWord::get( MAG_IMG_THUMBNAIL );
1464 $mwLeft =& MagicWord::get( MAG_IMG_LEFT );
1465 $mwRight =& MagicWord::get( MAG_IMG_RIGHT );
1466 $mwNone =& MagicWord::get( MAG_IMG_NONE );
1467 $mwWidth =& MagicWord::get( MAG_IMG_WIDTH );
1468 $mwCenter =& MagicWord::get( MAG_IMG_CENTER );
1469 $alt = $part[count($part)-1];
1471 $thumb=false;
1473 foreach( $part as $key => $val ) {
1474 if ( ! is_null( $mwThumb->matchVariableStartToEnd($val) ) ) {
1475 $thumb=true;
1476 } elseif ( ! is_null( $mwRight->matchVariableStartToEnd($val) ) ) {
1477 # remember to set an alignment, don't render immediately
1478 $align = "right";
1479 } elseif ( ! is_null( $mwLeft->matchVariableStartToEnd($val) ) ) {
1480 # remember to set an alignment, don't render immediately
1481 $align = "left";
1482 } elseif ( ! is_null( $mwCenter->matchVariableStartToEnd($val) ) ) {
1483 # remember to set an alignment, don't render immediately
1484 $align = "center";
1485 } elseif ( ! is_null( $mwNone->matchVariableStartToEnd($val) ) ) {
1486 # remember to set an alignment, don't render immediately
1487 $align = "none";
1488 } elseif ( ! is_null( $match = $mwWidth->matchVariableStartToEnd($val) ) ) {
1489 # $match is the image width in pixels
1490 $width = intval($match);
1493 if ( "center" == $align )
1495 $prefix = "<center>";
1496 $postfix = "</center>";
1497 $align = "none";
1500 if ( $thumb ) {
1502 # Create a thumbnail. Alignment depends on language
1503 # writing direction, # right aligned for left-to-right-
1504 # languages ("Western languages"), left-aligned
1505 # for right-to-left-languages ("Semitic languages")
1507 # If thumbnail width has not been provided, it is set
1508 # here to 180 pixels
1509 if ( $align == "" ) {
1510 $align = $wgLang->isRTL() ? "left" : "right";
1512 if ( ! isset($width) ) {
1513 $width = 180;
1515 return $prefix.$this->makeThumbLinkObj( $nt, $alt, $align, $width ).$postfix;
1517 } elseif ( isset($width) ) {
1519 # Create a resized image, without the additional thumbnail
1520 # features
1521 $url = $this->createThumb( $name, $width );
1523 } # endif $wgUseImageResize
1525 if ( empty( $alt ) ) {
1526 $alt = preg_replace( '/\.(.+?)^/', '', $name );
1528 $alt = htmlspecialchars( $alt );
1530 $u = $nt->escapeLocalURL();
1531 if ( $url == "" )
1533 $s = str_replace( "$1", $name, wfMsg("missingimage") );
1534 } else {
1535 $s = "<a href=\"{$u}\" class='image' title=\"{$alt}\">" .
1536 "<img border=\"0\" src=\"{$url}\" alt=\"{$alt}\"></a>";
1538 if ( "" != $align ) {
1539 $s = "<div class=\"float{$align}\">{$s}</div>";
1541 return $prefix.$s.$postfix;
1544 function createThumb( $name, $width ) {
1545 global $wgUploadDirectory;
1546 global $wgImageMagickConvertCommand;
1547 global $wgUseImageMagick;
1548 global $wgUseSquid, $wgInternalServer;
1549 $imgPath = wfImagePath( $name );
1550 $thumbName = $width."px-".$icon.$name;
1551 $thumbPath = wfImageThumbDir( $thumbName )."/".$thumbName;
1552 $thumbUrl = wfImageThumbUrl( $thumbName );
1554 if ( ! file_exists( $imgPath ) )
1556 # If there is no image, there will be no thumbnail
1557 return "";
1560 if ( (! file_exists( $thumbPath ) )
1561 || ( filemtime($thumbPath) < filemtime($imgPath) ) ) {
1562 # Squid purging
1563 if ( $wgUseSquid ) {
1564 $urlArr = Array(
1565 $wgInternalServer.$thumbUrl
1567 wfPurgeSquidServers($urlArr);
1570 if ( $wgUseImageMagick ) {
1571 # use ImageMagick
1572 $cmd = $wgImageMagickConvertCommand .
1573 " -quality 85 -geometry {$width} ".
1574 escapeshellarg($imgPath) . " " .
1575 escapeshellarg($thumbPath);
1576 $conv = shell_exec( $cmd );
1577 } else {
1578 # Use PHP's builtin GD library functions.
1580 # First find out what kind of file this is, and select the correct
1581 # input routine for this.
1582 list($src_width, $src_height, $src_type, $src_attr) = getimagesize( $imgPath );
1583 switch( $src_type ) {
1584 case 1: # GIF
1585 $src_image = imagecreatefromgif( $imgPath );
1586 break;
1587 case 2: # JPG
1588 $src_image = imagecreatefromjpeg( $imgPath );
1589 break;
1590 case 3: # PNG
1591 $src_image = imagecreatefrompng( $imgPath );
1592 break;
1593 case 15: # WBMP for WML
1594 $src_image = imagecreatefromwbmp( $imgPath );
1595 break;
1596 case 16: # XBM
1597 $src_image = imagecreatefromxbm( $imgPath );
1598 break;
1599 default:
1600 return "Image type not supported";
1601 break;
1603 $height = floor( $src_height * ( $width/$src_width ) );
1604 $dst_image = imagecreatetruecolor( $width, $height );
1605 imagecopyresampled( $dst_image, $src_image,
1606 0,0,0,0,
1607 $width, $height, $src_width, $src_height );
1608 switch( $src_type ) {
1609 case 1: # GIF
1610 case 3: # PNG
1611 case 15: # WBMP
1612 case 16: # XBM
1613 #$thumbUrl .= ".png";
1614 #$thumbPath .= ".png";
1615 imagepng( $dst_image, $thumbPath );
1616 break;
1617 case 2: # JPEG
1618 #$thumbUrl .= ".jpg";
1619 #$thumbPath .= ".jpg";
1620 imageinterlace( $dst_image );
1621 imagejpeg( $dst_image, $thumbPath, 95 );
1622 break;
1623 default:
1624 break;
1626 imagedestroy( $dst_image );
1627 imagedestroy( $src_image );
1632 # Check for zero-sized thumbnails. Those can be generated when
1633 # no disk space is available or some other error occurs
1635 $thumbstat = stat( $thumbPath );
1636 $imgstat = stat( $imgPath );
1637 if( $thumbstat["size"] == 0 )
1639 unlink( $thumbPath );
1643 return $thumbUrl;
1646 function makeThumbLinkObj( $nt, $label = "", $align = "right", $boxwidth = 180 ) {
1647 global $wgUploadPath, $wgLang;
1648 $name = $nt->getDBKey();
1649 $image = Title::makeTitle( Namespace::getImage(), $name );
1650 $url = wfImageUrl( $name );
1651 $path = wfImagePath( $name );
1653 #$label = htmlspecialchars( $label );
1654 $alt = preg_replace( "/<[^>]*>/", "", $label);
1655 $alt = htmlspecialchars( $alt );
1657 if ( file_exists( $path ) )
1659 list($width, $height, $type, $attr) = getimagesize( $path );
1660 } else {
1661 $width = $height = 200;
1663 $boxheight = intval( $height/($width/$boxwidth) );
1664 if ( $boxwidth > $width ) {
1665 $boxwidth = $width;
1666 $boxheight = $height;
1669 $thumbUrl = $this->createThumb( $name, $boxwidth );
1671 $u = $nt->escapeLocalURL();
1673 $more = htmlspecialchars( wfMsg( "thumbnail-more" ) );
1674 $magnifyalign = $wgLang->isRTL() ? "left" : "right";
1675 $textalign = $wgLang->isRTL() ? " style=\"text-align:right\"" : "";
1677 $s = "<div class=\"thumbnail-{$align}\" style=\"width:{$boxwidth}px;\">";
1678 if ( $thumbUrl == "" ) {
1679 $s .= str_replace( "$1", $name, wfMsg("missingimage") );
1680 } else {
1681 $s .= "<a href=\"{$u}\" class=\"internal\" title=\"{$alt}\">" .
1682 "<img border=\"0\" src=\"{$thumbUrl}\" alt=\"{$alt}\" " .
1683 " width=\"{$boxwidth}\" height=\"{$boxheight}\"></a>" .
1684 "<a href=\"{$u}\" class=\"internal\" title=\"{$more}\">" .
1685 "<img border=\"0\" src=\"{$wgUploadPath}/magnify-clip.png\" " .
1686 " width=\"26\" height=\"24\" align=\"{$magnifyalign}\" alt=\"{$more}\"></a>";
1688 $s .= "<p{$textalign}>{$label}</p></div>";
1689 return $s;
1692 function makeMediaLink( $name, $url, $alt = "" ) {
1693 $nt = Title::makeTitle( Namespace::getMedia(), $name );
1694 return $this->makeMediaLinkObj( $nt, $alt );
1697 function makeMediaLinkObj( $nt, $alt = "" )
1699 $name = $nt->getDBKey();
1700 $url = wfImageUrl( $name );
1701 if ( empty( $alt ) ) {
1702 $alt = preg_replace( '/\.(.+?)^/', '', $name );
1705 $u = htmlspecialchars( $url );
1706 $s = "<a href=\"{$u}\" class='internal' title=\"{$alt}\">{$alt}</a>";
1707 return $s;
1710 function specialLink( $name, $key = "" )
1712 global $wgLang;
1714 if ( "" == $key ) { $key = strtolower( $name ); }
1715 $pn = $wgLang->ucfirst( $name );
1716 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1717 wfMsg( $key ) );
1720 # Called by history lists and recent changes
1723 # Returns text for the start of the tabular part of RC
1724 function beginRecentChangesList()
1726 $this->rc_cache = array() ;
1727 $this->rcMoveIndex = 0;
1728 $this->rcCacheIndex = 0 ;
1729 $this->lastdate = "";
1730 return "";
1733 function beginImageHistoryList()
1735 $s = "\n<h2>" . wfMsg( "imghistory" ) . "</h2>\n" .
1736 "<p>" . wfMsg( "imghistlegend" ) . "\n<ul>";
1737 return $s;
1740 # Returns text for the end of RC
1741 # If enhanced RC is in use, returns pretty much all the text
1742 function endRecentChangesList()
1744 $s = $this->recentChangesBlock() ;
1745 $s .= "</ul>\n";
1746 return $s;
1749 # Enhanced RC ungrouped line
1750 function recentChangesBlockLine ( $rcObj )
1752 global $wgUploadPath, $wgLang ;
1754 # Get rc_xxxx variables
1755 extract( $rcObj->mAttribs ) ;
1756 $curIdEq = "curid=$rc_cur_id";
1758 # Spacer image
1759 $r = "" ;
1760 $r .= "<img src='{$wgUploadPath}/Arr_.png' width='12' height='12' border='0'>" ; $r .= "<tt>" ;
1762 if ( $rc_type == RC_MOVE ) {
1763 $r .= "&nbsp;&nbsp;";
1764 } else {
1765 # M & N (minor & new)
1766 $M = wfMsg( "minoreditletter" );
1767 $N = wfMsg( "newpageletter" );
1769 if ( $rc_type == RC_NEW ) {
1770 $r .= $N ;
1771 } else {
1772 $r .= "&nbsp;" ;
1774 if ( $rc_minor ) {
1775 $r .= $M ;
1776 } else {
1777 $r .= "&nbsp;" ;
1781 # Timestamp
1782 $r .= " ".$rcObj->timestamp." " ;
1783 $r .= "</tt>" ;
1785 # Article link
1786 $link = $rcObj->link ;
1787 if ( $rcObj->watched ) $link = "<strong>{$link}</strong>" ;
1788 $r .= $link ;
1790 # Cur
1791 $r .= " (" ;
1792 $r .= $rcObj->curlink ;
1793 $r .= "; " ;
1795 # Hist
1796 $r .= $this->makeKnownLinkObj( $rcObj->getTitle(), wfMsg( "hist" ), "{$curIdEq}&action=history" );
1798 # User/talk
1799 $r .= ") . . ".$rcObj->userlink ;
1800 $r .= $rcObj->usertalklink ;
1802 # Comment
1803 if ( $rc_comment != "" && $rc_type != RC_MOVE ) {
1804 $r .= $wgLang->emphasize( " (".wfEscapeHTML($rc_comment).")" );
1806 $r .= "<br>\n" ;
1807 return $r ;
1810 # Enhanced RC group
1811 function recentChangesBlockGroup ( $block )
1813 global $wgUploadPath, $wgLang ;
1815 $r = "" ;
1816 $M = wfMsg( "minoreditletter" );
1817 $N = wfMsg( "newpageletter" );
1819 # Collate list of users
1820 $isnew = false ;
1821 $userlinks = array () ;
1822 foreach ( $block AS $rcObj ) {
1823 $oldid = $rcObj->mAttribs['rc_last_oldid'];
1824 if ( $rcObj->mAttribs['rc_new'] ) $isnew = true ;
1825 $u = $rcObj->userlink ;
1826 if ( !isset ( $userlinks[$u] ) ) $userlinks[$u] = 0 ;
1827 $userlinks[$u]++ ;
1830 # Sort the list and convert to text
1831 krsort ( $userlinks ) ;
1832 asort ( $userlinks ) ;
1833 $users = array () ;
1834 foreach ( $userlinks as $userlink => $count) {
1835 $text = $userlink ;
1836 if ( $count > 1 ) $text .= " ({$count}&times;)" ;
1837 array_push ( $users , $text ) ;
1839 $users = " <font size='-1'>[".implode("; ",$users)."]</font>" ;
1841 # Arrow
1842 $rci = "RCI{$this->rcCacheIndex}" ;
1843 $rcl = "RCL{$this->rcCacheIndex}" ;
1844 $rcm = "RCM{$this->rcCacheIndex}" ;
1845 $toggleLink = "javascript:toggleVisibility(\"{$rci}\",\"{$rcm}\",\"{$rcl}\")" ;
1846 $arrowdir = $wgLang->isRTL() ? "l" : "r";
1847 $tl = "<span id='{$rcm}'><a href='$toggleLink'><img src='{$wgUploadPath}/Arr_{$arrowdir}.png' width='12' height='12' border='0' /></a></span>" ;
1848 $tl .= "<span id='{$rcl}' style='display:none'><a href='$toggleLink'><img src='{$wgUploadPath}/Arr_d.png' width='12' height='12' border='0' /></a></span>" ;
1849 $r .= $tl ;
1851 # Main line
1852 # M/N
1853 $r .= "<tt>" ;
1854 if ( $isnew ) $r .= $N ;
1855 else $r .= "&nbsp;" ;
1856 $r .= "&nbsp;" ; # Minor
1858 # Timestamp
1859 $r .= " ".$block[0]->timestamp." " ;
1860 $r .= "</tt>" ;
1862 # Article link
1863 $link = $block[0]->link ;
1864 if ( $block[0]->watched ) $link = "<strong>{$link}</strong>" ;
1865 $r .= $link ;
1867 $curIdEq = "curid=" . $block[0]->mAttribs['rc_cur_id'];
1868 if ( $block[0]->mAttribs['rc_type'] != RC_LOG ) {
1869 # Changes
1870 $r .= " (".count($block)." " ;
1871 if ( $isnew ) $r .= wfMsg("changes");
1872 else $r .= $this->makeKnownLinkObj( $block[0]->getTitle() , wfMsg("changes") ,
1873 "{$curIdEq}&diff=0&oldid=".$oldid ) ;
1874 $r .= "; " ;
1876 # History
1877 $r .= $this->makeKnownLinkObj( $block[0]->getTitle(), wfMsg( "history" ), "{$curIdEq}&action=history" );
1878 $r .= ")" ;
1881 $r .= $users ;
1882 $r .= "<br>\n" ;
1884 # Sub-entries
1885 $r .= "<div id='{$rci}' style='display:none'>" ;
1886 foreach ( $block AS $rcObj ) {
1887 # Get rc_xxxx variables
1888 extract( $rcObj->mAttribs );
1890 $r .= "<img src='{$wgUploadPath}/Arr_.png' width=12 height=12 border=0>";
1891 $r .= "<tt>&nbsp; &nbsp; &nbsp; &nbsp;" ;
1892 if ( $rc_new ) $r .= $N ;
1893 else $r .= "&nbsp;" ;
1894 if ( $rc_minor ) $r .= $M ;
1895 else $r .= "&nbsp;" ;
1896 $r .= "</tt>" ;
1898 $o = "" ;
1899 if ( $rc_last_oldid != 0 ) {
1900 $o = "oldid=".$rc_last_oldid ;
1902 if ( $rc_type == RC_LOG ) {
1903 $link = $rcObj->timestamp ;
1904 } else {
1905 $link = $this->makeKnownLinkObj( $rcObj->getTitle(), $rcObj->timestamp , "{$curIdEq}&$o" ) ;
1907 $link = "<tt>{$link}</tt>" ;
1909 $r .= $link ;
1910 $r .= " (" ;
1911 $r .= $rcObj->curlink ;
1912 $r .= "; " ;
1913 $r .= $rcObj->lastlink ;
1914 $r .= ") . . ".$rcObj->userlink ;
1915 $r .= $rcObj->usertalklink ;
1916 if ( $rc_comment != "" ) {
1917 $r .= $wgLang->emphasize( " (".wfEscapeHTML($rc_comment).")" ) ;
1919 $r .= "<br>\n" ;
1921 $r .= "</div>\n" ;
1923 $this->rcCacheIndex++ ;
1924 return $r ;
1927 # If enhanced RC is in use, this function takes the previously cached
1928 # RC lines, arranges them, and outputs the HTML
1929 function recentChangesBlock ()
1931 global $wgUploadPath ;
1932 if ( count ( $this->rc_cache ) == 0 ) return "" ;
1933 $blockOut = "";
1934 foreach ( $this->rc_cache AS $secureName => $block ) {
1935 if ( count ( $block ) < 2 ) {
1936 $blockOut .= $this->recentChangesBlockLine ( array_shift ( $block ) ) ;
1937 } else {
1938 $blockOut .= $this->recentChangesBlockGroup ( $block ) ;
1942 return "<div>{$blockOut}</div>" ;
1945 # Called in a loop over all displayed RC entries
1946 # Either returns the line, or caches it for later use
1947 function recentChangesLine( &$rc, $watched = false )
1949 global $wgUser ;
1950 $usenew = $wgUser->getOption( "usenewrc" );
1951 if ( $usenew )
1952 $line = $this->recentChangesLineNew ( $rc, $watched ) ;
1953 else
1954 $line = $this->recentChangesLineOld ( $rc, $watched ) ;
1955 return $line ;
1958 function recentChangesLineOld( &$rc, $watched = false )
1960 global $wgTitle, $wgLang, $wgUser;
1962 # Extract DB fields into local scope
1963 extract( $rc->mAttribs );
1964 $curIdEq = "curid=" . $rc_cur_id;
1966 # Make date header if necessary
1967 $date = $wgLang->date( $rc_timestamp, true);
1968 $s = "";
1969 if ( $date != $this->lastdate ) {
1970 if ( "" != $this->lastdate ) { $s .= "</ul>\n"; }
1971 $s .= "<h4>{$date}</h4>\n<ul>";
1972 $this->lastdate = $date;
1974 $s .= "<li> ";
1976 if ( $rc_type == RC_MOVE ) {
1977 # Diff
1978 $s .= "(" . wfMsg( "diff" ) . ") (";
1979 # Hist
1980 $s .= $this->makeKnownLinkObj( $rc->getMovedToTitle(), wfMsg( "hist" ), "action=history" ) .
1981 ") . . ";
1983 # "[[x]] moved to [[y]]"
1985 $s .= wfMsg( "1movedto2", $this->makeKnownLinkObj( $rc->getTitle(), "", "redirect=no" ),
1986 $this->makeKnownLinkObj( $rc->getMovedToTitle(), "" ) );
1988 } else {
1989 # Diff link
1990 if ( $rc_type == RC_NEW || $rc_type == RC_LOG ) {
1991 $diffLink = wfMsg( "diff" );
1992 } else {
1993 $diffLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( "diff" ),
1994 "{$curIdEq}&diff={$rc_this_oldid}&oldid={$rc_last_oldid}" );
1996 $s .= "($diffLink) (";
1998 # History link
1999 $s .= $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( "hist" ), "{$curIdEq}&action=history" );
2000 $s .= ") . . ";
2002 # M and N (minor and new)
2003 $M = wfMsg( "minoreditletter" );
2004 $N = wfMsg( "newpageletter" );
2005 if ( $rc_minor ) { $s .= " <strong>{$M}</strong>"; }
2006 if ( $rc_type == RC_NEW ) { $s .= "<strong>{$N}</strong>"; }
2008 # Article link
2009 $articleLink = $this->makeKnownLinkObj( $rc->getTitle(), "" );
2011 if ( $watched ) {
2012 $articleLink = "<strong>{$articleLink}</strong>";
2014 $s .= " $articleLink";
2018 # Timestamp
2019 $s .= "; " . $wgLang->time( $rc_timestamp, true ) . " . . ";
2021 # User link (or contributions for unregistered users)
2022 if ( 0 == $rc_user ) {
2023 $userLink = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
2024 $rc_user_text, "target=" . $rc_user_text );
2025 } else {
2026 $userLink = $this->makeLink( $wgLang->getNsText( NS_USER ) . ":{$rc_user_text}", $rc_user_text );
2028 $s .= $userLink;
2030 # User talk link
2031 $talkname=$wgLang->getNsText(NS_TALK); # use the shorter name
2032 global $wgDisableAnonTalk;
2033 if( 0 == $rc_user && $wgDisableAnonTalk ) {
2034 $userTalkLink = "";
2035 } else {
2036 $utns=$wgLang->getNsText(NS_USER_TALK);
2037 $userTalkLink= $this->makeLink($utns . ":{$rc_user_text}", $talkname );
2039 # Block link
2040 $blockLink="";
2041 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2042 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2043 "Blockip" ), wfMsg( "blocklink" ), "ip={$rc_user_text}" );
2046 if($blockLink) {
2047 if($userTalkLink) $userTalkLink .= " | ";
2048 $userTalkLink .= $blockLink;
2050 if($userTalkLink) $s.=" ({$userTalkLink})";
2052 # Add comment
2053 if ( "" != $rc_comment && "*" != $rc_comment && $rc_type != RC_MOVE ) {
2054 $s .= $wgLang->emphasize(" (" . wfEscapeHTML( $rc_comment ) . ")");
2056 $s .= "</li>\n";
2058 return $s;
2061 # function recentChangesLineNew( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched = false, $oldid = 0 , $diffid = 0 )
2062 function recentChangesLineNew( &$baseRC, $watched = false )
2064 global $wgTitle, $wgLang, $wgUser;
2066 # Create a specialised object
2067 $rc = RCCacheEntry::newFromParent( $baseRC ) ;
2069 # Extract fields from DB into the function scope (rc_xxxx variables)
2070 extract( $rc->mAttribs );
2071 $curIdEq = "curid=" . $rc_cur_id;
2073 # If it's a new day, add the headline and flush the cache
2074 $date = $wgLang->date( $rc_timestamp, true);
2075 $ret = "" ;
2076 if ( $date != $this->lastdate ) {
2077 # Process current cache
2078 $ret = $this->recentChangesBlock () ;
2079 $this->rc_cache = array() ;
2080 $ret .= "<h4>{$date}</h4>\n";
2081 $this->lastdate = $date;
2084 # Make article link
2085 if ( $rc_type == RC_MOVE ) {
2086 $clink = $this->makeKnownLinkObj( $rc->getTitle(), "", "redirect=no" );
2087 $clink .= " " . wfMsg("movedto") . " ";
2088 $clink .= $this->makeKnownLinkObj( $rc->getMovedToTitle(), "" );
2089 } else {
2090 $clink = $this->makeKnownLinkObj( $rc->getTitle(), "" ) ;
2093 $time = $wgLang->time( $rc_timestamp, true );
2094 $rc->watched = $watched ;
2095 $rc->link = $clink ;
2096 $rc->timestamp = $time;
2098 # Make "cur" link
2099 if ( ( $rc_type == RC_NEW && $rc_this_oldid == 0 ) || $rc_type == RC_LOG || $rc_type == RC_MOVE) {
2100 $curLink = wfMsg( "cur" );
2101 } else {
2102 $curLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( "cur" ),
2103 "{$curIdEq}&diff=0&oldid={$rc_this_oldid}" );
2106 # Make "last" link
2107 $titleObj = $rc->getTitle();
2108 if ( $rc_last_oldid == 0 || $rc_type == RC_LOG || $rc_type == RC_MOVE ) {
2109 $lastLink = wfMsg( "last" );
2110 } else {
2111 $lastLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( "last" ),
2112 "{$curIdEq}&diff={$rc_this_oldid}&oldid={$rc_last_oldid}" );
2115 # Make user link (or user contributions for unregistered users)
2116 if ( 0 == $rc_user ) {
2117 $userLink = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
2118 $rc_user_text, "target=" . $rc_user_text );
2119 } else {
2120 $userLink = $this->makeLink( $wgLang->getNsText(
2121 Namespace::getUser() ) . ":{$rc_user_text}", $rc_user_text );
2124 $rc->userlink = $userLink ;
2125 $rc->lastlink = $lastLink ;
2126 $rc->curlink = $curLink ;
2128 # Make user talk link
2129 $utns=$wgLang->getNsText(NS_USER_TALK);
2130 $talkname=$wgLang->getNsText(NS_TALK); # use the shorter name
2131 $userTalkLink= $this->makeLink($utns . ":{$rc_user_text}", $talkname );
2133 global $wgDisableAnonTalk;
2134 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2135 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2136 "Blockip" ), wfMsg( "blocklink" ), "ip={$rc_user_text}" );
2137 if( $wgDisableAnonTalk )
2138 $rc->usertalklink = " ({$blockLink})";
2139 else
2140 $rc->usertalklink = " ({$userTalkLink} | {$blockLink})";
2141 } else {
2142 if( $wgDisableAnonTalk && ($rc_user == 0) )
2143 $rc->usertalklink = "";
2144 else
2145 $rc->usertalklink = " ({$userTalkLink})";
2148 # Put accumulated information into the cache, for later display
2149 # Page moves go on their own line
2150 $title = $rc->getTitle();
2151 $secureName = $title->getPrefixedDBkey();
2152 if ( $rc_type == RC_MOVE ) {
2153 # Use an @ character to prevent collision with page names
2154 $this->rc_cache["@@" . ($this->rcMoveIndex++)] = array($rc);
2155 } else {
2156 if ( !isset ( $this->rc_cache[$secureName] ) ) $this->rc_cache[$secureName] = array() ;
2157 array_push ( $this->rc_cache[$secureName] , $rc ) ;
2159 return $ret;
2162 function endImageHistoryList()
2164 $s = "</ul>\n";
2165 return $s;
2168 function imageHistoryLine( $iscur, $ts, $img, $u, $ut, $size, $c )
2170 global $wgUser, $wgLang, $wgTitle;
2172 $dt = $wgLang->timeanddate( $ts, true );
2173 $del = wfMsg( "deleteimg" );
2174 $cur = wfMsg( "cur" );
2176 if ( $iscur ) {
2177 $url = wfImageUrl( $img );
2178 $rlink = $cur;
2179 if ( $wgUser->isSysop() ) {
2180 $link = $wgTitle->escapeLocalURL( "image=" . $wgTitle->getPartialURL() .
2181 "&action=delete" );
2182 $style = $this->getInternalLinkAttributes( $link, $del );
2184 $dlink = "<a href=\"{$link}\"{$style}>{$del}</a>";
2185 } else {
2186 $dlink = $del;
2188 } else {
2189 $url = wfEscapeHTML( wfImageArchiveUrl( $img ) );
2190 if( $wgUser->getID() != 0 ) {
2191 $rlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2192 wfMsg( "revertimg" ), "action=revert&oldimage=" .
2193 urlencode( $img ) );
2194 $dlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2195 $del, "action=delete&oldimage=" . urlencode( $img ) );
2196 } else {
2197 # Having live active links for non-logged in users
2198 # means that bots and spiders crawling our site can
2199 # inadvertently change content. Baaaad idea.
2200 $rlink = wfMsg( "revertimg" );
2201 $dlink = $del;
2204 if ( 0 == $u ) { $ul = $ut; }
2205 else { $ul = $this->makeLink( $wgLang->getNsText(
2206 Namespace::getUser() ) . ":{$ut}", $ut ); }
2208 $nb = wfMsg( "nbytes", $size );
2209 $style = $this->getInternalLinkAttributes( $url, $dt );
2211 $s = "<li> ({$dlink}) ({$rlink}) <a href=\"{$url}\"{$style}>{$dt}</a>"
2212 . " . . {$ul} ({$nb})";
2214 if ( "" != $c && "*" != $c ) {
2215 $s .= $wgLang->emphasize(" (" . wfEscapeHTML( $c ) . ")");
2217 $s .= "</li>\n";
2218 return $s;
2221 function tocIndent($level) {
2223 while($level-->0) $rv.="<div style=\"margin-left:2em;\">\n";
2224 return $rv;
2228 function tocUnindent($level) {
2229 $rv = "";
2230 while($level-->0) $rv.="</div>\n";
2231 return $rv;
2234 // parameter level defines if we are on an indentation level
2235 function tocLine($anchor,$tocline,$level) {
2237 if($level) {
2239 return "<A CLASS=\"internal\" HREF=\"#".$anchor."\">".$tocline."</A><BR>\n";
2240 } else {
2242 return "<div style=\"margin-bottom:0px;\">\n".
2243 "<A CLASS=\"internal\" HREF=\"#".$anchor."\">".$tocline."</A><BR>\n".
2244 "</div>\n";
2249 function tocTable($toc) {
2250 // note to CSS fanatics: putting this in a div does not work -- div won't auto-expand
2251 global $printable;
2253 if (!$printable) {
2254 $hideline = " <script type='text/javascript'>showTocToggle(\"" . wfMsg("showtoc") . "\",\"" . wfMsg("hidetoc") . "\")</script>";
2256 return
2257 "<p><table border=\"0\" id=\"toc\"><tr><td align=\"center\">\n".
2258 "<b>".wfMsg("toc")."</b>" .
2259 $hideline .
2260 "</td></tr><tr id='tocinside'><td>\n".
2261 $toc."</td></tr></table><P>\n";
2264 # These two do not check for permissions: check $wgTitle->userCanEdit before calling them
2265 function editSectionScript($section,$head) {
2267 global $wgTitle,$wgUser,$oldid;
2268 if($oldid) return $head;
2269 $url = $wgTitle->escapeLocalURL( "action=edit&section=$section" );
2270 return "<span onContextMenu='document.location=\"".$url."\";return false;'>{$head}</span>";
2273 function editSectionLink($section) {
2274 global $printable,$oldid;
2275 global $wgTitle, $wgUser, $wgLang;
2277 if( isset( $oldid ) ) return "";
2278 if( isset( $printable ) ) return "";
2280 $editurl = "&section={$section}";
2281 $url = $this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg("editsection"),"action=edit".$editurl);
2283 if( $wgLang->isRTL() ) {
2284 $farside = "left";
2285 $nearside = "right";
2286 } else {
2287 $farside = "right";
2288 $nearside = "left";
2290 return "<div style=\"float:$farside;margin-$nearside:5px;\"><small>[".$url."]</small></div>";
2294 // This function is called by EditPage.php and shows a bulletin board style
2295 // toolbar for common editing functions. It can be disabled in the user preferences.
2296 // The necsesary JavaScript code can be found in style/wikibits.js.
2297 function getEditToolbar() {
2299 global $wgUploadPath,$wgLang;
2301 // toolarray an array of arrays which each include the filename of
2302 // the button image (without path), the opening tag, the closing tag,
2303 // and optionally a sample text that is inserted between the two when no
2304 // selection is highlighted.
2305 // The tip text is shown when the user moves the mouse over the button.
2306 $toolarray=array(
2307 array( "image"=>"button_bold.png",
2308 "open"=>"\'\'\'",
2309 "close"=>"\'\'\'",
2310 "sample"=>wfMsg("bold_sample"),
2311 "tip"=>wfMsg("bold_tip")),
2312 array( "image"=>"button_italic.png",
2313 "open"=>"\'\'",
2314 "close"=>"\'\'",
2315 "sample"=>wfMsg("italic_sample"),
2316 "tip"=>wfMsg("italic_tip")),
2317 array( "image"=>"button_link.png",
2318 "open"=>"[[",
2319 "close"=>"]]",
2320 "sample"=>wfMsg("link_sample"),
2321 "tip"=>wfMsg("link_tip")),
2322 array( "image"=>"button_extlink.png",
2323 "open"=>"[",
2324 "close"=>"]",
2325 "sample"=>wfMsg("extlink_sample"),
2326 "tip"=>wfMsg("extlink_tip")),
2327 array( "image"=>"button_headline.png",
2328 "open"=>"\\n== ",
2329 "close"=>" ==\\n",
2330 "sample"=>wfMsg("headline_sample"),
2331 "tip"=>wfMsg("headline_tip")),
2332 array( "image"=>"button_image.png",
2333 "open"=>"[[".$wgLang->getNsText(NS_IMAGE).":",
2334 "close"=>"]]",
2335 "sample"=>wfMsg("image_sample"),
2336 "tip"=>wfMsg("image_tip")),
2337 array( "image"=>"button_media.png",
2338 "open"=>"[[".$wgLang->getNsText(NS_MEDIA).":",
2339 "close"=>"]]",
2340 "sample"=>wfMsg("media_sample"),
2341 "tip"=>wfMsg("media_tip")),
2342 array( "image"=>"button_math.png",
2343 "open"=>"\\<math\\>",
2344 "close"=>"\\</math\\>",
2345 "sample"=>wfMsg("math_sample"),
2346 "tip"=>wfMsg("math_tip")),
2347 array( "image"=>"button_nowiki.png",
2348 "open"=>"\\<nowiki\\>",
2349 "close"=>"\\</nowiki\\>",
2350 "sample"=>wfMsg("nowiki_sample"),
2351 "tip"=>wfMsg("nowiki_tip")),
2352 array( "image"=>"button_sig.png",
2353 "open"=>"--~~~~",
2354 "close"=>"",
2355 "sample"=>"",
2356 "tip"=>wfMsg("sig_tip")),
2357 array( "image"=>"button_hr.png",
2358 "open"=>"\\n----\\n",
2359 "close"=>"",
2360 "sample"=>"",
2361 "tip"=>wfMsg("hr_tip"))
2363 $toolbar ="<script type='text/javascript'>\n";
2364 $toolbar.="document.writeln(\"<div id='toolbar'>\");\n";
2365 foreach($toolarray as $tool) {
2367 $image=$wgUploadPath."/".$tool["image"];
2368 $open=$tool["open"];
2369 $close=$tool["close"];
2370 $sample = addslashes( $tool["sample"] );
2372 // Note that we use the tip both for the ALT tag and the TITLE tag of the image.
2373 // Older browsers show a "speedtip" type message only for ALT.
2374 // Ideally these should be different, realistically they
2375 // probably don't need to be.
2376 $tip = addslashes( $tool["tip"] );
2377 $toolbar.="addButton('$image','$tip','$open','$close','$sample');\n";
2380 $toolbar.="addInfobox('" . addslashes( wfMsg( "infobox" ) ) . "','" . addslashes(wfMsg("infobox_alert")) . "','" . addslashes(wfMsg("infobox_mozvote"))."');\n";
2381 $toolbar.="document.writeln(\"</div>\");\n</script>";
2382 return $toolbar;
2386 include_once( "SkinStandard.php" );
2387 include_once( "SkinNostalgia.php" );
2388 include_once( "SkinCologneBlue.php" );
2390 if( $wgUseSmarty ) {
2391 include_once( "SkinSmarty.php" );