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;
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 $s .= $this->doGetUserStyles();
172 function doGetUserStyles()
177 if ( 1 == $wgUser->getOption( "underline" ) ) {
178 # Don't override browser settings
183 "text-decoration: none; }\n";
185 if ( 1 == $wgUser->getOption( "highlightbroken" ) ) {
186 $s .= "a.new, #quickbar a.new { color: #CC2200; }\n";
188 if ( 1 == $wgUser->getOption( "justify" ) ) {
189 $s .= "#article { text-align: justify; }\n";
194 function getBodyOptions()
196 global $wgUser, $wgTitle, $wgNamespaceBackgrounds, $wgOut, $wgRequest;
198 extract( $wgRequest->getValues( 'oldid', 'redirect', 'diff', 'section','sectiontitle') );
199 $collapse=$wgOut->getCollapse();
201 if ( 0 != $wgTitle->getNamespace() ) {
202 $a = array( "bgcolor" => "#ffffec" );
204 else $a = array( "bgcolor" => "#FFFFFF" );
205 if($wgOut->isArticle() && $wgUser->getOption("editondblclick")) {
206 $s = $this->editThisPage(false);
207 $s = "document.location = \"" .$s ."\";";
208 $a +
= array ("ondblclick" => $s);
210 $a['onload'] = $wgOut->getOnloadHandler();
214 function getExternalLinkAttributes( $link, $text )
216 global $wgUser, $wgOut, $wgLang;
218 $link = urldecode( $link );
219 $link = $wgLang->checkTitleEncoding( $link );
220 $link = str_replace( "_", " ", $link );
221 $link = wfEscapeHTML( $link );
223 $r = " class='external'";
225 if ( 1 == $wgUser->getOption( "hover" ) ) {
226 $r .= " title=\"{$link}\"";
231 function getInternalLinkAttributes( $link, $text, $broken = false )
233 global $wgUser, $wgOut;
235 $link = urldecode( $link );
236 $link = str_replace( "_", " ", $link );
237 $link = wfEscapeHTML( $link );
239 if ( $broken == "stub" ) {
240 $r = " class='stub'";
241 } else if ( $broken == "yes" ) {
247 if ( 1 == $wgUser->getOption( "hover" ) ) {
248 $r .= " title=\"{$link}\"";
253 function getInternalLinkAttributesObj( &$nt, $text, $broken = false )
255 global $wgUser, $wgOut;
257 if ( $broken == "stub" ) {
258 $r = " class='stub'";
259 } else if ( $broken == "yes" ) {
265 if ( 1 == $wgUser->getOption( "hover" ) ) {
266 $r .= ' title ="' . $nt->getEscapedText() . '"';
277 # This will be called immediately after the <body> tag. Split into
278 # two functions to make it easier to subclass.
280 function beforeContent()
282 global $wgUser, $wgOut, $wgSiteNotice;
284 if( $wgSiteNotice ) {
285 $note = "\n<div id='notice' style='font-weight: bold; color: red; text-align: center'>$wgSiteNotice</div>\n";
289 return $this->doBeforeContent() . $note;
292 function doBeforeContent()
294 global $wgUser, $wgOut, $wgTitle, $wgLang;
295 $fname = "Skin::doBeforeContent";
296 wfProfileIn( $fname );
299 $qb = $this->qbSetting();
301 if( $langlinks = $this->otherLanguages() ) {
307 $borderhack = "class='top'";
310 $s .= "\n<div id='content'>\n<div id='topbar'>\n" .
311 "<table border='0' cellspacing='0' width='98%'>\n<tr>\n";
314 $left = ($qb == 1 ||
$qb == 3);
315 if($wgLang->isRTL()) $left = !$left;
318 $s .= "<td class='top' align='left' valign='top' rowspan='{$rows}'>\n" .
319 $this->logoText() . "</td>";
321 $s .= $this->getQuickbarCompensator( $rows );
323 $l = $wgLang->isRTL() ?
"right" : "left";
324 $s .= "<td {$borderhack} align='$l' valign='top'>\n";
326 $s .= $this->topLinks() ;
327 $s .= "<p class='subtitle'>" . $this->pageTitleLinks() . "</p>\n";
329 $r = $wgLang->isRTL() ?
"left" : "right";
330 $s .= "</td>\n<td {$borderhack} valign='top' align='$r' nowrap='nowrap'>";
331 $s .= $this->nameAndLogin();
332 $s .= "\n<br />" . $this->searchForm() . "</td>";
335 $s .= "</tr>\n<tr>\n<td class='top' colspan=\"2\">$langlinks</td>\n";
338 if ( $shove && !$left ) { # Right
339 $s .= $this->getQuickbarCompensator( $rows );
341 $s .= "</tr>\n</table>\n</div>\n";
342 $s .= "\n<div id='article'>\n";
344 $s .= $this->pageTitle();
345 $s .= $this->pageSubtitle() ;
346 $s .= $this->getCategories();
347 wfProfileOut( $fname );
351 function getCategories () {
352 global $wgOut, $wgTitle, $wgUser, $wgParser;
353 global $wgUseCategoryMagic;
354 if( !$wgUseCategoryMagic ) return "" ;
355 if( count( $wgOut->mCategoryLinks
) == 0 ) return "";
356 if( !$wgOut->isArticle() ) return "";
358 $t = implode ( " | " , $wgOut->mCategoryLinks
) ;
359 $s = $this->makeKnownLink( "Special:Categories",
360 wfMsg( "categories" ), "article=" . urlencode( $wgTitle->getPrefixedDBkey() ) )
362 return "<p class='catlinks'>$s</p>";
365 function getQuickbarCompensator( $rows = 1 )
367 return "<td width='152' rowspan='{$rows}'> </td>";
370 # This gets called immediately before the </body> tag.
372 function afterContent()
374 global $wgUser, $wgOut, $wgServer;
375 global $wgTitle, $wgLang;
377 $printfooter = "<div class=\"printfooter\">\n" . $this->printFooter() . "</div>\n";
378 return $printfooter . $this->doAfterContent();
381 function printFooter() {
383 $url = htmlspecialchars( $wgTitle->getFullURL() );
384 return "<p>" . wfMsg( "retrievedfrom", "<a href=\"$url\">$url</a>" ) .
385 "</p>\n\n<p>" . $this->pageStats() . "</p>\n";
388 function doAfterContent()
390 global $wgUser, $wgOut, $wgLang;
391 $fname = "Skin::doAfterContent";
392 wfProfileIn( $fname );
393 wfProfileIn( "$fname-1" );
395 $s = "\n</div><br clear='all' />\n";
396 $s .= "\n<div id='footer'>";
397 $s .= "<table border='0' cellspacing='0'><tr>";
399 wfProfileOut( "$fname-1" );
400 wfProfileIn( "$fname-2" );
402 $qb = $this->qbSetting();
404 $left = ($qb == 1 ||
$qb == 3);
405 if($wgLang->isRTL()) $left = !$left;
407 if ( $shove && $left ) { # Left
408 $s .= $this->getQuickbarCompensator();
410 wfProfileOut( "$fname-2" );
411 wfProfileIn( "$fname-3" );
412 $l = $wgLang->isRTL() ?
"right" : "left";
413 $s .= "<td class='bottom' align='$l' valign='top'>";
415 $s .= $this->bottomLinks();
416 $s .= "\n<br />" . $this->mainPageLink()
417 . " | " . $this->aboutLink()
418 . " | " . $this->specialLink( "recentchanges" )
419 . " | " . $this->searchForm()
420 . "<br /><span id='pagestats'>" . $this->pageStats() . "</span>";
423 if ( $shove && !$left ) { # Right
424 $s .= $this->getQuickbarCompensator();
426 $s .= "</tr></table>\n</div>\n</div>\n";
428 wfProfileOut( "$fname-3" );
429 wfProfileIn( "$fname-4" );
430 if ( 0 != $qb ) { $s .= $this->quickBar(); }
431 wfProfileOut( "$fname-4" );
432 wfProfileOut( $fname );
436 function pageTitleLinks()
438 global $wgOut, $wgTitle, $wgUser, $wgLang, $wgUseApproval, $wgRequest;
440 extract( $wgRequest->getValues( 'oldid', 'diff' ) );
441 $action = $wgRequest->getText( 'action' );
443 $s = $this->printableLink();
444 if ( wfMsg ( "disclaimers" ) != "-" ) $s .= " | " . $this->makeKnownLink( wfMsg( "disclaimerpage" ), wfMsg( "disclaimers" ) ) ;
446 if ( $wgOut->isArticleRelated() ) {
447 if ( $wgTitle->getNamespace() == Namespace::getImage() ) {
448 $name = $wgTitle->getDBkey();
449 $link = wfEscapeHTML( Image
::wfImageUrl( $name ) );
450 $style = $this->getInternalLinkAttributes( $link, $name );
451 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>";
453 # This will show the "Approve" link if $wgUseApproval=true;
454 if ( isset ( $wgUseApproval ) && $wgUseApproval )
456 $t = $wgTitle->getDBkey();
457 $name = "Approve this article" ;
458 $link = "http://test.wikipedia.org/w/magnus/wiki.phtml?title={$t}&action=submit&doit=1" ;
459 #wfEscapeHTML( wfImageUrl( $name ) );
460 $style = $this->getExternalLinkAttributes( $link, $name );
461 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>" ;
464 if ( "history" == $action ||
isset( $diff ) ||
isset( $oldid ) ) {
465 $s .= " | " . $this->makeKnownLink( $wgTitle->getPrefixedText(),
466 wfMsg( "currentrev" ) );
469 if ( $wgUser->getNewtalk() ) {
470 # do not show "You have new messages" text when we are viewing our
473 if(!(strcmp($wgTitle->getText(),$wgUser->getName()) == 0 &&
474 $wgTitle->getNamespace()==Namespace::getTalk(Namespace::getUser()))) {
475 $n =$wgUser->getName();
476 $tl = $this->makeKnownLink( $wgLang->getNsText(
477 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
478 wfMsg("newmessageslink") );
479 $s.=" | <strong>". wfMsg( "newmessages", $tl ) . "</strong>";
482 if( $wgUser->isSysop() &&
483 (($wgTitle->getArticleId() == 0) ||
($action == "history")) &&
484 ($n = $wgTitle->isDeleted() ) ) {
485 $s .= " | " . wfMsg( "thisisdeleted",
486 $this->makeKnownLink(
487 $wgLang->SpecialPage( "Undelete/" . $wgTitle->getPrefixedDBkey() ),
488 wfMsg( "restorelink", $n ) ) );
493 function printableLink()
495 global $wgOut, $wgFeedClasses, $wgRequest;
497 $baseurl = $_SERVER['REQUEST_URI'];
498 if( strpos( "?", $baseurl ) == false ) {
503 $baseurl = htmlspecialchars( $baseurl );
504 $printurl = $wgRequest->escapeAppendQuery( "printable=yes" );
506 $s = "<a href=\"$printurl\">" . wfMsg( "printableversion" ) . "</a>";
507 if( $wgOut->isSyndicated() ) {
508 foreach( $wgFeedClasses as $format => $class ) {
509 $feedurl = $wgRequest->escapeAppendQuery( "feed=$format" );
510 $s .= " | <a href=\"$feedurl\">{$format}</a>";
518 global $wgOut, $wgTitle, $wgUser, $wgRequest;
519 $section=$wgRequest->getVal('section');
520 $action=$wgRequest->getVal('action');
522 if ($section && $action=="view") {
523 $link= $this->makeLink( $wgTitle->getPrefixedText(), htmlspecialchars($wgOut->getPageTitle()) );
524 $s = "<h1 class='pagetitle'>" . $link . " " . wfMsg("sectionedit")."</h1>";
527 $s = "<h1 class='pagetitle'>" . htmlspecialchars( $wgOut->getPageTitle() ) . "</h1>";
529 if($wgUser->getOption("editsectiononrightclick") && $wgTitle->userCanEdit()) { $s=$this->editSectionScript(0,$s);}
533 function pageSubtitle()
537 $sub = $wgOut->getSubtitle();
539 global $wgExtraSubtitle;
540 $sub = wfMsg( "fromwikipedia" ) . $wgExtraSubtitle;
542 $subpages = $this->subPageSubtitle();
543 $sub .= !empty($subpages)?
"</p><p class='subpages'>$subpages":'';
544 $s = "<p class='subtitle'>{$sub}</p>\n";
548 function subPageSubtitle()
550 global $wgOut,$wgTitle,$wgNamespacesWithSubpages;
552 if($wgOut->isArticle() && !empty($wgNamespacesWithSubpages[$wgTitle->getNamespace()])) {
553 $ptext=$wgTitle->getPrefixedText();
554 if(preg_match("/\//",$ptext)) {
555 $links=explode("/",$ptext);
558 foreach($links as $link) {
560 if ($c<count($links)) {
561 $growinglink .= $link;
562 $getlink = $this->makeLink( $growinglink, $link );
563 if(preg_match("/class='new'/i",$getlink)) { break; } # this is a hack, but it saves time
569 $subpages .= $getlink;
578 function nameAndLogin()
580 global $wgUser, $wgTitle, $wgLang, $wgShowIPinHeader, $wgIP;
582 $li = $wgLang->specialPage( "Userlogin" );
583 $lo = $wgLang->specialPage( "Userlogout" );
586 if ( 0 == $wgUser->getID() ) {
587 if( $wgShowIPinHeader && isset( $_COOKIE[ini_get("session.name")] ) ) {
590 $tl = $this->makeKnownLink( $wgLang->getNsText(
591 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
592 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
594 $s .= $n . " (".$tl.")";
596 $s .= wfMsg("notloggedin");
599 $rt = $wgTitle->getPrefixedURL();
600 if ( 0 == strcasecmp( urlencode( $lo ), $rt ) ) {
602 } else { $q = "returnto={$rt}"; }
604 $s .= "\n<br />" . $this->makeKnownLink( $li,
605 wfMsg( "login" ), $q );
607 $n = $wgUser->getName();
608 $rt = $wgTitle->getPrefixedURL();
609 $tl = $this->makeKnownLink( $wgLang->getNsText(
610 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
611 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
615 $s .= $this->makeKnownLink( $wgLang->getNsText(
616 Namespace::getUser() ) . ":{$n}", $n ) . "{$tl}<br />" .
617 $this->makeKnownLink( $lo, wfMsg( "logout" ),
618 "returnto={$rt}" ) . " | " .
619 $this->specialLink( "preferences" );
621 $s .= " | " . $this->makeKnownLink( wfMsg( "helppage" ),
627 function getSearchLink() {
628 $searchPage =& Title
::makeTitle( NS_SPECIAL
, "Search" );
629 return $searchPage->getLocalURL();
632 function escapeSearchLink() {
633 return htmlspecialchars( $this->getSearchLink() );
636 function searchForm()
639 $search = $wgRequest->getText( 'search' );
641 $s = "<form name='search' class='inline' method='post' action=\""
642 . $this->escapeSearchLink() . "\">\n"
643 . "<input type='text' name=\"search\" size='19' value=\""
644 . htmlspecialchars(substr($search,0,256)) . "\" />\n"
645 . "<input type='submit' name=\"go\" value=\"" . wfMsg ("go") . "\" /> "
646 . "<input type='submit' name=\"fulltext\" value=\"" . wfMsg ("search") . "\" />\n</form>";
656 $s = $this->mainPageLink() . $sep
657 . $this->specialLink( "recentchanges" );
659 if ( $wgOut->isArticleRelated() ) {
660 $s .= $sep . $this->editThisPage()
661 . $sep . $this->historyLink();
663 # Many people don't like this dropdown box
664 #$s .= $sep . $this->specialPagesList();
669 function bottomLinks()
671 global $wgOut, $wgUser, $wgTitle;
675 if ( $wgOut->isArticleRelated() ) {
676 $s .= "<strong>" . $this->editThisPage() . "</strong>";
677 if ( 0 != $wgUser->getID() ) {
678 $s .= $sep . $this->watchThisPage();
680 $s .= $sep . $this->talkLink()
681 . $sep . $this->historyLink()
682 . $sep . $this->whatLinksHere()
683 . $sep . $this->watchPageLinksLink();
685 if ( $wgTitle->getNamespace() == Namespace::getUser()
686 ||
$wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser()) )
689 $id=User
::idFromName($wgTitle->getText());
690 $ip=User
::isIP($wgTitle->getText());
692 if($id ||
$ip) { # both anons and non-anons have contri list
693 $s .= $sep . $this->userContribsLink();
695 if ( 0 != $wgUser->getID() ) { # show only to signed in users
696 if($id) { # can only email non-anons
697 $s .= $sep . $this->emailUserLink();
701 if ( $wgUser->isSysop() && $wgTitle->getArticleId() ) {
702 $s .= "\n<br />" . $this->deleteThisPage() .
703 $sep . $this->protectThisPage() .
704 $sep . $this->moveThisPage();
706 $s .= "<br />\n" . $this->otherLanguages();
713 global $wgOut, $wgLang, $wgArticle, $wgRequest;
714 global $wgDisableCounters;
716 extract( $wgRequest->getValues( 'oldid', 'diff' ) );
717 if ( ! $wgOut->isArticle() ) { return ""; }
718 if ( isset( $oldid ) ||
isset( $diff ) ) { return ""; }
719 if ( 0 == $wgArticle->getID() ) { return ""; }
722 if ( !$wgDisableCounters ) {
723 $count = $wgLang->formatNum( $wgArticle->getCount() );
725 $s = wfMsg( "viewcount", $count );
729 $s .= " " . $this->getCredits();
731 return $s . " " . $this->getCopyright();
734 function getCredits() {
735 global $wgMaxCredits;
739 if (!isset($wgMaxCredits) ||
$wgMaxCredits == 0) {
740 $s = $this->lastModified();
742 $s = $this->getAuthorCredits();
743 if ($wgMaxCredits > 1) {
744 $s .= " " . $this->getContributorCredits();
751 function getAuthorCredits() {
752 global $wgLang, $wgArticle;
754 $last_author = $wgArticle->getUser();
756 if ($last_author == 0) {
757 $author_credit = wfMsg("anonymous");
759 $real_name = User
::whoIsReal($last_author);
760 if (!empty($real_name)) {
761 $author_credit = $real_name;
763 $author_credit = wfMsg("siteuser", User
::whoIs($last_author));
767 $timestamp = $wgArticle->getTimestamp();
769 $d = $wgLang->timeanddate( $wgArticle->getTimestamp(), true );
773 return wfMsg("lastmodifiedby", $d, $author_credit);
776 function getContributorCredits() {
778 global $wgArticle, $wgMaxCredits, $wgLang;
780 # don't count last editor
782 $contributors = $wgArticle->getContributors($wgMaxCredits - 1);
784 $real_names = array();
785 $user_names = array();
787 # Sift for real versus user names
789 foreach ($contributors as $user_id => $user_parts) {
791 if (!empty($user_parts[1])) {
792 $real_names[$user_id] = $user_parts[1];
794 $user_names[$user_id] = $user_parts[0];
799 $real = $wgLang->listToText(array_values($real_names));
800 $user = $wgLang->listToText(array_values($user_names));
803 $user = wfMsg("siteusers", $user);
806 if ($contributors[0] && $contributors[0][0] > 0) {
807 $anon = wfMsg("anonymous");
812 $creds = $wgLang->listToText(array($real, $user, $anon));
814 return wfMsg("othercontribs", $creds);
817 function getCopyright() {
818 global $wgRightsPage, $wgRightsUrl, $wgRightsText;
820 if( $wgRightsPage ) {
821 $link = $this->makeKnownLink( $wgRightsPage, $wgRightsText );
822 } elseif( $wgRightsUrl ) {
823 $link = $this->makeExternalLink( $wgRightsUrl, $wgRightsText );
828 $out .= wfMsg( "copyright", $link );
832 function getCopyrightIcon() {
833 global $wgRightsPage, $wgRightsUrl, $wgRightsText, $wgRightsIcon;
835 if( $wgRightsIcon ) {
836 $icon = htmlspecialchars( $wgRightsIcon );
838 $url = htmlspecialchars( $wgRightsUrl );
839 $out .= "<a href=\"$url\">";
841 $text = htmlspecialchars( $wgRightsText );
842 $out .= "<img src=\"$icon\" alt='$text' />";
850 function getPoweredBy() {
852 $url = htmlspecialchars( "$wgStylePath/images/poweredby_mediawiki_88x31.png" );
853 $img = "<a href='http://www.mediawiki.org/'><img src='$url' alt='MediaWiki' /></a>";
857 function lastModified()
859 global $wgLang, $wgArticle;
861 $timestamp = $wgArticle->getTimestamp();
863 $d = $wgLang->timeanddate( $wgArticle->getTimestamp(), true );
864 $s = " " . wfMsg( "lastmodified", $d );
871 function logoText( $align = "" )
873 if ( "" != $align ) { $a = " align='{$align}'"; }
876 $mp = wfMsg( "mainpage" );
877 $titleObj = Title
::newFromText( $mp );
878 $s = "<a href=\"" . $titleObj->escapeLocalURL()
879 . "\"><img{$a} src=\""
880 . $this->getLogo() . "\" alt=\"" . "[{$mp}]\" /></a>";
886 global $wgOut, $wgTitle, $wgUser, $wgRequest, $wgLang;
887 global $wgDisableUploads, $wgRemoteUploads;
889 $fname = "Skin::quickBar";
890 wfProfileIn( $fname );
892 $action = $wgRequest->getText( 'action' );
893 $wpPreview = $wgRequest->getBool( 'wpPreview' );
894 $tns=$wgTitle->getNamespace();
896 $s = "\n<div id='quickbar'>";
897 $s .= "\n" . $this->logoText() . "\n<hr class='sep' />";
900 $s .= $this->mainPageLink()
901 . $sep . $this->specialLink( "recentchanges" )
902 . $sep . $this->specialLink( "randompage" );
903 if ($wgUser->getID()) {
904 $s.= $sep . $this->specialLink( "watchlist" ) ;
905 $s .= $sep .$this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
906 wfMsg( "mycontris" ), "target=" . wfUrlencode($wgUser->getName() ) );
909 // only show watchlist link if logged in
910 if ( wfMsg ( "currentevents" ) != "-" ) $s .= $sep . $this->makeKnownLink( wfMsg( "currentevents" ), "" ) ;
911 $s .= "\n<br /><hr class='sep' />";
912 $articleExists = $wgTitle->getArticleId();
913 if ( $wgOut->isArticle() ||
$action =="edit" ||
$action =="history" ||
$wpPreview) {
914 if($wgOut->isArticle()) {
915 $s .= "<strong>" . $this->editThisPage() . "</strong>";
916 } else { # backlink to the article in edit or history mode
917 if($articleExists){ # no backlink if no article
920 $text = wfMsg("articlepage");
923 $text = wfMsg("viewtalkpage");
926 $text = wfMsg("userpage");
929 $text = wfMsg("viewtalkpage");
932 $text = wfMsg("wikipediapage");
935 $text = wfMsg("viewtalkpage");
938 $text = wfMsg("imagepage");
941 $text = wfMsg("viewtalkpage");
944 $text= wfMsg("articlepage");
947 $link = $wgTitle->getText();
948 if ($nstext = $wgLang->getNsText($tns) ) { # add namespace if necessary
949 $link = $nstext . ":" . $link ;
952 $s .= $this->makeLink( $link, $text );
953 } elseif( $wgTitle->getNamespace() != Namespace::getSpecial() ) {
954 # we just throw in a "New page" text to tell the user that he's in edit mode,
955 # and to avoid messing with the separator that is prepended to the next item
956 $s .= "<strong>" . wfMsg("newpage") . "</strong>";
962 if( $tns%2
&& $action!="edit" && !$wpPreview) {
963 $s.="<br />".$this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg("postcomment"),"action=edit§ion=new");
967 watching could cause problems in edit mode:
968 if user edits article, then loads "watch this article" in background and then saves
969 article with "Watch this article" checkbox disabled, the article is transparently
970 unwatched. Therefore we do not show the "Watch this page" link in edit mode
972 if ( 0 != $wgUser->getID() && $articleExists) {
973 if($action!="edit" && $action != "submit" )
975 $s .= $sep . $this->watchThisPage();
977 if ( $wgTitle->userCanEdit() )
978 $s .= $sep . $this->moveThisPage();
980 if ( $wgUser->isSysop() and $articleExists ) {
981 $s .= $sep . $this->deleteThisPage() .
982 $sep . $this->protectThisPage();
984 $s .= $sep . $this->talkLink();
985 if ($articleExists && $action !="history") {
986 $s .= $sep . $this->historyLink();
988 $s.=$sep . $this->whatLinksHere();
990 if($wgOut->isArticleRelated()) {
991 $s .= $sep . $this->watchPageLinksLink();
994 if ( Namespace::getUser() == $wgTitle->getNamespace()
995 ||
$wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser())
998 $id=User
::idFromName($wgTitle->getText());
999 $ip=User
::isIP($wgTitle->getText());
1002 $s .= $sep . $this->userContribsLink();
1004 if ( 0 != $wgUser->getID() ) {
1005 if($id) { # can only email real users
1006 $s .= $sep . $this->emailUserLink();
1010 $s .= "\n<br /><hr class='sep' />";
1013 if ( 0 != $wgUser->getID() && ( !$wgDisableUploads ||
$wgRemoteUploads ) ) {
1014 $s .= $this->specialLink( "upload" ) . $sep;
1016 $s .= $this->specialLink( "specialpages" )
1017 . $sep . $this->bugReportsLink();
1019 global $wgSiteSupportPage;
1020 if( $wgSiteSupportPage ) {
1021 $s .= "\n<br /><a href=\"" . htmlspecialchars( $wgSiteSupportPage ) .
1022 "\" class=\"internal\">" . wfMsg( "sitesupport" ) . "</a>";
1025 $s .= "\n<br /></div>\n";
1026 wfProfileOut( $fname );
1030 function specialPagesList()
1032 global $wgUser, $wgOut, $wgLang, $wgServer, $wgRedirectScript;
1035 $validSP = $wgLang->getValidSpecialPages();
1037 foreach ( $validSP as $name => $desc ) {
1038 if ( "" == $desc ) { continue; }
1041 if ( $wgUser->isSysop() )
1043 $sysopSP = $wgLang->getSysopSpecialPages();
1045 foreach ( $sysopSP as $name => $desc ) {
1046 if ( "" == $desc ) { continue; }
1050 if ( $wgUser->isDeveloper() )
1052 $devSP = $wgLang->getDeveloperSpecialPages();
1054 foreach ( $devSP as $name => $desc ) {
1055 if ( "" == $desc ) { continue; }
1059 $go = wfMsg( "go" );
1060 $sp = wfMsg( "specialpages" );
1061 $spp = $wgLang->specialPage( "Specialpages" );
1063 $s = "<form id=\"specialpages\" method=\"get\" class=\"inline\" " .
1064 "action=\"" . htmlspecialchars( "{$wgServer}{$wgRedirectScript}" ) . "\">\n";
1065 $s .= "<select name=\"wpDropdown\">\n";
1066 $s .= "<option value=\"{$spp}\">{$sp}</option>\n";
1068 foreach ( $a as $name => $desc ) {
1069 $p = $wgLang->specialPage( $name );
1070 $s .= "<option value=\"{$p}\">{$desc}</option>\n";
1072 $s .= "</select>\n";
1073 $s .= "<input type='submit' value=\"{$go}\" name='redirect' />\n";
1078 function mainPageLink()
1080 $mp = wfMsg( "mainpage" );
1081 $s = $this->makeKnownLink( $mp, $mp );
1085 function copyrightLink()
1087 $s = $this->makeKnownLink( wfMsg( "copyrightpage" ),
1088 wfMsg( "copyrightpagename" ) );
1092 function aboutLink()
1094 $s = $this->makeKnownLink( wfMsg( "aboutpage" ),
1095 wfMsg( "aboutwikipedia" ) );
1100 function disclaimerLink()
1102 $s = $this->makeKnownLink( wfMsg( "disclaimerpage" ),
1103 wfMsg( "disclaimers" ) );
1107 # if makeLink is false, just return the edit URL
1108 function editThisPage($makeLink=true)
1110 global $wgOut, $wgTitle, $wgRequest;
1112 $oldid = $wgRequest->getVal( 'oldid' );
1113 $diff = $wgRequest->getVal( 'diff' );
1114 $redirect = $wgRequest->getVal( 'redirect' );
1115 $section = $wgRequest->getVal('section');
1116 $sectiontitle = $wgRequest->getVal('sectiontitle');
1117 $collapse = $wgOut->getCollapse();
1119 if ( ! $wgOut->isArticleRelated() && $makeLink) {
1120 $s = wfMsg( "protectedpage" );
1122 $n = $wgTitle->getPrefixedText();
1123 if ( $wgTitle->userCanEdit() ) {
1124 $t = wfMsg( "editthispage" );
1126 #$t = wfMsg( "protectedpage" );
1127 $t = wfMsg( "viewsource" );
1129 $oid = $red = $sid = $stl = "";
1131 if ( !is_null( $redirect ) ) { $red = "&redirect={$redirect}"; }
1132 if ( $oldid && ! isset( $diff ) ) {
1133 $oid = "&oldid={$oldid}";
1135 if ( !empty($section) ) {
1136 $sid = "§ion={$section}";
1138 if ( !empty($sectiontitle) ) {
1139 $stl = "§iontitle={$sectiontitle}";
1141 if ($collapse && !$section) {
1142 $sid = "§ion=0";
1144 $action="action=edit{$oid}{$red}{$sid}{$stl}";
1146 $s = $this->makeKnownLink( $n, $t, $action );
1148 $s = $wgTitle->getFullUrl($action);
1154 function deleteThisPage()
1156 global $wgUser, $wgOut, $wgTitle, $wgRequest;
1158 $diff = $wgRequest->getVal( 'diff' );
1159 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
1160 $n = $wgTitle->getPrefixedText();
1161 $t = wfMsg( "deletethispage" );
1163 $s = $this->makeKnownLink( $n, $t, "action=delete" );
1170 function protectThisPage()
1172 global $wgUser, $wgOut, $wgTitle, $wgRequest;
1174 $diff = $wgRequest->getVal( 'diff' );
1175 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
1176 $n = $wgTitle->getPrefixedText();
1178 if ( $wgTitle->isProtected() ) {
1179 $t = wfMsg( "unprotectthispage" );
1180 $q = "action=unprotect";
1182 $t = wfMsg( "protectthispage" );
1183 $q = "action=protect";
1185 $s = $this->makeKnownLink( $n, $t, $q );
1192 function watchThisPage()
1194 global $wgUser, $wgOut, $wgTitle;
1196 if ( $wgOut->isArticleRelated() ) {
1197 $n = $wgTitle->getPrefixedText();
1199 if ( $wgTitle->userIsWatching() ) {
1200 $t = wfMsg( "unwatchthispage" );
1201 $q = "action=unwatch";
1203 $t = wfMsg( "watchthispage" );
1204 $q = "action=watch";
1206 $s = $this->makeKnownLink( $n, $t, $q );
1208 $s = wfMsg( "notanarticle" );
1213 function moveThisPage()
1215 global $wgTitle, $wgLang;
1217 if ( $wgTitle->userCanEdit() ) {
1218 $s = $this->makeKnownLink( $wgLang->specialPage( "Movepage" ),
1219 wfMsg( "movethispage" ), "target=" . $wgTitle->getPrefixedURL() );
1220 } // no message if page is protected - would be redundant
1224 function historyLink()
1228 $s = $this->makeKnownLink( $wgTitle->getPrefixedText(),
1229 wfMsg( "history" ), "action=history" );
1233 function whatLinksHere()
1235 global $wgTitle, $wgLang;
1237 $s = $this->makeKnownLink( $wgLang->specialPage( "Whatlinkshere" ),
1238 wfMsg( "whatlinkshere" ), "target=" . $wgTitle->getPrefixedURL() );
1242 function userContribsLink()
1244 global $wgTitle, $wgLang;
1246 $s = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
1247 wfMsg( "contributions" ), "target=" . $wgTitle->getPartialURL() );
1251 function emailUserLink()
1253 global $wgTitle, $wgLang;
1255 $s = $this->makeKnownLink( $wgLang->specialPage( "Emailuser" ),
1256 wfMsg( "emailuser" ), "target=" . $wgTitle->getPartialURL() );
1260 function watchPageLinksLink()
1262 global $wgOut, $wgTitle, $wgLang;
1264 if ( ! $wgOut->isArticleRelated() ) {
1265 $s = "(" . wfMsg( "notanarticle" ) . ")";
1267 $s = $this->makeKnownLink( $wgLang->specialPage(
1268 "Recentchangeslinked" ), wfMsg( "recentchangeslinked" ),
1269 "target=" . $wgTitle->getPrefixedURL() );
1274 function otherLanguages()
1276 global $wgOut, $wgLang, $wgTitle, $wgUseNewInterlanguage;
1278 $a = $wgOut->getLanguageLinks();
1279 if ( 0 == count( $a ) ) {
1280 if ( !$wgUseNewInterlanguage ) return "";
1281 $ns = $wgLang->getNsIndex ( $wgTitle->getNamespace () ) ;
1282 if ( $ns != 0 AND $ns != 1 ) return "" ;
1284 $x = "mode=addlink&xt=".$wgTitle->getDBkey() ;
1285 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1286 wfMsg( "intl" ) , $x );
1289 if ( !$wgUseNewInterlanguage ) {
1290 $s = wfMsg( "otherlanguages" ) . ": ";
1292 global $wgLanguageCode ;
1293 $x = "mode=zoom&xt=".$wgTitle->getDBkey() ;
1294 $x .= "&xl=".$wgLanguageCode ;
1295 $s = $this->makeKnownLink( $wgLang->specialPage( "Intl" ),
1296 wfMsg( "otherlanguages" ) , $x ) . ": " ;
1299 $s = wfMsg( "otherlanguages" ) . ": ";
1301 if($wgLang->isRTL()) $s .= "<span dir='LTR'>";
1302 foreach( $a as $l ) {
1303 if ( ! $first ) { $s .= " | "; }
1306 $nt = Title
::newFromText( $l );
1307 $url = $nt->getFullURL();
1308 $text = $wgLang->getLanguageName( $nt->getInterwiki() );
1310 if ( "" == $text ) { $text = $l; }
1311 $style = $this->getExternalLinkAttributes( $l, $text );
1312 $s .= "<a href=\"{$url}\"{$style}>{$text}</a>";
1314 if($wgLang->isRTL()) $s .= "</span>";
1318 function bugReportsLink()
1320 $s = $this->makeKnownLink( wfMsg( "bugreportspage" ),
1321 wfMsg( "bugreports" ) );
1327 global $wgLinkCache;
1328 $t1 = Title
::newFromText( gmdate( "F j" ) );
1329 $t2 = Title
::newFromText( gmdate( "Y" ) );
1331 $wgLinkCache->suspend();
1332 $id = $t1->getArticleID();
1333 $wgLinkCache->resume();
1336 $s = $this->makeBrokenLink( $t1->getText() );
1338 $s = $this->makeKnownLink( $t1->getText() );
1342 $wgLinkCache->suspend();
1343 $id = $t2->getArticleID();
1344 $wgLinkCache->resume();
1347 $s .= $this->makeBrokenLink( $t2->getText() );
1349 $s .= $this->makeKnownLink( $t2->getText() );
1356 global $wgLang, $wgTitle, $wgLinkCache;
1358 $tns = $wgTitle->getNamespace();
1359 if ( -1 == $tns ) { return ""; }
1361 $pn = $wgTitle->getText();
1362 $tp = wfMsg( "talkpage" );
1363 if ( Namespace::isTalk( $tns ) ) {
1364 $lns = Namespace::getSubject( $tns );
1367 $text = wfMsg("articlepage");
1370 $text = wfMsg("userpage");
1373 $text = wfMsg("wikipediapage");
1376 $text = wfMsg("imagepage");
1379 $text= wfMsg("articlepage");
1383 $lns = Namespace::getTalk( $tns );
1386 $n = $wgLang->getNsText( $lns );
1387 if ( "" == $n ) { $link = $pn; }
1388 else { $link = "{$n}:{$pn}"; }
1390 $wgLinkCache->suspend();
1391 $s = $this->makeLink( $link, $text );
1392 $wgLinkCache->resume();
1397 function commentLink()
1399 global $wgLang, $wgTitle, $wgLinkCache;
1401 $tns = $wgTitle->getNamespace();
1402 if ( -1 == $tns ) { return ""; }
1404 $lns = ( Namespace::isTalk( $tns ) ) ?
$tns : Namespace::getTalk( $tns );
1406 # assert Namespace::isTalk( $lns )
1408 $n = $wgLang->getNsText( $lns );
1409 $pn = $wgTitle->getText();
1411 $link = "{$n}:{$pn}";
1413 $wgLinkCache->suspend();
1414 $s = $this->makeKnownLink($link, wfMsg("postcomment"), "action=edit§ion=new");
1415 $wgLinkCache->resume();
1420 # After all the page content is transformed into HTML, it makes
1421 # a final pass through here for things like table backgrounds.
1423 function transformContent( $text )
1428 # Note: This function MUST call getArticleID() on the link,
1429 # otherwise the cache won't get updated properly. See LINKCACHE.DOC.
1431 function makeLink( $title, $text = "", $query = "", $trail = "" ) {
1432 wfProfileIn( "Skin::makeLink" );
1433 $nt = Title
::newFromText( $title );
1435 $result = $this->makeLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1437 wfDebug( "Invalid title passed to Skin::makeLink(): \"$title\"\n" );
1438 $result = $text == "" ?
$title : $text;
1441 wfProfileOut( "Skin::makeLink" );
1445 function makeKnownLink( $title, $text = "", $query = "", $trail = "", $prefix = '',$aprops = '') {
1446 $nt = Title
::newFromText( $title );
1448 return $this->makeKnownLinkObj( Title
::newFromText( $title ), $text, $query, $trail, $prefix , $aprops );
1450 wfDebug( "Invalid title passed to Skin::makeKnownLink(): \"$title\"\n" );
1451 return $text == "" ?
$title : $text;
1455 function makeBrokenLink( $title, $text = "", $query = "", $trail = "" ) {
1456 $nt = Title
::newFromText( $title );
1458 return $this->makeBrokenLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1460 wfDebug( "Invalid title passed to Skin::makeBrokenLink(): \"$title\"\n" );
1461 return $text == "" ?
$title : $text;
1465 function makeStubLink( $title, $text = "", $query = "", $trail = "" ) {
1466 $nt = Title
::newFromText( $title );
1468 return $this->makeStubLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1470 wfDebug( "Invalid title passed to Skin::makeStubLink(): \"$title\"\n" );
1471 return $text == "" ?
$title : $text;
1475 # Pass a title object, not a title string
1476 function makeLinkObj( &$nt, $text= "", $query = "", $trail = "", $prefix = "" )
1478 global $wgOut, $wgUser;
1479 if ( $nt->isExternal() ) {
1480 $u = $nt->getFullURL();
1481 $link = $nt->getPrefixedURL();
1482 if ( "" == $text ) { $text = $nt->getPrefixedText(); }
1483 $style = $this->getExternalLinkAttributes( $link, $text );
1486 if ( "" != $trail ) {
1487 if ( preg_match( "/^([a-z]+)(.*)$$/sD", $trail, $m ) ) {
1492 $retVal = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1493 } elseif ( 0 == $nt->getNamespace() && "" == $nt->getText() ) {
1494 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1495 } elseif ( ( -1 == $nt->getNamespace() ) ||
1496 ( Namespace::getImage() == $nt->getNamespace() ) ) {
1497 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1499 $aid = $nt->getArticleID() ;
1501 $retVal = $this->makeBrokenLinkObj( $nt, $text, $query, $trail, $prefix );
1503 $threshold = $wgUser->getOption("stubthreshold") ;
1504 if ( $threshold > 0 ) {
1505 $res = wfQuery ( "SELECT LENGTH(cur_text) AS x, cur_namespace, cur_is_redirect FROM cur WHERE cur_id='{$aid}'", DB_READ
) ;
1507 if ( wfNumRows( $res ) > 0 ) {
1508 $s = wfFetchObject( $res );
1510 if ( $s->cur_is_redirect
OR $s->cur_namespace
!= 0 ) {
1511 $size = $threshold*2 ; # Really big
1513 wfFreeResult( $res );
1515 $size = $threshold*2 ; # Really big
1520 if ( $size < $threshold ) {
1521 $retVal = $this->makeStubLinkObj( $nt, $text, $query, $trail, $prefix );
1523 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1530 # Pass a title object, not a title string
1531 function makeKnownLinkObj( &$nt, $text = "", $query = "", $trail = "", $prefix = "" , $aprops = '')
1533 global $wgOut, $wgTitle;
1535 $fname = "Skin::makeKnownLinkObj";
1536 wfProfileIn( $fname );
1538 $link = $nt->getPrefixedURL();
1540 if ( "" == $link ) {
1542 if ( "" == $text ) {
1543 $text = htmlspecialchars( $nt->getFragment() );
1546 $u = $nt->escapeLocalURL( $query );
1548 if ( "" != $nt->getFragment() ) {
1549 $u .= "#" . htmlspecialchars( $nt->getFragment() );
1551 if ( "" == $text ) {
1552 $text = htmlspecialchars( $nt->getPrefixedText() );
1554 $style = $this->getInternalLinkAttributesObj( $nt, $text );
1557 if ( "" != $trail ) {
1558 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1563 $r = "<a href=\"{$u}\"{$style}{$aprops}>{$prefix}{$text}{$inside}</a>{$trail}";
1564 wfProfileOut( $fname );
1568 # Pass a title object, not a title string
1569 function makeBrokenLinkObj( &$nt, $text = "", $query = "", $trail = "", $prefix = "" )
1571 global $wgOut, $wgUser;
1573 $fname = "Skin::makeBrokenLinkObj";
1574 wfProfileIn( $fname );
1576 if ( "" == $query ) {
1579 $q = "action=edit&{$query}";
1581 $u = $nt->escapeLocalURL( $q );
1583 if ( "" == $text ) {
1584 $text = htmlspecialchars( $nt->getPrefixedText() );
1586 $style = $this->getInternalLinkAttributesObj( $nt, $text, "yes" );
1589 if ( "" != $trail ) {
1590 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1595 if ( $wgUser->getOption( "highlightbroken" ) ) {
1596 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1598 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>?</a>{$trail}";
1601 wfProfileOut( $fname );
1605 # Pass a title object, not a title string
1606 function makeStubLinkObj( &$nt, $text = "", $query = "", $trail = "", $prefix = "" )
1608 global $wgOut, $wgUser;
1610 $link = $nt->getPrefixedURL();
1612 $u = $nt->escapeLocalURL( $query );
1614 if ( "" == $text ) {
1615 $text = htmlspecialchars( $nt->getPrefixedText() );
1617 $style = $this->getInternalLinkAttributesObj( $nt, $text, "stub" );
1620 if ( "" != $trail ) {
1621 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1626 if ( $wgUser->getOption( "highlightbroken" ) ) {
1627 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1629 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>!</a>{$trail}";
1634 function makeSelfLinkObj( &$nt, $text = "", $query = "", $trail = "", $prefix = "" )
1636 $u = $nt->escapeLocalURL( $query );
1637 if ( "" == $text ) {
1638 $text = htmlspecialchars( $nt->getPrefixedText() );
1641 if ( "" != $trail ) {
1642 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1647 return "<strong>{$prefix}{$text}{$inside}</strong>{$trail}";
1650 /* these are used extensively in SkinPHPTal, but also some other places */
1651 /*static*/ function makeSpecialUrl( $name, $urlaction='' ) {
1652 $title = Title
::makeTitle( NS_SPECIAL
, $name );
1653 $this->checkTitle(&$title, &$name);
1654 return $title->getLocalURL( $urlaction );
1656 /*static*/ function makeTalkUrl ( $name, $urlaction='' ) {
1657 $title = Title
::newFromText( $name );
1658 $title = $title->getTalkPage();
1659 $this->checkTitle(&$title, &$name);
1660 return $title->getLocalURL( $urlaction );
1662 /*static*/ function makeArticleUrl ( $name, $urlaction='' ) {
1663 $title = Title
::newFromText( $name );
1664 $title= $title->getSubjectPage();
1665 $this->checkTitle(&$title, &$name);
1666 return $title->getLocalURL( $urlaction );
1668 /*static*/ function makeI18nUrl ( $name, $urlaction='' ) {
1669 $title = Title
::newFromText( wfMsg($name) );
1670 $this->checkTitle(&$title, &$name);
1671 return $title->getLocalURL( $urlaction );
1673 /*static*/ function makeUrl ( $name, $urlaction='' ) {
1674 $title = Title
::newFromText( $name );
1675 $this->checkTitle(&$title, &$name);
1676 return $title->getLocalURL( $urlaction );
1679 # make sure we have some title to operate on, mind the '&'
1680 /*static*/ function &checkTitle ( $title, $name ) {
1681 if(!is_object($title)) {
1682 $title = Title
::newFromText( $name );
1683 if(!is_object($title)) {
1684 $title = Title
::newFromText( '<error: link target missing>' );
1689 function fnamePart( $url )
1691 $basename = strrchr( $url, "/" );
1692 if ( false === $basename ) { $basename = $url; }
1693 else { $basename = substr( $basename, 1 ); }
1694 return wfEscapeHTML( $basename );
1697 function makeImage( $url, $alt = "" )
1701 if ( "" == $alt ) { $alt = $this->fnamePart( $url ); }
1702 $s = "<img src=\"{$url}\" alt=\"{$alt}\" />";
1706 function makeImageLink( $name, $url, $alt = "" ) {
1707 $nt = Title
::makeTitle( Namespace::getImage(), $name );
1708 return $this->makeImageLinkObj( $nt, $alt );
1711 function makeImageLinkObj( $nt, $alt = "" ) {
1712 global $wgLang, $wgUseImageResize;
1713 $img = Image
::newFromTitle( $nt );
1714 $url = $img->getURL();
1717 $prefix = $postfix = "";
1719 if ( $wgUseImageResize ) {
1720 # Check if the alt text is of the form "options|alt text"
1722 # * thumbnail make a thumbnail with enlarge-icon and caption, alignment depends on lang
1723 # * left no resizing, just left align. label is used for alt= only
1724 # * right same, but right aligned
1725 # * none same, but not aligned
1726 # * ___px scale to ___ pixels width, no aligning. e.g. use in taxobox
1727 # * center center the image
1728 # * framed Keep original image size, no magnify-button.
1730 $part = explode( "|", $alt);
1732 $mwThumb =& MagicWord
::get( MAG_IMG_THUMBNAIL
);
1733 $mwLeft =& MagicWord
::get( MAG_IMG_LEFT
);
1734 $mwRight =& MagicWord
::get( MAG_IMG_RIGHT
);
1735 $mwNone =& MagicWord
::get( MAG_IMG_NONE
);
1736 $mwWidth =& MagicWord
::get( MAG_IMG_WIDTH
);
1737 $mwCenter =& MagicWord
::get( MAG_IMG_CENTER
);
1738 $mwFramed =& MagicWord
::get( MAG_IMG_FRAMED
);
1739 $alt = $part[count($part)-1];
1741 $height = $framed = $thumb = false;
1743 foreach( $part as $key => $val ) {
1744 if ( ! is_null( $mwThumb->matchVariableStartToEnd($val) ) ) {
1746 } elseif ( ! is_null( $mwRight->matchVariableStartToEnd($val) ) ) {
1747 # remember to set an alignment, don't render immediately
1749 } elseif ( ! is_null( $mwLeft->matchVariableStartToEnd($val) ) ) {
1750 # remember to set an alignment, don't render immediately
1752 } elseif ( ! is_null( $mwCenter->matchVariableStartToEnd($val) ) ) {
1753 # remember to set an alignment, don't render immediately
1755 } elseif ( ! is_null( $mwNone->matchVariableStartToEnd($val) ) ) {
1756 # remember to set an alignment, don't render immediately
1758 } elseif ( ! is_null( $match = $mwWidth->matchVariableStartToEnd($val) ) ) {
1759 # $match is the image width in pixels
1760 if ( preg_match( "/^([0-9]*)x([0-9]*)$/", $match, $m ) ) {
1761 $width = intval( $m[1] );
1762 $height = intval( $m[2] );
1764 $width = intval($match);
1766 } elseif ( ! is_null( $mwFramed->matchVariableStartToEnd($val) ) ) {
1770 if ( "center" == $align )
1772 $prefix = '<span style="text-align: center">';
1773 $postfix = '</span>';
1777 if ( $thumb ||
$framed ) {
1779 # Create a thumbnail. Alignment depends on language
1780 # writing direction, # right aligned for left-to-right-
1781 # languages ("Western languages"), left-aligned
1782 # for right-to-left-languages ("Semitic languages")
1784 # If thumbnail width has not been provided, it is set
1785 # here to 180 pixels
1786 if ( $align == "" ) {
1787 $align = $wgLang->isRTL() ?
"left" : "right";
1789 if ( ! isset($width) ) {
1792 return $prefix.$this->makeThumbLinkObj( $img, $alt, $align, $width, $height, $framed ).$postfix;
1794 } elseif ( isset($width) ) {
1796 # Create a resized image, without the additional thumbnail
1799 if ( ( ! $height === false )
1800 && ( $img->getHeight() * $width / $img->getWidth() > $height ) ) {
1801 print "height=$height<br>\nimg->getHeight() = ".$img->getHeight()."<br>\n";
1802 print "rescaling by factor ". $height / $img->getHeight() . "<br>\n";
1803 $width = $img->getWidth() * $height / $img->getHeight();
1805 $url = $img->createThumb( $width );
1807 } # endif $wgUseImageResize
1809 if ( empty( $alt ) ) {
1810 $alt = preg_replace( '/\.(.+?)^/', '', $img->getName() );
1812 $alt = htmlspecialchars( $alt );
1814 $u = $nt->escapeLocalURL();
1817 $s = str_replace( "$1", $img->getName(), wfMsg("missingimage") );
1818 $s .= "<br>{$alt}<br>{$url}<br>\n";
1820 $s = "<a href=\"{$u}\" class='image' title=\"{$alt}\">" .
1821 "<img src=\"{$url}\" alt=\"{$alt}\" /></a>";
1823 if ( "" != $align ) {
1824 $s = "<div class=\"float{$align}\"><span>{$s}</span>\n</div>";
1826 return $prefix.$s.$postfix;
1830 function makeThumbLinkObj( $img, $label = "", $align = "right", $boxwidth = 180, $boxheight=false, $framed=false ) {
1831 global $wgStylePath, $wgLang;
1832 # $image = Title::makeTitle( Namespace::getImage(), $name );
1833 $url = $img->getURL();
1835 #$label = htmlspecialchars( $label );
1836 $alt = preg_replace( "/<[^>]*>/", "", $label);
1837 $alt = htmlspecialchars( $alt );
1839 if ( $img->exists() )
1841 $width = $img->getWidth();
1842 $height = $img->getHeight();
1844 $width = $height = 200;
1848 // Use image dimensions, don't scale
1850 $oboxwidth = $boxwidth +
2;
1851 $boxheight = $height;
1854 $h = intval( $height/($width/$boxwidth) );
1855 $oboxwidth = $boxwidth +
2;
1856 if ( ( ! $boxheight === false ) && ( $h > $boxheight ) )
1858 $boxwidth *= $boxheight/$h;
1862 $thumbUrl = $img->createThumb( $boxwidth );
1865 $u = $img->getEscapeLocalURL();
1867 $more = htmlspecialchars( wfMsg( "thumbnail-more" ) );
1868 $magnifyalign = $wgLang->isRTL() ?
"left" : "right";
1869 $textalign = $wgLang->isRTL() ?
' style="text-align:right"' : "";
1871 $s = "<div class=\"thumb t{$align}\"><div style=\"width:{$oboxwidth}px;\">";
1872 if ( $thumbUrl == "" ) {
1873 $s .= str_replace( "$1", $img->getName(), wfMsg("missingimage") );
1876 $s .= '<a href="'.$u.'" class="internal" title="'.$alt.'">'.
1877 '<img src="'.$thumbUrl.'" alt="'.$alt.'" ' .
1878 'width="'.$boxwidth.'" height="'.$boxheight.'" /></a>';
1882 $zoomicon = '<div class="magnify" style="float:'.$magnifyalign.'">'.
1883 '<a href="'.$u.'" class="internal" title="'.$more.'">'.
1884 '<img src="'.$wgStylePath.'/images/magnify-clip.png" ' .
1885 'width="15" height="11" alt="'.$more.'" /></a></div>';
1888 $s .= ' <div class="thumbcaption" '.$textalign.'>'.$zoomicon.$label."</div></div>\n</div>";
1892 function makeMediaLink( $name, $url, $alt = "" ) {
1893 $nt = Title
::makeTitle( Namespace::getMedia(), $name );
1894 return $this->makeMediaLinkObj( $nt, $alt );
1897 function makeMediaLinkObj( $nt, $alt = "" )
1899 $name = $nt->getDBKey();
1900 $url = Image
::wfImageUrl( $name );
1901 if ( empty( $alt ) ) {
1902 $alt = preg_replace( '/\.(.+?)^/', '', $name );
1905 $u = htmlspecialchars( $url );
1906 $s = "<a href=\"{$u}\" class='internal' title=\"{$alt}\">{$alt}</a>";
1910 function specialLink( $name, $key = "" )
1914 if ( "" == $key ) { $key = strtolower( $name ); }
1915 $pn = $wgLang->ucfirst( $name );
1916 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1920 function makeExternalLink( $url, $text, $escape = true ) {
1921 $style = $this->getExternalLinkAttributes( $url, $text );
1922 $url = htmlspecialchars( $url );
1924 $text = htmlspecialchars( $text );
1926 return "<a href=\"$url\"$style>$text</a>";
1929 # Called by history lists and recent changes
1932 # Returns text for the start of the tabular part of RC
1933 function beginRecentChangesList()
1935 $this->rc_cache
= array() ;
1936 $this->rcMoveIndex
= 0;
1937 $this->rcCacheIndex
= 0 ;
1938 $this->lastdate
= "";
1939 $this->rclistOpen
= false;
1943 function beginImageHistoryList()
1945 $s = "\n<h2>" . wfMsg( "imghistory" ) . "</h2>\n" .
1946 "<p>" . wfMsg( "imghistlegend" ) . "</p>\n<ul class='special'>";
1950 # Returns text for the end of RC
1951 # If enhanced RC is in use, returns pretty much all the text
1952 function endRecentChangesList()
1954 $s = $this->recentChangesBlock() ;
1955 if( $this->rclistOpen
) {
1961 # Enhanced RC ungrouped line
1962 function recentChangesBlockLine ( $rcObj )
1964 global $wgStylePath, $wgLang ;
1966 # Get rc_xxxx variables
1967 extract( $rcObj->mAttribs
) ;
1968 $curIdEq = "curid=$rc_cur_id";
1973 $r .= "<img src='{$wgStylePath}/images/Arr_.png' width='12' height='12' border='0' />" ; $r .= "<tt>" ;
1975 if ( $rc_type == RC_MOVE
) {
1976 $r .= " ";
1978 # M & N (minor & new)
1979 $M = wfMsg( "minoreditletter" );
1980 $N = wfMsg( "newpageletter" );
1982 if ( $rc_type == RC_NEW
) {
1995 $r .= " ".$rcObj->timestamp
." " ;
1999 $link = $rcObj->link
;
2000 if ( $rcObj->watched
) $link = "<strong>{$link}</strong>" ;
2005 $r .= $rcObj->curlink
;
2009 $r .= $this->makeKnownLinkObj( $rcObj->getTitle(), wfMsg( "hist" ), "{$curIdEq}&action=history" );
2012 $r .= ") . . ".$rcObj->userlink
;
2013 $r .= $rcObj->usertalklink
;
2016 if ( $rc_comment != "" && $rc_type != RC_MOVE
) {
2017 $rc_comment=$this->formatComment($rc_comment);
2018 $r .= $wgLang->emphasize( " (".$rc_comment.")" );
2026 function recentChangesBlockGroup ( $block )
2028 global $wgStylePath, $wgLang ;
2031 $M = wfMsg( "minoreditletter" );
2032 $N = wfMsg( "newpageletter" );
2034 # Collate list of users
2036 $userlinks = array () ;
2037 foreach ( $block AS $rcObj ) {
2038 $oldid = $rcObj->mAttribs
['rc_last_oldid'];
2039 if ( $rcObj->mAttribs
['rc_new'] ) $isnew = true ;
2040 $u = $rcObj->userlink
;
2041 if ( !isset ( $userlinks[$u] ) ) $userlinks[$u] = 0 ;
2045 # Sort the list and convert to text
2046 krsort ( $userlinks ) ;
2047 asort ( $userlinks ) ;
2049 foreach ( $userlinks as $userlink => $count) {
2051 if ( $count > 1 ) $text .= " ({$count}×)" ;
2052 array_push ( $users , $text ) ;
2054 $users = " <font size='-1'>[".implode("; ",$users)."]</font>" ;
2057 $rci = "RCI{$this->rcCacheIndex}" ;
2058 $rcl = "RCL{$this->rcCacheIndex}" ;
2059 $rcm = "RCM{$this->rcCacheIndex}" ;
2060 $toggleLink = "javascript:toggleVisibility(\"{$rci}\",\"{$rcm}\",\"{$rcl}\")" ;
2061 $arrowdir = $wgLang->isRTL() ?
"l" : "r";
2062 $tl = "<span id='{$rcm}'><a href='$toggleLink'><img src='{$wgStylePath}/images/Arr_{$arrowdir}.png' width='12' height='12' /></a></span>" ;
2063 $tl .= "<span id='{$rcl}' style='display:none'><a href='$toggleLink'><img src='{$wgStylePath}/images/Arr_d.png' width='12' height='12' /></a></span>" ;
2069 if ( $isnew ) $r .= $N ;
2070 else $r .= " " ;
2071 $r .= " " ; # Minor
2074 $r .= " ".$block[0]->timestamp
." " ;
2078 $link = $block[0]->link
;
2079 if ( $block[0]->watched
) $link = "<strong>{$link}</strong>" ;
2082 $curIdEq = "curid=" . $block[0]->mAttribs
['rc_cur_id'];
2083 if ( $block[0]->mAttribs
['rc_type'] != RC_LOG
) {
2085 $r .= " (".count($block)." " ;
2086 if ( $isnew ) $r .= wfMsg("changes");
2087 else $r .= $this->makeKnownLinkObj( $block[0]->getTitle() , wfMsg("changes") ,
2088 "{$curIdEq}&diff=0&oldid=".$oldid ) ;
2092 $r .= $this->makeKnownLinkObj( $block[0]->getTitle(), wfMsg( "history" ), "{$curIdEq}&action=history" );
2100 $r .= "<div id='{$rci}' style='display:none'>" ;
2101 foreach ( $block AS $rcObj ) {
2102 # Get rc_xxxx variables
2103 extract( $rcObj->mAttribs
);
2105 $r .= "<img src='{$wgStylePath}/images/Arr_.png' width=12 height=12 />";
2106 $r .= "<tt> " ;
2107 if ( $rc_new ) $r .= $N ;
2108 else $r .= " " ;
2109 if ( $rc_minor ) $r .= $M ;
2110 else $r .= " " ;
2114 if ( $rc_last_oldid != 0 ) {
2115 $o = "oldid=".$rc_last_oldid ;
2117 if ( $rc_type == RC_LOG
) {
2118 $link = $rcObj->timestamp
;
2120 $link = $this->makeKnownLinkObj( $rcObj->getTitle(), $rcObj->timestamp
, "{$curIdEq}&$o" ) ;
2122 $link = "<tt>{$link}</tt>" ;
2126 $r .= $rcObj->curlink
;
2128 $r .= $rcObj->lastlink
;
2129 $r .= ") . . ".$rcObj->userlink
;
2130 $r .= $rcObj->usertalklink
;
2131 if ( $rc_comment != "" ) {
2132 $rc_comment=$this->formatComment($rc_comment);
2133 $r .= $wgLang->emphasize( " (".$rc_comment.")" ) ;
2139 $this->rcCacheIndex++
;
2143 # If enhanced RC is in use, this function takes the previously cached
2144 # RC lines, arranges them, and outputs the HTML
2145 function recentChangesBlock ()
2147 global $wgStylePath ;
2148 if ( count ( $this->rc_cache
) == 0 ) return "" ;
2150 foreach ( $this->rc_cache
AS $secureName => $block ) {
2151 if ( count ( $block ) < 2 ) {
2152 $blockOut .= $this->recentChangesBlockLine ( array_shift ( $block ) ) ;
2154 $blockOut .= $this->recentChangesBlockGroup ( $block ) ;
2158 return "<div>{$blockOut}</div>" ;
2161 # Called in a loop over all displayed RC entries
2162 # Either returns the line, or caches it for later use
2163 function recentChangesLine( &$rc, $watched = false )
2166 $usenew = $wgUser->getOption( "usenewrc" );
2168 $line = $this->recentChangesLineNew ( $rc, $watched ) ;
2170 $line = $this->recentChangesLineOld ( $rc, $watched ) ;
2174 function recentChangesLineOld( &$rc, $watched = false )
2176 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds;
2178 # Extract DB fields into local scope
2179 extract( $rc->mAttribs
);
2180 $curIdEq = "curid=" . $rc_cur_id;
2182 # Make date header if necessary
2183 $date = $wgLang->date( $rc_timestamp, true);
2185 if ( $date != $this->lastdate
) {
2186 if ( "" != $this->lastdate
) { $s .= "</ul>\n"; }
2187 $s .= "<h4>{$date}</h4>\n<ul class='special'>";
2188 $this->lastdate
= $date;
2189 $this->rclistOpen
= true;
2193 if ( $rc_type == RC_MOVE
) {
2195 $s .= "(" . wfMsg( "diff" ) . ") (";
2197 $s .= $this->makeKnownLinkObj( $rc->getMovedToTitle(), wfMsg( "hist" ), "action=history" ) .
2200 # "[[x]] moved to [[y]]"
2202 $s .= wfMsg( "1movedto2", $this->makeKnownLinkObj( $rc->getTitle(), "", "redirect=no" ),
2203 $this->makeKnownLinkObj( $rc->getMovedToTitle(), "" ) );
2207 if ( $rc_type == RC_NEW ||
$rc_type == RC_LOG
) {
2208 $diffLink = wfMsg( "diff" );
2210 $diffLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( "diff" ),
2211 "{$curIdEq}&diff={$rc_this_oldid}&oldid={$rc_last_oldid}" ,'' ,'' , ' tabindex="'.$rc->counter
.'"');
2213 $s .= "($diffLink) (";
2216 $s .= $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( "hist" ), "{$curIdEq}&action=history" );
2219 # M and N (minor and new)
2220 $M = wfMsg( "minoreditletter" );
2221 $N = wfMsg( "newpageletter" );
2222 if ( $rc_minor ) { $s .= " <strong>{$M}</strong>"; }
2223 if ( $rc_type == RC_NEW
) { $s .= "<strong>{$N}</strong>"; }
2226 $articleLink = $this->makeKnownLinkObj( $rc->getTitle(), "" );
2229 $articleLink = "<strong>{$articleLink}</strong>";
2231 $s .= " $articleLink";
2236 $s .= "; " . $wgLang->time( $rc_timestamp, true, $wgRCSeconds ) . " . . ";
2238 # User link (or contributions for unregistered users)
2239 if ( 0 == $rc_user ) {
2240 $userLink = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
2241 $rc_user_text, "target=" . $rc_user_text );
2243 $userLink = $this->makeLink( $wgLang->getNsText( NS_USER
) . ":{$rc_user_text}", $rc_user_text );
2248 $talkname=$wgLang->getNsText(NS_TALK
); # use the shorter name
2249 global $wgDisableAnonTalk;
2250 if( 0 == $rc_user && $wgDisableAnonTalk ) {
2253 $utns=$wgLang->getNsText(NS_USER_TALK
);
2254 $userTalkLink= $this->makeLink($utns . ":{$rc_user_text}", $talkname );
2258 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2259 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2260 "Blockip" ), wfMsg( "blocklink" ), "ip={$rc_user_text}" );
2264 if($userTalkLink) $userTalkLink .= " | ";
2265 $userTalkLink .= $blockLink;
2267 if($userTalkLink) $s.=" ({$userTalkLink})";
2270 if ( "" != $rc_comment && "*" != $rc_comment && $rc_type != RC_MOVE
) {
2271 $rc_comment=$this->formatComment($rc_comment);
2272 $s .= $wgLang->emphasize(" (" . $rc_comment . ")");
2279 # function recentChangesLineNew( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched = false, $oldid = 0 , $diffid = 0 )
2280 function recentChangesLineNew( &$baseRC, $watched = false )
2282 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds;
2284 # Create a specialised object
2285 $rc = RCCacheEntry
::newFromParent( $baseRC ) ;
2287 # Extract fields from DB into the function scope (rc_xxxx variables)
2288 extract( $rc->mAttribs
);
2289 $curIdEq = "curid=" . $rc_cur_id;
2291 # If it's a new day, add the headline and flush the cache
2292 $date = $wgLang->date( $rc_timestamp, true);
2294 if ( $date != $this->lastdate
) {
2295 # Process current cache
2296 $ret = $this->recentChangesBlock () ;
2297 $this->rc_cache
= array() ;
2298 $ret .= "<h4>{$date}</h4>\n";
2299 $this->lastdate
= $date;
2303 if ( $rc_type == RC_MOVE
) {
2304 $clink = $this->makeKnownLinkObj( $rc->getTitle(), "", "redirect=no" );
2305 $clink .= " " . wfMsg("movedto") . " ";
2306 $clink .= $this->makeKnownLinkObj( $rc->getMovedToTitle(), "" );
2308 $clink = $this->makeKnownLinkObj( $rc->getTitle(), "" ) ;
2311 $time = $wgLang->time( $rc_timestamp, true, $wgRCSeconds );
2312 $rc->watched
= $watched ;
2313 $rc->link
= $clink ;
2314 $rc->timestamp
= $time;
2317 if ( ( $rc_type == RC_NEW
&& $rc_this_oldid == 0 ) ||
$rc_type == RC_LOG ||
$rc_type == RC_MOVE
) {
2318 $curLink = wfMsg( "cur" );
2320 $curLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( "cur" ),
2321 "{$curIdEq}&diff=0&oldid={$rc_this_oldid}" ,'' ,'' , ' tabindex="'.$baseRC->counter
.'"' );
2325 $titleObj = $rc->getTitle();
2326 if ( $rc_last_oldid == 0 ||
$rc_type == RC_LOG ||
$rc_type == RC_MOVE
) {
2327 $lastLink = wfMsg( "last" );
2329 $lastLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( "last" ),
2330 "{$curIdEq}&diff={$rc_this_oldid}&oldid={$rc_last_oldid}" );
2333 # Make user link (or user contributions for unregistered users)
2334 if ( 0 == $rc_user ) {
2335 $userLink = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
2336 $rc_user_text, "target=" . $rc_user_text );
2338 $userLink = $this->makeLink( $wgLang->getNsText(
2339 Namespace::getUser() ) . ":{$rc_user_text}", $rc_user_text );
2342 $rc->userlink
= $userLink ;
2343 $rc->lastlink
= $lastLink ;
2344 $rc->curlink
= $curLink ;
2346 # Make user talk link
2347 $utns=$wgLang->getNsText(NS_USER_TALK
);
2348 $talkname=$wgLang->getNsText(NS_TALK
); # use the shorter name
2349 $userTalkLink= $this->makeLink($utns . ":{$rc_user_text}", $talkname );
2351 global $wgDisableAnonTalk;
2352 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2353 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2354 "Blockip" ), wfMsg( "blocklink" ), "ip={$rc_user_text}" );
2355 if( $wgDisableAnonTalk )
2356 $rc->usertalklink
= " ({$blockLink})";
2358 $rc->usertalklink
= " ({$userTalkLink} | {$blockLink})";
2360 if( $wgDisableAnonTalk && ($rc_user == 0) )
2361 $rc->usertalklink
= "";
2363 $rc->usertalklink
= " ({$userTalkLink})";
2366 # Put accumulated information into the cache, for later display
2367 # Page moves go on their own line
2368 $title = $rc->getTitle();
2369 $secureName = $title->getPrefixedDBkey();
2370 if ( $rc_type == RC_MOVE
) {
2371 # Use an @ character to prevent collision with page names
2372 $this->rc_cache
["@@" . ($this->rcMoveIndex++
)] = array($rc);
2374 if ( !isset ( $this->rc_cache
[$secureName] ) ) $this->rc_cache
[$secureName] = array() ;
2375 array_push ( $this->rc_cache
[$secureName] , $rc ) ;
2380 function endImageHistoryList()
2386 /* This function is called by all recent changes variants, by the page history,
2387 and by the user contributions list. It is responsible for formatting edit
2388 comments. It escapes any HTML in the comment, but adds some CSS to format
2389 auto-generated comments (from section editing) and formats [[wikilinks]].
2390 Main author: Erik Möller (moeller@scireview.de)
2392 function formatComment($comment)
2395 $comment=wfEscapeHTML($comment);
2397 # The pattern for autogen comments is / * foo * /, which makes for
2399 # We look for all comments, match any text before and after the comment,
2400 # add a separator where needed and format the comment itself with CSS
2401 while (preg_match("/(.*)\/\*\s*(.*?)\s*\*\/(.*)/", $comment,$match)) {
2406 if($pre) { $auto="$sep ".$auto; }
2407 if($post) { $auto.=" $sep"; }
2408 $auto="<span class=\"autocomment\">".$auto."</span>";
2409 $comment=$pre.$auto.$post;
2412 # format regular and media links - all other wiki formatting
2414 while(preg_match("/\[\[(.*?)(\|(.*?))*\]\]/",$comment,$match)) {
2416 $medians = $wgLang->getNsText(Namespace::getMedia());
2418 if(preg_match("/^".$medians."/i",$match[1])) {
2419 $func="makeMediaLink";
2421 if(isset($match[3]) ) {
2423 preg_replace("/\[\[(.*?)\]\]/",
2424 $this->$func($match[1],$match[3]),$comment,1);
2427 preg_replace("/\[\[(.*?)\]\]/",
2428 $this->$func($match[1],$match[1]),$comment,1);
2436 function imageHistoryLine( $iscur, $timestamp, $img, $user, $usertext, $size, $description )
2438 global $wgUser, $wgLang, $wgTitle;
2440 $datetime = $wgLang->timeanddate( $timestamp, true );
2441 $del = wfMsg( "deleteimg" );
2442 $cur = wfMsg( "cur" );
2445 $url = Image
::wfImageUrl( $img );
2447 if ( $wgUser->isSysop() ) {
2448 $link = $wgTitle->escapeLocalURL( "image=" . $wgTitle->getPartialURL() .
2450 $style = $this->getInternalLinkAttributes( $link, $del );
2452 $dlink = "<a href=\"{$link}\"{$style}>{$del}</a>";
2457 $url = wfEscapeHTML( wfImageArchiveUrl( $img ) );
2458 if( $wgUser->getID() != 0 ) {
2459 $rlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2460 wfMsg( "revertimg" ), "action=revert&oldimage=" .
2461 urlencode( $img ) );
2462 $dlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2463 $del, "action=delete&oldimage=" . urlencode( $img ) );
2465 # Having live active links for non-logged in users
2466 # means that bots and spiders crawling our site can
2467 # inadvertently change content. Baaaad idea.
2468 $rlink = wfMsg( "revertimg" );
2473 $userlink = $usertext;
2475 $userlink = $this->makeLink( $wgLang->getNsText( Namespace::getUser() ) .
2476 ":{$usertext}", $usertext );
2478 $nbytes = wfMsg( "nbytes", $size );
2479 $style = $this->getInternalLinkAttributes( $url, $datetime );
2481 $s = "<li> ({$dlink}) ({$rlink}) <a href=\"{$url}\"{$style}>{$datetime}</a>"
2482 . " . . {$userlink} ({$nbytes})";
2484 if ( "" != $description && "*" != $description ) {
2485 $sk=$wgUser->getSkin();
2486 $s .= $wgLang->emphasize(" (" . $sk->formatComment($description) . ")");
2492 function tocIndent($level) {
2493 return str_repeat( "<div class='tocindent'>\n", $level>0 ?
$level : 0 );
2496 function tocUnindent($level) {
2497 return str_repeat( "</div>\n", $level>0 ?
$level : 0 );
2500 # parameter level defines if we are on an indentation level
2501 function tocLine( $anchor, $tocline, $level,$section=0 ) {
2503 $url = $section ?
$wgTitle->getLocalURL( "action=view§ion={$section}§iontitle={$anchor}" )
2505 $link = "<a href=\"$url\" class='internal'>$tocline</a><br />";
2509 return "<div class='tocline'>$link</div>\n";
2514 function tocTable($toc) {
2515 # note to CSS fanatics: putting this in a div does not work -- div won't auto-expand
2516 # try min-width & co when somebody gets a chance
2517 global $wgRequest,$wgTitle,$wgOut;
2518 $collapse=$wgOut->getCollapse();
2519 $section=$wgRequest->getVal('section');
2523 $url=$wgTitle->getLocalURL("action=view&collapse=false");
2524 $collapseexpand="<a href=\"$url\" class=\"internal\">".wfMsg("expandpage")."</A>";
2526 $url=$wgTitle->getLocalURL("action=view&collapse=true");
2527 $collapseexpand="<a href=\"$url\" class=\"internal\">".wfMsg("collapsepage")."</A>";
2530 $hideline = " <script type='text/javascript'>showTocToggle(\"" . addslashes( wfMsg("showtoc") ) . "\",\"" . addslashes( wfMsg("hidetoc") ) . "\")</script>";
2532 "<table border=\"0\" id=\"toc\"><tr><td align=\"center\">\n".
2533 "<b>".wfMsg("toc")."</b>" .
2535 "</td></tr><tr id='tocinside'><td>\n".
2537 if($collapseexpand) {
2538 $rv.="<tr><td align=\"center\"><I>$collapseexpand</I></td></tr>";
2544 # These two do not check for permissions: check $wgTitle->userCanEdit before calling them
2545 function editSectionScript( $section, $head ) {
2546 global $wgTitle, $wgRequest;
2547 if( $wgRequest->getInt( "oldid" ) && ( $wgRequest->getVal( "diff" ) != "0" ) ) {
2550 $url = $wgTitle->escapeLocalURL( "action=edit§ion=$section" );
2551 return "<span oncontextmenu='document.location=\"$url\";return false;'>{$head}</span>";
2554 function editSectionLink( $section ) {
2556 global $wgTitle, $wgUser, $wgLang;
2558 if( $wgRequest->getInt( "oldid" ) && ( $wgRequest->getVal( "diff" ) != "0" ) ) {
2559 # Section edit links would be out of sync on an old page.
2560 # But, if we're diffing to the current page, they'll be
2565 $editurl = "§ion={$section}";
2566 $url = $this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg("editsection"),"action=edit".$editurl);
2568 if( $wgLang->isRTL() ) {
2570 $nearside = "right";
2575 return "<div class=\"editsection\" style=\"float:$farside;margin-$nearside:5px;\">[".$url."]</div>";
2579 // This function is called by EditPage.php and shows a bulletin board style
2580 // toolbar for common editing functions. It can be disabled in the user preferences.
2581 // The necsesary JavaScript code can be found in style/wikibits.js.
2582 function getEditToolbar() {
2583 global $wgStylePath, $wgLang, $wgMimeType;
2585 // toolarray an array of arrays which each include the filename of
2586 // the button image (without path), the opening tag, the closing tag,
2587 // and optionally a sample text that is inserted between the two when no
2588 // selection is highlighted.
2589 // The tip text is shown when the user moves the mouse over the button.
2591 // Already here are accesskeys (key), which are not used yet until someone
2592 // can figure out a way to make them work in IE. However, we should make
2593 // sure these keys are not defined on the edit page.
2595 array( "image"=>"button_bold.png",
2598 "sample"=>wfMsg("bold_sample"),
2599 "tip"=>wfMsg("bold_tip"),
2602 array( "image"=>"button_italic.png",
2605 "sample"=>wfMsg("italic_sample"),
2606 "tip"=>wfMsg("italic_tip"),
2609 array( "image"=>"button_link.png",
2612 "sample"=>wfMsg("link_sample"),
2613 "tip"=>wfMsg("link_tip"),
2616 array( "image"=>"button_extlink.png",
2619 "sample"=>wfMsg("extlink_sample"),
2620 "tip"=>wfMsg("extlink_tip"),
2623 array( "image"=>"button_headline.png",
2626 "sample"=>wfMsg("headline_sample"),
2627 "tip"=>wfMsg("headline_tip"),
2630 array( "image"=>"button_image.png",
2631 "open"=>"[[".$wgLang->getNsText(NS_IMAGE
).":",
2633 "sample"=>wfMsg("image_sample"),
2634 "tip"=>wfMsg("image_tip"),
2637 array( "image"=>"button_media.png",
2638 "open"=>"[[".$wgLang->getNsText(NS_MEDIA
).":",
2640 "sample"=>wfMsg("media_sample"),
2641 "tip"=>wfMsg("media_tip"),
2644 array( "image"=>"button_math.png",
2645 "open"=>"\\<math\\>",
2646 "close"=>"\\</math\\>",
2647 "sample"=>wfMsg("math_sample"),
2648 "tip"=>wfMsg("math_tip"),
2651 array( "image"=>"button_nowiki.png",
2652 "open"=>"\\<nowiki\\>",
2653 "close"=>"\\</nowiki\\>",
2654 "sample"=>wfMsg("nowiki_sample"),
2655 "tip"=>wfMsg("nowiki_tip"),
2658 array( "image"=>"button_sig.png",
2662 "tip"=>wfMsg("sig_tip"),
2665 array( "image"=>"button_hr.png",
2666 "open"=>"\\n----\\n",
2669 "tip"=>wfMsg("hr_tip"),
2673 $toolbar ="<script type='text/javascript'>\n/*<![CDATA[*/\n";
2675 $toolbar.="document.writeln(\"<div id='toolbar'>\");\n";
2676 foreach($toolarray as $tool) {
2678 $image=$wgStylePath."/images/".$tool["image"];
2679 $open=$tool["open"];
2680 $close=$tool["close"];
2681 $sample = addslashes( $tool["sample"] );
2683 // Note that we use the tip both for the ALT tag and the TITLE tag of the image.
2684 // Older browsers show a "speedtip" type message only for ALT.
2685 // Ideally these should be different, realistically they
2686 // probably don't need to be.
2687 $tip = addslashes( $tool["tip"] );
2689 #$key = $tool["key"];
2691 $toolbar.="addButton('$image','$tip','$open','$close','$sample');\n";
2694 $toolbar.="addInfobox('" . addslashes( wfMsg( "infobox" ) ) . "','" . addslashes(wfMsg("infobox_alert")) . "');\n";
2695 $toolbar.="document.writeln(\"</div>\");\n";
2697 $toolbar.="/*]]>*/\n</script>";
2702 require_once( "SkinStandard.php" );
2703 require_once( "SkinNostalgia.php" );
2704 require_once( "SkinCologneBlue.php" );
2706 if( $wgUsePHPTal ) {
2707 require_once( "SkinPHPTal.php" );