Oops, left debug output in
[mediawiki.git] / includes / Skin.php
blob28d60a6932d7f1d550c699e9316d16cb7086a026
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" #, "Smarty", "Montparnasse"
12 include_once( "RecentChange.php" );
14 # For some odd PHP bug, this function can't be part of a class
15 function getCategories ()
17 global $wgOut , $wgTitle , $wgUseCategoryMagic , $wgUser , $wgParser ;
18 if ( !isset ( $wgUseCategoryMagic ) || !$wgUseCategoryMagic ) return "" ;
19 if ( count ( $wgParser->mCategoryLinks ) == 0 ) return "" ;
20 if ( !$wgOut->isArticle() ) return "" ;
21 $sk = $wgUser->getSkin() ;
22 $s = "" ;
23 $s .= "\n<br>\n";
24 $s .= $sk->makeKnownLink ( "Special:Categories" , "Categories" , "article=".$wgTitle->getDBkey() ) ;
25 $t = implode ( " | " , $wgParser->mCategoryLinks ) ;
26 if ( $t != "" ) $s .= " : " ;
27 $s .= $t ;
28 return $s ;
31 class RCCacheEntry extends RecentChange
33 var $secureName, $link;
34 var $curlink , $lastlink , $usertalklink , $versionlink ;
35 var $userlink, $timestamp, $watched;
37 function newFromParent( $rc )
39 $rc2 = new RCCacheEntry;
40 $rc2->mAttribs = $rc->mAttribs;
41 $rc2->mExtra = $rc->mExtra;
42 return $rc2;
44 } ;
46 class Skin {
48 /* private */ var $lastdate, $lastline;
49 var $linktrail ; # linktrail regexp
50 var $rc_cache ; # Cache for Enhanced Recent Changes
51 var $rcCacheIndex ; # Recent Changes Cache Counter for visibility toggle
52 var $rcMoveIndex;
54 function Skin()
56 $this->linktrail = wfMsg("linktrail");
59 function getSkinNames()
61 global $wgValidSkinNames;
62 return $wgValidSkinNames;
65 function getStylesheet()
67 return "wikistandard.css";
70 function qbSetting()
72 global $wgOut, $wgUser;
74 if ( $wgOut->isQuickbarSuppressed() ) { return 0; }
75 $q = $wgUser->getOption( "quickbar" );
76 if ( "" == $q ) { $q = 0; }
77 return $q;
80 function initPage( &$out )
82 global $wgStyleSheetPath;
83 $fname = "Skin::initPage";
84 wfProfileIn( $fname );
86 $out->addLink( "shortcut icon", "", "/favicon.ico" );
88 wfProfileOut( $fname );
91 function outputPage( &$out ) {
92 global $wgDebugComments;
94 wfProfileIn( "Skin::outputPage" );
95 $this->initPage( $out );
96 $out->out( $out->headElement() );
98 $out->out( "\n<body" );
99 $ops = $this->getBodyOptions();
100 foreach ( $ops as $name => $val ) {
101 $out->out( " $name='$val'" );
103 $out->out( ">\n" );
104 if ( $wgDebugComments ) {
105 $out->out( "<!-- Wiki debugging output:\n" .
106 $out->mDebugtext . "-->\n" );
108 $out->out( $this->beforeContent() );
110 $out->out( $out->mBodytext );
112 $out->out( $this->afterContent() );
114 wfProfileClose();
115 $out->out( $out->reportTime() );
117 $out->out( "\n</body></html>" );
120 function getHeadScripts() {
121 global $wgStyleSheetPath;
122 $r = "<script type=\"text/javascript\" src=\"{$wgStyleSheetPath}/wikibits.js\"></script>\n";
123 return $r;
126 function getUserStyles()
128 global $wgOut, $wgStyleSheetPath;
129 if( $wgOut->isPrintable() ) {
130 $sheet = "wikiprintable.css";
131 } else {
132 $sheet = $this->getStylesheet();
134 $s = "<style type='text/css'><!--\n";
135 $s .= "@import url(\"$wgStyleSheetPath/$sheet\");\n";
136 $s .= "/*/*/\n"; # <-- Hide the styles from Netscape 4 without hiding them from IE/Mac
137 $s .= $this->doGetUserStyles();
138 $s .= "/* */\n";
139 $s .= "//--></style>\n";
140 return $s;
143 function doGetUserStyles()
145 global $wgUser;
147 $s = "";
148 if ( 1 == $wgUser->getOption( "underline" ) ) {
149 # Don't override browser settings
150 } else {
151 # CHECK MERGE @@@
152 # Force no underline
153 $s .= "a.stub, a.new, a.internal, a.external { " .
154 "text-decoration: none; }\n";
156 if ( 1 == $wgUser->getOption( "highlightbroken" ) ) {
157 $s .= "a.new, #quickbar a.new { color: #CC2200; }\n";
159 if ( 1 == $wgUser->getOption( "justify" ) ) {
160 $s .= "#article { text-align: justify; }\n";
162 return $s;
165 function getBodyOptions()
167 global $wgUser, $wgTitle, $wgNamespaceBackgrounds, $wgOut, $oldid, $redirect, $diff,$action;
169 if ( 0 != $wgTitle->getNamespace() ) {
170 $a = array( "bgcolor" => "#ffffec" );
172 else $a = array( "bgcolor" => "#FFFFFF" );
173 if($wgOut->isArticle() && $wgUser->getOption("editondblclick")
175 (!$wgTitle->isProtected() || $wgUser->isSysop())
178 $t = wfMsg( "editthispage" );
179 $oid = $red = "";
180 if ( $redirect ) { $red = "&redirect={$redirect}"; }
181 if ( $oldid && ! isset( $diff ) ) {
182 $oid = "&oldid={$oldid}";
184 $s = $wgTitle->getUrl( "action=edit{$oid}{$red}", false, true );
185 $s = "document.location = \"" .$s ."\";";
186 $a += array ("ondblclick" => $s);
189 $a['onload'] = $wgOut->getOnloadHandler();
190 return $a;
193 function getExternalLinkAttributes( $link, $text )
195 global $wgUser, $wgOut, $wgLang;
197 $link = urldecode( $link );
198 $link = $wgLang->checkTitleEncoding( $link );
199 $link = str_replace( "_", " ", $link );
200 $link = wfEscapeHTML( $link );
202 if ( $wgOut->isPrintable() ) { $r = " class='printable'"; }
203 else { $r = " class='external'"; }
205 if ( 1 == $wgUser->getOption( "hover" ) ) {
206 $r .= " title=\"{$link}\"";
208 return $r;
211 function getInternalLinkAttributes( $link, $text, $broken = false )
213 global $wgUser, $wgOut;
215 $link = urldecode( $link );
216 $link = str_replace( "_", " ", $link );
217 $link = wfEscapeHTML( $link );
219 if ( $wgOut->isPrintable() ) {
220 $r = " class='printable'";
221 } else if ( $broken == "stub" ) {
222 $r = " class='stub'";
223 } else if ( $broken == "yes" ) {
224 $r = " class='new'";
225 } else {
226 $r = " class='internal'";
229 if ( 1 == $wgUser->getOption( "hover" ) ) {
230 $r .= " title=\"{$link}\"";
232 return $r;
235 function getInternalLinkAttributesObj( &$nt, $text, $broken = false )
237 global $wgUser, $wgOut;
239 if ( $wgOut->isPrintable() ) {
240 $r = " class='printable'";
241 } else if ( $broken == "stub" ) {
242 $r = " class='stub'";
243 } else if ( $broken == "yes" ) {
244 $r = " class='new'";
245 } else {
246 $r = " class='internal'";
249 if ( 1 == $wgUser->getOption( "hover" ) ) {
250 $r .= ' title ="' . $nt->getEscapedText() . '"';
252 return $r;
255 function getLogo()
257 global $wgLogo;
258 return $wgLogo;
261 # This will be called immediately after the <body> tag. Split into
262 # two functions to make it easier to subclass.
264 function beforeContent()
266 global $wgUser, $wgOut, $wgSiteNotice;
268 if ( $wgOut->isPrintable() ) {
269 $s = $this->pageTitle() . $this->pageSubtitle() . "\n";
270 $s .= "\n<div class='bodytext'>";
271 return $s;
273 if( $wgSiteNotice ) {
274 $note = "\n<div id='notice' style='font-weight: bold; color: red; text-align: center'>$wgSiteNotice</div>\n";
275 } else {
276 $note = "";
278 return $this->doBeforeContent() . $note;
281 function doBeforeContent()
283 global $wgUser, $wgOut, $wgTitle, $wgLang;
284 $fname = "Skin::doBeforeContent";
285 wfProfileIn( $fname );
287 $s = "";
288 $qb = $this->qbSetting();
290 if( $langlinks = $this->otherLanguages() ) {
291 $rows = 2;
292 $borderhack = "";
293 } else {
294 $rows = 1;
295 $langlinks = false;
296 $borderhack = "class='top'";
299 $s .= "\n<div id='content'>\n<div id='topbar'>" .
300 "<table width='98%' border=0 cellspacing=0><tr>";
302 $shove = ($qb != 0);
303 $left = ($qb == 1 || $qb == 3);
304 if($wgLang->isRTL()) $left = !$left;
306 if ( !$shove ) {
307 $s .= "<td class='top' align=left valign=top rowspan='{$rows}'>" .
308 $this->logoText() . "</td>";
309 } elseif( $left ) {
310 $s .= $this->getQuickbarCompensator( $rows );
312 $l = $wgLang->isRTL() ? "right" : "left";
313 $s .= "<td {$borderhack} align='$l' valign='top'>";
315 $s .= $this->topLinks() ;
316 $s .= "<p class='subtitle'>" . $this->pageTitleLinks();
318 $r = $wgLang->isRTL() ? "left" : "right";
319 $s .= "</td>\n<td {$borderhack} valign='top' align='$r' nowrap>";
320 $s .= $this->nameAndLogin();
321 $s .= "\n<br>" . $this->searchForm() . "</td>";
323 if ( $langlinks ) {
324 $s .= "</tr>\n<tr><td class='top' colspan=\"2\">$langlinks</td>";
327 if ( $shove && !$left ) { # Right
328 $s .= $this->getQuickbarCompensator( $rows );
330 $s .= "</tr></table>\n</div>\n";
331 $s .= "\n<div id='article'>";
333 $s .= $this->pageTitle();
334 $s .= $this->pageSubtitle() ;
335 $s .= getCategories(); // For some odd reason, zhis can't be a function of the object
336 $s .= "\n<p>";
337 wfProfileOut( $fname );
338 return $s;
341 function getQuickbarCompensator( $rows = 1 )
343 return "<td width='152' rowspan='{$rows}'>&nbsp;</td>";
346 # This gets called immediately before the </body> tag.
348 function afterContent()
350 global $wgUser, $wgOut, $wgServer;
351 global $wgTitle, $wgLang;
353 if ( $wgOut->isPrintable() ) {
354 $s = "\n</div>\n";
356 $u = htmlspecialchars( $wgServer . $wgTitle->getFullURL() );
357 $u = "<a href=\"$u\">$u</a>";
358 $rf = wfMsg( "retrievedfrom", $u );
360 if ( $wgOut->isArticle() ) {
361 $lm = "<br>" . $this->lastModified();
362 } else { $lm = ""; }
364 $cr = wfMsg( "gnunote" );
365 $s .= "<p>" . $wgLang->emphasize("{$rf}{$lm} {$cr}\n");
366 return $s;
368 return $this->doAfterContent();
371 function doAfterContent()
373 global $wgUser, $wgOut, $wgLang;
374 $fname = "Skin::doAfterContent";
375 wfProfileIn( $fname );
376 wfProfileIn( "$fname-1" );
378 $s = "\n</div><br clear=all>\n";
379 $s .= "\n<div id='footer'>";
380 $s .= "<table width='98%' border=0 cellspacing=0><tr>";
382 wfProfileOut( "$fname-1" );
383 wfProfileIn( "$fname-2" );
385 $qb = $this->qbSetting();
386 $shove = ($qb != 0);
387 $left = ($qb == 1 || $qb == 3);
388 if($wgLang->isRTL()) $left = !$left;
390 if ( $shove && $left ) { # Left
391 $s .= $this->getQuickbarCompensator();
393 wfProfileOut( "$fname-2" );
394 wfProfileIn( "$fname-3" );
395 $l = $wgLang->isRTL() ? "right" : "left";
396 $s .= "<td class='bottom' align='$l' valign='top'>";
398 $s .= $this->bottomLinks();
399 $s .= "\n<br>" . $this->mainPageLink()
400 . " | " . $this->aboutLink()
401 . " | " . $this->specialLink( "recentchanges" )
402 . " | " . $this->searchForm()
403 . "<br>" . $this->pageStats();
405 $s .= "</td>";
406 if ( $shove && !$left ) { # Right
407 $s .= $this->getQuickbarCompensator();
409 $s .= "</tr></table>\n</div>\n</div>\n";
411 wfProfileOut( "$fname-3" );
412 wfProfileIn( "$fname-4" );
413 if ( 0 != $qb ) { $s .= $this->quickBar(); }
414 wfProfileOut( "$fname-4" );
415 wfProfileOut( $fname );
416 return $s;
419 function pageTitleLinks()
421 global $wgOut, $wgTitle, $oldid, $action, $diff, $wgUser, $wgLang, $wgUseApproval ;
423 $s = $this->printableLink();
424 if ( wfMsg ( "disclaimers" ) != "-" ) $s .= " | " . $this->makeKnownLink( wfMsg( "disclaimerpage" ), wfMsg( "disclaimers" ) ) ;
426 if ( $wgOut->isArticleRelated() ) {
427 if ( $wgTitle->getNamespace() == Namespace::getImage() ) {
428 $name = $wgTitle->getDBkey();
429 $link = wfEscapeHTML( wfImageUrl( $name ) );
430 $style = $this->getInternalLinkAttributes( $link, $name );
431 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>";
433 # This will show the "Approve" link if $wgUseApproval=true;
434 if ( isset ( $wgUseApproval ) && $wgUseApproval )
436 $t = $wgTitle->getDBkey();
437 $name = "Approve this article" ;
438 $link = "http://test.wikipedia.org/w/magnus/wiki.phtml?title={$t}&action=submit&doit=1" ;
439 #wfEscapeHTML( wfImageUrl( $name ) );
440 $style = $this->getExternalLinkAttributes( $link, $name );
441 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>" ;
444 if ( "history" == $action || isset( $diff ) || isset( $oldid ) ) {
445 $s .= " | " . $this->makeKnownLink( $wgTitle->getPrefixedText(),
446 wfMsg( "currentrev" ) );
449 if ( $wgUser->getNewtalk() ) {
450 # do not show "You have new messages" text when we are viewing our
451 # own talk page
453 if(!(strcmp($wgTitle->getText(),$wgUser->getName()) == 0 &&
454 $wgTitle->getNamespace()==Namespace::getTalk(Namespace::getUser()))) {
455 $n =$wgUser->getName();
456 $tl = $this->makeKnownLink( $wgLang->getNsText(
457 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
458 wfMsg("newmessageslink") );
459 $s.=" | <strong>". wfMsg( "newmessages", $tl ) . "</strong>";
462 if( $wgUser->isSysop() &&
463 (($wgTitle->getArticleId() == 0) || ($action == "history")) &&
464 ($n = $wgTitle->isDeleted() ) ) {
465 $s .= " | " . wfMsg( "thisisdeleted",
466 $this->makeKnownLink(
467 $wgLang->SpecialPage( "Undelete/" . $wgTitle->getPrefixedDBkey() ),
468 wfMsg( "restorelink", $n ) ) );
470 return $s;
473 function printableLink()
475 global $wgOut, $wgTitle, $oldid, $action;
477 $q = "";
478 foreach( $_GET as $var => $val ) {
479 if( $var != "title" && $var != "printable" )
480 $q .= urlencode( $var ) . "=" . urlencode( $val );
482 if( !empty( $q ) ) $q .= "&";
484 $s = $this->makeKnownLink( $wgTitle->getPrefixedText(),
485 WfMsg( "printableversion" ), "{$q}printable=yes" );
486 return $s;
489 function pageTitle()
491 global $wgOut, $wgTitle, $wgUser;
493 $s = "<h1 class='pagetitle'>" . $wgOut->getPageTitle() . "</h1>";
494 if($wgUser->getOption("editsectiononrightclick") && $wgTitle->userCanEdit()) { $s=$this->editSectionScript(0,$s);}
495 return $s;
498 function pageSubtitle()
500 global $wgOut,$wgTitle,$wgNamespacesWithSubpages;
502 $sub = $wgOut->getSubtitle();
503 if ( "" == $sub ) {
504 global $wgExtraSubtitle;
505 $sub = wfMsg( "fromwikipedia" ) . $wgExtraSubtitle;
507 if($wgOut->isArticle() && $wgNamespacesWithSubpages[$wgTitle->getNamespace()]) {
508 $ptext=$wgTitle->getPrefixedText();
509 if(preg_match("/\//",$ptext)) {
510 $sub.="</p><p class='subpages'>";
511 $links=explode("/",$ptext);
512 $c=0;
513 $growinglink="";
514 foreach($links as $link) {
515 $c++;
516 if ($c<count($links)) {
517 $growinglink .= $link;
518 $getlink = $this->makeLink( $growinglink, $link );
519 if(preg_match("/class='new'/i",$getlink)) { break; } # this is a hack, but it saves time
520 if ($c>1) {
521 $sub .= " | ";
522 } else {
523 $sub .="&lt; ";
525 $sub .= $getlink;
526 $growinglink.="/";
532 $s = "<p class='subtitle'>{$sub}\n";
533 return $s;
536 function nameAndLogin()
538 global $wgUser, $wgTitle, $wgLang, $wgShowIPinHeader, $wgIP;
540 $li = $wgLang->specialPage( "Userlogin" );
541 $lo = $wgLang->specialPage( "Userlogout" );
543 $s = "";
544 if ( 0 == $wgUser->getID() ) {
545 if( $wgShowIPinHeader && isset( $_COOKIE[ini_get("session.name")] ) ) {
546 $n = $wgIP;
548 $tl = $this->makeKnownLink( $wgLang->getNsText(
549 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
550 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
552 $s .= $n . " (".$tl.")";
553 } else {
554 $s .= wfMsg("notloggedin");
557 $rt = $wgTitle->getPrefixedURL();
558 if ( 0 == strcasecmp( urlencode( $lo ), $rt ) ) {
559 $q = "";
560 } else { $q = "returnto={$rt}"; }
562 $s .= "\n<br>" . $this->makeKnownLink( $li,
563 wfMsg( "login" ), $q );
564 } else {
565 $n = $wgUser->getName();
566 $rt = $wgTitle->getPrefixedURL();
567 $tl = $this->makeKnownLink( $wgLang->getNsText(
568 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
569 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
571 $tl = " ({$tl})";
573 $s .= $this->makeKnownLink( $wgLang->getNsText(
574 Namespace::getUser() ) . ":{$n}", $n ) . "{$tl}<br>" .
575 $this->makeKnownLink( $lo, wfMsg( "logout" ),
576 "returnto={$rt}" ) . " | " .
577 $this->specialLink( "preferences" );
579 $s .= " | " . $this->makeKnownLink( wfMsg( "helppage" ),
580 wfMsg( "help" ) );
582 return $s;
585 function searchForm()
587 global $search;
589 $s = "<form name='search' class='inline' method=post action=\""
590 . wfLocalUrl( "" ) . "\">"
591 . "<input type=text name=\"search\" size=19 value=\""
592 . htmlspecialchars(substr($search,0,256)) . "\">\n"
593 . "<input type=submit name=\"go\" value=\"" . wfMsg ("go") . "\">&nbsp;"
594 . "<input type=submit name=\"fulltext\" value=\"" . wfMsg ("search") . "\"></form>";
596 return $s;
599 function topLinks()
601 global $wgOut;
602 $sep = " |\n";
604 $s = $this->mainPageLink() . $sep
605 . $this->specialLink( "recentchanges" );
607 if ( $wgOut->isArticleRelated() ) {
608 $s .= $sep . $this->editThisPage()
609 . $sep . $this->historyLink();
611 # Many people don't like this dropdown box
612 #$s .= $sep . $this->specialPagesList();
614 return $s;
617 function bottomLinks()
619 global $wgOut, $wgUser, $wgTitle;
620 $sep = " |\n";
622 $s = "";
623 if ( $wgOut->isArticleRelated() ) {
624 $s .= "<strong>" . $this->editThisPage() . "</strong>";
625 if ( 0 != $wgUser->getID() ) {
626 $s .= $sep . $this->watchThisPage();
628 $s .= $sep . $this->talkLink()
629 . $sep . $this->historyLink()
630 . $sep . $this->whatLinksHere()
631 . $sep . $this->watchPageLinksLink();
633 if ( $wgTitle->getNamespace() == Namespace::getUser()
634 || $wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser()) )
637 $id=User::idFromName($wgTitle->getText());
638 $ip=User::isIP($wgTitle->getText());
640 if($id || $ip) { # both anons and non-anons have contri list
641 $s .= $sep . $this->userContribsLink();
643 if ( 0 != $wgUser->getID() ) { # show only to signed in users
644 if($id) { # can only email non-anons
645 $s .= $sep . $this->emailUserLink();
649 if ( $wgUser->isSysop() && $wgTitle->getArticleId() ) {
650 $s .= "\n<br>" . $this->deleteThisPage() .
651 $sep . $this->protectThisPage() .
652 $sep . $this->moveThisPage();
654 $s .= "<br>\n" . $this->otherLanguages();
656 return $s;
659 function pageStats()
661 global $wgOut, $wgLang, $wgArticle;
662 global $oldid, $diff, $wgDisableCounters;
664 if ( ! $wgOut->isArticle() ) { return ""; }
665 if ( isset( $oldid ) || isset( $diff ) ) { return ""; }
666 if ( 0 == $wgArticle->getID() ) { return ""; }
668 if ( $wgDisableCounters ) {
669 $s = "";
670 } else {
671 $count = $wgArticle->getCount();
672 $s = wfMsg( "viewcount", $count );
674 $s .= $this->lastModified();
675 $s .= " " . wfMsg( "gnunote" );
676 return "<span id='pagestats'>{$s}</span>";
679 function lastModified()
681 global $wgLang, $wgArticle;
683 $d = $wgLang->timeanddate( $wgArticle->getTimestamp(), true );
684 $s = " " . wfMsg( "lastmodified", $d );
685 return $s;
688 function logoText( $align = "" )
690 if ( "" != $align ) { $a = " align='{$align}'"; }
691 else { $a = ""; }
693 $mp = wfMsg( "mainpage" );
694 $titleObj = Title::newFromText( $mp );
695 $s = "<a href=\"" . $titleObj->getURL( "", true )
696 . "\"><img{$a} border=0 src=\""
697 . $this->getLogo() . "\" alt=\"" . "[{$mp}]\"></a>";
698 return $s;
701 function quickBar()
703 global $wgOut, $wgTitle, $wgUser, $action, $wgLang;
704 global $wpPreview, $wgDisableUploads, $wgRemoteUploads;
706 $fname = "Skin::quickBar";
707 wfProfileIn( $fname );
709 $tns=$wgTitle->getNamespace();
711 $s = "\n<div id='quickbar'>";
712 $s .= "\n" . $this->logoText() . "\n<hr class='sep'>";
714 $sep = "\n<br>";
715 $s .= $this->mainPageLink()
716 . $sep . $this->specialLink( "recentchanges" )
717 . $sep . $this->specialLink( "randompage" );
718 if ($wgUser->getID()) {
719 $s.= $sep . $this->specialLink( "watchlist" ) ;
720 $s .= $sep .$this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
721 wfMsg( "mycontris" ), "target=" . wfUrlencode($wgUser->getName() ) );
724 // only show watchlist link if logged in
725 if ( wfMsg ( "currentevents" ) != "-" ) $s .= $sep . $this->makeKnownLink( wfMsg( "currentevents" ), "" ) ;
726 $s .= "\n<br><hr class='sep'>";
727 $articleExists = $wgTitle->getArticleId();
728 if ( $wgOut->isArticle() || $action =="edit" || $action =="history" || $wpPreview) {
729 if($wgOut->isArticle()) {
730 $s .= "<strong>" . $this->editThisPage() . "</strong>";
731 } else { # backlink to the article in edit or history mode
732 if($articleExists){ # no backlink if no article
733 switch($tns) {
734 case 0:
735 $text = wfMsg("articlepage");
736 break;
737 case 1:
738 $text = wfMsg("viewtalkpage");
739 break;
740 case 2:
741 $text = wfMsg("userpage");
742 break;
743 case 3:
744 $text = wfMsg("viewtalkpage");
745 break;
746 case 4:
747 $text = wfMsg("wikipediapage");
748 break;
749 case 5:
750 $text = wfMsg("viewtalkpage");
751 break;
752 case 6:
753 $text = wfMsg("imagepage");
754 break;
755 case 7:
756 $text = wfMsg("viewtalkpage");
757 break;
758 default:
759 $text= wfMsg("articlepage");
762 $link = $wgTitle->getText();
763 if ($nstext = $wgLang->getNsText($tns) ) { # add namespace if necessary
764 $link = $nstext . ":" . $link ;
767 $s .= $this->makeLink( $link, $text );
768 } elseif( $wgTitle->getNamespace() != Namespace::getSpecial() ) {
769 # we just throw in a "New page" text to tell the user that he's in edit mode,
770 # and to avoid messing with the separator that is prepended to the next item
771 $s .= "<strong>" . wfMsg("newpage") . "</strong>";
777 if( $tns%2 && $action!="edit" && !$wpPreview) {
778 $s.="<br>".$this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg("postcomment"),"action=edit&section=new");
782 watching could cause problems in edit mode:
783 if user edits article, then loads "watch this article" in background and then saves
784 article with "Watch this article" checkbox disabled, the article is transparently
785 unwatched. Therefore we do not show the "Watch this page" link in edit mode
787 if ( 0 != $wgUser->getID() && $articleExists) {
788 if($action!="edit" && $action != "submit" )
790 $s .= $sep . $this->watchThisPage();
792 if ( $wgTitle->userCanEdit() )
793 $s .= $sep . $this->moveThisPage();
795 if ( $wgUser->isSysop() and $articleExists ) {
796 $s .= $sep . $this->deleteThisPage() .
797 $sep . $this->protectThisPage();
799 $s .= $sep . $this->talkLink();
800 if ($articleExists && $action !="history") {
801 $s .= $sep . $this->historyLink();
803 $s.=$sep . $this->whatLinksHere();
805 if($wgOut->isArticleRelated()) {
806 $s .= $sep . $this->watchPageLinksLink();
809 if ( Namespace::getUser() == $wgTitle->getNamespace()
810 || $wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser())
813 $id=User::idFromName($wgTitle->getText());
814 $ip=User::isIP($wgTitle->getText());
816 if($id||$ip) {
817 $s .= $sep . $this->userContribsLink();
819 if ( 0 != $wgUser->getID() ) {
820 if($id) { # can only email real users
821 $s .= $sep . $this->emailUserLink();
825 $s .= "\n<br><hr class='sep'>";
828 if ( 0 != $wgUser->getID() && ( !$wgDisableUploads || $wgRemoteUploads ) ) {
829 $s .= $this->specialLink( "upload" ) . $sep;
831 $s .= $this->specialLink( "specialpages" )
832 . $sep . $this->bugReportsLink();
834 global $wgSiteSupportPage;
835 if( $wgSiteSupportPage ) {
836 $s .= "\n<br><a href=\"" . htmlspecialchars( $wgSiteSupportPage ) .
837 "\" class=\"internal\">" . wfMsg( "sitesupport" ) . "</a>";
840 $s .= "\n<br></div>\n";
841 wfProfileOut( $fname );
842 return $s;
845 function specialPagesList()
847 global $wgUser, $wgOut, $wgLang, $wgServer, $wgRedirectScript;
848 $a = array();
850 $validSP = $wgLang->getValidSpecialPages();
852 foreach ( $validSP as $name => $desc ) {
853 if ( "" == $desc ) { continue; }
854 $a[$name] = $desc;
856 if ( $wgUser->isSysop() )
858 $sysopSP = $wgLang->getSysopSpecialPages();
860 foreach ( $sysopSP as $name => $desc ) {
861 if ( "" == $desc ) { continue; }
862 $a[$name] = $desc ;
865 if ( $wgUser->isDeveloper() )
867 $devSP = $wgLang->getDeveloperSpecialPages();
869 foreach ( $devSP as $name => $desc ) {
870 if ( "" == $desc ) { continue; }
871 $a[$name] = $desc ;
874 $go = wfMsg( "go" );
875 $sp = wfMsg( "specialpages" );
876 $spp = $wgLang->specialPage( "Specialpages" );
878 $s = "<form id=\"specialpages\" method=\"get\" class=\"inline\" " .
879 "action=\"{$wgServer}{$wgRedirectScript}\">\n";
880 $s .= "<select name=\"wpDropdown\">\n";
881 $s .= "<option value=\"{$spp}\">{$sp}</option>\n";
883 foreach ( $a as $name => $desc ) {
884 $p = $wgLang->specialPage( $name );
885 $s .= "<option value=\"{$p}\">{$desc}</option>\n";
887 $s .= "</select>\n";
888 $s .= "<input type=submit value=\"{$go}\" name=redirect>\n";
889 $s .= "</form>\n";
890 return $s;
893 function mainPageLink()
895 $mp = wfMsg( "mainpage" );
896 $s = $this->makeKnownLink( $mp, $mp );
897 return $s;
900 function copyrightLink()
902 $s = $this->makeKnownLink( wfMsg( "copyrightpage" ),
903 wfMsg( "copyrightpagename" ) );
904 return $s;
907 function aboutLink()
909 $s = $this->makeKnownLink( wfMsg( "aboutpage" ),
910 wfMsg( "aboutwikipedia" ) );
911 return $s;
915 function disclaimerLink()
917 $s = $this->makeKnownLink( wfMsg( "disclaimerpage" ),
918 wfMsg( "disclaimers" ) );
919 return $s;
922 function editThisPage()
924 global $wgOut, $wgTitle, $oldid, $redirect, $diff;
926 if ( ! $wgOut->isArticleRelated() ) {
927 $s = wfMsg( "protectedpage" );
928 } else {
929 $n = $wgTitle->getPrefixedText();
930 if ( $wgTitle->userCanEdit() ) {
931 $t = wfMsg( "editthispage" );
932 } else {
933 #$t = wfMsg( "protectedpage" );
934 $t = wfMsg( "viewsource" );
936 $oid = $red = "";
938 if ( $redirect ) { $red = "&redirect={$redirect}"; }
939 if ( $oldid && ! isset( $diff ) ) {
940 $oid = "&oldid={$oldid}";
942 $s = $this->makeKnownLink( $n, $t, "action=edit{$oid}{$red}" );
944 return $s;
947 function deleteThisPage()
949 global $wgUser, $wgOut, $wgTitle, $diff;
951 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
952 $n = $wgTitle->getPrefixedText();
953 $t = wfMsg( "deletethispage" );
955 $s = $this->makeKnownLink( $n, $t, "action=delete" );
956 } else {
957 $s = "";
959 return $s;
962 function protectThisPage()
964 global $wgUser, $wgOut, $wgTitle, $diff;
966 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
967 $n = $wgTitle->getPrefixedText();
969 if ( $wgTitle->isProtected() ) {
970 $t = wfMsg( "unprotectthispage" );
971 $q = "action=unprotect";
972 } else {
973 $t = wfMsg( "protectthispage" );
974 $q = "action=protect";
976 $s = $this->makeKnownLink( $n, $t, $q );
977 } else {
978 $s = "";
980 return $s;
983 function watchThisPage()
985 global $wgUser, $wgOut, $wgTitle, $diff;
987 if ( $wgOut->isArticleRelated() ) {
988 $n = $wgTitle->getPrefixedText();
990 if ( $wgTitle->userIsWatching() ) {
991 $t = wfMsg( "unwatchthispage" );
992 $q = "action=unwatch";
993 } else {
994 $t = wfMsg( "watchthispage" );
995 $q = "action=watch";
997 $s = $this->makeKnownLink( $n, $t, $q );
998 } else {
999 $s = wfMsg( "notanarticle" );
1001 return $s;
1004 function moveThisPage()
1006 global $wgTitle, $wgLang;
1008 if ( $wgTitle->userCanEdit() ) {
1009 $s = $this->makeKnownLink( $wgLang->specialPage( "Movepage" ),
1010 wfMsg( "movethispage" ), "target=" . $wgTitle->getPrefixedURL() );
1011 } // no message if page is protected - would be redundant
1012 return $s;
1015 function historyLink()
1017 global $wgTitle;
1019 $s = $this->makeKnownLink( $wgTitle->getPrefixedText(),
1020 wfMsg( "history" ), "action=history" );
1021 return $s;
1024 function whatLinksHere()
1026 global $wgTitle, $wgLang;
1028 $s = $this->makeKnownLink( $wgLang->specialPage( "Whatlinkshere" ),
1029 wfMsg( "whatlinkshere" ), "target=" . $wgTitle->getPrefixedURL() );
1030 return $s;
1033 function userContribsLink()
1035 global $wgTitle, $wgLang;
1037 $s = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
1038 wfMsg( "contributions" ), "target=" . $wgTitle->getPartialURL() );
1039 return $s;
1042 function emailUserLink()
1044 global $wgTitle, $wgLang;
1046 $s = $this->makeKnownLink( $wgLang->specialPage( "Emailuser" ),
1047 wfMsg( "emailuser" ), "target=" . $wgTitle->getPartialURL() );
1048 return $s;
1051 function watchPageLinksLink()
1053 global $wgOut, $wgTitle, $wgLang;
1055 if ( ! $wgOut->isArticleRelated() ) {
1056 $s = "(" . wfMsg( "notanarticle" ) . ")";
1057 } else {
1058 $s = $this->makeKnownLink( $wgLang->specialPage(
1059 "Recentchangeslinked" ), wfMsg( "recentchangeslinked" ),
1060 "target=" . $wgTitle->getPrefixedURL() );
1062 return $s;
1065 function otherLanguages()
1067 global $wgOut, $wgLang, $wgTitle, $wgUseNewInterlanguage;
1069 $a = $wgOut->getLanguageLinks();
1070 # TEST THIS @@@
1071 if ( 0 == count( $a ) ) {
1072 if ( !$wgUseNewInterlanguage ) return "";
1073 $ns = $wgLang->getNsIndex ( $wgTitle->getNamespace () ) ;
1074 if ( $ns != 0 AND $ns != 1 ) return "" ;
1075 $pn = "Intl" ;
1076 $x = "mode=addlink&xt=".$wgTitle->getDBkey() ;
1077 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1078 wfMsg( "intl" ) , $x );
1081 if ( !$wgUseNewInterlanguage ) {
1082 $s = wfMsg( "otherlanguages" ) . ": ";
1083 } else {
1084 global $wgLanguageCode ;
1085 $x = "mode=zoom&xt=".$wgTitle->getDBkey() ;
1086 $x .= "&xl=".$wgLanguageCode ;
1087 $s = $this->makeKnownLink( $wgLang->specialPage( "Intl" ),
1088 wfMsg( "otherlanguages" ) , $x ) . ": " ;
1091 $s = wfMsg( "otherlanguages" ) . ": ";
1092 $first = true;
1093 if($wgLang->isRTL()) $s .= "<span dir='LTR'>";
1094 foreach( $a as $l ) {
1095 if ( ! $first ) { $s .= " | "; }
1096 $first = false;
1098 $nt = Title::newFromText( $l );
1099 $url = $nt->getFullURL();
1100 $text = $wgLang->getLanguageName( $nt->getInterwiki() );
1102 if ( "" == $text ) { $text = $l; }
1103 $style = $this->getExternalLinkAttributes( $l, $text );
1104 $s .= "<a href=\"{$url}\"{$style}>{$text}</a>";
1106 if($wgLang->isRTL()) $s .= "</span>";
1107 return $s;
1110 function bugReportsLink()
1112 $s = $this->makeKnownLink( wfMsg( "bugreportspage" ),
1113 wfMsg( "bugreports" ) );
1114 return $s;
1117 function dateLink()
1119 global $wgLinkCache;
1120 $t1 = Title::newFromText( gmdate( "F j" ) );
1121 $t2 = Title::newFromText( gmdate( "Y" ) );
1123 $wgLinkCache->suspend();
1124 $id = $t1->getArticleID();
1125 $wgLinkCache->resume();
1127 if ( 0 == $id ) {
1128 $s = $this->makeBrokenLink( $t1->getText() );
1129 } else {
1130 $s = $this->makeKnownLink( $t1->getText() );
1132 $s .= ", ";
1134 $wgLinkCache->suspend();
1135 $id = $t2->getArticleID();
1136 $wgLinkCache->resume();
1138 if ( 0 == $id ) {
1139 $s .= $this->makeBrokenLink( $t2->getText() );
1140 } else {
1141 $s .= $this->makeKnownLink( $t2->getText() );
1143 return $s;
1146 function talkLink()
1148 global $wgLang, $wgTitle, $wgLinkCache;
1150 $tns = $wgTitle->getNamespace();
1151 if ( -1 == $tns ) { return ""; }
1153 $pn = $wgTitle->getText();
1154 $tp = wfMsg( "talkpage" );
1155 if ( Namespace::isTalk( $tns ) ) {
1156 $lns = Namespace::getSubject( $tns );
1157 switch($tns) {
1158 case 1:
1159 $text = wfMsg("articlepage");
1160 break;
1161 case 3:
1162 $text = wfMsg("userpage");
1163 break;
1164 case 5:
1165 $text = wfMsg("wikipediapage");
1166 break;
1167 case 7:
1168 $text = wfMsg("imagepage");
1169 break;
1170 default:
1171 $text= wfMsg("articlepage");
1173 } else {
1175 $lns = Namespace::getTalk( $tns );
1176 $text=$tp;
1178 $n = $wgLang->getNsText( $lns );
1179 if ( "" == $n ) { $link = $pn; }
1180 else { $link = "{$n}:{$pn}"; }
1182 $wgLinkCache->suspend();
1183 $s = $this->makeLink( $link, $text );
1184 $wgLinkCache->resume();
1186 return $s;
1189 function commentLink()
1191 global $wgLang, $wgTitle, $wgLinkCache;
1193 $tns = $wgTitle->getNamespace();
1194 if ( -1 == $tns ) { return ""; }
1196 $lns = ( Namespace::isTalk( $tns ) ) ? $tns : Namespace::getTalk( $tns );
1198 # assert Namespace::isTalk( $lns )
1200 $n = $wgLang->getNsText( $lns );
1201 $pn = $wgTitle->getText();
1203 $link = "{$n}:{$pn}";
1205 $wgLinkCache->suspend();
1206 $s = $this->makeKnownLink($link, wfMsg("postcomment"), "action=edit&section=new");
1207 $wgLinkCache->resume();
1209 return $s;
1212 # After all the page content is transformed into HTML, it makes
1213 # a final pass through here for things like table backgrounds.
1215 function transformContent( $text )
1217 return $text;
1220 # Note: This function MUST call getArticleID() on the link,
1221 # otherwise the cache won't get updated properly. See LINKCACHE.DOC.
1223 function makeLink( $title, $text = "", $query = "", $trail = "" ) {
1224 wfProfileIn( "Skin::makeLink" );
1225 $nt = Title::newFromText( $title );
1226 if ($nt) {
1227 $result = $this->makeLinkObj( Title::newFromText( $title ), $text, $query, $trail );
1228 } else {
1229 wfDebug( "Invalid title passed to Skin::makeLink(): \"$title\"\n" );
1230 $result = $text == "" ? $title : $text;
1233 wfProfileOut( "Skin::makeLink" );
1234 return $result;
1237 function makeKnownLink( $title, $text = "", $query = "", $trail = "" ) {
1238 $nt = Title::newFromText( $title );
1239 if ($nt) {
1240 return $this->makeKnownLinkObj( Title::newFromText( $title ), $text, $query, $trail );
1241 } else {
1242 wfDebug( "Invalid title passed to Skin::makeKnownLink(): \"$title\"\n" );
1243 return $text == "" ? $title : $text;
1247 function makeBrokenLink( $title, $text = "", $query = "", $trail = "" ) {
1248 $nt = Title::newFromText( $title );
1249 if ($nt) {
1250 return $this->makeBrokenLinkObj( Title::newFromText( $title ), $text, $query, $trail );
1251 } else {
1252 wfDebug( "Invalid title passed to Skin::makeBrokenLink(): \"$title\"\n" );
1253 return $text == "" ? $title : $text;
1257 function makeStubLink( $title, $text = "", $query = "", $trail = "" ) {
1258 $nt = Title::newFromText( $title );
1259 if ($nt) {
1260 return $this->makeStubLinkObj( Title::newFromText( $title ), $text, $query, $trail );
1261 } else {
1262 wfDebug( "Invalid title passed to Skin::makeStubLink(): \"$title\"\n" );
1263 return $text == "" ? $title : $text;
1267 # Pass a title object, not a title string
1268 function makeLinkObj( &$nt, $text= "", $query = "", $trail = "", $prefix = "" )
1270 global $wgOut, $wgUser;
1271 if ( $nt->isExternal() ) {
1272 $u = $nt->getFullURL();
1273 if ( "" == $text ) { $text = $nt->getPrefixedText(); }
1274 $style = $this->getExternalLinkAttributes( $link, $text );
1276 $inside = "";
1277 if ( "" != $trail ) {
1278 if ( preg_match( "/^([a-z]+)(.*)$$/sD", $trail, $m ) ) {
1279 $inside = $m[1];
1280 $trail = $m[2];
1283 $retVal = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1284 } elseif ( 0 == $nt->getNamespace() && "" == $nt->getText() ) {
1285 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1286 } elseif ( ( -1 == $nt->getNamespace() ) ||
1287 ( Namespace::getImage() == $nt->getNamespace() ) ) {
1288 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1289 } else {
1290 $aid = $nt->getArticleID() ;
1291 if ( 0 == $aid ) {
1292 $retVal = $this->makeBrokenLinkObj( $nt, $text, $query, $trail, $prefix );
1293 } else {
1294 $threshold = $wgUser->getOption("stubthreshold") ;
1295 if ( $threshold > 0 ) {
1296 $res = wfQuery ( "SELECT LENGTH(cur_text) AS x, cur_namespace, cur_is_redirect FROM cur WHERE cur_id='{$aid}'", DB_READ ) ;
1298 if ( wfNumRows( $res ) > 0 ) {
1299 $s = wfFetchObject( $res );
1300 $size = $s->x;
1301 if ( $s->cur_is_redirect OR $s->cur_namespace != 0 ) {
1302 $size = $threshold*2 ; # Really big
1304 wfFreeResult( $res );
1305 } else {
1306 $size = $threshold*2 ; # Really big
1308 } else {
1309 $size = 1 ;
1311 if ( $size < $threshold ) {
1312 $retVal = $this->makeStubLinkObj( $nt, $text, $query, $trail, $prefix );
1313 } else {
1314 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1318 return $retVal;
1321 # Pass a title object, not a title string
1322 function makeKnownLinkObj( &$nt, $text = "", $query = "", $trail = "", $prefix = "" )
1324 global $wgOut, $wgTitle;
1326 $fname = "Skin::makeKnownLinkObj";
1327 wfProfileIn( $fname );
1329 $link = $nt->getPrefixedURL();
1331 if ( "" == $link ) {
1332 $u = "";
1333 if ( "" == $text ) { $text = $nt->getFragment(); }
1334 } else {
1335 $u = $nt->getURL( $query, true );
1337 if ( "" != $nt->getFragment() ) {
1338 $u .= "#" . wfEscapeHTML( $nt->getFragment() );
1340 if ( "" == $text ) { $text = $nt->getPrefixedText(); }
1341 $style = $this->getInternalLinkAttributesObj( $nt, $text );
1343 $inside = "";
1344 if ( "" != $trail ) {
1345 if ( preg_match( $this->linktrail, $trail, $m ) ) {
1346 $inside = $m[1];
1347 $trail = $m[2];
1350 $r = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1351 wfProfileOut( $fname );
1352 return $r;
1355 # Pass a title object, not a title string
1356 function makeBrokenLinkObj( &$nt, $text = "", $query = "", $trail = "", $prefix = "" )
1358 global $wgOut, $wgUser;
1360 $fname = "Skin::makeBrokenLinkObj";
1361 wfProfileIn( $fname );
1363 $link = $nt->getPrefixedURL();
1365 if ( "" == $query ) { $q = "action=edit"; }
1366 else { $q = "action=edit&{$query}"; }
1367 $u = $nt->getURL( $q );
1369 if ( "" == $text ) { $text = $nt->getPrefixedText(); }
1370 $style = $this->getInternalLinkAttributesObj( $nt, $text, "yes" );
1372 $inside = "";
1373 if ( "" != $trail ) {
1374 if ( preg_match( $this->linktrail, $trail, $m ) ) {
1375 $inside = $m[1];
1376 $trail = $m[2];
1379 if ( $wgOut->isPrintable() ||
1380 ( 1 == $wgUser->getOption( "highlightbroken" ) ) ) {
1381 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1382 } else {
1383 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>?</a>{$trail}";
1386 wfProfileOut( $fname );
1387 return $s;
1390 # Pass a title object, not a title string
1391 function makeStubLinkObj( &$nt, $text = "", $query = "", $trail = "", $prefix = "" )
1393 global $wgOut, $wgUser;
1395 $link = $nt->getPrefixedURL();
1397 $u = $nt->getURL( $query, true );
1399 if ( "" == $text ) { $text = $nt->getPrefixedText(); }
1400 $style = $this->getInternalLinkAttributesObj( $nt, $text, "stub" );
1402 $inside = "";
1403 if ( "" != $trail ) {
1404 if ( preg_match( $this->linktrail, $trail, $m ) ) {
1405 $inside = $m[1];
1406 $trail = $m[2];
1409 if ( $wgOut->isPrintable() ||
1410 ( 1 == $wgUser->getOption( "highlightbroken" ) ) ) {
1411 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1412 } else {
1413 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>!</a>{$trail}";
1415 return $s;
1418 function fnamePart( $url )
1420 $basename = strrchr( $url, "/" );
1421 if ( false === $basename ) { $basename = $url; }
1422 else { $basename = substr( $basename, 1 ); }
1423 return wfEscapeHTML( $basename );
1426 function makeImage( $url, $alt = "" )
1428 global $wgOut;
1430 if ( "" == $alt ) { $alt = $this->fnamePart( $url ); }
1431 $s = "<img src=\"{$url}\" alt=\"{$alt}\">";
1432 return $s;
1435 function makeImageLink( $name, $url, $alt = "" ) {
1436 $nt = Title::makeTitle( Namespace::getImage(), $name );
1437 return $this->makeImageLinkObj( $nt, $alt );
1440 function makeImageLinkObj( $nt, $alt = "" ) {
1441 global $wgLang, $wgUseImageResize;
1442 $name = $nt->getDBKey();
1443 $url = wfImageUrl( $name );
1444 $align = "";
1445 $prefix = $postfix = "";
1447 if ( $wgUseImageResize ) {
1448 # Check if the alt text is of the form "options|alt text"
1449 # Options are:
1450 # * thumbnail make a thumbnail with enlarge-icon and caption, alignment depends on lang
1451 # * left no resizing, just left align. label is used for alt= only
1452 # * right same, but right aligned
1453 # * none same, but not aligned
1454 # * ___px scale to ___ pixels width, no aligning. e.g. use in taxobox
1456 $part = explode( "|", $alt);
1458 $mwThumb =& MagicWord::get( MAG_IMG_THUMBNAIL );
1459 $mwLeft =& MagicWord::get( MAG_IMG_LEFT );
1460 $mwRight =& MagicWord::get( MAG_IMG_RIGHT );
1461 $mwNone =& MagicWord::get( MAG_IMG_NONE );
1462 $mwWidth =& MagicWord::get( MAG_IMG_WIDTH );
1463 $mwCenter =& MagicWord::get( MAG_IMG_CENTER );
1464 $alt = $part[count($part)-1];
1466 $thumb=false;
1468 foreach( $part as $key => $val ) {
1469 if ( ! is_null( $mwThumb->matchVariableStartToEnd($val) ) ) {
1470 $thumb=true;
1471 } elseif ( ! is_null( $mwRight->matchVariableStartToEnd($val) ) ) {
1472 # remember to set an alignment, don't render immediately
1473 $align = "right";
1474 } elseif ( ! is_null( $mwLeft->matchVariableStartToEnd($val) ) ) {
1475 # remember to set an alignment, don't render immediately
1476 $align = "left";
1477 } elseif ( ! is_null( $mwCenter->matchVariableStartToEnd($val) ) ) {
1478 # remember to set an alignment, don't render immediately
1479 $align = "center";
1480 } elseif ( ! is_null( $mwNone->matchVariableStartToEnd($val) ) ) {
1481 # remember to set an alignment, don't render immediately
1482 $align = "none";
1483 } elseif ( ! is_null( $match = $mwWidth->matchVariableStartToEnd($val) ) ) {
1484 # $match is the image width in pixels
1485 $width = intval($match);
1488 if ( "center" == $align )
1490 $prefix = "<center>";
1491 $postfix = "</center>";
1492 $align = "none";
1495 if ( $thumb ) {
1497 # Create a thumbnail. Alignment depends on language
1498 # writing direction, # right aligned for left-to-right-
1499 # languages ("Western languages"), left-aligned
1500 # for right-to-left-languages ("Semitic languages")
1502 # If thumbnail width has not been provided, it is set
1503 # here to 180 pixels
1504 if ( $align == "" ) {
1505 $align = $wgLang->isRTL() ? "left" : "right";
1507 if ( ! isset($width) ) {
1508 $width = 180;
1510 return $prefix.$this->makeThumbLinkObj( $nt, $alt, $align, $width ).$postfix;
1512 } elseif ( isset($width) ) {
1514 # Create a resized image, without the additional thumbnail
1515 # features
1516 $url = $this->createThumb( $name, $width );
1518 } # endif $wgUseImageResize
1520 if ( empty( $alt ) ) {
1521 $alt = preg_replace( '/\.(.+?)^/', '', $name );
1523 $alt = htmlspecialchars( $alt );
1525 $u = $nt->getURL( "", true );
1526 $s = "<a href=\"{$u}\" class='image' title=\"{$alt}\">" .
1527 "<img border=\"0\" src=\"{$url}\" alt=\"{$alt}\"></a>";
1528 if ( "" != $align ) {
1529 $s = "<div class=\"float{$align}\">{$s}</div>";
1531 return $prefix.$s.$postfix;
1534 function createThumb( $name, $width ) {
1535 global $wgUploadDirectory;
1536 global $wgImageMagickConvertCommand;
1537 global $wgUseImageMagick;
1538 global $wgUseSquid, $wgInternalServer;
1539 $imgPath = wfImagePath( $name );
1540 $thumbName = $width."px-".$icon.$name;
1541 $thumbPath = wfImageThumbDir( $thumbName )."/".$thumbName;
1542 $thumbUrl = wfImageThumbUrl( $thumbName );
1544 if ( (! file_exists( $thumbPath ) && file_exists( $imgPath ))
1545 || ( filemtime($thumbPath) < filemtime($imgPath) ) ) {
1546 # Squid purging
1547 if ( $wgUseSquid ) {
1548 $urlArr = Array(
1549 $wgInternalServer.$thumbUrl
1551 wfPurgeSquidServers($urlArr);
1554 if ( $wgUseImageMagick ) {
1555 # use ImageMagick
1556 $cmd = $wgImageMagickConvertCommand .
1557 " -quality 85 -geometry {$width} ".
1558 escapeshellarg($imgPath) . " " .
1559 escapeshellarg($thumbPath);
1560 $conv = shell_exec( $cmd );
1561 } else {
1562 # Use PHP's builtin GD library functions.
1564 # First find out what kind of file this is, and select the correct
1565 # input routine for this.
1566 list($src_width, $src_height, $src_type, $src_attr) = getimagesize( $imgPath );
1567 switch( $src_type ) {
1568 case 1: # GIF
1569 $src_image = imagecreatefromgif( $imgPath );
1570 break;
1571 case 2: # JPG
1572 $src_image = imagecreatefromjpeg( $imgPath );
1573 break;
1574 case 3: # PNG
1575 $src_image = imagecreatefrompng( $imgPath );
1576 break;
1577 case 15: # WBMP for WML
1578 $src_image = imagecreatefromwbmp( $imgPath );
1579 break;
1580 case 16: # XBM
1581 $src_image = imagecreatefromxbm( $imgPath );
1582 break;
1583 default:
1584 return "Image type not supported";
1585 break;
1587 $height = floor( $src_height * ( $width/$src_width ) );
1588 $dst_image = imagecreatetruecolor( $width, $height );
1589 imagecopyresampled( $dst_image, $src_image,
1590 0,0,0,0,
1591 $width, $height, $src_width, $src_height );
1592 switch( $src_type ) {
1593 case 1: # GIF
1594 case 3: # PNG
1595 case 15: # WBMP
1596 case 16: # XBM
1597 #$thumbUrl .= ".png";
1598 #$thumbPath .= ".png";
1599 imagepng( $dst_image, $thumbPath );
1600 break;
1601 case 2: # JPEG
1602 #$thumbUrl .= ".jpg";
1603 #$thumbPath .= ".jpg";
1604 imageinterlace( $dst_image );
1605 imagejpeg( $dst_image, $thumbPath, 95 );
1606 break;
1607 default:
1608 break;
1610 imagedestroy( $dst_image );
1611 imagedestroy( $src_image );
1616 # Check for zero-sized thumbnails. Those can be generated when
1617 # no disk space is available or some other error occurs
1619 $thumbstat = stat( $thumbPath );
1620 $imgstat = stat( $imgPath );
1621 if( $thumbstat["size"] == 0 )
1623 unlink( $thumbPath );
1627 return $thumbUrl;
1630 function makeThumbLinkObj( $nt, $label = "", $align = "right", $boxwidth = 180 ) {
1631 global $wgUploadPath;
1632 $name = $nt->getDBKey();
1633 $image = Title::makeTitle( Namespace::getImage(), $name );
1634 $url = wfImageUrl( $name );
1635 $path = wfImagePath( $name );
1637 #$label = htmlspecialchars( $label );
1638 $alt = preg_replace( "/<[^>]*>/", "", $label);
1639 $alt = htmlspecialchars( $alt );
1641 list($width, $height, $type, $attr) = getimagesize( $path );
1642 $boxheight = intval( $height/($width/$boxwidth) );
1643 if ( $boxwidth > $width ) {
1644 $boxwidth = $width;
1645 $boxheight = $height;
1648 $thumbUrl = $this->createThumb( $name, $boxwidth );
1650 $u = $nt->getURL( "", true );
1652 $more = htmlspecialchars(wfMsg( "thumbnail-more" ));
1654 $s = "<div class=\"thumbnail-{$align}\" style=\"width:{$boxwidth}px;\">" .
1655 "<a href=\"{$u}\" class=\"internal\" title=\"{$alt}\">" .
1656 "<img border=\"0\" src=\"{$thumbUrl}\" alt=\"{$alt}\" width=\"{$boxwidth}\" height=\"{$boxheight}\"></a>" .
1657 "<a href=\"{$u}\" class=\"internal\" title=\"{$more}\">" .
1658 "<img border=\"0\" src=\"{$wgUploadPath}/magnify-clip.png\" width=\"26\" height=\"24\" align=\"right\" alt=\"{$more}\"></a>" .
1659 "<p>{$label}</p></div>";
1660 return $s;
1663 function makeMediaLink( $name, $url, $alt = "" ) {
1664 $nt = Title::makeTitle( Namespace::getMedia(), $name );
1665 return $this->makeMediaLinkObj( $nt, $alt );
1668 function makeMediaLinkObj( $nt, $alt = "" )
1670 $name = $nt->getDBKey();
1671 $url = wfImageUrl( $name );
1672 if ( empty( $alt ) ) {
1673 $alt = preg_replace( '/\.(.+?)^/', '', $name );
1676 $u = htmlspecialchars( $url );
1677 $s = "<a href=\"{$u}\" class='internal' title=\"{$alt}\">{$alt}</a>";
1678 return $s;
1681 function specialLink( $name, $key = "" )
1683 global $wgLang;
1685 if ( "" == $key ) { $key = strtolower( $name ); }
1686 $pn = $wgLang->ucfirst( $name );
1687 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1688 wfMsg( $key ) );
1691 # Called by history lists and recent changes
1694 # Returns text for the start of the tabular part of RC
1695 function beginRecentChangesList()
1697 $this->rc_cache = array() ;
1698 $this->rcMoveIndex = 0;
1699 $this->rcCacheIndex = 0 ;
1700 $this->lastdate = "";
1701 return "";
1704 function beginImageHistoryList()
1706 $s = "\n<h2>" . wfMsg( "imghistory" ) . "</h2>\n" .
1707 "<p>" . wfMsg( "imghistlegend" ) . "\n<ul>";
1708 return $s;
1711 # Returns text for the end of RC
1712 # If enhanced RC is in use, returns pretty much all the text
1713 function endRecentChangesList()
1715 $s = $this->recentChangesBlock() ;
1716 $s .= "</ul>\n";
1717 return $s;
1720 # Enhanced RC ungrouped line
1721 function recentChangesBlockLine ( $rcObj )
1723 global $wgUploadPath, $wgLang ;
1725 # Get rc_xxxx variables
1726 extract( $rcObj->mAttribs ) ;
1727 $curIdEq = "curid=$rc_cur_id";
1729 # Spacer image
1730 $r = "" ;
1731 $r .= "<img src='{$wgUploadPath}/Arr_.png' width=12 height=12 border=0>" ; $r .= "<tt>" ;
1733 if ( $rc_type == RC_MOVE ) {
1734 $r .= "&nbsp;&nbsp;";
1735 } else {
1736 # M & N (minor & new)
1737 $M = wfMsg( "minoreditletter" );
1738 $N = wfMsg( "newpageletter" );
1740 if ( $rc_type == RC_NEW ) {
1741 $r .= $N ;
1742 } else {
1743 $r .= "&nbsp;" ;
1745 if ( $rc_minor ) {
1746 $r .= $M ;
1747 } else {
1748 $r .= "&nbsp;" ;
1752 # Timestamp
1753 $r .= " ".$rcObj->timestamp." " ;
1754 $r .= "</tt>" ;
1756 # Article link
1757 $link = $rcObj->link ;
1758 if ( $rcObj->watched ) $link = "<strong>{$link}</strong>" ;
1759 $r .= $link ;
1761 # Cur
1762 $r .= " (" ;
1763 $r .= $rcObj->curlink ;
1764 $r .= "; " ;
1766 # Hist
1767 $r .= $this->makeKnownLinkObj( $rcObj->getTitle(), wfMsg( "hist" ), "{$curIdEq}&action=history" );
1769 # User/talk
1770 $r .= ") . . ".$rcObj->userlink ;
1771 $r .= $rcObj->usertalklink ;
1773 # Comment
1774 if ( $rc_comment != "" && $rc_type != RC_MOVE ) {
1775 $r .= $wgLang->emphasize( " (".wfEscapeHTML($rc_comment).")" );
1777 $r .= "<br>\n" ;
1778 return $r ;
1781 # Enhanced RC group
1782 function recentChangesBlockGroup ( $block )
1784 global $wgUploadPath, $wgLang ;
1786 $r = "" ;
1787 $M = wfMsg( "minoreditletter" );
1788 $N = wfMsg( "newpageletter" );
1790 # Collate list of users
1791 $isnew = false ;
1792 $userlinks = array () ;
1793 foreach ( $block AS $rcObj ) {
1794 $oldid = $rcObj->mAttribs['rc_last_oldid'];
1795 if ( $rcObj->mAttribs['rc_new'] ) $isnew = true ;
1796 $u = $rcObj->userlink ;
1797 if ( !isset ( $userlinks[$u] ) ) $userlinks[$u] = 0 ;
1798 $userlinks[$u]++ ;
1801 # Sort the list and convert to text
1802 krsort ( $userlinks ) ;
1803 asort ( $userlinks ) ;
1804 $users = array () ;
1805 foreach ( $userlinks as $userlink => $count) {
1806 $text = $userlink ;
1807 if ( $count > 1 ) $text .= " ({$count}&times;)" ;
1808 array_push ( $users , $text ) ;
1810 $users = " <font size='-1'>[".implode("; ",$users)."]</font>" ;
1812 # Arrow
1813 $rci = "RCI{$this->rcCacheIndex}" ;
1814 $rcl = "RCL{$this->rcCacheIndex}" ;
1815 $rcm = "RCM{$this->rcCacheIndex}" ;
1816 $tl = "<a href='javascript:toggleVisibility(\"{$rci}\",\"{$rcm}\",\"{$rcl}\")'>" ;
1817 $tl .= "<span id='{$rcm}'><img src='{$wgUploadPath}/Arr_r.png' width=12 height=12 border=0></span>" ;
1818 $tl .= "<span id='{$rcl}' style='display:none'><img src='{$wgUploadPath}/Arr_d.png' width=12 height=12 border=0></span>" ;
1819 $tl .= "</a>" ;
1820 $r .= $tl ;
1822 # Main line
1823 # M/N
1824 $r .= "<tt>" ;
1825 if ( $isnew ) $r .= $N ;
1826 else $r .= "&nbsp;" ;
1827 $r .= "&nbsp;" ; # Minor
1829 # Timestamp
1830 $r .= " ".$block[0]->timestamp." " ;
1831 $r .= "</tt>" ;
1833 # Article link
1834 $link = $block[0]->link ;
1835 if ( $block[0]->watched ) $link = "<strong>{$link}</strong>" ;
1836 $r .= $link ;
1838 $curIdEq = "curid=" . $block[0]->mAttribs['rc_cur_id'];
1839 if ( $block[0]->mAttribs['rc_type'] != RC_LOG ) {
1840 # Changes
1841 $r .= " (".count($block)." " ;
1842 if ( $isnew ) $r .= wfMsg("changes");
1843 else $r .= $this->makeKnownLinkObj( $block[0]->getTitle() , wfMsg("changes") ,
1844 "{$curIdEq}&diff=0&oldid=".$oldid ) ;
1845 $r .= "; " ;
1847 # History
1848 $r .= $this->makeKnownLinkObj( $block[0]->getTitle(), wfMsg( "history" ), "{$curIdEq}&action=history" );
1849 $r .= ")" ;
1852 $r .= $users ;
1853 $r .= "<br>\n" ;
1855 # Sub-entries
1856 $r .= "<div id='{$rci}' style='display:none'>" ;
1857 foreach ( $block AS $rcObj ) {
1858 # Get rc_xxxx variables
1859 extract( $rcObj->mAttribs );
1861 $r .= "<img src='{$wgUploadPath}/Arr_.png' width=12 height=12 border=0>";
1862 $r .= "<tt>&nbsp; &nbsp; &nbsp; &nbsp;" ;
1863 if ( $rc_new ) $r .= $N ;
1864 else $r .= "&nbsp;" ;
1865 if ( $rc_minor ) $r .= $M ;
1866 else $r .= "&nbsp;" ;
1867 $r .= "</tt>" ;
1869 $o = "" ;
1870 if ( $rc_last_oldid != 0 ) {
1871 $o = "oldid=".$rc_last_oldid ;
1873 if ( $rc_type == RC_LOG ) {
1874 $link = $rcObj->timestamp ;
1875 } else {
1876 $link = $this->makeKnownLink( $rcObj->getTitle(), $rcObj->timestamp , "{$curIdEq}&$o" ) ;
1878 $link = "<tt>{$link}</tt>" ;
1880 $r .= $link ;
1881 $r .= " (" ;
1882 $r .= $rcObj->curlink ;
1883 $r .= "; " ;
1884 $r .= $rcObj->lastlink ;
1885 $r .= ") . . ".$rcObj->userlink ;
1886 $r .= $rcObj->usertalklink ;
1887 if ( $rc_comment != "" ) {
1888 $r .= $wgLang->emphasize( " (".wfEscapeHTML($rc_comment).")" ) ;
1890 $r .= "<br>\n" ;
1892 $r .= "</div>\n" ;
1894 $this->rcCacheIndex++ ;
1895 return $r ;
1898 # If enhanced RC is in use, this function takes the previously cached
1899 # RC lines, arranges them, and outputs the HTML
1900 function recentChangesBlock ()
1902 global $wgUploadPath ;
1903 if ( count ( $this->rc_cache ) == 0 ) return "" ;
1904 #$k = array_keys ( $this->rc_cache ) ;
1905 foreach ( $this->rc_cache AS $secureName => $block ) {
1906 if ( count ( $block ) < 2 ) {
1907 $r .= $this->recentChangesBlockLine ( array_shift ( $block ) ) ;
1908 } else {
1909 $r .= $this->recentChangesBlockGroup ( $block ) ;
1913 return "<div align=left>{$r}</div>" ;
1916 # Called in a loop over all displayed RC entries
1917 # Either returns the line, or caches it for later use
1918 function recentChangesLine( &$rc, $watched = false )
1920 global $wgUser ;
1921 $usenew = $wgUser->getOption( "usenewrc" );
1922 if ( $usenew )
1923 $line = $this->recentChangesLineNew ( $rc, $watched ) ;
1924 else
1925 $line = $this->recentChangesLineOld ( $rc, $watched ) ;
1926 return $line ;
1929 function recentChangesLineOld( &$rc, $watched = false )
1931 global $wgTitle, $wgLang, $wgUser;
1933 # Extract DB fields into local scope
1934 extract( $rc->mAttribs );
1935 $curIdEq = "curid=" . $rc_cur_id;
1937 # Make date header if necessary
1938 $date = $wgLang->date( $rc_timestamp, true);
1939 $s = "";
1940 if ( $date != $this->lastdate ) {
1941 if ( "" != $this->lastdate ) { $s .= "</ul>\n"; }
1942 $s .= "<h4>{$date}</h4>\n<ul>";
1943 $this->lastdate = $date;
1945 $s .= "<li> ";
1947 if ( $rc_type == RC_MOVE ) {
1948 # Diff
1949 $s .= "(" . wfMsg( "diff" ) . ") (";
1950 # Hist
1951 $s .= $this->makeKnownLinkObj( $rc->getMovedToTitle(), wfMsg( "hist" ), "action=history" ) .
1952 ") . . ";
1954 # "[[x]] moved to [[y]]"
1956 $s .= wfMsg( "1movedto2", $this->makeKnownLinkObj( $rc->getTitle(), "", "redirect=no" ),
1957 $this->makeKnownLinkObj( $rc->getMovedToTitle(), "" ) );
1959 } else {
1960 # Diff link
1961 if ( $rc_type == RC_NEW || $rc_type == RC_LOG ) {
1962 $diffLink = wfMsg( "diff" );
1963 } else {
1964 $diffLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( "diff" ),
1965 "{$curIdEq}&diff={$rc_this_oldid}&oldid={$rc_last_oldid}" );
1967 $s .= "($diffLink) (";
1969 # History link
1970 $s .= $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( "hist" ), "{$curIdEq}&action=history" );
1971 $s .= ") . . ";
1973 # M and N (minor and new)
1974 $M = wfMsg( "minoreditletter" );
1975 $N = wfMsg( "newpageletter" );
1976 if ( $rc_minor ) { $s .= " <strong>{$M}</strong>"; }
1977 if ( $rc_type == RC_NEW ) { $s .= "<strong>{$N}</strong>"; }
1979 # Article link
1980 $articleLink = $this->makeKnownLinkObj( $rc->getTitle(), "" );
1982 if ( $watched ) {
1983 $articleLink = "<strong>{$articleLink}</strong>";
1985 $s .= " $articleLink";
1989 # Timestamp
1990 $s .= "; " . $wgLang->time( $rc_timestamp, true ) . " . . ";
1992 # User link (or contributions for unregistered users)
1993 if ( 0 == $rc_user ) {
1994 $userLink = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
1995 $rc_user_text, "target=" . $rc_user_text );
1996 } else {
1997 $userLink = $this->makeLink( $wgLang->getNsText( NS_USER ) . ":{$rc_user_text}", $rc_user_text );
1999 $s .= $userLink;
2001 # User talk link
2002 $talkname=$wgLang->getNsText(NS_TALK); # use the shorter name
2003 global $wgDisableAnonTalk;
2004 if( 0 == $rc_user && $wgDisableAnonTalk ) {
2005 $userTalkLink = "";
2006 } else {
2007 $utns=$wgLang->getNsText(NS_USER_TALK);
2008 $userTalkLink= $this->makeLink($utns . ":{$rc_user_text}", $talkname );
2010 # Block link
2011 $blockLink="";
2012 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2013 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2014 "Blockip" ), wfMsg( "blocklink" ), "ip={$rc_user_text}" );
2017 if($blockLink) {
2018 if($userTalkLink) $userTalkLink .= " | ";
2019 $userTalkLink .= $blockLink;
2021 if($userTalkLink) $s.=" ({$userTalkLink})";
2023 # Add comment
2024 if ( "" != $rc_comment && "*" != $rc_comment && $rc_type != RC_MOVE ) {
2025 $s .= $wgLang->emphasize(" (" . wfEscapeHTML( $rc_comment ) . ")");
2027 $s .= "</li>\n";
2029 return $s;
2032 # function recentChangesLineNew( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched = false, $oldid = 0 , $diffid = 0 )
2033 function recentChangesLineNew( &$baseRC, $watched = false )
2035 global $wgTitle, $wgLang, $wgUser;
2037 # Create a specialised object
2038 $rc = RCCacheEntry::newFromParent( $baseRC ) ;
2040 # Extract fields from DB into the function scope (rc_xxxx variables)
2041 extract( $rc->mAttribs );
2042 $curIdEq = "curid=" . $rc_cur_id;
2044 # If it's a new day, add the headline and flush the cache
2045 $date = $wgLang->date( $rc_timestamp, true);
2046 $ret = "" ;
2047 if ( $date != $this->lastdate ) {
2048 # Process current cache
2049 $ret = $this->recentChangesBlock () ;
2050 $this->rc_cache = array() ;
2051 $ret .= "<h4>{$date}</h4>\n";
2052 $this->lastdate = $date;
2055 # Make article link
2056 if ( $rc_type == RC_MOVE ) {
2057 $clink = $this->makeKnownLinkObj( $rc->getTitle(), "", "redirect=no" );
2058 $clink .= " " . wfMsg("movedto") . " ";
2059 $clink .= $this->makeKnownLinkObj( $rc->getMovedToTitle(), "" );
2060 } else {
2061 $clink = $this->makeKnownLinkObj( $rc->getTitle(), "" ) ;
2064 $time = $wgLang->time( $rc_timestamp, true );
2065 $rc->watched = $watched ;
2066 $rc->link = $clink ;
2067 $rc->timestamp = $time;
2069 # Make "cur" link
2070 if ( ( $rc_type == RC_NEW && $rc_this_oldid == 0 ) || $rc_type == RC_LOG || $rc_type == RC_MOVE) {
2071 $curLink = wfMsg( "cur" );
2072 } else {
2073 $curLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( "cur" ),
2074 "{$curIdEq}&diff=0&oldid={$rc_this_oldid}" );
2077 # Make "last" link
2078 $titleObj = $rc->getTitle();
2079 if ( $rc_last_oldid == 0 || $rc_type == RC_LOG || $rc_type == RC_MOVE ) {
2080 $lastLink = wfMsg( "last" );
2081 } else {
2082 $lastLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( "last" ),
2083 "{$curIdEq}&diff={$rc_this_oldid}&oldid={$rc_last_oldid}" );
2086 # Make user link (or user contributions for unregistered users)
2087 if ( 0 == $rc_user ) {
2088 $userLink = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
2089 $rc_user_text, "target=" . $rc_user_text );
2090 } else {
2091 $userLink = $this->makeLink( $wgLang->getNsText(
2092 Namespace::getUser() ) . ":{$rc_user_text}", $rc_user_text );
2095 $rc->userlink = $userLink ;
2096 $rc->lastlink = $lastLink ;
2097 $rc->curlink = $curLink ;
2099 # Make user talk link
2100 $utns=$wgLang->getNsText(NS_USER_TALK);
2101 $talkname=$wgLang->getNsText(NS_TALK); # use the shorter name
2102 $userTalkLink= $this->makeLink($utns . ":{$rc_user_text}", $talkname );
2104 global $wgDisableAnonTalk;
2105 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2106 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2107 "Blockip" ), wfMsg( "blocklink" ), "ip={$rc_user_text}" );
2108 if( $wgDisableAnonTalk )
2109 $rc->usertalklink = " ({$blockLink})";
2110 else
2111 $rc->usertalklink = " ({$userTalkLink} | {$blockLink})";
2112 } else {
2113 if( $wgDisableAnonTalk && ($rc_user == 0) )
2114 $rc->usertalklink = "";
2115 else
2116 $rc->usertalklink = " ({$userTalkLink})";
2119 # Put accumulated information into the cache, for later display
2120 # Page moves go on their own line
2121 $title = $rc->getTitle();
2122 $secureName = $title->getPrefixedDBkey();
2123 if ( $rc_type == RC_MOVE ) {
2124 # Use an @ character to prevent collision with page names
2125 $this->rc_cache["@@" . ($rcMoveIndex++)] = array($rc);
2126 } else {
2127 if ( !isset ( $this->rc_cache[$secureName] ) ) $this->rc_cache[$secureName] = array() ;
2128 array_push ( $this->rc_cache[$secureName] , $rc ) ;
2130 return $ret;
2133 function endImageHistoryList()
2135 $s = "</ul>\n";
2136 return $s;
2139 function imageHistoryLine( $iscur, $ts, $img, $u, $ut, $size, $c )
2141 global $wgUser, $wgLang, $wgTitle;
2143 $dt = $wgLang->timeanddate( $ts, true );
2144 $del = wfMsg( "deleteimg" );
2145 $cur = wfMsg( "cur" );
2147 if ( $iscur ) {
2148 $url = wfImageUrl( $img );
2149 $rlink = $cur;
2150 if ( $wgUser->isSysop() ) {
2151 $link = $wgTitle->getURL( "image=" . $wgTitle->getPartialURL() .
2152 "&action=delete", true );
2153 $style = $this->getInternalLinkAttributes( $link, $del );
2155 $dlink = "<a href=\"{$link}\"{$style}>{$del}</a>";
2156 } else {
2157 $dlink = $del;
2159 } else {
2160 $url = wfEscapeHTML( wfImageArchiveUrl( $img ) );
2161 if( $wgUser->getID() != 0 ) {
2162 $rlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2163 wfMsg( "revertimg" ), "action=revert&oldimage=" .
2164 urlencode( $img ) );
2165 $dlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2166 $del, "action=delete&oldimage=" . urlencode( $img ) );
2167 } else {
2168 # Having live active links for non-logged in users
2169 # means that bots and spiders crawling our site can
2170 # inadvertently change content. Baaaad idea.
2171 $rlink = wfMsg( "revertimg" );
2172 $dlink = $del;
2175 if ( 0 == $u ) { $ul = $ut; }
2176 else { $ul = $this->makeLink( $wgLang->getNsText(
2177 Namespace::getUser() ) . ":{$ut}", $ut ); }
2179 $nb = wfMsg( "nbytes", $size );
2180 $style = $this->getInternalLinkAttributes( $url, $dt );
2182 $s = "<li> ({$dlink}) ({$rlink}) <a href=\"{$url}\"{$style}>{$dt}</a>"
2183 . " . . {$ul} ({$nb})";
2185 if ( "" != $c && "*" != $c ) {
2186 $s .= $wgLang->emphasize(" (" . wfEscapeHTML( $c ) . ")");
2188 $s .= "</li>\n";
2189 return $s;
2192 function tocIndent($level) {
2194 while($level-->0) $rv.="<div style=\"margin-left:2em;\">\n";
2195 return $rv;
2199 function tocUnindent($level) {
2200 $rv = "";
2201 while($level-->0) $rv.="</div>\n";
2202 return $rv;
2205 // parameter level defines if we are on an indentation level
2206 function tocLine($anchor,$tocline,$level) {
2208 if($level) {
2210 return "<A CLASS=\"internal\" HREF=\"#".$anchor."\">".$tocline."</A><BR>\n";
2211 } else {
2213 return "<div style=\"margin-bottom:0px;\">\n".
2214 "<A CLASS=\"internal\" HREF=\"#".$anchor."\">".$tocline."</A><BR>\n".
2215 "</div>\n";
2220 function tocTable($toc) {
2221 // note to CSS fanatics: putting this in a div does not work -- div won't auto-expand
2222 global $printable;
2224 if (!$printable) {
2225 $hideline = " <script type='text/javascript'>showTocToggle(\"" . wfMsg("showtoc") . "\",\"" . wfMsg("hidetoc") . "\")</script>";
2227 return
2228 "<p><table border=\"0\" id=\"toc\"><tr><td align=\"center\">\n".
2229 "<b>".wfMsg("toc")."</b>" .
2230 $hideline .
2231 "</td></tr><tr id='tocinside'><td>\n".
2232 $toc."</td></tr></table><P>\n";
2235 # These two do not check for permissions: check $wgTitle->userCanEdit before calling them
2236 function editSectionScript($section,$head) {
2238 global $wgTitle,$wgUser,$oldid;
2239 if($oldid) return $head;
2240 $url = $wgTitle->getUrl( "action=edit&section=$section", true );
2241 return "<span onContextMenu='document.location=\"".$url."\";return false;'>{$head}</span>";
2244 function editSectionLink($section) {
2245 global $printable,$oldid;
2246 global $wgTitle, $wgUser, $wgLang;
2248 if( isset( $oldid ) ) return "";
2249 if( isset( $printable ) ) return "";
2251 $editurl = "&section={$section}";
2252 $url = $this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg("editsection"),"action=edit".$editurl);
2254 if( $wgLang->isRTL() ) {
2255 $farside = "left";
2256 $nearside = "right";
2257 } else {
2258 $farside = "right";
2259 $nearside = "left";
2261 return "<div style=\"float:$farside;margin-$nearside:5px;\"><small>[".$url."]</small></div>";
2265 // This function is called by EditPage.php and shows a bulletin board style
2266 // toolbar for common editing functions. It can be disabled in the user preferences.
2267 // The necsesary JavaScript code can be found in style/wikibits.js.
2268 function getEditToolbar() {
2270 global $wgUploadPath,$wgLang;
2272 // toolarray an array of arrays which each include the filename of
2273 // the button image (without path), the opening tag, the closing tag,
2274 // and optionally a sample text that is inserted between the two when no
2275 // selection is highlighted.
2276 // The tip text is shown when the user moves the mouse over the button.
2277 $toolarray=array(
2278 array( "image"=>"button_bold.png",
2279 "open"=>"\'\'\'",
2280 "close"=>"\'\'\'",
2281 "sample"=>wfMsg("bold_sample"),
2282 "tip"=>wfMsg("bold_tip")),
2283 array( "image"=>"button_italic.png",
2284 "open"=>"\'\'",
2285 "close"=>"\'\'",
2286 "sample"=>wfMsg("italic_sample"),
2287 "tip"=>wfMsg("italic_tip")),
2288 array( "image"=>"button_link.png",
2289 "open"=>"[[",
2290 "close"=>"]]",
2291 "sample"=>wfMsg("link_sample"),
2292 "tip"=>wfMsg("link_tip")),
2293 array( "image"=>"button_extlink.png",
2294 "open"=>"[",
2295 "close"=>"]",
2296 "sample"=>wfMsg("extlink_sample"),
2297 "tip"=>wfMsg("extlink_tip")),
2298 array( "image"=>"button_headline.png",
2299 "open"=>"\\n== ",
2300 "close"=>" ==\\n",
2301 "sample"=>wfMsg("headline_sample"),
2302 "tip"=>wfMsg("headline_tip")),
2303 array( "image"=>"button_image.png",
2304 "open"=>"[[".$wgLang->getNsText(NS_IMAGE).":",
2305 "close"=>"]]",
2306 "sample"=>wfMsg("image_sample"),
2307 "tip"=>wfMsg("image_tip")),
2308 array( "image"=>"button_media.png",
2309 "open"=>"[[".$wgLang->getNsText(NS_MEDIA).":",
2310 "close"=>"]]",
2311 "sample"=>wfMsg("media_sample"),
2312 "tip"=>wfMsg("media_tip")),
2313 array( "image"=>"button_math.png",
2314 "open"=>"\\<math\\>",
2315 "close"=>"\\</math\\>",
2316 "sample"=>wfMsg("math_sample"),
2317 "tip"=>wfMsg("math_tip")),
2318 array( "image"=>"button_nowiki.png",
2319 "open"=>"\\<nowiki\\>",
2320 "close"=>"\\</nowiki\\>",
2321 "sample"=>wfMsg("nowiki_sample"),
2322 "tip"=>wfMsg("nowiki_tip")),
2323 array( "image"=>"button_sig.png",
2324 "open"=>"--~~~~",
2325 "close"=>"",
2326 "sample"=>"",
2327 "tip"=>wfMsg("sig_tip")),
2328 array( "image"=>"button_hr.png",
2329 "open"=>"\\n----\\n",
2330 "close"=>"",
2331 "sample"=>"",
2332 "tip"=>wfMsg("hr_tip"))
2334 $toolbar.="<script type='text/javascript'>\n";
2335 $toolbar.="document.writeln(\"<div id='toolbar'>\");\n";
2336 foreach($toolarray as $tool) {
2338 $image=$wgUploadPath."/".$tool["image"];
2339 $open=$tool["open"];
2340 $close=$tool["close"];
2341 $sample = addslashes( $tool["sample"] );
2343 // Note that we use the tip both for the ALT tag and the TITLE tag of the image.
2344 // Older browsers show a "speedtip" type message only for ALT.
2345 // Ideally these should be different, realistically they
2346 // probably don't need to be.
2347 $tip = addslashes( $tool["tip"] );
2348 $toolbar.="addButton('$image','$tip','$open','$close','$sample');\n";
2351 $toolbar.="addInfobox('" . addslashes( wfMsg( "infobox" ) ) . "');\n";
2352 $toolbar.="document.writeln(\"</div>\");\n</script>";
2353 return $toolbar;
2357 include_once( "SkinStandard.php" );
2358 include_once( "SkinNostalgia.php" );
2359 include_once( "SkinCologneBlue.php" );
2361 #include_once( "SkinSmarty.php" );