3 require_once( "Feed.php" );
4 require_once( "Image.php" );
8 # These are the INTERNAL names, which get mapped
9 # directly to class names. For display purposes, the
10 # Language class has internationalized names
12 /* private */ $wgValidSkinNames = array(
13 'standard' => "Standard",
14 'nostalgia' => "Nostalgia",
15 'cologneblue' => "CologneBlue"
18 #$wgValidSkinNames[] = "PHPTal";
19 #$wgValidSkinNames['davinci'] = "DaVinci";
20 #$wgValidSkinNames['mono'] = "Mono";
21 $wgValidSkinNames['monobook'] = "MonoBook";
22 #$wgValidSkinNames['monobookminimal'] = "MonoBookMinimal";
25 require_once( "RecentChange.php" );
27 class RCCacheEntry
extends RecentChange
29 var $secureName, $link;
30 var $curlink , $lastlink , $usertalklink , $versionlink ;
31 var $userlink, $timestamp, $watched;
33 function newFromParent( $rc )
35 $rc2 = new RCCacheEntry
;
36 $rc2->mAttribs
= $rc->mAttribs
;
37 $rc2->mExtra
= $rc->mExtra
;
44 /* private */ var $lastdate, $lastline;
45 var $linktrail ; # linktrail regexp
46 var $rc_cache ; # Cache for Enhanced Recent Changes
47 var $rcCacheIndex ; # Recent Changes Cache Counter for visibility toggle
52 $this->linktrail
= wfMsg("linktrail");
55 function getSkinNames()
57 global $wgValidSkinNames;
58 return $wgValidSkinNames;
61 function getStylesheet()
63 return "wikistandard.css";
68 global $wgOut, $wgUser;
70 if ( $wgOut->isQuickbarSuppressed() ) { return 0; }
71 $q = $wgUser->getOption( "quickbar" );
72 if ( "" == $q ) { $q = 0; }
76 function initPage( &$out )
78 $fname = "Skin::initPage";
79 wfProfileIn( $fname );
81 $out->addLink( array( "rel" => "shortcut icon", "href" => "/favicon.ico" ) );
83 $this->addMetadataLinks($out);
85 wfProfileOut( $fname );
88 function addMetadataLinks( &$out ) {
89 global $wgTitle, $wgEnableDublinCoreRdf, $wgEnableCreativeCommonsRdf, $wgRdfMimeType, $action;
90 global $wgRightsPage, $wgRightsUrl;
92 if( $out->isArticleRelated() ) {
93 # note: buggy CC software only reads first "meta" link
94 if( $wgEnableCreativeCommonsRdf ) {
95 $out->addMetadataLink( array(
96 'title' => 'Creative Commons',
97 'type' => 'application/rdf+xml',
98 'href' => $wgTitle->getLocalURL( "action=creativecommons") ) );
100 if( $wgEnableDublinCoreRdf ) {
101 $out->addMetadataLink( array(
102 'title' => 'Dublin Core',
103 'type' => 'application/rdf+xml',
104 'href' => $wgTitle->getLocalURL( "action=dublincore" ) ) );
108 if( $wgRightsPage ) {
109 $copy = Title
::newFromText( $wgRightsPage );
111 $copyright = $copy->getLocalURL();
114 if( !$copyright && $wgRightsUrl ) {
115 $copyright = $wgRightsUrl;
118 $out->addLink( array(
119 "rel" => "copyright",
120 "href" => $copyright ) );
124 function outputPage( &$out ) {
125 global $wgDebugComments;
127 wfProfileIn( "Skin::outputPage" );
128 $this->initPage( $out );
129 $out->out( $out->headElement() );
131 $out->out( "\n<body" );
132 $ops = $this->getBodyOptions();
133 foreach ( $ops as $name => $val ) {
134 $out->out( " $name='$val'" );
137 if ( $wgDebugComments ) {
138 $out->out( "<!-- Wiki debugging output:\n" .
139 $out->mDebugtext
. "-->\n" );
141 $out->out( $this->beforeContent() );
143 $out->out( $out->mBodytext
. "\n" );
145 $out->out( $this->afterContent() );
148 $out->out( $out->reportTime() );
150 $out->out( "\n</body></html>" );
153 function getHeadScripts() {
155 $r = "<script type=\"text/javascript\" src=\"{$wgStylePath}/wikibits.js\"></script>\n";
159 function getUserStyles()
161 global $wgOut, $wgStylePath, $wgLang;
162 $sheet = $this->getStylesheet();
163 $s = "<style type='text/css'>\n";
164 $s .= "/*/*/\n"; # <-- Hide the styles from Netscape 4 without hiding them from IE/Mac
165 $s .= "@import url(\"$wgStylePath/$sheet\");\n";
166 if($wgLang->isRTL()) $s .= "@import url(\"$wgStylePath/common_rtl.css\");\n";
167 $s .= $this->doGetUserStyles();
173 function doGetUserStyles()
178 if ( 1 == $wgUser->getOption( "underline" ) ) {
179 # Don't override browser settings
184 "text-decoration: none; }\n";
186 if ( 1 == $wgUser->getOption( "highlightbroken" ) ) {
187 $s .= "a.new, #quickbar a.new { color: #CC2200; }\n";
189 if ( 1 == $wgUser->getOption( "justify" ) ) {
190 $s .= "#article { text-align: justify; }\n";
195 function getBodyOptions()
197 global $wgUser, $wgTitle, $wgNamespaceBackgrounds, $wgOut, $wgRequest;
199 extract( $wgRequest->getValues( 'oldid', 'redirect', 'diff' ) );
201 if ( 0 != $wgTitle->getNamespace() ) {
202 $a = array( "bgcolor" => "#ffffec" );
204 else $a = array( "bgcolor" => "#FFFFFF" );
205 if($wgOut->isArticle() && $wgUser->getOption("editondblclick") &&
206 (!$wgTitle->isProtected() ||
$wgUser->isSysop()) ) {
207 $t = wfMsg( "editthispage" );
209 if ( !empty($redirect) ) {
210 $red = "&redirect={$redirect}";
212 if ( !empty($oldid) && ! isset( $diff ) ) {
213 $oid = "&oldid={$oldid}";
215 $s = $wgTitle->getFullURL( "action=edit{$oid}{$red}" );
216 $s = "document.location = \"" .$s ."\";";
217 $a +
= array ("ondblclick" => $s);
220 $a['onload'] = $wgOut->getOnloadHandler();
224 function getExternalLinkAttributes( $link, $text, $class='' )
226 global $wgUser, $wgOut, $wgLang;
228 $link = urldecode( $link );
229 $link = $wgLang->checkTitleEncoding( $link );
230 $link = str_replace( "_", " ", $link );
231 $link = wfEscapeHTML( $link );
233 $r = ($class != '') ?
" class='$class'" : " class='external'";
235 if ( 1 == $wgUser->getOption( "hover" ) ) {
236 $r .= " title=\"{$link}\"";
241 function getInternalLinkAttributes( $link, $text, $broken = false )
243 global $wgUser, $wgOut;
245 $link = urldecode( $link );
246 $link = str_replace( "_", " ", $link );
247 $link = wfEscapeHTML( $link );
249 if ( $broken == "stub" ) {
250 $r = " class='stub'";
251 } else if ( $broken == "yes" ) {
257 if ( 1 == $wgUser->getOption( "hover" ) ) {
258 $r .= " title=\"{$link}\"";
263 function getInternalLinkAttributesObj( &$nt, $text, $broken = false )
265 global $wgUser, $wgOut;
267 if ( $broken == "stub" ) {
268 $r = " class='stub'";
269 } else if ( $broken == "yes" ) {
275 if ( 1 == $wgUser->getOption( "hover" ) ) {
276 $r .= ' title ="' . $nt->getEscapedText() . '"';
287 # This will be called immediately after the <body> tag. Split into
288 # two functions to make it easier to subclass.
290 function beforeContent()
292 global $wgUser, $wgOut, $wgSiteNotice;
294 if( $wgSiteNotice ) {
295 $note = "\n<div id='siteNotice'>$wgSiteNotice</div>\n";
299 return $this->doBeforeContent() . $note;
302 function doBeforeContent()
304 global $wgUser, $wgOut, $wgTitle, $wgLang;
305 $fname = "Skin::doBeforeContent";
306 wfProfileIn( $fname );
309 $qb = $this->qbSetting();
311 if( $langlinks = $this->otherLanguages() ) {
317 $borderhack = "class='top'";
320 $s .= "\n<div id='content'>\n<div id='topbar'>\n" .
321 "<table border='0' cellspacing='0' width='98%'>\n<tr>\n";
324 $left = ($qb == 1 ||
$qb == 3);
325 if($wgLang->isRTL()) $left = !$left;
328 $s .= "<td class='top' align='left' valign='top' rowspan='{$rows}'>\n" .
329 $this->logoText() . "</td>";
331 $s .= $this->getQuickbarCompensator( $rows );
333 $l = $wgLang->isRTL() ?
"right" : "left";
334 $s .= "<td {$borderhack} align='$l' valign='top'>\n";
336 $s .= $this->topLinks() ;
337 $s .= "<p class='subtitle'>" . $this->pageTitleLinks() . "</p>\n";
339 $r = $wgLang->isRTL() ?
"left" : "right";
340 $s .= "</td>\n<td {$borderhack} valign='top' align='$r' nowrap='nowrap'>";
341 $s .= $this->nameAndLogin();
342 $s .= "\n<br />" . $this->searchForm() . "</td>";
345 $s .= "</tr>\n<tr>\n<td class='top' colspan=\"2\">$langlinks</td>\n";
348 if ( $shove && !$left ) { # Right
349 $s .= $this->getQuickbarCompensator( $rows );
351 $s .= "</tr>\n</table>\n</div>\n";
352 $s .= "\n<div id='article'>\n";
354 $s .= $this->pageTitle();
355 $s .= $this->pageSubtitle() ;
356 $s .= $this->getCategories();
357 wfProfileOut( $fname );
361 function getCategoryLinks () {
362 global $wgOut, $wgTitle, $wgUser, $wgParser;
363 global $wgUseCategoryMagic, $wgUseCategoryBrowser, $wgLang;
364 if( !$wgUseCategoryMagic ) return "" ;
365 if( count( $wgOut->mCategoryLinks
) == 0 ) return "";
366 if( !$wgOut->isArticle() ) return "";
368 $t = implode ( " | " , $wgOut->mCategoryLinks
) ;
369 $s = $this->makeKnownLink( "Special:Categories",
370 wfMsg( "categories" ), "article=" . urlencode( $wgTitle->getPrefixedDBkey() ) )
373 if($wgUseCategoryBrowser) {
376 $wgTitle->getAllParentCategories(&$catstack);
377 foreach ($catstack as $key => $cat)
379 $s .= $this->makeLink($wgLang->getNSText( Namespace::getCategory() ).":".$key, $key )." > ".$cat."<br/>\n";
386 function getCategories() {
387 $catlinks=$this->getCategoryLinks();
388 if(!empty($catlinks)) {
389 return "<p class='catlinks'>{$catlinks}</p>";
393 function getQuickbarCompensator( $rows = 1 )
395 return "<td width='152' rowspan='{$rows}'> </td>";
398 # This gets called immediately before the </body> tag.
400 function afterContent()
402 global $wgUser, $wgOut, $wgServer;
403 global $wgTitle, $wgLang;
405 $printfooter = "<div class=\"printfooter\">\n" . $this->printFooter() . "</div>\n";
406 return $printfooter . $this->doAfterContent();
409 function printFooter() {
411 $url = htmlspecialchars( $wgTitle->getFullURL() );
412 return "<p>" . wfMsg( "retrievedfrom", "<a href=\"$url\">$url</a>" ) .
413 "</p>\n\n<p>" . $this->pageStats() . "</p>\n";
416 function doAfterContent()
418 global $wgUser, $wgOut, $wgLang;
419 $fname = "Skin::doAfterContent";
420 wfProfileIn( $fname );
421 wfProfileIn( "$fname-1" );
423 $s = "\n</div><br style=\"clear:both\" />\n";
424 $s .= "\n<div id='footer'>";
425 $s .= "<table border='0' cellspacing='0'><tr>";
427 wfProfileOut( "$fname-1" );
428 wfProfileIn( "$fname-2" );
430 $qb = $this->qbSetting();
432 $left = ($qb == 1 ||
$qb == 3);
433 if($wgLang->isRTL()) $left = !$left;
435 if ( $shove && $left ) { # Left
436 $s .= $this->getQuickbarCompensator();
438 wfProfileOut( "$fname-2" );
439 wfProfileIn( "$fname-3" );
440 $l = $wgLang->isRTL() ?
"right" : "left";
441 $s .= "<td class='bottom' align='$l' valign='top'>";
443 $s .= $this->bottomLinks();
444 $s .= "\n<br />" . $this->mainPageLink()
445 . " | " . $this->aboutLink()
446 . " | " . $this->specialLink( "recentchanges" )
447 . " | " . $this->searchForm()
448 . "<br /><span id='pagestats'>" . $this->pageStats() . "</span>";
451 if ( $shove && !$left ) { # Right
452 $s .= $this->getQuickbarCompensator();
454 $s .= "</tr></table>\n</div>\n</div>\n";
456 wfProfileOut( "$fname-3" );
457 wfProfileIn( "$fname-4" );
458 if ( 0 != $qb ) { $s .= $this->quickBar(); }
459 wfProfileOut( "$fname-4" );
460 wfProfileOut( $fname );
464 function pageTitleLinks()
466 global $wgOut, $wgTitle, $wgUser, $wgLang, $wgUseApproval, $wgRequest;
468 extract( $wgRequest->getValues( 'oldid', 'diff' ) );
469 $action = $wgRequest->getText( 'action' );
471 $s = $this->printableLink();
472 if ( wfMsg ( "disclaimers" ) != "-" ) $s .= " | " . $this->makeKnownLink( wfMsg( "disclaimerpage" ), wfMsg( "disclaimers" ) ) ;
474 if ( $wgOut->isArticleRelated() ) {
475 if ( $wgTitle->getNamespace() == Namespace::getImage() ) {
476 $name = $wgTitle->getDBkey();
477 $link = wfEscapeHTML( Image
::wfImageUrl( $name ) );
478 $style = $this->getInternalLinkAttributes( $link, $name );
479 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>";
481 # This will show the "Approve" link if $wgUseApproval=true;
482 if ( isset ( $wgUseApproval ) && $wgUseApproval )
484 $t = $wgTitle->getDBkey();
485 $name = "Approve this article" ;
486 $link = "http://test.wikipedia.org/w/magnus/wiki.phtml?title={$t}&action=submit&doit=1" ;
487 #wfEscapeHTML( wfImageUrl( $name ) );
488 $style = $this->getExternalLinkAttributes( $link, $name );
489 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>" ;
492 if ( "history" == $action ||
isset( $diff ) ||
isset( $oldid ) ) {
493 $s .= " | " . $this->makeKnownLink( $wgTitle->getPrefixedText(),
494 wfMsg( "currentrev" ) );
497 if ( $wgUser->getNewtalk() ) {
498 # do not show "You have new messages" text when we are viewing our
501 if(!(strcmp($wgTitle->getText(),$wgUser->getName()) == 0 &&
502 $wgTitle->getNamespace()==Namespace::getTalk(Namespace::getUser()))) {
503 $n =$wgUser->getName();
504 $tl = $this->makeKnownLink( $wgLang->getNsText(
505 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
506 wfMsg("newmessageslink") );
507 $s.=" | <strong>". wfMsg( "newmessages", $tl ) . "</strong>";
511 $undelete = $this->getUndeleteLink();
512 if( !empty( $undelete ) ) {
513 $s .= " | $undelete";
518 function getUndeleteLink() {
519 global $wgUser, $wgTitle, $wgLang, $action;
520 if( $wgUser->isSysop() &&
521 (($wgTitle->getArticleId() == 0) ||
($action == "history")) &&
522 ($n = $wgTitle->isDeleted() ) ) {
523 return wfMsg( "thisisdeleted",
524 $this->makeKnownLink(
525 $wgLang->SpecialPage( "Undelete/" . $wgTitle->getPrefixedDBkey() ),
526 wfMsg( "restorelink", $n ) ) );
531 function printableLink()
533 global $wgOut, $wgFeedClasses, $wgRequest;
535 $baseurl = $_SERVER['REQUEST_URI'];
536 if( strpos( "?", $baseurl ) == false ) {
541 $baseurl = htmlspecialchars( $baseurl );
542 $printurl = $wgRequest->escapeAppendQuery( "printable=yes" );
544 $s = "<a href=\"$printurl\">" . wfMsg( "printableversion" ) . "</a>";
545 if( $wgOut->isSyndicated() ) {
546 foreach( $wgFeedClasses as $format => $class ) {
547 $feedurl = $wgRequest->escapeAppendQuery( "feed=$format" );
548 $s .= " | <a href=\"$feedurl\">{$format}</a>";
556 global $wgOut, $wgTitle, $wgUser;
558 $s = "<h1 class='pagetitle'>" . htmlspecialchars( $wgOut->getPageTitle() ) . "</h1>";
559 if($wgUser->getOption("editsectiononrightclick") && $wgTitle->userCanEdit()) { $s=$this->editSectionScript(0,$s);}
563 function pageSubtitle()
567 $sub = $wgOut->getSubtitle();
569 global $wgExtraSubtitle;
570 $sub = wfMsg( "fromwikipedia" ) . $wgExtraSubtitle;
572 $subpages = $this->subPageSubtitle();
573 $sub .= !empty($subpages)?
"</p><p class='subpages'>$subpages":'';
574 $s = "<p class='subtitle'>{$sub}</p>\n";
578 function subPageSubtitle()
580 global $wgOut,$wgTitle,$wgNamespacesWithSubpages;
582 if($wgOut->isArticle() && !empty($wgNamespacesWithSubpages[$wgTitle->getNamespace()])) {
583 $ptext=$wgTitle->getPrefixedText();
584 if(preg_match("/\//",$ptext)) {
585 $links=explode("/",$ptext);
588 foreach($links as $link) {
590 if ($c<count($links)) {
591 $growinglink .= $link;
592 $getlink = $this->makeLink( $growinglink, $link );
593 if(preg_match("/class='new'/i",$getlink)) { break; } # this is a hack, but it saves time
599 $subpages .= $getlink;
608 function nameAndLogin()
610 global $wgUser, $wgTitle, $wgLang, $wgShowIPinHeader, $wgIP;
612 $li = $wgLang->specialPage( "Userlogin" );
613 $lo = $wgLang->specialPage( "Userlogout" );
616 if ( 0 == $wgUser->getID() ) {
617 if( $wgShowIPinHeader && isset( $_COOKIE[ini_get("session.name")] ) ) {
620 $tl = $this->makeKnownLink( $wgLang->getNsText(
621 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
622 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
624 $s .= $n . " (".$tl.")";
626 $s .= wfMsg("notloggedin");
629 $rt = $wgTitle->getPrefixedURL();
630 if ( 0 == strcasecmp( urlencode( $lo ), $rt ) ) {
632 } else { $q = "returnto={$rt}"; }
634 $s .= "\n<br />" . $this->makeKnownLink( $li,
635 wfMsg( "login" ), $q );
637 $n = $wgUser->getName();
638 $rt = $wgTitle->getPrefixedURL();
639 $tl = $this->makeKnownLink( $wgLang->getNsText(
640 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
641 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
645 $s .= $this->makeKnownLink( $wgLang->getNsText(
646 Namespace::getUser() ) . ":{$n}", $n ) . "{$tl}<br />" .
647 $this->makeKnownLink( $lo, wfMsg( "logout" ),
648 "returnto={$rt}" ) . " | " .
649 $this->specialLink( "preferences" );
651 $s .= " | " . $this->makeKnownLink( wfMsg( "helppage" ),
657 function getSearchLink() {
658 $searchPage =& Title
::makeTitle( NS_SPECIAL
, "Search" );
659 return $searchPage->getLocalURL();
662 function escapeSearchLink() {
663 return htmlspecialchars( $this->getSearchLink() );
666 function searchForm()
669 $search = $wgRequest->getText( 'search' );
671 $s = "<form name='search' class='inline' method='post' action=\""
672 . $this->escapeSearchLink() . "\">\n"
673 . "<input type='text' name=\"search\" size='19' value=\""
674 . htmlspecialchars(substr($search,0,256)) . "\" />\n"
675 . "<input type='submit' name=\"go\" value=\"" . wfMsg ("go") . "\" /> "
676 . "<input type='submit' name=\"fulltext\" value=\"" . wfMsg ("search") . "\" />\n</form>";
686 $s = $this->mainPageLink() . $sep
687 . $this->specialLink( "recentchanges" );
689 if ( $wgOut->isArticleRelated() ) {
690 $s .= $sep . $this->editThisPage()
691 . $sep . $this->historyLink();
693 # Many people don't like this dropdown box
694 #$s .= $sep . $this->specialPagesList();
699 function bottomLinks()
701 global $wgOut, $wgUser, $wgTitle;
705 if ( $wgOut->isArticleRelated() ) {
706 $s .= "<strong>" . $this->editThisPage() . "</strong>";
707 if ( 0 != $wgUser->getID() ) {
708 $s .= $sep . $this->watchThisPage();
710 $s .= $sep . $this->talkLink()
711 . $sep . $this->historyLink()
712 . $sep . $this->whatLinksHere()
713 . $sep . $this->watchPageLinksLink();
715 if ( $wgTitle->getNamespace() == Namespace::getUser()
716 ||
$wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser()) )
719 $id=User
::idFromName($wgTitle->getText());
720 $ip=User
::isIP($wgTitle->getText());
722 if($id ||
$ip) { # both anons and non-anons have contri list
723 $s .= $sep . $this->userContribsLink();
725 if ( 0 != $wgUser->getID() ) { # show only to signed in users
726 if($id) { # can only email non-anons
727 $s .= $sep . $this->emailUserLink();
731 if ( $wgUser->isSysop() && $wgTitle->getArticleId() ) {
732 $s .= "\n<br />" . $this->deleteThisPage() .
733 $sep . $this->protectThisPage() .
734 $sep . $this->moveThisPage();
736 $s .= "<br />\n" . $this->otherLanguages();
743 global $wgOut, $wgLang, $wgArticle, $wgRequest;
744 global $wgDisableCounters;
746 extract( $wgRequest->getValues( 'oldid', 'diff' ) );
747 if ( ! $wgOut->isArticle() ) { return ""; }
748 if ( isset( $oldid ) ||
isset( $diff ) ) { return ""; }
749 if ( 0 == $wgArticle->getID() ) { return ""; }
752 if ( !$wgDisableCounters ) {
753 $count = $wgLang->formatNum( $wgArticle->getCount() );
755 $s = wfMsg( "viewcount", $count );
759 $s .= " " . $this->getCredits();
761 return $s . " " . $this->getCopyright();
764 function getCredits() {
765 global $wgMaxCredits;
769 if (!isset($wgMaxCredits) ||
$wgMaxCredits == 0) {
770 $s = $this->lastModified();
772 $s = $this->getAuthorCredits();
773 if ($wgMaxCredits > 1) {
774 $s .= " " . $this->getContributorCredits();
781 function getAuthorCredits() {
782 global $wgLang, $wgArticle;
784 $last_author = $wgArticle->getUser();
786 if ($last_author == 0) {
787 $author_credit = wfMsg("anonymous");
789 $real_name = User
::whoIsReal($last_author);
790 if (!empty($real_name)) {
791 $author_credit = $real_name;
793 $author_credit = wfMsg("siteuser", User
::whoIs($last_author));
797 $timestamp = $wgArticle->getTimestamp();
799 $d = $wgLang->timeanddate( $wgArticle->getTimestamp(), true );
803 return wfMsg("lastmodifiedby", $d, $author_credit);
806 function getContributorCredits() {
808 global $wgArticle, $wgMaxCredits, $wgLang;
810 # don't count last editor
812 $contributors = $wgArticle->getContributors($wgMaxCredits - 1);
814 $real_names = array();
815 $user_names = array();
817 # Sift for real versus user names
819 foreach ($contributors as $user_id => $user_parts) {
821 if (!empty($user_parts[1])) {
822 $real_names[$user_id] = $user_parts[1];
824 $user_names[$user_id] = $user_parts[0];
829 $real = $wgLang->listToText(array_values($real_names));
830 $user = $wgLang->listToText(array_values($user_names));
833 $user = wfMsg("siteusers", $user);
836 if ($contributors[0] && $contributors[0][0] > 0) {
837 $anon = wfMsg("anonymous");
842 $creds = $wgLang->listToText(array($real, $user, $anon));
844 return wfMsg("othercontribs", $creds);
847 function getCopyright() {
848 global $wgRightsPage, $wgRightsUrl, $wgRightsText;
850 if( $wgRightsPage ) {
851 $link = $this->makeKnownLink( $wgRightsPage, $wgRightsText );
852 } elseif( $wgRightsUrl ) {
853 $link = $this->makeExternalLink( $wgRightsUrl, $wgRightsText );
858 $out .= wfMsg( "copyright", $link );
862 function getCopyrightIcon() {
863 global $wgRightsPage, $wgRightsUrl, $wgRightsText, $wgRightsIcon;
865 if( $wgRightsIcon ) {
866 $icon = htmlspecialchars( $wgRightsIcon );
868 $url = htmlspecialchars( $wgRightsUrl );
869 $out .= "<a href=\"$url\">";
871 $text = htmlspecialchars( $wgRightsText );
872 $out .= "<img src=\"$icon\" alt='$text' />";
880 function getPoweredBy() {
882 $url = htmlspecialchars( "$wgStylePath/images/poweredby_mediawiki_88x31.png" );
883 $img = "<a href='http://www.mediawiki.org/'><img src='$url' alt='MediaWiki' /></a>";
887 function lastModified()
889 global $wgLang, $wgArticle;
891 $timestamp = $wgArticle->getTimestamp();
893 $d = $wgLang->timeanddate( $wgArticle->getTimestamp(), true );
894 $s = " " . wfMsg( "lastmodified", $d );
901 function logoText( $align = "" )
903 if ( "" != $align ) { $a = " align='{$align}'"; }
906 $mp = wfMsg( "mainpage" );
907 $titleObj = Title
::newFromText( $mp );
908 $s = "<a href=\"" . $titleObj->escapeLocalURL()
909 . "\"><img{$a} src=\""
910 . $this->getLogo() . "\" alt=\"" . "[{$mp}]\" /></a>";
916 global $wgOut, $wgTitle, $wgUser, $wgRequest, $wgLang;
917 global $wgDisableUploads, $wgRemoteUploads;
919 $fname = "Skin::quickBar";
920 wfProfileIn( $fname );
922 $action = $wgRequest->getText( 'action' );
923 $wpPreview = $wgRequest->getBool( 'wpPreview' );
924 $tns=$wgTitle->getNamespace();
926 $s = "\n<div id='quickbar'>";
927 $s .= "\n" . $this->logoText() . "\n<hr class='sep' />";
930 $s .= $this->mainPageLink()
931 . $sep . $this->specialLink( "recentchanges" )
932 . $sep . $this->specialLink( "randompage" );
933 if ($wgUser->getID()) {
934 $s.= $sep . $this->specialLink( "watchlist" ) ;
935 $s .= $sep .$this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
936 wfMsg( "mycontris" ), "target=" . wfUrlencode($wgUser->getName() ) );
939 // only show watchlist link if logged in
940 if ( wfMsg ( "currentevents" ) != "-" ) $s .= $sep . $this->makeKnownLink( wfMsg( "currentevents" ), "" ) ;
941 $s .= "\n<br /><hr class='sep' />";
942 $articleExists = $wgTitle->getArticleId();
943 if ( $wgOut->isArticle() ||
$action =="edit" ||
$action =="history" ||
$wpPreview) {
944 if($wgOut->isArticle()) {
945 $s .= "<strong>" . $this->editThisPage() . "</strong>";
946 } else { # backlink to the article in edit or history mode
947 if($articleExists){ # no backlink if no article
950 $text = wfMsg("articlepage");
953 $text = wfMsg("viewtalkpage");
956 $text = wfMsg("userpage");
959 $text = wfMsg("viewtalkpage");
962 $text = wfMsg("wikipediapage");
965 $text = wfMsg("viewtalkpage");
968 $text = wfMsg("imagepage");
971 $text = wfMsg("viewtalkpage");
974 $text= wfMsg("articlepage");
977 $link = $wgTitle->getText();
978 if ($nstext = $wgLang->getNsText($tns) ) { # add namespace if necessary
979 $link = $nstext . ":" . $link ;
982 $s .= $this->makeLink( $link, $text );
983 } elseif( $wgTitle->getNamespace() != Namespace::getSpecial() ) {
984 # we just throw in a "New page" text to tell the user that he's in edit mode,
985 # and to avoid messing with the separator that is prepended to the next item
986 $s .= "<strong>" . wfMsg("newpage") . "</strong>";
992 if( $tns%2
&& $action!="edit" && !$wpPreview) {
993 $s.="<br />".$this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg("postcomment"),"action=edit§ion=new");
997 watching could cause problems in edit mode:
998 if user edits article, then loads "watch this article" in background and then saves
999 article with "Watch this article" checkbox disabled, the article is transparently
1000 unwatched. Therefore we do not show the "Watch this page" link in edit mode
1002 if ( 0 != $wgUser->getID() && $articleExists) {
1003 if($action!="edit" && $action != "submit" )
1005 $s .= $sep . $this->watchThisPage();
1007 if ( $wgTitle->userCanEdit() )
1008 $s .= $sep . $this->moveThisPage();
1010 if ( $wgUser->isSysop() and $articleExists ) {
1011 $s .= $sep . $this->deleteThisPage() .
1012 $sep . $this->protectThisPage();
1014 $s .= $sep . $this->talkLink();
1015 if ($articleExists && $action !="history") {
1016 $s .= $sep . $this->historyLink();
1018 $s.=$sep . $this->whatLinksHere();
1020 if($wgOut->isArticleRelated()) {
1021 $s .= $sep . $this->watchPageLinksLink();
1024 if ( Namespace::getUser() == $wgTitle->getNamespace()
1025 ||
$wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser())
1028 $id=User
::idFromName($wgTitle->getText());
1029 $ip=User
::isIP($wgTitle->getText());
1032 $s .= $sep . $this->userContribsLink();
1034 if ( 0 != $wgUser->getID() ) {
1035 if($id) { # can only email real users
1036 $s .= $sep . $this->emailUserLink();
1040 $s .= "\n<br /><hr class='sep' />";
1043 if ( 0 != $wgUser->getID() && ( !$wgDisableUploads ||
$wgRemoteUploads ) ) {
1044 $s .= $this->specialLink( "upload" ) . $sep;
1046 $s .= $this->specialLink( "specialpages" )
1047 . $sep . $this->bugReportsLink();
1049 global $wgSiteSupportPage;
1050 if( $wgSiteSupportPage ) {
1051 $s .= "\n<br /><a href=\"" . htmlspecialchars( $wgSiteSupportPage ) .
1052 "\" class=\"internal\">" . wfMsg( "sitesupport" ) . "</a>";
1055 $s .= "\n<br /></div>\n";
1056 wfProfileOut( $fname );
1060 function specialPagesList()
1062 global $wgUser, $wgOut, $wgLang, $wgServer, $wgRedirectScript;
1064 $pages = SpecialPage
::getPages();
1066 foreach ( $pages[""] as $name => $page ) {
1067 $a[$name] = $page->getDescription();
1069 if ( $wgUser->isSysop() )
1071 foreach ( $pages["sysop"] as $name => $page ) {
1072 $a[$name] = $page->getDescription();
1075 if ( $wgUser->isDeveloper() )
1077 foreach ( $pages["developer"] as $name => $page ) {
1078 $a[$name] = $page->getDescription() ;
1081 $go = wfMsg( "go" );
1082 $sp = wfMsg( "specialpages" );
1083 $spp = $wgLang->specialPage( "Specialpages" );
1085 $s = "<form id=\"specialpages\" method=\"get\" class=\"inline\" " .
1086 "action=\"" . htmlspecialchars( "{$wgServer}{$wgRedirectScript}" ) . "\">\n";
1087 $s .= "<select name=\"wpDropdown\">\n";
1088 $s .= "<option value=\"{$spp}\">{$sp}</option>\n";
1090 foreach ( $a as $name => $desc ) {
1091 $p = $wgLang->specialPage( $name );
1092 $s .= "<option value=\"{$p}\">{$desc}</option>\n";
1094 $s .= "</select>\n";
1095 $s .= "<input type='submit' value=\"{$go}\" name='redirect' />\n";
1100 function mainPageLink()
1102 $mp = wfMsg( "mainpage" );
1103 $s = $this->makeKnownLink( $mp, $mp );
1107 function copyrightLink()
1109 $s = $this->makeKnownLink( wfMsg( "copyrightpage" ),
1110 wfMsg( "copyrightpagename" ) );
1114 function aboutLink()
1116 $s = $this->makeKnownLink( wfMsg( "aboutpage" ),
1117 wfMsg( "aboutwikipedia" ) );
1122 function disclaimerLink()
1124 $s = $this->makeKnownLink( wfMsg( "disclaimerpage" ),
1125 wfMsg( "disclaimers" ) );
1129 function editThisPage()
1131 global $wgOut, $wgTitle, $wgRequest;
1133 $oldid = $wgRequest->getVal( 'oldid' );
1134 $diff = $wgRequest->getVal( 'diff' );
1135 $redirect = $wgRequest->getVal( 'redirect' );
1137 if ( ! $wgOut->isArticleRelated() ) {
1138 $s = wfMsg( "protectedpage" );
1140 $n = $wgTitle->getPrefixedText();
1141 if ( $wgTitle->userCanEdit() ) {
1142 $t = wfMsg( "editthispage" );
1144 #$t = wfMsg( "protectedpage" );
1145 $t = wfMsg( "viewsource" );
1149 if ( !is_null( $redirect ) ) { $red = "&redirect={$redirect}"; }
1150 if ( $oldid && ! isset( $diff ) ) {
1151 $oid = "&oldid={$oldid}";
1153 $s = $this->makeKnownLink( $n, $t, "action=edit{$oid}{$red}" );
1158 function deleteThisPage()
1160 global $wgUser, $wgOut, $wgTitle, $wgRequest;
1162 $diff = $wgRequest->getVal( 'diff' );
1163 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
1164 $n = $wgTitle->getPrefixedText();
1165 $t = wfMsg( "deletethispage" );
1167 $s = $this->makeKnownLink( $n, $t, "action=delete" );
1174 function protectThisPage()
1176 global $wgUser, $wgOut, $wgTitle, $wgRequest;
1178 $diff = $wgRequest->getVal( 'diff' );
1179 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
1180 $n = $wgTitle->getPrefixedText();
1182 if ( $wgTitle->isProtected() ) {
1183 $t = wfMsg( "unprotectthispage" );
1184 $q = "action=unprotect";
1186 $t = wfMsg( "protectthispage" );
1187 $q = "action=protect";
1189 $s = $this->makeKnownLink( $n, $t, $q );
1196 function watchThisPage()
1198 global $wgUser, $wgOut, $wgTitle;
1200 if ( $wgOut->isArticleRelated() ) {
1201 $n = $wgTitle->getPrefixedText();
1203 if ( $wgTitle->userIsWatching() ) {
1204 $t = wfMsg( "unwatchthispage" );
1205 $q = "action=unwatch";
1207 $t = wfMsg( "watchthispage" );
1208 $q = "action=watch";
1210 $s = $this->makeKnownLink( $n, $t, $q );
1212 $s = wfMsg( "notanarticle" );
1217 function moveThisPage()
1219 global $wgTitle, $wgLang;
1221 if ( $wgTitle->userCanEdit() ) {
1222 $s = $this->makeKnownLink( $wgLang->specialPage( "Movepage" ),
1223 wfMsg( "movethispage" ), "target=" . $wgTitle->getPrefixedURL() );
1224 } // no message if page is protected - would be redundant
1228 function historyLink()
1232 $s = $this->makeKnownLink( $wgTitle->getPrefixedText(),
1233 wfMsg( "history" ), "action=history" );
1237 function whatLinksHere()
1239 global $wgTitle, $wgLang;
1241 $s = $this->makeKnownLink( $wgLang->specialPage( "Whatlinkshere" ),
1242 wfMsg( "whatlinkshere" ), "target=" . $wgTitle->getPrefixedURL() );
1246 function userContribsLink()
1248 global $wgTitle, $wgLang;
1250 $s = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
1251 wfMsg( "contributions" ), "target=" . $wgTitle->getPartialURL() );
1255 function emailUserLink()
1257 global $wgTitle, $wgLang;
1259 $s = $this->makeKnownLink( $wgLang->specialPage( "Emailuser" ),
1260 wfMsg( "emailuser" ), "target=" . $wgTitle->getPartialURL() );
1264 function watchPageLinksLink()
1266 global $wgOut, $wgTitle, $wgLang;
1268 if ( ! $wgOut->isArticleRelated() ) {
1269 $s = "(" . wfMsg( "notanarticle" ) . ")";
1271 $s = $this->makeKnownLink( $wgLang->specialPage(
1272 "Recentchangeslinked" ), wfMsg( "recentchangeslinked" ),
1273 "target=" . $wgTitle->getPrefixedURL() );
1278 function otherLanguages()
1280 global $wgOut, $wgLang, $wgTitle, $wgUseNewInterlanguage;
1282 $a = $wgOut->getLanguageLinks();
1283 if ( 0 == count( $a ) ) {
1284 if ( !$wgUseNewInterlanguage ) return "";
1285 $ns = $wgLang->getNsIndex ( $wgTitle->getNamespace () ) ;
1286 if ( $ns != 0 AND $ns != 1 ) return "" ;
1288 $x = "mode=addlink&xt=".$wgTitle->getDBkey() ;
1289 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1290 wfMsg( "intl" ) , $x );
1293 if ( !$wgUseNewInterlanguage ) {
1294 $s = wfMsg( "otherlanguages" ) . ": ";
1296 global $wgLanguageCode ;
1297 $x = "mode=zoom&xt=".$wgTitle->getDBkey() ;
1298 $x .= "&xl=".$wgLanguageCode ;
1299 $s = $this->makeKnownLink( $wgLang->specialPage( "Intl" ),
1300 wfMsg( "otherlanguages" ) , $x ) . ": " ;
1303 $s = wfMsg( "otherlanguages" ) . ": ";
1305 if($wgLang->isRTL()) $s .= "<span dir='LTR'>";
1306 foreach( $a as $l ) {
1307 if ( ! $first ) { $s .= " | "; }
1310 $nt = Title
::newFromText( $l );
1311 $url = $nt->getFullURL();
1312 $text = $wgLang->getLanguageName( $nt->getInterwiki() );
1314 if ( "" == $text ) { $text = $l; }
1315 $style = $this->getExternalLinkAttributes( $l, $text );
1316 $s .= "<a href=\"{$url}\"{$style}>{$text}</a>";
1318 if($wgLang->isRTL()) $s .= "</span>";
1322 function bugReportsLink()
1324 $s = $this->makeKnownLink( wfMsg( "bugreportspage" ),
1325 wfMsg( "bugreports" ) );
1331 global $wgLinkCache;
1332 $t1 = Title
::newFromText( gmdate( "F j" ) );
1333 $t2 = Title
::newFromText( gmdate( "Y" ) );
1335 $wgLinkCache->suspend();
1336 $id = $t1->getArticleID();
1337 $wgLinkCache->resume();
1340 $s = $this->makeBrokenLink( $t1->getText() );
1342 $s = $this->makeKnownLink( $t1->getText() );
1346 $wgLinkCache->suspend();
1347 $id = $t2->getArticleID();
1348 $wgLinkCache->resume();
1351 $s .= $this->makeBrokenLink( $t2->getText() );
1353 $s .= $this->makeKnownLink( $t2->getText() );
1360 global $wgLang, $wgTitle, $wgLinkCache;
1362 $tns = $wgTitle->getNamespace();
1363 if ( -1 == $tns ) { return ""; }
1365 $pn = $wgTitle->getText();
1366 $tp = wfMsg( "talkpage" );
1367 if ( Namespace::isTalk( $tns ) ) {
1368 $lns = Namespace::getSubject( $tns );
1371 $text = wfMsg("articlepage");
1374 $text = wfMsg("userpage");
1377 $text = wfMsg("wikipediapage");
1380 $text = wfMsg("imagepage");
1383 $text= wfMsg("articlepage");
1387 $lns = Namespace::getTalk( $tns );
1390 $n = $wgLang->getNsText( $lns );
1391 if ( "" == $n ) { $link = $pn; }
1392 else { $link = "{$n}:{$pn}"; }
1394 $wgLinkCache->suspend();
1395 $s = $this->makeLink( $link, $text );
1396 $wgLinkCache->resume();
1401 function commentLink()
1403 global $wgLang, $wgTitle, $wgLinkCache;
1405 $tns = $wgTitle->getNamespace();
1406 if ( -1 == $tns ) { return ""; }
1408 $lns = ( Namespace::isTalk( $tns ) ) ?
$tns : Namespace::getTalk( $tns );
1410 # assert Namespace::isTalk( $lns )
1412 $n = $wgLang->getNsText( $lns );
1413 $pn = $wgTitle->getText();
1415 $link = "{$n}:{$pn}";
1417 $wgLinkCache->suspend();
1418 $s = $this->makeKnownLink($link, wfMsg("postcomment"), "action=edit§ion=new");
1419 $wgLinkCache->resume();
1424 # After all the page content is transformed into HTML, it makes
1425 # a final pass through here for things like table backgrounds.
1427 function transformContent( $text )
1432 # Note: This function MUST call getArticleID() on the link,
1433 # otherwise the cache won't get updated properly. See LINKCACHE.DOC.
1435 function makeLink( $title, $text = "", $query = "", $trail = "" ) {
1436 wfProfileIn( "Skin::makeLink" );
1437 $nt = Title
::newFromText( $title );
1439 $result = $this->makeLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1441 wfDebug( "Invalid title passed to Skin::makeLink(): \"$title\"\n" );
1442 $result = $text == "" ?
$title : $text;
1445 wfProfileOut( "Skin::makeLink" );
1449 function makeKnownLink( $title, $text = "", $query = "", $trail = "", $prefix = '',$aprops = '') {
1450 $nt = Title
::newFromText( $title );
1452 return $this->makeKnownLinkObj( Title
::newFromText( $title ), $text, $query, $trail, $prefix , $aprops );
1454 wfDebug( "Invalid title passed to Skin::makeKnownLink(): \"$title\"\n" );
1455 return $text == "" ?
$title : $text;
1459 function makeBrokenLink( $title, $text = "", $query = "", $trail = "" ) {
1460 $nt = Title
::newFromText( $title );
1462 return $this->makeBrokenLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1464 wfDebug( "Invalid title passed to Skin::makeBrokenLink(): \"$title\"\n" );
1465 return $text == "" ?
$title : $text;
1469 function makeStubLink( $title, $text = "", $query = "", $trail = "" ) {
1470 $nt = Title
::newFromText( $title );
1472 return $this->makeStubLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1474 wfDebug( "Invalid title passed to Skin::makeStubLink(): \"$title\"\n" );
1475 return $text == "" ?
$title : $text;
1479 # Pass a title object, not a title string
1480 function makeLinkObj( &$nt, $text= "", $query = "", $trail = "", $prefix = "" )
1482 global $wgOut, $wgUser;
1483 if ( $nt->isExternal() ) {
1484 $u = $nt->getFullURL();
1485 $link = $nt->getPrefixedURL();
1486 if ( "" == $text ) { $text = $nt->getPrefixedText(); }
1487 $style = $this->getExternalLinkAttributes( $link, $text, 'extiw' );
1490 if ( "" != $trail ) {
1491 if ( preg_match( "/^([a-z]+)(.*)$$/sD", $trail, $m ) ) {
1496 $retVal = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1497 } elseif ( 0 == $nt->getNamespace() && "" == $nt->getText() ) {
1498 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1499 } elseif ( ( -1 == $nt->getNamespace() ) ||
1500 ( Namespace::getImage() == $nt->getNamespace() ) ) {
1501 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1503 $aid = $nt->getArticleID() ;
1505 $retVal = $this->makeBrokenLinkObj( $nt, $text, $query, $trail, $prefix );
1507 $threshold = $wgUser->getOption("stubthreshold") ;
1508 if ( $threshold > 0 ) {
1509 $res = wfQuery ( "SELECT LENGTH(cur_text) AS x, cur_namespace, cur_is_redirect FROM cur WHERE cur_id='{$aid}'", DB_READ
) ;
1511 if ( wfNumRows( $res ) > 0 ) {
1512 $s = wfFetchObject( $res );
1514 if ( $s->cur_is_redirect
OR $s->cur_namespace
!= 0 ) {
1515 $size = $threshold*2 ; # Really big
1517 wfFreeResult( $res );
1519 $size = $threshold*2 ; # Really big
1524 if ( $size < $threshold ) {
1525 $retVal = $this->makeStubLinkObj( $nt, $text, $query, $trail, $prefix );
1527 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1534 # Pass a title object, not a title string
1535 function makeKnownLinkObj( &$nt, $text = "", $query = "", $trail = "", $prefix = "" , $aprops = '')
1537 global $wgOut, $wgTitle;
1539 $fname = "Skin::makeKnownLinkObj";
1540 wfProfileIn( $fname );
1542 $link = $nt->getPrefixedURL();
1544 if ( "" == $link ) {
1546 if ( "" == $text ) {
1547 $text = htmlspecialchars( $nt->getFragment() );
1550 $u = $nt->escapeLocalURL( $query );
1552 if ( "" != $nt->getFragment() ) {
1553 $u .= "#" . htmlspecialchars( $nt->getFragment() );
1555 if ( "" == $text ) {
1556 $text = htmlspecialchars( $nt->getPrefixedText() );
1558 $style = $this->getInternalLinkAttributesObj( $nt, $text );
1561 if ( "" != $trail ) {
1562 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1567 $r = "<a href=\"{$u}\"{$style}{$aprops}>{$prefix}{$text}{$inside}</a>{$trail}";
1568 wfProfileOut( $fname );
1572 # Pass a title object, not a title string
1573 function makeBrokenLinkObj( &$nt, $text = "", $query = "", $trail = "", $prefix = "" )
1575 global $wgOut, $wgUser;
1577 $fname = "Skin::makeBrokenLinkObj";
1578 wfProfileIn( $fname );
1580 if ( "" == $query ) {
1583 $q = "action=edit&{$query}";
1585 $u = $nt->escapeLocalURL( $q );
1587 if ( "" == $text ) {
1588 $text = htmlspecialchars( $nt->getPrefixedText() );
1590 $style = $this->getInternalLinkAttributesObj( $nt, $text, "yes" );
1593 if ( "" != $trail ) {
1594 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1599 if ( $wgUser->getOption( "highlightbroken" ) ) {
1600 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1602 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>?</a>{$trail}";
1605 wfProfileOut( $fname );
1609 # Pass a title object, not a title string
1610 function makeStubLinkObj( &$nt, $text = "", $query = "", $trail = "", $prefix = "" )
1612 global $wgOut, $wgUser;
1614 $link = $nt->getPrefixedURL();
1616 $u = $nt->escapeLocalURL( $query );
1618 if ( "" == $text ) {
1619 $text = htmlspecialchars( $nt->getPrefixedText() );
1621 $style = $this->getInternalLinkAttributesObj( $nt, $text, "stub" );
1624 if ( "" != $trail ) {
1625 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1630 if ( $wgUser->getOption( "highlightbroken" ) ) {
1631 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1633 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>!</a>{$trail}";
1638 function makeSelfLinkObj( &$nt, $text = "", $query = "", $trail = "", $prefix = "" )
1640 $u = $nt->escapeLocalURL( $query );
1641 if ( "" == $text ) {
1642 $text = htmlspecialchars( $nt->getPrefixedText() );
1645 if ( "" != $trail ) {
1646 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1651 return "<strong>{$prefix}{$text}{$inside}</strong>{$trail}";
1654 /* these are used extensively in SkinPHPTal, but also some other places */
1655 /*static*/ function makeSpecialUrl( $name, $urlaction='' ) {
1656 $title = Title
::makeTitle( NS_SPECIAL
, $name );
1657 $this->checkTitle($title, $name);
1658 return $title->getLocalURL( $urlaction );
1660 /*static*/ function makeTalkUrl ( $name, $urlaction='' ) {
1661 $title = Title
::newFromText( $name );
1662 $title = $title->getTalkPage();
1663 $this->checkTitle($title, $name);
1664 return $title->getLocalURL( $urlaction );
1666 /*static*/ function makeArticleUrl ( $name, $urlaction='' ) {
1667 $title = Title
::newFromText( $name );
1668 $title= $title->getSubjectPage();
1669 $this->checkTitle($title, $name);
1670 return $title->getLocalURL( $urlaction );
1672 /*static*/ function makeI18nUrl ( $name, $urlaction='' ) {
1673 $title = Title
::newFromText( wfMsg($name) );
1674 $this->checkTitle($title, $name);
1675 return $title->getLocalURL( $urlaction );
1677 /*static*/ function makeUrl ( $name, $urlaction='' ) {
1678 $title = Title
::newFromText( $name );
1679 $this->checkTitle($title, $name);
1680 return $title->getLocalURL( $urlaction );
1682 # this can be passed the NS number as defined in Language.php
1683 /*static*/ function makeNSUrl( $name, $urlaction='', $namespace=0 ) {
1684 $title = Title
::makeTitle( $namespace, $name );
1685 $this->checkTitle($title, $name);
1686 return $title->getLocalURL( $urlaction );
1689 /* these return an array with the 'href' and boolean 'exists' */
1690 /*static*/ function makeUrlDetails ( $name, $urlaction='' ) {
1691 $title = Title
::newFromText( $name );
1692 $this->checkTitle($title, $name);
1694 'href' => $title->getLocalURL( $urlaction ),
1695 'exists' => $title->getArticleID() != 0?
true:false
1698 /*static*/ function makeTalkUrlDetails ( $name, $urlaction='' ) {
1699 $title = Title
::newFromText( $name );
1700 $title = $title->getTalkPage();
1701 $this->checkTitle($title, $name);
1703 'href' => $title->getLocalURL( $urlaction ),
1704 'exists' => $title->getArticleID() != 0?
true:false
1707 /*static*/ function makeArticleUrlDetails ( $name, $urlaction='' ) {
1708 $title = Title
::newFromText( $name );
1709 $title= $title->getSubjectPage();
1710 $this->checkTitle($title, $name);
1712 'href' => $title->getLocalURL( $urlaction ),
1713 'exists' => $title->getArticleID() != 0?
true:false
1716 /*static*/ function makeI18nUrlDetails ( $name, $urlaction='' ) {
1717 $title = Title
::newFromText( wfMsg($name) );
1718 $this->checkTitle($title, $name);
1720 'href' => $title->getLocalURL( $urlaction ),
1721 'exists' => $title->getArticleID() != 0?
true:false
1725 # make sure we have some title to operate on
1726 /*static*/ function checkTitle ( &$title, &$name ) {
1727 if(!is_object($title)) {
1728 $title = Title
::newFromText( $name );
1729 if(!is_object($title)) {
1730 $title = Title
::newFromText( '<error: link target missing>' );
1735 function fnamePart( $url )
1737 $basename = strrchr( $url, "/" );
1738 if ( false === $basename ) { $basename = $url; }
1739 else { $basename = substr( $basename, 1 ); }
1740 return wfEscapeHTML( $basename );
1743 function makeImage( $url, $alt = "" )
1747 if ( "" == $alt ) { $alt = $this->fnamePart( $url ); }
1748 $s = "<img src=\"{$url}\" alt=\"{$alt}\" />";
1752 function makeImageLink( $name, $url, $alt = "" ) {
1753 $nt = Title
::makeTitle( Namespace::getImage(), $name );
1754 return $this->makeImageLinkObj( $nt, $alt );
1757 function makeImageLinkObj( $nt, $alt = "" ) {
1758 global $wgLang, $wgUseImageResize;
1759 $img = Image
::newFromTitle( $nt );
1760 $url = $img->getURL();
1763 $prefix = $postfix = "";
1765 if ( $wgUseImageResize ) {
1766 # Check if the alt text is of the form "options|alt text"
1768 # * thumbnail make a thumbnail with enlarge-icon and caption, alignment depends on lang
1769 # * left no resizing, just left align. label is used for alt= only
1770 # * right same, but right aligned
1771 # * none same, but not aligned
1772 # * ___px scale to ___ pixels width, no aligning. e.g. use in taxobox
1773 # * center center the image
1774 # * framed Keep original image size, no magnify-button.
1776 $part = explode( "|", $alt);
1778 $mwThumb =& MagicWord
::get( MAG_IMG_THUMBNAIL
);
1779 $mwLeft =& MagicWord
::get( MAG_IMG_LEFT
);
1780 $mwRight =& MagicWord
::get( MAG_IMG_RIGHT
);
1781 $mwNone =& MagicWord
::get( MAG_IMG_NONE
);
1782 $mwWidth =& MagicWord
::get( MAG_IMG_WIDTH
);
1783 $mwCenter =& MagicWord
::get( MAG_IMG_CENTER
);
1784 $mwFramed =& MagicWord
::get( MAG_IMG_FRAMED
);
1785 $alt = $part[count($part)-1];
1787 $height = $framed = $thumb = false;
1789 foreach( $part as $key => $val ) {
1790 if ( ! is_null( $mwThumb->matchVariableStartToEnd($val) ) ) {
1792 } elseif ( ! is_null( $mwRight->matchVariableStartToEnd($val) ) ) {
1793 # remember to set an alignment, don't render immediately
1795 } elseif ( ! is_null( $mwLeft->matchVariableStartToEnd($val) ) ) {
1796 # remember to set an alignment, don't render immediately
1798 } elseif ( ! is_null( $mwCenter->matchVariableStartToEnd($val) ) ) {
1799 # remember to set an alignment, don't render immediately
1801 } elseif ( ! is_null( $mwNone->matchVariableStartToEnd($val) ) ) {
1802 # remember to set an alignment, don't render immediately
1804 } elseif ( ! is_null( $match = $mwWidth->matchVariableStartToEnd($val) ) ) {
1805 # $match is the image width in pixels
1806 if ( preg_match( "/^([0-9]*)x([0-9]*)$/", $match, $m ) ) {
1807 $width = intval( $m[1] );
1808 $height = intval( $m[2] );
1810 $width = intval($match);
1812 } elseif ( ! is_null( $mwFramed->matchVariableStartToEnd($val) ) ) {
1816 if ( "center" == $align )
1818 $prefix = '<span style="text-align: center">';
1819 $postfix = '</span>';
1823 if ( $thumb ||
$framed ) {
1825 # Create a thumbnail. Alignment depends on language
1826 # writing direction, # right aligned for left-to-right-
1827 # languages ("Western languages"), left-aligned
1828 # for right-to-left-languages ("Semitic languages")
1830 # If thumbnail width has not been provided, it is set
1831 # here to 180 pixels
1832 if ( $align == "" ) {
1833 $align = $wgLang->isRTL() ?
"left" : "right";
1835 if ( ! isset($width) ) {
1838 return $prefix.$this->makeThumbLinkObj( $img, $alt, $align, $width, $height, $framed ).$postfix;
1840 } elseif ( isset($width) ) {
1842 # Create a resized image, without the additional thumbnail
1845 if ( ( ! $height === false )
1846 && ( $img->getHeight() * $width / $img->getWidth() > $height ) ) {
1847 print "height=$height<br>\nimg->getHeight() = ".$img->getHeight()."<br>\n";
1848 print "rescaling by factor ". $height / $img->getHeight() . "<br>\n";
1849 $width = $img->getWidth() * $height / $img->getHeight();
1851 $url = $img->createThumb( $width );
1853 } # endif $wgUseImageResize
1855 if ( empty( $alt ) ) {
1856 $alt = preg_replace( '/\.(.+?)^/', '', $img->getName() );
1858 $alt = htmlspecialchars( $alt );
1860 $u = $nt->escapeLocalURL();
1863 $s = str_replace( "$1", $img->getName(), wfMsg("missingimage") );
1864 $s .= "<br>{$alt}<br>{$url}<br>\n";
1866 $s = "<a href=\"{$u}\" class='image' title=\"{$alt}\">" .
1867 "<img src=\"{$url}\" alt=\"{$alt}\" /></a>";
1869 if ( "" != $align ) {
1870 $s = "<div class=\"float{$align}\"><span>{$s}</span></div>";
1872 return str_replace("\n", ' ',$prefix.$s.$postfix);
1876 function makeThumbLinkObj( $img, $label = "", $align = "right", $boxwidth = 180, $boxheight=false, $framed=false ) {
1877 global $wgStylePath, $wgLang;
1878 # $image = Title::makeTitle( Namespace::getImage(), $name );
1879 $url = $img->getURL();
1881 #$label = htmlspecialchars( $label );
1882 $alt = preg_replace( "/<[^>]*>/", "", $label);
1883 $alt = htmlspecialchars( $alt );
1885 if ( $img->exists() )
1887 $width = $img->getWidth();
1888 $height = $img->getHeight();
1890 $width = $height = 200;
1894 // Use image dimensions, don't scale
1896 $oboxwidth = $boxwidth +
2;
1897 $boxheight = $height;
1900 $h = intval( $height/($width/$boxwidth) );
1901 $oboxwidth = $boxwidth +
2;
1902 if ( ( ! $boxheight === false ) && ( $h > $boxheight ) )
1904 $boxwidth *= $boxheight/$h;
1908 $thumbUrl = $img->createThumb( $boxwidth );
1911 $u = $img->getEscapeLocalURL();
1913 $more = htmlspecialchars( wfMsg( "thumbnail-more" ) );
1914 $magnifyalign = $wgLang->isRTL() ?
"left" : "right";
1915 $textalign = $wgLang->isRTL() ?
' style="text-align:right"' : "";
1917 $s = "<div class=\"thumb t{$align}\"><div style=\"width:{$oboxwidth}px;\">";
1918 if ( $thumbUrl == "" ) {
1919 $s .= str_replace( "$1", $img->getName(), wfMsg("missingimage") );
1922 $s .= '<a href="'.$u.'" class="internal" title="'.$alt.'">'.
1923 '<img src="'.$thumbUrl.'" alt="'.$alt.'" ' .
1924 'width="'.$boxwidth.'" height="'.$boxheight.'" /></a>';
1928 $zoomicon = '<div class="magnify" style="float:'.$magnifyalign.'">'.
1929 '<a href="'.$u.'" class="internal" title="'.$more.'">'.
1930 '<img src="'.$wgStylePath.'/images/magnify-clip.png" ' .
1931 'width="15" height="11" alt="'.$more.'" /></a></div>';
1934 $s .= ' <div class="thumbcaption" '.$textalign.'>'.$zoomicon.$label."</div></div></div>";
1935 return str_replace("\n", ' ', $s);
1938 function makeMediaLink( $name, $url, $alt = "" ) {
1939 $nt = Title
::makeTitle( Namespace::getMedia(), $name );
1940 return $this->makeMediaLinkObj( $nt, $alt );
1943 function makeMediaLinkObj( $nt, $alt = "" )
1945 if ( ! isset( $nt ) )
1947 ### HOTFIX. Instead of breaking, return empry string.
1950 $name = $nt->getDBKey();
1951 $url = Image
::wfImageUrl( $name );
1952 if ( empty( $alt ) ) {
1953 $alt = preg_replace( '/\.(.+?)^/', '', $name );
1956 $u = htmlspecialchars( $url );
1957 $s = "<a href=\"{$u}\" class='internal' title=\"{$alt}\">{$alt}</a>";
1962 function specialLink( $name, $key = "" )
1966 if ( "" == $key ) { $key = strtolower( $name ); }
1967 $pn = $wgLang->ucfirst( $name );
1968 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1972 function makeExternalLink( $url, $text, $escape = true ) {
1973 $style = $this->getExternalLinkAttributes( $url, $text );
1974 $url = htmlspecialchars( $url );
1976 $text = htmlspecialchars( $text );
1978 return "<a href=\"$url\"$style>$text</a>";
1981 # Called by history lists and recent changes
1984 # Returns text for the start of the tabular part of RC
1985 function beginRecentChangesList()
1987 $this->rc_cache
= array() ;
1988 $this->rcMoveIndex
= 0;
1989 $this->rcCacheIndex
= 0 ;
1990 $this->lastdate
= "";
1991 $this->rclistOpen
= false;
1995 function beginImageHistoryList()
1997 $s = "\n<h2>" . wfMsg( "imghistory" ) . "</h2>\n" .
1998 "<p>" . wfMsg( "imghistlegend" ) . "</p>\n<ul class='special'>";
2002 # Returns text for the end of RC
2003 # If enhanced RC is in use, returns pretty much all the text
2004 function endRecentChangesList()
2006 $s = $this->recentChangesBlock() ;
2007 if( $this->rclistOpen
) {
2013 # Enhanced RC ungrouped line
2014 function recentChangesBlockLine ( $rcObj )
2016 global $wgStylePath, $wgLang ;
2018 # Get rc_xxxx variables
2019 extract( $rcObj->mAttribs
) ;
2020 $curIdEq = "curid=$rc_cur_id";
2025 $r .= "<img src='{$wgStylePath}/images/Arr_.png' width='12' height='12' border='0' />" ; $r .= "<tt>" ;
2027 if ( $rc_type == RC_MOVE
) {
2028 $r .= " ";
2030 # M & N (minor & new)
2031 $M = wfMsg( "minoreditletter" );
2032 $N = wfMsg( "newpageletter" );
2034 if ( $rc_type == RC_NEW
) {
2047 $r .= " ".$rcObj->timestamp
." " ;
2051 $link = $rcObj->link
;
2052 if ( $rcObj->watched
) $link = "<strong>{$link}</strong>" ;
2057 $r .= $rcObj->curlink
;
2061 $r .= $this->makeKnownLinkObj( $rcObj->getTitle(), wfMsg( "hist" ), "{$curIdEq}&action=history" );
2064 $r .= ") . . ".$rcObj->userlink
;
2065 $r .= $rcObj->usertalklink
;
2068 if ( $rc_comment != "" && $rc_type != RC_MOVE
) {
2069 $rc_comment=$this->formatComment($rc_comment);
2070 $r .= $wgLang->emphasize( " (".$rc_comment.")" );
2078 function recentChangesBlockGroup ( $block )
2080 global $wgStylePath, $wgLang ;
2083 $M = wfMsg( "minoreditletter" );
2084 $N = wfMsg( "newpageletter" );
2086 # Collate list of users
2088 $userlinks = array () ;
2089 foreach ( $block AS $rcObj ) {
2090 $oldid = $rcObj->mAttribs
['rc_last_oldid'];
2091 if ( $rcObj->mAttribs
['rc_new'] ) $isnew = true ;
2092 $u = $rcObj->userlink
;
2093 if ( !isset ( $userlinks[$u] ) ) $userlinks[$u] = 0 ;
2097 # Sort the list and convert to text
2098 krsort ( $userlinks ) ;
2099 asort ( $userlinks ) ;
2101 foreach ( $userlinks as $userlink => $count) {
2103 if ( $count > 1 ) $text .= " ({$count}×)" ;
2104 array_push ( $users , $text ) ;
2106 $users = " <font size='-1'>[".implode("; ",$users)."]</font>" ;
2109 $rci = "RCI{$this->rcCacheIndex}" ;
2110 $rcl = "RCL{$this->rcCacheIndex}" ;
2111 $rcm = "RCM{$this->rcCacheIndex}" ;
2112 $toggleLink = "javascript:toggleVisibility(\"{$rci}\",\"{$rcm}\",\"{$rcl}\")" ;
2113 $arrowdir = $wgLang->isRTL() ?
"l" : "r";
2114 $tl = "<span id='{$rcm}'><a href='$toggleLink'><img src='{$wgStylePath}/images/Arr_{$arrowdir}.png' width='12' height='12' /></a></span>" ;
2115 $tl .= "<span id='{$rcl}' style='display:none'><a href='$toggleLink'><img src='{$wgStylePath}/images/Arr_d.png' width='12' height='12' /></a></span>" ;
2121 if ( $isnew ) $r .= $N ;
2122 else $r .= " " ;
2123 $r .= " " ; # Minor
2126 $r .= " ".$block[0]->timestamp
." " ;
2130 $link = $block[0]->link
;
2131 if ( $block[0]->watched
) $link = "<strong>{$link}</strong>" ;
2134 $curIdEq = "curid=" . $block[0]->mAttribs
['rc_cur_id'];
2135 if ( $block[0]->mAttribs
['rc_type'] != RC_LOG
) {
2137 $r .= " (".count($block)." " ;
2138 if ( $isnew ) $r .= wfMsg("changes");
2139 else $r .= $this->makeKnownLinkObj( $block[0]->getTitle() , wfMsg("changes") ,
2140 "{$curIdEq}&diff=0&oldid=".$oldid ) ;
2144 $r .= $this->makeKnownLinkObj( $block[0]->getTitle(), wfMsg( "history" ), "{$curIdEq}&action=history" );
2152 $r .= "<div id='{$rci}' style='display:none'>" ;
2153 foreach ( $block AS $rcObj ) {
2154 # Get rc_xxxx variables
2155 extract( $rcObj->mAttribs
);
2157 $r .= "<img src='{$wgStylePath}/images/Arr_.png' width=12 height=12 />";
2158 $r .= "<tt> " ;
2159 if ( $rc_new ) $r .= $N ;
2160 else $r .= " " ;
2161 if ( $rc_minor ) $r .= $M ;
2162 else $r .= " " ;
2166 if ( $rc_last_oldid != 0 ) {
2167 $o = "oldid=".$rc_last_oldid ;
2169 if ( $rc_type == RC_LOG
) {
2170 $link = $rcObj->timestamp
;
2172 $link = $this->makeKnownLinkObj( $rcObj->getTitle(), $rcObj->timestamp
, "{$curIdEq}&$o" ) ;
2174 $link = "<tt>{$link}</tt>" ;
2178 $r .= $rcObj->curlink
;
2180 $r .= $rcObj->lastlink
;
2181 $r .= ") . . ".$rcObj->userlink
;
2182 $r .= $rcObj->usertalklink
;
2183 if ( $rc_comment != "" ) {
2184 $rc_comment=$this->formatComment($rc_comment);
2185 $r .= $wgLang->emphasize( " (".$rc_comment.")" ) ;
2191 $this->rcCacheIndex++
;
2195 # If enhanced RC is in use, this function takes the previously cached
2196 # RC lines, arranges them, and outputs the HTML
2197 function recentChangesBlock ()
2199 global $wgStylePath ;
2200 if ( count ( $this->rc_cache
) == 0 ) return "" ;
2202 foreach ( $this->rc_cache
AS $secureName => $block ) {
2203 if ( count ( $block ) < 2 ) {
2204 $blockOut .= $this->recentChangesBlockLine ( array_shift ( $block ) ) ;
2206 $blockOut .= $this->recentChangesBlockGroup ( $block ) ;
2210 return "<div>{$blockOut}</div>" ;
2213 # Called in a loop over all displayed RC entries
2214 # Either returns the line, or caches it for later use
2215 function recentChangesLine( &$rc, $watched = false )
2218 $usenew = $wgUser->getOption( "usenewrc" );
2220 $line = $this->recentChangesLineNew ( $rc, $watched ) ;
2222 $line = $this->recentChangesLineOld ( $rc, $watched ) ;
2226 function recentChangesLineOld( &$rc, $watched = false )
2228 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds;
2230 # Extract DB fields into local scope
2231 extract( $rc->mAttribs
);
2232 $curIdEq = "curid=" . $rc_cur_id;
2234 # Make date header if necessary
2235 $date = $wgLang->date( $rc_timestamp, true);
2237 if ( $date != $this->lastdate
) {
2238 if ( "" != $this->lastdate
) { $s .= "</ul>\n"; }
2239 $s .= "<h4>{$date}</h4>\n<ul class='special'>";
2240 $this->lastdate
= $date;
2241 $this->rclistOpen
= true;
2245 if ( $rc_type == RC_MOVE
) {
2247 $s .= "(" . wfMsg( "diff" ) . ") (";
2249 $s .= $this->makeKnownLinkObj( $rc->getMovedToTitle(), wfMsg( "hist" ), "action=history" ) .
2252 # "[[x]] moved to [[y]]"
2254 $s .= wfMsg( "1movedto2", $this->makeKnownLinkObj( $rc->getTitle(), "", "redirect=no" ),
2255 $this->makeKnownLinkObj( $rc->getMovedToTitle(), "" ) );
2259 if ( $rc_type == RC_NEW ||
$rc_type == RC_LOG
) {
2260 $diffLink = wfMsg( "diff" );
2262 $diffLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( "diff" ),
2263 "{$curIdEq}&diff={$rc_this_oldid}&oldid={$rc_last_oldid}" ,'' ,'' , ' tabindex="'.$rc->counter
.'"');
2265 $s .= "($diffLink) (";
2268 $s .= $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( "hist" ), "{$curIdEq}&action=history" );
2271 # M and N (minor and new)
2272 $M = wfMsg( "minoreditletter" );
2273 $N = wfMsg( "newpageletter" );
2274 if ( $rc_minor ) { $s .= " <strong>{$M}</strong>"; }
2275 if ( $rc_type == RC_NEW
) { $s .= "<strong>{$N}</strong>"; }
2278 $articleLink = $this->makeKnownLinkObj( $rc->getTitle(), "" );
2281 $articleLink = "<strong>{$articleLink}</strong>";
2283 $s .= " $articleLink";
2288 $s .= "; " . $wgLang->time( $rc_timestamp, true, $wgRCSeconds ) . " . . ";
2290 # User link (or contributions for unregistered users)
2291 if ( 0 == $rc_user ) {
2292 $userLink = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
2293 $rc_user_text, "target=" . $rc_user_text );
2295 $userLink = $this->makeLink( $wgLang->getNsText( NS_USER
) . ":{$rc_user_text}", $rc_user_text );
2300 $talkname=$wgLang->getNsText(NS_TALK
); # use the shorter name
2301 global $wgDisableAnonTalk;
2302 if( 0 == $rc_user && $wgDisableAnonTalk ) {
2305 $utns=$wgLang->getNsText(NS_USER_TALK
);
2306 $userTalkLink= $this->makeLink($utns . ":{$rc_user_text}", $talkname );
2310 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2311 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2312 "Blockip" ), wfMsg( "blocklink" ), "ip={$rc_user_text}" );
2316 if($userTalkLink) $userTalkLink .= " | ";
2317 $userTalkLink .= $blockLink;
2319 if($userTalkLink) $s.=" ({$userTalkLink})";
2322 if ( "" != $rc_comment && "*" != $rc_comment && $rc_type != RC_MOVE
) {
2323 $rc_comment=$this->formatComment($rc_comment);
2324 $s .= $wgLang->emphasize(" (" . $rc_comment . ")");
2331 # function recentChangesLineNew( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched = false, $oldid = 0 , $diffid = 0 )
2332 function recentChangesLineNew( &$baseRC, $watched = false )
2334 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds;
2336 # Create a specialised object
2337 $rc = RCCacheEntry
::newFromParent( $baseRC ) ;
2339 # Extract fields from DB into the function scope (rc_xxxx variables)
2340 extract( $rc->mAttribs
);
2341 $curIdEq = "curid=" . $rc_cur_id;
2343 # If it's a new day, add the headline and flush the cache
2344 $date = $wgLang->date( $rc_timestamp, true);
2346 if ( $date != $this->lastdate
) {
2347 # Process current cache
2348 $ret = $this->recentChangesBlock () ;
2349 $this->rc_cache
= array() ;
2350 $ret .= "<h4>{$date}</h4>\n";
2351 $this->lastdate
= $date;
2355 if ( $rc_type == RC_MOVE
) {
2356 $clink = $this->makeKnownLinkObj( $rc->getTitle(), "", "redirect=no" );
2357 $clink .= " " . wfMsg("movedto") . " ";
2358 $clink .= $this->makeKnownLinkObj( $rc->getMovedToTitle(), "" );
2360 $clink = $this->makeKnownLinkObj( $rc->getTitle(), "" ) ;
2363 $time = $wgLang->time( $rc_timestamp, true, $wgRCSeconds );
2364 $rc->watched
= $watched ;
2365 $rc->link
= $clink ;
2366 $rc->timestamp
= $time;
2369 if ( ( $rc_type == RC_NEW
&& $rc_this_oldid == 0 ) ||
$rc_type == RC_LOG ||
$rc_type == RC_MOVE
) {
2370 $curLink = wfMsg( "cur" );
2372 $curLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( "cur" ),
2373 "{$curIdEq}&diff=0&oldid={$rc_this_oldid}" ,'' ,'' , ' tabindex="'.$baseRC->counter
.'"' );
2377 $titleObj = $rc->getTitle();
2378 if ( $rc_last_oldid == 0 ||
$rc_type == RC_LOG ||
$rc_type == RC_MOVE
) {
2379 $lastLink = wfMsg( "last" );
2381 $lastLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( "last" ),
2382 "{$curIdEq}&diff={$rc_this_oldid}&oldid={$rc_last_oldid}" );
2385 # Make user link (or user contributions for unregistered users)
2386 if ( 0 == $rc_user ) {
2387 $userLink = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
2388 $rc_user_text, "target=" . $rc_user_text );
2390 $userLink = $this->makeLink( $wgLang->getNsText(
2391 Namespace::getUser() ) . ":{$rc_user_text}", $rc_user_text );
2394 $rc->userlink
= $userLink ;
2395 $rc->lastlink
= $lastLink ;
2396 $rc->curlink
= $curLink ;
2398 # Make user talk link
2399 $utns=$wgLang->getNsText(NS_USER_TALK
);
2400 $talkname=$wgLang->getNsText(NS_TALK
); # use the shorter name
2401 $userTalkLink= $this->makeLink($utns . ":{$rc_user_text}", $talkname );
2403 global $wgDisableAnonTalk;
2404 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2405 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2406 "Blockip" ), wfMsg( "blocklink" ), "ip={$rc_user_text}" );
2407 if( $wgDisableAnonTalk )
2408 $rc->usertalklink
= " ({$blockLink})";
2410 $rc->usertalklink
= " ({$userTalkLink} | {$blockLink})";
2412 if( $wgDisableAnonTalk && ($rc_user == 0) )
2413 $rc->usertalklink
= "";
2415 $rc->usertalklink
= " ({$userTalkLink})";
2418 # Put accumulated information into the cache, for later display
2419 # Page moves go on their own line
2420 $title = $rc->getTitle();
2421 $secureName = $title->getPrefixedDBkey();
2422 if ( $rc_type == RC_MOVE
) {
2423 # Use an @ character to prevent collision with page names
2424 $this->rc_cache
["@@" . ($this->rcMoveIndex++
)] = array($rc);
2426 if ( !isset ( $this->rc_cache
[$secureName] ) ) $this->rc_cache
[$secureName] = array() ;
2427 array_push ( $this->rc_cache
[$secureName] , $rc ) ;
2432 function endImageHistoryList()
2438 /* This function is called by all recent changes variants, by the page history,
2439 and by the user contributions list. It is responsible for formatting edit
2440 comments. It escapes any HTML in the comment, but adds some CSS to format
2441 auto-generated comments (from section editing) and formats [[wikilinks]].
2442 Main author: Erik Möller (moeller@scireview.de)
2444 function formatComment($comment)
2447 $comment=wfEscapeHTML($comment);
2449 # The pattern for autogen comments is / * foo * /, which makes for
2451 # We look for all comments, match any text before and after the comment,
2452 # add a separator where needed and format the comment itself with CSS
2453 while (preg_match("/(.*)\/\*\s*(.*?)\s*\*\/(.*)/", $comment,$match)) {
2458 if($pre) { $auto="$sep ".$auto; }
2459 if($post) { $auto.=" $sep"; }
2460 $auto="<span class=\"autocomment\">".$auto."</span>";
2461 $comment=$pre.$auto.$post;
2464 # format regular and media links - all other wiki formatting
2466 while(preg_match("/\[\[(.*?)(\|(.*?))*\]\]/",$comment,$match)) {
2468 $medians = $wgLang->getNsText(Namespace::getMedia());
2470 if(preg_match("/^".$medians."/i",$match[1])) {
2471 $func="makeMediaLink";
2473 if(isset($match[3]) ) {
2475 preg_replace("/\[\[(.*?)\]\]/",
2476 $this->$func($match[1],$match[3]),$comment,1);
2479 preg_replace("/\[\[(.*?)\]\]/",
2480 $this->$func($match[1],$match[1]),$comment,1);
2488 function imageHistoryLine( $iscur, $timestamp, $img, $user, $usertext, $size, $description )
2490 global $wgUser, $wgLang, $wgTitle;
2492 $datetime = $wgLang->timeanddate( $timestamp, true );
2493 $del = wfMsg( "deleteimg" );
2494 $cur = wfMsg( "cur" );
2497 $url = Image
::wfImageUrl( $img );
2499 if ( $wgUser->isSysop() ) {
2500 $link = $wgTitle->escapeLocalURL( "image=" . $wgTitle->getPartialURL() .
2502 $style = $this->getInternalLinkAttributes( $link, $del );
2504 $dlink = "<a href=\"{$link}\"{$style}>{$del}</a>";
2509 $url = wfEscapeHTML( wfImageArchiveUrl( $img ) );
2510 if( $wgUser->getID() != 0 ) {
2511 $rlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2512 wfMsg( "revertimg" ), "action=revert&oldimage=" .
2513 urlencode( $img ) );
2514 $dlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2515 $del, "action=delete&oldimage=" . urlencode( $img ) );
2517 # Having live active links for non-logged in users
2518 # means that bots and spiders crawling our site can
2519 # inadvertently change content. Baaaad idea.
2520 $rlink = wfMsg( "revertimg" );
2525 $userlink = $usertext;
2527 $userlink = $this->makeLink( $wgLang->getNsText( Namespace::getUser() ) .
2528 ":{$usertext}", $usertext );
2530 $nbytes = wfMsg( "nbytes", $size );
2531 $style = $this->getInternalLinkAttributes( $url, $datetime );
2533 $s = "<li> ({$dlink}) ({$rlink}) <a href=\"{$url}\"{$style}>{$datetime}</a>"
2534 . " . . {$userlink} ({$nbytes})";
2536 if ( "" != $description && "*" != $description ) {
2537 $sk=$wgUser->getSkin();
2538 $s .= $wgLang->emphasize(" (" . $sk->formatComment($description) . ")");
2544 function tocIndent($level) {
2545 return str_repeat( "<div class='tocindent'>\n", $level>0 ?
$level : 0 );
2548 function tocUnindent($level) {
2549 return str_repeat( "</div>\n", $level>0 ?
$level : 0 );
2552 # parameter level defines if we are on an indentation level
2553 function tocLine( $anchor, $tocline, $level ) {
2554 $link = "<a href=\"#$anchor\">$tocline</a><br />";
2558 return "<div class='tocline'>$link</div>\n";
2563 function tocTable($toc) {
2564 # note to CSS fanatics: putting this in a div does not work -- div won't auto-expand
2565 # try min-width & co when somebody gets a chance
2566 $hideline = " <script type='text/javascript'>showTocToggle(\"" . addslashes( wfMsg("showtoc") ) . "\",\"" . addslashes( wfMsg("hidetoc") ) . "\")</script>";
2568 "<table border=\"0\" id=\"toc\"><tr><td align=\"center\">\n".
2569 "<b>".wfMsg("toc")."</b>" .
2571 "</td></tr><tr id='tocinside'><td>\n".
2572 $toc."</td></tr></table>\n";
2575 # These two do not check for permissions: check $wgTitle->userCanEdit before calling them
2576 function editSectionScript( $section, $head ) {
2577 global $wgTitle, $wgRequest;
2578 if( $wgRequest->getInt( "oldid" ) && ( $wgRequest->getVal( "diff" ) != "0" ) ) {
2581 $url = $wgTitle->escapeLocalURL( "action=edit§ion=$section" );
2582 return "<span oncontextmenu='document.location=\"$url\";return false;'>{$head}</span>";
2585 function editSectionLink( $section ) {
2587 global $wgTitle, $wgUser, $wgLang;
2589 if( $wgRequest->getInt( "oldid" ) && ( $wgRequest->getVal( "diff" ) != "0" ) ) {
2590 # Section edit links would be out of sync on an old page.
2591 # But, if we're diffing to the current page, they'll be
2596 $editurl = "§ion={$section}";
2597 $url = $this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg("editsection"),"action=edit".$editurl);
2599 if( $wgLang->isRTL() ) {
2601 $nearside = "right";
2606 return "<div class=\"editsection\" style=\"float:$farside;margin-$nearside:5px;\">[".$url."]</div>";
2610 // This function is called by EditPage.php and shows a bulletin board style
2611 // toolbar for common editing functions. It can be disabled in the user preferences.
2612 // The necsesary JavaScript code can be found in style/wikibits.js.
2613 function getEditToolbar() {
2614 global $wgStylePath, $wgLang, $wgMimeType;
2616 // toolarray an array of arrays which each include the filename of
2617 // the button image (without path), the opening tag, the closing tag,
2618 // and optionally a sample text that is inserted between the two when no
2619 // selection is highlighted.
2620 // The tip text is shown when the user moves the mouse over the button.
2622 // Already here are accesskeys (key), which are not used yet until someone
2623 // can figure out a way to make them work in IE. However, we should make
2624 // sure these keys are not defined on the edit page.
2626 array( "image"=>"button_bold.png",
2629 "sample"=>wfMsg("bold_sample"),
2630 "tip"=>wfMsg("bold_tip"),
2633 array( "image"=>"button_italic.png",
2636 "sample"=>wfMsg("italic_sample"),
2637 "tip"=>wfMsg("italic_tip"),
2640 array( "image"=>"button_link.png",
2643 "sample"=>wfMsg("link_sample"),
2644 "tip"=>wfMsg("link_tip"),
2647 array( "image"=>"button_extlink.png",
2650 "sample"=>wfMsg("extlink_sample"),
2651 "tip"=>wfMsg("extlink_tip"),
2654 array( "image"=>"button_headline.png",
2657 "sample"=>wfMsg("headline_sample"),
2658 "tip"=>wfMsg("headline_tip"),
2661 array( "image"=>"button_image.png",
2662 "open"=>"[[".$wgLang->getNsText(NS_IMAGE
).":",
2664 "sample"=>wfMsg("image_sample"),
2665 "tip"=>wfMsg("image_tip"),
2668 array( "image"=>"button_media.png",
2669 "open"=>"[[".$wgLang->getNsText(NS_MEDIA
).":",
2671 "sample"=>wfMsg("media_sample"),
2672 "tip"=>wfMsg("media_tip"),
2675 array( "image"=>"button_math.png",
2676 "open"=>"\\<math\\>",
2677 "close"=>"\\</math\\>",
2678 "sample"=>wfMsg("math_sample"),
2679 "tip"=>wfMsg("math_tip"),
2682 array( "image"=>"button_nowiki.png",
2683 "open"=>"\\<nowiki\\>",
2684 "close"=>"\\</nowiki\\>",
2685 "sample"=>wfMsg("nowiki_sample"),
2686 "tip"=>wfMsg("nowiki_tip"),
2689 array( "image"=>"button_sig.png",
2693 "tip"=>wfMsg("sig_tip"),
2696 array( "image"=>"button_hr.png",
2697 "open"=>"\\n----\\n",
2700 "tip"=>wfMsg("hr_tip"),
2704 $toolbar ="<script type='text/javascript'>\n/*<![CDATA[*/\n";
2706 $toolbar.="document.writeln(\"<div id='toolbar'>\");\n";
2707 foreach($toolarray as $tool) {
2709 $image=$wgStylePath."/images/".$tool["image"];
2710 $open=$tool["open"];
2711 $close=$tool["close"];
2712 $sample = addslashes( $tool["sample"] );
2714 // Note that we use the tip both for the ALT tag and the TITLE tag of the image.
2715 // Older browsers show a "speedtip" type message only for ALT.
2716 // Ideally these should be different, realistically they
2717 // probably don't need to be.
2718 $tip = addslashes( $tool["tip"] );
2720 #$key = $tool["key"];
2722 $toolbar.="addButton('$image','$tip','$open','$close','$sample');\n";
2725 $toolbar.="addInfobox('" . addslashes( wfMsg( "infobox" ) ) . "','" . addslashes(wfMsg("infobox_alert")) . "');\n";
2726 $toolbar.="document.writeln(\"</div>\");\n";
2728 $toolbar.="/*]]>*/\n</script>";
2734 require_once( "SkinStandard.php" );
2735 require_once( "SkinNostalgia.php" );
2736 require_once( "SkinCologneBlue.php" );
2738 if( $wgUsePHPTal ) {
2739 require_once( "SkinPHPTal.php" );