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 )
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='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='notice' style='font-weight: bold; color: red; text-align: center'>$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 getCategories () {
362 global $wgOut, $wgTitle, $wgUser, $wgParser;
363 global $wgUseCategoryMagic;
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() ) )
372 return "<p class='catlinks'>$s</p>";
375 function getQuickbarCompensator( $rows = 1 )
377 return "<td width='152' rowspan='{$rows}'> </td>";
380 # This gets called immediately before the </body> tag.
382 function afterContent()
384 global $wgUser, $wgOut, $wgServer;
385 global $wgTitle, $wgLang;
387 $printfooter = "<div class=\"printfooter\">\n" . $this->printFooter() . "</div>\n";
388 return $printfooter . $this->doAfterContent();
391 function printFooter() {
393 $url = htmlspecialchars( $wgTitle->getFullURL() );
394 return "<p>" . wfMsg( "retrievedfrom", "<a href=\"$url\">$url</a>" ) .
395 "</p>\n\n<p>" . $this->pageStats() . "</p>\n";
398 function doAfterContent()
400 global $wgUser, $wgOut, $wgLang;
401 $fname = "Skin::doAfterContent";
402 wfProfileIn( $fname );
403 wfProfileIn( "$fname-1" );
405 $s = "\n</div><br style=\"clear:both\" />\n";
406 $s .= "\n<div id='footer'>";
407 $s .= "<table border='0' cellspacing='0'><tr>";
409 wfProfileOut( "$fname-1" );
410 wfProfileIn( "$fname-2" );
412 $qb = $this->qbSetting();
414 $left = ($qb == 1 ||
$qb == 3);
415 if($wgLang->isRTL()) $left = !$left;
417 if ( $shove && $left ) { # Left
418 $s .= $this->getQuickbarCompensator();
420 wfProfileOut( "$fname-2" );
421 wfProfileIn( "$fname-3" );
422 $l = $wgLang->isRTL() ?
"right" : "left";
423 $s .= "<td class='bottom' align='$l' valign='top'>";
425 $s .= $this->bottomLinks();
426 $s .= "\n<br />" . $this->mainPageLink()
427 . " | " . $this->aboutLink()
428 . " | " . $this->specialLink( "recentchanges" )
429 . " | " . $this->searchForm()
430 . "<br /><span id='pagestats'>" . $this->pageStats() . "</span>";
433 if ( $shove && !$left ) { # Right
434 $s .= $this->getQuickbarCompensator();
436 $s .= "</tr></table>\n</div>\n</div>\n";
438 wfProfileOut( "$fname-3" );
439 wfProfileIn( "$fname-4" );
440 if ( 0 != $qb ) { $s .= $this->quickBar(); }
441 wfProfileOut( "$fname-4" );
442 wfProfileOut( $fname );
446 function pageTitleLinks()
448 global $wgOut, $wgTitle, $wgUser, $wgLang, $wgUseApproval, $wgRequest;
450 extract( $wgRequest->getValues( 'oldid', 'diff' ) );
451 $action = $wgRequest->getText( 'action' );
453 $s = $this->printableLink();
454 if ( wfMsg ( "disclaimers" ) != "-" ) $s .= " | " . $this->makeKnownLink( wfMsg( "disclaimerpage" ), wfMsg( "disclaimers" ) ) ;
456 if ( $wgOut->isArticleRelated() ) {
457 if ( $wgTitle->getNamespace() == Namespace::getImage() ) {
458 $name = $wgTitle->getDBkey();
459 $link = wfEscapeHTML( Image
::wfImageUrl( $name ) );
460 $style = $this->getInternalLinkAttributes( $link, $name );
461 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>";
463 # This will show the "Approve" link if $wgUseApproval=true;
464 if ( isset ( $wgUseApproval ) && $wgUseApproval )
466 $t = $wgTitle->getDBkey();
467 $name = "Approve this article" ;
468 $link = "http://test.wikipedia.org/w/magnus/wiki.phtml?title={$t}&action=submit&doit=1" ;
469 #wfEscapeHTML( wfImageUrl( $name ) );
470 $style = $this->getExternalLinkAttributes( $link, $name );
471 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>" ;
474 if ( "history" == $action ||
isset( $diff ) ||
isset( $oldid ) ) {
475 $s .= " | " . $this->makeKnownLink( $wgTitle->getPrefixedText(),
476 wfMsg( "currentrev" ) );
479 if ( $wgUser->getNewtalk() ) {
480 # do not show "You have new messages" text when we are viewing our
483 if(!(strcmp($wgTitle->getText(),$wgUser->getName()) == 0 &&
484 $wgTitle->getNamespace()==Namespace::getTalk(Namespace::getUser()))) {
485 $n =$wgUser->getName();
486 $tl = $this->makeKnownLink( $wgLang->getNsText(
487 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
488 wfMsg("newmessageslink") );
489 $s.=" | <strong>". wfMsg( "newmessages", $tl ) . "</strong>";
492 if( $wgUser->isSysop() &&
493 (($wgTitle->getArticleId() == 0) ||
($action == "history")) &&
494 ($n = $wgTitle->isDeleted() ) ) {
495 $s .= " | " . wfMsg( "thisisdeleted",
496 $this->makeKnownLink(
497 $wgLang->SpecialPage( "Undelete/" . $wgTitle->getPrefixedDBkey() ),
498 wfMsg( "restorelink", $n ) ) );
503 function printableLink()
505 global $wgOut, $wgFeedClasses, $wgRequest;
507 $baseurl = $_SERVER['REQUEST_URI'];
508 if( strpos( "?", $baseurl ) == false ) {
513 $baseurl = htmlspecialchars( $baseurl );
514 $printurl = $wgRequest->escapeAppendQuery( "printable=yes" );
516 $s = "<a href=\"$printurl\">" . wfMsg( "printableversion" ) . "</a>";
517 if( $wgOut->isSyndicated() ) {
518 foreach( $wgFeedClasses as $format => $class ) {
519 $feedurl = $wgRequest->escapeAppendQuery( "feed=$format" );
520 $s .= " | <a href=\"$feedurl\">{$format}</a>";
528 global $wgOut, $wgTitle, $wgUser;
530 $s = "<h1 class='pagetitle'>" . htmlspecialchars( $wgOut->getPageTitle() ) . "</h1>";
531 if($wgUser->getOption("editsectiononrightclick") && $wgTitle->userCanEdit()) { $s=$this->editSectionScript(0,$s);}
535 function pageSubtitle()
539 $sub = $wgOut->getSubtitle();
541 global $wgExtraSubtitle;
542 $sub = wfMsg( "fromwikipedia" ) . $wgExtraSubtitle;
544 $subpages = $this->subPageSubtitle();
545 $sub .= !empty($subpages)?
"</p><p class='subpages'>$subpages":'';
546 $s = "<p class='subtitle'>{$sub}</p>\n";
550 function subPageSubtitle()
552 global $wgOut,$wgTitle,$wgNamespacesWithSubpages;
554 if($wgOut->isArticle() && !empty($wgNamespacesWithSubpages[$wgTitle->getNamespace()])) {
555 $ptext=$wgTitle->getPrefixedText();
556 if(preg_match("/\//",$ptext)) {
557 $links=explode("/",$ptext);
560 foreach($links as $link) {
562 if ($c<count($links)) {
563 $growinglink .= $link;
564 $getlink = $this->makeLink( $growinglink, $link );
565 if(preg_match("/class='new'/i",$getlink)) { break; } # this is a hack, but it saves time
571 $subpages .= $getlink;
580 function nameAndLogin()
582 global $wgUser, $wgTitle, $wgLang, $wgShowIPinHeader, $wgIP;
584 $li = $wgLang->specialPage( "Userlogin" );
585 $lo = $wgLang->specialPage( "Userlogout" );
588 if ( 0 == $wgUser->getID() ) {
589 if( $wgShowIPinHeader && isset( $_COOKIE[ini_get("session.name")] ) ) {
592 $tl = $this->makeKnownLink( $wgLang->getNsText(
593 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
594 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
596 $s .= $n . " (".$tl.")";
598 $s .= wfMsg("notloggedin");
601 $rt = $wgTitle->getPrefixedURL();
602 if ( 0 == strcasecmp( urlencode( $lo ), $rt ) ) {
604 } else { $q = "returnto={$rt}"; }
606 $s .= "\n<br />" . $this->makeKnownLink( $li,
607 wfMsg( "login" ), $q );
609 $n = $wgUser->getName();
610 $rt = $wgTitle->getPrefixedURL();
611 $tl = $this->makeKnownLink( $wgLang->getNsText(
612 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
613 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
617 $s .= $this->makeKnownLink( $wgLang->getNsText(
618 Namespace::getUser() ) . ":{$n}", $n ) . "{$tl}<br />" .
619 $this->makeKnownLink( $lo, wfMsg( "logout" ),
620 "returnto={$rt}" ) . " | " .
621 $this->specialLink( "preferences" );
623 $s .= " | " . $this->makeKnownLink( wfMsg( "helppage" ),
629 function getSearchLink() {
630 $searchPage =& Title
::makeTitle( NS_SPECIAL
, "Search" );
631 return $searchPage->getLocalURL();
634 function escapeSearchLink() {
635 return htmlspecialchars( $this->getSearchLink() );
638 function searchForm()
641 $search = $wgRequest->getText( 'search' );
643 $s = "<form name='search' class='inline' method='post' action=\""
644 . $this->escapeSearchLink() . "\">\n"
645 . "<input type='text' name=\"search\" size='19' value=\""
646 . htmlspecialchars(substr($search,0,256)) . "\" />\n"
647 . "<input type='submit' name=\"go\" value=\"" . wfMsg ("go") . "\" /> "
648 . "<input type='submit' name=\"fulltext\" value=\"" . wfMsg ("search") . "\" />\n</form>";
658 $s = $this->mainPageLink() . $sep
659 . $this->specialLink( "recentchanges" );
661 if ( $wgOut->isArticleRelated() ) {
662 $s .= $sep . $this->editThisPage()
663 . $sep . $this->historyLink();
665 # Many people don't like this dropdown box
666 #$s .= $sep . $this->specialPagesList();
671 function bottomLinks()
673 global $wgOut, $wgUser, $wgTitle;
677 if ( $wgOut->isArticleRelated() ) {
678 $s .= "<strong>" . $this->editThisPage() . "</strong>";
679 if ( 0 != $wgUser->getID() ) {
680 $s .= $sep . $this->watchThisPage();
682 $s .= $sep . $this->talkLink()
683 . $sep . $this->historyLink()
684 . $sep . $this->whatLinksHere()
685 . $sep . $this->watchPageLinksLink();
687 if ( $wgTitle->getNamespace() == Namespace::getUser()
688 ||
$wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser()) )
691 $id=User
::idFromName($wgTitle->getText());
692 $ip=User
::isIP($wgTitle->getText());
694 if($id ||
$ip) { # both anons and non-anons have contri list
695 $s .= $sep . $this->userContribsLink();
697 if ( 0 != $wgUser->getID() ) { # show only to signed in users
698 if($id) { # can only email non-anons
699 $s .= $sep . $this->emailUserLink();
703 if ( $wgUser->isSysop() && $wgTitle->getArticleId() ) {
704 $s .= "\n<br />" . $this->deleteThisPage() .
705 $sep . $this->protectThisPage() .
706 $sep . $this->moveThisPage();
708 $s .= "<br />\n" . $this->otherLanguages();
715 global $wgOut, $wgLang, $wgArticle, $wgRequest;
716 global $wgDisableCounters;
718 extract( $wgRequest->getValues( 'oldid', 'diff' ) );
719 if ( ! $wgOut->isArticle() ) { return ""; }
720 if ( isset( $oldid ) ||
isset( $diff ) ) { return ""; }
721 if ( 0 == $wgArticle->getID() ) { return ""; }
724 if ( !$wgDisableCounters ) {
725 $count = $wgLang->formatNum( $wgArticle->getCount() );
727 $s = wfMsg( "viewcount", $count );
731 $s .= " " . $this->getCredits();
733 return $s . " " . $this->getCopyright();
736 function getCredits() {
737 global $wgMaxCredits;
741 if (!isset($wgMaxCredits) ||
$wgMaxCredits == 0) {
742 $s = $this->lastModified();
744 $s = $this->getAuthorCredits();
745 if ($wgMaxCredits > 1) {
746 $s .= " " . $this->getContributorCredits();
753 function getAuthorCredits() {
754 global $wgLang, $wgArticle;
756 $last_author = $wgArticle->getUser();
758 if ($last_author == 0) {
759 $author_credit = wfMsg("anonymous");
761 $real_name = User
::whoIsReal($last_author);
762 if (!empty($real_name)) {
763 $author_credit = $real_name;
765 $author_credit = wfMsg("siteuser", User
::whoIs($last_author));
769 $timestamp = $wgArticle->getTimestamp();
771 $d = $wgLang->timeanddate( $wgArticle->getTimestamp(), true );
775 return wfMsg("lastmodifiedby", $d, $author_credit);
778 function getContributorCredits() {
780 global $wgArticle, $wgMaxCredits, $wgLang;
782 # don't count last editor
784 $contributors = $wgArticle->getContributors($wgMaxCredits - 1);
786 $real_names = array();
787 $user_names = array();
789 # Sift for real versus user names
791 foreach ($contributors as $user_id => $user_parts) {
793 if (!empty($user_parts[1])) {
794 $real_names[$user_id] = $user_parts[1];
796 $user_names[$user_id] = $user_parts[0];
801 $real = $wgLang->listToText(array_values($real_names));
802 $user = $wgLang->listToText(array_values($user_names));
805 $user = wfMsg("siteusers", $user);
808 if ($contributors[0] && $contributors[0][0] > 0) {
809 $anon = wfMsg("anonymous");
814 $creds = $wgLang->listToText(array($real, $user, $anon));
816 return wfMsg("othercontribs", $creds);
819 function getCopyright() {
820 global $wgRightsPage, $wgRightsUrl, $wgRightsText;
822 if( $wgRightsPage ) {
823 $link = $this->makeKnownLink( $wgRightsPage, $wgRightsText );
824 } elseif( $wgRightsUrl ) {
825 $link = $this->makeExternalLink( $wgRightsUrl, $wgRightsText );
830 $out .= wfMsg( "copyright", $link );
834 function getCopyrightIcon() {
835 global $wgRightsPage, $wgRightsUrl, $wgRightsText, $wgRightsIcon;
837 if( $wgRightsIcon ) {
838 $icon = htmlspecialchars( $wgRightsIcon );
840 $url = htmlspecialchars( $wgRightsUrl );
841 $out .= "<a href=\"$url\">";
843 $text = htmlspecialchars( $wgRightsText );
844 $out .= "<img src=\"$icon\" alt='$text' />";
852 function getPoweredBy() {
854 $url = htmlspecialchars( "$wgStylePath/images/poweredby_mediawiki_88x31.png" );
855 $img = "<a href='http://www.mediawiki.org/'><img src='$url' alt='MediaWiki' /></a>";
859 function lastModified()
861 global $wgLang, $wgArticle;
863 $timestamp = $wgArticle->getTimestamp();
865 $d = $wgLang->timeanddate( $wgArticle->getTimestamp(), true );
866 $s = " " . wfMsg( "lastmodified", $d );
873 function logoText( $align = "" )
875 if ( "" != $align ) { $a = " align='{$align}'"; }
878 $mp = wfMsg( "mainpage" );
879 $titleObj = Title
::newFromText( $mp );
880 $s = "<a href=\"" . $titleObj->escapeLocalURL()
881 . "\"><img{$a} src=\""
882 . $this->getLogo() . "\" alt=\"" . "[{$mp}]\" /></a>";
888 global $wgOut, $wgTitle, $wgUser, $wgRequest, $wgLang;
889 global $wgDisableUploads, $wgRemoteUploads;
891 $fname = "Skin::quickBar";
892 wfProfileIn( $fname );
894 $action = $wgRequest->getText( 'action' );
895 $wpPreview = $wgRequest->getBool( 'wpPreview' );
896 $tns=$wgTitle->getNamespace();
898 $s = "\n<div id='quickbar'>";
899 $s .= "\n" . $this->logoText() . "\n<hr class='sep' />";
902 $s .= $this->mainPageLink()
903 . $sep . $this->specialLink( "recentchanges" )
904 . $sep . $this->specialLink( "randompage" );
905 if ($wgUser->getID()) {
906 $s.= $sep . $this->specialLink( "watchlist" ) ;
907 $s .= $sep .$this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
908 wfMsg( "mycontris" ), "target=" . wfUrlencode($wgUser->getName() ) );
911 // only show watchlist link if logged in
912 if ( wfMsg ( "currentevents" ) != "-" ) $s .= $sep . $this->makeKnownLink( wfMsg( "currentevents" ), "" ) ;
913 $s .= "\n<br /><hr class='sep' />";
914 $articleExists = $wgTitle->getArticleId();
915 if ( $wgOut->isArticle() ||
$action =="edit" ||
$action =="history" ||
$wpPreview) {
916 if($wgOut->isArticle()) {
917 $s .= "<strong>" . $this->editThisPage() . "</strong>";
918 } else { # backlink to the article in edit or history mode
919 if($articleExists){ # no backlink if no article
922 $text = wfMsg("articlepage");
925 $text = wfMsg("viewtalkpage");
928 $text = wfMsg("userpage");
931 $text = wfMsg("viewtalkpage");
934 $text = wfMsg("wikipediapage");
937 $text = wfMsg("viewtalkpage");
940 $text = wfMsg("imagepage");
943 $text = wfMsg("viewtalkpage");
946 $text= wfMsg("articlepage");
949 $link = $wgTitle->getText();
950 if ($nstext = $wgLang->getNsText($tns) ) { # add namespace if necessary
951 $link = $nstext . ":" . $link ;
954 $s .= $this->makeLink( $link, $text );
955 } elseif( $wgTitle->getNamespace() != Namespace::getSpecial() ) {
956 # we just throw in a "New page" text to tell the user that he's in edit mode,
957 # and to avoid messing with the separator that is prepended to the next item
958 $s .= "<strong>" . wfMsg("newpage") . "</strong>";
964 if( $tns%2
&& $action!="edit" && !$wpPreview) {
965 $s.="<br />".$this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg("postcomment"),"action=edit§ion=new");
969 watching could cause problems in edit mode:
970 if user edits article, then loads "watch this article" in background and then saves
971 article with "Watch this article" checkbox disabled, the article is transparently
972 unwatched. Therefore we do not show the "Watch this page" link in edit mode
974 if ( 0 != $wgUser->getID() && $articleExists) {
975 if($action!="edit" && $action != "submit" )
977 $s .= $sep . $this->watchThisPage();
979 if ( $wgTitle->userCanEdit() )
980 $s .= $sep . $this->moveThisPage();
982 if ( $wgUser->isSysop() and $articleExists ) {
983 $s .= $sep . $this->deleteThisPage() .
984 $sep . $this->protectThisPage();
986 $s .= $sep . $this->talkLink();
987 if ($articleExists && $action !="history") {
988 $s .= $sep . $this->historyLink();
990 $s.=$sep . $this->whatLinksHere();
992 if($wgOut->isArticleRelated()) {
993 $s .= $sep . $this->watchPageLinksLink();
996 if ( Namespace::getUser() == $wgTitle->getNamespace()
997 ||
$wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser())
1000 $id=User
::idFromName($wgTitle->getText());
1001 $ip=User
::isIP($wgTitle->getText());
1004 $s .= $sep . $this->userContribsLink();
1006 if ( 0 != $wgUser->getID() ) {
1007 if($id) { # can only email real users
1008 $s .= $sep . $this->emailUserLink();
1012 $s .= "\n<br /><hr class='sep' />";
1015 if ( 0 != $wgUser->getID() && ( !$wgDisableUploads ||
$wgRemoteUploads ) ) {
1016 $s .= $this->specialLink( "upload" ) . $sep;
1018 $s .= $this->specialLink( "specialpages" )
1019 . $sep . $this->bugReportsLink();
1021 global $wgSiteSupportPage;
1022 if( $wgSiteSupportPage ) {
1023 $s .= "\n<br /><a href=\"" . htmlspecialchars( $wgSiteSupportPage ) .
1024 "\" class=\"internal\">" . wfMsg( "sitesupport" ) . "</a>";
1027 $s .= "\n<br /></div>\n";
1028 wfProfileOut( $fname );
1032 function specialPagesList()
1034 global $wgUser, $wgOut, $wgLang, $wgServer, $wgRedirectScript;
1036 $pages = SpecialPage
::getPages();
1038 foreach ( $pages[""] as $name => $page ) {
1039 $a[$name] = $page->getDescription();
1041 if ( $wgUser->isSysop() )
1043 foreach ( $pages["sysop"] as $name => $page ) {
1044 $a[$name] = $page->getDescription();
1047 if ( $wgUser->isDeveloper() )
1049 foreach ( $pages["developer"] as $name => $page ) {
1050 $a[$name] = $page->getDescription() ;
1053 $go = wfMsg( "go" );
1054 $sp = wfMsg( "specialpages" );
1055 $spp = $wgLang->specialPage( "Specialpages" );
1057 $s = "<form id=\"specialpages\" method=\"get\" class=\"inline\" " .
1058 "action=\"" . htmlspecialchars( "{$wgServer}{$wgRedirectScript}" ) . "\">\n";
1059 $s .= "<select name=\"wpDropdown\">\n";
1060 $s .= "<option value=\"{$spp}\">{$sp}</option>\n";
1062 foreach ( $a as $name => $desc ) {
1063 $p = $wgLang->specialPage( $name );
1064 $s .= "<option value=\"{$p}\">{$desc}</option>\n";
1066 $s .= "</select>\n";
1067 $s .= "<input type='submit' value=\"{$go}\" name='redirect' />\n";
1072 function mainPageLink()
1074 $mp = wfMsg( "mainpage" );
1075 $s = $this->makeKnownLink( $mp, $mp );
1079 function copyrightLink()
1081 $s = $this->makeKnownLink( wfMsg( "copyrightpage" ),
1082 wfMsg( "copyrightpagename" ) );
1086 function aboutLink()
1088 $s = $this->makeKnownLink( wfMsg( "aboutpage" ),
1089 wfMsg( "aboutwikipedia" ) );
1094 function disclaimerLink()
1096 $s = $this->makeKnownLink( wfMsg( "disclaimerpage" ),
1097 wfMsg( "disclaimers" ) );
1101 function editThisPage()
1103 global $wgOut, $wgTitle, $wgRequest;
1105 $oldid = $wgRequest->getVal( 'oldid' );
1106 $diff = $wgRequest->getVal( 'diff' );
1107 $redirect = $wgRequest->getVal( 'redirect' );
1109 if ( ! $wgOut->isArticleRelated() ) {
1110 $s = wfMsg( "protectedpage" );
1112 $n = $wgTitle->getPrefixedText();
1113 if ( $wgTitle->userCanEdit() ) {
1114 $t = wfMsg( "editthispage" );
1116 #$t = wfMsg( "protectedpage" );
1117 $t = wfMsg( "viewsource" );
1121 if ( !is_null( $redirect ) ) { $red = "&redirect={$redirect}"; }
1122 if ( $oldid && ! isset( $diff ) ) {
1123 $oid = "&oldid={$oldid}";
1125 $s = $this->makeKnownLink( $n, $t, "action=edit{$oid}{$red}" );
1130 function deleteThisPage()
1132 global $wgUser, $wgOut, $wgTitle, $wgRequest;
1134 $diff = $wgRequest->getVal( 'diff' );
1135 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
1136 $n = $wgTitle->getPrefixedText();
1137 $t = wfMsg( "deletethispage" );
1139 $s = $this->makeKnownLink( $n, $t, "action=delete" );
1146 function protectThisPage()
1148 global $wgUser, $wgOut, $wgTitle, $wgRequest;
1150 $diff = $wgRequest->getVal( 'diff' );
1151 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
1152 $n = $wgTitle->getPrefixedText();
1154 if ( $wgTitle->isProtected() ) {
1155 $t = wfMsg( "unprotectthispage" );
1156 $q = "action=unprotect";
1158 $t = wfMsg( "protectthispage" );
1159 $q = "action=protect";
1161 $s = $this->makeKnownLink( $n, $t, $q );
1168 function watchThisPage()
1170 global $wgUser, $wgOut, $wgTitle;
1172 if ( $wgOut->isArticleRelated() ) {
1173 $n = $wgTitle->getPrefixedText();
1175 if ( $wgTitle->userIsWatching() ) {
1176 $t = wfMsg( "unwatchthispage" );
1177 $q = "action=unwatch";
1179 $t = wfMsg( "watchthispage" );
1180 $q = "action=watch";
1182 $s = $this->makeKnownLink( $n, $t, $q );
1184 $s = wfMsg( "notanarticle" );
1189 function moveThisPage()
1191 global $wgTitle, $wgLang;
1193 if ( $wgTitle->userCanEdit() ) {
1194 $s = $this->makeKnownLink( $wgLang->specialPage( "Movepage" ),
1195 wfMsg( "movethispage" ), "target=" . $wgTitle->getPrefixedURL() );
1196 } // no message if page is protected - would be redundant
1200 function historyLink()
1204 $s = $this->makeKnownLink( $wgTitle->getPrefixedText(),
1205 wfMsg( "history" ), "action=history" );
1209 function whatLinksHere()
1211 global $wgTitle, $wgLang;
1213 $s = $this->makeKnownLink( $wgLang->specialPage( "Whatlinkshere" ),
1214 wfMsg( "whatlinkshere" ), "target=" . $wgTitle->getPrefixedURL() );
1218 function userContribsLink()
1220 global $wgTitle, $wgLang;
1222 $s = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
1223 wfMsg( "contributions" ), "target=" . $wgTitle->getPartialURL() );
1227 function emailUserLink()
1229 global $wgTitle, $wgLang;
1231 $s = $this->makeKnownLink( $wgLang->specialPage( "Emailuser" ),
1232 wfMsg( "emailuser" ), "target=" . $wgTitle->getPartialURL() );
1236 function watchPageLinksLink()
1238 global $wgOut, $wgTitle, $wgLang;
1240 if ( ! $wgOut->isArticleRelated() ) {
1241 $s = "(" . wfMsg( "notanarticle" ) . ")";
1243 $s = $this->makeKnownLink( $wgLang->specialPage(
1244 "Recentchangeslinked" ), wfMsg( "recentchangeslinked" ),
1245 "target=" . $wgTitle->getPrefixedURL() );
1250 function otherLanguages()
1252 global $wgOut, $wgLang, $wgTitle, $wgUseNewInterlanguage;
1254 $a = $wgOut->getLanguageLinks();
1255 if ( 0 == count( $a ) ) {
1256 if ( !$wgUseNewInterlanguage ) return "";
1257 $ns = $wgLang->getNsIndex ( $wgTitle->getNamespace () ) ;
1258 if ( $ns != 0 AND $ns != 1 ) return "" ;
1260 $x = "mode=addlink&xt=".$wgTitle->getDBkey() ;
1261 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1262 wfMsg( "intl" ) , $x );
1265 if ( !$wgUseNewInterlanguage ) {
1266 $s = wfMsg( "otherlanguages" ) . ": ";
1268 global $wgLanguageCode ;
1269 $x = "mode=zoom&xt=".$wgTitle->getDBkey() ;
1270 $x .= "&xl=".$wgLanguageCode ;
1271 $s = $this->makeKnownLink( $wgLang->specialPage( "Intl" ),
1272 wfMsg( "otherlanguages" ) , $x ) . ": " ;
1275 $s = wfMsg( "otherlanguages" ) . ": ";
1277 if($wgLang->isRTL()) $s .= "<span dir='LTR'>";
1278 foreach( $a as $l ) {
1279 if ( ! $first ) { $s .= " | "; }
1282 $nt = Title
::newFromText( $l );
1283 $url = $nt->getFullURL();
1284 $text = $wgLang->getLanguageName( $nt->getInterwiki() );
1286 if ( "" == $text ) { $text = $l; }
1287 $style = $this->getExternalLinkAttributes( $l, $text );
1288 $s .= "<a href=\"{$url}\"{$style}>{$text}</a>";
1290 if($wgLang->isRTL()) $s .= "</span>";
1294 function bugReportsLink()
1296 $s = $this->makeKnownLink( wfMsg( "bugreportspage" ),
1297 wfMsg( "bugreports" ) );
1303 global $wgLinkCache;
1304 $t1 = Title
::newFromText( gmdate( "F j" ) );
1305 $t2 = Title
::newFromText( gmdate( "Y" ) );
1307 $wgLinkCache->suspend();
1308 $id = $t1->getArticleID();
1309 $wgLinkCache->resume();
1312 $s = $this->makeBrokenLink( $t1->getText() );
1314 $s = $this->makeKnownLink( $t1->getText() );
1318 $wgLinkCache->suspend();
1319 $id = $t2->getArticleID();
1320 $wgLinkCache->resume();
1323 $s .= $this->makeBrokenLink( $t2->getText() );
1325 $s .= $this->makeKnownLink( $t2->getText() );
1332 global $wgLang, $wgTitle, $wgLinkCache;
1334 $tns = $wgTitle->getNamespace();
1335 if ( -1 == $tns ) { return ""; }
1337 $pn = $wgTitle->getText();
1338 $tp = wfMsg( "talkpage" );
1339 if ( Namespace::isTalk( $tns ) ) {
1340 $lns = Namespace::getSubject( $tns );
1343 $text = wfMsg("articlepage");
1346 $text = wfMsg("userpage");
1349 $text = wfMsg("wikipediapage");
1352 $text = wfMsg("imagepage");
1355 $text= wfMsg("articlepage");
1359 $lns = Namespace::getTalk( $tns );
1362 $n = $wgLang->getNsText( $lns );
1363 if ( "" == $n ) { $link = $pn; }
1364 else { $link = "{$n}:{$pn}"; }
1366 $wgLinkCache->suspend();
1367 $s = $this->makeLink( $link, $text );
1368 $wgLinkCache->resume();
1373 function commentLink()
1375 global $wgLang, $wgTitle, $wgLinkCache;
1377 $tns = $wgTitle->getNamespace();
1378 if ( -1 == $tns ) { return ""; }
1380 $lns = ( Namespace::isTalk( $tns ) ) ?
$tns : Namespace::getTalk( $tns );
1382 # assert Namespace::isTalk( $lns )
1384 $n = $wgLang->getNsText( $lns );
1385 $pn = $wgTitle->getText();
1387 $link = "{$n}:{$pn}";
1389 $wgLinkCache->suspend();
1390 $s = $this->makeKnownLink($link, wfMsg("postcomment"), "action=edit§ion=new");
1391 $wgLinkCache->resume();
1396 # After all the page content is transformed into HTML, it makes
1397 # a final pass through here for things like table backgrounds.
1399 function transformContent( $text )
1404 # Note: This function MUST call getArticleID() on the link,
1405 # otherwise the cache won't get updated properly. See LINKCACHE.DOC.
1407 function makeLink( $title, $text = "", $query = "", $trail = "" ) {
1408 wfProfileIn( "Skin::makeLink" );
1409 $nt = Title
::newFromText( $title );
1411 $result = $this->makeLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1413 wfDebug( "Invalid title passed to Skin::makeLink(): \"$title\"\n" );
1414 $result = $text == "" ?
$title : $text;
1417 wfProfileOut( "Skin::makeLink" );
1421 function makeKnownLink( $title, $text = "", $query = "", $trail = "", $prefix = '',$aprops = '') {
1422 $nt = Title
::newFromText( $title );
1424 return $this->makeKnownLinkObj( Title
::newFromText( $title ), $text, $query, $trail, $prefix , $aprops );
1426 wfDebug( "Invalid title passed to Skin::makeKnownLink(): \"$title\"\n" );
1427 return $text == "" ?
$title : $text;
1431 function makeBrokenLink( $title, $text = "", $query = "", $trail = "" ) {
1432 $nt = Title
::newFromText( $title );
1434 return $this->makeBrokenLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1436 wfDebug( "Invalid title passed to Skin::makeBrokenLink(): \"$title\"\n" );
1437 return $text == "" ?
$title : $text;
1441 function makeStubLink( $title, $text = "", $query = "", $trail = "" ) {
1442 $nt = Title
::newFromText( $title );
1444 return $this->makeStubLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1446 wfDebug( "Invalid title passed to Skin::makeStubLink(): \"$title\"\n" );
1447 return $text == "" ?
$title : $text;
1451 # Pass a title object, not a title string
1452 function makeLinkObj( &$nt, $text= "", $query = "", $trail = "", $prefix = "" )
1454 global $wgOut, $wgUser;
1455 if ( $nt->isExternal() ) {
1456 $u = $nt->getFullURL();
1457 $link = $nt->getPrefixedURL();
1458 if ( "" == $text ) { $text = $nt->getPrefixedText(); }
1459 $style = $this->getExternalLinkAttributes( $link, $text );
1462 if ( "" != $trail ) {
1463 if ( preg_match( "/^([a-z]+)(.*)$$/sD", $trail, $m ) ) {
1468 $retVal = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1469 } elseif ( 0 == $nt->getNamespace() && "" == $nt->getText() ) {
1470 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1471 } elseif ( ( -1 == $nt->getNamespace() ) ||
1472 ( Namespace::getImage() == $nt->getNamespace() ) ) {
1473 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1475 $aid = $nt->getArticleID() ;
1477 $retVal = $this->makeBrokenLinkObj( $nt, $text, $query, $trail, $prefix );
1479 $threshold = $wgUser->getOption("stubthreshold") ;
1480 if ( $threshold > 0 ) {
1481 $res = wfQuery ( "SELECT LENGTH(cur_text) AS x, cur_namespace, cur_is_redirect FROM cur WHERE cur_id='{$aid}'", DB_READ
) ;
1483 if ( wfNumRows( $res ) > 0 ) {
1484 $s = wfFetchObject( $res );
1486 if ( $s->cur_is_redirect
OR $s->cur_namespace
!= 0 ) {
1487 $size = $threshold*2 ; # Really big
1489 wfFreeResult( $res );
1491 $size = $threshold*2 ; # Really big
1496 if ( $size < $threshold ) {
1497 $retVal = $this->makeStubLinkObj( $nt, $text, $query, $trail, $prefix );
1499 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1506 # Pass a title object, not a title string
1507 function makeKnownLinkObj( &$nt, $text = "", $query = "", $trail = "", $prefix = "" , $aprops = '')
1509 global $wgOut, $wgTitle;
1511 $fname = "Skin::makeKnownLinkObj";
1512 wfProfileIn( $fname );
1514 $link = $nt->getPrefixedURL();
1516 if ( "" == $link ) {
1518 if ( "" == $text ) {
1519 $text = htmlspecialchars( $nt->getFragment() );
1522 $u = $nt->escapeLocalURL( $query );
1524 if ( "" != $nt->getFragment() ) {
1525 $u .= "#" . htmlspecialchars( $nt->getFragment() );
1527 if ( "" == $text ) {
1528 $text = htmlspecialchars( $nt->getPrefixedText() );
1530 $style = $this->getInternalLinkAttributesObj( $nt, $text );
1533 if ( "" != $trail ) {
1534 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1539 $r = "<a href=\"{$u}\"{$style}{$aprops}>{$prefix}{$text}{$inside}</a>{$trail}";
1540 wfProfileOut( $fname );
1544 # Pass a title object, not a title string
1545 function makeBrokenLinkObj( &$nt, $text = "", $query = "", $trail = "", $prefix = "" )
1547 global $wgOut, $wgUser;
1549 $fname = "Skin::makeBrokenLinkObj";
1550 wfProfileIn( $fname );
1552 if ( "" == $query ) {
1555 $q = "action=edit&{$query}";
1557 $u = $nt->escapeLocalURL( $q );
1559 if ( "" == $text ) {
1560 $text = htmlspecialchars( $nt->getPrefixedText() );
1562 $style = $this->getInternalLinkAttributesObj( $nt, $text, "yes" );
1565 if ( "" != $trail ) {
1566 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1571 if ( $wgUser->getOption( "highlightbroken" ) ) {
1572 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1574 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>?</a>{$trail}";
1577 wfProfileOut( $fname );
1581 # Pass a title object, not a title string
1582 function makeStubLinkObj( &$nt, $text = "", $query = "", $trail = "", $prefix = "" )
1584 global $wgOut, $wgUser;
1586 $link = $nt->getPrefixedURL();
1588 $u = $nt->escapeLocalURL( $query );
1590 if ( "" == $text ) {
1591 $text = htmlspecialchars( $nt->getPrefixedText() );
1593 $style = $this->getInternalLinkAttributesObj( $nt, $text, "stub" );
1596 if ( "" != $trail ) {
1597 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1602 if ( $wgUser->getOption( "highlightbroken" ) ) {
1603 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1605 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>!</a>{$trail}";
1610 function makeSelfLinkObj( &$nt, $text = "", $query = "", $trail = "", $prefix = "" )
1612 $u = $nt->escapeLocalURL( $query );
1613 if ( "" == $text ) {
1614 $text = htmlspecialchars( $nt->getPrefixedText() );
1617 if ( "" != $trail ) {
1618 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1623 return "<strong>{$prefix}{$text}{$inside}</strong>{$trail}";
1626 /* these are used extensively in SkinPHPTal, but also some other places */
1627 /*static*/ function makeSpecialUrl( $name, $urlaction='' ) {
1628 $title = Title
::makeTitle( NS_SPECIAL
, $name );
1629 $this->checkTitle($title, $name);
1630 return $title->getLocalURL( $urlaction );
1632 /*static*/ function makeTalkUrl ( $name, $urlaction='' ) {
1633 $title = Title
::newFromText( $name );
1634 $title = $title->getTalkPage();
1635 $this->checkTitle($title, $name);
1636 return $title->getLocalURL( $urlaction );
1638 /*static*/ function makeArticleUrl ( $name, $urlaction='' ) {
1639 $title = Title
::newFromText( $name );
1640 $title= $title->getSubjectPage();
1641 $this->checkTitle($title, $name);
1642 return $title->getLocalURL( $urlaction );
1644 /*static*/ function makeI18nUrl ( $name, $urlaction='' ) {
1645 $title = Title
::newFromText( wfMsg($name) );
1646 $this->checkTitle($title, $name);
1647 return $title->getLocalURL( $urlaction );
1649 /*static*/ function makeUrl ( $name, $urlaction='' ) {
1650 $title = Title
::newFromText( $name );
1651 $this->checkTitle($title, $name);
1652 return $title->getLocalURL( $urlaction );
1655 /* these return an array with the 'href' and boolean 'exists' */
1656 /*static*/ function makeUrlDetails ( $name, $urlaction='' ) {
1657 $title = Title
::newFromText( $name );
1658 $this->checkTitle($title, $name);
1660 'href' => $title->getLocalURL( $urlaction ),
1661 'exists' => $title->getArticleID() != 0?
true:false
1664 /*static*/ function makeTalkUrlDetails ( $name, $urlaction='' ) {
1665 $title = Title
::newFromText( $name );
1666 $title = $title->getTalkPage();
1667 $this->checkTitle($title, $name);
1669 'href' => $title->getLocalURL( $urlaction ),
1670 'exists' => $title->getArticleID() != 0?
true:false
1673 /*static*/ function makeArticleUrlDetails ( $name, $urlaction='' ) {
1674 $title = Title
::newFromText( $name );
1675 $title= $title->getSubjectPage();
1676 $this->checkTitle($title, $name);
1678 'href' => $title->getLocalURL( $urlaction ),
1679 'exists' => $title->getArticleID() != 0?
true:false
1682 /*static*/ function makeI18nUrlDetails ( $name, $urlaction='' ) {
1683 $title = Title
::newFromText( wfMsg($name) );
1684 $this->checkTitle($title, $name);
1686 'href' => $title->getLocalURL( $urlaction ),
1687 'exists' => $title->getArticleID() != 0?
true:false
1691 # make sure we have some title to operate on
1692 /*static*/ function checkTitle ( &$title, &$name ) {
1693 if(!is_object($title)) {
1694 $title = Title
::newFromText( $name );
1695 if(!is_object($title)) {
1696 $title = Title
::newFromText( '<error: link target missing>' );
1701 function fnamePart( $url )
1703 $basename = strrchr( $url, "/" );
1704 if ( false === $basename ) { $basename = $url; }
1705 else { $basename = substr( $basename, 1 ); }
1706 return wfEscapeHTML( $basename );
1709 function makeImage( $url, $alt = "" )
1713 if ( "" == $alt ) { $alt = $this->fnamePart( $url ); }
1714 $s = "<img src=\"{$url}\" alt=\"{$alt}\" />";
1718 function makeImageLink( $name, $url, $alt = "" ) {
1719 $nt = Title
::makeTitle( Namespace::getImage(), $name );
1720 return $this->makeImageLinkObj( $nt, $alt );
1723 function makeImageLinkObj( $nt, $alt = "" ) {
1724 global $wgLang, $wgUseImageResize;
1725 $img = Image
::newFromTitle( $nt );
1726 $url = $img->getURL();
1729 $prefix = $postfix = "";
1731 if ( $wgUseImageResize ) {
1732 # Check if the alt text is of the form "options|alt text"
1734 # * thumbnail make a thumbnail with enlarge-icon and caption, alignment depends on lang
1735 # * left no resizing, just left align. label is used for alt= only
1736 # * right same, but right aligned
1737 # * none same, but not aligned
1738 # * ___px scale to ___ pixels width, no aligning. e.g. use in taxobox
1739 # * center center the image
1740 # * framed Keep original image size, no magnify-button.
1742 $part = explode( "|", $alt);
1744 $mwThumb =& MagicWord
::get( MAG_IMG_THUMBNAIL
);
1745 $mwLeft =& MagicWord
::get( MAG_IMG_LEFT
);
1746 $mwRight =& MagicWord
::get( MAG_IMG_RIGHT
);
1747 $mwNone =& MagicWord
::get( MAG_IMG_NONE
);
1748 $mwWidth =& MagicWord
::get( MAG_IMG_WIDTH
);
1749 $mwCenter =& MagicWord
::get( MAG_IMG_CENTER
);
1750 $mwFramed =& MagicWord
::get( MAG_IMG_FRAMED
);
1751 $alt = $part[count($part)-1];
1753 $height = $framed = $thumb = false;
1755 foreach( $part as $key => $val ) {
1756 if ( ! is_null( $mwThumb->matchVariableStartToEnd($val) ) ) {
1758 } elseif ( ! is_null( $mwRight->matchVariableStartToEnd($val) ) ) {
1759 # remember to set an alignment, don't render immediately
1761 } elseif ( ! is_null( $mwLeft->matchVariableStartToEnd($val) ) ) {
1762 # remember to set an alignment, don't render immediately
1764 } elseif ( ! is_null( $mwCenter->matchVariableStartToEnd($val) ) ) {
1765 # remember to set an alignment, don't render immediately
1767 } elseif ( ! is_null( $mwNone->matchVariableStartToEnd($val) ) ) {
1768 # remember to set an alignment, don't render immediately
1770 } elseif ( ! is_null( $match = $mwWidth->matchVariableStartToEnd($val) ) ) {
1771 # $match is the image width in pixels
1772 if ( preg_match( "/^([0-9]*)x([0-9]*)$/", $match, $m ) ) {
1773 $width = intval( $m[1] );
1774 $height = intval( $m[2] );
1776 $width = intval($match);
1778 } elseif ( ! is_null( $mwFramed->matchVariableStartToEnd($val) ) ) {
1782 if ( "center" == $align )
1784 $prefix = '<span style="text-align: center">';
1785 $postfix = '</span>';
1789 if ( $thumb ||
$framed ) {
1791 # Create a thumbnail. Alignment depends on language
1792 # writing direction, # right aligned for left-to-right-
1793 # languages ("Western languages"), left-aligned
1794 # for right-to-left-languages ("Semitic languages")
1796 # If thumbnail width has not been provided, it is set
1797 # here to 180 pixels
1798 if ( $align == "" ) {
1799 $align = $wgLang->isRTL() ?
"left" : "right";
1801 if ( ! isset($width) ) {
1804 return $prefix.$this->makeThumbLinkObj( $img, $alt, $align, $width, $height, $framed ).$postfix;
1806 } elseif ( isset($width) ) {
1808 # Create a resized image, without the additional thumbnail
1811 if ( ( ! $height === false )
1812 && ( $img->getHeight() * $width / $img->getWidth() > $height ) ) {
1813 print "height=$height<br>\nimg->getHeight() = ".$img->getHeight()."<br>\n";
1814 print "rescaling by factor ". $height / $img->getHeight() . "<br>\n";
1815 $width = $img->getWidth() * $height / $img->getHeight();
1817 $url = $img->createThumb( $width );
1819 } # endif $wgUseImageResize
1821 if ( empty( $alt ) ) {
1822 $alt = preg_replace( '/\.(.+?)^/', '', $img->getName() );
1824 $alt = htmlspecialchars( $alt );
1826 $u = $nt->escapeLocalURL();
1829 $s = str_replace( "$1", $img->getName(), wfMsg("missingimage") );
1830 $s .= "<br>{$alt}<br>{$url}<br>\n";
1832 $s = "<a href=\"{$u}\" class='image' title=\"{$alt}\">" .
1833 "<img src=\"{$url}\" alt=\"{$alt}\" /></a>";
1835 if ( "" != $align ) {
1836 $s = "<div class=\"float{$align}\"><span>{$s}</span></div>";
1838 return str_replace("\n", ' ',$prefix.$s.$postfix);
1842 function makeThumbLinkObj( $img, $label = "", $align = "right", $boxwidth = 180, $boxheight=false, $framed=false ) {
1843 global $wgStylePath, $wgLang;
1844 # $image = Title::makeTitle( Namespace::getImage(), $name );
1845 $url = $img->getURL();
1847 #$label = htmlspecialchars( $label );
1848 $alt = preg_replace( "/<[^>]*>/", "", $label);
1849 $alt = htmlspecialchars( $alt );
1851 if ( $img->exists() )
1853 $width = $img->getWidth();
1854 $height = $img->getHeight();
1856 $width = $height = 200;
1860 // Use image dimensions, don't scale
1862 $oboxwidth = $boxwidth +
2;
1863 $boxheight = $height;
1866 $h = intval( $height/($width/$boxwidth) );
1867 $oboxwidth = $boxwidth +
2;
1868 if ( ( ! $boxheight === false ) && ( $h > $boxheight ) )
1870 $boxwidth *= $boxheight/$h;
1874 $thumbUrl = $img->createThumb( $boxwidth );
1877 $u = $img->getEscapeLocalURL();
1879 $more = htmlspecialchars( wfMsg( "thumbnail-more" ) );
1880 $magnifyalign = $wgLang->isRTL() ?
"left" : "right";
1881 $textalign = $wgLang->isRTL() ?
' style="text-align:right"' : "";
1883 $s = "<div class=\"thumb t{$align}\"><div style=\"width:{$oboxwidth}px;\">";
1884 if ( $thumbUrl == "" ) {
1885 $s .= str_replace( "$1", $img->getName(), wfMsg("missingimage") );
1888 $s .= '<a href="'.$u.'" class="internal" title="'.$alt.'">'.
1889 '<img src="'.$thumbUrl.'" alt="'.$alt.'" ' .
1890 'width="'.$boxwidth.'" height="'.$boxheight.'" /></a>';
1894 $zoomicon = '<div class="magnify" style="float:'.$magnifyalign.'">'.
1895 '<a href="'.$u.'" class="internal" title="'.$more.'">'.
1896 '<img src="'.$wgStylePath.'/images/magnify-clip.png" ' .
1897 'width="15" height="11" alt="'.$more.'" /></a></div>';
1900 $s .= ' <div class="thumbcaption" '.$textalign.'>'.$zoomicon.$label."</div></div></div>";
1901 return str_replace("\n", ' ', $s);
1904 function makeMediaLink( $name, $url, $alt = "" ) {
1905 $nt = Title
::makeTitle( Namespace::getMedia(), $name );
1906 return $this->makeMediaLinkObj( $nt, $alt );
1909 function makeMediaLinkObj( $nt, $alt = "" )
1911 $name = $nt->getDBKey();
1912 $url = Image
::wfImageUrl( $name );
1913 if ( empty( $alt ) ) {
1914 $alt = preg_replace( '/\.(.+?)^/', '', $name );
1917 $u = htmlspecialchars( $url );
1918 $s = "<a href=\"{$u}\" class='internal' title=\"{$alt}\">{$alt}</a>";
1922 function specialLink( $name, $key = "" )
1926 if ( "" == $key ) { $key = strtolower( $name ); }
1927 $pn = $wgLang->ucfirst( $name );
1928 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1932 function makeExternalLink( $url, $text, $escape = true ) {
1933 $style = $this->getExternalLinkAttributes( $url, $text );
1934 $url = htmlspecialchars( $url );
1936 $text = htmlspecialchars( $text );
1938 return "<a href=\"$url\"$style>$text</a>";
1941 # Called by history lists and recent changes
1944 # Returns text for the start of the tabular part of RC
1945 function beginRecentChangesList()
1947 $this->rc_cache
= array() ;
1948 $this->rcMoveIndex
= 0;
1949 $this->rcCacheIndex
= 0 ;
1950 $this->lastdate
= "";
1951 $this->rclistOpen
= false;
1955 function beginImageHistoryList()
1957 $s = "\n<h2>" . wfMsg( "imghistory" ) . "</h2>\n" .
1958 "<p>" . wfMsg( "imghistlegend" ) . "</p>\n<ul class='special'>";
1962 # Returns text for the end of RC
1963 # If enhanced RC is in use, returns pretty much all the text
1964 function endRecentChangesList()
1966 $s = $this->recentChangesBlock() ;
1967 if( $this->rclistOpen
) {
1973 # Enhanced RC ungrouped line
1974 function recentChangesBlockLine ( $rcObj )
1976 global $wgStylePath, $wgLang ;
1978 # Get rc_xxxx variables
1979 extract( $rcObj->mAttribs
) ;
1980 $curIdEq = "curid=$rc_cur_id";
1985 $r .= "<img src='{$wgStylePath}/images/Arr_.png' width='12' height='12' border='0' />" ; $r .= "<tt>" ;
1987 if ( $rc_type == RC_MOVE
) {
1988 $r .= " ";
1990 # M & N (minor & new)
1991 $M = wfMsg( "minoreditletter" );
1992 $N = wfMsg( "newpageletter" );
1994 if ( $rc_type == RC_NEW
) {
2007 $r .= " ".$rcObj->timestamp
." " ;
2011 $link = $rcObj->link
;
2012 if ( $rcObj->watched
) $link = "<strong>{$link}</strong>" ;
2017 $r .= $rcObj->curlink
;
2021 $r .= $this->makeKnownLinkObj( $rcObj->getTitle(), wfMsg( "hist" ), "{$curIdEq}&action=history" );
2024 $r .= ") . . ".$rcObj->userlink
;
2025 $r .= $rcObj->usertalklink
;
2028 if ( $rc_comment != "" && $rc_type != RC_MOVE
) {
2029 $rc_comment=$this->formatComment($rc_comment);
2030 $r .= $wgLang->emphasize( " (".$rc_comment.")" );
2038 function recentChangesBlockGroup ( $block )
2040 global $wgStylePath, $wgLang ;
2043 $M = wfMsg( "minoreditletter" );
2044 $N = wfMsg( "newpageletter" );
2046 # Collate list of users
2048 $userlinks = array () ;
2049 foreach ( $block AS $rcObj ) {
2050 $oldid = $rcObj->mAttribs
['rc_last_oldid'];
2051 if ( $rcObj->mAttribs
['rc_new'] ) $isnew = true ;
2052 $u = $rcObj->userlink
;
2053 if ( !isset ( $userlinks[$u] ) ) $userlinks[$u] = 0 ;
2057 # Sort the list and convert to text
2058 krsort ( $userlinks ) ;
2059 asort ( $userlinks ) ;
2061 foreach ( $userlinks as $userlink => $count) {
2063 if ( $count > 1 ) $text .= " ({$count}×)" ;
2064 array_push ( $users , $text ) ;
2066 $users = " <font size='-1'>[".implode("; ",$users)."]</font>" ;
2069 $rci = "RCI{$this->rcCacheIndex}" ;
2070 $rcl = "RCL{$this->rcCacheIndex}" ;
2071 $rcm = "RCM{$this->rcCacheIndex}" ;
2072 $toggleLink = "javascript:toggleVisibility(\"{$rci}\",\"{$rcm}\",\"{$rcl}\")" ;
2073 $arrowdir = $wgLang->isRTL() ?
"l" : "r";
2074 $tl = "<span id='{$rcm}'><a href='$toggleLink'><img src='{$wgStylePath}/images/Arr_{$arrowdir}.png' width='12' height='12' /></a></span>" ;
2075 $tl .= "<span id='{$rcl}' style='display:none'><a href='$toggleLink'><img src='{$wgStylePath}/images/Arr_d.png' width='12' height='12' /></a></span>" ;
2081 if ( $isnew ) $r .= $N ;
2082 else $r .= " " ;
2083 $r .= " " ; # Minor
2086 $r .= " ".$block[0]->timestamp
." " ;
2090 $link = $block[0]->link
;
2091 if ( $block[0]->watched
) $link = "<strong>{$link}</strong>" ;
2094 $curIdEq = "curid=" . $block[0]->mAttribs
['rc_cur_id'];
2095 if ( $block[0]->mAttribs
['rc_type'] != RC_LOG
) {
2097 $r .= " (".count($block)." " ;
2098 if ( $isnew ) $r .= wfMsg("changes");
2099 else $r .= $this->makeKnownLinkObj( $block[0]->getTitle() , wfMsg("changes") ,
2100 "{$curIdEq}&diff=0&oldid=".$oldid ) ;
2104 $r .= $this->makeKnownLinkObj( $block[0]->getTitle(), wfMsg( "history" ), "{$curIdEq}&action=history" );
2112 $r .= "<div id='{$rci}' style='display:none'>" ;
2113 foreach ( $block AS $rcObj ) {
2114 # Get rc_xxxx variables
2115 extract( $rcObj->mAttribs
);
2117 $r .= "<img src='{$wgStylePath}/images/Arr_.png' width=12 height=12 />";
2118 $r .= "<tt> " ;
2119 if ( $rc_new ) $r .= $N ;
2120 else $r .= " " ;
2121 if ( $rc_minor ) $r .= $M ;
2122 else $r .= " " ;
2126 if ( $rc_last_oldid != 0 ) {
2127 $o = "oldid=".$rc_last_oldid ;
2129 if ( $rc_type == RC_LOG
) {
2130 $link = $rcObj->timestamp
;
2132 $link = $this->makeKnownLinkObj( $rcObj->getTitle(), $rcObj->timestamp
, "{$curIdEq}&$o" ) ;
2134 $link = "<tt>{$link}</tt>" ;
2138 $r .= $rcObj->curlink
;
2140 $r .= $rcObj->lastlink
;
2141 $r .= ") . . ".$rcObj->userlink
;
2142 $r .= $rcObj->usertalklink
;
2143 if ( $rc_comment != "" ) {
2144 $rc_comment=$this->formatComment($rc_comment);
2145 $r .= $wgLang->emphasize( " (".$rc_comment.")" ) ;
2151 $this->rcCacheIndex++
;
2155 # If enhanced RC is in use, this function takes the previously cached
2156 # RC lines, arranges them, and outputs the HTML
2157 function recentChangesBlock ()
2159 global $wgStylePath ;
2160 if ( count ( $this->rc_cache
) == 0 ) return "" ;
2162 foreach ( $this->rc_cache
AS $secureName => $block ) {
2163 if ( count ( $block ) < 2 ) {
2164 $blockOut .= $this->recentChangesBlockLine ( array_shift ( $block ) ) ;
2166 $blockOut .= $this->recentChangesBlockGroup ( $block ) ;
2170 return "<div>{$blockOut}</div>" ;
2173 # Called in a loop over all displayed RC entries
2174 # Either returns the line, or caches it for later use
2175 function recentChangesLine( &$rc, $watched = false )
2178 $usenew = $wgUser->getOption( "usenewrc" );
2180 $line = $this->recentChangesLineNew ( $rc, $watched ) ;
2182 $line = $this->recentChangesLineOld ( $rc, $watched ) ;
2186 function recentChangesLineOld( &$rc, $watched = false )
2188 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds;
2190 # Extract DB fields into local scope
2191 extract( $rc->mAttribs
);
2192 $curIdEq = "curid=" . $rc_cur_id;
2194 # Make date header if necessary
2195 $date = $wgLang->date( $rc_timestamp, true);
2197 if ( $date != $this->lastdate
) {
2198 if ( "" != $this->lastdate
) { $s .= "</ul>\n"; }
2199 $s .= "<h4>{$date}</h4>\n<ul class='special'>";
2200 $this->lastdate
= $date;
2201 $this->rclistOpen
= true;
2205 if ( $rc_type == RC_MOVE
) {
2207 $s .= "(" . wfMsg( "diff" ) . ") (";
2209 $s .= $this->makeKnownLinkObj( $rc->getMovedToTitle(), wfMsg( "hist" ), "action=history" ) .
2212 # "[[x]] moved to [[y]]"
2214 $s .= wfMsg( "1movedto2", $this->makeKnownLinkObj( $rc->getTitle(), "", "redirect=no" ),
2215 $this->makeKnownLinkObj( $rc->getMovedToTitle(), "" ) );
2219 if ( $rc_type == RC_NEW ||
$rc_type == RC_LOG
) {
2220 $diffLink = wfMsg( "diff" );
2222 $diffLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( "diff" ),
2223 "{$curIdEq}&diff={$rc_this_oldid}&oldid={$rc_last_oldid}" ,'' ,'' , ' tabindex="'.$rc->counter
.'"');
2225 $s .= "($diffLink) (";
2228 $s .= $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( "hist" ), "{$curIdEq}&action=history" );
2231 # M and N (minor and new)
2232 $M = wfMsg( "minoreditletter" );
2233 $N = wfMsg( "newpageletter" );
2234 if ( $rc_minor ) { $s .= " <strong>{$M}</strong>"; }
2235 if ( $rc_type == RC_NEW
) { $s .= "<strong>{$N}</strong>"; }
2238 $articleLink = $this->makeKnownLinkObj( $rc->getTitle(), "" );
2241 $articleLink = "<strong>{$articleLink}</strong>";
2243 $s .= " $articleLink";
2248 $s .= "; " . $wgLang->time( $rc_timestamp, true, $wgRCSeconds ) . " . . ";
2250 # User link (or contributions for unregistered users)
2251 if ( 0 == $rc_user ) {
2252 $userLink = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
2253 $rc_user_text, "target=" . $rc_user_text );
2255 $userLink = $this->makeLink( $wgLang->getNsText( NS_USER
) . ":{$rc_user_text}", $rc_user_text );
2260 $talkname=$wgLang->getNsText(NS_TALK
); # use the shorter name
2261 global $wgDisableAnonTalk;
2262 if( 0 == $rc_user && $wgDisableAnonTalk ) {
2265 $utns=$wgLang->getNsText(NS_USER_TALK
);
2266 $userTalkLink= $this->makeLink($utns . ":{$rc_user_text}", $talkname );
2270 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2271 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2272 "Blockip" ), wfMsg( "blocklink" ), "ip={$rc_user_text}" );
2276 if($userTalkLink) $userTalkLink .= " | ";
2277 $userTalkLink .= $blockLink;
2279 if($userTalkLink) $s.=" ({$userTalkLink})";
2282 if ( "" != $rc_comment && "*" != $rc_comment && $rc_type != RC_MOVE
) {
2283 $rc_comment=$this->formatComment($rc_comment);
2284 $s .= $wgLang->emphasize(" (" . $rc_comment . ")");
2291 # function recentChangesLineNew( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched = false, $oldid = 0 , $diffid = 0 )
2292 function recentChangesLineNew( &$baseRC, $watched = false )
2294 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds;
2296 # Create a specialised object
2297 $rc = RCCacheEntry
::newFromParent( $baseRC ) ;
2299 # Extract fields from DB into the function scope (rc_xxxx variables)
2300 extract( $rc->mAttribs
);
2301 $curIdEq = "curid=" . $rc_cur_id;
2303 # If it's a new day, add the headline and flush the cache
2304 $date = $wgLang->date( $rc_timestamp, true);
2306 if ( $date != $this->lastdate
) {
2307 # Process current cache
2308 $ret = $this->recentChangesBlock () ;
2309 $this->rc_cache
= array() ;
2310 $ret .= "<h4>{$date}</h4>\n";
2311 $this->lastdate
= $date;
2315 if ( $rc_type == RC_MOVE
) {
2316 $clink = $this->makeKnownLinkObj( $rc->getTitle(), "", "redirect=no" );
2317 $clink .= " " . wfMsg("movedto") . " ";
2318 $clink .= $this->makeKnownLinkObj( $rc->getMovedToTitle(), "" );
2320 $clink = $this->makeKnownLinkObj( $rc->getTitle(), "" ) ;
2323 $time = $wgLang->time( $rc_timestamp, true, $wgRCSeconds );
2324 $rc->watched
= $watched ;
2325 $rc->link
= $clink ;
2326 $rc->timestamp
= $time;
2329 if ( ( $rc_type == RC_NEW
&& $rc_this_oldid == 0 ) ||
$rc_type == RC_LOG ||
$rc_type == RC_MOVE
) {
2330 $curLink = wfMsg( "cur" );
2332 $curLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( "cur" ),
2333 "{$curIdEq}&diff=0&oldid={$rc_this_oldid}" ,'' ,'' , ' tabindex="'.$baseRC->counter
.'"' );
2337 $titleObj = $rc->getTitle();
2338 if ( $rc_last_oldid == 0 ||
$rc_type == RC_LOG ||
$rc_type == RC_MOVE
) {
2339 $lastLink = wfMsg( "last" );
2341 $lastLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( "last" ),
2342 "{$curIdEq}&diff={$rc_this_oldid}&oldid={$rc_last_oldid}" );
2345 # Make user link (or user contributions for unregistered users)
2346 if ( 0 == $rc_user ) {
2347 $userLink = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
2348 $rc_user_text, "target=" . $rc_user_text );
2350 $userLink = $this->makeLink( $wgLang->getNsText(
2351 Namespace::getUser() ) . ":{$rc_user_text}", $rc_user_text );
2354 $rc->userlink
= $userLink ;
2355 $rc->lastlink
= $lastLink ;
2356 $rc->curlink
= $curLink ;
2358 # Make user talk link
2359 $utns=$wgLang->getNsText(NS_USER_TALK
);
2360 $talkname=$wgLang->getNsText(NS_TALK
); # use the shorter name
2361 $userTalkLink= $this->makeLink($utns . ":{$rc_user_text}", $talkname );
2363 global $wgDisableAnonTalk;
2364 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2365 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2366 "Blockip" ), wfMsg( "blocklink" ), "ip={$rc_user_text}" );
2367 if( $wgDisableAnonTalk )
2368 $rc->usertalklink
= " ({$blockLink})";
2370 $rc->usertalklink
= " ({$userTalkLink} | {$blockLink})";
2372 if( $wgDisableAnonTalk && ($rc_user == 0) )
2373 $rc->usertalklink
= "";
2375 $rc->usertalklink
= " ({$userTalkLink})";
2378 # Put accumulated information into the cache, for later display
2379 # Page moves go on their own line
2380 $title = $rc->getTitle();
2381 $secureName = $title->getPrefixedDBkey();
2382 if ( $rc_type == RC_MOVE
) {
2383 # Use an @ character to prevent collision with page names
2384 $this->rc_cache
["@@" . ($this->rcMoveIndex++
)] = array($rc);
2386 if ( !isset ( $this->rc_cache
[$secureName] ) ) $this->rc_cache
[$secureName] = array() ;
2387 array_push ( $this->rc_cache
[$secureName] , $rc ) ;
2392 function endImageHistoryList()
2398 /* This function is called by all recent changes variants, by the page history,
2399 and by the user contributions list. It is responsible for formatting edit
2400 comments. It escapes any HTML in the comment, but adds some CSS to format
2401 auto-generated comments (from section editing) and formats [[wikilinks]].
2402 Main author: Erik Möller (moeller@scireview.de)
2404 function formatComment($comment)
2407 $comment=wfEscapeHTML($comment);
2409 # The pattern for autogen comments is / * foo * /, which makes for
2411 # We look for all comments, match any text before and after the comment,
2412 # add a separator where needed and format the comment itself with CSS
2413 while (preg_match("/(.*)\/\*\s*(.*?)\s*\*\/(.*)/", $comment,$match)) {
2418 if($pre) { $auto="$sep ".$auto; }
2419 if($post) { $auto.=" $sep"; }
2420 $auto="<span class=\"autocomment\">".$auto."</span>";
2421 $comment=$pre.$auto.$post;
2424 # format regular and media links - all other wiki formatting
2426 while(preg_match("/\[\[(.*?)(\|(.*?))*\]\]/",$comment,$match)) {
2428 $medians = $wgLang->getNsText(Namespace::getMedia());
2430 if(preg_match("/^".$medians."/i",$match[1])) {
2431 $func="makeMediaLink";
2433 if(isset($match[3]) ) {
2435 preg_replace("/\[\[(.*?)\]\]/",
2436 $this->$func($match[1],$match[3]),$comment,1);
2439 preg_replace("/\[\[(.*?)\]\]/",
2440 $this->$func($match[1],$match[1]),$comment,1);
2448 function imageHistoryLine( $iscur, $timestamp, $img, $user, $usertext, $size, $description )
2450 global $wgUser, $wgLang, $wgTitle;
2452 $datetime = $wgLang->timeanddate( $timestamp, true );
2453 $del = wfMsg( "deleteimg" );
2454 $cur = wfMsg( "cur" );
2457 $url = Image
::wfImageUrl( $img );
2459 if ( $wgUser->isSysop() ) {
2460 $link = $wgTitle->escapeLocalURL( "image=" . $wgTitle->getPartialURL() .
2462 $style = $this->getInternalLinkAttributes( $link, $del );
2464 $dlink = "<a href=\"{$link}\"{$style}>{$del}</a>";
2469 $url = wfEscapeHTML( wfImageArchiveUrl( $img ) );
2470 if( $wgUser->getID() != 0 ) {
2471 $rlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2472 wfMsg( "revertimg" ), "action=revert&oldimage=" .
2473 urlencode( $img ) );
2474 $dlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2475 $del, "action=delete&oldimage=" . urlencode( $img ) );
2477 # Having live active links for non-logged in users
2478 # means that bots and spiders crawling our site can
2479 # inadvertently change content. Baaaad idea.
2480 $rlink = wfMsg( "revertimg" );
2485 $userlink = $usertext;
2487 $userlink = $this->makeLink( $wgLang->getNsText( Namespace::getUser() ) .
2488 ":{$usertext}", $usertext );
2490 $nbytes = wfMsg( "nbytes", $size );
2491 $style = $this->getInternalLinkAttributes( $url, $datetime );
2493 $s = "<li> ({$dlink}) ({$rlink}) <a href=\"{$url}\"{$style}>{$datetime}</a>"
2494 . " . . {$userlink} ({$nbytes})";
2496 if ( "" != $description && "*" != $description ) {
2497 $sk=$wgUser->getSkin();
2498 $s .= $wgLang->emphasize(" (" . $sk->formatComment($description) . ")");
2504 function tocIndent($level) {
2505 return str_repeat( "<div class='tocindent'>\n", $level>0 ?
$level : 0 );
2508 function tocUnindent($level) {
2509 return str_repeat( "</div>\n", $level>0 ?
$level : 0 );
2512 # parameter level defines if we are on an indentation level
2513 function tocLine( $anchor, $tocline, $level ) {
2514 $link = "<a href=\"#$anchor\">$tocline</a><br />";
2518 return "<div class='tocline'>$link</div>\n";
2523 function tocTable($toc) {
2524 # note to CSS fanatics: putting this in a div does not work -- div won't auto-expand
2525 # try min-width & co when somebody gets a chance
2526 $hideline = " <script type='text/javascript'>showTocToggle(\"" . addslashes( wfMsg("showtoc") ) . "\",\"" . addslashes( wfMsg("hidetoc") ) . "\")</script>";
2528 "<table border=\"0\" id=\"toc\"><tr><td align=\"center\">\n".
2529 "<b>".wfMsg("toc")."</b>" .
2531 "</td></tr><tr id='tocinside'><td>\n".
2532 $toc."</td></tr></table>\n";
2535 # These two do not check for permissions: check $wgTitle->userCanEdit before calling them
2536 function editSectionScript( $section, $head ) {
2537 global $wgTitle, $wgRequest;
2538 if( $wgRequest->getInt( "oldid" ) && ( $wgRequest->getVal( "diff" ) != "0" ) ) {
2541 $url = $wgTitle->escapeLocalURL( "action=edit§ion=$section" );
2542 return "<span oncontextmenu='document.location=\"$url\";return false;'>{$head}</span>";
2545 function editSectionLink( $section ) {
2547 global $wgTitle, $wgUser, $wgLang;
2549 if( $wgRequest->getInt( "oldid" ) && ( $wgRequest->getVal( "diff" ) != "0" ) ) {
2550 # Section edit links would be out of sync on an old page.
2551 # But, if we're diffing to the current page, they'll be
2556 $editurl = "§ion={$section}";
2557 $url = $this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg("editsection"),"action=edit".$editurl);
2559 if( $wgLang->isRTL() ) {
2561 $nearside = "right";
2566 return "<div class=\"editsection\" style=\"float:$farside;margin-$nearside:5px;\">[".$url."]</div>";
2570 // This function is called by EditPage.php and shows a bulletin board style
2571 // toolbar for common editing functions. It can be disabled in the user preferences.
2572 // The necsesary JavaScript code can be found in style/wikibits.js.
2573 function getEditToolbar() {
2574 global $wgStylePath, $wgLang, $wgMimeType;
2576 // toolarray an array of arrays which each include the filename of
2577 // the button image (without path), the opening tag, the closing tag,
2578 // and optionally a sample text that is inserted between the two when no
2579 // selection is highlighted.
2580 // The tip text is shown when the user moves the mouse over the button.
2582 // Already here are accesskeys (key), which are not used yet until someone
2583 // can figure out a way to make them work in IE. However, we should make
2584 // sure these keys are not defined on the edit page.
2586 array( "image"=>"button_bold.png",
2589 "sample"=>wfMsg("bold_sample"),
2590 "tip"=>wfMsg("bold_tip"),
2593 array( "image"=>"button_italic.png",
2596 "sample"=>wfMsg("italic_sample"),
2597 "tip"=>wfMsg("italic_tip"),
2600 array( "image"=>"button_link.png",
2603 "sample"=>wfMsg("link_sample"),
2604 "tip"=>wfMsg("link_tip"),
2607 array( "image"=>"button_extlink.png",
2610 "sample"=>wfMsg("extlink_sample"),
2611 "tip"=>wfMsg("extlink_tip"),
2614 array( "image"=>"button_headline.png",
2617 "sample"=>wfMsg("headline_sample"),
2618 "tip"=>wfMsg("headline_tip"),
2621 array( "image"=>"button_image.png",
2622 "open"=>"[[".$wgLang->getNsText(NS_IMAGE
).":",
2624 "sample"=>wfMsg("image_sample"),
2625 "tip"=>wfMsg("image_tip"),
2628 array( "image"=>"button_media.png",
2629 "open"=>"[[".$wgLang->getNsText(NS_MEDIA
).":",
2631 "sample"=>wfMsg("media_sample"),
2632 "tip"=>wfMsg("media_tip"),
2635 array( "image"=>"button_math.png",
2636 "open"=>"\\<math\\>",
2637 "close"=>"\\</math\\>",
2638 "sample"=>wfMsg("math_sample"),
2639 "tip"=>wfMsg("math_tip"),
2642 array( "image"=>"button_nowiki.png",
2643 "open"=>"\\<nowiki\\>",
2644 "close"=>"\\</nowiki\\>",
2645 "sample"=>wfMsg("nowiki_sample"),
2646 "tip"=>wfMsg("nowiki_tip"),
2649 array( "image"=>"button_sig.png",
2653 "tip"=>wfMsg("sig_tip"),
2656 array( "image"=>"button_hr.png",
2657 "open"=>"\\n----\\n",
2660 "tip"=>wfMsg("hr_tip"),
2664 $toolbar ="<script type='text/javascript'>\n/*<![CDATA[*/\n";
2666 $toolbar.="document.writeln(\"<div id='toolbar'>\");\n";
2667 foreach($toolarray as $tool) {
2669 $image=$wgStylePath."/images/".$tool["image"];
2670 $open=$tool["open"];
2671 $close=$tool["close"];
2672 $sample = addslashes( $tool["sample"] );
2674 // Note that we use the tip both for the ALT tag and the TITLE tag of the image.
2675 // Older browsers show a "speedtip" type message only for ALT.
2676 // Ideally these should be different, realistically they
2677 // probably don't need to be.
2678 $tip = addslashes( $tool["tip"] );
2680 #$key = $tool["key"];
2682 $toolbar.="addButton('$image','$tip','$open','$close','$sample');\n";
2685 $toolbar.="addInfobox('" . addslashes( wfMsg( "infobox" ) ) . "','" . addslashes(wfMsg("infobox_alert")) . "');\n";
2686 $toolbar.="document.writeln(\"</div>\");\n";
2688 $toolbar.="/*]]>*/\n</script>";
2694 require_once( "SkinStandard.php" );
2695 require_once( "SkinNostalgia.php" );
2696 require_once( "SkinCologneBlue.php" );
2698 if( $wgUsePHPTal ) {
2699 require_once( "SkinPHPTal.php" );