minor change
[mediawiki.git] / includes / Skin.php
blobcdf16ef49371085e88c3738fc2bdc53d584bfdb5
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 ;
18 if ( !isset ( $wgUseCategoryMagic ) || !$wgUseCategoryMagic ) return "" ;
19 if ( count ( $wgOut->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 ( " | " , $wgOut->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;
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()
58 function getSkinNames()
60 global $wgValidSkinNames;
61 return $wgValidSkinNames;
64 function getStylesheet()
66 return "wikistandard.css";
69 function qbSetting()
71 global $wgOut, $wgUser;
73 if ( $wgOut->isQuickbarSupressed() ) { return 0; }
74 $q = $wgUser->getOption( "quickbar" );
75 if ( "" == $q ) { $q = 0; }
76 return $q;
79 function initPage( &$out )
81 global $wgStyleSheetPath;
82 $fname = "Skin::initPage";
83 wfProfileIn( $fname );
85 $out->addLink( "shortcut icon", "", "/favicon.ico" );
86 if ( $out->isPrintable() ) { $ss = "wikiprintable.css"; }
87 else { $ss = $this->getStylesheet(); }
88 $out->addLink( "stylesheet", "", "{$wgStyleSheetPath}/{$ss}" );
89 wfProfileOut( $fname );
92 function outputPage( &$out ) {
93 global $wgDebugComments;
95 wfProfileIn( "Skin::outputPage" );
96 $this->initPage( $out );
97 $out->out( $out->headElement() );
99 $out->out( "\n<body" );
100 $ops = $this->getBodyOptions();
101 foreach ( $ops as $name => $val ) {
102 $out->out( " $name='$val'" );
104 $out->out( ">\n" );
105 if ( $wgDebugComments ) {
106 $out->out( "<!-- Wiki debugging output:\n" .
107 $out->mDebugtext . "-->\n" );
109 $out->out( $this->beforeContent() );
111 $out->out( $out->mBodytext );
113 $out->out( $this->afterContent() );
115 wfProfileClose();
116 $out->out( $out->reportTime() );
118 $out->out( "\n</body></html>" );
121 function getHeadScripts() {
122 global $wgStyleSheetPath;
123 $r = "<script type=\"text/javascript\" src=\"{$wgStyleSheetPath}/wikibits.js\"></script>\n";
124 return $r;
127 function getUserStyles()
129 $s = "<style type='text/css'><!--\n";
130 $s .= $this->doGetUserStyles();
131 $s .= "//--></style>\n";
132 return $s;
135 function doGetUserStyles()
137 global $wgUser;
139 $s = "";
140 if ( 1 == $wgUser->getOption( "underline" ) ) {
141 # Don't override browser settings
142 } else {
143 # CHECK MERGE @@@
144 # Force no underline
145 $s .= "a.stub, a.new, a.internal, a.external { " .
146 "text-decoration: none; }\n";
148 if ( 1 == $wgUser->getOption( "highlightbroken" ) ) {
149 $s .= "a.new, #quickbar a.new { color: #CC2200; }\n";
151 if ( 1 == $wgUser->getOption( "justify" ) ) {
152 $s .= "#article { text-align: justify; }\n";
154 return $s;
157 function getBodyOptions()
159 global $wgUser, $wgTitle, $wgNamespaceBackgrounds, $wgOut, $oldid, $redirect, $diff,$action;
161 if ( 0 != $wgTitle->getNamespace() ) {
162 $a = array( "bgcolor" => "#ffffec" );
164 else $a = array( "bgcolor" => "#FFFFFF" );
165 if($wgOut->isArticle() && $wgUser->getOption("editondblclick")
167 (!$wgTitle->isProtected() || $wgUser->isSysop())
170 $n = $wgTitle->getPrefixedURL();
171 $t = wfMsg( "editthispage" );
172 $oid = $red = "";
173 if ( $redirect ) { $red = "&redirect={$redirect}"; }
174 if ( $oldid && ! isset( $diff ) ) {
175 $oid = "&oldid={$oldid}";
177 $s = wfLocalUrlE($n,"action=edit{$oid}{$red}");
178 $s = "document.location = \"" .$s ."\";";
179 $a += array ("ondblclick" => $s);
182 $a['onload'] = $wgOut->getOnloadHandler();
183 return $a;
186 function getExternalLinkAttributes( $link, $text )
188 global $wgUser, $wgOut, $wgLang;
190 $link = urldecode( $link );
191 $link = $wgLang->checkTitleEncoding( $link );
192 $link = str_replace( "_", " ", $link );
193 $link = wfEscapeHTML( $link );
195 if ( $wgOut->isPrintable() ) { $r = " class='printable'"; }
196 else { $r = " class='external'"; }
198 if ( 1 == $wgUser->getOption( "hover" ) ) {
199 $r .= " title=\"{$link}\"";
201 return $r;
204 function getInternalLinkAttributes( $link, $text, $broken = false )
206 global $wgUser, $wgOut;
208 $link = urldecode( $link );
209 $link = str_replace( "_", " ", $link );
210 $link = wfEscapeHTML( $link );
212 if ( $wgOut->isPrintable() ) {
213 $r = " class='printable'";
214 } else if ( $broken == "stub" ) {
215 $r = " class='stub'";
216 } else if ( $broken == "yes" ) {
217 $r = " class='new'";
218 } else {
219 $r = " class='internal'";
222 if ( 1 == $wgUser->getOption( "hover" ) ) {
223 $r .= " title=\"{$link}\"";
225 return $r;
228 function getInternalLinkAttributesObj( &$nt, $text, $broken = false )
230 global $wgUser, $wgOut;
232 if ( $wgOut->isPrintable() ) {
233 $r = " class='printable'";
234 } else if ( $broken == "stub" ) {
235 $r = " class='stub'";
236 } else if ( $broken == "yes" ) {
237 $r = " class='new'";
238 } else {
239 $r = " class='internal'";
242 if ( 1 == $wgUser->getOption( "hover" ) ) {
243 $r .= ' title ="' . $nt->getEscapedText() . '"';
245 return $r;
248 function getLogo()
250 global $wgLogo;
251 return $wgLogo;
254 # This will be called immediately after the <body> tag. Split into
255 # two functions to make it easier to subclass.
257 function beforeContent()
259 global $wgUser, $wgOut, $wgSiteNotice;
261 if ( $wgOut->isPrintable() ) {
262 $s = $this->pageTitle() . $this->pageSubtitle() . "\n";
263 $s .= "\n<div class='bodytext'>";
264 return $s;
266 if( $wgSiteNotice ) {
267 $note = "\n<div id='notice' style='font-weight: bold; color: red; text-align: center'>$wgSiteNotice</div>\n";
268 } else {
269 $note = "";
271 return $this->doBeforeContent() . $note;
274 function doBeforeContent()
276 global $wgUser, $wgOut, $wgTitle, $wgLang;
277 $fname = "Skin::doBeforeContent";
278 wfProfileIn( $fname );
280 $s = "";
281 $qb = $this->qbSetting();
283 if( $langlinks = $this->otherLanguages() ) {
284 $rows = 2;
285 $borderhack = "";
286 } else {
287 $rows = 1;
288 $langlinks = false;
289 $borderhack = "class='top'";
292 $s .= "\n<div id='content'>\n<div id='topbar'>" .
293 "<table width='98%' border=0 cellspacing=0><tr>";
295 $shove = ($qb != 0);
296 $left = ($qb == 1 || $qb == 3);
297 if($wgLang->isRTL()) $left = !$left;
299 if ( !$shove ) {
300 $s .= "<td class='top' align=left valign=top rowspan='{$rows}'>" .
301 $this->logoText() . "</td>";
302 } elseif( $left ) {
303 $s .= $this->getQuickbarCompensator( $rows );
305 $l = $wgLang->isRTL() ? "right" : "left";
306 $s .= "<td {$borderhack} align='$l' valign='top'>";
308 $s .= $this->topLinks() ;
309 $s .= "<p class='subtitle'>" . $this->pageTitleLinks();
311 $r = $wgLang->isRTL() ? "left" : "right";
312 $s .= "</td>\n<td {$borderhack} valign='top' align='$r' nowrap>";
313 $s .= $this->nameAndLogin();
314 $s .= "\n<br>" . $this->searchForm() . "</td>";
316 if ( $langlinks ) {
317 $s .= "</tr>\n<tr><td class='top' colspan=\"2\">$langlinks</td>";
320 if ( $shove && !$left ) { # Right
321 $s .= $this->getQuickbarCompensator( $rows );
323 $s .= "</tr></table>\n</div>\n";
324 $s .= "\n<div id='article'>";
326 $s .= $this->pageTitle();
327 $s .= $this->pageSubtitle() ;
328 $s .= getCategories(); // For some odd reason, zhis can't be a function of the object
329 $s .= "\n<p>";
330 wfProfileOut( $fname );
331 return $s;
334 function getQuickbarCompensator( $rows = 1 )
336 return "<td width='152' rowspan='{$rows}'>&nbsp;</td>";
339 # This gets called immediately before the </body> tag.
341 function afterContent()
343 global $wgUser, $wgOut, $wgServer;
344 global $wgTitle, $wgLang;
346 if ( $wgOut->isPrintable() ) {
347 $s = "\n</div>\n";
349 $u = htmlspecialchars( $wgServer . $wgTitle->getFullURL() );
350 $u = "<a href=\"$u\">$u</a>";
351 $rf = wfMsg( "retrievedfrom", $u );
353 if ( $wgOut->isArticle() ) {
354 $lm = "<br>" . $this->lastModified();
355 } else { $lm = ""; }
357 $cr = wfMsg( "gnunote" );
358 $s .= "<p>" . $wgLang->emphasize("{$rf}{$lm} {$cr}\n");
359 return $s;
361 return $this->doAfterContent();
364 function doAfterContent()
366 global $wgUser, $wgOut, $wgLang;
367 $fname = "Skin::doAfterContent";
368 wfProfileIn( $fname );
369 wfProfileIn( "$fname-1" );
371 $s = "\n</div><br clear=all>\n";
372 $s .= "\n<div id='footer'>";
373 $s .= "<table width='98%' border=0 cellspacing=0><tr>";
375 wfProfileOut( "$fname-1" );
376 wfProfileIn( "$fname-2" );
378 $qb = $this->qbSetting();
379 $shove = ($qb != 0);
380 $left = ($qb == 1 || $qb == 3);
381 if($wgLang->isRTL()) $left = !$left;
383 if ( $shove && $left ) { # Left
384 $s .= $this->getQuickbarCompensator();
386 wfProfileOut( "$fname-2" );
387 wfProfileIn( "$fname-3" );
388 $l = $wgLang->isRTL() ? "right" : "left";
389 $s .= "<td class='bottom' align='$l' valign='top'>";
391 $s .= $this->bottomLinks();
392 $s .= "\n<br>" . $this->mainPageLink()
393 . " | " . $this->aboutLink()
394 . " | " . $this->specialLink( "recentchanges" )
395 . " | " . $this->searchForm()
396 . "<br>" . $this->pageStats();
398 $s .= "</td>";
399 if ( $shove && !$left ) { # Right
400 $s .= $this->getQuickbarCompensator();
402 $s .= "</tr></table>\n</div>\n</div>\n";
404 wfProfileOut( "$fname-3" );
405 wfProfileIn( "$fname-4" );
406 if ( 0 != $qb ) { $s .= $this->quickBar(); }
407 wfProfileOut( "$fname-4" );
408 wfProfileOut( $fname );
409 return $s;
412 function pageTitleLinks()
414 global $wgOut, $wgTitle, $oldid, $action, $diff, $wgUser, $wgLang, $wgUseApproval ;
416 $s = $this->printableLink();
417 if ( wfMsg ( "disclaimers" ) != "-" ) $s .= " | " . $this->makeKnownLink( wfMsg( "disclaimerpage" ), wfMsg( "disclaimers" ) ) ;
419 if ( $wgOut->isArticleRelated() ) {
420 if ( $wgTitle->getNamespace() == Namespace::getImage() ) {
421 $name = $wgTitle->getDBkey();
422 $link = wfEscapeHTML( wfImageUrl( $name ) );
423 $style = $this->getInternalLinkAttributes( $link, $name );
424 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>";
426 # This will show the "Approve" link if $wgUseApproval=true;
427 if ( isset ( $wgUseApproval ) && $wgUseApproval )
429 $t = $wgTitle->getDBkey();
430 $name = "Approve this article" ;
431 $link = "http://test.wikipedia.org/w/magnus/wiki.phtml?title={$t}&action=submit&doit=1" ;
432 #wfEscapeHTML( wfImageUrl( $name ) );
433 $style = $this->getExternalLinkAttributes( $link, $name );
434 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>" ;
437 if ( "history" == $action || isset( $diff ) || isset( $oldid ) ) {
438 $s .= " | " . $this->makeKnownLink( $wgTitle->getPrefixedText(),
439 wfMsg( "currentrev" ) );
442 if ( $wgUser->getNewtalk() ) {
443 # do not show "You have new messages" text when we are viewing our
444 # own talk page
446 if(!(strcmp($wgTitle->getText(),$wgUser->getName()) == 0 &&
447 $wgTitle->getNamespace()==Namespace::getTalk(Namespace::getUser()))) {
448 $n =$wgUser->getName();
449 $tl = $this->makeKnownLink( $wgLang->getNsText(
450 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
451 wfMsg("newmessageslink") );
452 $s.=" | <strong>". wfMsg( "newmessages", $tl ) . "</strong>";
455 if( $wgUser->isSysop() &&
456 (($wgTitle->getArticleId() == 0) || ($action == "history")) &&
457 ($n = $wgTitle->isDeleted() ) ) {
458 $s .= " | " . wfMsg( "thisisdeleted",
459 $this->makeKnownLink(
460 $wgLang->SpecialPage( "Undelete/" . $wgTitle->getPrefixedDBkey() ),
461 wfMsg( "restorelink", $n ) ) );
463 return $s;
466 function printableLink()
468 global $wgOut, $wgTitle, $oldid, $action;
470 $q = "";
471 foreach( $_GET as $var => $val ) {
472 if( $var != "title" && $var != "printable" )
473 $q .= urlencode( $var ) . "=" . urlencode( $val );
475 if( !empty( $q ) ) $q .= "&";
477 $s = $this->makeKnownLink( $wgTitle->getPrefixedText(),
478 WfMsg( "printableversion" ), "{$q}printable=yes" );
479 return $s;
482 function pageTitle()
484 global $wgOut, $wgTitle, $wgUser;
486 $s = "<h1 class='pagetitle'>" . $wgOut->getPageTitle() . "</h1>";
487 if($wgUser->getOption("editsectiononrightclick") && $wgTitle->userCanEdit()) { $s=$this->editSectionScript(0,$s);}
488 return $s;
491 function pageSubtitle()
493 global $wgOut,$wgTitle,$wgNamespacesWithSubpages;
495 $sub = $wgOut->getSubtitle();
496 if ( "" == $sub ) {
497 global $wgExtraSubtitle;
498 $sub = wfMsg( "fromwikipedia" ) . $wgExtraSubtitle;
500 if($wgOut->isArticle() && $wgNamespacesWithSubpages[$wgTitle->getNamespace()]) {
501 $ptext=$wgTitle->getPrefixedText();
502 if(preg_match("/\//",$ptext)) {
503 $sub.="</p><p class='subpages'>";
504 $links=explode("/",$ptext);
505 $c=0;
506 $growinglink="";
507 foreach($links as $link) {
508 $c++;
509 if ($c<count($links)) {
510 $growinglink .= $link;
511 $getlink = $this->makeLink( $growinglink, $link );
512 if(preg_match("/class='new'/i",$getlink)) { break; } # this is a hack, but it saves time
513 if ($c>1) {
514 $sub .= " | ";
515 } else {
516 $sub .="&lt; ";
518 $sub .= $getlink;
519 $growinglink.="/";
525 $s = "<p class='subtitle'>{$sub}\n";
526 return $s;
529 function nameAndLogin()
531 global $wgUser, $wgTitle, $wgLang, $wgShowIPinHeader, $wgIP;
533 $li = $wgLang->specialPage( "Userlogin" );
534 $lo = $wgLang->specialPage( "Userlogout" );
536 $s = "";
537 if ( 0 == $wgUser->getID() ) {
538 if( $wgShowIPinHeader && isset( $_COOKIE[ini_get("session.name")] ) ) {
539 $n = $wgIP;
541 $tl = $this->makeKnownLink( $wgLang->getNsText(
542 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
543 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
545 $s .= $n . " (".$tl.")";
546 } else {
547 $s .= wfMsg("notloggedin");
550 $rt = $wgTitle->getPrefixedURL();
551 if ( 0 == strcasecmp( urlencode( $lo ), $rt ) ) {
552 $q = "";
553 } else { $q = "returnto={$rt}"; }
555 $s .= "\n<br>" . $this->makeKnownLink( $li,
556 wfMsg( "login" ), $q );
557 } else {
558 $n = $wgUser->getName();
559 $rt = $wgTitle->getPrefixedURL();
560 $tl = $this->makeKnownLink( $wgLang->getNsText(
561 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
562 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
564 $tl = " ({$tl})";
566 $s .= $this->makeKnownLink( $wgLang->getNsText(
567 Namespace::getUser() ) . ":{$n}", $n ) . "{$tl}<br>" .
568 $this->makeKnownLink( $lo, wfMsg( "logout" ),
569 "returnto={$rt}" ) . " | " .
570 $this->specialLink( "preferences" );
572 $s .= " | " . $this->makeKnownLink( wfMsg( "helppage" ),
573 wfMsg( "help" ) );
575 return $s;
578 function searchForm()
580 global $search;
582 $s = "<form name='search' class='inline' method=post action=\""
583 . wfLocalUrl( "" ) . "\">"
584 . "<input type=text name=\"search\" size=19 value=\""
585 . htmlspecialchars(substr($search,0,256)) . "\">\n"
586 . "<input type=submit name=\"go\" value=\"" . wfMsg ("go") . "\">&nbsp;"
587 . "<input type=submit name=\"fulltext\" value=\"" . wfMsg ("search") . "\"></form>";
589 return $s;
592 function topLinks()
594 global $wgOut;
595 $sep = " |\n";
597 $s = $this->mainPageLink() . $sep
598 . $this->specialLink( "recentchanges" );
600 if ( $wgOut->isArticleRelated() ) {
601 $s .= $sep . $this->editThisPage()
602 . $sep . $this->historyLink();
604 # Many people don't like this dropdown box
605 #$s .= $sep . $this->specialPagesList();
607 return $s;
610 function bottomLinks()
612 global $wgOut, $wgUser, $wgTitle;
613 $sep = " |\n";
615 $s = "";
616 if ( $wgOut->isArticleRelated() ) {
617 $s .= "<strong>" . $this->editThisPage() . "</strong>";
618 if ( 0 != $wgUser->getID() ) {
619 $s .= $sep . $this->watchThisPage();
621 $s .= $sep . $this->talkLink()
622 . $sep . $this->historyLink()
623 . $sep . $this->whatLinksHere()
624 . $sep . $this->watchPageLinksLink();
626 if ( $wgTitle->getNamespace() == Namespace::getUser()
627 || $wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser()) )
630 $id=User::idFromName($wgTitle->getText());
631 $ip=User::isIP($wgTitle->getText());
633 if($id || $ip) { # both anons and non-anons have contri list
634 $s .= $sep . $this->userContribsLink();
636 if ( 0 != $wgUser->getID() ) { # show only to signed in users
637 if($id) { # can only email non-anons
638 $s .= $sep . $this->emailUserLink();
642 if ( $wgUser->isSysop() && $wgTitle->getArticleId() ) {
643 $s .= "\n<br>" . $this->deleteThisPage() .
644 $sep . $this->protectThisPage() .
645 $sep . $this->moveThisPage();
647 $s .= "<br>\n" . $this->otherLanguages();
649 return $s;
652 function pageStats()
654 global $wgOut, $wgLang, $wgArticle;
655 global $oldid, $diff, $wgDisableCounters;
657 if ( ! $wgOut->isArticle() ) { return ""; }
658 if ( isset( $oldid ) || isset( $diff ) ) { return ""; }
659 if ( 0 == $wgArticle->getID() ) { return ""; }
661 if ( $wgDisableCounters ) {
662 $s = "";
663 } else {
664 $count = $wgArticle->getCount();
665 $s = wfMsg( "viewcount", $count );
667 $s .= $this->lastModified();
668 $s .= " " . wfMsg( "gnunote" );
669 return "<span id='pagestats'>{$s}</span>";
672 function lastModified()
674 global $wgLang, $wgArticle;
676 $d = $wgLang->timeanddate( $wgArticle->getTimestamp(), true );
677 $s = " " . wfMsg( "lastmodified", $d );
678 return $s;
681 function logoText( $align = "" )
683 if ( "" != $align ) { $a = " align='{$align}'"; }
684 else { $a = ""; }
686 $mp = wfMsg( "mainpage" );
687 $s = "<a href=\"" . wfLocalUrlE( urlencode( str_replace(' ','_',$mp) ) )
688 . "\"><img{$a} border=0 src=\""
689 . $this->getLogo() . "\" alt=\"" . "[{$mp}]\"></a>";
690 return $s;
693 function quickBar()
695 global $wgOut, $wgTitle, $wgUser, $action, $wgLang;
696 global $wpPreview, $wgDisableUploads, $wgRemoteUploads;
698 $fname = "Skin::quickBar";
699 wfProfileIn( $fname );
701 $tns=$wgTitle->getNamespace();
703 $s = "\n<div id='quickbar'>";
704 $s .= "\n" . $this->logoText() . "\n<hr class='sep'>";
706 $sep = "\n<br>";
707 $s .= $this->mainPageLink()
708 . $sep . $this->specialLink( "recentchanges" )
709 . $sep . $this->specialLink( "randompage" );
710 if ($wgUser->getID()) {
711 $s.= $sep . $this->specialLink( "watchlist" ) ;
712 $s .= $sep .$this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
713 wfMsg( "mycontris" ), "target=" . wfUrlencode($wgUser->getName() ) );
716 // only show watchlist link if logged in
717 if ( wfMsg ( "currentevents" ) != "-" ) $s .= $sep . $this->makeKnownLink( wfMsg( "currentevents" ), "" ) ;
718 $s .= "\n<br><hr class='sep'>";
719 $articleExists = $wgTitle->getArticleId();
720 if ( $wgOut->isArticle() || $action =="edit" || $action =="history" || $wpPreview) {
721 if($wgOut->isArticle()) {
722 $s .= "<strong>" . $this->editThisPage() . "</strong>";
723 } else { # backlink to the article in edit or history mode
724 if($articleExists){ # no backlink if no article
725 switch($tns) {
726 case 0:
727 $text = wfMsg("articlepage");
728 break;
729 case 1:
730 $text = wfMsg("viewtalkpage");
731 break;
732 case 2:
733 $text = wfMsg("userpage");
734 break;
735 case 3:
736 $text = wfMsg("viewtalkpage");
737 break;
738 case 4:
739 $text = wfMsg("wikipediapage");
740 break;
741 case 5:
742 $text = wfMsg("viewtalkpage");
743 break;
744 case 6:
745 $text = wfMsg("imagepage");
746 break;
747 case 7:
748 $text = wfMsg("viewtalkpage");
749 break;
750 default:
751 $text= wfMsg("articlepage");
754 $link = $wgTitle->getText();
755 if ($nstext = $wgLang->getNsText($tns) ) { # add namespace if necessary
756 $link = $nstext . ":" . $link ;
759 $s .= $this->makeLink( $link, $text );
760 } elseif( $wgTitle->getNamespace() != Namespace::getSpecial() ) {
761 # we just throw in a "New page" text to tell the user that he's in edit mode,
762 # and to avoid messing with the separator that is prepended to the next item
763 $s .= "<strong>" . wfMsg("newpage") . "</strong>";
769 if( $tns%2 && $action!="edit" && !$wpPreview) {
770 $s.="<br>".$this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg("postcomment"),"action=edit&section=new");
774 watching could cause problems in edit mode:
775 if user edits article, then loads "watch this article" in background and then saves
776 article with "Watch this article" checkbox disabled, the article is transparently
777 unwatched. Therefore we do not show the "Watch this page" link in edit mode
779 if ( 0 != $wgUser->getID() && $articleExists) {
780 if($action!="edit" && $action != "submit" )
782 $s .= $sep . $this->watchThisPage();
784 if ( $wgTitle->userCanEdit() )
785 $s .= $sep . $this->moveThisPage();
787 if ( $wgUser->isSysop() and $articleExists ) {
788 $s .= $sep . $this->deleteThisPage() .
789 $sep . $this->protectThisPage();
791 $s .= $sep . $this->talkLink();
792 if ($articleExists && $action !="history") {
793 $s .= $sep . $this->historyLink();
795 $s.=$sep . $this->whatLinksHere();
797 if($wgOut->isArticleRelated()) {
798 $s .= $sep . $this->watchPageLinksLink();
801 if ( Namespace::getUser() == $wgTitle->getNamespace()
802 || $wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser())
805 $id=User::idFromName($wgTitle->getText());
806 $ip=User::isIP($wgTitle->getText());
808 if($id||$ip) {
809 $s .= $sep . $this->userContribsLink();
811 if ( 0 != $wgUser->getID() ) {
812 if($id) { # can only email real users
813 $s .= $sep . $this->emailUserLink();
817 $s .= "\n<br><hr class='sep'>";
820 if ( 0 != $wgUser->getID() && ( !$wgDisableUploads || $wgRemoteUploads ) ) {
821 $s .= $this->specialLink( "upload" ) . $sep;
823 $s .= $this->specialLink( "specialpages" )
824 . $sep . $this->bugReportsLink();
826 global $wgSiteSupportPage;
827 if( $wgSiteSupportPage ) {
828 $s .= "\n<br><a href=\"" . htmlspecialchars( $wgSiteSupportPage ) .
829 "\" class=\"internal\">" . wfMsg( "sitesupport" ) . "</a>";
832 $s .= "\n<br></div>\n";
833 wfProfileOut( $fname );
834 return $s;
837 function specialPagesList()
839 global $wgUser, $wgOut, $wgLang, $wgServer, $wgRedirectScript;
840 $a = array();
842 $validSP = $wgLang->getValidSpecialPages();
844 foreach ( $validSP as $name => $desc ) {
845 if ( "" == $desc ) { continue; }
846 $a[$name] = $desc;
848 if ( $wgUser->isSysop() )
850 $sysopSP = $wgLang->getSysopSpecialPages();
852 foreach ( $sysopSP as $name => $desc ) {
853 if ( "" == $desc ) { continue; }
854 $a[$name] = $desc ;
857 if ( $wgUser->isDeveloper() )
859 $devSP = $wgLang->getDeveloperSpecialPages();
861 foreach ( $devSP as $name => $desc ) {
862 if ( "" == $desc ) { continue; }
863 $a[$name] = $desc ;
866 $go = wfMsg( "go" );
867 $sp = wfMsg( "specialpages" );
868 $spp = $wgLang->specialPage( "Specialpages" );
870 $s = "<form id=\"specialpages\" method=\"get\" class=\"inline\" " .
871 "action=\"{$wgServer}{$wgRedirectScript}\">\n";
872 $s .= "<select name=\"wpDropdown\">\n";
873 $s .= "<option value=\"{$spp}\">{$sp}</option>\n";
875 foreach ( $a as $name => $desc ) {
876 $p = $wgLang->specialPage( $name );
877 $s .= "<option value=\"{$p}\">{$desc}</option>\n";
879 $s .= "</select>\n";
880 $s .= "<input type=submit value=\"{$go}\" name=redirect>\n";
881 $s .= "</form>\n";
882 return $s;
885 function mainPageLink()
887 $mp = wfMsg( "mainpage" );
888 $s = $this->makeKnownLink( $mp, $mp );
889 return $s;
892 function copyrightLink()
894 $s = $this->makeKnownLink( wfMsg( "copyrightpage" ),
895 wfMsg( "copyrightpagename" ) );
896 return $s;
899 function aboutLink()
901 $s = $this->makeKnownLink( wfMsg( "aboutpage" ),
902 wfMsg( "aboutwikipedia" ) );
903 return $s;
907 function disclaimerLink()
909 $s = $this->makeKnownLink( wfMsg( "disclaimerpage" ),
910 wfMsg( "disclaimers" ) );
911 return $s;
914 function editThisPage()
916 global $wgOut, $wgTitle, $oldid, $redirect, $diff;
918 if ( ! $wgOut->isArticleRelated() ) {
919 $s = wfMsg( "protectedpage" );
920 } else {
921 $n = $wgTitle->getPrefixedText();
922 if ( $wgTitle->userCanEdit() ) {
923 $t = wfMsg( "editthispage" );
924 } else {
925 #$t = wfMsg( "protectedpage" );
926 $t = wfMsg( "viewsource" );
928 $oid = $red = "";
930 if ( $redirect ) { $red = "&redirect={$redirect}"; }
931 if ( $oldid && ! isset( $diff ) ) {
932 $oid = "&oldid={$oldid}";
934 $s = $this->makeKnownLink( $n, $t, "action=edit{$oid}{$red}" );
936 return $s;
939 function deleteThisPage()
941 global $wgUser, $wgOut, $wgTitle, $diff;
943 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
944 $n = $wgTitle->getPrefixedText();
945 $t = wfMsg( "deletethispage" );
947 $s = $this->makeKnownLink( $n, $t, "action=delete" );
948 } else {
949 $s = "";
951 return $s;
954 function protectThisPage()
956 global $wgUser, $wgOut, $wgTitle, $diff;
958 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
959 $n = $wgTitle->getPrefixedText();
961 if ( $wgTitle->isProtected() ) {
962 $t = wfMsg( "unprotectthispage" );
963 $q = "action=unprotect";
964 } else {
965 $t = wfMsg( "protectthispage" );
966 $q = "action=protect";
968 $s = $this->makeKnownLink( $n, $t, $q );
969 } else {
970 $s = "";
972 return $s;
975 function watchThisPage()
977 global $wgUser, $wgOut, $wgTitle, $diff;
979 if ( $wgOut->isArticleRelated() ) {
980 $n = $wgTitle->getPrefixedText();
982 if ( $wgTitle->userIsWatching() ) {
983 $t = wfMsg( "unwatchthispage" );
984 $q = "action=unwatch";
985 } else {
986 $t = wfMsg( "watchthispage" );
987 $q = "action=watch";
989 $s = $this->makeKnownLink( $n, $t, $q );
990 } else {
991 $s = wfMsg( "notanarticle" );
993 return $s;
996 function moveThisPage()
998 global $wgTitle, $wgLang;
1000 if ( $wgTitle->userCanEdit() ) {
1001 $s = $this->makeKnownLink( $wgLang->specialPage( "Movepage" ),
1002 wfMsg( "movethispage" ), "target=" . $wgTitle->getPrefixedURL() );
1003 } // no message if page is protected - would be redundant
1004 return $s;
1007 function historyLink()
1009 global $wgTitle;
1011 $s = $this->makeKnownLink( $wgTitle->getPrefixedText(),
1012 wfMsg( "history" ), "action=history" );
1013 return $s;
1016 function whatLinksHere()
1018 global $wgTitle, $wgLang;
1020 $s = $this->makeKnownLink( $wgLang->specialPage( "Whatlinkshere" ),
1021 wfMsg( "whatlinkshere" ), "target=" . $wgTitle->getPrefixedURL() );
1022 return $s;
1025 function userContribsLink()
1027 global $wgTitle, $wgLang;
1029 $s = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
1030 wfMsg( "contributions" ), "target=" . $wgTitle->getURL() );
1031 return $s;
1034 function emailUserLink()
1036 global $wgTitle, $wgLang;
1038 $s = $this->makeKnownLink( $wgLang->specialPage( "Emailuser" ),
1039 wfMsg( "emailuser" ), "target=" . $wgTitle->getURL() );
1040 return $s;
1043 function watchPageLinksLink()
1045 global $wgOut, $wgTitle, $wgLang;
1047 if ( ! $wgOut->isArticleRelated() ) {
1048 $s = "(" . wfMsg( "notanarticle" ) . ")";
1049 } else {
1050 $s = $this->makeKnownLink( $wgLang->specialPage(
1051 "Recentchangeslinked" ), wfMsg( "recentchangeslinked" ),
1052 "target=" . $wgTitle->getPrefixedURL() );
1054 return $s;
1057 function otherLanguages()
1059 global $wgOut, $wgLang, $wgTitle, $wgUseNewInterlanguage;
1061 $a = $wgOut->getLanguageLinks();
1062 # TEST THIS @@@
1063 if ( 0 == count( $a ) ) {
1064 if ( !$wgUseNewInterlanguage ) return "";
1065 $ns = $wgLang->getNsIndex ( $wgTitle->getNamespace () ) ;
1066 if ( $ns != 0 AND $ns != 1 ) return "" ;
1067 $pn = "Intl" ;
1068 $x = "mode=addlink&xt=".$wgTitle->getDBkey() ;
1069 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1070 wfMsg( "intl" ) , $x );
1073 if ( !$wgUseNewInterlanguage ) {
1074 $s = wfMsg( "otherlanguages" ) . ": ";
1075 } else {
1076 global $wgLanguageCode ;
1077 $x = "mode=zoom&xt=".$wgTitle->getDBkey() ;
1078 $x .= "&xl=".$wgLanguageCode ;
1079 $s = $this->makeKnownLink( $wgLang->specialPage( "Intl" ),
1080 wfMsg( "otherlanguages" ) , $x ) . ": " ;
1083 $s = wfMsg( "otherlanguages" ) . ": ";
1084 $first = true;
1085 if($wgLang->isRTL()) $s .= "<span dir='LTR'>";
1086 foreach( $a as $l ) {
1087 if ( ! $first ) { $s .= " | "; }
1088 $first = false;
1090 $nt = Title::newFromText( $l );
1091 $url = $nt->getFullURL();
1092 $text = $wgLang->getLanguageName( $nt->getInterwiki() );
1094 if ( "" == $text ) { $text = $l; }
1095 $style = $this->getExternalLinkAttributes( $l, $text );
1096 $s .= "<a href=\"{$url}\"{$style}>{$text}</a>";
1098 if($wgLang->isRTL()) $s .= "</span>";
1099 return $s;
1102 function bugReportsLink()
1104 $s = $this->makeKnownLink( wfMsg( "bugreportspage" ),
1105 wfMsg( "bugreports" ) );
1106 return $s;
1109 function dateLink()
1111 global $wgLinkCache;
1112 $t1 = Title::newFromText( gmdate( "F j" ) );
1113 $t2 = Title::newFromText( gmdate( "Y" ) );
1115 $wgLinkCache->suspend();
1116 $id = $t1->getArticleID();
1117 $wgLinkCache->resume();
1119 if ( 0 == $id ) {
1120 $s = $this->makeBrokenLink( $t1->getText() );
1121 } else {
1122 $s = $this->makeKnownLink( $t1->getText() );
1124 $s .= ", ";
1126 $wgLinkCache->suspend();
1127 $id = $t2->getArticleID();
1128 $wgLinkCache->resume();
1130 if ( 0 == $id ) {
1131 $s .= $this->makeBrokenLink( $t2->getText() );
1132 } else {
1133 $s .= $this->makeKnownLink( $t2->getText() );
1135 return $s;
1138 function talkLink()
1140 global $wgLang, $wgTitle, $wgLinkCache;
1142 $tns = $wgTitle->getNamespace();
1143 if ( -1 == $tns ) { return ""; }
1145 $pn = $wgTitle->getText();
1146 $tp = wfMsg( "talkpage" );
1147 if ( Namespace::isTalk( $tns ) ) {
1148 $lns = Namespace::getSubject( $tns );
1149 switch($tns) {
1150 case 1:
1151 $text = wfMsg("articlepage");
1152 break;
1153 case 3:
1154 $text = wfMsg("userpage");
1155 break;
1156 case 5:
1157 $text = wfMsg("wikipediapage");
1158 break;
1159 case 7:
1160 $text = wfMsg("imagepage");
1161 break;
1162 default:
1163 $text= wfMsg("articlepage");
1165 } else {
1167 $lns = Namespace::getTalk( $tns );
1168 $text=$tp;
1170 $n = $wgLang->getNsText( $lns );
1171 if ( "" == $n ) { $link = $pn; }
1172 else { $link = "{$n}:{$pn}"; }
1174 $wgLinkCache->suspend();
1175 $s = $this->makeLink( $link, $text );
1176 $wgLinkCache->resume();
1178 return $s;
1181 function commentLink()
1183 global $wgLang, $wgTitle, $wgLinkCache;
1185 $tns = $wgTitle->getNamespace();
1186 if ( -1 == $tns ) { return ""; }
1188 $lns = ( Namespace::isTalk( $tns ) ) ? $tns : Namespace::getTalk( $tns );
1190 # assert Namespace::isTalk( $lns )
1192 $n = $wgLang->getNsText( $lns );
1193 $pn = $wgTitle->getText();
1195 $link = "{$n}:{$pn}";
1197 $wgLinkCache->suspend();
1198 $s = $this->makeKnownLink($link, wfMsg("postcomment"), "action=edit&section=new");
1199 $wgLinkCache->resume();
1201 return $s;
1204 # After all the page content is transformed into HTML, it makes
1205 # a final pass through here for things like table backgrounds.
1207 function transformContent( $text )
1209 return $text;
1212 # Note: This function MUST call getArticleID() on the link,
1213 # otherwise the cache won't get updated properly. See LINKCACHE.DOC.
1215 function makeLink( $title, $text = "", $query = "", $trail = "" ) {
1216 wfProfileIn( "Skin::makeLink" );
1217 $nt = Title::newFromText( $title );
1218 if ($nt) {
1219 $result = $this->makeLinkObj( Title::newFromText( $title ), $text, $query, $trail );
1220 } else {
1221 wfDebug( "Invalid title passed to Skin::makeLink(): \"$title\"\n" );
1222 $result = $text == "" ? $title : $text;
1225 wfProfileOut( "Skin::makeLink" );
1226 return $result;
1229 function makeKnownLink( $title, $text = "", $query = "", $trail = "" ) {
1230 $nt = Title::newFromText( $title );
1231 if ($nt) {
1232 return $this->makeKnownLinkObj( Title::newFromText( $title ), $text, $query, $trail );
1233 } else {
1234 wfDebug( "Invalid title passed to Skin::makeKnownLink(): \"$title\"\n" );
1235 return $text == "" ? $title : $text;
1239 function makeBrokenLink( $title, $text = "", $query = "", $trail = "" ) {
1240 $nt = Title::newFromText( $title );
1241 if ($nt) {
1242 return $this->makeBrokenLinkObj( Title::newFromText( $title ), $text, $query, $trail );
1243 } else {
1244 wfDebug( "Invalid title passed to Skin::makeBrokenLink(): \"$title\"\n" );
1245 return $text == "" ? $title : $text;
1249 function makeStubLink( $title, $text = "", $query = "", $trail = "" ) {
1250 $nt = Title::newFromText( $title );
1251 if ($nt) {
1252 return $this->makeStubLinkObj( Title::newFromText( $title ), $text, $query, $trail );
1253 } else {
1254 wfDebug( "Invalid title passed to Skin::makeStubLink(): \"$title\"\n" );
1255 return $text == "" ? $title : $text;
1259 # Pass a title object, not a title string
1260 function makeLinkObj( &$nt, $text= "", $query = "", $trail = "", $prefix = "" )
1262 global $wgOut, $wgUser;
1263 if ( $nt->isExternal() ) {
1264 $u = $nt->getFullURL();
1265 if ( "" == $text ) { $text = $nt->getPrefixedText(); }
1266 $style = $this->getExternalLinkAttributes( $link, $text );
1268 $inside = "";
1269 if ( "" != $trail ) {
1270 if ( preg_match( "/^([a-z]+)(.*)$$/sD", $trail, $m ) ) {
1271 $inside = $m[1];
1272 $trail = $m[2];
1275 $retVal = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1276 } elseif ( 0 == $nt->getNamespace() && "" == $nt->getText() ) {
1277 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1278 } elseif ( ( -1 == $nt->getNamespace() ) ||
1279 ( Namespace::getImage() == $nt->getNamespace() ) ) {
1280 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1281 } else {
1282 $aid = $nt->getArticleID() ;
1283 if ( 0 == $aid ) {
1284 $retVal = $this->makeBrokenLinkObj( $nt, $text, $query, $trail, $prefix );
1285 } else {
1286 $threshold = $wgUser->getOption("stubthreshold") ;
1287 if ( $threshold > 0 ) {
1288 $res = wfQuery ( "SELECT LENGTH(cur_text) AS x, cur_namespace, cur_is_redirect FROM cur WHERE cur_id='{$aid}'", DB_READ ) ;
1290 if ( wfNumRows( $res ) > 0 ) {
1291 $s = wfFetchObject( $res );
1292 $size = $s->x;
1293 if ( $s->cur_is_redirect OR $s->cur_namespace != 0 ) {
1294 $size = $threshold*2 ; # Really big
1296 wfFreeResult( $res );
1297 } else {
1298 $size = $threshold*2 ; # Really big
1300 } else {
1301 $size = 1 ;
1303 if ( $size < $threshold ) {
1304 $retVal = $this->makeStubLinkObj( $nt, $text, $query, $trail, $prefix );
1305 } else {
1306 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1310 return $retVal;
1313 # Pass a title object, not a title string
1314 function makeKnownLinkObj( &$nt, $text = "", $query = "", $trail = "", $prefix = "" )
1316 global $wgOut, $wgTitle;
1318 $fname = "Skin::makeKnownLinkObj";
1319 wfProfileIn( $fname );
1321 $link = $nt->getPrefixedURL();
1323 if ( "" == $link ) {
1324 $u = "";
1325 if ( "" == $text ) { $text = $nt->getFragment(); }
1326 } else {
1327 $u = wfLocalUrlE( $link, $query );
1329 if ( "" != $nt->getFragment() ) {
1330 $u .= "#" . wfEscapeHTML( $nt->getFragment() );
1332 if ( "" == $text ) { $text = $nt->getPrefixedText(); }
1333 $style = $this->getInternalLinkAttributesObj( $nt, $text );
1335 $inside = "";
1336 if ( "" != $trail ) {
1337 if ( preg_match( wfMsg("linktrail"), $trail, $m ) ) {
1338 $inside = $m[1];
1339 $trail = $m[2];
1342 $r = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1343 wfProfileOut( $fname );
1344 return $r;
1347 # Pass a title object, not a title string
1348 function makeBrokenLinkObj( &$nt, $text = "", $query = "", $trail = "", $prefix = "" )
1350 global $wgOut, $wgUser;
1352 $fname = "Skin::makeBrokenLinkObj";
1353 wfProfileIn( $fname );
1355 $link = $nt->getPrefixedURL();
1357 if ( "" == $query ) { $q = "action=edit"; }
1358 else { $q = "action=edit&{$query}"; }
1359 $u = wfLocalUrlE( $link, $q );
1361 if ( "" == $text ) { $text = $nt->getPrefixedText(); }
1362 $style = $this->getInternalLinkAttributesObj( $nt, $text, "yes" );
1364 $inside = "";
1365 if ( "" != $trail ) {
1366 if ( preg_match( wfMsg("linktrail"), $trail, $m ) ) {
1367 $inside = $m[1];
1368 $trail = $m[2];
1371 if ( $wgOut->isPrintable() ||
1372 ( 1 == $wgUser->getOption( "highlightbroken" ) ) ) {
1373 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1374 } else {
1375 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>?</a>{$trail}";
1378 wfProfileOut( $fname );
1379 return $s;
1382 # Pass a title object, not a title string
1383 function makeStubLinkObj( &$nt, $text = "", $query = "", $trail = "", $prefix = "" )
1385 global $wgOut, $wgUser;
1387 $link = $nt->getPrefixedURL();
1389 $u = wfLocalUrlE( $link, $query );
1391 if ( "" == $text ) { $text = $nt->getPrefixedText(); }
1392 $style = $this->getInternalLinkAttributesObj( $nt, $text, "stub" );
1394 $inside = "";
1395 if ( "" != $trail ) {
1396 if ( preg_match( wfMsg("linktrail"), $trail, $m ) ) {
1397 $inside = $m[1];
1398 $trail = $m[2];
1401 if ( $wgOut->isPrintable() ||
1402 ( 1 == $wgUser->getOption( "highlightbroken" ) ) ) {
1403 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1404 } else {
1405 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>!</a>{$trail}";
1407 return $s;
1410 function fnamePart( $url )
1412 $basename = strrchr( $url, "/" );
1413 if ( false === $basename ) { $basename = $url; }
1414 else { $basename = substr( $basename, 1 ); }
1415 return wfEscapeHTML( $basename );
1418 function makeImage( $url, $alt = "" )
1420 global $wgOut;
1422 if ( "" == $alt ) { $alt = $this->fnamePart( $url ); }
1423 $s = "<img src=\"{$url}\" alt=\"{$alt}\">";
1424 return $s;
1427 function makeImageLink( $name, $url, $alt = "" ) {
1428 $nt = Title::makeTitle( Namespace::getImage(), $name );
1429 return $this->makeImageLinkObj( $nt, $alt );
1432 function makeImageLinkObj( $nt, $alt = "" ) {
1433 global $wgLang, $wgUseImageResize;
1434 $link = $nt->getPrefixedURL();
1435 $name = $nt->getDBKey();
1436 $url = wfImageUrl( $name );
1437 $align = "";
1438 $prefix = $postfix = "";
1440 if ( $wgUseImageResize ) {
1441 # Check if the alt text is of the form "options|alt text"
1442 # Options are:
1443 # * thumbnail make a thumbnail with enlarge-icon and caption, alignment depends on lang
1444 # * left no resizing, just left align. label is used for alt= only
1445 # * right same, but right aligned
1446 # * none same, but not aligned
1447 # * ___px scale to ___ pixels width, no aligning. e.g. use in taxobox
1449 $part = explode( "|", $alt);
1451 $mwThumb =& MagicWord::get( MAG_IMG_THUMBNAIL );
1452 $mwLeft =& MagicWord::get( MAG_IMG_LEFT );
1453 $mwRight =& MagicWord::get( MAG_IMG_RIGHT );
1454 $mwNone =& MagicWord::get( MAG_IMG_NONE );
1455 $mwWidth =& MagicWord::get( MAG_IMG_WIDTH );
1456 $mwCenter =& MagicWord::get( MAG_IMG_CENTER );
1457 $alt = $part[count($part)-1];
1459 $thumb=false;
1461 foreach( $part as $key => $val ) {
1462 if ( ! is_null( $mwThumb->matchVariableStartToEnd($val) ) ) {
1463 $thumb=true;
1464 } elseif ( ! is_null( $mwRight->matchVariableStartToEnd($val) ) ) {
1465 # remember to set an alignment, don't render immediately
1466 $align = "right";
1467 } elseif ( ! is_null( $mwLeft->matchVariableStartToEnd($val) ) ) {
1468 # remember to set an alignment, don't render immediately
1469 $align = "left";
1470 } elseif ( ! is_null( $mwCenter->matchVariableStartToEnd($val) ) ) {
1471 # remember to set an alignment, don't render immediately
1472 $align = "center";
1473 } elseif ( ! is_null( $mwNone->matchVariableStartToEnd($val) ) ) {
1474 # remember to set an alignment, don't render immediately
1475 $align = "none";
1476 } elseif ( ! is_null( $match = $mwWidth->matchVariableStartToEnd($val) ) ) {
1477 # $match is the image width in pixels
1478 $width = intval($match);
1481 if ( "center" == $align )
1483 $prefix = "<center>";
1484 $postfix = "</center>";
1485 $align = "none";
1488 if ( $thumb ) {
1490 # Create a thumbnail. Alignment depends on language
1491 # writing direction, # right aligned for left-to-right-
1492 # languages ("Western languages"), left-aligned
1493 # for right-to-left-languages ("Semitic languages")
1495 # If thumbnail width has not been provided, it is set
1496 # here to 180 pixels
1497 if ( $align == "" ) {
1498 $align = $wgLang->isRTL() ? "left" : "right";
1500 if ( ! isset($width) ) {
1501 $width = 180;
1503 return $prefix.$this->makeThumbLinkObj( $nt, $alt, $align, $width ).$postfix;
1505 } elseif ( isset($width) ) {
1507 # Create a resized image, without the additional thumbnail
1508 # features
1509 $url = $this->createThumb( $name, $width );
1511 } # endif $wgUseImageResize
1513 if ( empty( $alt ) ) {
1514 $alt = preg_replace( '/\.(.+?)^/', '', $name );
1516 $alt = htmlspecialchars( $alt );
1518 $u = wfLocalUrlE( $link );
1519 $s = "<a href=\"{$u}\" class='image' title=\"{$alt}\">" .
1520 "<img border=\"0\" src=\"{$url}\" alt=\"{$alt}\"></a>";
1521 if ( "" != $align ) {
1522 $s = "<div class=\"float{$align}\">{$s}</div>";
1524 return $prefix.$s.$postfix;
1527 function createThumb( $name, $width ) {
1528 global $wgUploadDirectory;
1529 global $wgImageMagickConvertCommand;
1530 global $wgUseImageMagick;
1531 global $wgUseSquid, $wgInternalServer;
1532 $imgPath = wfImagePath( $name );
1533 $thumbName = $width."px-".$icon.$name;
1534 $thumbPath = wfImageThumbDir( $thumbName )."/".$thumbName;
1535 $thumbUrl = wfImageThumbUrl( $thumbName );
1537 if ( (! file_exists( $thumbPath ) && file_exists( $imgPath ))
1538 || ( filemtime($thumbPath) < filemtime($imgPath) ) ) {
1539 # Squid purging
1540 if ( $wgUseSquid ) {
1541 $urlArr = Array(
1542 $wgInternalServer.$thumbUrl
1544 wfPurgeSquidServers($urlArr);
1547 if ( $wgUseImageMagick ) {
1548 # use ImageMagick
1549 $cmd = $wgImageMagickConvertCommand .
1550 " -quality 85 -geometry {$width} ".
1551 escapeshellarg($imgPath) . " " .
1552 escapeshellarg($thumbPath);
1553 $conv = shell_exec( $cmd );
1554 } else {
1555 # Use PHP's builtin GD library functions.
1557 # First find out what kind of file this is, and select the correct
1558 # input routine for this.
1559 list($src_width, $src_height, $src_type, $src_attr) = getimagesize( $imgPath );
1560 switch( $src_type ) {
1561 case 1: # GIF
1562 $src_image = imagecreatefromgif( $imgPath );
1563 break;
1564 case 2: # JPG
1565 $src_image = imagecreatefromjpeg( $imgPath );
1566 break;
1567 case 3: # PNG
1568 $src_image = imagecreatefrompng( $imgPath );
1569 break;
1570 case 15: # WBMP for WML
1571 $src_image = imagecreatefromwbmp( $imgPath );
1572 break;
1573 case 16: # XBM
1574 $src_image = imagecreatefromxbm( $imgPath );
1575 break;
1576 default:
1577 return "Image type not supported";
1578 break;
1580 $height = floor( $src_height * ( $width/$src_width ) );
1581 $dst_image = imagecreatetruecolor( $width, $height );
1582 imagecopyresampled( $dst_image, $src_image,
1583 0,0,0,0,
1584 $width, $height, $src_width, $src_height );
1585 switch( $src_type ) {
1586 case 1: # GIF
1587 case 3: # PNG
1588 case 15: # WBMP
1589 case 16: # XBM
1590 #$thumbUrl .= ".png";
1591 #$thumbPath .= ".png";
1592 imagepng( $dst_image, $thumbPath );
1593 break;
1594 case 2: # JPEG
1595 #$thumbUrl .= ".jpg";
1596 #$thumbPath .= ".jpg";
1597 imageinterlace( $dst_image );
1598 imagejpeg( $dst_image, $thumbPath, 95 );
1599 break;
1600 default:
1601 break;
1603 imagedestroy( $dst_image );
1604 imagedestroy( $src_image );
1609 # Check for zero-sized thumbnails. Those can be generated when
1610 # no disk space is available or some other error occurs
1612 $thumbstat = stat( $thumbPath );
1613 $imgstat = stat( $imgPath );
1614 if( $thumbstat["size"] == 0 )
1616 unlink( $thumbPath );
1620 return $thumbUrl;
1623 function makeThumbLinkObj( $nt, $label = "", $align = "right", $boxwidth = 180 ) {
1624 global $wgUploadPath;
1625 $name = $nt->getDBKey();
1626 $image = Title::makeTitle( Namespace::getImage(), $name );
1627 $link = $image->getPrefixedURL();
1628 $url = wfImageUrl( $name );
1629 $path = wfImagePath( $name );
1631 $label = htmlspecialchars( $label );
1633 list($width, $height, $type, $attr) = getimagesize( $path );
1634 $boxheight = intval( $height/($width/$boxwidth) );
1635 if ( $boxwidth > $width ) {
1636 $boxwidth = $width;
1637 $boxheight = $height;
1640 $thumbUrl = $this->createThumb( $name, $boxwidth );
1642 $u = wfLocalUrlE( $link );
1644 $more = wfMsg( "thumbnail-more" );
1646 $s = "<div class=\"thumbnail-{$align}\" style=\"width:{$boxwidth}px;\">" .
1647 "<a href=\"{$u}\" class=\"internal\" title=\"{$label}\">" .
1648 "<img border=\"0\" src=\"{$thumbUrl}\" alt=\"{$label}\" width=\"{$boxwidth}\" height=\"{$boxheight}\"></a>" .
1649 "<a href=\"{$u}\" class=\"internal\" title=\"{$more}\">" .
1650 "<img border=\"0\" src=\"{$wgUploadPath}/magnify-clip.png\" width=\"26\" height=\"24\" align=\"right\" alt=\"{$more}\"></a>" .
1651 "<p>{$label}</p></div>";
1652 return $s;
1655 function makeMediaLink( $name, $url, $alt = "" ) {
1656 $nt = Title::makeTitle( Namespace::getMedia(), $name );
1657 return $this->makeMediaLinkObj( $nt, $alt );
1660 function makeMediaLinkObj( $nt, $alt = "" )
1662 $name = $nt->getDBKey();
1663 $url = wfImageUrl( $name );
1664 if ( empty( $alt ) ) {
1665 $alt = preg_replace( '/\.(.+?)^/', '', $name );
1668 $u = htmlspecialchars( $url );
1669 $s = "<a href=\"{$u}\" class='internal' title=\"{$alt}\">{$alt}</a>";
1670 return $s;
1673 function specialLink( $name, $key = "" )
1675 global $wgLang;
1677 if ( "" == $key ) { $key = strtolower( $name ); }
1678 $pn = $wgLang->ucfirst( $name );
1679 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1680 wfMsg( $key ) );
1683 # Called by history lists and recent changes
1686 # Returns text for the start of the tabular part of RC
1687 function beginRecentChangesList()
1689 $this->rc_cache = array() ;
1690 $this->rcMoveIndex = 0;
1691 $this->rcCacheIndex = 0 ;
1692 $this->lastdate = "";
1693 return "";
1696 function beginImageHistoryList()
1698 $s = "\n<h2>" . wfMsg( "imghistory" ) . "</h2>\n" .
1699 "<p>" . wfMsg( "imghistlegend" ) . "\n<ul>";
1700 return $s;
1703 # Returns text for the end of RC
1704 # If enhanced RC is in use, returns pretty much all the text
1705 function endRecentChangesList()
1707 $s = $this->recentChangesBlock() ;
1708 $s .= "</ul>\n";
1709 return $s;
1712 # Enhanced RC ungrouped line
1713 function recentChangesBlockLine ( $rcObj )
1715 global $wgUploadPath, $wgLang ;
1717 # Get rc_xxxx variables
1718 extract( $rcObj->mAttribs ) ;
1719 $curIdEq = "curid=$rc_cur_id";
1721 # Spacer image
1722 $r = "" ;
1723 $r .= "<img src='{$wgUploadPath}/Arr_.png' width=12 height=12 border=0>" ; $r .= "<tt>" ;
1725 if ( $rc_type == RC_MOVE ) {
1726 $r .= "&nbsp;&nbsp;";
1727 } else {
1728 # M & N (minor & new)
1729 $M = wfMsg( "minoreditletter" );
1730 $N = wfMsg( "newpageletter" );
1732 if ( $rc_type == RC_NEW ) {
1733 $r .= $N ;
1734 } else {
1735 $r .= "&nbsp;" ;
1737 if ( $rc_minor ) {
1738 $r .= $M ;
1739 } else {
1740 $r .= "&nbsp;" ;
1744 # Timestamp
1745 $r .= " ".$rcObj->timestamp." " ;
1746 $r .= "</tt>" ;
1748 # Article link
1749 $link = $rcObj->link ;
1750 if ( $rcObj->watched ) $link = "<strong>{$link}</strong>" ;
1751 $r .= $link ;
1753 # Cur
1754 $r .= " (" ;
1755 $r .= $rcObj->curlink ;
1756 $r .= "; " ;
1758 # Hist
1759 $r .= $this->makeKnownLinkObj( $rcObj->getTitle(), wfMsg( "hist" ), "{$curIdEq}&action=history" );
1761 # User/talk
1762 $r .= ") . . ".$rcObj->userlink ;
1763 $r .= $rcObj->usertalklink ;
1765 # Comment
1766 if ( $rc_comment != "" && $rc_type != RC_MOVE ) {
1767 $r .= $wgLang->emphasize( " (".wfEscapeHTML($rc_comment).")" );
1769 $r .= "<br>\n" ;
1770 return $r ;
1773 # Enhanced RC group
1774 function recentChangesBlockGroup ( $block )
1776 global $wgUploadPath, $wgLang ;
1778 $r = "" ;
1779 $M = wfMsg( "minoreditletter" );
1780 $N = wfMsg( "newpageletter" );
1782 # Collate list of users
1783 $isnew = false ;
1784 $userlinks = array () ;
1785 foreach ( $block AS $rcObj ) {
1786 $oldid = $rcObj->mAttribs['rc_last_oldid'];
1787 if ( $rcObj->mAttribs['rc_new'] ) $isnew = true ;
1788 $u = $rcObj->userlink ;
1789 if ( !isset ( $userlinks[$u] ) ) $userlinks[$u] = 0 ;
1790 $userlinks[$u]++ ;
1793 # Sort the list and convert to text
1794 krsort ( $userlinks ) ;
1795 asort ( $userlinks ) ;
1796 $users = array () ;
1797 foreach ( $userlinks as $userlink => $count) {
1798 $text = $userlink ;
1799 if ( $count > 1 ) $text .= " ({$count}&times;)" ;
1800 array_push ( $users , $text ) ;
1802 $users = " <font size='-1'>[".implode("; ",$users)."]</font>" ;
1804 # Arrow
1805 $rci = "RCI{$this->rcCacheIndex}" ;
1806 $rcl = "RCL{$this->rcCacheIndex}" ;
1807 $rcm = "RCM{$this->rcCacheIndex}" ;
1808 $tl = "<a href='javascript:toggleVisibility(\"{$rci}\",\"{$rcm}\",\"{$rcl}\")'>" ;
1809 $tl .= "<span id='{$rcm}'><img src='{$wgUploadPath}/Arr_r.png' width=12 height=12 border=0></span>" ;
1810 $tl .= "<span id='{$rcl}' style='display:none'><img src='{$wgUploadPath}/Arr_d.png' width=12 height=12 border=0></span>" ;
1811 $tl .= "</a>" ;
1812 $r .= $tl ;
1814 # Main line
1815 # M/N
1816 $r .= "<tt>" ;
1817 if ( $isnew ) $r .= $N ;
1818 else $r .= "&nbsp;" ;
1819 $r .= "&nbsp;" ; # Minor
1821 # Timestamp
1822 $r .= " ".$block[0]->timestamp." " ;
1823 $r .= "</tt>" ;
1825 # Article link
1826 $link = $block[0]->link ;
1827 if ( $block[0]->watched ) $link = "<strong>{$link}</strong>" ;
1828 $r .= $link ;
1830 $curIdEq = "curid=" . $block[0]->mAttribs['rc_cur_id'];
1831 if ( $block[0]->mAttribs['rc_type'] != RC_LOG ) {
1832 # Changes
1833 $r .= " (".count($block)." " ;
1834 if ( $isnew ) $r .= wfMsg("changes");
1835 else $r .= $this->makeKnownLinkObj( $block[0]->getTitle() , wfMsg("changes") ,
1836 "{$curIdEq}&diff=0&oldid=".$oldid ) ;
1837 $r .= "; " ;
1839 # History
1840 $r .= $this->makeKnownLinkObj( $block[0]->getTitle(), wfMsg( "history" ), "{$curIdEq}&action=history" );
1841 $r .= ")" ;
1844 $r .= $users ;
1845 $r .= "<br>\n" ;
1847 # Sub-entries
1848 $r .= "<div id='{$rci}' style='display:none'>" ;
1849 foreach ( $block AS $rcObj ) {
1850 # Get rc_xxxx variables
1851 extract( $rcObj->mAttribs );
1853 $r .= "<img src='{$wgUploadPath}/Arr_.png' width=12 height=12 border=0>";
1854 $r .= "<tt>&nbsp; &nbsp; &nbsp; &nbsp;" ;
1855 if ( $rc_new ) $r .= $N ;
1856 else $r .= "&nbsp;" ;
1857 if ( $rc_minor ) $r .= $M ;
1858 else $r .= "&nbsp;" ;
1859 $r .= "</tt>" ;
1861 $o = "" ;
1862 if ( $rc_last_oldid != 0 ) {
1863 $o = "oldid=".$rc_last_oldid ;
1865 if ( $rc_type == RC_LOG ) {
1866 $link = $rcObj->timestamp ;
1867 } else {
1868 $link = $this->makeKnownLink( $rcObj->getTitle(), $rcObj->timestamp , "{$curIdEq}&$o" ) ;
1870 $link = "<tt>{$link}</tt>" ;
1872 $r .= $link ;
1873 $r .= " (" ;
1874 $r .= $rcObj->curlink ;
1875 $r .= "; " ;
1876 $r .= $rcObj->lastlink ;
1877 $r .= ") . . ".$rcObj->userlink ;
1878 $r .= $rcObj->usertalklink ;
1879 if ( $rc_comment != "" ) {
1880 $r .= $wgLang->emphasize( " (".wfEscapeHTML($rc_comment).")" ) ;
1882 $r .= "<br>\n" ;
1884 $r .= "</div>\n" ;
1886 $this->rcCacheIndex++ ;
1887 return $r ;
1890 # If enhanced RC is in use, this function takes the previously cached
1891 # RC lines, arranges them, and outputs the HTML
1892 function recentChangesBlock ()
1894 global $wgUploadPath ;
1895 if ( count ( $this->rc_cache ) == 0 ) return "" ;
1896 #$k = array_keys ( $this->rc_cache ) ;
1897 foreach ( $this->rc_cache AS $secureName => $block ) {
1898 if ( count ( $block ) < 2 ) {
1899 $r .= $this->recentChangesBlockLine ( array_shift ( $block ) ) ;
1900 } else {
1901 $r .= $this->recentChangesBlockGroup ( $block ) ;
1905 return "<div align=left>{$r}</div>" ;
1908 # Called in a loop over all displayed RC entries
1909 # Either returns the line, or caches it for later use
1910 function recentChangesLine( &$rc, $watched = false )
1912 global $wgUser ;
1913 $usenew = $wgUser->getOption( "usenewrc" );
1914 if ( $usenew )
1915 $line = $this->recentChangesLineNew ( $rc, $watched ) ;
1916 else
1917 $line = $this->recentChangesLineOld ( $rc, $watched ) ;
1918 return $line ;
1921 function recentChangesLineOld( &$rc, $watched = false )
1923 global $wgTitle, $wgLang, $wgUser;
1925 # Extract DB fields into local scope
1926 extract( $rc->mAttribs );
1927 $curIdEq = "curid=" . $rc_cur_id;
1929 # Make date header if necessary
1930 $date = $wgLang->date( $rc_timestamp, true);
1931 $s = "";
1932 if ( $date != $this->lastdate ) {
1933 if ( "" != $this->lastdate ) { $s .= "</ul>\n"; }
1934 $s .= "<h4>{$date}</h4>\n<ul>";
1935 $this->lastdate = $date;
1937 $s .= "<li> ";
1939 if ( $rc_type == RC_MOVE ) {
1940 # Diff
1941 $s .= "(" . wfMsg( "diff" ) . ") (";
1942 # Hist
1943 $s .= $this->makeKnownLinkObj( $rc->getMovedToTitle(), wfMsg( "hist" ), "action=history" ) .
1944 ") . . ";
1946 # "[[x]] moved to [[y]]"
1948 $s .= wfMsg( "1movedto2", $this->makeKnownLinkObj( $rc->getTitle(), "", "redirect=no" ),
1949 $this->makeKnownLinkObj( $rc->getMovedToTitle(), "" ) );
1951 } else {
1952 # Diff link
1953 if ( $rc_type == RC_NEW || $rc_type == RC_LOG ) {
1954 $diffLink = wfMsg( "diff" );
1955 } else {
1956 $diffLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( "diff" ),
1957 "{$curIdEq}&diff={$rc_this_oldid}&oldid={$rc_last_oldid}" );
1959 $s .= "($diffLink) (";
1961 # History link
1962 $s .= $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( "hist" ), "{$curIdEq}&action=history" );
1963 $s .= ") . . ";
1965 # M and N (minor and new)
1966 $M = wfMsg( "minoreditletter" );
1967 $N = wfMsg( "newpageletter" );
1968 if ( $rc_minor ) { $s .= " <strong>{$M}</strong>"; }
1969 if ( $rc_type == RC_NEW ) { $s .= "<strong>{$N}</strong>"; }
1971 # Article link
1972 $articleLink = $this->makeKnownLinkObj( $rc->getTitle(), "" );
1974 if ( $watched ) {
1975 $articleLink = "<strong>{$articleLink}</strong>";
1977 $s .= " $articleLink";
1981 # Timestamp
1982 $s .= "; " . $wgLang->time( $rc_timestamp, true ) . " . . ";
1984 # User link (or contributions for unregistered users)
1985 if ( 0 == $rc_user ) {
1986 $userLink = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
1987 $rc_user_text, "target=" . $rc_user_text );
1988 } else {
1989 $userLink = $this->makeLink( $wgLang->getNsText( NS_USER ) . ":{$rc_user_text}", $rc_user_text );
1991 $s .= $userLink;
1993 # User talk link
1994 $talkname=$wgLang->getNsText(NS_TALK); # use the shorter name
1995 global $wgDisableAnonTalk;
1996 if( 0 == $rc_user && $wgDisableAnonTalk ) {
1997 $userTalkLink = "";
1998 } else {
1999 $utns=$wgLang->getNsText(NS_USER_TALK);
2000 $userTalkLink= $this->makeLink($utns . ":{$rc_user_text}", $talkname );
2002 # Block link
2003 $blockLink="";
2004 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2005 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2006 "Blockip" ), wfMsg( "blocklink" ), "ip={$rc_user_text}" );
2009 if($blockLink) {
2010 if($userTalkLink) $userTalkLink .= " | ";
2011 $userTalkLink .= $blockLink;
2013 if($userTalkLink) $s.=" ({$userTalkLink})";
2015 # Add comment
2016 if ( "" != $rc_comment && "*" != $rc_comment && $rc_type != RC_MOVE ) {
2017 $s .= $wgLang->emphasize(" (" . wfEscapeHTML( $rc_comment ) . ")");
2019 $s .= "</li>\n";
2021 return $s;
2024 # function recentChangesLineNew( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched = false, $oldid = 0 , $diffid = 0 )
2025 function recentChangesLineNew( &$baseRC, $watched = false )
2027 global $wgTitle, $wgLang, $wgUser;
2029 # Create a specialised object
2030 $rc = RCCacheEntry::newFromParent( $baseRC ) ;
2032 # Extract fields from DB into the function scope (rc_xxxx variables)
2033 extract( $rc->mAttribs );
2034 $curIdEq = "curid=" . $rc_cur_id;
2036 # If it's a new day, add the headline and flush the cache
2037 $date = $wgLang->date( $rc_timestamp, true);
2038 $ret = "" ;
2039 if ( $date != $this->lastdate ) {
2040 # Process current cache
2041 $ret = $this->recentChangesBlock () ;
2042 $this->rc_cache = array() ;
2043 $ret .= "<h4>{$date}</h4>\n";
2044 $this->lastdate = $date;
2047 # Make article link
2048 if ( $rc_type == RC_MOVE ) {
2049 $clink = $this->makeKnownLinkObj( $rc->getTitle(), "", "redirect=no" );
2050 $clink .= " " . wfMsg("movedto") . " ";
2051 $clink .= $this->makeKnownLinkObj( $rc->getMovedToTitle(), "" );
2052 } else {
2053 $clink = $this->makeKnownLinkObj( $rc->getTitle(), "" ) ;
2056 $time = $wgLang->time( $rc_timestamp, true );
2057 $rc->watched = $watched ;
2058 $rc->link = $clink ;
2059 $rc->timestamp = $time;
2061 # Make "cur" link
2062 if ( ( $rc_type == RC_NEW && $rc_this_oldid == 0 ) || $rc_type == RC_LOG || $rc_type == RC_MOVE) {
2063 $curLink = wfMsg( "cur" );
2064 } else {
2065 $curLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( "cur" ),
2066 "{$curIdEq}&diff=0&oldid={$rc_this_oldid}" );
2069 # Make "last" link
2070 $titleObj = $rc->getTitle();
2071 if ( $rc_last_oldid == 0 || $rc_type == RC_LOG || $rc_type == RC_MOVE ) {
2072 $lastLink = wfMsg( "last" );
2073 } else {
2074 $lastLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( "last" ),
2075 "{$curIdEq}&diff={$rc_this_oldid}&oldid={$rc_last_oldid}" );
2078 # Make user link (or user contributions for unregistered users)
2079 if ( 0 == $rc_user ) {
2080 $userLink = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
2081 $rc_user_text, "target=" . $rc_user_text );
2082 } else {
2083 $userLink = $this->makeLink( $wgLang->getNsText(
2084 Namespace::getUser() ) . ":{$rc_user_text}", $rc_user_text );
2087 $rc->userlink = $userLink ;
2088 $rc->lastlink = $lastLink ;
2089 $rc->curlink = $curLink ;
2091 # Make user talk link
2092 $utns=$wgLang->getNsText(NS_USER_TALK);
2093 $talkname=$wgLang->getNsText(NS_TALK); # use the shorter name
2094 $userTalkLink= $this->makeLink($utns . ":{$rc_user_text}", $talkname );
2096 global $wgDisableAnonTalk;
2097 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2098 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2099 "Blockip" ), wfMsg( "blocklink" ), "ip={$rc_user_text}" );
2100 if( $wgDisableAnonTalk )
2101 $rc->usertalklink = " ({$blockLink})";
2102 else
2103 $rc->usertalklink = " ({$userTalkLink} | {$blockLink})";
2104 } else {
2105 if( $wgDisableAnonTalk && ($rc_user == 0) )
2106 $rc->usertalklink = "";
2107 else
2108 $rc->usertalklink = " ({$userTalkLink})";
2111 # Put accumulated information into the cache, for later display
2112 # Page moves go on their own line
2113 $title = $rc->getTitle();
2114 $secureName = $title->getPrefixedDBkey();
2115 if ( $rc_type == RC_MOVE ) {
2116 # Use an @ character to prevent collision with page names
2117 $this->rc_cache["@@" . ($rcMoveIndex++)] = array($rc);
2118 } else {
2119 if ( !isset ( $this->rc_cache[$secureName] ) ) $this->rc_cache[$secureName] = array() ;
2120 array_push ( $this->rc_cache[$secureName] , $rc ) ;
2122 return $ret;
2125 function endImageHistoryList()
2127 $s = "</ul>\n";
2128 return $s;
2131 function imageHistoryLine( $iscur, $ts, $img, $u, $ut, $size, $c )
2133 global $wgUser, $wgLang, $wgTitle;
2135 $dt = $wgLang->timeanddate( $ts, true );
2136 $del = wfMsg( "deleteimg" );
2137 $cur = wfMsg( "cur" );
2139 if ( $iscur ) {
2140 $url = wfImageUrl( $img );
2141 $rlink = $cur;
2142 if ( $wgUser->isSysop() ) {
2143 $link = wfLocalUrlE( $wgTitle->getPrefixedText(), "image=" . $wgTitle->getURL() .
2144 "&action=delete" );
2145 $style = $this->getInternalLinkAttributes( $link, $del );
2147 $dlink = "<a href=\"{$link}\"{$style}>{$del}</a>";
2148 } else {
2149 $dlink = $del;
2151 } else {
2152 $url = wfEscapeHTML( wfImageArchiveUrl( $img ) );
2153 if( $wgUser->getID() != 0 ) {
2154 $rlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2155 wfMsg( "revertimg" ), "action=revert&oldimage=" .
2156 urlencode( $img ) );
2157 $dlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2158 $del, "action=delete&oldimage=" . urlencode( $img ) );
2159 } else {
2160 # Having live active links for non-logged in users
2161 # means that bots and spiders crawling our site can
2162 # inadvertently change content. Baaaad idea.
2163 $rlink = wfMsg( "revertimg" );
2164 $dlink = $del;
2167 if ( 0 == $u ) { $ul = $ut; }
2168 else { $ul = $this->makeLink( $wgLang->getNsText(
2169 Namespace::getUser() ) . ":{$ut}", $ut ); }
2171 $nb = wfMsg( "nbytes", $size );
2172 $style = $this->getInternalLinkAttributes( $url, $dt );
2174 $s = "<li> ({$dlink}) ({$rlink}) <a href=\"{$url}\"{$style}>{$dt}</a>"
2175 . " . . {$ul} ({$nb})";
2177 if ( "" != $c && "*" != $c ) {
2178 $s .= $wgLang->emphasize(" (" . wfEscapeHTML( $c ) . ")");
2180 $s .= "</li>\n";
2181 return $s;
2184 function tocIndent($level) {
2186 while($level-->0) $rv.="<div style=\"margin-left:2em;\">\n";
2187 return $rv;
2191 function tocUnindent($level) {
2192 $rv = "";
2193 while($level-->0) $rv.="</div>\n";
2194 return $rv;
2197 // parameter level defines if we are on an indentation level
2198 function tocLine($anchor,$tocline,$level) {
2200 if($level) {
2202 return "<A CLASS=\"internal\" HREF=\"#".$anchor."\">".$tocline."</A><BR>\n";
2203 } else {
2205 return "<div style=\"margin-bottom:0px;\">\n".
2206 "<A CLASS=\"internal\" HREF=\"#".$anchor."\">".$tocline."</A><BR>\n".
2207 "</div>\n";
2212 function tocTable($toc) {
2213 // note to CSS fanatics: putting this in a div does not work -- div won't auto-expand
2214 global $printable;
2216 if (!$printable) {
2217 $hideline = " <script type='text/javascript'>showTocToggle(\"" . wfMsg("showtoc") . "\",\"" . wfMsg("hidetoc") . "\")</script>";
2219 return
2220 "<p><table border=\"0\" id=\"toc\"><tr><td align=\"center\">\n".
2221 "<b>".wfMsg("toc")."</b>" .
2222 $hideline .
2223 "</td></tr><tr id='tocinside'><td>\n".
2224 $toc."</td></tr></table><P>\n";
2227 # These two do not check for permissions: check $wgTitle->userCanEdit before calling them
2228 function editSectionScript($section,$head) {
2230 global $wgTitle,$wgUser,$oldid;
2231 if($oldid) return $head;
2232 $url = wfLocalUrlE(urlencode(str_replace(' ','_',$wgTitle->getPrefixedText())),"action=edit&section=$section");
2233 return "<span onContextMenu='document.location=\"".$url."\";return false;'>{$head}</span>";
2236 function editSectionLink($section) {
2237 global $printable,$oldid;
2238 global $wgTitle, $wgUser, $wgLang;
2240 if( isset( $oldid ) ) return "";
2241 if( isset( $printable ) ) return "";
2243 $editurl = "&section={$section}";
2244 $url = $this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg("editsection"),"action=edit".$editurl);
2246 if( $wgLang->isRTL() ) {
2247 $farside = "left";
2248 $nearside = "right";
2249 } else {
2250 $farside = "right";
2251 $nearside = "left";
2253 return "<div style=\"float:$farside;margin-$nearside:5px;\"><small>[".$url."]</small></div>";
2257 // This function is called by EditPage.php and shows a bulletin board style
2258 // toolbar for common editing functions. It can be disabled in the user preferences.
2259 // The necsesary JavaScript code can be found in style/wikibits.js.
2260 function getEditToolbar() {
2262 global $wgUploadPath,$wgLang;
2264 // toolarray an array of arrays which each include the filename of
2265 // the button image (without path), the opening tag, the closing tag,
2266 // and optionally a sample text that is inserted between the two when no
2267 // selection is highlighted.
2268 // The tip text is shown when the user moves the mouse over the button.
2269 $toolarray=array(
2270 array( "image"=>"button_bold.gif",
2271 "open"=>"\'\'\'",
2272 "close"=>"\'\'\'",
2273 "sample"=>wfMsg("bold_sample"),
2274 "tip"=>wfMsg("bold_tip")),
2275 array( "image"=>"button_italic.gif",
2276 "open"=>"\'\'",
2277 "close"=>"\'\'",
2278 "sample"=>wfMsg("italic_sample"),
2279 "tip"=>wfMsg("italic_tip")),
2280 array( "image"=>"button_link.gif",
2281 "open"=>"[[",
2282 "close"=>"]]",
2283 "sample"=>wfMsg("link_sample"),
2284 "tip"=>wfMsg("link_tip")),
2285 array( "image"=>"button_extlink.gif",
2286 "open"=>"[",
2287 "close"=>"]",
2288 "sample"=>wfMsg("extlink_sample"),
2289 "tip"=>wfMsg("extlink_tip")),
2290 array( "image"=>"button_headline.gif",
2291 "open"=>"\\n== ",
2292 "close"=>" ==\\n",
2293 "sample"=>wfMsg("headline_sample"),
2294 "tip"=>wfMsg("headline_tip")),
2295 array( "image"=>"button_image.gif",
2296 "open"=>"[[".$wgLang->getNsText(NS_IMAGE).":",
2297 "close"=>"]]",
2298 "sample"=>wfMsg("image_sample"),
2299 "tip"=>wfMsg("image_tip")),
2300 array( "image"=>"button_media.gif",
2301 "open"=>"[[".$wgLang->getNsText(NS_MEDIA).":",
2302 "close"=>"]]",
2303 "sample"=>wfMsg("media_sample"),
2304 "tip"=>wfMsg("media_tip")),
2305 array( "image"=>"button_math.gif",
2306 "open"=>"\\<math\\>",
2307 "close"=>"\\</math\\>",
2308 "sample"=>wfMsg("math_sample"),
2309 "tip"=>wfMsg("math_tip")),
2310 array( "image"=>"button_nowiki.gif",
2311 "open"=>"\\<nowiki\\>",
2312 "close"=>"\\</nowiki\\>",
2313 "sample"=>wfMsg("nowiki_sample"),
2314 "tip"=>wfMsg("nowiki_tip")),
2315 array( "image"=>"button_sig.gif",
2316 "open"=>"--~~~~",
2317 "close"=>"",
2318 "sample"=>"",
2319 "tip"=>wfMsg("sig_tip")),
2320 array( "image"=>"button_hr.gif",
2321 "open"=>"\\n----\\n",
2322 "close"=>"",
2323 "sample"=>"",
2324 "tip"=>wfMsg("hr_tip"))
2326 $toolbar.="<script type='text/javascript'>\n";
2327 $toolbar.="document.writeln(\"<div id='toolbar'>\");\n";
2328 foreach($toolarray as $tool) {
2330 $image=$wgUploadPath."/".$tool["image"];
2331 $open=$tool["open"];
2332 $close=$tool["close"];
2333 $sample=$tool["sample"];
2335 // Note that we use the tip both for the ALT tag and the TITLE tag of the image.
2336 // Older browsers show a "speedtip" type message only for ALT.
2337 // Ideally these should be different, realistically they
2338 // probably don't need to be.
2339 $tip=$tool["tip"];
2340 $toolbar.="addButton('$image','$tip','$open','$close','$sample');\n";
2343 $toolbar.="addInfobox('".wfMsg("infobox")."');\n";
2344 $toolbar.="document.writeln(\"</div>\");\n</script>";
2345 return $toolbar;
2349 include_once( "SkinStandard.php" );
2350 include_once( "SkinNostalgia.php" );
2351 include_once( "SkinCologneBlue.php" );
2353 #include_once( "SkinSmarty.php" );