3 require_once( "Feed.php" );
4 require_once( "Image.php" );
8 # These are the INTERNAL names, which get mapped
9 # directly to class names. For display purposes, the
10 # Language class has internationalized names
12 /* private */ $wgValidSkinNames = array(
13 'standard' => "Standard",
14 'nostalgia' => "Nostalgia",
15 'cologneblue' => "CologneBlue"
18 #$wgValidSkinNames[] = "PHPTal";
19 #$wgValidSkinNames['davinci'] = "DaVinci";
20 #$wgValidSkinNames['mono'] = "Mono";
21 $wgValidSkinNames['monobook'] = "MonoBook";
22 #$wgValidSkinNames['monobookminimal'] = "MonoBookMinimal";
25 require_once( "RecentChange.php" );
27 class RCCacheEntry
extends RecentChange
29 var $secureName, $link;
30 var $curlink , $lastlink , $usertalklink , $versionlink ;
31 var $userlink, $timestamp, $watched;
33 function newFromParent( $rc )
35 $rc2 = new RCCacheEntry
;
36 $rc2->mAttribs
= $rc->mAttribs
;
37 $rc2->mExtra
= $rc->mExtra
;
44 /* private */ var $lastdate, $lastline;
45 var $linktrail ; # linktrail regexp
46 var $rc_cache ; # Cache for Enhanced Recent Changes
47 var $rcCacheIndex ; # Recent Changes Cache Counter for visibility toggle
52 $this->linktrail
= wfMsg("linktrail");
55 function getSkinNames()
57 global $wgValidSkinNames;
58 return $wgValidSkinNames;
61 function getStylesheet()
63 return "wikistandard.css";
68 global $wgOut, $wgUser;
70 if ( $wgOut->isQuickbarSuppressed() ) { return 0; }
71 $q = $wgUser->getOption( "quickbar" );
72 if ( "" == $q ) { $q = 0; }
76 function initPage( &$out )
78 $fname = "Skin::initPage";
79 wfProfileIn( $fname );
81 $out->addLink( array( "rel" => "shortcut icon", "href" => "/favicon.ico" ) );
83 $this->addMetadataLinks($out);
85 wfProfileOut( $fname );
88 function addMetadataLinks( &$out ) {
89 global $wgTitle, $wgEnableDublinCoreRdf, $wgEnableCreativeCommonsRdf, $wgRdfMimeType, $action;
90 global $wgRightsPage, $wgRightsUrl;
92 if( $out->isArticleRelated() ) {
93 # note: buggy CC software only reads first "meta" link
94 if( $wgEnableCreativeCommonsRdf ) {
95 $out->addMetadataLink( array(
96 'title' => 'Creative Commons',
97 'type' => 'application/rdf+xml',
98 'href' => $wgTitle->getLocalURL( "action=creativecommons") ) );
100 if( $wgEnableDublinCoreRdf ) {
101 $out->addMetadataLink( array(
102 'title' => 'Dublin Core',
103 'type' => 'application/rdf+xml',
104 'href' => $wgTitle->getLocalURL( "action=dublincore" ) ) );
108 if( $wgRightsPage ) {
109 $copy = Title
::newFromText( $wgRightsPage );
111 $copyright = $copy->getLocalURL();
114 if( !$copyright && $wgRightsUrl ) {
115 $copyright = $wgRightsUrl;
118 $out->addLink( array(
119 "rel" => "copyright",
120 "href" => $copyright ) );
124 function outputPage( &$out ) {
125 global $wgDebugComments;
127 wfProfileIn( "Skin::outputPage" );
128 $this->initPage( $out );
129 $out->out( $out->headElement() );
131 $out->out( "\n<body" );
132 $ops = $this->getBodyOptions();
133 foreach ( $ops as $name => $val ) {
134 $out->out( " $name='$val'" );
137 if ( $wgDebugComments ) {
138 $out->out( "<!-- Wiki debugging output:\n" .
139 $out->mDebugtext
. "-->\n" );
141 $out->out( $this->beforeContent() );
143 $out->out( $out->mBodytext
. "\n" );
145 $out->out( $this->afterContent() );
148 $out->out( $out->reportTime() );
150 $out->out( "\n</body></html>" );
153 function getHeadScripts() {
155 $r = "<script type=\"text/javascript\" src=\"{$wgStylePath}/wikibits.js\"></script>\n";
159 function getUserStyles()
161 global $wgOut, $wgStylePath, $wgLang;
162 $sheet = $this->getStylesheet();
163 $s = "<style type='text/css'>\n";
164 $s .= "/*/*/\n"; # <-- Hide the styles from Netscape 4 without hiding them from IE/Mac
165 $s .= "@import url(\"$wgStylePath/$sheet\");\n";
166 if($wgLang->isRTL()) $s .= "@import url(\"$wgStylePath/common_rtl.css\");\n";
167 $s .= $this->doGetUserStyles();
173 function doGetUserStyles()
178 if ( 1 == $wgUser->getOption( "underline" ) ) {
179 # Don't override browser settings
184 "text-decoration: none; }\n";
186 if ( 1 == $wgUser->getOption( "highlightbroken" ) ) {
187 $s .= "a.new, #quickbar a.new { color: #CC2200; }\n";
189 if ( 1 == $wgUser->getOption( "justify" ) ) {
190 $s .= "#article { text-align: justify; }\n";
195 function getBodyOptions()
197 global $wgUser, $wgTitle, $wgNamespaceBackgrounds, $wgOut, $wgRequest;
199 extract( $wgRequest->getValues( 'oldid', 'redirect', 'diff' ) );
201 if ( 0 != $wgTitle->getNamespace() ) {
202 $a = array( "bgcolor" => "#ffffec" );
204 else $a = array( "bgcolor" => "#FFFFFF" );
205 if($wgOut->isArticle() && $wgUser->getOption("editondblclick") &&
206 (!$wgTitle->isProtected() ||
$wgUser->isSysop()) ) {
207 $t = wfMsg( "editthispage" );
209 if ( !empty($redirect) ) {
210 $red = "&redirect={$redirect}";
212 if ( !empty($oldid) && ! isset( $diff ) ) {
213 $oid = "&oldid={$oldid}";
215 $s = $wgTitle->getFullURL( "action=edit{$oid}{$red}" );
216 $s = "document.location = \"" .$s ."\";";
217 $a +
= array ("ondblclick" => $s);
220 $a['onload'] = $wgOut->getOnloadHandler();
224 function getExternalLinkAttributes( $link, $text, $class='' )
226 global $wgUser, $wgOut, $wgLang;
228 $link = urldecode( $link );
229 $link = $wgLang->checkTitleEncoding( $link );
230 $link = str_replace( "_", " ", $link );
231 $link = wfEscapeHTML( $link );
233 $r = ($class != '') ?
" class='$class'" : " class='external'";
235 if ( 1 == $wgUser->getOption( "hover" ) ) {
236 $r .= " title=\"{$link}\"";
241 function getInternalLinkAttributes( $link, $text, $broken = false )
243 global $wgUser, $wgOut;
245 $link = urldecode( $link );
246 $link = str_replace( "_", " ", $link );
247 $link = wfEscapeHTML( $link );
249 if ( $broken == "stub" ) {
250 $r = " class='stub'";
251 } else if ( $broken == "yes" ) {
257 if ( 1 == $wgUser->getOption( "hover" ) ) {
258 $r .= " title=\"{$link}\"";
263 function getInternalLinkAttributesObj( &$nt, $text, $broken = false )
265 global $wgUser, $wgOut;
267 if ( $broken == "stub" ) {
268 $r = " class='stub'";
269 } else if ( $broken == "yes" ) {
275 if ( 1 == $wgUser->getOption( "hover" ) ) {
276 $r .= ' title ="' . $nt->getEscapedText() . '"';
287 # This will be called immediately after the <body> tag. Split into
288 # two functions to make it easier to subclass.
290 function beforeContent()
292 global $wgUser, $wgOut, $wgSiteNotice;
294 if( $wgSiteNotice ) {
295 $note = "\n<div id='siteNotice'>$wgSiteNotice</div>\n";
299 return $this->doBeforeContent() . $note;
302 function doBeforeContent()
304 global $wgUser, $wgOut, $wgTitle, $wgLang;
305 $fname = "Skin::doBeforeContent";
306 wfProfileIn( $fname );
309 $qb = $this->qbSetting();
311 if( $langlinks = $this->otherLanguages() ) {
317 $borderhack = "class='top'";
320 $s .= "\n<div id='content'>\n<div id='topbar'>\n" .
321 "<table border='0' cellspacing='0' width='98%'>\n<tr>\n";
324 $left = ($qb == 1 ||
$qb == 3);
325 if($wgLang->isRTL()) $left = !$left;
328 $s .= "<td class='top' align='left' valign='top' rowspan='{$rows}'>\n" .
329 $this->logoText() . "</td>";
331 $s .= $this->getQuickbarCompensator( $rows );
333 $l = $wgLang->isRTL() ?
"right" : "left";
334 $s .= "<td {$borderhack} align='$l' valign='top'>\n";
336 $s .= $this->topLinks() ;
337 $s .= "<p class='subtitle'>" . $this->pageTitleLinks() . "</p>\n";
339 $r = $wgLang->isRTL() ?
"left" : "right";
340 $s .= "</td>\n<td {$borderhack} valign='top' align='$r' nowrap='nowrap'>";
341 $s .= $this->nameAndLogin();
342 $s .= "\n<br />" . $this->searchForm() . "</td>";
345 $s .= "</tr>\n<tr>\n<td class='top' colspan=\"2\">$langlinks</td>\n";
348 if ( $shove && !$left ) { # Right
349 $s .= $this->getQuickbarCompensator( $rows );
351 $s .= "</tr>\n</table>\n</div>\n";
352 $s .= "\n<div id='article'>\n";
354 $s .= $this->pageTitle();
355 $s .= $this->pageSubtitle() ;
356 $s .= $this->getCategories();
357 wfProfileOut( $fname );
361 function getCategoryLinks () {
362 global $wgOut, $wgTitle, $wgUser, $wgParser;
363 global $wgUseCategoryMagic;
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, 'extiw' );
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 );
1671 # this can be passed the NS number as defined in Language.php
1672 /*static*/ function makeNSUrl( $name, $urlaction='', $namespace=0 ) {
1673 $title = Title
::makeTitle( $namespace, $name );
1674 $this->checkTitle($title, $name);
1675 return $title->getLocalURL( $urlaction );
1678 /* these return an array with the 'href' and boolean 'exists' */
1679 /*static*/ function makeUrlDetails ( $name, $urlaction='' ) {
1680 $title = Title
::newFromText( $name );
1681 $this->checkTitle($title, $name);
1683 'href' => $title->getLocalURL( $urlaction ),
1684 'exists' => $title->getArticleID() != 0?
true:false
1687 /*static*/ function makeTalkUrlDetails ( $name, $urlaction='' ) {
1688 $title = Title
::newFromText( $name );
1689 $title = $title->getTalkPage();
1690 $this->checkTitle($title, $name);
1692 'href' => $title->getLocalURL( $urlaction ),
1693 'exists' => $title->getArticleID() != 0?
true:false
1696 /*static*/ function makeArticleUrlDetails ( $name, $urlaction='' ) {
1697 $title = Title
::newFromText( $name );
1698 $title= $title->getSubjectPage();
1699 $this->checkTitle($title, $name);
1701 'href' => $title->getLocalURL( $urlaction ),
1702 'exists' => $title->getArticleID() != 0?
true:false
1705 /*static*/ function makeI18nUrlDetails ( $name, $urlaction='' ) {
1706 $title = Title
::newFromText( wfMsg($name) );
1707 $this->checkTitle($title, $name);
1709 'href' => $title->getLocalURL( $urlaction ),
1710 'exists' => $title->getArticleID() != 0?
true:false
1714 # make sure we have some title to operate on
1715 /*static*/ function checkTitle ( &$title, &$name ) {
1716 if(!is_object($title)) {
1717 $title = Title
::newFromText( $name );
1718 if(!is_object($title)) {
1719 $title = Title
::newFromText( '<error: link target missing>' );
1724 function fnamePart( $url )
1726 $basename = strrchr( $url, "/" );
1727 if ( false === $basename ) { $basename = $url; }
1728 else { $basename = substr( $basename, 1 ); }
1729 return wfEscapeHTML( $basename );
1732 function makeImage( $url, $alt = "" )
1736 if ( "" == $alt ) { $alt = $this->fnamePart( $url ); }
1737 $s = "<img src=\"{$url}\" alt=\"{$alt}\" />";
1741 function makeImageLink( $name, $url, $alt = "" ) {
1742 $nt = Title
::makeTitle( Namespace::getImage(), $name );
1743 return $this->makeImageLinkObj( $nt, $alt );
1746 function makeImageLinkObj( $nt, $alt = "" ) {
1747 global $wgLang, $wgUseImageResize;
1748 $img = Image
::newFromTitle( $nt );
1749 $url = $img->getURL();
1752 $prefix = $postfix = "";
1754 if ( $wgUseImageResize ) {
1755 # Check if the alt text is of the form "options|alt text"
1757 # * thumbnail make a thumbnail with enlarge-icon and caption, alignment depends on lang
1758 # * left no resizing, just left align. label is used for alt= only
1759 # * right same, but right aligned
1760 # * none same, but not aligned
1761 # * ___px scale to ___ pixels width, no aligning. e.g. use in taxobox
1762 # * center center the image
1763 # * framed Keep original image size, no magnify-button.
1765 $part = explode( "|", $alt);
1767 $mwThumb =& MagicWord
::get( MAG_IMG_THUMBNAIL
);
1768 $mwLeft =& MagicWord
::get( MAG_IMG_LEFT
);
1769 $mwRight =& MagicWord
::get( MAG_IMG_RIGHT
);
1770 $mwNone =& MagicWord
::get( MAG_IMG_NONE
);
1771 $mwWidth =& MagicWord
::get( MAG_IMG_WIDTH
);
1772 $mwCenter =& MagicWord
::get( MAG_IMG_CENTER
);
1773 $mwFramed =& MagicWord
::get( MAG_IMG_FRAMED
);
1774 $alt = $part[count($part)-1];
1776 $height = $framed = $thumb = false;
1778 foreach( $part as $key => $val ) {
1779 if ( ! is_null( $mwThumb->matchVariableStartToEnd($val) ) ) {
1781 } elseif ( ! is_null( $mwRight->matchVariableStartToEnd($val) ) ) {
1782 # remember to set an alignment, don't render immediately
1784 } elseif ( ! is_null( $mwLeft->matchVariableStartToEnd($val) ) ) {
1785 # remember to set an alignment, don't render immediately
1787 } elseif ( ! is_null( $mwCenter->matchVariableStartToEnd($val) ) ) {
1788 # remember to set an alignment, don't render immediately
1790 } elseif ( ! is_null( $mwNone->matchVariableStartToEnd($val) ) ) {
1791 # remember to set an alignment, don't render immediately
1793 } elseif ( ! is_null( $match = $mwWidth->matchVariableStartToEnd($val) ) ) {
1794 # $match is the image width in pixels
1795 if ( preg_match( "/^([0-9]*)x([0-9]*)$/", $match, $m ) ) {
1796 $width = intval( $m[1] );
1797 $height = intval( $m[2] );
1799 $width = intval($match);
1801 } elseif ( ! is_null( $mwFramed->matchVariableStartToEnd($val) ) ) {
1805 if ( "center" == $align )
1807 $prefix = '<span style="text-align: center">';
1808 $postfix = '</span>';
1812 if ( $thumb ||
$framed ) {
1814 # Create a thumbnail. Alignment depends on language
1815 # writing direction, # right aligned for left-to-right-
1816 # languages ("Western languages"), left-aligned
1817 # for right-to-left-languages ("Semitic languages")
1819 # If thumbnail width has not been provided, it is set
1820 # here to 180 pixels
1821 if ( $align == "" ) {
1822 $align = $wgLang->isRTL() ?
"left" : "right";
1824 if ( ! isset($width) ) {
1827 return $prefix.$this->makeThumbLinkObj( $img, $alt, $align, $width, $height, $framed ).$postfix;
1829 } elseif ( isset($width) ) {
1831 # Create a resized image, without the additional thumbnail
1834 if ( ( ! $height === false )
1835 && ( $img->getHeight() * $width / $img->getWidth() > $height ) ) {
1836 print "height=$height<br>\nimg->getHeight() = ".$img->getHeight()."<br>\n";
1837 print "rescaling by factor ". $height / $img->getHeight() . "<br>\n";
1838 $width = $img->getWidth() * $height / $img->getHeight();
1840 $url = $img->createThumb( $width );
1842 } # endif $wgUseImageResize
1844 if ( empty( $alt ) ) {
1845 $alt = preg_replace( '/\.(.+?)^/', '', $img->getName() );
1847 $alt = htmlspecialchars( $alt );
1849 $u = $nt->escapeLocalURL();
1852 $s = str_replace( "$1", $img->getName(), wfMsg("missingimage") );
1853 $s .= "<br>{$alt}<br>{$url}<br>\n";
1855 $s = "<a href=\"{$u}\" class='image' title=\"{$alt}\">" .
1856 "<img src=\"{$url}\" alt=\"{$alt}\" /></a>";
1858 if ( "" != $align ) {
1859 $s = "<div class=\"float{$align}\"><span>{$s}</span></div>";
1861 return str_replace("\n", ' ',$prefix.$s.$postfix);
1865 function makeThumbLinkObj( $img, $label = "", $align = "right", $boxwidth = 180, $boxheight=false, $framed=false ) {
1866 global $wgStylePath, $wgLang;
1867 # $image = Title::makeTitle( Namespace::getImage(), $name );
1868 $url = $img->getURL();
1870 #$label = htmlspecialchars( $label );
1871 $alt = preg_replace( "/<[^>]*>/", "", $label);
1872 $alt = htmlspecialchars( $alt );
1874 if ( $img->exists() )
1876 $width = $img->getWidth();
1877 $height = $img->getHeight();
1879 $width = $height = 200;
1883 // Use image dimensions, don't scale
1885 $oboxwidth = $boxwidth +
2;
1886 $boxheight = $height;
1889 $h = intval( $height/($width/$boxwidth) );
1890 $oboxwidth = $boxwidth +
2;
1891 if ( ( ! $boxheight === false ) && ( $h > $boxheight ) )
1893 $boxwidth *= $boxheight/$h;
1897 $thumbUrl = $img->createThumb( $boxwidth );
1900 $u = $img->getEscapeLocalURL();
1902 $more = htmlspecialchars( wfMsg( "thumbnail-more" ) );
1903 $magnifyalign = $wgLang->isRTL() ?
"left" : "right";
1904 $textalign = $wgLang->isRTL() ?
' style="text-align:right"' : "";
1906 $s = "<div class=\"thumb t{$align}\"><div style=\"width:{$oboxwidth}px;\">";
1907 if ( $thumbUrl == "" ) {
1908 $s .= str_replace( "$1", $img->getName(), wfMsg("missingimage") );
1911 $s .= '<a href="'.$u.'" class="internal" title="'.$alt.'">'.
1912 '<img src="'.$thumbUrl.'" alt="'.$alt.'" ' .
1913 'width="'.$boxwidth.'" height="'.$boxheight.'" /></a>';
1917 $zoomicon = '<div class="magnify" style="float:'.$magnifyalign.'">'.
1918 '<a href="'.$u.'" class="internal" title="'.$more.'">'.
1919 '<img src="'.$wgStylePath.'/images/magnify-clip.png" ' .
1920 'width="15" height="11" alt="'.$more.'" /></a></div>';
1923 $s .= ' <div class="thumbcaption" '.$textalign.'>'.$zoomicon.$label."</div></div></div>";
1924 return str_replace("\n", ' ', $s);
1927 function makeMediaLink( $name, $url, $alt = "" ) {
1928 $nt = Title
::makeTitle( Namespace::getMedia(), $name );
1929 return $this->makeMediaLinkObj( $nt, $alt );
1932 function makeMediaLinkObj( $nt, $alt = "" )
1934 if ( ! isset( $nt ) )
1936 ### HOTFIX. Instead of breaking, return empry string.
1939 $name = $nt->getDBKey();
1940 $url = Image
::wfImageUrl( $name );
1941 if ( empty( $alt ) ) {
1942 $alt = preg_replace( '/\.(.+?)^/', '', $name );
1945 $u = htmlspecialchars( $url );
1946 $s = "<a href=\"{$u}\" class='internal' title=\"{$alt}\">{$alt}</a>";
1951 function specialLink( $name, $key = "" )
1955 if ( "" == $key ) { $key = strtolower( $name ); }
1956 $pn = $wgLang->ucfirst( $name );
1957 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1961 function makeExternalLink( $url, $text, $escape = true ) {
1962 $style = $this->getExternalLinkAttributes( $url, $text );
1963 $url = htmlspecialchars( $url );
1965 $text = htmlspecialchars( $text );
1967 return "<a href=\"$url\"$style>$text</a>";
1970 # Called by history lists and recent changes
1973 # Returns text for the start of the tabular part of RC
1974 function beginRecentChangesList()
1976 $this->rc_cache
= array() ;
1977 $this->rcMoveIndex
= 0;
1978 $this->rcCacheIndex
= 0 ;
1979 $this->lastdate
= "";
1980 $this->rclistOpen
= false;
1984 function beginImageHistoryList()
1986 $s = "\n<h2>" . wfMsg( "imghistory" ) . "</h2>\n" .
1987 "<p>" . wfMsg( "imghistlegend" ) . "</p>\n<ul class='special'>";
1991 # Returns text for the end of RC
1992 # If enhanced RC is in use, returns pretty much all the text
1993 function endRecentChangesList()
1995 $s = $this->recentChangesBlock() ;
1996 if( $this->rclistOpen
) {
2002 # Enhanced RC ungrouped line
2003 function recentChangesBlockLine ( $rcObj )
2005 global $wgStylePath, $wgLang ;
2007 # Get rc_xxxx variables
2008 extract( $rcObj->mAttribs
) ;
2009 $curIdEq = "curid=$rc_cur_id";
2014 $r .= "<img src='{$wgStylePath}/images/Arr_.png' width='12' height='12' border='0' />" ; $r .= "<tt>" ;
2016 if ( $rc_type == RC_MOVE
) {
2017 $r .= " ";
2019 # M & N (minor & new)
2020 $M = wfMsg( "minoreditletter" );
2021 $N = wfMsg( "newpageletter" );
2023 if ( $rc_type == RC_NEW
) {
2036 $r .= " ".$rcObj->timestamp
." " ;
2040 $link = $rcObj->link
;
2041 if ( $rcObj->watched
) $link = "<strong>{$link}</strong>" ;
2046 $r .= $rcObj->curlink
;
2050 $r .= $this->makeKnownLinkObj( $rcObj->getTitle(), wfMsg( "hist" ), "{$curIdEq}&action=history" );
2053 $r .= ") . . ".$rcObj->userlink
;
2054 $r .= $rcObj->usertalklink
;
2057 if ( $rc_comment != "" && $rc_type != RC_MOVE
) {
2058 $rc_comment=$this->formatComment($rc_comment);
2059 $r .= $wgLang->emphasize( " (".$rc_comment.")" );
2067 function recentChangesBlockGroup ( $block )
2069 global $wgStylePath, $wgLang ;
2072 $M = wfMsg( "minoreditletter" );
2073 $N = wfMsg( "newpageletter" );
2075 # Collate list of users
2077 $userlinks = array () ;
2078 foreach ( $block AS $rcObj ) {
2079 $oldid = $rcObj->mAttribs
['rc_last_oldid'];
2080 if ( $rcObj->mAttribs
['rc_new'] ) $isnew = true ;
2081 $u = $rcObj->userlink
;
2082 if ( !isset ( $userlinks[$u] ) ) $userlinks[$u] = 0 ;
2086 # Sort the list and convert to text
2087 krsort ( $userlinks ) ;
2088 asort ( $userlinks ) ;
2090 foreach ( $userlinks as $userlink => $count) {
2092 if ( $count > 1 ) $text .= " ({$count}×)" ;
2093 array_push ( $users , $text ) ;
2095 $users = " <font size='-1'>[".implode("; ",$users)."]</font>" ;
2098 $rci = "RCI{$this->rcCacheIndex}" ;
2099 $rcl = "RCL{$this->rcCacheIndex}" ;
2100 $rcm = "RCM{$this->rcCacheIndex}" ;
2101 $toggleLink = "javascript:toggleVisibility(\"{$rci}\",\"{$rcm}\",\"{$rcl}\")" ;
2102 $arrowdir = $wgLang->isRTL() ?
"l" : "r";
2103 $tl = "<span id='{$rcm}'><a href='$toggleLink'><img src='{$wgStylePath}/images/Arr_{$arrowdir}.png' width='12' height='12' /></a></span>" ;
2104 $tl .= "<span id='{$rcl}' style='display:none'><a href='$toggleLink'><img src='{$wgStylePath}/images/Arr_d.png' width='12' height='12' /></a></span>" ;
2110 if ( $isnew ) $r .= $N ;
2111 else $r .= " " ;
2112 $r .= " " ; # Minor
2115 $r .= " ".$block[0]->timestamp
." " ;
2119 $link = $block[0]->link
;
2120 if ( $block[0]->watched
) $link = "<strong>{$link}</strong>" ;
2123 $curIdEq = "curid=" . $block[0]->mAttribs
['rc_cur_id'];
2124 if ( $block[0]->mAttribs
['rc_type'] != RC_LOG
) {
2126 $r .= " (".count($block)." " ;
2127 if ( $isnew ) $r .= wfMsg("changes");
2128 else $r .= $this->makeKnownLinkObj( $block[0]->getTitle() , wfMsg("changes") ,
2129 "{$curIdEq}&diff=0&oldid=".$oldid ) ;
2133 $r .= $this->makeKnownLinkObj( $block[0]->getTitle(), wfMsg( "history" ), "{$curIdEq}&action=history" );
2141 $r .= "<div id='{$rci}' style='display:none'>" ;
2142 foreach ( $block AS $rcObj ) {
2143 # Get rc_xxxx variables
2144 extract( $rcObj->mAttribs
);
2146 $r .= "<img src='{$wgStylePath}/images/Arr_.png' width=12 height=12 />";
2147 $r .= "<tt> " ;
2148 if ( $rc_new ) $r .= $N ;
2149 else $r .= " " ;
2150 if ( $rc_minor ) $r .= $M ;
2151 else $r .= " " ;
2155 if ( $rc_last_oldid != 0 ) {
2156 $o = "oldid=".$rc_last_oldid ;
2158 if ( $rc_type == RC_LOG
) {
2159 $link = $rcObj->timestamp
;
2161 $link = $this->makeKnownLinkObj( $rcObj->getTitle(), $rcObj->timestamp
, "{$curIdEq}&$o" ) ;
2163 $link = "<tt>{$link}</tt>" ;
2167 $r .= $rcObj->curlink
;
2169 $r .= $rcObj->lastlink
;
2170 $r .= ") . . ".$rcObj->userlink
;
2171 $r .= $rcObj->usertalklink
;
2172 if ( $rc_comment != "" ) {
2173 $rc_comment=$this->formatComment($rc_comment);
2174 $r .= $wgLang->emphasize( " (".$rc_comment.")" ) ;
2180 $this->rcCacheIndex++
;
2184 # If enhanced RC is in use, this function takes the previously cached
2185 # RC lines, arranges them, and outputs the HTML
2186 function recentChangesBlock ()
2188 global $wgStylePath ;
2189 if ( count ( $this->rc_cache
) == 0 ) return "" ;
2191 foreach ( $this->rc_cache
AS $secureName => $block ) {
2192 if ( count ( $block ) < 2 ) {
2193 $blockOut .= $this->recentChangesBlockLine ( array_shift ( $block ) ) ;
2195 $blockOut .= $this->recentChangesBlockGroup ( $block ) ;
2199 return "<div>{$blockOut}</div>" ;
2202 # Called in a loop over all displayed RC entries
2203 # Either returns the line, or caches it for later use
2204 function recentChangesLine( &$rc, $watched = false )
2207 $usenew = $wgUser->getOption( "usenewrc" );
2209 $line = $this->recentChangesLineNew ( $rc, $watched ) ;
2211 $line = $this->recentChangesLineOld ( $rc, $watched ) ;
2215 function recentChangesLineOld( &$rc, $watched = false )
2217 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds;
2219 # Extract DB fields into local scope
2220 extract( $rc->mAttribs
);
2221 $curIdEq = "curid=" . $rc_cur_id;
2223 # Make date header if necessary
2224 $date = $wgLang->date( $rc_timestamp, true);
2226 if ( $date != $this->lastdate
) {
2227 if ( "" != $this->lastdate
) { $s .= "</ul>\n"; }
2228 $s .= "<h4>{$date}</h4>\n<ul class='special'>";
2229 $this->lastdate
= $date;
2230 $this->rclistOpen
= true;
2234 if ( $rc_type == RC_MOVE
) {
2236 $s .= "(" . wfMsg( "diff" ) . ") (";
2238 $s .= $this->makeKnownLinkObj( $rc->getMovedToTitle(), wfMsg( "hist" ), "action=history" ) .
2241 # "[[x]] moved to [[y]]"
2243 $s .= wfMsg( "1movedto2", $this->makeKnownLinkObj( $rc->getTitle(), "", "redirect=no" ),
2244 $this->makeKnownLinkObj( $rc->getMovedToTitle(), "" ) );
2248 if ( $rc_type == RC_NEW ||
$rc_type == RC_LOG
) {
2249 $diffLink = wfMsg( "diff" );
2251 $diffLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( "diff" ),
2252 "{$curIdEq}&diff={$rc_this_oldid}&oldid={$rc_last_oldid}" ,'' ,'' , ' tabindex="'.$rc->counter
.'"');
2254 $s .= "($diffLink) (";
2257 $s .= $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( "hist" ), "{$curIdEq}&action=history" );
2260 # M and N (minor and new)
2261 $M = wfMsg( "minoreditletter" );
2262 $N = wfMsg( "newpageletter" );
2263 if ( $rc_minor ) { $s .= " <strong>{$M}</strong>"; }
2264 if ( $rc_type == RC_NEW
) { $s .= "<strong>{$N}</strong>"; }
2267 $articleLink = $this->makeKnownLinkObj( $rc->getTitle(), "" );
2270 $articleLink = "<strong>{$articleLink}</strong>";
2272 $s .= " $articleLink";
2277 $s .= "; " . $wgLang->time( $rc_timestamp, true, $wgRCSeconds ) . " . . ";
2279 # User link (or contributions for unregistered users)
2280 if ( 0 == $rc_user ) {
2281 $userLink = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
2282 $rc_user_text, "target=" . $rc_user_text );
2284 $userLink = $this->makeLink( $wgLang->getNsText( NS_USER
) . ":{$rc_user_text}", $rc_user_text );
2289 $talkname=$wgLang->getNsText(NS_TALK
); # use the shorter name
2290 global $wgDisableAnonTalk;
2291 if( 0 == $rc_user && $wgDisableAnonTalk ) {
2294 $utns=$wgLang->getNsText(NS_USER_TALK
);
2295 $userTalkLink= $this->makeLink($utns . ":{$rc_user_text}", $talkname );
2299 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2300 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2301 "Blockip" ), wfMsg( "blocklink" ), "ip={$rc_user_text}" );
2305 if($userTalkLink) $userTalkLink .= " | ";
2306 $userTalkLink .= $blockLink;
2308 if($userTalkLink) $s.=" ({$userTalkLink})";
2311 if ( "" != $rc_comment && "*" != $rc_comment && $rc_type != RC_MOVE
) {
2312 $rc_comment=$this->formatComment($rc_comment);
2313 $s .= $wgLang->emphasize(" (" . $rc_comment . ")");
2320 # function recentChangesLineNew( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched = false, $oldid = 0 , $diffid = 0 )
2321 function recentChangesLineNew( &$baseRC, $watched = false )
2323 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds;
2325 # Create a specialised object
2326 $rc = RCCacheEntry
::newFromParent( $baseRC ) ;
2328 # Extract fields from DB into the function scope (rc_xxxx variables)
2329 extract( $rc->mAttribs
);
2330 $curIdEq = "curid=" . $rc_cur_id;
2332 # If it's a new day, add the headline and flush the cache
2333 $date = $wgLang->date( $rc_timestamp, true);
2335 if ( $date != $this->lastdate
) {
2336 # Process current cache
2337 $ret = $this->recentChangesBlock () ;
2338 $this->rc_cache
= array() ;
2339 $ret .= "<h4>{$date}</h4>\n";
2340 $this->lastdate
= $date;
2344 if ( $rc_type == RC_MOVE
) {
2345 $clink = $this->makeKnownLinkObj( $rc->getTitle(), "", "redirect=no" );
2346 $clink .= " " . wfMsg("movedto") . " ";
2347 $clink .= $this->makeKnownLinkObj( $rc->getMovedToTitle(), "" );
2349 $clink = $this->makeKnownLinkObj( $rc->getTitle(), "" ) ;
2352 $time = $wgLang->time( $rc_timestamp, true, $wgRCSeconds );
2353 $rc->watched
= $watched ;
2354 $rc->link
= $clink ;
2355 $rc->timestamp
= $time;
2358 if ( ( $rc_type == RC_NEW
&& $rc_this_oldid == 0 ) ||
$rc_type == RC_LOG ||
$rc_type == RC_MOVE
) {
2359 $curLink = wfMsg( "cur" );
2361 $curLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( "cur" ),
2362 "{$curIdEq}&diff=0&oldid={$rc_this_oldid}" ,'' ,'' , ' tabindex="'.$baseRC->counter
.'"' );
2366 $titleObj = $rc->getTitle();
2367 if ( $rc_last_oldid == 0 ||
$rc_type == RC_LOG ||
$rc_type == RC_MOVE
) {
2368 $lastLink = wfMsg( "last" );
2370 $lastLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( "last" ),
2371 "{$curIdEq}&diff={$rc_this_oldid}&oldid={$rc_last_oldid}" );
2374 # Make user link (or user contributions for unregistered users)
2375 if ( 0 == $rc_user ) {
2376 $userLink = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
2377 $rc_user_text, "target=" . $rc_user_text );
2379 $userLink = $this->makeLink( $wgLang->getNsText(
2380 Namespace::getUser() ) . ":{$rc_user_text}", $rc_user_text );
2383 $rc->userlink
= $userLink ;
2384 $rc->lastlink
= $lastLink ;
2385 $rc->curlink
= $curLink ;
2387 # Make user talk link
2388 $utns=$wgLang->getNsText(NS_USER_TALK
);
2389 $talkname=$wgLang->getNsText(NS_TALK
); # use the shorter name
2390 $userTalkLink= $this->makeLink($utns . ":{$rc_user_text}", $talkname );
2392 global $wgDisableAnonTalk;
2393 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2394 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2395 "Blockip" ), wfMsg( "blocklink" ), "ip={$rc_user_text}" );
2396 if( $wgDisableAnonTalk )
2397 $rc->usertalklink
= " ({$blockLink})";
2399 $rc->usertalklink
= " ({$userTalkLink} | {$blockLink})";
2401 if( $wgDisableAnonTalk && ($rc_user == 0) )
2402 $rc->usertalklink
= "";
2404 $rc->usertalklink
= " ({$userTalkLink})";
2407 # Put accumulated information into the cache, for later display
2408 # Page moves go on their own line
2409 $title = $rc->getTitle();
2410 $secureName = $title->getPrefixedDBkey();
2411 if ( $rc_type == RC_MOVE
) {
2412 # Use an @ character to prevent collision with page names
2413 $this->rc_cache
["@@" . ($this->rcMoveIndex++
)] = array($rc);
2415 if ( !isset ( $this->rc_cache
[$secureName] ) ) $this->rc_cache
[$secureName] = array() ;
2416 array_push ( $this->rc_cache
[$secureName] , $rc ) ;
2421 function endImageHistoryList()
2427 /* This function is called by all recent changes variants, by the page history,
2428 and by the user contributions list. It is responsible for formatting edit
2429 comments. It escapes any HTML in the comment, but adds some CSS to format
2430 auto-generated comments (from section editing) and formats [[wikilinks]].
2431 Main author: Erik Möller (moeller@scireview.de)
2433 function formatComment($comment)
2436 $comment=wfEscapeHTML($comment);
2438 # The pattern for autogen comments is / * foo * /, which makes for
2440 # We look for all comments, match any text before and after the comment,
2441 # add a separator where needed and format the comment itself with CSS
2442 while (preg_match("/(.*)\/\*\s*(.*?)\s*\*\/(.*)/", $comment,$match)) {
2447 if($pre) { $auto="$sep ".$auto; }
2448 if($post) { $auto.=" $sep"; }
2449 $auto="<span class=\"autocomment\">".$auto."</span>";
2450 $comment=$pre.$auto.$post;
2453 # format regular and media links - all other wiki formatting
2455 while(preg_match("/\[\[(.*?)(\|(.*?))*\]\]/",$comment,$match)) {
2457 $medians = $wgLang->getNsText(Namespace::getMedia());
2459 if(preg_match("/^".$medians."/i",$match[1])) {
2460 $func="makeMediaLink";
2462 if(isset($match[3]) ) {
2464 preg_replace("/\[\[(.*?)\]\]/",
2465 $this->$func($match[1],$match[3]),$comment,1);
2468 preg_replace("/\[\[(.*?)\]\]/",
2469 $this->$func($match[1],$match[1]),$comment,1);
2477 function imageHistoryLine( $iscur, $timestamp, $img, $user, $usertext, $size, $description )
2479 global $wgUser, $wgLang, $wgTitle;
2481 $datetime = $wgLang->timeanddate( $timestamp, true );
2482 $del = wfMsg( "deleteimg" );
2483 $cur = wfMsg( "cur" );
2486 $url = Image
::wfImageUrl( $img );
2488 if ( $wgUser->isSysop() ) {
2489 $link = $wgTitle->escapeLocalURL( "image=" . $wgTitle->getPartialURL() .
2491 $style = $this->getInternalLinkAttributes( $link, $del );
2493 $dlink = "<a href=\"{$link}\"{$style}>{$del}</a>";
2498 $url = wfEscapeHTML( wfImageArchiveUrl( $img ) );
2499 if( $wgUser->getID() != 0 ) {
2500 $rlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2501 wfMsg( "revertimg" ), "action=revert&oldimage=" .
2502 urlencode( $img ) );
2503 $dlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2504 $del, "action=delete&oldimage=" . urlencode( $img ) );
2506 # Having live active links for non-logged in users
2507 # means that bots and spiders crawling our site can
2508 # inadvertently change content. Baaaad idea.
2509 $rlink = wfMsg( "revertimg" );
2514 $userlink = $usertext;
2516 $userlink = $this->makeLink( $wgLang->getNsText( Namespace::getUser() ) .
2517 ":{$usertext}", $usertext );
2519 $nbytes = wfMsg( "nbytes", $size );
2520 $style = $this->getInternalLinkAttributes( $url, $datetime );
2522 $s = "<li> ({$dlink}) ({$rlink}) <a href=\"{$url}\"{$style}>{$datetime}</a>"
2523 . " . . {$userlink} ({$nbytes})";
2525 if ( "" != $description && "*" != $description ) {
2526 $sk=$wgUser->getSkin();
2527 $s .= $wgLang->emphasize(" (" . $sk->formatComment($description) . ")");
2533 function tocIndent($level) {
2534 return str_repeat( "<div class='tocindent'>\n", $level>0 ?
$level : 0 );
2537 function tocUnindent($level) {
2538 return str_repeat( "</div>\n", $level>0 ?
$level : 0 );
2541 # parameter level defines if we are on an indentation level
2542 function tocLine( $anchor, $tocline, $level ) {
2543 $link = "<a href=\"#$anchor\">$tocline</a><br />";
2547 return "<div class='tocline'>$link</div>\n";
2552 function tocTable($toc) {
2553 # note to CSS fanatics: putting this in a div does not work -- div won't auto-expand
2554 # try min-width & co when somebody gets a chance
2555 $hideline = " <script type='text/javascript'>showTocToggle(\"" . addslashes( wfMsg("showtoc") ) . "\",\"" . addslashes( wfMsg("hidetoc") ) . "\")</script>";
2557 "<table border=\"0\" id=\"toc\"><tr><td align=\"center\">\n".
2558 "<b>".wfMsg("toc")."</b>" .
2560 "</td></tr><tr id='tocinside'><td>\n".
2561 $toc."</td></tr></table>\n";
2564 # These two do not check for permissions: check $wgTitle->userCanEdit before calling them
2565 function editSectionScript( $section, $head ) {
2566 global $wgTitle, $wgRequest;
2567 if( $wgRequest->getInt( "oldid" ) && ( $wgRequest->getVal( "diff" ) != "0" ) ) {
2570 $url = $wgTitle->escapeLocalURL( "action=edit§ion=$section" );
2571 return "<span oncontextmenu='document.location=\"$url\";return false;'>{$head}</span>";
2574 function editSectionLink( $section ) {
2576 global $wgTitle, $wgUser, $wgLang;
2578 if( $wgRequest->getInt( "oldid" ) && ( $wgRequest->getVal( "diff" ) != "0" ) ) {
2579 # Section edit links would be out of sync on an old page.
2580 # But, if we're diffing to the current page, they'll be
2585 $editurl = "§ion={$section}";
2586 $url = $this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg("editsection"),"action=edit".$editurl);
2588 if( $wgLang->isRTL() ) {
2590 $nearside = "right";
2595 return "<div class=\"editsection\" style=\"float:$farside;margin-$nearside:5px;\">[".$url."]</div>";
2599 // This function is called by EditPage.php and shows a bulletin board style
2600 // toolbar for common editing functions. It can be disabled in the user preferences.
2601 // The necsesary JavaScript code can be found in style/wikibits.js.
2602 function getEditToolbar() {
2603 global $wgStylePath, $wgLang, $wgMimeType;
2605 // toolarray an array of arrays which each include the filename of
2606 // the button image (without path), the opening tag, the closing tag,
2607 // and optionally a sample text that is inserted between the two when no
2608 // selection is highlighted.
2609 // The tip text is shown when the user moves the mouse over the button.
2611 // Already here are accesskeys (key), which are not used yet until someone
2612 // can figure out a way to make them work in IE. However, we should make
2613 // sure these keys are not defined on the edit page.
2615 array( "image"=>"button_bold.png",
2618 "sample"=>wfMsg("bold_sample"),
2619 "tip"=>wfMsg("bold_tip"),
2622 array( "image"=>"button_italic.png",
2625 "sample"=>wfMsg("italic_sample"),
2626 "tip"=>wfMsg("italic_tip"),
2629 array( "image"=>"button_link.png",
2632 "sample"=>wfMsg("link_sample"),
2633 "tip"=>wfMsg("link_tip"),
2636 array( "image"=>"button_extlink.png",
2639 "sample"=>wfMsg("extlink_sample"),
2640 "tip"=>wfMsg("extlink_tip"),
2643 array( "image"=>"button_headline.png",
2646 "sample"=>wfMsg("headline_sample"),
2647 "tip"=>wfMsg("headline_tip"),
2650 array( "image"=>"button_image.png",
2651 "open"=>"[[".$wgLang->getNsText(NS_IMAGE
).":",
2653 "sample"=>wfMsg("image_sample"),
2654 "tip"=>wfMsg("image_tip"),
2657 array( "image"=>"button_media.png",
2658 "open"=>"[[".$wgLang->getNsText(NS_MEDIA
).":",
2660 "sample"=>wfMsg("media_sample"),
2661 "tip"=>wfMsg("media_tip"),
2664 array( "image"=>"button_math.png",
2665 "open"=>"\\<math\\>",
2666 "close"=>"\\</math\\>",
2667 "sample"=>wfMsg("math_sample"),
2668 "tip"=>wfMsg("math_tip"),
2671 array( "image"=>"button_nowiki.png",
2672 "open"=>"\\<nowiki\\>",
2673 "close"=>"\\</nowiki\\>",
2674 "sample"=>wfMsg("nowiki_sample"),
2675 "tip"=>wfMsg("nowiki_tip"),
2678 array( "image"=>"button_sig.png",
2682 "tip"=>wfMsg("sig_tip"),
2685 array( "image"=>"button_hr.png",
2686 "open"=>"\\n----\\n",
2689 "tip"=>wfMsg("hr_tip"),
2693 $toolbar ="<script type='text/javascript'>\n/*<![CDATA[*/\n";
2695 $toolbar.="document.writeln(\"<div id='toolbar'>\");\n";
2696 foreach($toolarray as $tool) {
2698 $image=$wgStylePath."/images/".$tool["image"];
2699 $open=$tool["open"];
2700 $close=$tool["close"];
2701 $sample = addslashes( $tool["sample"] );
2703 // Note that we use the tip both for the ALT tag and the TITLE tag of the image.
2704 // Older browsers show a "speedtip" type message only for ALT.
2705 // Ideally these should be different, realistically they
2706 // probably don't need to be.
2707 $tip = addslashes( $tool["tip"] );
2709 #$key = $tool["key"];
2711 $toolbar.="addButton('$image','$tip','$open','$close','$sample');\n";
2714 $toolbar.="addInfobox('" . addslashes( wfMsg( "infobox" ) ) . "','" . addslashes(wfMsg("infobox_alert")) . "');\n";
2715 $toolbar.="document.writeln(\"</div>\");\n";
2717 $toolbar.="/*]]>*/\n</script>";
2723 require_once( "SkinStandard.php" );
2724 require_once( "SkinNostalgia.php" );
2725 require_once( "SkinCologneBlue.php" );
2727 if( $wgUsePHPTal ) {
2728 require_once( "SkinPHPTal.php" );