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='siteNotice'>$wgSiteNotice</div>\n";
299 return $this->doBeforeContent() . $note;
302 function doBeforeContent()
304 global $wgUser, $wgOut, $wgTitle, $wgLang;
305 $fname = "Skin::doBeforeContent";
306 wfProfileIn( $fname );
309 $qb = $this->qbSetting();
311 if( $langlinks = $this->otherLanguages() ) {
317 $borderhack = "class='top'";
320 $s .= "\n<div id='content'>\n<div id='topbar'>\n" .
321 "<table border='0' cellspacing='0' width='98%'>\n<tr>\n";
324 $left = ($qb == 1 ||
$qb == 3);
325 if($wgLang->isRTL()) $left = !$left;
328 $s .= "<td class='top' align='left' valign='top' rowspan='{$rows}'>\n" .
329 $this->logoText() . "</td>";
331 $s .= $this->getQuickbarCompensator( $rows );
333 $l = $wgLang->isRTL() ?
"right" : "left";
334 $s .= "<td {$borderhack} align='$l' valign='top'>\n";
336 $s .= $this->topLinks() ;
337 $s .= "<p class='subtitle'>" . $this->pageTitleLinks() . "</p>\n";
339 $r = $wgLang->isRTL() ?
"left" : "right";
340 $s .= "</td>\n<td {$borderhack} valign='top' align='$r' nowrap='nowrap'>";
341 $s .= $this->nameAndLogin();
342 $s .= "\n<br />" . $this->searchForm() . "</td>";
345 $s .= "</tr>\n<tr>\n<td class='top' colspan=\"2\">$langlinks</td>\n";
348 if ( $shove && !$left ) { # Right
349 $s .= $this->getQuickbarCompensator( $rows );
351 $s .= "</tr>\n</table>\n</div>\n";
352 $s .= "\n<div id='article'>\n";
354 $s .= $this->pageTitle();
355 $s .= $this->pageSubtitle() ;
356 $s .= $this->getCategories();
357 wfProfileOut( $fname );
361 function getCategoryLinks () {
362 global $wgOut, $wgTitle, $wgUser, $wgParser;
363 global $wgUseCategoryMagic;
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() ) )
375 function getCategories() {
376 $catlinks=$this->getCategoryLinks();
377 if(!empty($catlinks)) {
378 return "<p class='catlinks'>{$catlinks}</p>";
382 function getQuickbarCompensator( $rows = 1 )
384 return "<td width='152' rowspan='{$rows}'> </td>";
387 # This gets called immediately before the </body> tag.
389 function afterContent()
391 global $wgUser, $wgOut, $wgServer;
392 global $wgTitle, $wgLang;
394 $printfooter = "<div class=\"printfooter\">\n" . $this->printFooter() . "</div>\n";
395 return $printfooter . $this->doAfterContent();
398 function printFooter() {
400 $url = htmlspecialchars( $wgTitle->getFullURL() );
401 return "<p>" . wfMsg( "retrievedfrom", "<a href=\"$url\">$url</a>" ) .
402 "</p>\n\n<p>" . $this->pageStats() . "</p>\n";
405 function doAfterContent()
407 global $wgUser, $wgOut, $wgLang;
408 $fname = "Skin::doAfterContent";
409 wfProfileIn( $fname );
410 wfProfileIn( "$fname-1" );
412 $s = "\n</div><br style=\"clear:both\" />\n";
413 $s .= "\n<div id='footer'>";
414 $s .= "<table border='0' cellspacing='0'><tr>";
416 wfProfileOut( "$fname-1" );
417 wfProfileIn( "$fname-2" );
419 $qb = $this->qbSetting();
421 $left = ($qb == 1 ||
$qb == 3);
422 if($wgLang->isRTL()) $left = !$left;
424 if ( $shove && $left ) { # Left
425 $s .= $this->getQuickbarCompensator();
427 wfProfileOut( "$fname-2" );
428 wfProfileIn( "$fname-3" );
429 $l = $wgLang->isRTL() ?
"right" : "left";
430 $s .= "<td class='bottom' align='$l' valign='top'>";
432 $s .= $this->bottomLinks();
433 $s .= "\n<br />" . $this->mainPageLink()
434 . " | " . $this->aboutLink()
435 . " | " . $this->specialLink( "recentchanges" )
436 . " | " . $this->searchForm()
437 . "<br /><span id='pagestats'>" . $this->pageStats() . "</span>";
440 if ( $shove && !$left ) { # Right
441 $s .= $this->getQuickbarCompensator();
443 $s .= "</tr></table>\n</div>\n</div>\n";
445 wfProfileOut( "$fname-3" );
446 wfProfileIn( "$fname-4" );
447 if ( 0 != $qb ) { $s .= $this->quickBar(); }
448 wfProfileOut( "$fname-4" );
449 wfProfileOut( $fname );
453 function pageTitleLinks()
455 global $wgOut, $wgTitle, $wgUser, $wgLang, $wgUseApproval, $wgRequest;
457 extract( $wgRequest->getValues( 'oldid', 'diff' ) );
458 $action = $wgRequest->getText( 'action' );
460 $s = $this->printableLink();
461 if ( wfMsg ( "disclaimers" ) != "-" ) $s .= " | " . $this->makeKnownLink( wfMsg( "disclaimerpage" ), wfMsg( "disclaimers" ) ) ;
463 if ( $wgOut->isArticleRelated() ) {
464 if ( $wgTitle->getNamespace() == Namespace::getImage() ) {
465 $name = $wgTitle->getDBkey();
466 $link = wfEscapeHTML( Image
::wfImageUrl( $name ) );
467 $style = $this->getInternalLinkAttributes( $link, $name );
468 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>";
470 # This will show the "Approve" link if $wgUseApproval=true;
471 if ( isset ( $wgUseApproval ) && $wgUseApproval )
473 $t = $wgTitle->getDBkey();
474 $name = "Approve this article" ;
475 $link = "http://test.wikipedia.org/w/magnus/wiki.phtml?title={$t}&action=submit&doit=1" ;
476 #wfEscapeHTML( wfImageUrl( $name ) );
477 $style = $this->getExternalLinkAttributes( $link, $name );
478 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>" ;
481 if ( "history" == $action ||
isset( $diff ) ||
isset( $oldid ) ) {
482 $s .= " | " . $this->makeKnownLink( $wgTitle->getPrefixedText(),
483 wfMsg( "currentrev" ) );
486 if ( $wgUser->getNewtalk() ) {
487 # do not show "You have new messages" text when we are viewing our
490 if(!(strcmp($wgTitle->getText(),$wgUser->getName()) == 0 &&
491 $wgTitle->getNamespace()==Namespace::getTalk(Namespace::getUser()))) {
492 $n =$wgUser->getName();
493 $tl = $this->makeKnownLink( $wgLang->getNsText(
494 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
495 wfMsg("newmessageslink") );
496 $s.=" | <strong>". wfMsg( "newmessages", $tl ) . "</strong>";
500 $undelete = $this->getUndeleteLink();
501 if( !empty( $undelete ) ) {
502 $s .= " | $undelete";
507 function getUndeleteLink() {
508 global $wgUser, $wgTitle, $wgLang, $action;
509 if( $wgUser->isSysop() &&
510 (($wgTitle->getArticleId() == 0) ||
($action == "history")) &&
511 ($n = $wgTitle->isDeleted() ) ) {
512 return wfMsg( "thisisdeleted",
513 $this->makeKnownLink(
514 $wgLang->SpecialPage( "Undelete/" . $wgTitle->getPrefixedDBkey() ),
515 wfMsg( "restorelink", $n ) ) );
520 function printableLink()
522 global $wgOut, $wgFeedClasses, $wgRequest;
524 $baseurl = $_SERVER['REQUEST_URI'];
525 if( strpos( "?", $baseurl ) == false ) {
530 $baseurl = htmlspecialchars( $baseurl );
531 $printurl = $wgRequest->escapeAppendQuery( "printable=yes" );
533 $s = "<a href=\"$printurl\">" . wfMsg( "printableversion" ) . "</a>";
534 if( $wgOut->isSyndicated() ) {
535 foreach( $wgFeedClasses as $format => $class ) {
536 $feedurl = $wgRequest->escapeAppendQuery( "feed=$format" );
537 $s .= " | <a href=\"$feedurl\">{$format}</a>";
545 global $wgOut, $wgTitle, $wgUser;
547 $s = "<h1 class='pagetitle'>" . htmlspecialchars( $wgOut->getPageTitle() ) . "</h1>";
548 if($wgUser->getOption("editsectiononrightclick") && $wgTitle->userCanEdit()) { $s=$this->editSectionScript(0,$s);}
552 function pageSubtitle()
556 $sub = $wgOut->getSubtitle();
558 global $wgExtraSubtitle;
559 $sub = wfMsg( "fromwikipedia" ) . $wgExtraSubtitle;
561 $subpages = $this->subPageSubtitle();
562 $sub .= !empty($subpages)?
"</p><p class='subpages'>$subpages":'';
563 $s = "<p class='subtitle'>{$sub}</p>\n";
567 function subPageSubtitle()
569 global $wgOut,$wgTitle,$wgNamespacesWithSubpages;
571 if($wgOut->isArticle() && !empty($wgNamespacesWithSubpages[$wgTitle->getNamespace()])) {
572 $ptext=$wgTitle->getPrefixedText();
573 if(preg_match("/\//",$ptext)) {
574 $links=explode("/",$ptext);
577 foreach($links as $link) {
579 if ($c<count($links)) {
580 $growinglink .= $link;
581 $getlink = $this->makeLink( $growinglink, $link );
582 if(preg_match("/class='new'/i",$getlink)) { break; } # this is a hack, but it saves time
588 $subpages .= $getlink;
597 function nameAndLogin()
599 global $wgUser, $wgTitle, $wgLang, $wgShowIPinHeader, $wgIP;
601 $li = $wgLang->specialPage( "Userlogin" );
602 $lo = $wgLang->specialPage( "Userlogout" );
605 if ( 0 == $wgUser->getID() ) {
606 if( $wgShowIPinHeader && isset( $_COOKIE[ini_get("session.name")] ) ) {
609 $tl = $this->makeKnownLink( $wgLang->getNsText(
610 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
611 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
613 $s .= $n . " (".$tl.")";
615 $s .= wfMsg("notloggedin");
618 $rt = $wgTitle->getPrefixedURL();
619 if ( 0 == strcasecmp( urlencode( $lo ), $rt ) ) {
621 } else { $q = "returnto={$rt}"; }
623 $s .= "\n<br />" . $this->makeKnownLink( $li,
624 wfMsg( "login" ), $q );
626 $n = $wgUser->getName();
627 $rt = $wgTitle->getPrefixedURL();
628 $tl = $this->makeKnownLink( $wgLang->getNsText(
629 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
630 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
634 $s .= $this->makeKnownLink( $wgLang->getNsText(
635 Namespace::getUser() ) . ":{$n}", $n ) . "{$tl}<br />" .
636 $this->makeKnownLink( $lo, wfMsg( "logout" ),
637 "returnto={$rt}" ) . " | " .
638 $this->specialLink( "preferences" );
640 $s .= " | " . $this->makeKnownLink( wfMsg( "helppage" ),
646 function getSearchLink() {
647 $searchPage =& Title
::makeTitle( NS_SPECIAL
, "Search" );
648 return $searchPage->getLocalURL();
651 function escapeSearchLink() {
652 return htmlspecialchars( $this->getSearchLink() );
655 function searchForm()
658 $search = $wgRequest->getText( 'search' );
660 $s = "<form name='search' class='inline' method='post' action=\""
661 . $this->escapeSearchLink() . "\">\n"
662 . "<input type='text' name=\"search\" size='19' value=\""
663 . htmlspecialchars(substr($search,0,256)) . "\" />\n"
664 . "<input type='submit' name=\"go\" value=\"" . wfMsg ("go") . "\" /> "
665 . "<input type='submit' name=\"fulltext\" value=\"" . wfMsg ("search") . "\" />\n</form>";
675 $s = $this->mainPageLink() . $sep
676 . $this->specialLink( "recentchanges" );
678 if ( $wgOut->isArticleRelated() ) {
679 $s .= $sep . $this->editThisPage()
680 . $sep . $this->historyLink();
682 # Many people don't like this dropdown box
683 #$s .= $sep . $this->specialPagesList();
688 function bottomLinks()
690 global $wgOut, $wgUser, $wgTitle;
694 if ( $wgOut->isArticleRelated() ) {
695 $s .= "<strong>" . $this->editThisPage() . "</strong>";
696 if ( 0 != $wgUser->getID() ) {
697 $s .= $sep . $this->watchThisPage();
699 $s .= $sep . $this->talkLink()
700 . $sep . $this->historyLink()
701 . $sep . $this->whatLinksHere()
702 . $sep . $this->watchPageLinksLink();
704 if ( $wgTitle->getNamespace() == Namespace::getUser()
705 ||
$wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser()) )
708 $id=User
::idFromName($wgTitle->getText());
709 $ip=User
::isIP($wgTitle->getText());
711 if($id ||
$ip) { # both anons and non-anons have contri list
712 $s .= $sep . $this->userContribsLink();
714 if ( 0 != $wgUser->getID() ) { # show only to signed in users
715 if($id) { # can only email non-anons
716 $s .= $sep . $this->emailUserLink();
720 if ( $wgUser->isSysop() && $wgTitle->getArticleId() ) {
721 $s .= "\n<br />" . $this->deleteThisPage() .
722 $sep . $this->protectThisPage() .
723 $sep . $this->moveThisPage();
725 $s .= "<br />\n" . $this->otherLanguages();
732 global $wgOut, $wgLang, $wgArticle, $wgRequest;
733 global $wgDisableCounters;
735 extract( $wgRequest->getValues( 'oldid', 'diff' ) );
736 if ( ! $wgOut->isArticle() ) { return ""; }
737 if ( isset( $oldid ) ||
isset( $diff ) ) { return ""; }
738 if ( 0 == $wgArticle->getID() ) { return ""; }
741 if ( !$wgDisableCounters ) {
742 $count = $wgLang->formatNum( $wgArticle->getCount() );
744 $s = wfMsg( "viewcount", $count );
748 $s .= " " . $this->getCredits();
750 return $s . " " . $this->getCopyright();
753 function getCredits() {
754 global $wgMaxCredits;
758 if (!isset($wgMaxCredits) ||
$wgMaxCredits == 0) {
759 $s = $this->lastModified();
761 $s = $this->getAuthorCredits();
762 if ($wgMaxCredits > 1) {
763 $s .= " " . $this->getContributorCredits();
770 function getAuthorCredits() {
771 global $wgLang, $wgArticle;
773 $last_author = $wgArticle->getUser();
775 if ($last_author == 0) {
776 $author_credit = wfMsg("anonymous");
778 $real_name = User
::whoIsReal($last_author);
779 if (!empty($real_name)) {
780 $author_credit = $real_name;
782 $author_credit = wfMsg("siteuser", User
::whoIs($last_author));
786 $timestamp = $wgArticle->getTimestamp();
788 $d = $wgLang->timeanddate( $wgArticle->getTimestamp(), true );
792 return wfMsg("lastmodifiedby", $d, $author_credit);
795 function getContributorCredits() {
797 global $wgArticle, $wgMaxCredits, $wgLang;
799 # don't count last editor
801 $contributors = $wgArticle->getContributors($wgMaxCredits - 1);
803 $real_names = array();
804 $user_names = array();
806 # Sift for real versus user names
808 foreach ($contributors as $user_id => $user_parts) {
810 if (!empty($user_parts[1])) {
811 $real_names[$user_id] = $user_parts[1];
813 $user_names[$user_id] = $user_parts[0];
818 $real = $wgLang->listToText(array_values($real_names));
819 $user = $wgLang->listToText(array_values($user_names));
822 $user = wfMsg("siteusers", $user);
825 if ($contributors[0] && $contributors[0][0] > 0) {
826 $anon = wfMsg("anonymous");
831 $creds = $wgLang->listToText(array($real, $user, $anon));
833 return wfMsg("othercontribs", $creds);
836 function getCopyright() {
837 global $wgRightsPage, $wgRightsUrl, $wgRightsText;
839 if( $wgRightsPage ) {
840 $link = $this->makeKnownLink( $wgRightsPage, $wgRightsText );
841 } elseif( $wgRightsUrl ) {
842 $link = $this->makeExternalLink( $wgRightsUrl, $wgRightsText );
847 $out .= wfMsg( "copyright", $link );
851 function getCopyrightIcon() {
852 global $wgRightsPage, $wgRightsUrl, $wgRightsText, $wgRightsIcon;
854 if( $wgRightsIcon ) {
855 $icon = htmlspecialchars( $wgRightsIcon );
857 $url = htmlspecialchars( $wgRightsUrl );
858 $out .= "<a href=\"$url\">";
860 $text = htmlspecialchars( $wgRightsText );
861 $out .= "<img src=\"$icon\" alt='$text' />";
869 function getPoweredBy() {
871 $url = htmlspecialchars( "$wgStylePath/images/poweredby_mediawiki_88x31.png" );
872 $img = "<a href='http://www.mediawiki.org/'><img src='$url' alt='MediaWiki' /></a>";
876 function lastModified()
878 global $wgLang, $wgArticle;
880 $timestamp = $wgArticle->getTimestamp();
882 $d = $wgLang->timeanddate( $wgArticle->getTimestamp(), true );
883 $s = " " . wfMsg( "lastmodified", $d );
890 function logoText( $align = "" )
892 if ( "" != $align ) { $a = " align='{$align}'"; }
895 $mp = wfMsg( "mainpage" );
896 $titleObj = Title
::newFromText( $mp );
897 $s = "<a href=\"" . $titleObj->escapeLocalURL()
898 . "\"><img{$a} src=\""
899 . $this->getLogo() . "\" alt=\"" . "[{$mp}]\" /></a>";
905 global $wgOut, $wgTitle, $wgUser, $wgRequest, $wgLang;
906 global $wgDisableUploads, $wgRemoteUploads;
908 $fname = "Skin::quickBar";
909 wfProfileIn( $fname );
911 $action = $wgRequest->getText( 'action' );
912 $wpPreview = $wgRequest->getBool( 'wpPreview' );
913 $tns=$wgTitle->getNamespace();
915 $s = "\n<div id='quickbar'>";
916 $s .= "\n" . $this->logoText() . "\n<hr class='sep' />";
919 $s .= $this->mainPageLink()
920 . $sep . $this->specialLink( "recentchanges" )
921 . $sep . $this->specialLink( "randompage" );
922 if ($wgUser->getID()) {
923 $s.= $sep . $this->specialLink( "watchlist" ) ;
924 $s .= $sep .$this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
925 wfMsg( "mycontris" ), "target=" . wfUrlencode($wgUser->getName() ) );
928 // only show watchlist link if logged in
929 if ( wfMsg ( "currentevents" ) != "-" ) $s .= $sep . $this->makeKnownLink( wfMsg( "currentevents" ), "" ) ;
930 $s .= "\n<br /><hr class='sep' />";
931 $articleExists = $wgTitle->getArticleId();
932 if ( $wgOut->isArticle() ||
$action =="edit" ||
$action =="history" ||
$wpPreview) {
933 if($wgOut->isArticle()) {
934 $s .= "<strong>" . $this->editThisPage() . "</strong>";
935 } else { # backlink to the article in edit or history mode
936 if($articleExists){ # no backlink if no article
939 $text = wfMsg("articlepage");
942 $text = wfMsg("viewtalkpage");
945 $text = wfMsg("userpage");
948 $text = wfMsg("viewtalkpage");
951 $text = wfMsg("wikipediapage");
954 $text = wfMsg("viewtalkpage");
957 $text = wfMsg("imagepage");
960 $text = wfMsg("viewtalkpage");
963 $text= wfMsg("articlepage");
966 $link = $wgTitle->getText();
967 if ($nstext = $wgLang->getNsText($tns) ) { # add namespace if necessary
968 $link = $nstext . ":" . $link ;
971 $s .= $this->makeLink( $link, $text );
972 } elseif( $wgTitle->getNamespace() != Namespace::getSpecial() ) {
973 # we just throw in a "New page" text to tell the user that he's in edit mode,
974 # and to avoid messing with the separator that is prepended to the next item
975 $s .= "<strong>" . wfMsg("newpage") . "</strong>";
981 if( $tns%2
&& $action!="edit" && !$wpPreview) {
982 $s.="<br />".$this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg("postcomment"),"action=edit§ion=new");
986 watching could cause problems in edit mode:
987 if user edits article, then loads "watch this article" in background and then saves
988 article with "Watch this article" checkbox disabled, the article is transparently
989 unwatched. Therefore we do not show the "Watch this page" link in edit mode
991 if ( 0 != $wgUser->getID() && $articleExists) {
992 if($action!="edit" && $action != "submit" )
994 $s .= $sep . $this->watchThisPage();
996 if ( $wgTitle->userCanEdit() )
997 $s .= $sep . $this->moveThisPage();
999 if ( $wgUser->isSysop() and $articleExists ) {
1000 $s .= $sep . $this->deleteThisPage() .
1001 $sep . $this->protectThisPage();
1003 $s .= $sep . $this->talkLink();
1004 if ($articleExists && $action !="history") {
1005 $s .= $sep . $this->historyLink();
1007 $s.=$sep . $this->whatLinksHere();
1009 if($wgOut->isArticleRelated()) {
1010 $s .= $sep . $this->watchPageLinksLink();
1013 if ( Namespace::getUser() == $wgTitle->getNamespace()
1014 ||
$wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser())
1017 $id=User
::idFromName($wgTitle->getText());
1018 $ip=User
::isIP($wgTitle->getText());
1021 $s .= $sep . $this->userContribsLink();
1023 if ( 0 != $wgUser->getID() ) {
1024 if($id) { # can only email real users
1025 $s .= $sep . $this->emailUserLink();
1029 $s .= "\n<br /><hr class='sep' />";
1032 if ( 0 != $wgUser->getID() && ( !$wgDisableUploads ||
$wgRemoteUploads ) ) {
1033 $s .= $this->specialLink( "upload" ) . $sep;
1035 $s .= $this->specialLink( "specialpages" )
1036 . $sep . $this->bugReportsLink();
1038 global $wgSiteSupportPage;
1039 if( $wgSiteSupportPage ) {
1040 $s .= "\n<br /><a href=\"" . htmlspecialchars( $wgSiteSupportPage ) .
1041 "\" class=\"internal\">" . wfMsg( "sitesupport" ) . "</a>";
1044 $s .= "\n<br /></div>\n";
1045 wfProfileOut( $fname );
1049 function specialPagesList()
1051 global $wgUser, $wgOut, $wgLang, $wgServer, $wgRedirectScript;
1053 $pages = SpecialPage
::getPages();
1055 foreach ( $pages[""] as $name => $page ) {
1056 $a[$name] = $page->getDescription();
1058 if ( $wgUser->isSysop() )
1060 foreach ( $pages["sysop"] as $name => $page ) {
1061 $a[$name] = $page->getDescription();
1064 if ( $wgUser->isDeveloper() )
1066 foreach ( $pages["developer"] as $name => $page ) {
1067 $a[$name] = $page->getDescription() ;
1070 $go = wfMsg( "go" );
1071 $sp = wfMsg( "specialpages" );
1072 $spp = $wgLang->specialPage( "Specialpages" );
1074 $s = "<form id=\"specialpages\" method=\"get\" class=\"inline\" " .
1075 "action=\"" . htmlspecialchars( "{$wgServer}{$wgRedirectScript}" ) . "\">\n";
1076 $s .= "<select name=\"wpDropdown\">\n";
1077 $s .= "<option value=\"{$spp}\">{$sp}</option>\n";
1079 foreach ( $a as $name => $desc ) {
1080 $p = $wgLang->specialPage( $name );
1081 $s .= "<option value=\"{$p}\">{$desc}</option>\n";
1083 $s .= "</select>\n";
1084 $s .= "<input type='submit' value=\"{$go}\" name='redirect' />\n";
1089 function mainPageLink()
1091 $mp = wfMsg( "mainpage" );
1092 $s = $this->makeKnownLink( $mp, $mp );
1096 function copyrightLink()
1098 $s = $this->makeKnownLink( wfMsg( "copyrightpage" ),
1099 wfMsg( "copyrightpagename" ) );
1103 function aboutLink()
1105 $s = $this->makeKnownLink( wfMsg( "aboutpage" ),
1106 wfMsg( "aboutwikipedia" ) );
1111 function disclaimerLink()
1113 $s = $this->makeKnownLink( wfMsg( "disclaimerpage" ),
1114 wfMsg( "disclaimers" ) );
1118 function editThisPage()
1120 global $wgOut, $wgTitle, $wgRequest;
1122 $oldid = $wgRequest->getVal( 'oldid' );
1123 $diff = $wgRequest->getVal( 'diff' );
1124 $redirect = $wgRequest->getVal( 'redirect' );
1126 if ( ! $wgOut->isArticleRelated() ) {
1127 $s = wfMsg( "protectedpage" );
1129 $n = $wgTitle->getPrefixedText();
1130 if ( $wgTitle->userCanEdit() ) {
1131 $t = wfMsg( "editthispage" );
1133 #$t = wfMsg( "protectedpage" );
1134 $t = wfMsg( "viewsource" );
1138 if ( !is_null( $redirect ) ) { $red = "&redirect={$redirect}"; }
1139 if ( $oldid && ! isset( $diff ) ) {
1140 $oid = "&oldid={$oldid}";
1142 $s = $this->makeKnownLink( $n, $t, "action=edit{$oid}{$red}" );
1147 function deleteThisPage()
1149 global $wgUser, $wgOut, $wgTitle, $wgRequest;
1151 $diff = $wgRequest->getVal( 'diff' );
1152 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
1153 $n = $wgTitle->getPrefixedText();
1154 $t = wfMsg( "deletethispage" );
1156 $s = $this->makeKnownLink( $n, $t, "action=delete" );
1163 function protectThisPage()
1165 global $wgUser, $wgOut, $wgTitle, $wgRequest;
1167 $diff = $wgRequest->getVal( 'diff' );
1168 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
1169 $n = $wgTitle->getPrefixedText();
1171 if ( $wgTitle->isProtected() ) {
1172 $t = wfMsg( "unprotectthispage" );
1173 $q = "action=unprotect";
1175 $t = wfMsg( "protectthispage" );
1176 $q = "action=protect";
1178 $s = $this->makeKnownLink( $n, $t, $q );
1185 function watchThisPage()
1187 global $wgUser, $wgOut, $wgTitle;
1189 if ( $wgOut->isArticleRelated() ) {
1190 $n = $wgTitle->getPrefixedText();
1192 if ( $wgTitle->userIsWatching() ) {
1193 $t = wfMsg( "unwatchthispage" );
1194 $q = "action=unwatch";
1196 $t = wfMsg( "watchthispage" );
1197 $q = "action=watch";
1199 $s = $this->makeKnownLink( $n, $t, $q );
1201 $s = wfMsg( "notanarticle" );
1206 function moveThisPage()
1208 global $wgTitle, $wgLang;
1210 if ( $wgTitle->userCanEdit() ) {
1211 $s = $this->makeKnownLink( $wgLang->specialPage( "Movepage" ),
1212 wfMsg( "movethispage" ), "target=" . $wgTitle->getPrefixedURL() );
1213 } // no message if page is protected - would be redundant
1217 function historyLink()
1221 $s = $this->makeKnownLink( $wgTitle->getPrefixedText(),
1222 wfMsg( "history" ), "action=history" );
1226 function whatLinksHere()
1228 global $wgTitle, $wgLang;
1230 $s = $this->makeKnownLink( $wgLang->specialPage( "Whatlinkshere" ),
1231 wfMsg( "whatlinkshere" ), "target=" . $wgTitle->getPrefixedURL() );
1235 function userContribsLink()
1237 global $wgTitle, $wgLang;
1239 $s = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
1240 wfMsg( "contributions" ), "target=" . $wgTitle->getPartialURL() );
1244 function emailUserLink()
1246 global $wgTitle, $wgLang;
1248 $s = $this->makeKnownLink( $wgLang->specialPage( "Emailuser" ),
1249 wfMsg( "emailuser" ), "target=" . $wgTitle->getPartialURL() );
1253 function watchPageLinksLink()
1255 global $wgOut, $wgTitle, $wgLang;
1257 if ( ! $wgOut->isArticleRelated() ) {
1258 $s = "(" . wfMsg( "notanarticle" ) . ")";
1260 $s = $this->makeKnownLink( $wgLang->specialPage(
1261 "Recentchangeslinked" ), wfMsg( "recentchangeslinked" ),
1262 "target=" . $wgTitle->getPrefixedURL() );
1267 function otherLanguages()
1269 global $wgOut, $wgLang, $wgTitle, $wgUseNewInterlanguage;
1271 $a = $wgOut->getLanguageLinks();
1272 if ( 0 == count( $a ) ) {
1273 if ( !$wgUseNewInterlanguage ) return "";
1274 $ns = $wgLang->getNsIndex ( $wgTitle->getNamespace () ) ;
1275 if ( $ns != 0 AND $ns != 1 ) return "" ;
1277 $x = "mode=addlink&xt=".$wgTitle->getDBkey() ;
1278 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1279 wfMsg( "intl" ) , $x );
1282 if ( !$wgUseNewInterlanguage ) {
1283 $s = wfMsg( "otherlanguages" ) . ": ";
1285 global $wgLanguageCode ;
1286 $x = "mode=zoom&xt=".$wgTitle->getDBkey() ;
1287 $x .= "&xl=".$wgLanguageCode ;
1288 $s = $this->makeKnownLink( $wgLang->specialPage( "Intl" ),
1289 wfMsg( "otherlanguages" ) , $x ) . ": " ;
1292 $s = wfMsg( "otherlanguages" ) . ": ";
1294 if($wgLang->isRTL()) $s .= "<span dir='LTR'>";
1295 foreach( $a as $l ) {
1296 if ( ! $first ) { $s .= " | "; }
1299 $nt = Title
::newFromText( $l );
1300 $url = $nt->getFullURL();
1301 $text = $wgLang->getLanguageName( $nt->getInterwiki() );
1303 if ( "" == $text ) { $text = $l; }
1304 $style = $this->getExternalLinkAttributes( $l, $text );
1305 $s .= "<a href=\"{$url}\"{$style}>{$text}</a>";
1307 if($wgLang->isRTL()) $s .= "</span>";
1311 function bugReportsLink()
1313 $s = $this->makeKnownLink( wfMsg( "bugreportspage" ),
1314 wfMsg( "bugreports" ) );
1320 global $wgLinkCache;
1321 $t1 = Title
::newFromText( gmdate( "F j" ) );
1322 $t2 = Title
::newFromText( gmdate( "Y" ) );
1324 $wgLinkCache->suspend();
1325 $id = $t1->getArticleID();
1326 $wgLinkCache->resume();
1329 $s = $this->makeBrokenLink( $t1->getText() );
1331 $s = $this->makeKnownLink( $t1->getText() );
1335 $wgLinkCache->suspend();
1336 $id = $t2->getArticleID();
1337 $wgLinkCache->resume();
1340 $s .= $this->makeBrokenLink( $t2->getText() );
1342 $s .= $this->makeKnownLink( $t2->getText() );
1349 global $wgLang, $wgTitle, $wgLinkCache;
1351 $tns = $wgTitle->getNamespace();
1352 if ( -1 == $tns ) { return ""; }
1354 $pn = $wgTitle->getText();
1355 $tp = wfMsg( "talkpage" );
1356 if ( Namespace::isTalk( $tns ) ) {
1357 $lns = Namespace::getSubject( $tns );
1360 $text = wfMsg("articlepage");
1363 $text = wfMsg("userpage");
1366 $text = wfMsg("wikipediapage");
1369 $text = wfMsg("imagepage");
1372 $text= wfMsg("articlepage");
1376 $lns = Namespace::getTalk( $tns );
1379 $n = $wgLang->getNsText( $lns );
1380 if ( "" == $n ) { $link = $pn; }
1381 else { $link = "{$n}:{$pn}"; }
1383 $wgLinkCache->suspend();
1384 $s = $this->makeLink( $link, $text );
1385 $wgLinkCache->resume();
1390 function commentLink()
1392 global $wgLang, $wgTitle, $wgLinkCache;
1394 $tns = $wgTitle->getNamespace();
1395 if ( -1 == $tns ) { return ""; }
1397 $lns = ( Namespace::isTalk( $tns ) ) ?
$tns : Namespace::getTalk( $tns );
1399 # assert Namespace::isTalk( $lns )
1401 $n = $wgLang->getNsText( $lns );
1402 $pn = $wgTitle->getText();
1404 $link = "{$n}:{$pn}";
1406 $wgLinkCache->suspend();
1407 $s = $this->makeKnownLink($link, wfMsg("postcomment"), "action=edit§ion=new");
1408 $wgLinkCache->resume();
1413 # After all the page content is transformed into HTML, it makes
1414 # a final pass through here for things like table backgrounds.
1416 function transformContent( $text )
1421 # Note: This function MUST call getArticleID() on the link,
1422 # otherwise the cache won't get updated properly. See LINKCACHE.DOC.
1424 function makeLink( $title, $text = "", $query = "", $trail = "" ) {
1425 wfProfileIn( "Skin::makeLink" );
1426 $nt = Title
::newFromText( $title );
1428 $result = $this->makeLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1430 wfDebug( "Invalid title passed to Skin::makeLink(): \"$title\"\n" );
1431 $result = $text == "" ?
$title : $text;
1434 wfProfileOut( "Skin::makeLink" );
1438 function makeKnownLink( $title, $text = "", $query = "", $trail = "", $prefix = '',$aprops = '') {
1439 $nt = Title
::newFromText( $title );
1441 return $this->makeKnownLinkObj( Title
::newFromText( $title ), $text, $query, $trail, $prefix , $aprops );
1443 wfDebug( "Invalid title passed to Skin::makeKnownLink(): \"$title\"\n" );
1444 return $text == "" ?
$title : $text;
1448 function makeBrokenLink( $title, $text = "", $query = "", $trail = "" ) {
1449 $nt = Title
::newFromText( $title );
1451 return $this->makeBrokenLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1453 wfDebug( "Invalid title passed to Skin::makeBrokenLink(): \"$title\"\n" );
1454 return $text == "" ?
$title : $text;
1458 function makeStubLink( $title, $text = "", $query = "", $trail = "" ) {
1459 $nt = Title
::newFromText( $title );
1461 return $this->makeStubLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1463 wfDebug( "Invalid title passed to Skin::makeStubLink(): \"$title\"\n" );
1464 return $text == "" ?
$title : $text;
1468 # Pass a title object, not a title string
1469 function makeLinkObj( &$nt, $text= "", $query = "", $trail = "", $prefix = "" )
1471 global $wgOut, $wgUser;
1472 if ( $nt->isExternal() ) {
1473 $u = $nt->getFullURL();
1474 $link = $nt->getPrefixedURL();
1475 if ( "" == $text ) { $text = $nt->getPrefixedText(); }
1476 $style = $this->getExternalLinkAttributes( $link, $text );
1479 if ( "" != $trail ) {
1480 if ( preg_match( "/^([a-z]+)(.*)$$/sD", $trail, $m ) ) {
1485 $retVal = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1486 } elseif ( 0 == $nt->getNamespace() && "" == $nt->getText() ) {
1487 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1488 } elseif ( ( -1 == $nt->getNamespace() ) ||
1489 ( Namespace::getImage() == $nt->getNamespace() ) ) {
1490 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1492 $aid = $nt->getArticleID() ;
1494 $retVal = $this->makeBrokenLinkObj( $nt, $text, $query, $trail, $prefix );
1496 $threshold = $wgUser->getOption("stubthreshold") ;
1497 if ( $threshold > 0 ) {
1498 $res = wfQuery ( "SELECT LENGTH(cur_text) AS x, cur_namespace, cur_is_redirect FROM cur WHERE cur_id='{$aid}'", DB_READ
) ;
1500 if ( wfNumRows( $res ) > 0 ) {
1501 $s = wfFetchObject( $res );
1503 if ( $s->cur_is_redirect
OR $s->cur_namespace
!= 0 ) {
1504 $size = $threshold*2 ; # Really big
1506 wfFreeResult( $res );
1508 $size = $threshold*2 ; # Really big
1513 if ( $size < $threshold ) {
1514 $retVal = $this->makeStubLinkObj( $nt, $text, $query, $trail, $prefix );
1516 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1523 # Pass a title object, not a title string
1524 function makeKnownLinkObj( &$nt, $text = "", $query = "", $trail = "", $prefix = "" , $aprops = '')
1526 global $wgOut, $wgTitle;
1528 $fname = "Skin::makeKnownLinkObj";
1529 wfProfileIn( $fname );
1531 $link = $nt->getPrefixedURL();
1533 if ( "" == $link ) {
1535 if ( "" == $text ) {
1536 $text = htmlspecialchars( $nt->getFragment() );
1539 $u = $nt->escapeLocalURL( $query );
1541 if ( "" != $nt->getFragment() ) {
1542 $u .= "#" . htmlspecialchars( $nt->getFragment() );
1544 if ( "" == $text ) {
1545 $text = htmlspecialchars( $nt->getPrefixedText() );
1547 $style = $this->getInternalLinkAttributesObj( $nt, $text );
1550 if ( "" != $trail ) {
1551 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1556 $r = "<a href=\"{$u}\"{$style}{$aprops}>{$prefix}{$text}{$inside}</a>{$trail}";
1557 wfProfileOut( $fname );
1561 # Pass a title object, not a title string
1562 function makeBrokenLinkObj( &$nt, $text = "", $query = "", $trail = "", $prefix = "" )
1564 global $wgOut, $wgUser;
1566 $fname = "Skin::makeBrokenLinkObj";
1567 wfProfileIn( $fname );
1569 if ( "" == $query ) {
1572 $q = "action=edit&{$query}";
1574 $u = $nt->escapeLocalURL( $q );
1576 if ( "" == $text ) {
1577 $text = htmlspecialchars( $nt->getPrefixedText() );
1579 $style = $this->getInternalLinkAttributesObj( $nt, $text, "yes" );
1582 if ( "" != $trail ) {
1583 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1588 if ( $wgUser->getOption( "highlightbroken" ) ) {
1589 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1591 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>?</a>{$trail}";
1594 wfProfileOut( $fname );
1598 # Pass a title object, not a title string
1599 function makeStubLinkObj( &$nt, $text = "", $query = "", $trail = "", $prefix = "" )
1601 global $wgOut, $wgUser;
1603 $link = $nt->getPrefixedURL();
1605 $u = $nt->escapeLocalURL( $query );
1607 if ( "" == $text ) {
1608 $text = htmlspecialchars( $nt->getPrefixedText() );
1610 $style = $this->getInternalLinkAttributesObj( $nt, $text, "stub" );
1613 if ( "" != $trail ) {
1614 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1619 if ( $wgUser->getOption( "highlightbroken" ) ) {
1620 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1622 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>!</a>{$trail}";
1627 function makeSelfLinkObj( &$nt, $text = "", $query = "", $trail = "", $prefix = "" )
1629 $u = $nt->escapeLocalURL( $query );
1630 if ( "" == $text ) {
1631 $text = htmlspecialchars( $nt->getPrefixedText() );
1634 if ( "" != $trail ) {
1635 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1640 return "<strong>{$prefix}{$text}{$inside}</strong>{$trail}";
1643 /* these are used extensively in SkinPHPTal, but also some other places */
1644 /*static*/ function makeSpecialUrl( $name, $urlaction='' ) {
1645 $title = Title
::makeTitle( NS_SPECIAL
, $name );
1646 $this->checkTitle($title, $name);
1647 return $title->getLocalURL( $urlaction );
1649 /*static*/ function makeTalkUrl ( $name, $urlaction='' ) {
1650 $title = Title
::newFromText( $name );
1651 $title = $title->getTalkPage();
1652 $this->checkTitle($title, $name);
1653 return $title->getLocalURL( $urlaction );
1655 /*static*/ function makeArticleUrl ( $name, $urlaction='' ) {
1656 $title = Title
::newFromText( $name );
1657 $title= $title->getSubjectPage();
1658 $this->checkTitle($title, $name);
1659 return $title->getLocalURL( $urlaction );
1661 /*static*/ function makeI18nUrl ( $name, $urlaction='' ) {
1662 $title = Title
::newFromText( wfMsg($name) );
1663 $this->checkTitle($title, $name);
1664 return $title->getLocalURL( $urlaction );
1666 /*static*/ function makeUrl ( $name, $urlaction='' ) {
1667 $title = Title
::newFromText( $name );
1668 $this->checkTitle($title, $name);
1669 return $title->getLocalURL( $urlaction );
1672 /* these return an array with the 'href' and boolean 'exists' */
1673 /*static*/ function makeUrlDetails ( $name, $urlaction='' ) {
1674 $title = Title
::newFromText( $name );
1675 $this->checkTitle($title, $name);
1677 'href' => $title->getLocalURL( $urlaction ),
1678 'exists' => $title->getArticleID() != 0?
true:false
1681 /*static*/ function makeTalkUrlDetails ( $name, $urlaction='' ) {
1682 $title = Title
::newFromText( $name );
1683 $title = $title->getTalkPage();
1684 $this->checkTitle($title, $name);
1686 'href' => $title->getLocalURL( $urlaction ),
1687 'exists' => $title->getArticleID() != 0?
true:false
1690 /*static*/ function makeArticleUrlDetails ( $name, $urlaction='' ) {
1691 $title = Title
::newFromText( $name );
1692 $title= $title->getSubjectPage();
1693 $this->checkTitle($title, $name);
1695 'href' => $title->getLocalURL( $urlaction ),
1696 'exists' => $title->getArticleID() != 0?
true:false
1699 /*static*/ function makeI18nUrlDetails ( $name, $urlaction='' ) {
1700 $title = Title
::newFromText( wfMsg($name) );
1701 $this->checkTitle($title, $name);
1703 'href' => $title->getLocalURL( $urlaction ),
1704 'exists' => $title->getArticleID() != 0?
true:false
1708 # make sure we have some title to operate on
1709 /*static*/ function checkTitle ( &$title, &$name ) {
1710 if(!is_object($title)) {
1711 $title = Title
::newFromText( $name );
1712 if(!is_object($title)) {
1713 $title = Title
::newFromText( '<error: link target missing>' );
1718 function fnamePart( $url )
1720 $basename = strrchr( $url, "/" );
1721 if ( false === $basename ) { $basename = $url; }
1722 else { $basename = substr( $basename, 1 ); }
1723 return wfEscapeHTML( $basename );
1726 function makeImage( $url, $alt = "" )
1730 if ( "" == $alt ) { $alt = $this->fnamePart( $url ); }
1731 $s = "<img src=\"{$url}\" alt=\"{$alt}\" />";
1735 function makeImageLink( $name, $url, $alt = "" ) {
1736 $nt = Title
::makeTitle( Namespace::getImage(), $name );
1737 return $this->makeImageLinkObj( $nt, $alt );
1740 function makeImageLinkObj( $nt, $alt = "" ) {
1741 global $wgLang, $wgUseImageResize;
1742 $img = Image
::newFromTitle( $nt );
1743 $url = $img->getURL();
1746 $prefix = $postfix = "";
1748 if ( $wgUseImageResize ) {
1749 # Check if the alt text is of the form "options|alt text"
1751 # * thumbnail make a thumbnail with enlarge-icon and caption, alignment depends on lang
1752 # * left no resizing, just left align. label is used for alt= only
1753 # * right same, but right aligned
1754 # * none same, but not aligned
1755 # * ___px scale to ___ pixels width, no aligning. e.g. use in taxobox
1756 # * center center the image
1757 # * framed Keep original image size, no magnify-button.
1759 $part = explode( "|", $alt);
1761 $mwThumb =& MagicWord
::get( MAG_IMG_THUMBNAIL
);
1762 $mwLeft =& MagicWord
::get( MAG_IMG_LEFT
);
1763 $mwRight =& MagicWord
::get( MAG_IMG_RIGHT
);
1764 $mwNone =& MagicWord
::get( MAG_IMG_NONE
);
1765 $mwWidth =& MagicWord
::get( MAG_IMG_WIDTH
);
1766 $mwCenter =& MagicWord
::get( MAG_IMG_CENTER
);
1767 $mwFramed =& MagicWord
::get( MAG_IMG_FRAMED
);
1768 $alt = $part[count($part)-1];
1770 $height = $framed = $thumb = false;
1772 foreach( $part as $key => $val ) {
1773 if ( ! is_null( $mwThumb->matchVariableStartToEnd($val) ) ) {
1775 } elseif ( ! is_null( $mwRight->matchVariableStartToEnd($val) ) ) {
1776 # remember to set an alignment, don't render immediately
1778 } elseif ( ! is_null( $mwLeft->matchVariableStartToEnd($val) ) ) {
1779 # remember to set an alignment, don't render immediately
1781 } elseif ( ! is_null( $mwCenter->matchVariableStartToEnd($val) ) ) {
1782 # remember to set an alignment, don't render immediately
1784 } elseif ( ! is_null( $mwNone->matchVariableStartToEnd($val) ) ) {
1785 # remember to set an alignment, don't render immediately
1787 } elseif ( ! is_null( $match = $mwWidth->matchVariableStartToEnd($val) ) ) {
1788 # $match is the image width in pixels
1789 if ( preg_match( "/^([0-9]*)x([0-9]*)$/", $match, $m ) ) {
1790 $width = intval( $m[1] );
1791 $height = intval( $m[2] );
1793 $width = intval($match);
1795 } elseif ( ! is_null( $mwFramed->matchVariableStartToEnd($val) ) ) {
1799 if ( "center" == $align )
1801 $prefix = '<span style="text-align: center">';
1802 $postfix = '</span>';
1806 if ( $thumb ||
$framed ) {
1808 # Create a thumbnail. Alignment depends on language
1809 # writing direction, # right aligned for left-to-right-
1810 # languages ("Western languages"), left-aligned
1811 # for right-to-left-languages ("Semitic languages")
1813 # If thumbnail width has not been provided, it is set
1814 # here to 180 pixels
1815 if ( $align == "" ) {
1816 $align = $wgLang->isRTL() ?
"left" : "right";
1818 if ( ! isset($width) ) {
1821 return $prefix.$this->makeThumbLinkObj( $img, $alt, $align, $width, $height, $framed ).$postfix;
1823 } elseif ( isset($width) ) {
1825 # Create a resized image, without the additional thumbnail
1828 if ( ( ! $height === false )
1829 && ( $img->getHeight() * $width / $img->getWidth() > $height ) ) {
1830 print "height=$height<br>\nimg->getHeight() = ".$img->getHeight()."<br>\n";
1831 print "rescaling by factor ". $height / $img->getHeight() . "<br>\n";
1832 $width = $img->getWidth() * $height / $img->getHeight();
1834 $url = $img->createThumb( $width );
1836 } # endif $wgUseImageResize
1838 if ( empty( $alt ) ) {
1839 $alt = preg_replace( '/\.(.+?)^/', '', $img->getName() );
1841 $alt = htmlspecialchars( $alt );
1843 $u = $nt->escapeLocalURL();
1846 $s = str_replace( "$1", $img->getName(), wfMsg("missingimage") );
1847 $s .= "<br>{$alt}<br>{$url}<br>\n";
1849 $s = "<a href=\"{$u}\" class='image' title=\"{$alt}\">" .
1850 "<img src=\"{$url}\" alt=\"{$alt}\" /></a>";
1852 if ( "" != $align ) {
1853 $s = "<div class=\"float{$align}\"><span>{$s}</span></div>";
1855 return str_replace("\n", ' ',$prefix.$s.$postfix);
1859 function makeThumbLinkObj( $img, $label = "", $align = "right", $boxwidth = 180, $boxheight=false, $framed=false ) {
1860 global $wgStylePath, $wgLang;
1861 # $image = Title::makeTitle( Namespace::getImage(), $name );
1862 $url = $img->getURL();
1864 #$label = htmlspecialchars( $label );
1865 $alt = preg_replace( "/<[^>]*>/", "", $label);
1866 $alt = htmlspecialchars( $alt );
1868 if ( $img->exists() )
1870 $width = $img->getWidth();
1871 $height = $img->getHeight();
1873 $width = $height = 200;
1877 // Use image dimensions, don't scale
1879 $oboxwidth = $boxwidth +
2;
1880 $boxheight = $height;
1883 $h = intval( $height/($width/$boxwidth) );
1884 $oboxwidth = $boxwidth +
2;
1885 if ( ( ! $boxheight === false ) && ( $h > $boxheight ) )
1887 $boxwidth *= $boxheight/$h;
1891 $thumbUrl = $img->createThumb( $boxwidth );
1894 $u = $img->getEscapeLocalURL();
1896 $more = htmlspecialchars( wfMsg( "thumbnail-more" ) );
1897 $magnifyalign = $wgLang->isRTL() ?
"left" : "right";
1898 $textalign = $wgLang->isRTL() ?
' style="text-align:right"' : "";
1900 $s = "<div class=\"thumb t{$align}\"><div style=\"width:{$oboxwidth}px;\">";
1901 if ( $thumbUrl == "" ) {
1902 $s .= str_replace( "$1", $img->getName(), wfMsg("missingimage") );
1905 $s .= '<a href="'.$u.'" class="internal" title="'.$alt.'">'.
1906 '<img src="'.$thumbUrl.'" alt="'.$alt.'" ' .
1907 'width="'.$boxwidth.'" height="'.$boxheight.'" /></a>';
1911 $zoomicon = '<div class="magnify" style="float:'.$magnifyalign.'">'.
1912 '<a href="'.$u.'" class="internal" title="'.$more.'">'.
1913 '<img src="'.$wgStylePath.'/images/magnify-clip.png" ' .
1914 'width="15" height="11" alt="'.$more.'" /></a></div>';
1917 $s .= ' <div class="thumbcaption" '.$textalign.'>'.$zoomicon.$label."</div></div></div>";
1918 return str_replace("\n", ' ', $s);
1921 function makeMediaLink( $name, $url, $alt = "" ) {
1922 $nt = Title
::makeTitle( Namespace::getMedia(), $name );
1923 return $this->makeMediaLinkObj( $nt, $alt );
1926 function makeMediaLinkObj( $nt, $alt = "" )
1928 if ( ! isset( $nt ) )
1930 ### HOTFIX. Instead of breaking, return empry string.
1933 $name = $nt->getDBKey();
1934 $url = Image
::wfImageUrl( $name );
1935 if ( empty( $alt ) ) {
1936 $alt = preg_replace( '/\.(.+?)^/', '', $name );
1939 $u = htmlspecialchars( $url );
1940 $s = "<a href=\"{$u}\" class='internal' title=\"{$alt}\">{$alt}</a>";
1945 function specialLink( $name, $key = "" )
1949 if ( "" == $key ) { $key = strtolower( $name ); }
1950 $pn = $wgLang->ucfirst( $name );
1951 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1955 function makeExternalLink( $url, $text, $escape = true ) {
1956 $style = $this->getExternalLinkAttributes( $url, $text );
1957 $url = htmlspecialchars( $url );
1959 $text = htmlspecialchars( $text );
1961 return "<a href=\"$url\"$style>$text</a>";
1964 # Called by history lists and recent changes
1967 # Returns text for the start of the tabular part of RC
1968 function beginRecentChangesList()
1970 $this->rc_cache
= array() ;
1971 $this->rcMoveIndex
= 0;
1972 $this->rcCacheIndex
= 0 ;
1973 $this->lastdate
= "";
1974 $this->rclistOpen
= false;
1978 function beginImageHistoryList()
1980 $s = "\n<h2>" . wfMsg( "imghistory" ) . "</h2>\n" .
1981 "<p>" . wfMsg( "imghistlegend" ) . "</p>\n<ul class='special'>";
1985 # Returns text for the end of RC
1986 # If enhanced RC is in use, returns pretty much all the text
1987 function endRecentChangesList()
1989 $s = $this->recentChangesBlock() ;
1990 if( $this->rclistOpen
) {
1996 # Enhanced RC ungrouped line
1997 function recentChangesBlockLine ( $rcObj )
1999 global $wgStylePath, $wgLang ;
2001 # Get rc_xxxx variables
2002 extract( $rcObj->mAttribs
) ;
2003 $curIdEq = "curid=$rc_cur_id";
2008 $r .= "<img src='{$wgStylePath}/images/Arr_.png' width='12' height='12' border='0' />" ; $r .= "<tt>" ;
2010 if ( $rc_type == RC_MOVE
) {
2011 $r .= " ";
2013 # M & N (minor & new)
2014 $M = wfMsg( "minoreditletter" );
2015 $N = wfMsg( "newpageletter" );
2017 if ( $rc_type == RC_NEW
) {
2030 $r .= " ".$rcObj->timestamp
." " ;
2034 $link = $rcObj->link
;
2035 if ( $rcObj->watched
) $link = "<strong>{$link}</strong>" ;
2040 $r .= $rcObj->curlink
;
2044 $r .= $this->makeKnownLinkObj( $rcObj->getTitle(), wfMsg( "hist" ), "{$curIdEq}&action=history" );
2047 $r .= ") . . ".$rcObj->userlink
;
2048 $r .= $rcObj->usertalklink
;
2051 if ( $rc_comment != "" && $rc_type != RC_MOVE
) {
2052 $rc_comment=$this->formatComment($rc_comment);
2053 $r .= $wgLang->emphasize( " (".$rc_comment.")" );
2061 function recentChangesBlockGroup ( $block )
2063 global $wgStylePath, $wgLang ;
2066 $M = wfMsg( "minoreditletter" );
2067 $N = wfMsg( "newpageletter" );
2069 # Collate list of users
2071 $userlinks = array () ;
2072 foreach ( $block AS $rcObj ) {
2073 $oldid = $rcObj->mAttribs
['rc_last_oldid'];
2074 if ( $rcObj->mAttribs
['rc_new'] ) $isnew = true ;
2075 $u = $rcObj->userlink
;
2076 if ( !isset ( $userlinks[$u] ) ) $userlinks[$u] = 0 ;
2080 # Sort the list and convert to text
2081 krsort ( $userlinks ) ;
2082 asort ( $userlinks ) ;
2084 foreach ( $userlinks as $userlink => $count) {
2086 if ( $count > 1 ) $text .= " ({$count}×)" ;
2087 array_push ( $users , $text ) ;
2089 $users = " <font size='-1'>[".implode("; ",$users)."]</font>" ;
2092 $rci = "RCI{$this->rcCacheIndex}" ;
2093 $rcl = "RCL{$this->rcCacheIndex}" ;
2094 $rcm = "RCM{$this->rcCacheIndex}" ;
2095 $toggleLink = "javascript:toggleVisibility(\"{$rci}\",\"{$rcm}\",\"{$rcl}\")" ;
2096 $arrowdir = $wgLang->isRTL() ?
"l" : "r";
2097 $tl = "<span id='{$rcm}'><a href='$toggleLink'><img src='{$wgStylePath}/images/Arr_{$arrowdir}.png' width='12' height='12' /></a></span>" ;
2098 $tl .= "<span id='{$rcl}' style='display:none'><a href='$toggleLink'><img src='{$wgStylePath}/images/Arr_d.png' width='12' height='12' /></a></span>" ;
2104 if ( $isnew ) $r .= $N ;
2105 else $r .= " " ;
2106 $r .= " " ; # Minor
2109 $r .= " ".$block[0]->timestamp
." " ;
2113 $link = $block[0]->link
;
2114 if ( $block[0]->watched
) $link = "<strong>{$link}</strong>" ;
2117 $curIdEq = "curid=" . $block[0]->mAttribs
['rc_cur_id'];
2118 if ( $block[0]->mAttribs
['rc_type'] != RC_LOG
) {
2120 $r .= " (".count($block)." " ;
2121 if ( $isnew ) $r .= wfMsg("changes");
2122 else $r .= $this->makeKnownLinkObj( $block[0]->getTitle() , wfMsg("changes") ,
2123 "{$curIdEq}&diff=0&oldid=".$oldid ) ;
2127 $r .= $this->makeKnownLinkObj( $block[0]->getTitle(), wfMsg( "history" ), "{$curIdEq}&action=history" );
2135 $r .= "<div id='{$rci}' style='display:none'>" ;
2136 foreach ( $block AS $rcObj ) {
2137 # Get rc_xxxx variables
2138 extract( $rcObj->mAttribs
);
2140 $r .= "<img src='{$wgStylePath}/images/Arr_.png' width=12 height=12 />";
2141 $r .= "<tt> " ;
2142 if ( $rc_new ) $r .= $N ;
2143 else $r .= " " ;
2144 if ( $rc_minor ) $r .= $M ;
2145 else $r .= " " ;
2149 if ( $rc_last_oldid != 0 ) {
2150 $o = "oldid=".$rc_last_oldid ;
2152 if ( $rc_type == RC_LOG
) {
2153 $link = $rcObj->timestamp
;
2155 $link = $this->makeKnownLinkObj( $rcObj->getTitle(), $rcObj->timestamp
, "{$curIdEq}&$o" ) ;
2157 $link = "<tt>{$link}</tt>" ;
2161 $r .= $rcObj->curlink
;
2163 $r .= $rcObj->lastlink
;
2164 $r .= ") . . ".$rcObj->userlink
;
2165 $r .= $rcObj->usertalklink
;
2166 if ( $rc_comment != "" ) {
2167 $rc_comment=$this->formatComment($rc_comment);
2168 $r .= $wgLang->emphasize( " (".$rc_comment.")" ) ;
2174 $this->rcCacheIndex++
;
2178 # If enhanced RC is in use, this function takes the previously cached
2179 # RC lines, arranges them, and outputs the HTML
2180 function recentChangesBlock ()
2182 global $wgStylePath ;
2183 if ( count ( $this->rc_cache
) == 0 ) return "" ;
2185 foreach ( $this->rc_cache
AS $secureName => $block ) {
2186 if ( count ( $block ) < 2 ) {
2187 $blockOut .= $this->recentChangesBlockLine ( array_shift ( $block ) ) ;
2189 $blockOut .= $this->recentChangesBlockGroup ( $block ) ;
2193 return "<div>{$blockOut}</div>" ;
2196 # Called in a loop over all displayed RC entries
2197 # Either returns the line, or caches it for later use
2198 function recentChangesLine( &$rc, $watched = false )
2201 $usenew = $wgUser->getOption( "usenewrc" );
2203 $line = $this->recentChangesLineNew ( $rc, $watched ) ;
2205 $line = $this->recentChangesLineOld ( $rc, $watched ) ;
2209 function recentChangesLineOld( &$rc, $watched = false )
2211 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds;
2213 # Extract DB fields into local scope
2214 extract( $rc->mAttribs
);
2215 $curIdEq = "curid=" . $rc_cur_id;
2217 # Make date header if necessary
2218 $date = $wgLang->date( $rc_timestamp, true);
2220 if ( $date != $this->lastdate
) {
2221 if ( "" != $this->lastdate
) { $s .= "</ul>\n"; }
2222 $s .= "<h4>{$date}</h4>\n<ul class='special'>";
2223 $this->lastdate
= $date;
2224 $this->rclistOpen
= true;
2228 if ( $rc_type == RC_MOVE
) {
2230 $s .= "(" . wfMsg( "diff" ) . ") (";
2232 $s .= $this->makeKnownLinkObj( $rc->getMovedToTitle(), wfMsg( "hist" ), "action=history" ) .
2235 # "[[x]] moved to [[y]]"
2237 $s .= wfMsg( "1movedto2", $this->makeKnownLinkObj( $rc->getTitle(), "", "redirect=no" ),
2238 $this->makeKnownLinkObj( $rc->getMovedToTitle(), "" ) );
2242 if ( $rc_type == RC_NEW ||
$rc_type == RC_LOG
) {
2243 $diffLink = wfMsg( "diff" );
2245 $diffLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( "diff" ),
2246 "{$curIdEq}&diff={$rc_this_oldid}&oldid={$rc_last_oldid}" ,'' ,'' , ' tabindex="'.$rc->counter
.'"');
2248 $s .= "($diffLink) (";
2251 $s .= $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( "hist" ), "{$curIdEq}&action=history" );
2254 # M and N (minor and new)
2255 $M = wfMsg( "minoreditletter" );
2256 $N = wfMsg( "newpageletter" );
2257 if ( $rc_minor ) { $s .= " <strong>{$M}</strong>"; }
2258 if ( $rc_type == RC_NEW
) { $s .= "<strong>{$N}</strong>"; }
2261 $articleLink = $this->makeKnownLinkObj( $rc->getTitle(), "" );
2264 $articleLink = "<strong>{$articleLink}</strong>";
2266 $s .= " $articleLink";
2271 $s .= "; " . $wgLang->time( $rc_timestamp, true, $wgRCSeconds ) . " . . ";
2273 # User link (or contributions for unregistered users)
2274 if ( 0 == $rc_user ) {
2275 $userLink = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
2276 $rc_user_text, "target=" . $rc_user_text );
2278 $userLink = $this->makeLink( $wgLang->getNsText( NS_USER
) . ":{$rc_user_text}", $rc_user_text );
2283 $talkname=$wgLang->getNsText(NS_TALK
); # use the shorter name
2284 global $wgDisableAnonTalk;
2285 if( 0 == $rc_user && $wgDisableAnonTalk ) {
2288 $utns=$wgLang->getNsText(NS_USER_TALK
);
2289 $userTalkLink= $this->makeLink($utns . ":{$rc_user_text}", $talkname );
2293 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2294 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2295 "Blockip" ), wfMsg( "blocklink" ), "ip={$rc_user_text}" );
2299 if($userTalkLink) $userTalkLink .= " | ";
2300 $userTalkLink .= $blockLink;
2302 if($userTalkLink) $s.=" ({$userTalkLink})";
2305 if ( "" != $rc_comment && "*" != $rc_comment && $rc_type != RC_MOVE
) {
2306 $rc_comment=$this->formatComment($rc_comment);
2307 $s .= $wgLang->emphasize(" (" . $rc_comment . ")");
2314 # function recentChangesLineNew( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched = false, $oldid = 0 , $diffid = 0 )
2315 function recentChangesLineNew( &$baseRC, $watched = false )
2317 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds;
2319 # Create a specialised object
2320 $rc = RCCacheEntry
::newFromParent( $baseRC ) ;
2322 # Extract fields from DB into the function scope (rc_xxxx variables)
2323 extract( $rc->mAttribs
);
2324 $curIdEq = "curid=" . $rc_cur_id;
2326 # If it's a new day, add the headline and flush the cache
2327 $date = $wgLang->date( $rc_timestamp, true);
2329 if ( $date != $this->lastdate
) {
2330 # Process current cache
2331 $ret = $this->recentChangesBlock () ;
2332 $this->rc_cache
= array() ;
2333 $ret .= "<h4>{$date}</h4>\n";
2334 $this->lastdate
= $date;
2338 if ( $rc_type == RC_MOVE
) {
2339 $clink = $this->makeKnownLinkObj( $rc->getTitle(), "", "redirect=no" );
2340 $clink .= " " . wfMsg("movedto") . " ";
2341 $clink .= $this->makeKnownLinkObj( $rc->getMovedToTitle(), "" );
2343 $clink = $this->makeKnownLinkObj( $rc->getTitle(), "" ) ;
2346 $time = $wgLang->time( $rc_timestamp, true, $wgRCSeconds );
2347 $rc->watched
= $watched ;
2348 $rc->link
= $clink ;
2349 $rc->timestamp
= $time;
2352 if ( ( $rc_type == RC_NEW
&& $rc_this_oldid == 0 ) ||
$rc_type == RC_LOG ||
$rc_type == RC_MOVE
) {
2353 $curLink = wfMsg( "cur" );
2355 $curLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( "cur" ),
2356 "{$curIdEq}&diff=0&oldid={$rc_this_oldid}" ,'' ,'' , ' tabindex="'.$baseRC->counter
.'"' );
2360 $titleObj = $rc->getTitle();
2361 if ( $rc_last_oldid == 0 ||
$rc_type == RC_LOG ||
$rc_type == RC_MOVE
) {
2362 $lastLink = wfMsg( "last" );
2364 $lastLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( "last" ),
2365 "{$curIdEq}&diff={$rc_this_oldid}&oldid={$rc_last_oldid}" );
2368 # Make user link (or user contributions for unregistered users)
2369 if ( 0 == $rc_user ) {
2370 $userLink = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
2371 $rc_user_text, "target=" . $rc_user_text );
2373 $userLink = $this->makeLink( $wgLang->getNsText(
2374 Namespace::getUser() ) . ":{$rc_user_text}", $rc_user_text );
2377 $rc->userlink
= $userLink ;
2378 $rc->lastlink
= $lastLink ;
2379 $rc->curlink
= $curLink ;
2381 # Make user talk link
2382 $utns=$wgLang->getNsText(NS_USER_TALK
);
2383 $talkname=$wgLang->getNsText(NS_TALK
); # use the shorter name
2384 $userTalkLink= $this->makeLink($utns . ":{$rc_user_text}", $talkname );
2386 global $wgDisableAnonTalk;
2387 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2388 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2389 "Blockip" ), wfMsg( "blocklink" ), "ip={$rc_user_text}" );
2390 if( $wgDisableAnonTalk )
2391 $rc->usertalklink
= " ({$blockLink})";
2393 $rc->usertalklink
= " ({$userTalkLink} | {$blockLink})";
2395 if( $wgDisableAnonTalk && ($rc_user == 0) )
2396 $rc->usertalklink
= "";
2398 $rc->usertalklink
= " ({$userTalkLink})";
2401 # Put accumulated information into the cache, for later display
2402 # Page moves go on their own line
2403 $title = $rc->getTitle();
2404 $secureName = $title->getPrefixedDBkey();
2405 if ( $rc_type == RC_MOVE
) {
2406 # Use an @ character to prevent collision with page names
2407 $this->rc_cache
["@@" . ($this->rcMoveIndex++
)] = array($rc);
2409 if ( !isset ( $this->rc_cache
[$secureName] ) ) $this->rc_cache
[$secureName] = array() ;
2410 array_push ( $this->rc_cache
[$secureName] , $rc ) ;
2415 function endImageHistoryList()
2421 /* This function is called by all recent changes variants, by the page history,
2422 and by the user contributions list. It is responsible for formatting edit
2423 comments. It escapes any HTML in the comment, but adds some CSS to format
2424 auto-generated comments (from section editing) and formats [[wikilinks]].
2425 Main author: Erik Möller (moeller@scireview.de)
2427 function formatComment($comment)
2430 $comment=wfEscapeHTML($comment);
2432 # The pattern for autogen comments is / * foo * /, which makes for
2434 # We look for all comments, match any text before and after the comment,
2435 # add a separator where needed and format the comment itself with CSS
2436 while (preg_match("/(.*)\/\*\s*(.*?)\s*\*\/(.*)/", $comment,$match)) {
2441 if($pre) { $auto="$sep ".$auto; }
2442 if($post) { $auto.=" $sep"; }
2443 $auto="<span class=\"autocomment\">".$auto."</span>";
2444 $comment=$pre.$auto.$post;
2447 # format regular and media links - all other wiki formatting
2449 while(preg_match("/\[\[(.*?)(\|(.*?))*\]\]/",$comment,$match)) {
2451 $medians = $wgLang->getNsText(Namespace::getMedia());
2453 if(preg_match("/^".$medians."/i",$match[1])) {
2454 $func="makeMediaLink";
2456 if(isset($match[3]) ) {
2458 preg_replace("/\[\[(.*?)\]\]/",
2459 $this->$func($match[1],$match[3]),$comment,1);
2462 preg_replace("/\[\[(.*?)\]\]/",
2463 $this->$func($match[1],$match[1]),$comment,1);
2471 function imageHistoryLine( $iscur, $timestamp, $img, $user, $usertext, $size, $description )
2473 global $wgUser, $wgLang, $wgTitle;
2475 $datetime = $wgLang->timeanddate( $timestamp, true );
2476 $del = wfMsg( "deleteimg" );
2477 $cur = wfMsg( "cur" );
2480 $url = Image
::wfImageUrl( $img );
2482 if ( $wgUser->isSysop() ) {
2483 $link = $wgTitle->escapeLocalURL( "image=" . $wgTitle->getPartialURL() .
2485 $style = $this->getInternalLinkAttributes( $link, $del );
2487 $dlink = "<a href=\"{$link}\"{$style}>{$del}</a>";
2492 $url = wfEscapeHTML( wfImageArchiveUrl( $img ) );
2493 if( $wgUser->getID() != 0 ) {
2494 $rlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2495 wfMsg( "revertimg" ), "action=revert&oldimage=" .
2496 urlencode( $img ) );
2497 $dlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2498 $del, "action=delete&oldimage=" . urlencode( $img ) );
2500 # Having live active links for non-logged in users
2501 # means that bots and spiders crawling our site can
2502 # inadvertently change content. Baaaad idea.
2503 $rlink = wfMsg( "revertimg" );
2508 $userlink = $usertext;
2510 $userlink = $this->makeLink( $wgLang->getNsText( Namespace::getUser() ) .
2511 ":{$usertext}", $usertext );
2513 $nbytes = wfMsg( "nbytes", $size );
2514 $style = $this->getInternalLinkAttributes( $url, $datetime );
2516 $s = "<li> ({$dlink}) ({$rlink}) <a href=\"{$url}\"{$style}>{$datetime}</a>"
2517 . " . . {$userlink} ({$nbytes})";
2519 if ( "" != $description && "*" != $description ) {
2520 $sk=$wgUser->getSkin();
2521 $s .= $wgLang->emphasize(" (" . $sk->formatComment($description) . ")");
2527 function tocIndent($level) {
2528 return str_repeat( "<div class='tocindent'>\n", $level>0 ?
$level : 0 );
2531 function tocUnindent($level) {
2532 return str_repeat( "</div>\n", $level>0 ?
$level : 0 );
2535 # parameter level defines if we are on an indentation level
2536 function tocLine( $anchor, $tocline, $level ) {
2537 $link = "<a href=\"#$anchor\">$tocline</a><br />";
2541 return "<div class='tocline'>$link</div>\n";
2546 function tocTable($toc) {
2547 # note to CSS fanatics: putting this in a div does not work -- div won't auto-expand
2548 # try min-width & co when somebody gets a chance
2549 $hideline = " <script type='text/javascript'>showTocToggle(\"" . addslashes( wfMsg("showtoc") ) . "\",\"" . addslashes( wfMsg("hidetoc") ) . "\")</script>";
2551 "<table border=\"0\" id=\"toc\"><tr><td align=\"center\">\n".
2552 "<b>".wfMsg("toc")."</b>" .
2554 "</td></tr><tr id='tocinside'><td>\n".
2555 $toc."</td></tr></table>\n";
2558 # These two do not check for permissions: check $wgTitle->userCanEdit before calling them
2559 function editSectionScript( $section, $head ) {
2560 global $wgTitle, $wgRequest;
2561 if( $wgRequest->getInt( "oldid" ) && ( $wgRequest->getVal( "diff" ) != "0" ) ) {
2564 $url = $wgTitle->escapeLocalURL( "action=edit§ion=$section" );
2565 return "<span oncontextmenu='document.location=\"$url\";return false;'>{$head}</span>";
2568 function editSectionLink( $section ) {
2570 global $wgTitle, $wgUser, $wgLang;
2572 if( $wgRequest->getInt( "oldid" ) && ( $wgRequest->getVal( "diff" ) != "0" ) ) {
2573 # Section edit links would be out of sync on an old page.
2574 # But, if we're diffing to the current page, they'll be
2579 $editurl = "§ion={$section}";
2580 $url = $this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg("editsection"),"action=edit".$editurl);
2582 if( $wgLang->isRTL() ) {
2584 $nearside = "right";
2589 return "<div class=\"editsection\" style=\"float:$farside;margin-$nearside:5px;\">[".$url."]</div>";
2593 // This function is called by EditPage.php and shows a bulletin board style
2594 // toolbar for common editing functions. It can be disabled in the user preferences.
2595 // The necsesary JavaScript code can be found in style/wikibits.js.
2596 function getEditToolbar() {
2597 global $wgStylePath, $wgLang, $wgMimeType;
2599 // toolarray an array of arrays which each include the filename of
2600 // the button image (without path), the opening tag, the closing tag,
2601 // and optionally a sample text that is inserted between the two when no
2602 // selection is highlighted.
2603 // The tip text is shown when the user moves the mouse over the button.
2605 // Already here are accesskeys (key), which are not used yet until someone
2606 // can figure out a way to make them work in IE. However, we should make
2607 // sure these keys are not defined on the edit page.
2609 array( "image"=>"button_bold.png",
2612 "sample"=>wfMsg("bold_sample"),
2613 "tip"=>wfMsg("bold_tip"),
2616 array( "image"=>"button_italic.png",
2619 "sample"=>wfMsg("italic_sample"),
2620 "tip"=>wfMsg("italic_tip"),
2623 array( "image"=>"button_link.png",
2626 "sample"=>wfMsg("link_sample"),
2627 "tip"=>wfMsg("link_tip"),
2630 array( "image"=>"button_extlink.png",
2633 "sample"=>wfMsg("extlink_sample"),
2634 "tip"=>wfMsg("extlink_tip"),
2637 array( "image"=>"button_headline.png",
2640 "sample"=>wfMsg("headline_sample"),
2641 "tip"=>wfMsg("headline_tip"),
2644 array( "image"=>"button_image.png",
2645 "open"=>"[[".$wgLang->getNsText(NS_IMAGE
).":",
2647 "sample"=>wfMsg("image_sample"),
2648 "tip"=>wfMsg("image_tip"),
2651 array( "image"=>"button_media.png",
2652 "open"=>"[[".$wgLang->getNsText(NS_MEDIA
).":",
2654 "sample"=>wfMsg("media_sample"),
2655 "tip"=>wfMsg("media_tip"),
2658 array( "image"=>"button_math.png",
2659 "open"=>"\\<math\\>",
2660 "close"=>"\\</math\\>",
2661 "sample"=>wfMsg("math_sample"),
2662 "tip"=>wfMsg("math_tip"),
2665 array( "image"=>"button_nowiki.png",
2666 "open"=>"\\<nowiki\\>",
2667 "close"=>"\\</nowiki\\>",
2668 "sample"=>wfMsg("nowiki_sample"),
2669 "tip"=>wfMsg("nowiki_tip"),
2672 array( "image"=>"button_sig.png",
2676 "tip"=>wfMsg("sig_tip"),
2679 array( "image"=>"button_hr.png",
2680 "open"=>"\\n----\\n",
2683 "tip"=>wfMsg("hr_tip"),
2687 $toolbar ="<script type='text/javascript'>\n/*<![CDATA[*/\n";
2689 $toolbar.="document.writeln(\"<div id='toolbar'>\");\n";
2690 foreach($toolarray as $tool) {
2692 $image=$wgStylePath."/images/".$tool["image"];
2693 $open=$tool["open"];
2694 $close=$tool["close"];
2695 $sample = addslashes( $tool["sample"] );
2697 // Note that we use the tip both for the ALT tag and the TITLE tag of the image.
2698 // Older browsers show a "speedtip" type message only for ALT.
2699 // Ideally these should be different, realistically they
2700 // probably don't need to be.
2701 $tip = addslashes( $tool["tip"] );
2703 #$key = $tool["key"];
2705 $toolbar.="addButton('$image','$tip','$open','$close','$sample');\n";
2708 $toolbar.="addInfobox('" . addslashes( wfMsg( "infobox" ) ) . "','" . addslashes(wfMsg("infobox_alert")) . "');\n";
2709 $toolbar.="document.writeln(\"</div>\");\n";
2711 $toolbar.="/*]]>*/\n</script>";
2717 require_once( "SkinStandard.php" );
2718 require_once( "SkinNostalgia.php" );
2719 require_once( "SkinCologneBlue.php" );
2721 if( $wgUsePHPTal ) {
2722 require_once( "SkinPHPTal.php" );