d15272e9d14845b65af28113b885c57d1cef9faf
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() ;
24 $s .= $sk->makeKnownLink ( "Special:Categories" , "Categories" , "article=".$wgTitle->getDBkey() ) ;
25 $t = implode ( " | " , $wgOut->mCategoryLinks
) ;
26 if ( $t != "" ) $s .= " : " ;
31 class RCCacheEntry
extends RecentChange
33 var $secureName, $link;
34 var $curlink , $lastlink , $usertalklink , $versionlink ;
35 var $userlink, $timestamp, $watched;
40 /* private */ var $lastdate, $lastline;
42 var $rc_cache ; # Cache for Enhanced Recent Changes
43 var $rcCacheIndex ; # Recent Changes Cache Counter for visibility toggle
50 function getSkinNames()
52 global $wgValidSkinNames;
53 return $wgValidSkinNames;
56 function getStylesheet()
58 return "wikistandard.css";
63 global $wgOut, $wgUser;
65 if ( $wgOut->isQuickbarSupressed() ) { return 0; }
66 $q = $wgUser->getOption( "quickbar" );
67 if ( "" == $q ) { $q = 0; }
71 function initPage( &$out )
73 global $wgStyleSheetPath;
74 $fname = "Skin::initPage";
75 wfProfileIn( $fname );
77 $out->addLink( "shortcut icon", "", "/favicon.ico" );
78 if ( $out->isPrintable() ) { $ss = "wikiprintable.css"; }
79 else { $ss = $this->getStylesheet(); }
80 $out->addLink( "stylesheet", "", "{$wgStyleSheetPath}/{$ss}" );
81 wfProfileOut( $fname );
84 function outputPage( &$out ) {
85 global $wgDebugComments;
87 wfProfileIn( "Skin::outputPage" );
88 $this->initPage( $out );
89 $out->out( $out->headElement() );
91 $out->out( "\n<body" );
92 $ops = $this->getBodyOptions();
93 foreach ( $ops as $name => $val ) {
94 $out->out( " $name='$val'" );
97 if ( $wgDebugComments ) {
98 $out->out( "<!-- Wiki debugging output:\n" .
99 $out->mDebugtext
. "-->\n" );
101 $out->out( $this->beforeContent() );
103 $out->out( $out->mBodytext
);
105 $out->out( $this->afterContent() );
108 $out->out( $out->reportTime() );
110 $out->out( "\n</body></html>" );
113 function getHeadScripts() {
114 global $wgStyleSheetPath;
115 $r = "<script type=\"text/javascript\" src=\"{$wgStyleSheetPath}/wikibits.js\"></script>\n";
119 function getUserStyles()
121 $s = "<style type='text/css'><!--\n";
122 $s .= $this->doGetUserStyles();
123 $s .= "//--></style>\n";
127 function doGetUserStyles()
132 if ( 1 == $wgUser->getOption( "underline" ) ) {
133 # Don't override browser settings
137 $s .= "a.stub, a.new, a.internal, a.external { " .
138 "text-decoration: none; }\n";
140 if ( 1 == $wgUser->getOption( "highlightbroken" ) ) {
141 $s .= "a.new, #quickbar a.new { color: #CC2200; }\n";
143 if ( 1 == $wgUser->getOption( "justify" ) ) {
144 $s .= "#article { text-align: justify; }\n";
149 function getBodyOptions()
151 global $wgUser, $wgTitle, $wgNamespaceBackgrounds, $wgOut, $oldid, $redirect, $diff,$action;
153 if ( 0 != $wgTitle->getNamespace() ) {
154 $a = array( "bgcolor" => "#ffffec" );
156 else $a = array( "bgcolor" => "#FFFFFF" );
157 if($wgOut->isArticle() && $wgUser->getOption("editondblclick")
159 (!$wgTitle->isProtected() ||
$wgUser->isSysop())
162 $n = $wgTitle->getPrefixedURL();
163 $t = wfMsg( "editthispage" );
165 if ( $redirect ) { $red = "&redirect={$redirect}"; }
166 if ( $oldid && ! isset( $diff ) ) {
167 $oid = "&oldid={$oldid}";
169 $s = wfLocalUrlE($n,"action=edit{$oid}{$red}");
170 $s = "document.location = \"" .$s ."\";";
171 $a +
= array ("ondblclick" => $s);
174 $a['onload'] = $wgOut->getOnloadHandler();
178 function getExternalLinkAttributes( $link, $text )
180 global $wgUser, $wgOut, $wgLang;
182 $link = urldecode( $link );
183 $link = $wgLang->checkTitleEncoding( $link );
184 $link = str_replace( "_", " ", $link );
185 $link = wfEscapeHTML( $link );
187 if ( $wgOut->isPrintable() ) { $r = " class='printable'"; }
188 else { $r = " class='external'"; }
190 if ( 1 == $wgUser->getOption( "hover" ) ) {
191 $r .= " title=\"{$link}\"";
196 function getInternalLinkAttributes( $link, $text, $broken = false )
198 global $wgUser, $wgOut;
200 $link = urldecode( $link );
201 $link = str_replace( "_", " ", $link );
202 $link = wfEscapeHTML( $link );
204 if ( $wgOut->isPrintable() ) {
205 $r = " class='printable'";
206 } else if ( $broken == "stub" ) {
207 $r = " class='stub'";
208 } else if ( $broken == "yes" ) {
211 $r = " class='internal'";
214 if ( 1 == $wgUser->getOption( "hover" ) ) {
215 $r .= " title=\"{$link}\"";
220 function getInternalLinkAttributesObj( &$nt, $text, $broken = false )
222 global $wgUser, $wgOut;
224 if ( $wgOut->isPrintable() ) {
225 $r = " class='printable'";
226 } else if ( $broken == "stub" ) {
227 $r = " class='stub'";
228 } else if ( $broken == "yes" ) {
231 $r = " class='internal'";
234 if ( 1 == $wgUser->getOption( "hover" ) ) {
235 $r .= ' title ="' . $nt->getEscapedText() . '"';
246 # This will be called immediately after the <body> tag. Split into
247 # two functions to make it easier to subclass.
249 function beforeContent()
251 global $wgUser, $wgOut, $wgSiteNotice;
253 if ( $wgOut->isPrintable() ) {
254 $s = $this->pageTitle() . $this->pageSubtitle() . "\n";
255 $s .= "\n<div class='bodytext'>";
258 if( $wgSiteNotice ) {
259 $note = "\n<div id='notice' style='font-weight: bold; color: red; text-align: center'>$wgSiteNotice</div>\n";
263 return $this->doBeforeContent() . $note;
266 function doBeforeContent()
268 global $wgUser, $wgOut, $wgTitle, $wgLang;
269 $fname = "Skin::doBeforeContent";
270 wfProfileIn( $fname );
273 $qb = $this->qbSetting();
275 if( $langlinks = $this->otherLanguages() ) {
281 $borderhack = "class='top'";
284 $s .= "\n<div id='content'>\n<div id='topbar'>" .
285 "<table width='98%' border=0 cellspacing=0><tr>";
288 $left = ($qb == 1 ||
$qb == 3);
289 if($wgLang->isRTL()) $left = !$left;
292 $s .= "<td class='top' align=left valign=top rowspan='{$rows}'>" .
293 $this->logoText() . "</td>";
295 $s .= $this->getQuickbarCompensator( $rows );
297 $l = $wgLang->isRTL() ?
"right" : "left";
298 $s .= "<td {$borderhack} align='$l' valign='top'>";
300 $s .= $this->topLinks() ;
301 $s .= "<p class='subtitle'>" . $this->pageTitleLinks();
303 $r = $wgLang->isRTL() ?
"left" : "right";
304 $s .= "</td>\n<td {$borderhack} valign='top' align='$r' nowrap>";
305 $s .= $this->nameAndLogin();
306 $s .= "\n<br>" . $this->searchForm() . "</td>";
309 $s .= "</tr>\n<tr><td class='top' colspan=\"2\">$langlinks</td>";
312 if ( $shove && !$left ) { # Right
313 $s .= $this->getQuickbarCompensator( $rows );
315 $s .= "</tr></table>\n</div>\n";
316 $s .= "\n<div id='article'>";
318 $s .= $this->pageTitle();
319 $s .= $this->pageSubtitle() ;
320 $s .= getCategories(); // For some odd reason, zhis can't be a function of the object
322 wfProfileOut( $fname );
326 function getQuickbarCompensator( $rows = 1 )
328 return "<td width='152' rowspan='{$rows}'> </td>";
331 # This gets called immediately before the </body> tag.
333 function afterContent()
335 global $wgUser, $wgOut, $wgServer;
338 if ( $wgOut->isPrintable() ) {
341 $u = htmlspecialchars( $wgServer . $wgTitle->getFullURL() );
342 $u = "<a href=\"$u\">$u</a>";
343 $rf = wfMsg( "retrievedfrom", $u );
345 if ( $wgOut->isArticle() ) {
346 $lm = "<br>" . $this->lastModified();
349 $cr = wfMsg( "gnunote" );
350 $s .= "<p><em>{$rf}{$lm} {$cr}</em>\n";
353 return $this->doAfterContent();
356 function doAfterContent()
358 global $wgUser, $wgOut, $wgLang;
359 $fname = "Skin::doAfterContent";
360 wfProfileIn( $fname );
361 wfProfileIn( "$fname-1" );
363 $s = "\n</div><br clear=all>\n";
364 $s .= "\n<div id='footer'>";
365 $s .= "<table width='98%' border=0 cellspacing=0><tr>";
367 wfProfileOut( "$fname-1" );
368 wfProfileIn( "$fname-2" );
370 $qb = $this->qbSetting();
372 $left = ($qb == 1 ||
$qb == 3);
373 if($wgLang->isRTL()) $left = !$left;
375 if ( $shove && $left ) { # Left
376 $s .= $this->getQuickbarCompensator();
378 wfProfileOut( "$fname-2" );
379 wfProfileIn( "$fname-3" );
380 $l = $wgLang->isRTL() ?
"right" : "left";
381 $s .= "<td class='bottom' align='$l' valign='top'>";
383 $s .= $this->bottomLinks();
384 $s .= "\n<br>" . $this->mainPageLink()
385 . " | " . $this->aboutLink()
386 . " | " . $this->specialLink( "recentchanges" )
387 . " | " . $this->searchForm()
388 . "<br>" . $this->pageStats();
391 if ( $shove && !$left ) { # Right
392 $s .= $this->getQuickbarCompensator();
394 $s .= "</tr></table>\n</div>\n</div>\n";
396 wfProfileOut( "$fname-3" );
397 wfProfileIn( "$fname-4" );
398 if ( 0 != $qb ) { $s .= $this->quickBar(); }
399 wfProfileOut( "$fname-4" );
400 wfProfileOut( $fname );
404 function pageTitleLinks()
406 global $wgOut, $wgTitle, $oldid, $action, $diff, $wgUser, $wgLang, $wgUseApproval ;
408 $s = $this->printableLink();
409 if ( wfMsg ( "disclaimers" ) != "-" ) $s .= " | " . $this->makeKnownLink( wfMsg( "disclaimerpage" ), wfMsg( "disclaimers" ) ) ;
411 if ( $wgOut->isArticle() ) {
412 if ( $wgTitle->getNamespace() == Namespace::getImage() ) {
413 $name = $wgTitle->getDBkey();
414 $link = wfEscapeHTML( wfImageUrl( $name ) );
415 $style = $this->getInternalLinkAttributes( $link, $name );
416 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>";
418 # This will show the "Approve" link if $wgUseApproval=true;
419 if ( isset ( $wgUseApproval ) && $wgUseApproval )
421 $t = $wgTitle->getDBkey();
422 $name = "Approve this article" ;
423 $link = "http://test.wikipedia.org/w/magnus/wiki.phtml?title={$t}&action=submit&doit=1" ;
424 #wfEscapeHTML( wfImageUrl( $name ) );
425 $style = $this->getExternalLinkAttributes( $link, $name );
426 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>" ;
428 if ( "history" == $action ||
isset( $diff ) ||
isset( $oldid ) ) {
429 $s .= " | " . $this->makeKnownLink( $wgTitle->getPrefixedText(),
430 wfMsg( "currentrev" ) );
433 if ( $wgUser->getNewtalk() ) {
434 # do not show "You have new messages" text when we are viewing our
437 if(!(strcmp($wgTitle->getText(),$wgUser->getName()) == 0 &&
438 $wgTitle->getNamespace()==Namespace::getTalk(Namespace::getUser()))) {
439 $n =$wgUser->getName();
440 $tl = $this->makeKnownLink( $wgLang->getNsText(
441 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
442 wfMsg("newmessageslink") );
443 $s.=" | <strong>". wfMsg( "newmessages", $tl ) . "</strong>";
446 if( $wgUser->isSysop() &&
447 (($wgTitle->getArticleId() == 0) ||
($action == "history")) &&
448 ($n = $wgTitle->isDeleted() ) ) {
449 $s .= " | " . wfMsg( "thisisdeleted",
450 $this->makeKnownLink(
451 $wgLang->SpecialPage( "Undelete/" . $wgTitle->getPrefixedDBkey() ),
452 wfMsg( "restorelink", $n ) ) );
457 function printableLink()
459 global $wgOut, $wgTitle, $oldid, $action;
462 foreach( $_GET as $var => $val ) {
463 if( $var != "title" && $var != "printable" )
464 $q .= urlencode( $var ) . "=" . urlencode( $val );
466 if( !empty( $q ) ) $q .= "&";
468 $s = $this->makeKnownLink( $wgTitle->getPrefixedText(),
469 WfMsg( "printableversion" ), "{$q}printable=yes" );
475 global $wgOut, $wgTitle, $wgUser;
477 $s = "<h1 class='pagetitle'>" . $wgOut->getPageTitle() . "</h1>";
478 if($wgUser->getOption("editsectiononrightclick") && $wgTitle->userCanEdit()) { $s=$this->editSectionScript(0,$s);}
482 function pageSubtitle()
484 global $wgOut,$wgTitle,$wgNamespacesWithSubpages;
486 $sub = $wgOut->getSubtitle();
488 global $wgExtraSubtitle;
489 $sub = wfMsg( "fromwikipedia" ) . $wgExtraSubtitle;
491 if($wgOut->isArticle() && $wgNamespacesWithSubpages[$wgTitle->getNamespace()]) {
492 $ptext=$wgTitle->getPrefixedText();
493 if(preg_match("/\//",$ptext)) {
494 $sub.="</p><p class='subpages'>";
495 $links=explode("/",$ptext);
498 foreach($links as $link) {
500 if ($c<count($links)) {
501 $growinglink .= $link;
502 $getlink = $this->makeLink( $growinglink, $link );
503 if(preg_match("/class='new'/i",$getlink)) { break; } # this is a hack, but it saves time
516 $s = "<p class='subtitle'>{$sub}\n";
520 function nameAndLogin()
522 global $wgUser, $wgTitle, $wgLang, $wgShowIPinHeader;
524 $li = $wgLang->specialPage( "Userlogin" );
525 $lo = $wgLang->specialPage( "Userlogout" );
528 if ( 0 == $wgUser->getID() ) {
529 if( $wgShowIPinHeader ) {
530 $n = getenv( "REMOTE_ADDR" );
532 $tl = $this->makeKnownLink( $wgLang->getNsText(
533 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
534 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
536 $s .= $n . " (".$tl.")";
538 $s .= wfMsg("notloggedin");
541 $rt = $wgTitle->getPrefixedURL();
542 if ( 0 == strcasecmp( urlencode( $lo ), $rt ) ) {
544 } else { $q = "returnto={$rt}"; }
546 $s .= "\n<br>" . $this->makeKnownLink( $li,
547 wfMsg( "login" ), $q );
549 $n = $wgUser->getName();
550 $rt = $wgTitle->getPrefixedURL();
551 $tl = $this->makeKnownLink( $wgLang->getNsText(
552 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
553 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
557 $s .= $this->makeKnownLink( $wgLang->getNsText(
558 Namespace::getUser() ) . ":{$n}", $n ) . "{$tl}<br>" .
559 $this->makeKnownLink( $lo, wfMsg( "logout" ),
560 "returnto={$rt}" ) . " | " .
561 $this->specialLink( "preferences" );
563 $s .= " | " . $this->makeKnownLink( wfMsg( "helppage" ),
569 function searchForm()
573 $s = "<form name='search' class='inline' method=get action=\""
574 . wfLocalUrl( "" ) . "\">"
575 . "<input type=text name=\"search\" size=19 value=\""
576 . htmlspecialchars(substr($search,0,256)) . "\">\n"
577 . "<input type=submit name=\"go\" value=\"" . wfMsg ("go") . "\"> "
578 . "<input type=submit value=\"" . wfMsg ("search") . "\"></form>";
588 $s = $this->mainPageLink() . $sep
589 . $this->specialLink( "recentchanges" );
591 if ( $wgOut->isArticle() ) {
592 $s .= $sep . $this->editThisPage()
593 . $sep . $this->historyLink();
595 # Many people don't like this dropdown box
596 #$s .= $sep . $this->specialPagesList();
601 function bottomLinks()
603 global $wgOut, $wgUser, $wgTitle;
607 if ( $wgOut->isArticle() ) {
608 $s .= "<strong>" . $this->editThisPage() . "</strong>";
609 if ( 0 != $wgUser->getID() ) {
610 $s .= $sep . $this->watchThisPage();
612 $s .= $sep . $this->talkLink()
613 . $sep . $this->historyLink()
614 . $sep . $this->whatLinksHere()
615 . $sep . $this->watchPageLinksLink();
617 if ( $wgTitle->getNamespace() == Namespace::getUser()
618 ||
$wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser()) )
621 $id=User
::idFromName($wgTitle->getText());
622 $ip=User
::isIP($wgTitle->getText());
624 if($id ||
$ip) { # both anons and non-anons have contri list
625 $s .= $sep . $this->userContribsLink();
627 if ( 0 != $wgUser->getID() ) { # show only to signed in users
628 if($id) { # can only email non-anons
629 $s .= $sep . $this->emailUserLink();
633 if ( $wgUser->isSysop() && $wgTitle->getArticleId() ) {
634 $s .= "\n<br>" . $this->deleteThisPage() .
635 $sep . $this->protectThisPage() .
636 $sep . $this->moveThisPage();
638 $s .= "<br>\n" . $this->otherLanguages();
645 global $wgOut, $wgLang, $wgArticle;
646 global $oldid, $diff, $wgDisableCounters;
648 if ( ! $wgOut->isArticle() ) { return ""; }
649 if ( isset( $oldid ) ||
isset( $diff ) ) { return ""; }
650 if ( 0 == $wgArticle->getID() ) { return ""; }
652 if ( $wgDisableCounters ) {
655 $count = $wgArticle->getCount();
656 $s = wfMsg( "viewcount", $count );
658 $s .= $this->lastModified();
659 $s .= " " . wfMsg( "gnunote" );
660 return "<span id='pagestats'>{$s}</span>";
663 function lastModified()
665 global $wgLang, $wgArticle;
667 $d = $wgLang->timeanddate( $wgArticle->getTimestamp(), true );
668 $s = " " . wfMsg( "lastmodified", $d );
672 function logoText( $align = "" )
674 if ( "" != $align ) { $a = " align='{$align}'"; }
677 $mp = wfMsg( "mainpage" );
678 $s = "<a href=\"" . wfLocalUrlE( urlencode( $mp ) )
679 . "\"><img{$a} border=0 src=\""
680 . $this->getLogo() . "\" alt=\"" . "[{$mp}]\"></a>";
686 global $wgOut, $wgTitle, $wgUser, $action, $wgLang;
687 global $wpPreview, $wgDisableUploads, $wgRemoteUploads;
689 $fname = "Skin::quickBar";
690 wfProfileIn( $fname );
692 $tns=$wgTitle->getNamespace();
694 $s = "\n<div id='quickbar'>";
695 $s .= "\n" . $this->logoText() . "\n<hr class='sep'>";
698 $s .= $this->mainPageLink()
699 . $sep . $this->specialLink( "recentchanges" )
700 . $sep . $this->specialLink( "randompage" );
701 if ($wgUser->getID()) {
702 $s.= $sep . $this->specialLink( "watchlist" ) ;
703 $s .= $sep .$this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
704 wfMsg( "mycontris" ), "target=" . wfUrlencode($wgUser->getName() ) );
707 // only show watchlist link if logged in
708 if ( wfMsg ( "currentevents" ) != "-" ) $s .= $sep . $this->makeKnownLink( wfMsg( "currentevents" ), "" ) ;
709 $s .= "\n<br><hr class='sep'>";
710 $articleExists = $wgTitle->getArticleId();
711 if ( $wgOut->isArticle() ||
$action =="edit" ||
$action =="history" ||
$wpPreview) {
712 if($wgOut->isArticle()) {
713 $s .= "<strong>" . $this->editThisPage() . "</strong>";
714 } else { # backlink to the article in edit or history mode
715 if($articleExists){ # no backlink if no article
718 $text = wfMsg("articlepage");
721 $text = wfMsg("viewtalkpage");
724 $text = wfMsg("userpage");
727 $text = wfMsg("viewtalkpage");
730 $text = wfMsg("wikipediapage");
733 $text = wfMsg("viewtalkpage");
736 $text = wfMsg("imagepage");
739 $text = wfMsg("viewtalkpage");
742 $text= wfMsg("articlepage");
745 $link = $wgTitle->getText();
746 if ($nstext = $wgLang->getNsText($tns) ) { # add namespace if necessary
747 $link = $nstext . ":" . $link ;
750 $s .= $this->makeLink( $link, $text );
751 } elseif( $wgTitle->getNamespace() != Namespace::getSpecial() ) {
752 # we just throw in a "New page" text to tell the user that he's in edit mode,
753 # and to avoid messing with the separator that is prepended to the next item
754 $s .= "<strong>" . wfMsg("newpage") . "</strong>";
760 if( $tns%2
&& $action!="edit" && !$wpPreview) {
761 $s.="<br>".$this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg("postcomment"),"action=edit§ion=new");
765 watching could cause problems in edit mode:
766 if user edits article, then loads "watch this article" in background and then saves
767 article with "Watch this article" checkbox disabled, the article is transparently
768 unwatched. Therefore we do not show the "Watch this page" link in edit mode
770 if ( 0 != $wgUser->getID() && $articleExists) {
771 if($action!="edit" && $action!="history" &&
772 $action != "submit" )
774 $s .= $sep . $this->watchThisPage();
776 if ( $wgTitle->userCanEdit() )
777 $s .= $sep . $this->moveThisPage();
779 if ( $wgUser->isSysop() and $articleExists ) {
780 $s .= $sep . $this->deleteThisPage() .
781 $sep . $this->protectThisPage();
783 $s .= $sep . $this->talkLink();
784 if ($articleExists && $action !="history") {
785 $s .= $sep . $this->historyLink();
787 $s.=$sep . $this->whatLinksHere();
789 if($wgOut->isArticle()) {
790 $s .= $sep . $this->watchPageLinksLink();
793 if ( Namespace::getUser() == $wgTitle->getNamespace()
794 ||
$wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser())
797 $id=User
::idFromName($wgTitle->getText());
798 $ip=User
::isIP($wgTitle->getText());
801 $s .= $sep . $this->userContribsLink();
803 if ( 0 != $wgUser->getID() ) {
804 if($id) { # can only email real users
805 $s .= $sep . $this->emailUserLink();
809 $s .= "\n<br><hr class='sep'>";
812 if ( 0 != $wgUser->getID() && ( !$wgDisableUploads ||
$wgRemoteUploads ) ) {
813 $s .= $this->specialLink( "upload" ) . $sep;
815 $s .= $this->specialLink( "specialpages" )
816 . $sep . $this->bugReportsLink();
818 global $wgSiteSupportPage;
819 if( $wgSiteSupportPage ) {
820 $s .= "\n<br><a href=\"" . htmlspecialchars( $wgSiteSupportPage ) .
821 "\" class=\"internal\">" . wfMsg( "sitesupport" ) . "</a>";
824 $s .= "\n<br></div>\n";
825 wfProfileOut( $fname );
829 function specialPagesList()
831 global $wgUser, $wgOut, $wgLang, $wgServer, $wgRedirectScript;
834 $validSP = $wgLang->getValidSpecialPages();
836 foreach ( $validSP as $name => $desc ) {
837 if ( "" == $desc ) { continue; }
840 if ( $wgUser->isSysop() )
842 $sysopSP = $wgLang->getSysopSpecialPages();
844 foreach ( $sysopSP as $name => $desc ) {
845 if ( "" == $desc ) { continue; }
849 if ( $wgUser->isDeveloper() )
851 $devSP = $wgLang->getDeveloperSpecialPages();
853 foreach ( $devSP as $name => $desc ) {
854 if ( "" == $desc ) { continue; }
859 $sp = wfMsg( "specialpages" );
860 $spp = $wgLang->specialPage( "Specialpages" );
862 $s = "<form id=\"specialpages\" method=\"get\" class=\"inline\" " .
863 "action=\"{$wgServer}{$wgRedirectScript}\">\n";
864 $s .= "<select name=\"wpDropdown\">\n";
865 $s .= "<option value=\"{$spp}\">{$sp}</option>\n";
867 foreach ( $a as $name => $desc ) {
868 $p = $wgLang->specialPage( $name );
869 $s .= "<option value=\"{$p}\">{$desc}</option>\n";
872 $s .= "<input type=submit value=\"{$go}\" name=redirect>\n";
877 function mainPageLink()
879 $mp = wfMsg( "mainpage" );
880 $s = $this->makeKnownLink( $mp, $mp );
884 function copyrightLink()
886 $s = $this->makeKnownLink( wfMsg( "copyrightpage" ),
887 wfMsg( "copyrightpagename" ) );
893 $s = $this->makeKnownLink( wfMsg( "aboutpage" ),
894 wfMsg( "aboutwikipedia" ) );
899 function disclaimerLink()
901 $s = $this->makeKnownLink( wfMsg( "disclaimerpage" ),
902 wfMsg( "disclaimers" ) );
906 function editThisPage()
908 global $wgOut, $wgTitle, $oldid, $redirect, $diff;
910 if ( ! $wgOut->isArticle() ||
$diff ) {
911 $s = wfMsg( "protectedpage" );
913 $n = $wgTitle->getPrefixedText();
914 if ( $wgTitle->userCanEdit() ) {
915 $t = wfMsg( "editthispage" );
917 #$t = wfMsg( "protectedpage" );
918 $t = wfMsg( "viewsource" );
922 if ( $redirect ) { $red = "&redirect={$redirect}"; }
923 if ( $oldid && ! isset( $diff ) ) {
924 $oid = "&oldid={$oldid}";
926 $s = $this->makeKnownLink( $n, $t, "action=edit{$oid}{$red}" );
931 function deleteThisPage()
933 global $wgUser, $wgOut, $wgTitle, $diff;
935 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
936 $n = $wgTitle->getPrefixedText();
937 $t = wfMsg( "deletethispage" );
939 $s = $this->makeKnownLink( $n, $t, "action=delete" );
946 function protectThisPage()
948 global $wgUser, $wgOut, $wgTitle, $diff;
950 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
951 $n = $wgTitle->getPrefixedText();
953 if ( $wgTitle->isProtected() ) {
954 $t = wfMsg( "unprotectthispage" );
955 $q = "action=unprotect";
957 $t = wfMsg( "protectthispage" );
958 $q = "action=protect";
960 $s = $this->makeKnownLink( $n, $t, $q );
967 function watchThisPage()
969 global $wgUser, $wgOut, $wgTitle, $diff;
971 if ( $wgOut->isArticle() && ( ! $diff ) ) {
972 $n = $wgTitle->getPrefixedText();
974 if ( $wgTitle->userIsWatching() ) {
975 $t = wfMsg( "unwatchthispage" );
976 $q = "action=unwatch";
978 $t = wfMsg( "watchthispage" );
981 $s = $this->makeKnownLink( $n, $t, $q );
983 $s = wfMsg( "notanarticle" );
988 function moveThisPage()
990 global $wgTitle, $wgLang;
992 if ( $wgTitle->userCanEdit() ) {
993 $s = $this->makeKnownLink( $wgLang->specialPage( "Movepage" ),
994 wfMsg( "movethispage" ), "target=" . $wgTitle->getPrefixedURL() );
995 } // no message if page is protected - would be redundant
999 function historyLink()
1003 $s = $this->makeKnownLink( $wgTitle->getPrefixedText(),
1004 wfMsg( "history" ), "action=history" );
1008 function whatLinksHere()
1010 global $wgTitle, $wgLang;
1012 $s = $this->makeKnownLink( $wgLang->specialPage( "Whatlinkshere" ),
1013 wfMsg( "whatlinkshere" ), "target=" . $wgTitle->getPrefixedURL() );
1017 function userContribsLink()
1019 global $wgTitle, $wgLang;
1021 $s = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
1022 wfMsg( "contributions" ), "target=" . $wgTitle->getURL() );
1026 function emailUserLink()
1028 global $wgTitle, $wgLang;
1030 $s = $this->makeKnownLink( $wgLang->specialPage( "Emailuser" ),
1031 wfMsg( "emailuser" ), "target=" . $wgTitle->getURL() );
1035 function watchPageLinksLink()
1037 global $wgOut, $wgTitle, $wgLang;
1039 if ( ! $wgOut->isArticle() ) {
1040 $s = "(" . wfMsg( "notanarticle" ) . ")";
1042 $s = $this->makeKnownLink( $wgLang->specialPage(
1043 "Recentchangeslinked" ), wfMsg( "recentchangeslinked" ),
1044 "target=" . $wgTitle->getPrefixedURL() );
1049 function otherLanguages()
1051 global $wgOut, $wgLang, $wgTitle, $wgUseNewInterlanguage;
1053 $a = $wgOut->getLanguageLinks();
1055 if ( 0 == count( $a ) ) {
1056 if ( !$wgUseNewInterlanguage ) return "";
1057 $ns = $wgLang->getNsIndex ( $wgTitle->getNamespace () ) ;
1058 if ( $ns != 0 AND $ns != 1 ) return "" ;
1060 $x = "mode=addlink&xt=".$wgTitle->getDBkey() ;
1061 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1062 wfMsg( "intl" ) , $x );
1065 if ( !$wgUseNewInterlanguage ) {
1066 $s = wfMsg( "otherlanguages" ) . ": ";
1068 global $wgLanguageCode ;
1069 $x = "mode=zoom&xt=".$wgTitle->getDBkey() ;
1070 $x .= "&xl=".$wgLanguageCode ;
1071 $s = $this->makeKnownLink( $wgLang->specialPage( "Intl" ),
1072 wfMsg( "otherlanguages" ) , $x ) . ": " ;
1075 $s = wfMsg( "otherlanguages" ) . ": ";
1077 if($wgLang->isRTL()) $s .= "<span dir='LTR'>";
1078 foreach( $a as $l ) {
1079 if ( ! $first ) { $s .= " | "; }
1082 $nt = Title
::newFromText( $l );
1083 $url = $nt->getFullURL();
1084 $text = $wgLang->getLanguageName( $nt->getInterwiki() );
1086 if ( "" == $text ) { $text = $l; }
1087 $style = $this->getExternalLinkAttributes( $l, $text );
1088 $s .= "<a href=\"{$url}\"{$style}>{$text}</a>";
1090 if($wgLang->isRTL()) $s .= "</span>";
1094 function bugReportsLink()
1096 $s = $this->makeKnownLink( wfMsg( "bugreportspage" ),
1097 wfMsg( "bugreports" ) );
1103 global $wgLinkCache;
1104 $t1 = Title
::newFromText( gmdate( "F j" ) );
1105 $t2 = Title
::newFromText( gmdate( "Y" ) );
1107 $wgLinkCache->suspend();
1108 $id = $t1->getArticleID();
1109 $wgLinkCache->resume();
1112 $s = $this->makeBrokenLink( $t1->getText() );
1114 $s = $this->makeKnownLink( $t1->getText() );
1118 $wgLinkCache->suspend();
1119 $id = $t2->getArticleID();
1120 $wgLinkCache->resume();
1123 $s .= $this->makeBrokenLink( $t2->getText() );
1125 $s .= $this->makeKnownLink( $t2->getText() );
1132 global $wgLang, $wgTitle, $wgLinkCache;
1134 $tns = $wgTitle->getNamespace();
1135 if ( -1 == $tns ) { return ""; }
1137 $pn = $wgTitle->getText();
1138 $tp = wfMsg( "talkpage" );
1139 if ( Namespace::isTalk( $tns ) ) {
1140 $lns = Namespace::getSubject( $tns );
1143 $text = wfMsg("articlepage");
1146 $text = wfMsg("userpage");
1149 $text = wfMsg("wikipediapage");
1152 $text = wfMsg("imagepage");
1155 $text= wfMsg("articlepage");
1159 $lns = Namespace::getTalk( $tns );
1162 $n = $wgLang->getNsText( $lns );
1163 if ( "" == $n ) { $link = $pn; }
1164 else { $link = "{$n}:{$pn}"; }
1166 $wgLinkCache->suspend();
1167 $s = $this->makeLink( $link, $text );
1168 $wgLinkCache->resume();
1173 function commentLink()
1175 global $wgLang, $wgTitle, $wgLinkCache;
1177 $tns = $wgTitle->getNamespace();
1178 if ( -1 == $tns ) { return ""; }
1180 $lns = ( Namespace::isTalk( $tns ) ) ?
$tns : Namespace::getTalk( $tns );
1182 # assert Namespace::isTalk( $lns )
1184 $n = $wgLang->getNsText( $lns );
1185 $pn = $wgTitle->getText();
1187 $link = "{$n}:{$pn}";
1189 $wgLinkCache->suspend();
1190 $s = $this->makeKnownLink($link, wfMsg("postcomment"), "action=edit§ion=new");
1191 $wgLinkCache->resume();
1196 # After all the page content is transformed into HTML, it makes
1197 # a final pass through here for things like table backgrounds.
1199 function transformContent( $text )
1204 # Note: This function MUST call getArticleID() on the link,
1205 # otherwise the cache won't get updated properly. See LINKCACHE.DOC.
1207 function makeLink( $title, $text = "", $query = "", $trail = "" ) {
1208 wfProfileIn( "Skin::makeLink" );
1209 $nt = Title
::newFromText( $title );
1211 $result = $this->makeLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1213 wfDebug( "Invalid title passed to Skin::makeLink(): \"$title\"\n" );
1214 $result = $text == "" ?
$title : $text;
1217 wfProfileOut( "Skin::makeLink" );
1221 function makeKnownLink( $title, $text = "", $query = "", $trail = "" ) {
1222 $nt = Title
::newFromText( $title );
1224 return $this->makeKnownLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1226 wfDebug( "Invalid title passed to Skin::makeKnownLink(): \"$title\"\n" );
1227 return $text == "" ?
$title : $text;
1231 function makeBrokenLink( $title, $text = "", $query = "", $trail = "" ) {
1232 $nt = Title
::newFromText( $title );
1234 return $this->makeBrokenLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1236 wfDebug( "Invalid title passed to Skin::makeBrokenLink(): \"$title\"\n" );
1237 return $text == "" ?
$title : $text;
1241 function makeStubLink( $title, $text = "", $query = "", $trail = "" ) {
1242 $nt = Title
::newFromText( $title );
1244 return $this->makeStubLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1246 wfDebug( "Invalid title passed to Skin::makeStubLink(): \"$title\"\n" );
1247 return $text == "" ?
$title : $text;
1251 # Pass a title object, not a title string
1252 function makeLinkObj( &$nt, $text= "", $query = "", $trail = "" )
1254 global $wgOut, $wgUser;
1255 if ( $nt->isExternal() ) {
1256 $u = $nt->getFullURL();
1257 if ( "" == $text ) { $text = $nt->getPrefixedText(); }
1258 $style = $this->getExternalLinkAttributes( $link, $text );
1261 if ( "" != $trail ) {
1262 if ( preg_match( "/^([a-z]+)(.*)$$/sD", $trail, $m ) ) {
1267 $retVal = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1268 } elseif ( 0 == $nt->getNamespace() && "" == $nt->getText() ) {
1269 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail );
1270 } elseif ( ( -1 == $nt->getNamespace() ) ||
1271 ( Namespace::getImage() == $nt->getNamespace() ) ) {
1272 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail );
1274 $aid = $nt->getArticleID() ;
1276 $retVal = $this->makeBrokenLinkObj( $nt, $text, $query, $trail );
1278 $threshold = $wgUser->getOption("stubthreshold") ;
1279 if ( $threshold > 0 ) {
1280 $res = wfQuery ( "SELECT HIGH_PRIORITY length(cur_text) AS x, cur_namespace, cur_is_redirect FROM cur WHERE cur_id='{$aid}'", DB_READ
) ;
1282 if ( wfNumRows( $res ) > 0 ) {
1283 $s = wfFetchObject( $res );
1285 if ( $s->cur_is_redirect
OR $s->cur_namespace
!= 0 ) {
1286 $size = $threshold*2 ; # Really big
1288 wfFreeResult( $res );
1290 $size = $threshold*2 ; # Really big
1295 if ( $size < $threshold ) {
1296 $retVal = $this->makeStubLinkObj( $nt, $text, $query, $trail );
1298 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail );
1305 # Pass a title object, not a title string
1306 function makeKnownLinkObj( &$nt, $text = "", $query = "", $trail = "" )
1308 global $wgOut, $wgTitle;
1310 $fname = "Skin::makeKnownLinkObj";
1311 wfProfileIn( $fname );
1313 $link = $nt->getPrefixedURL();
1315 if ( "" == $link ) {
1317 if ( "" == $text ) { $text = $nt->getFragment(); }
1319 $u = wfLocalUrlE( $link, $query );
1321 if ( "" != $nt->getFragment() ) {
1322 $u .= "#" . wfEscapeHTML( $nt->getFragment() );
1324 if ( "" == $text ) { $text = $nt->getPrefixedText(); }
1325 $style = $this->getInternalLinkAttributesObj( $nt, $text );
1328 if ( "" != $trail ) {
1329 if ( preg_match( wfMsg("linktrail"), $trail, $m ) ) {
1334 $r = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1335 wfProfileOut( $fname );
1339 # Pass a title object, not a title string
1340 function makeBrokenLinkObj( &$nt, $text = "", $query = "", $trail = "" )
1342 global $wgOut, $wgUser;
1344 $fname = "Skin::makeBrokenLinkObj";
1345 wfProfileIn( $fname );
1347 $link = $nt->getPrefixedURL();
1349 if ( "" == $query ) { $q = "action=edit"; }
1350 else { $q = "action=edit&{$query}"; }
1351 $u = wfLocalUrlE( $link, $q );
1353 if ( "" == $text ) { $text = $nt->getPrefixedText(); }
1354 $style = $this->getInternalLinkAttributesObj( $nt, $text, "yes" );
1357 if ( "" != $trail ) {
1358 if ( preg_match( wfMsg("linktrail"), $trail, $m ) ) {
1363 if ( $wgOut->isPrintable() ||
1364 ( 1 == $wgUser->getOption( "highlightbroken" ) ) ) {
1365 $s = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1367 $s = "{$text}{$inside}<a href=\"{$u}\"{$style}>?</a>{$trail}";
1370 wfProfileOut( $fname );
1374 # Pass a title object, not a title string
1375 function makeStubLinkObj( &$nt, $text = "", $query = "", $trail = "" )
1377 global $wgOut, $wgUser;
1379 $link = $nt->getPrefixedURL();
1381 $u = wfLocalUrlE( $link, $query );
1383 if ( "" == $text ) { $text = $nt->getPrefixedText(); }
1384 $style = $this->getInternalLinkAttributesObj( $nt, $text, "stub" );
1387 if ( "" != $trail ) {
1388 if ( preg_match( wfMsg("linktrail"), $trail, $m ) ) {
1393 if ( $wgOut->isPrintable() ||
1394 ( 1 == $wgUser->getOption( "highlightbroken" ) ) ) {
1395 $s = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1397 $s = "{$text}{$inside}<a href=\"{$u}\"{$style}>!</a>{$trail}";
1402 function fnamePart( $url )
1404 $basename = strrchr( $url, "/" );
1405 if ( false === $basename ) { $basename = $url; }
1406 else { $basename = substr( $basename, 1 ); }
1407 return wfEscapeHTML( $basename );
1410 function makeImage( $url, $alt = "" )
1414 if ( "" == $alt ) { $alt = $this->fnamePart( $url ); }
1415 $s = "<img src=\"{$url}\" alt=\"{$alt}\">";
1419 function makeImageLink( $name, $url, $alt = "" ) {
1420 $nt = Title
::makeTitle( Namespace::getImage(), $name );
1421 return $this->makeImageLinkObj( $nt, $alt );
1424 function makeImageLinkObj( $nt, $alt = "" ) {
1425 global $wgLang, $wgUseImageResize;
1426 $link = $nt->getPrefixedURL();
1427 $name = $nt->getDBKey();
1428 $url = wfImageUrl( $name );
1431 if ( $wgUseImageResize ) {
1432 # Check if the alt text is of the form "options|alt text"
1434 # * thumbnail make a thumbnail with enlarge-icon and caption, alignment depends on lang
1435 # * left no resizing, just left align. label is used for alt= only
1436 # * right same, but right aligned
1437 # * none same, but not aligned
1438 # * ___px scale to ___ pixels width, no aligning. e.g. use in taxobox
1440 $part = explode( "|", $alt);
1442 if ( count($part) > 1 ) {
1443 $mwThumb =& MagicWord
::get( MAG_IMG_THUMBNAIL
);
1444 $mwLeft =& MagicWord
::get( MAG_IMG_LEFT
);
1445 $mwRight =& MagicWord
::get( MAG_IMG_RIGHT
);
1446 $mwNone =& MagicWord
::get( MAG_IMG_NONE
);
1447 $mwWidth =& MagicWord
::get( MAG_IMG_WIDTH
);
1448 $alt = $part[count($part)-1];
1452 foreach( $part as $key => $val ) {
1453 if ( ! is_null( $mwThumb->matchVariableStartToEnd($val) ) ) {
1455 } elseif ( ! is_null( $mwRight->matchVariableStartToEnd($val) ) ) {
1456 # remember to set an alignment, don't render immediately
1458 } elseif ( ! is_null( $mwLeft->matchVariableStartToEnd($val) ) ) {
1459 # remember to set an alignment, don't render immediately
1461 } elseif ( ! is_null( $mwNone->matchVariableStartToEnd($val) ) ) {
1462 # remember to set an alignment, don't render immediately
1464 } elseif ( ! is_null( $match = $mwWidth->matchVariableStartToEnd($val) ) ) {
1465 # $match is the image width in pixels
1466 $width = intval($match);
1473 # Create a thumbnail. Alignment depends on language
1474 # writing direction, # right aligned for left-to-right-
1475 # languages ("Western languages"), left-aligned
1476 # for right-to-left-languages ("Semitic languages")
1478 # If thumbnail width has not been provided, it is set
1479 # here to 180 pixels
1480 if ( $align == "" ) {
1481 $align = $wgLang->isRTL() ?
"left" : "right";
1483 if ( ! isset($width) ) {
1486 return $this->makeThumbLinkObj( $nt, $alt, $align, $width );
1488 } elseif ( isset($width) ) {
1490 # Create a resized image, without the additional thumbnail
1492 $url = $this->createThumb( $name, $width );
1494 } # endif $wgUseImageResize
1496 if ( empty( $alt ) ) {
1497 $alt = preg_replace( '/\.(.+?)^/', '', $name );
1499 $alt = htmlspecialchars( $alt );
1501 $u = wfLocalUrlE( $link );
1502 $s = "<a href=\"{$u}\" class='image' title=\"{$alt}\">" .
1503 "<img border=\"0\" src=\"{$url}\" alt=\"{$alt}\"></a>";
1504 if ( "" != $align ) {
1505 $s = "<div class=\"float{$align}\">{$s}</div>";
1510 function createThumb( $name, $width ) {
1511 global $wgUploadDirectory;
1512 global $wgImageMagickConvertCommand;
1513 global $wgUseImageMagick;
1514 $imgPath = wfImagePath( $name );
1515 $thumbName = $width."px-".$icon.$name;
1516 $thumbPath = wfImageArchiveDir( $thumbName, "thumb" )."/".$thumbName;
1517 $thumbUrl = wfImageArchiveUrl( $thumbName, "thumb" );
1519 if ( (! file_exists( $thumbPath ) && file_exists( $imgPath ))
1520 ||
( filemtime($thumbPath) < filemtime($imgPath) ) ) {
1521 if ( $wgUseImageMagick ) {
1523 $cmd = $wgImageMagickConvertCommand .
1524 " -quality 95 -geometry {$width}x ".
1525 escapeshellarg($imgPath) . " " .
1526 escapeshellarg($thumbPath);
1527 $conv = shell_exec( $cmd );
1529 # Use PHP's builtin GD library functions.
1531 # First find out what kind of file this is, and select the correct
1532 # input routine for this.
1533 list($src_width, $src_height, $src_type, $src_attr) = getimagesize( $imgPath );
1534 switch( $src_type ) {
1536 $src_image = imagecreatefromgif( $imgPath );
1539 $src_image = imagecreatefromjpeg( $imgPath );
1542 $src_image = imagecreatefrompng( $imgPath );
1544 case 15: # WBMP for WML
1545 $src_image = imagecreatefromwbmp( $imgPath );
1548 $src_image = imagecreatefromxbm( $imgPath );
1551 return "Image type not supported";
1554 $height = floor( $src_height * ( $width/$src_width ) );
1555 $dst_image = imagecreatetruecolor( $width, $height );
1556 imagecopyresampled( $dst_image, $src_image,
1558 $width, $height, $src_width, $src_height );
1559 switch( $src_type ) {
1564 #$thumbUrl .= ".png";
1565 #$thumbPath .= ".png";
1566 imagepng( $dst_image, $thumbPath );
1569 #$thumbUrl .= ".jpg";
1570 #$thumbPath .= ".jpg";
1571 imageinterlace( $dst_image );
1572 imagejpeg( $dst_image, $thumbPath, 95 );
1577 imagedestroy( $dst_image );
1578 imagedestroy( $src_image );
1587 function makeThumbLinkObj( $nt, $label = "", $align = "right", $boxwidth = 180 ) {
1588 global $wgUploadPath;
1589 $name = $nt->getDBKey();
1590 $image = Title
::makeTitle( Namespace::getImage(), $name );
1591 $link = $image->getPrefixedURL();
1592 $url = wfImageUrl( $name );
1593 $path = wfImagePath( $name );
1595 list($width, $height, $type, $attr) = getimagesize( $path );
1596 $cwidth = $boxwidth;
1597 $cheight = intval( $height/($width/$cwidth) );
1598 if ($cheight > $boxwidth*1.5) {
1599 $cheight = $boxwidth*1.3;
1600 $cwidth = intval( $width/($height/$cheight) );
1602 if ( $cwidth > $width ) {
1607 $thumbUrl = $this->createThumb( $name, $cwidth );
1609 $u = wfLocalUrlE( $link );
1611 $more = wfMsg( "thumbnail-more" );
1613 $s = "<div class=\"thumbnail-{$align}\" style=\"width:{$boxwidth}px;\">" .
1614 "<a href=\"{$u}\" class=\"internal\" title=\"{$label}\">" .
1615 "<img border=\"0\" src=\"{$thumbUrl}\" alt=\"{$label}\" width=\"{$cwidth}\" height=\"{$cheight}\"></a>" .
1616 "<a href=\"{$u}\" class=\"internal\" title=\"{$more}\">" .
1617 "<img border=\"0\" src=\"{$wgUploadPath}/magnify-clip.png\" width=\"26\" height=\"24\" align=\"right\" alt=\"{$more}\"></a>" .
1618 "<p>{$label}</div></p>";
1622 function makeMediaLink( $name, $url, $alt = "" ) {
1623 $nt = Title
::makeTitle( Namespace::getMedia(), $name );
1624 return $this->makeMediaLinkObj( $nt, $alt );
1627 function makeMediaLinkObj( $nt, $alt = "" )
1629 $name = $nt->getDBKey();
1630 $url = wfImageUrl( $name );
1631 if ( empty( $alt ) ) {
1632 $alt = preg_replace( '/\.(.+?)^/', '', $name );
1635 $u = htmlspecialchars( $url );
1636 $s = "<a href=\"{$u}\" class='internal' title=\"{$alt}\">{$alt}</a>";
1640 function specialLink( $name, $key = "" )
1644 if ( "" == $key ) { $key = strtolower( $name ); }
1645 $pn = $wgLang->ucfirst( $name );
1646 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1650 # Called by history lists and recent changes
1653 # Returns text for the start of the tabular part of RC
1654 function beginRecentChangesList()
1656 $this->rc_cache
= array() ;
1657 $this->rcCacheIndex
= 0 ;
1658 $this->lastdate
= "";
1662 function beginImageHistoryList()
1664 $s = "\n<h2>" . wfMsg( "imghistory" ) . "</h2>\n" .
1665 "<p>" . wfMsg( "imghistlegend" ) . "\n<ul>";
1669 # Returns text for the end of RC
1670 # If enhanced RC is in use, returns pretty much all the text
1671 function endRecentChangesList()
1673 $s = $this->recentChangesBlock() ;
1678 # Enhanced RC ungrouped line
1679 function recentChangesBlockLine ( $rcObj )
1681 global $wgUploadPath ;
1683 # Get rc_xxxx variables
1684 extract( $rcObj->mAttribs
) ;
1685 $curIdEq = "curid=$rc_cur_id";
1689 $r .= "<img src='{$wgUploadPath}/Arr_.png' width=12 height=12 border=0>" ; $r .= "<tt>" ;
1691 if ( $rc_type == RC_MOVE
) {
1692 $r .= " ";
1694 # M & N (minor & new)
1695 $M = wfMsg( "minoreditletter" );
1696 $N = wfMsg( "newpageletter" );
1698 if ( $rc_type == RC_NEW
) {
1711 $r .= " ".$rcObj->timestamp
." " ;
1715 $link = $rcObj->link
;
1716 if ( $rcObj->watched
) $link = "<strong>{$link}</strong>" ;
1721 $r .= $rcObj->curlink
;
1725 $r .= $this->makeKnownLinkObj( $rcObj->getTitle(), wfMsg( "hist" ), "{$curIdEq}&action=history" );
1728 $r .= ") . . ".$rcObj->userlink
;
1729 $r .= $rcObj->usertalklink
;
1732 if ( $rc_comment != "" && $rc_type != RC_MOVE
)
1733 $r .= " <em>(".wfEscapeHTML($rc_comment).")</em>" ;
1739 function recentChangesBlockGroup ( $block )
1741 global $wgUploadPath ;
1744 $M = wfMsg( "minoreditletter" );
1745 $N = wfMsg( "newpageletter" );
1747 # Collate list of users
1749 $userlinks = array () ;
1750 foreach ( $block AS $rcObj ) {
1751 $oldid = $rcObj->mAttribs
['rc_last_oldid'];
1752 if ( $rcObj->mAttribs
['rc_new'] ) $isnew = true ;
1753 $u = $rcObj->userlink
;
1754 if ( !isset ( $userlinks[$u] ) ) $userlinks[$u] = 0 ;
1758 # Sort the list and convert to text
1759 krsort ( $userlinks ) ;
1760 asort ( $userlinks ) ;
1762 foreach ( $userlinks as $userlink => $count) {
1764 if ( $count > 1 ) $text .= " ({$count}×)" ;
1765 array_push ( $users , $text ) ;
1767 $users = " <font size='-1'>[".implode("; ",$users)."]</font>" ;
1770 $rci = "RCI{$this->rcCacheIndex}" ;
1771 $rcl = "RCL{$this->rcCacheIndex}" ;
1772 $rcm = "RCM{$this->rcCacheIndex}" ;
1773 $tl = "<a href='javascript:toggleVisibility(\"{$rci}\",\"{$rcm}\",\"{$rcl}\")'>" ;
1774 $tl .= "<span id='{$rcm}'><img src='{$wgUploadPath}/Arr_r.png' width=12 height=12 border=0></span>" ;
1775 $tl .= "<span id='{$rcl}' style='display:none'><img src='{$wgUploadPath}/Arr_d.png' width=12 height=12 border=0></span>" ;
1782 if ( $isnew ) $r .= $N ;
1783 else $r .= " " ;
1784 $r .= " " ; # Minor
1787 $r .= " ".$block[0]->timestamp
." " ;
1791 $link = $block[0]->link
;
1792 if ( $block[0]->watched
) $link = "<strong>{$link}</strong>" ;
1795 $curIdEq = "curid=" . $block[0]->mAttribs
['rc_cur_id'];
1796 if ( $block[0]->mAttribs
['rc_type'] != RC_LOG
) {
1798 $r .= " (".count($block)." " ;
1799 if ( $isnew ) $r .= wfMsg("changes");
1800 else $r .= $this->makeKnownLinkObj( $block[0]->getTitle() , wfMsg("changes") ,
1801 "{$curIdEq}&diff=0&oldid=".$oldid ) ;
1805 $r .= $this->makeKnownLink( $block[0]->getTitle(), wfMsg( "history" ), "{$curIdEq}&action=history" );
1813 $r .= "<div id='{$rci}' style='display:none'>" ;
1814 foreach ( $block AS $rcObj ) {
1815 # Get rc_xxxx variables
1816 extract( $rcObj->mAttribs
);
1818 $r .= "<img src='{$wgUploadPath}/Arr_.png' width=12 height=12 border=0>";
1819 $r .= "<tt> " ;
1820 if ( $rc_new ) $r .= $N ;
1821 else $r .= " " ;
1822 if ( $rc_minor ) $r .= $M ;
1823 else $r .= " " ;
1827 if ( $rc_last_oldid != 0 ) {
1828 $o = "oldid=".$rc_last_oldid ;
1830 if ( $rc_type == RC_LOG
) {
1831 $link = $rcObj->timestamp
;
1833 $link = $this->makeKnownLink( $rcObj->getTitle(), $rcObj->timestamp
, "{$curIdEq}&$o" ) ;
1835 $link = "<tt>{$link}</tt>" ;
1839 $r .= $rcObj->curlink
;
1841 $r .= $rcObj->lastlink
;
1842 $r .= ") . . ".$rcObj->userlink
;
1843 $r .= $rcObj->usertalklink
;
1844 if ( $rc_comment != "" )
1845 $r .= " <em>(".wfEscapeHTML($rc_comment).")</em>" ;
1850 $this->rcCacheIndex++
;
1854 # If enhanced RC is in use, this function takes the previously cached
1855 # RC lines, arranges them, and outputs the HTML
1856 function recentChangesBlock ()
1858 global $wgUploadPath ;
1859 if ( count ( $this->rc_cache
) == 0 ) return "" ;
1860 #$k = array_keys ( $this->rc_cache ) ;
1861 foreach ( $this->rc_cache
AS $secureName => $block ) {
1862 if ( count ( $block ) < 2 ) {
1863 $r .= $this->recentChangesBlockLine ( array_shift ( $block ) ) ;
1865 $r .= $this->recentChangesBlockGroup ( $block ) ;
1869 return "<div align=left>{$r}</div>" ;
1872 # Called in a loop over all displayed RC entries
1873 # Either returns the line, or caches it for later use
1874 function recentChangesLine( $row, $watched = false )
1877 $usenew = $wgUser->getOption( "usenewrc" );
1879 $line = $this->recentChangesLineNew ( $row, $watched ) ;
1881 $line = $this->recentChangesLineOld ( $row, $watched ) ;
1885 function recentChangesLineOld( $row, $watched = false )
1887 global $wgTitle, $wgLang, $wgUser;
1889 # Extract DB fields into local scope
1890 extract( get_object_vars( $row ) );
1891 $rc = RecentChange
::newFromRow( $row );
1892 $curIdEq = "curid=" . $rc_cur_id;
1894 # Make date header if necessary
1895 $date = $wgLang->date( $rc_timestamp, true);
1897 if ( $date != $this->lastdate
) {
1898 if ( "" != $this->lastdate
) { $s .= "</ul>\n"; }
1899 $s .= "<h4>{$date}</h4>\n<ul>";
1900 $this->lastdate
= $date;
1904 if ( $rc_type == RC_MOVE
) {
1906 $s .= "(" . wfMsg( "diff" ) . ") (";
1908 $s .= $this->makeKnownLinkObj( $rc->getMovedToTitle(), wfMsg( "hist" ), "action=history" ) .
1911 # "[[x]] moved to [[y]]"
1912 $s .= $this->makeKnownLinkObj( $rc->getTitle(), "", "redirect=no" );
1913 $s .= " " . wfMsg( "movedto" ). " ";
1914 $s .= $this->makeKnownLinkObj( $rc->getMovedToTitle(), "" );
1917 if ( $rc_type == RC_NEW ||
$rc_type == RC_LOG
) {
1918 $diffLink = wfMsg( "diff" );
1920 $diffLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( "diff" ),
1921 "{$curIdEq}&diff={$rc_this_oldid}&oldid={$rc_last_oldid}" );
1923 $s .= "($diffLink) (";
1926 $s .= $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( "hist" ), "{$curIdEq}&action=history" );
1929 # M and N (minor and new)
1930 $M = wfMsg( "minoreditletter" );
1931 $N = wfMsg( "newpageletter" );
1932 if ( $rc_minor ) { $s .= " <strong>{$M}</strong>"; }
1933 if ( $rc_type == RC_NEW
) { $s .= "<strong>{$N}</strong>"; }
1936 $articleLink = $this->makeKnownLinkObj( $rc->getTitle(), "" );
1939 $articleLink = "<strong>{$articleLink}</strong>";
1941 $s .= " $articleLink";
1946 $s .= "; " . $wgLang->time( $rc_timestamp, true ) . " . . ";
1948 # User link (or contributions for unregistered users)
1949 if ( 0 == $rc_user ) {
1950 $userLink = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
1951 $rc_user_text, "target=" . $rc_user_text );
1953 $userLink = $this->makeLink( $wgLang->getNsText( NS_USER
) . ":{$rc_user_text}", $rc_user_text );
1958 $talkname=$wgLang->getNsText(NS_TALK
); # use the shorter name
1959 global $wgDisableAnonTalk;
1960 if( 0 == $rc_user && $wgDisableAnonTalk ) {
1963 $utns=$wgLang->getNsText(NS_USER_TALK
);
1964 $userTalkLink= $this->makeLink($utns . ":{$rc_user_text}", $talkname );
1968 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
1969 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
1970 "Blockip" ), wfMsg( "blocklink" ), "ip={$rc_user_text}" );
1974 if($userTalkLink) $userTalkLink .= " | ";
1975 $userTalkLink .= $blockLink;
1977 if($userTalkLink) $s.=" ({$userTalkLink})";
1980 if ( "" != $rc_comment && "*" != $rc_comment && $rc_type != RC_MOVE
) {
1981 $s .= " <em>(" . wfEscapeHTML( $rc_comment ) . ")</em>";
1988 # function recentChangesLineNew( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched = false, $oldid = 0 , $diffid = 0 )
1989 function recentChangesLineNew( $row, $watched = false )
1991 global $wgTitle, $wgLang, $wgUser;
1993 # Fill $rc with all the information from the row
1994 $rc = new RCCacheEntry
;
1995 $rc->loadFromRow( $row );
1997 # Extract fields from DB into the function scope (rc_xxxx variables)
1998 extract( $rc->mAttribs
);
1999 $curIdEq = "curid=" . $rc_cur_id;
2001 # If it's a new day, add the headline and flush the cache
2002 $date = $wgLang->date( $rc_timestamp, true);
2004 if ( $date != $this->lastdate
) {
2005 # Process current cache
2006 $ret = $this->recentChangesBlock () ;
2007 $this->rc_cache
= array() ;
2008 $ret .= "<h4>{$date}</h4>\n";
2009 $this->lastdate
= $date;
2013 if ( $rc_type == RC_MOVE
) {
2014 $clink = $this->makeKnownLinkObj( $rc->getTitle(), "", "redirect=no" );
2015 $clink .= " " . wfMsg("movedto") . " ";
2016 $clink .= $this->makeKnownLinkObj( $rc->getMovedToTitle(), "" );
2018 $clink = $this->makeKnownLinkObj( $rc->getTitle(), "" ) ;
2021 $time = $wgLang->time( $rc_timestamp, true );
2022 $rc->watched
= $watched ;
2023 $rc->link
= $clink ;
2024 $rc->timestamp
= $time;
2027 if ( ( $rc_type == RC_NEW
&& $rc_this_oldid == 0 ) ||
$rc_type == RC_LOG ||
$rc_type == RC_MOVE
) {
2028 $curLink = wfMsg( "cur" );
2030 $curLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( "cur" ),
2031 "{$curIdEq}&diff=0&oldid={$rc_this_oldid}" );
2035 $titleObj = $rc->getTitle();
2036 if ( $rc_last_oldid == 0 ||
$rc_type == RC_LOG ||
$rc_type == RC_MOVE
) {
2037 $lastLink = wfMsg( "last" );
2039 $lastLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( "last" ),
2040 "{$curIdEq}&diff={$rc_this_oldid}&oldid={$rc_last_oldid}" );
2043 # Make user link (or user contributions for unregistered users)
2044 if ( 0 == $rc_user ) {
2045 $userLink = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
2046 $rc_user_text, "target=" . $rc_user_text );
2047 } else { $userLink = $this->makeLink( $wgLang->getNsText(
2048 Namespace::getUser() ) . ":{$rc_user_text}", $rc_user_text ); }
2050 $rc->userlink
= $userLink ;
2051 $rc->lastlink
= $lastLink ;
2052 $rc->curlink
= $curLink ;
2054 # Make user talk link
2055 $utns=$wgLang->getNsText(NS_USER_TALK
);
2056 $talkname=$wgLang->getNsText(NS_TALK
); # use the shorter name
2057 $userTalkLink= $this->makeLink($utns . ":{$rc_user_text}", $talkname );
2059 global $wgDisableAnonTalk;
2060 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2061 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2062 "Blockip" ), wfMsg( "blocklink" ), "ip={$rc_user_text}" );
2063 if( $wgDisableAnonTalk )
2064 $rc->usertalklink
= " ({$blockLink})";
2066 $rc->usertalklink
= " ({$userTalkLink} | {$blockLink})";
2068 if( $wgDisableAnonTalk && ($rc_user == 0) )
2069 $rc->usertalklink
= "";
2071 $rc->usertalklink
= " ({$userTalkLink})";
2074 # Put accumulated information into the cache, for later display
2075 # Page moves go on their own line
2076 $title = $rc->getTitle();
2077 $secureName = $title->getPrefixedDBkey();
2078 if ( $rc_type == RC_MOVE
) {
2079 array_push($this->rc_cache
, array($rc) );
2081 if ( !isset ( $this->rc_cache
[$secureName] ) ) $this->rc_cache
[$secureName] = array() ;
2082 array_push ( $this->rc_cache
[$secureName] , $rc ) ;
2087 function endImageHistoryList()
2093 function imageHistoryLine( $iscur, $ts, $img, $u, $ut, $size, $c )
2095 global $wgUser, $wgLang, $wgTitle;
2097 $dt = $wgLang->timeanddate( $ts, true );
2098 $del = wfMsg( "deleteimg" );
2099 $cur = wfMsg( "cur" );
2102 $url = wfImageUrl( $img );
2104 if ( $wgUser->isSysop() ) {
2105 $link = wfLocalUrlE( $wgTitle->getPrefixedText(), "image=" . $wgTitle->getURL() .
2107 $style = $this->getInternalLinkAttributes( $link, $del );
2109 $dlink = "<a href=\"{$link}\"{$style}>{$del}</a>";
2114 $url = wfEscapeHTML( wfImageArchiveUrl( $img ) );
2115 if( $wgUser->getID() != 0 ) {
2116 $rlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2117 wfMsg( "revertimg" ), "action=revert&oldimage=" .
2118 urlencode( $img ) );
2119 $dlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2120 $del, "action=delete&oldimage=" . urlencode( $img ) );
2122 # Having live active links for non-logged in users
2123 # means that bots and spiders crawling our site can
2124 # inadvertently change content. Baaaad idea.
2125 $rlink = wfMsg( "revertimg" );
2129 if ( 0 == $u ) { $ul = $ut; }
2130 else { $ul = $this->makeLink( $wgLang->getNsText(
2131 Namespace::getUser() ) . ":{$ut}", $ut ); }
2133 $nb = wfMsg( "nbytes", $size );
2134 $style = $this->getInternalLinkAttributes( $url, $dt );
2136 $s = "<li> ({$dlink}) ({$rlink}) <a href=\"{$url}\"{$style}>{$dt}</a>"
2137 . " . . {$ul} ({$nb})";
2139 if ( "" != $c && "*" != $c ) {
2140 $s .= " <em>(" . wfEscapeHTML( $c ) . ")</em>";
2146 function tocIndent($level) {
2148 while($level-->0) $rv.="<div style=\"margin-left:2em;\">\n";
2153 function tocUnindent($level) {
2155 while($level-->0) $rv.="</div>\n";
2159 // parameter level defines if we are on an indentation level
2160 function tocLine($anchor,$tocline,$level) {
2164 return "<A CLASS=\"internal\" HREF=\"#".$anchor."\">".$tocline."</A><BR>\n";
2167 return "<div style=\"margin-bottom:0px;\">\n".
2168 "<A CLASS=\"internal\" HREF=\"#".$anchor."\">".$tocline."</A><BR>\n".
2174 function tocTable($toc) {
2175 // note to CSS fanatics: putting this in a div does not work -- div won't auto-expand
2179 $hideline = " <script type='text/javascript'>showTocToggle(\"" . wfMsg("showtoc") . "\",\"" . wfMsg("hidetoc") . "\")</script>";
2182 "<p><table border=\"0\" id=\"toc\"><tr><td align=\"center\">\n".
2183 "<b>".wfMsg("toc")."</b>" .
2185 "</td></tr><tr id='tocinside'><td align=\"left\">\n".
2186 $toc."</td></tr></table><P>\n";
2189 # These two do not check for permissions: check $wgTitle->userCanEdit before calling them
2190 function editSectionScript($section,$head) {
2192 global $wgTitle,$wgUser,$oldid;
2193 if($oldid) return $head;
2194 $url = wfLocalUrlE(urlencode($wgTitle->getPrefixedText()),"action=edit§ion=$section");
2195 return "<span onContextMenu='document.location=\"".$url."\";return false;'>{$head}</span>";
2198 function editSectionLink($section) {
2201 global $wgTitle,$wgUser,$oldid;
2202 if($oldid) return "";
2203 if ($printable) return "";
2204 $editurl="§ion={$section}";
2205 $url=$this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg("editsection"),"action=edit".$editurl);
2206 return "<div style=\"float:right;margin-left:5px;\"><small>[".$url."]</small></div>";
2210 // This function is called by EditPage.php and shows a bulletin board style
2211 // toolbar for common editing functions. It can be disabled in the user preferences.
2212 // The necsesary JavaScript code can be found in style/wikibits.js.
2213 function getEditToolbar() {
2215 global $wgUploadPath;
2217 // toolarray an array of arrays which each include the filename of
2218 // the button image (without path), the opening tag, the closing tag,
2219 // and optionally a sample text that is inserted between the two when no
2220 // selection is highlighted.
2221 // The tip text is shown when the user moves the mouse over the button.
2223 array( "image"=>"button_bold.gif",
2224 "open"=>"\\'\\'\\'",
2225 "close"=>"\\'\\'\\'",
2226 "sample"=>wfMsg("bold_sample"),
2227 "tip"=>wfMsg("bold_tip")),
2228 array( "image"=>"button_italic.gif",
2231 "sample"=>wfMsg("italic_sample"),
2232 "tip"=>wfMsg("italic_tip")),
2233 array( "image"=>"button_link.gif",
2236 "sample"=>wfMsg("link_sample"),
2237 "tip"=>wfMsg("link_tip")),
2238 array( "image"=>"button_extlink.gif",
2241 "sample"=>wfMsg("extlink_sample"),
2242 "tip"=>wfMsg("extlink_tip")),
2243 array( "image"=>"button_headline.gif",
2246 "sample"=>wfMsg("headline_sample"),
2247 "tip"=>wfMsg("headline_tip")),
2248 array( "image"=>"button_math.gif",
2249 "open"=>"\\<math\\>",
2250 "close"=>"\\</math\\>",
2251 "sample"=>wfMsg("math_sample"),
2252 "tip"=>wfMsg("math_tip")),
2253 array( "image"=>"button_image.gif",
2256 "sample"=>wfMsg("image_sample"),
2257 "tip"=>wfMsg("image_tip")),
2258 array( "image"=>"button_media.gif",
2261 "sample"=>wfMsg("media_sample"),
2262 "tip"=>wfMsg("media_tip")),
2263 array( "image"=>"button_sig.gif",
2267 "tip"=>wfMsg("sig_tip")),
2268 array( "image"=>"button_hr.gif",
2269 "open"=>"\\n----\\n",
2272 "tip"=>wfMsg("hr_tip"))
2275 <div id=\"toolbar\">";
2276 foreach($toolarray as $tool) {
2278 $image=$tool["image"];
2279 $open=$tool["open"];
2280 $close=$tool["close"];
2281 $sample=$tool["sample"];
2283 // Note that we use the tip both for the ALT tag and the TITLE tag of the image.
2284 // Older browsers show a "speedtip" type message only for ALT.
2285 // Ideally these should be different, realistically they
2286 // probably don't need to be.
2291 "onclick=\"javascript:insertTags('$open','$close','$sample');\">".
2292 "<img src=\"$wgUploadPath/$image\" border=\"0\" ALT=\"$tip\" TITLE=\"$tip\">".
2303 include_once( "SkinStandard.php" );
2304 include_once( "SkinNostalgia.php" );
2305 include_once( "SkinCologneBlue.php" );
2307 #include_once( "SkinSmarty.php" );