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['myskin'] = "MySkin";
23 #$wgValidSkinNames['monobookminimal'] = "MonoBookMinimal";
26 require_once( "RecentChange.php" );
28 class RCCacheEntry
extends RecentChange
30 var $secureName, $link;
31 var $curlink , $lastlink , $usertalklink , $versionlink ;
32 var $userlink, $timestamp, $watched;
34 function newFromParent( $rc )
36 $rc2 = new RCCacheEntry
;
37 $rc2->mAttribs
= $rc->mAttribs
;
38 $rc2->mExtra
= $rc->mExtra
;
45 /* private */ var $lastdate, $lastline;
46 var $linktrail ; # linktrail regexp
47 var $rc_cache ; # Cache for Enhanced Recent Changes
48 var $rcCacheIndex ; # Recent Changes Cache Counter for visibility toggle
53 $this->linktrail
= wfMsg("linktrail");
56 function getSkinNames()
58 global $wgValidSkinNames;
59 return $wgValidSkinNames;
62 function getStylesheet()
64 return "wikistandard.css";
69 global $wgOut, $wgUser;
71 if ( $wgOut->isQuickbarSuppressed() ) { return 0; }
72 $q = $wgUser->getOption( "quickbar" );
73 if ( "" == $q ) { $q = 0; }
77 function initPage( &$out )
79 $fname = "Skin::initPage";
80 wfProfileIn( $fname );
82 $out->addLink( array( "rel" => "shortcut icon", "href" => "/favicon.ico" ) );
84 $this->addMetadataLinks($out);
86 wfProfileOut( $fname );
89 function addMetadataLinks( &$out ) {
90 global $wgTitle, $wgEnableDublinCoreRdf, $wgEnableCreativeCommonsRdf, $wgRdfMimeType, $action;
91 global $wgRightsPage, $wgRightsUrl;
93 if( $out->isArticleRelated() ) {
94 # note: buggy CC software only reads first "meta" link
95 if( $wgEnableCreativeCommonsRdf ) {
96 $out->addMetadataLink( array(
97 'title' => 'Creative Commons',
98 'type' => 'application/rdf+xml',
99 'href' => $wgTitle->getLocalURL( "action=creativecommons") ) );
101 if( $wgEnableDublinCoreRdf ) {
102 $out->addMetadataLink( array(
103 'title' => 'Dublin Core',
104 'type' => 'application/rdf+xml',
105 'href' => $wgTitle->getLocalURL( "action=dublincore" ) ) );
109 if( $wgRightsPage ) {
110 $copy = Title
::newFromText( $wgRightsPage );
112 $copyright = $copy->getLocalURL();
115 if( !$copyright && $wgRightsUrl ) {
116 $copyright = $wgRightsUrl;
119 $out->addLink( array(
120 "rel" => "copyright",
121 "href" => $copyright ) );
125 function outputPage( &$out ) {
126 global $wgDebugComments;
128 wfProfileIn( "Skin::outputPage" );
129 $this->initPage( $out );
130 $out->out( $out->headElement() );
132 $out->out( "\n<body" );
133 $ops = $this->getBodyOptions();
134 foreach ( $ops as $name => $val ) {
135 $out->out( " $name='$val'" );
138 if ( $wgDebugComments ) {
139 $out->out( "<!-- Wiki debugging output:\n" .
140 $out->mDebugtext
. "-->\n" );
142 $out->out( $this->beforeContent() );
144 $out->out( $out->mBodytext
. "\n" );
146 $out->out( $this->afterContent() );
149 $out->out( $out->reportTime() );
151 $out->out( "\n</body></html>" );
154 function getHeadScripts() {
156 $r = "<script type=\"text/javascript\" src=\"{$wgStylePath}/wikibits.js\"></script>\n";
160 function getUserStyles()
162 global $wgOut, $wgStylePath, $wgLang;
163 $sheet = $this->getStylesheet();
164 $s = "<style type='text/css'>\n";
165 $s .= "/*/*/\n"; # <-- Hide the styles from Netscape 4 without hiding them from IE/Mac
166 $s .= "@import url(\"$wgStylePath/$sheet\");\n";
167 if($wgLang->isRTL()) $s .= "@import url(\"$wgStylePath/common_rtl.css\");\n";
168 $s .= $this->doGetUserStyles();
174 function doGetUserStyles()
179 if ( 1 == $wgUser->getOption( "underline" ) ) {
180 # Don't override browser settings
185 "text-decoration: none; }\n";
187 if ( 1 == $wgUser->getOption( "highlightbroken" ) ) {
188 $s .= "a.new, #quickbar a.new { color: #CC2200; }\n";
190 if ( 1 == $wgUser->getOption( "justify" ) ) {
191 $s .= "#article { text-align: justify; }\n";
196 function getBodyOptions()
198 global $wgUser, $wgTitle, $wgNamespaceBackgrounds, $wgOut, $wgRequest;
200 extract( $wgRequest->getValues( 'oldid', 'redirect', 'diff' ) );
202 if ( 0 != $wgTitle->getNamespace() ) {
203 $a = array( "bgcolor" => "#ffffec" );
205 else $a = array( "bgcolor" => "#FFFFFF" );
206 if($wgOut->isArticle() && $wgUser->getOption("editondblclick") &&
207 (!$wgTitle->isProtected() ||
$wgUser->isSysop()) ) {
208 $t = wfMsg( "editthispage" );
210 if ( !empty($redirect) ) {
211 $red = "&redirect={$redirect}";
213 if ( !empty($oldid) && ! isset( $diff ) ) {
214 $oid = "&oldid={$oldid}";
216 $s = $wgTitle->getFullURL( "action=edit{$oid}{$red}" );
217 $s = "document.location = \"" .$s ."\";";
218 $a +
= array ("ondblclick" => $s);
221 $a['onload'] = $wgOut->getOnloadHandler();
225 function getExternalLinkAttributes( $link, $text, $class='' )
227 global $wgUser, $wgOut, $wgLang;
229 $link = urldecode( $link );
230 $link = $wgLang->checkTitleEncoding( $link );
231 $link = str_replace( "_", " ", $link );
232 $link = wfEscapeHTML( $link );
234 $r = ($class != '') ?
" class='$class'" : " class='external'";
236 if ( 1 == $wgUser->getOption( "hover" ) ) {
237 $r .= " title=\"{$link}\"";
242 function getInternalLinkAttributes( $link, $text, $broken = false )
244 global $wgUser, $wgOut;
246 $link = urldecode( $link );
247 $link = str_replace( "_", " ", $link );
248 $link = wfEscapeHTML( $link );
250 if ( $broken == "stub" ) {
251 $r = " class='stub'";
252 } else if ( $broken == "yes" ) {
258 if ( 1 == $wgUser->getOption( "hover" ) ) {
259 $r .= " title=\"{$link}\"";
264 function getInternalLinkAttributesObj( &$nt, $text, $broken = false )
266 global $wgUser, $wgOut;
268 if ( $broken == "stub" ) {
269 $r = " class='stub'";
270 } else if ( $broken == "yes" ) {
276 if ( 1 == $wgUser->getOption( "hover" ) ) {
277 $r .= ' title ="' . $nt->getEscapedText() . '"';
288 # This will be called immediately after the <body> tag. Split into
289 # two functions to make it easier to subclass.
291 function beforeContent()
293 global $wgUser, $wgOut, $wgSiteNotice;
295 if( $wgSiteNotice ) {
296 $note = "\n<div id='siteNotice'>$wgSiteNotice</div>\n";
300 return $this->doBeforeContent() . $note;
303 function doBeforeContent()
305 global $wgUser, $wgOut, $wgTitle, $wgLang;
306 $fname = "Skin::doBeforeContent";
307 wfProfileIn( $fname );
310 $qb = $this->qbSetting();
312 if( $langlinks = $this->otherLanguages() ) {
318 $borderhack = "class='top'";
321 $s .= "\n<div id='content'>\n<div id='topbar'>\n" .
322 "<table border='0' cellspacing='0' width='98%'>\n<tr>\n";
325 $left = ($qb == 1 ||
$qb == 3);
326 if($wgLang->isRTL()) $left = !$left;
329 $s .= "<td class='top' align='left' valign='top' rowspan='{$rows}'>\n" .
330 $this->logoText() . "</td>";
332 $s .= $this->getQuickbarCompensator( $rows );
334 $l = $wgLang->isRTL() ?
"right" : "left";
335 $s .= "<td {$borderhack} align='$l' valign='top'>\n";
337 $s .= $this->topLinks() ;
338 $s .= "<p class='subtitle'>" . $this->pageTitleLinks() . "</p>\n";
340 $r = $wgLang->isRTL() ?
"left" : "right";
341 $s .= "</td>\n<td {$borderhack} valign='top' align='$r' nowrap='nowrap'>";
342 $s .= $this->nameAndLogin();
343 $s .= "\n<br />" . $this->searchForm() . "</td>";
346 $s .= "</tr>\n<tr>\n<td class='top' colspan=\"2\">$langlinks</td>\n";
349 if ( $shove && !$left ) { # Right
350 $s .= $this->getQuickbarCompensator( $rows );
352 $s .= "</tr>\n</table>\n</div>\n";
353 $s .= "\n<div id='article'>\n";
355 $s .= $this->pageTitle();
356 $s .= $this->pageSubtitle() ;
357 $s .= $this->getCategories();
358 wfProfileOut( $fname );
362 function getCategoryLinks () {
363 global $wgOut, $wgTitle, $wgUser, $wgParser;
364 global $wgUseCategoryMagic, $wgUseCategoryBrowser, $wgLang;
365 if( !$wgUseCategoryMagic ) return "" ;
366 if( count( $wgOut->mCategoryLinks
) == 0 ) return "";
367 if( !$wgOut->isArticle() ) return "";
369 $t = implode ( " | " , $wgOut->mCategoryLinks
) ;
370 $s = $this->makeKnownLink( "Special:Categories",
371 wfMsg( "categories" ), "article=" . urlencode( $wgTitle->getPrefixedDBkey() ) )
374 if($wgUseCategoryBrowser) {
377 $wgTitle->getAllParentCategories(&$catstack);
378 foreach ($catstack as $key => $cat)
380 $s .= $this->makeLink($wgLang->getNSText( Namespace::getCategory() ).":".$key, $key )." > ".$cat."<br/>\n";
387 function getCategories() {
388 $catlinks=$this->getCategoryLinks();
389 if(!empty($catlinks)) {
390 return "<p class='catlinks'>{$catlinks}</p>";
394 function getQuickbarCompensator( $rows = 1 )
396 return "<td width='152' rowspan='{$rows}'> </td>";
399 # This gets called immediately before the </body> tag.
401 function afterContent()
403 global $wgUser, $wgOut, $wgServer;
404 global $wgTitle, $wgLang;
406 $printfooter = "<div class=\"printfooter\">\n" . $this->printFooter() . "</div>\n";
407 return $printfooter . $this->doAfterContent();
410 function printFooter() {
412 $url = htmlspecialchars( $wgTitle->getFullURL() );
413 return "<p>" . wfMsg( "retrievedfrom", "<a href=\"$url\">$url</a>" ) .
414 "</p>\n\n<p>" . $this->pageStats() . "</p>\n";
417 function doAfterContent()
419 global $wgUser, $wgOut, $wgLang;
420 $fname = "Skin::doAfterContent";
421 wfProfileIn( $fname );
422 wfProfileIn( "$fname-1" );
424 $s = "\n</div><br style=\"clear:both\" />\n";
425 $s .= "\n<div id='footer'>";
426 $s .= "<table border='0' cellspacing='0'><tr>";
428 wfProfileOut( "$fname-1" );
429 wfProfileIn( "$fname-2" );
431 $qb = $this->qbSetting();
433 $left = ($qb == 1 ||
$qb == 3);
434 if($wgLang->isRTL()) $left = !$left;
436 if ( $shove && $left ) { # Left
437 $s .= $this->getQuickbarCompensator();
439 wfProfileOut( "$fname-2" );
440 wfProfileIn( "$fname-3" );
441 $l = $wgLang->isRTL() ?
"right" : "left";
442 $s .= "<td class='bottom' align='$l' valign='top'>";
444 $s .= $this->bottomLinks();
445 $s .= "\n<br />" . $this->mainPageLink()
446 . " | " . $this->aboutLink()
447 . " | " . $this->specialLink( "recentchanges" )
448 . " | " . $this->searchForm()
449 . "<br /><span id='pagestats'>" . $this->pageStats() . "</span>";
452 if ( $shove && !$left ) { # Right
453 $s .= $this->getQuickbarCompensator();
455 $s .= "</tr></table>\n</div>\n</div>\n";
457 wfProfileOut( "$fname-3" );
458 wfProfileIn( "$fname-4" );
459 if ( 0 != $qb ) { $s .= $this->quickBar(); }
460 wfProfileOut( "$fname-4" );
461 wfProfileOut( $fname );
465 function pageTitleLinks()
467 global $wgOut, $wgTitle, $wgUser, $wgLang, $wgUseApproval, $wgRequest;
469 extract( $wgRequest->getValues( 'oldid', 'diff' ) );
470 $action = $wgRequest->getText( 'action' );
472 $s = $this->printableLink();
473 if ( wfMsg ( "disclaimers" ) != "-" ) $s .= " | " . $this->makeKnownLink( wfMsg( "disclaimerpage" ), wfMsg( "disclaimers" ) ) ;
475 if ( $wgOut->isArticleRelated() ) {
476 if ( $wgTitle->getNamespace() == Namespace::getImage() ) {
477 $name = $wgTitle->getDBkey();
478 $link = wfEscapeHTML( Image
::wfImageUrl( $name ) );
479 $style = $this->getInternalLinkAttributes( $link, $name );
480 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>";
482 # This will show the "Approve" link if $wgUseApproval=true;
483 if ( isset ( $wgUseApproval ) && $wgUseApproval )
485 $t = $wgTitle->getDBkey();
486 $name = "Approve this article" ;
487 $link = "http://test.wikipedia.org/w/magnus/wiki.phtml?title={$t}&action=submit&doit=1" ;
488 #wfEscapeHTML( wfImageUrl( $name ) );
489 $style = $this->getExternalLinkAttributes( $link, $name );
490 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>" ;
493 if ( "history" == $action ||
isset( $diff ) ||
isset( $oldid ) ) {
494 $s .= " | " . $this->makeKnownLink( $wgTitle->getPrefixedText(),
495 wfMsg( "currentrev" ) );
498 if ( $wgUser->getNewtalk() ) {
499 # do not show "You have new messages" text when we are viewing our
502 if(!(strcmp($wgTitle->getText(),$wgUser->getName()) == 0 &&
503 $wgTitle->getNamespace()==Namespace::getTalk(Namespace::getUser()))) {
504 $n =$wgUser->getName();
505 $tl = $this->makeKnownLink( $wgLang->getNsText(
506 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
507 wfMsg("newmessageslink") );
508 $s.=" | <strong>". wfMsg( "newmessages", $tl ) . "</strong>";
512 $undelete = $this->getUndeleteLink();
513 if( !empty( $undelete ) ) {
514 $s .= " | $undelete";
519 function getUndeleteLink() {
520 global $wgUser, $wgTitle, $wgLang, $action;
521 if( $wgUser->isSysop() &&
522 (($wgTitle->getArticleId() == 0) ||
($action == "history")) &&
523 ($n = $wgTitle->isDeleted() ) ) {
524 return wfMsg( "thisisdeleted",
525 $this->makeKnownLink(
526 $wgLang->SpecialPage( "Undelete/" . $wgTitle->getPrefixedDBkey() ),
527 wfMsg( "restorelink", $n ) ) );
532 function printableLink()
534 global $wgOut, $wgFeedClasses, $wgRequest;
536 $baseurl = $_SERVER['REQUEST_URI'];
537 if( strpos( "?", $baseurl ) == false ) {
542 $baseurl = htmlspecialchars( $baseurl );
543 $printurl = $wgRequest->escapeAppendQuery( "printable=yes" );
545 $s = "<a href=\"$printurl\">" . wfMsg( "printableversion" ) . "</a>";
546 if( $wgOut->isSyndicated() ) {
547 foreach( $wgFeedClasses as $format => $class ) {
548 $feedurl = $wgRequest->escapeAppendQuery( "feed=$format" );
549 $s .= " | <a href=\"$feedurl\">{$format}</a>";
557 global $wgOut, $wgTitle, $wgUser;
559 $s = "<h1 class='pagetitle'>" . htmlspecialchars( $wgOut->getPageTitle() ) . "</h1>";
560 if($wgUser->getOption("editsectiononrightclick") && $wgTitle->userCanEdit()) { $s=$this->editSectionScript(0,$s);}
564 function pageSubtitle()
568 $sub = $wgOut->getSubtitle();
570 global $wgExtraSubtitle;
571 $sub = wfMsg( "fromwikipedia" ) . $wgExtraSubtitle;
573 $subpages = $this->subPageSubtitle();
574 $sub .= !empty($subpages)?
"</p><p class='subpages'>$subpages":'';
575 $s = "<p class='subtitle'>{$sub}</p>\n";
579 function subPageSubtitle()
581 global $wgOut,$wgTitle,$wgNamespacesWithSubpages;
583 if($wgOut->isArticle() && !empty($wgNamespacesWithSubpages[$wgTitle->getNamespace()])) {
584 $ptext=$wgTitle->getPrefixedText();
585 if(preg_match("/\//",$ptext)) {
586 $links=explode("/",$ptext);
589 foreach($links as $link) {
591 if ($c<count($links)) {
592 $growinglink .= $link;
593 $getlink = $this->makeLink( $growinglink, $link );
594 if(preg_match("/class='new'/i",$getlink)) { break; } # this is a hack, but it saves time
600 $subpages .= $getlink;
609 function nameAndLogin()
611 global $wgUser, $wgTitle, $wgLang, $wgShowIPinHeader, $wgIP;
613 $li = $wgLang->specialPage( "Userlogin" );
614 $lo = $wgLang->specialPage( "Userlogout" );
617 if ( 0 == $wgUser->getID() ) {
618 if( $wgShowIPinHeader && isset( $_COOKIE[ini_get("session.name")] ) ) {
621 $tl = $this->makeKnownLink( $wgLang->getNsText(
622 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
623 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
625 $s .= $n . " (".$tl.")";
627 $s .= wfMsg("notloggedin");
630 $rt = $wgTitle->getPrefixedURL();
631 if ( 0 == strcasecmp( urlencode( $lo ), $rt ) ) {
633 } else { $q = "returnto={$rt}"; }
635 $s .= "\n<br />" . $this->makeKnownLink( $li,
636 wfMsg( "login" ), $q );
638 $n = $wgUser->getName();
639 $rt = $wgTitle->getPrefixedURL();
640 $tl = $this->makeKnownLink( $wgLang->getNsText(
641 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
642 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
646 $s .= $this->makeKnownLink( $wgLang->getNsText(
647 Namespace::getUser() ) . ":{$n}", $n ) . "{$tl}<br />" .
648 $this->makeKnownLink( $lo, wfMsg( "logout" ),
649 "returnto={$rt}" ) . " | " .
650 $this->specialLink( "preferences" );
652 $s .= " | " . $this->makeKnownLink( wfMsg( "helppage" ),
658 function getSearchLink() {
659 $searchPage =& Title
::makeTitle( NS_SPECIAL
, "Search" );
660 return $searchPage->getLocalURL();
663 function escapeSearchLink() {
664 return htmlspecialchars( $this->getSearchLink() );
667 function searchForm()
670 $search = $wgRequest->getText( 'search' );
672 $s = "<form name='search' class='inline' method='post' action=\""
673 . $this->escapeSearchLink() . "\">\n"
674 . "<input type='text' name=\"search\" size='19' value=\""
675 . htmlspecialchars(substr($search,0,256)) . "\" />\n"
676 . "<input type='submit' name=\"go\" value=\"" . wfMsg ("go") . "\" /> "
677 . "<input type='submit' name=\"fulltext\" value=\"" . wfMsg ("search") . "\" />\n</form>";
687 $s = $this->mainPageLink() . $sep
688 . $this->specialLink( "recentchanges" );
690 if ( $wgOut->isArticleRelated() ) {
691 $s .= $sep . $this->editThisPage()
692 . $sep . $this->historyLink();
694 # Many people don't like this dropdown box
695 #$s .= $sep . $this->specialPagesList();
700 function bottomLinks()
702 global $wgOut, $wgUser, $wgTitle;
706 if ( $wgOut->isArticleRelated() ) {
707 $s .= "<strong>" . $this->editThisPage() . "</strong>";
708 if ( 0 != $wgUser->getID() ) {
709 $s .= $sep . $this->watchThisPage();
711 $s .= $sep . $this->talkLink()
712 . $sep . $this->historyLink()
713 . $sep . $this->whatLinksHere()
714 . $sep . $this->watchPageLinksLink();
716 if ( $wgTitle->getNamespace() == Namespace::getUser()
717 ||
$wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser()) )
720 $id=User
::idFromName($wgTitle->getText());
721 $ip=User
::isIP($wgTitle->getText());
723 if($id ||
$ip) { # both anons and non-anons have contri list
724 $s .= $sep . $this->userContribsLink();
726 if ( 0 != $wgUser->getID() ) { # show only to signed in users
727 if($id) { # can only email non-anons
728 $s .= $sep . $this->emailUserLink();
732 if ( $wgUser->isSysop() && $wgTitle->getArticleId() ) {
733 $s .= "\n<br />" . $this->deleteThisPage() .
734 $sep . $this->protectThisPage() .
735 $sep . $this->moveThisPage();
737 $s .= "<br />\n" . $this->otherLanguages();
744 global $wgOut, $wgLang, $wgArticle, $wgRequest;
745 global $wgDisableCounters;
747 extract( $wgRequest->getValues( 'oldid', 'diff' ) );
748 if ( ! $wgOut->isArticle() ) { return ""; }
749 if ( isset( $oldid ) ||
isset( $diff ) ) { return ""; }
750 if ( 0 == $wgArticle->getID() ) { return ""; }
753 if ( !$wgDisableCounters ) {
754 $count = $wgLang->formatNum( $wgArticle->getCount() );
756 $s = wfMsg( "viewcount", $count );
760 $s .= " " . $this->getCredits();
762 return $s . " " . $this->getCopyright();
765 function getCredits() {
766 global $wgMaxCredits;
770 if (!isset($wgMaxCredits) ||
$wgMaxCredits == 0) {
771 $s = $this->lastModified();
773 $s = $this->getAuthorCredits();
774 if ($wgMaxCredits > 1) {
775 $s .= " " . $this->getContributorCredits();
782 function getAuthorCredits() {
783 global $wgLang, $wgArticle;
785 $last_author = $wgArticle->getUser();
787 if ($last_author == 0) {
788 $author_credit = wfMsg("anonymous");
790 $real_name = User
::whoIsReal($last_author);
791 if (!empty($real_name)) {
792 $author_credit = $real_name;
794 $author_credit = wfMsg("siteuser", User
::whoIs($last_author));
798 $timestamp = $wgArticle->getTimestamp();
800 $d = $wgLang->timeanddate( $wgArticle->getTimestamp(), true );
804 return wfMsg("lastmodifiedby", $d, $author_credit);
807 function getContributorCredits() {
809 global $wgArticle, $wgMaxCredits, $wgLang;
811 # don't count last editor
813 $contributors = $wgArticle->getContributors($wgMaxCredits - 1);
815 $real_names = array();
816 $user_names = array();
818 # Sift for real versus user names
820 foreach ($contributors as $user_id => $user_parts) {
822 if (!empty($user_parts[1])) {
823 $real_names[$user_id] = $user_parts[1];
825 $user_names[$user_id] = $user_parts[0];
830 $real = $wgLang->listToText(array_values($real_names));
831 $user = $wgLang->listToText(array_values($user_names));
834 $user = wfMsg("siteusers", $user);
837 if ($contributors[0] && $contributors[0][0] > 0) {
838 $anon = wfMsg("anonymous");
843 $creds = $wgLang->listToText(array($real, $user, $anon));
845 return wfMsg("othercontribs", $creds);
848 function getCopyright() {
849 global $wgRightsPage, $wgRightsUrl, $wgRightsText;
851 if( $wgRightsPage ) {
852 $link = $this->makeKnownLink( $wgRightsPage, $wgRightsText );
853 } elseif( $wgRightsUrl ) {
854 $link = $this->makeExternalLink( $wgRightsUrl, $wgRightsText );
859 $out .= wfMsg( "copyright", $link );
863 function getCopyrightIcon() {
864 global $wgRightsPage, $wgRightsUrl, $wgRightsText, $wgRightsIcon;
866 if( $wgRightsIcon ) {
867 $icon = htmlspecialchars( $wgRightsIcon );
869 $url = htmlspecialchars( $wgRightsUrl );
870 $out .= "<a href=\"$url\">";
872 $text = htmlspecialchars( $wgRightsText );
873 $out .= "<img src=\"$icon\" alt='$text' />";
881 function getPoweredBy() {
883 $url = htmlspecialchars( "$wgStylePath/images/poweredby_mediawiki_88x31.png" );
884 $img = "<a href='http://www.mediawiki.org/'><img src='$url' alt='MediaWiki' /></a>";
888 function lastModified()
890 global $wgLang, $wgArticle;
892 $timestamp = $wgArticle->getTimestamp();
894 $d = $wgLang->timeanddate( $wgArticle->getTimestamp(), true );
895 $s = " " . wfMsg( "lastmodified", $d );
902 function logoText( $align = "" )
904 if ( "" != $align ) { $a = " align='{$align}'"; }
907 $mp = wfMsg( "mainpage" );
908 $titleObj = Title
::newFromText( $mp );
909 $s = "<a href=\"" . $titleObj->escapeLocalURL()
910 . "\"><img{$a} src=\""
911 . $this->getLogo() . "\" alt=\"" . "[{$mp}]\" /></a>";
917 global $wgOut, $wgTitle, $wgUser, $wgRequest, $wgLang;
918 global $wgDisableUploads, $wgRemoteUploads;
920 $fname = "Skin::quickBar";
921 wfProfileIn( $fname );
923 $action = $wgRequest->getText( 'action' );
924 $wpPreview = $wgRequest->getBool( 'wpPreview' );
925 $tns=$wgTitle->getNamespace();
927 $s = "\n<div id='quickbar'>";
928 $s .= "\n" . $this->logoText() . "\n<hr class='sep' />";
931 $s .= $this->mainPageLink()
932 . $sep . $this->specialLink( "recentchanges" )
933 . $sep . $this->specialLink( "randompage" );
934 if ($wgUser->getID()) {
935 $s.= $sep . $this->specialLink( "watchlist" ) ;
936 $s .= $sep .$this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
937 wfMsg( "mycontris" ), "target=" . wfUrlencode($wgUser->getName() ) );
940 // only show watchlist link if logged in
941 if ( wfMsg ( "currentevents" ) != "-" ) $s .= $sep . $this->makeKnownLink( wfMsg( "currentevents" ), "" ) ;
942 $s .= "\n<br /><hr class='sep' />";
943 $articleExists = $wgTitle->getArticleId();
944 if ( $wgOut->isArticle() ||
$action =="edit" ||
$action =="history" ||
$wpPreview) {
945 if($wgOut->isArticle()) {
946 $s .= "<strong>" . $this->editThisPage() . "</strong>";
947 } else { # backlink to the article in edit or history mode
948 if($articleExists){ # no backlink if no article
951 $text = wfMsg("articlepage");
954 $text = wfMsg("viewtalkpage");
957 $text = wfMsg("userpage");
960 $text = wfMsg("viewtalkpage");
963 $text = wfMsg("wikipediapage");
966 $text = wfMsg("viewtalkpage");
969 $text = wfMsg("imagepage");
972 $text = wfMsg("viewtalkpage");
975 $text= wfMsg("articlepage");
978 $link = $wgTitle->getText();
979 if ($nstext = $wgLang->getNsText($tns) ) { # add namespace if necessary
980 $link = $nstext . ":" . $link ;
983 $s .= $this->makeLink( $link, $text );
984 } elseif( $wgTitle->getNamespace() != Namespace::getSpecial() ) {
985 # we just throw in a "New page" text to tell the user that he's in edit mode,
986 # and to avoid messing with the separator that is prepended to the next item
987 $s .= "<strong>" . wfMsg("newpage") . "</strong>";
993 if( $tns%2
&& $action!="edit" && !$wpPreview) {
994 $s.="<br />".$this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg("postcomment"),"action=edit§ion=new");
998 watching could cause problems in edit mode:
999 if user edits article, then loads "watch this article" in background and then saves
1000 article with "Watch this article" checkbox disabled, the article is transparently
1001 unwatched. Therefore we do not show the "Watch this page" link in edit mode
1003 if ( 0 != $wgUser->getID() && $articleExists) {
1004 if($action!="edit" && $action != "submit" )
1006 $s .= $sep . $this->watchThisPage();
1008 if ( $wgTitle->userCanEdit() )
1009 $s .= $sep . $this->moveThisPage();
1011 if ( $wgUser->isSysop() and $articleExists ) {
1012 $s .= $sep . $this->deleteThisPage() .
1013 $sep . $this->protectThisPage();
1015 $s .= $sep . $this->talkLink();
1016 if ($articleExists && $action !="history") {
1017 $s .= $sep . $this->historyLink();
1019 $s.=$sep . $this->whatLinksHere();
1021 if($wgOut->isArticleRelated()) {
1022 $s .= $sep . $this->watchPageLinksLink();
1025 if ( Namespace::getUser() == $wgTitle->getNamespace()
1026 ||
$wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser())
1029 $id=User
::idFromName($wgTitle->getText());
1030 $ip=User
::isIP($wgTitle->getText());
1033 $s .= $sep . $this->userContribsLink();
1035 if ( 0 != $wgUser->getID() ) {
1036 if($id) { # can only email real users
1037 $s .= $sep . $this->emailUserLink();
1041 $s .= "\n<br /><hr class='sep' />";
1044 if ( 0 != $wgUser->getID() && ( !$wgDisableUploads ||
$wgRemoteUploads ) ) {
1045 $s .= $this->specialLink( "upload" ) . $sep;
1047 $s .= $this->specialLink( "specialpages" )
1048 . $sep . $this->bugReportsLink();
1050 global $wgSiteSupportPage;
1051 if( $wgSiteSupportPage ) {
1052 $s .= "\n<br /><a href=\"" . htmlspecialchars( $wgSiteSupportPage ) .
1053 "\" class=\"internal\">" . wfMsg( "sitesupport" ) . "</a>";
1056 $s .= "\n<br /></div>\n";
1057 wfProfileOut( $fname );
1061 function specialPagesList()
1063 global $wgUser, $wgOut, $wgLang, $wgServer, $wgRedirectScript;
1065 $pages = SpecialPage
::getPages();
1067 foreach ( $pages[""] as $name => $page ) {
1068 $a[$name] = $page->getDescription();
1070 if ( $wgUser->isSysop() )
1072 foreach ( $pages["sysop"] as $name => $page ) {
1073 $a[$name] = $page->getDescription();
1076 if ( $wgUser->isDeveloper() )
1078 foreach ( $pages["developer"] as $name => $page ) {
1079 $a[$name] = $page->getDescription() ;
1082 $go = wfMsg( "go" );
1083 $sp = wfMsg( "specialpages" );
1084 $spp = $wgLang->specialPage( "Specialpages" );
1086 $s = "<form id=\"specialpages\" method=\"get\" class=\"inline\" " .
1087 "action=\"" . htmlspecialchars( "{$wgServer}{$wgRedirectScript}" ) . "\">\n";
1088 $s .= "<select name=\"wpDropdown\">\n";
1089 $s .= "<option value=\"{$spp}\">{$sp}</option>\n";
1091 foreach ( $a as $name => $desc ) {
1092 $p = $wgLang->specialPage( $name );
1093 $s .= "<option value=\"{$p}\">{$desc}</option>\n";
1095 $s .= "</select>\n";
1096 $s .= "<input type='submit' value=\"{$go}\" name='redirect' />\n";
1101 function mainPageLink()
1103 $mp = wfMsg( "mainpage" );
1104 $s = $this->makeKnownLink( $mp, $mp );
1108 function copyrightLink()
1110 $s = $this->makeKnownLink( wfMsg( "copyrightpage" ),
1111 wfMsg( "copyrightpagename" ) );
1115 function aboutLink()
1117 $s = $this->makeKnownLink( wfMsg( "aboutpage" ),
1118 wfMsg( "aboutwikipedia" ) );
1123 function disclaimerLink()
1125 $s = $this->makeKnownLink( wfMsg( "disclaimerpage" ),
1126 wfMsg( "disclaimers" ) );
1130 function editThisPage()
1132 global $wgOut, $wgTitle, $wgRequest;
1134 $oldid = $wgRequest->getVal( 'oldid' );
1135 $diff = $wgRequest->getVal( 'diff' );
1136 $redirect = $wgRequest->getVal( 'redirect' );
1138 if ( ! $wgOut->isArticleRelated() ) {
1139 $s = wfMsg( "protectedpage" );
1141 $n = $wgTitle->getPrefixedText();
1142 if ( $wgTitle->userCanEdit() ) {
1143 $t = wfMsg( "editthispage" );
1145 #$t = wfMsg( "protectedpage" );
1146 $t = wfMsg( "viewsource" );
1150 if ( !is_null( $redirect ) ) { $red = "&redirect={$redirect}"; }
1151 if ( $oldid && ! isset( $diff ) ) {
1152 $oid = "&oldid={$oldid}";
1154 $s = $this->makeKnownLink( $n, $t, "action=edit{$oid}{$red}" );
1159 function deleteThisPage()
1161 global $wgUser, $wgOut, $wgTitle, $wgRequest;
1163 $diff = $wgRequest->getVal( 'diff' );
1164 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
1165 $n = $wgTitle->getPrefixedText();
1166 $t = wfMsg( "deletethispage" );
1168 $s = $this->makeKnownLink( $n, $t, "action=delete" );
1175 function protectThisPage()
1177 global $wgUser, $wgOut, $wgTitle, $wgRequest;
1179 $diff = $wgRequest->getVal( 'diff' );
1180 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
1181 $n = $wgTitle->getPrefixedText();
1183 if ( $wgTitle->isProtected() ) {
1184 $t = wfMsg( "unprotectthispage" );
1185 $q = "action=unprotect";
1187 $t = wfMsg( "protectthispage" );
1188 $q = "action=protect";
1190 $s = $this->makeKnownLink( $n, $t, $q );
1197 function watchThisPage()
1199 global $wgUser, $wgOut, $wgTitle;
1201 if ( $wgOut->isArticleRelated() ) {
1202 $n = $wgTitle->getPrefixedText();
1204 if ( $wgTitle->userIsWatching() ) {
1205 $t = wfMsg( "unwatchthispage" );
1206 $q = "action=unwatch";
1208 $t = wfMsg( "watchthispage" );
1209 $q = "action=watch";
1211 $s = $this->makeKnownLink( $n, $t, $q );
1213 $s = wfMsg( "notanarticle" );
1218 function moveThisPage()
1220 global $wgTitle, $wgLang;
1222 if ( $wgTitle->userCanEdit() ) {
1223 $s = $this->makeKnownLink( $wgLang->specialPage( "Movepage" ),
1224 wfMsg( "movethispage" ), "target=" . $wgTitle->getPrefixedURL() );
1225 } // no message if page is protected - would be redundant
1229 function historyLink()
1233 $s = $this->makeKnownLink( $wgTitle->getPrefixedText(),
1234 wfMsg( "history" ), "action=history" );
1238 function whatLinksHere()
1240 global $wgTitle, $wgLang;
1242 $s = $this->makeKnownLink( $wgLang->specialPage( "Whatlinkshere" ),
1243 wfMsg( "whatlinkshere" ), "target=" . $wgTitle->getPrefixedURL() );
1247 function userContribsLink()
1249 global $wgTitle, $wgLang;
1251 $s = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
1252 wfMsg( "contributions" ), "target=" . $wgTitle->getPartialURL() );
1256 function emailUserLink()
1258 global $wgTitle, $wgLang;
1260 $s = $this->makeKnownLink( $wgLang->specialPage( "Emailuser" ),
1261 wfMsg( "emailuser" ), "target=" . $wgTitle->getPartialURL() );
1265 function watchPageLinksLink()
1267 global $wgOut, $wgTitle, $wgLang;
1269 if ( ! $wgOut->isArticleRelated() ) {
1270 $s = "(" . wfMsg( "notanarticle" ) . ")";
1272 $s = $this->makeKnownLink( $wgLang->specialPage(
1273 "Recentchangeslinked" ), wfMsg( "recentchangeslinked" ),
1274 "target=" . $wgTitle->getPrefixedURL() );
1279 function otherLanguages()
1281 global $wgOut, $wgLang, $wgTitle, $wgUseNewInterlanguage;
1283 $a = $wgOut->getLanguageLinks();
1284 if ( 0 == count( $a ) ) {
1285 if ( !$wgUseNewInterlanguage ) return "";
1286 $ns = $wgLang->getNsIndex ( $wgTitle->getNamespace () ) ;
1287 if ( $ns != 0 AND $ns != 1 ) return "" ;
1289 $x = "mode=addlink&xt=".$wgTitle->getDBkey() ;
1290 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1291 wfMsg( "intl" ) , $x );
1294 if ( !$wgUseNewInterlanguage ) {
1295 $s = wfMsg( "otherlanguages" ) . ": ";
1297 global $wgLanguageCode ;
1298 $x = "mode=zoom&xt=".$wgTitle->getDBkey() ;
1299 $x .= "&xl=".$wgLanguageCode ;
1300 $s = $this->makeKnownLink( $wgLang->specialPage( "Intl" ),
1301 wfMsg( "otherlanguages" ) , $x ) . ": " ;
1304 $s = wfMsg( "otherlanguages" ) . ": ";
1306 if($wgLang->isRTL()) $s .= "<span dir='LTR'>";
1307 foreach( $a as $l ) {
1308 if ( ! $first ) { $s .= " | "; }
1311 $nt = Title
::newFromText( $l );
1312 $url = $nt->getFullURL();
1313 $text = $wgLang->getLanguageName( $nt->getInterwiki() );
1315 if ( "" == $text ) { $text = $l; }
1316 $style = $this->getExternalLinkAttributes( $l, $text );
1317 $s .= "<a href=\"{$url}\"{$style}>{$text}</a>";
1319 if($wgLang->isRTL()) $s .= "</span>";
1323 function bugReportsLink()
1325 $s = $this->makeKnownLink( wfMsg( "bugreportspage" ),
1326 wfMsg( "bugreports" ) );
1332 global $wgLinkCache;
1333 $t1 = Title
::newFromText( gmdate( "F j" ) );
1334 $t2 = Title
::newFromText( gmdate( "Y" ) );
1336 $wgLinkCache->suspend();
1337 $id = $t1->getArticleID();
1338 $wgLinkCache->resume();
1341 $s = $this->makeBrokenLink( $t1->getText() );
1343 $s = $this->makeKnownLink( $t1->getText() );
1347 $wgLinkCache->suspend();
1348 $id = $t2->getArticleID();
1349 $wgLinkCache->resume();
1352 $s .= $this->makeBrokenLink( $t2->getText() );
1354 $s .= $this->makeKnownLink( $t2->getText() );
1361 global $wgLang, $wgTitle, $wgLinkCache;
1363 $tns = $wgTitle->getNamespace();
1364 if ( -1 == $tns ) { return ""; }
1366 $pn = $wgTitle->getText();
1367 $tp = wfMsg( "talkpage" );
1368 if ( Namespace::isTalk( $tns ) ) {
1369 $lns = Namespace::getSubject( $tns );
1372 $text = wfMsg("articlepage");
1375 $text = wfMsg("userpage");
1378 $text = wfMsg("wikipediapage");
1381 $text = wfMsg("imagepage");
1384 $text= wfMsg("articlepage");
1388 $lns = Namespace::getTalk( $tns );
1391 $n = $wgLang->getNsText( $lns );
1392 if ( "" == $n ) { $link = $pn; }
1393 else { $link = "{$n}:{$pn}"; }
1395 $wgLinkCache->suspend();
1396 $s = $this->makeLink( $link, $text );
1397 $wgLinkCache->resume();
1402 function commentLink()
1404 global $wgLang, $wgTitle, $wgLinkCache;
1406 $tns = $wgTitle->getNamespace();
1407 if ( -1 == $tns ) { return ""; }
1409 $lns = ( Namespace::isTalk( $tns ) ) ?
$tns : Namespace::getTalk( $tns );
1411 # assert Namespace::isTalk( $lns )
1413 $n = $wgLang->getNsText( $lns );
1414 $pn = $wgTitle->getText();
1416 $link = "{$n}:{$pn}";
1418 $wgLinkCache->suspend();
1419 $s = $this->makeKnownLink($link, wfMsg("postcomment"), "action=edit§ion=new");
1420 $wgLinkCache->resume();
1425 # After all the page content is transformed into HTML, it makes
1426 # a final pass through here for things like table backgrounds.
1428 function transformContent( $text )
1433 # Note: This function MUST call getArticleID() on the link,
1434 # otherwise the cache won't get updated properly. See LINKCACHE.DOC.
1436 function makeLink( $title, $text = "", $query = "", $trail = "" ) {
1437 wfProfileIn( "Skin::makeLink" );
1438 $nt = Title
::newFromText( $title );
1440 $result = $this->makeLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1442 wfDebug( "Invalid title passed to Skin::makeLink(): \"$title\"\n" );
1443 $result = $text == "" ?
$title : $text;
1446 wfProfileOut( "Skin::makeLink" );
1450 function makeKnownLink( $title, $text = "", $query = "", $trail = "", $prefix = '',$aprops = '') {
1451 $nt = Title
::newFromText( $title );
1453 return $this->makeKnownLinkObj( Title
::newFromText( $title ), $text, $query, $trail, $prefix , $aprops );
1455 wfDebug( "Invalid title passed to Skin::makeKnownLink(): \"$title\"\n" );
1456 return $text == "" ?
$title : $text;
1460 function makeBrokenLink( $title, $text = "", $query = "", $trail = "" ) {
1461 $nt = Title
::newFromText( $title );
1463 return $this->makeBrokenLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1465 wfDebug( "Invalid title passed to Skin::makeBrokenLink(): \"$title\"\n" );
1466 return $text == "" ?
$title : $text;
1470 function makeStubLink( $title, $text = "", $query = "", $trail = "" ) {
1471 $nt = Title
::newFromText( $title );
1473 return $this->makeStubLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1475 wfDebug( "Invalid title passed to Skin::makeStubLink(): \"$title\"\n" );
1476 return $text == "" ?
$title : $text;
1480 # Pass a title object, not a title string
1481 function makeLinkObj( &$nt, $text= "", $query = "", $trail = "", $prefix = "" )
1483 global $wgOut, $wgUser;
1484 if ( $nt->isExternal() ) {
1485 $u = $nt->getFullURL();
1486 $link = $nt->getPrefixedURL();
1487 if ( "" == $text ) { $text = $nt->getPrefixedText(); }
1488 $style = $this->getExternalLinkAttributes( $link, $text, 'extiw' );
1491 if ( "" != $trail ) {
1492 if ( preg_match( "/^([a-z]+)(.*)$$/sD", $trail, $m ) ) {
1497 $retVal = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1498 } elseif ( 0 == $nt->getNamespace() && "" == $nt->getText() ) {
1499 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1500 } elseif ( ( -1 == $nt->getNamespace() ) ||
1501 ( Namespace::getImage() == $nt->getNamespace() ) ) {
1502 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1504 $aid = $nt->getArticleID() ;
1506 $retVal = $this->makeBrokenLinkObj( $nt, $text, $query, $trail, $prefix );
1508 $threshold = $wgUser->getOption("stubthreshold") ;
1509 if ( $threshold > 0 ) {
1510 $res = wfQuery ( "SELECT LENGTH(cur_text) AS x, cur_namespace, cur_is_redirect FROM cur WHERE cur_id='{$aid}'", DB_READ
) ;
1512 if ( wfNumRows( $res ) > 0 ) {
1513 $s = wfFetchObject( $res );
1515 if ( $s->cur_is_redirect
OR $s->cur_namespace
!= 0 ) {
1516 $size = $threshold*2 ; # Really big
1518 wfFreeResult( $res );
1520 $size = $threshold*2 ; # Really big
1525 if ( $size < $threshold ) {
1526 $retVal = $this->makeStubLinkObj( $nt, $text, $query, $trail, $prefix );
1528 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1535 # Pass a title object, not a title string
1536 function makeKnownLinkObj( &$nt, $text = "", $query = "", $trail = "", $prefix = "" , $aprops = '')
1538 global $wgOut, $wgTitle;
1540 $fname = "Skin::makeKnownLinkObj";
1541 wfProfileIn( $fname );
1543 $link = $nt->getPrefixedURL();
1545 if ( "" == $link ) {
1547 if ( "" == $text ) {
1548 $text = htmlspecialchars( $nt->getFragment() );
1551 $u = $nt->escapeLocalURL( $query );
1553 if ( "" != $nt->getFragment() ) {
1554 $u .= "#" . htmlspecialchars( $nt->getFragment() );
1556 if ( "" == $text ) {
1557 $text = htmlspecialchars( $nt->getPrefixedText() );
1559 $style = $this->getInternalLinkAttributesObj( $nt, $text );
1562 if ( "" != $trail ) {
1563 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1568 $r = "<a href=\"{$u}\"{$style}{$aprops}>{$prefix}{$text}{$inside}</a>{$trail}";
1569 wfProfileOut( $fname );
1573 # Pass a title object, not a title string
1574 function makeBrokenLinkObj( &$nt, $text = "", $query = "", $trail = "", $prefix = "" )
1576 global $wgOut, $wgUser;
1578 $fname = "Skin::makeBrokenLinkObj";
1579 wfProfileIn( $fname );
1581 if ( "" == $query ) {
1584 $q = "action=edit&{$query}";
1586 $u = $nt->escapeLocalURL( $q );
1588 if ( "" == $text ) {
1589 $text = htmlspecialchars( $nt->getPrefixedText() );
1591 $style = $this->getInternalLinkAttributesObj( $nt, $text, "yes" );
1594 if ( "" != $trail ) {
1595 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1600 if ( $wgUser->getOption( "highlightbroken" ) ) {
1601 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1603 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>?</a>{$trail}";
1606 wfProfileOut( $fname );
1610 # Pass a title object, not a title string
1611 function makeStubLinkObj( &$nt, $text = "", $query = "", $trail = "", $prefix = "" )
1613 global $wgOut, $wgUser;
1615 $link = $nt->getPrefixedURL();
1617 $u = $nt->escapeLocalURL( $query );
1619 if ( "" == $text ) {
1620 $text = htmlspecialchars( $nt->getPrefixedText() );
1622 $style = $this->getInternalLinkAttributesObj( $nt, $text, "stub" );
1625 if ( "" != $trail ) {
1626 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1631 if ( $wgUser->getOption( "highlightbroken" ) ) {
1632 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1634 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>!</a>{$trail}";
1639 function makeSelfLinkObj( &$nt, $text = "", $query = "", $trail = "", $prefix = "" )
1641 $u = $nt->escapeLocalURL( $query );
1642 if ( "" == $text ) {
1643 $text = htmlspecialchars( $nt->getPrefixedText() );
1646 if ( "" != $trail ) {
1647 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1652 return "<strong>{$prefix}{$text}{$inside}</strong>{$trail}";
1655 /* these are used extensively in SkinPHPTal, but also some other places */
1656 /*static*/ function makeSpecialUrl( $name, $urlaction='' ) {
1657 $title = Title
::makeTitle( NS_SPECIAL
, $name );
1658 $this->checkTitle($title, $name);
1659 return $title->getLocalURL( $urlaction );
1661 /*static*/ function makeTalkUrl ( $name, $urlaction='' ) {
1662 $title = Title
::newFromText( $name );
1663 $title = $title->getTalkPage();
1664 $this->checkTitle($title, $name);
1665 return $title->getLocalURL( $urlaction );
1667 /*static*/ function makeArticleUrl ( $name, $urlaction='' ) {
1668 $title = Title
::newFromText( $name );
1669 $title= $title->getSubjectPage();
1670 $this->checkTitle($title, $name);
1671 return $title->getLocalURL( $urlaction );
1673 /*static*/ function makeI18nUrl ( $name, $urlaction='' ) {
1674 $title = Title
::newFromText( wfMsg($name) );
1675 $this->checkTitle($title, $name);
1676 return $title->getLocalURL( $urlaction );
1678 /*static*/ function makeUrl ( $name, $urlaction='' ) {
1679 $title = Title
::newFromText( $name );
1680 $this->checkTitle($title, $name);
1681 return $title->getLocalURL( $urlaction );
1683 # this can be passed the NS number as defined in Language.php
1684 /*static*/ function makeNSUrl( $name, $urlaction='', $namespace=0 ) {
1685 $title = Title
::makeTitle( $namespace, $name );
1686 $this->checkTitle($title, $name);
1687 return $title->getLocalURL( $urlaction );
1690 /* these return an array with the 'href' and boolean 'exists' */
1691 /*static*/ function makeUrlDetails ( $name, $urlaction='' ) {
1692 $title = Title
::newFromText( $name );
1693 $this->checkTitle($title, $name);
1695 'href' => $title->getLocalURL( $urlaction ),
1696 'exists' => $title->getArticleID() != 0?
true:false
1699 /*static*/ function makeTalkUrlDetails ( $name, $urlaction='' ) {
1700 $title = Title
::newFromText( $name );
1701 $title = $title->getTalkPage();
1702 $this->checkTitle($title, $name);
1704 'href' => $title->getLocalURL( $urlaction ),
1705 'exists' => $title->getArticleID() != 0?
true:false
1708 /*static*/ function makeArticleUrlDetails ( $name, $urlaction='' ) {
1709 $title = Title
::newFromText( $name );
1710 $title= $title->getSubjectPage();
1711 $this->checkTitle($title, $name);
1713 'href' => $title->getLocalURL( $urlaction ),
1714 'exists' => $title->getArticleID() != 0?
true:false
1717 /*static*/ function makeI18nUrlDetails ( $name, $urlaction='' ) {
1718 $title = Title
::newFromText( wfMsg($name) );
1719 $this->checkTitle($title, $name);
1721 'href' => $title->getLocalURL( $urlaction ),
1722 'exists' => $title->getArticleID() != 0?
true:false
1726 # make sure we have some title to operate on
1727 /*static*/ function checkTitle ( &$title, &$name ) {
1728 if(!is_object($title)) {
1729 $title = Title
::newFromText( $name );
1730 if(!is_object($title)) {
1731 $title = Title
::newFromText( '<error: link target missing>' );
1736 function fnamePart( $url )
1738 $basename = strrchr( $url, "/" );
1739 if ( false === $basename ) { $basename = $url; }
1740 else { $basename = substr( $basename, 1 ); }
1741 return wfEscapeHTML( $basename );
1744 function makeImage( $url, $alt = "" )
1748 if ( "" == $alt ) { $alt = $this->fnamePart( $url ); }
1749 $s = "<img src=\"{$url}\" alt=\"{$alt}\" />";
1753 function makeImageLink( $name, $url, $alt = "" ) {
1754 $nt = Title
::makeTitle( Namespace::getImage(), $name );
1755 return $this->makeImageLinkObj( $nt, $alt );
1758 function makeImageLinkObj( $nt, $alt = "" ) {
1759 global $wgLang, $wgUseImageResize;
1760 $img = Image
::newFromTitle( $nt );
1761 $url = $img->getURL();
1764 $prefix = $postfix = "";
1766 if ( $wgUseImageResize ) {
1767 # Check if the alt text is of the form "options|alt text"
1769 # * thumbnail make a thumbnail with enlarge-icon and caption, alignment depends on lang
1770 # * left no resizing, just left align. label is used for alt= only
1771 # * right same, but right aligned
1772 # * none same, but not aligned
1773 # * ___px scale to ___ pixels width, no aligning. e.g. use in taxobox
1774 # * center center the image
1775 # * framed Keep original image size, no magnify-button.
1777 $part = explode( "|", $alt);
1779 $mwThumb =& MagicWord
::get( MAG_IMG_THUMBNAIL
);
1780 $mwLeft =& MagicWord
::get( MAG_IMG_LEFT
);
1781 $mwRight =& MagicWord
::get( MAG_IMG_RIGHT
);
1782 $mwNone =& MagicWord
::get( MAG_IMG_NONE
);
1783 $mwWidth =& MagicWord
::get( MAG_IMG_WIDTH
);
1784 $mwCenter =& MagicWord
::get( MAG_IMG_CENTER
);
1785 $mwFramed =& MagicWord
::get( MAG_IMG_FRAMED
);
1786 $alt = $part[count($part)-1];
1788 $height = $framed = $thumb = false;
1790 foreach( $part as $key => $val ) {
1791 if ( ! is_null( $mwThumb->matchVariableStartToEnd($val) ) ) {
1793 } elseif ( ! is_null( $mwRight->matchVariableStartToEnd($val) ) ) {
1794 # remember to set an alignment, don't render immediately
1796 } elseif ( ! is_null( $mwLeft->matchVariableStartToEnd($val) ) ) {
1797 # remember to set an alignment, don't render immediately
1799 } elseif ( ! is_null( $mwCenter->matchVariableStartToEnd($val) ) ) {
1800 # remember to set an alignment, don't render immediately
1802 } elseif ( ! is_null( $mwNone->matchVariableStartToEnd($val) ) ) {
1803 # remember to set an alignment, don't render immediately
1805 } elseif ( ! is_null( $match = $mwWidth->matchVariableStartToEnd($val) ) ) {
1806 # $match is the image width in pixels
1807 if ( preg_match( "/^([0-9]*)x([0-9]*)$/", $match, $m ) ) {
1808 $width = intval( $m[1] );
1809 $height = intval( $m[2] );
1811 $width = intval($match);
1813 } elseif ( ! is_null( $mwFramed->matchVariableStartToEnd($val) ) ) {
1817 if ( "center" == $align )
1819 $prefix = '<span style="text-align: center">';
1820 $postfix = '</span>';
1824 if ( $thumb ||
$framed ) {
1826 # Create a thumbnail. Alignment depends on language
1827 # writing direction, # right aligned for left-to-right-
1828 # languages ("Western languages"), left-aligned
1829 # for right-to-left-languages ("Semitic languages")
1831 # If thumbnail width has not been provided, it is set
1832 # here to 180 pixels
1833 if ( $align == "" ) {
1834 $align = $wgLang->isRTL() ?
"left" : "right";
1836 if ( ! isset($width) ) {
1839 return $prefix.$this->makeThumbLinkObj( $img, $alt, $align, $width, $height, $framed ).$postfix;
1841 } elseif ( isset($width) ) {
1843 # Create a resized image, without the additional thumbnail
1846 if ( ( ! $height === false )
1847 && ( $img->getHeight() * $width / $img->getWidth() > $height ) ) {
1848 print "height=$height<br>\nimg->getHeight() = ".$img->getHeight()."<br>\n";
1849 print "rescaling by factor ". $height / $img->getHeight() . "<br>\n";
1850 $width = $img->getWidth() * $height / $img->getHeight();
1852 $url = $img->createThumb( $width );
1854 } # endif $wgUseImageResize
1856 if ( empty( $alt ) ) {
1857 $alt = preg_replace( '/\.(.+?)^/', '', $img->getName() );
1859 $alt = htmlspecialchars( $alt );
1861 $u = $nt->escapeLocalURL();
1864 $s = str_replace( "$1", $img->getName(), wfMsg("missingimage") );
1865 $s .= "<br>{$alt}<br>{$url}<br>\n";
1867 $s = "<a href=\"{$u}\" class='image' title=\"{$alt}\">" .
1868 "<img src=\"{$url}\" alt=\"{$alt}\" /></a>";
1870 if ( "" != $align ) {
1871 $s = "<div class=\"float{$align}\"><span>{$s}</span></div>";
1873 return str_replace("\n", ' ',$prefix.$s.$postfix);
1877 function makeThumbLinkObj( $img, $label = "", $align = "right", $boxwidth = 180, $boxheight=false, $framed=false ) {
1878 global $wgStylePath, $wgLang;
1879 # $image = Title::makeTitle( Namespace::getImage(), $name );
1880 $url = $img->getURL();
1882 #$label = htmlspecialchars( $label );
1883 $alt = preg_replace( "/<[^>]*>/", "", $label);
1884 $alt = htmlspecialchars( $alt );
1886 if ( $img->exists() )
1888 $width = $img->getWidth();
1889 $height = $img->getHeight();
1891 $width = $height = 200;
1895 // Use image dimensions, don't scale
1897 $oboxwidth = $boxwidth +
2;
1898 $boxheight = $height;
1901 $h = intval( $height/($width/$boxwidth) );
1902 $oboxwidth = $boxwidth +
2;
1903 if ( ( ! $boxheight === false ) && ( $h > $boxheight ) )
1905 $boxwidth *= $boxheight/$h;
1909 $thumbUrl = $img->createThumb( $boxwidth );
1912 $u = $img->getEscapeLocalURL();
1914 $more = htmlspecialchars( wfMsg( "thumbnail-more" ) );
1915 $magnifyalign = $wgLang->isRTL() ?
"left" : "right";
1916 $textalign = $wgLang->isRTL() ?
' style="text-align:right"' : "";
1918 $s = "<div class=\"thumb t{$align}\"><div style=\"width:{$oboxwidth}px;\">";
1919 if ( $thumbUrl == "" ) {
1920 $s .= str_replace( "$1", $img->getName(), wfMsg("missingimage") );
1923 $s .= '<a href="'.$u.'" class="internal" title="'.$alt.'">'.
1924 '<img src="'.$thumbUrl.'" alt="'.$alt.'" ' .
1925 'width="'.$boxwidth.'" height="'.$boxheight.'" /></a>';
1929 $zoomicon = '<div class="magnify" style="float:'.$magnifyalign.'">'.
1930 '<a href="'.$u.'" class="internal" title="'.$more.'">'.
1931 '<img src="'.$wgStylePath.'/images/magnify-clip.png" ' .
1932 'width="15" height="11" alt="'.$more.'" /></a></div>';
1935 $s .= ' <div class="thumbcaption" '.$textalign.'>'.$zoomicon.$label."</div></div></div>";
1936 return str_replace("\n", ' ', $s);
1939 function makeMediaLink( $name, $url, $alt = "" ) {
1940 $nt = Title
::makeTitle( Namespace::getMedia(), $name );
1941 return $this->makeMediaLinkObj( $nt, $alt );
1944 function makeMediaLinkObj( $nt, $alt = "" )
1946 if ( ! isset( $nt ) )
1948 ### HOTFIX. Instead of breaking, return empry string.
1951 $name = $nt->getDBKey();
1952 $url = Image
::wfImageUrl( $name );
1953 if ( empty( $alt ) ) {
1954 $alt = preg_replace( '/\.(.+?)^/', '', $name );
1957 $u = htmlspecialchars( $url );
1958 $s = "<a href=\"{$u}\" class='internal' title=\"{$alt}\">{$alt}</a>";
1963 function specialLink( $name, $key = "" )
1967 if ( "" == $key ) { $key = strtolower( $name ); }
1968 $pn = $wgLang->ucfirst( $name );
1969 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1973 function makeExternalLink( $url, $text, $escape = true ) {
1974 $style = $this->getExternalLinkAttributes( $url, $text );
1975 $url = htmlspecialchars( $url );
1977 $text = htmlspecialchars( $text );
1979 return "<a href=\"$url\"$style>$text</a>";
1982 # Called by history lists and recent changes
1985 # Returns text for the start of the tabular part of RC
1986 function beginRecentChangesList()
1988 $this->rc_cache
= array() ;
1989 $this->rcMoveIndex
= 0;
1990 $this->rcCacheIndex
= 0 ;
1991 $this->lastdate
= "";
1992 $this->rclistOpen
= false;
1996 function beginImageHistoryList()
1998 $s = "\n<h2>" . wfMsg( "imghistory" ) . "</h2>\n" .
1999 "<p>" . wfMsg( "imghistlegend" ) . "</p>\n<ul class='special'>";
2003 # Returns text for the end of RC
2004 # If enhanced RC is in use, returns pretty much all the text
2005 function endRecentChangesList()
2007 $s = $this->recentChangesBlock() ;
2008 if( $this->rclistOpen
) {
2014 # Enhanced RC ungrouped line
2015 function recentChangesBlockLine ( $rcObj )
2017 global $wgStylePath, $wgLang ;
2019 # Get rc_xxxx variables
2020 extract( $rcObj->mAttribs
) ;
2021 $curIdEq = "curid=$rc_cur_id";
2026 $r .= "<img src='{$wgStylePath}/images/Arr_.png' width='12' height='12' border='0' />" ; $r .= "<tt>" ;
2028 if ( $rc_type == RC_MOVE
) {
2029 $r .= " ";
2031 # M & N (minor & new)
2032 $M = wfMsg( "minoreditletter" );
2033 $N = wfMsg( "newpageletter" );
2035 if ( $rc_type == RC_NEW
) {
2048 $r .= " ".$rcObj->timestamp
." " ;
2052 $link = $rcObj->link
;
2053 if ( $rcObj->watched
) $link = "<strong>{$link}</strong>" ;
2058 $r .= $rcObj->curlink
;
2062 $r .= $this->makeKnownLinkObj( $rcObj->getTitle(), wfMsg( "hist" ), "{$curIdEq}&action=history" );
2065 $r .= ") . . ".$rcObj->userlink
;
2066 $r .= $rcObj->usertalklink
;
2069 if ( $rc_comment != "" && $rc_type != RC_MOVE
) {
2070 $rc_comment=$this->formatComment($rc_comment);
2071 $r .= $wgLang->emphasize( " (".$rc_comment.")" );
2079 function recentChangesBlockGroup ( $block )
2081 global $wgStylePath, $wgLang ;
2084 $M = wfMsg( "minoreditletter" );
2085 $N = wfMsg( "newpageletter" );
2087 # Collate list of users
2089 $userlinks = array () ;
2090 foreach ( $block AS $rcObj ) {
2091 $oldid = $rcObj->mAttribs
['rc_last_oldid'];
2092 if ( $rcObj->mAttribs
['rc_new'] ) $isnew = true ;
2093 $u = $rcObj->userlink
;
2094 if ( !isset ( $userlinks[$u] ) ) $userlinks[$u] = 0 ;
2098 # Sort the list and convert to text
2099 krsort ( $userlinks ) ;
2100 asort ( $userlinks ) ;
2102 foreach ( $userlinks as $userlink => $count) {
2104 if ( $count > 1 ) $text .= " ({$count}×)" ;
2105 array_push ( $users , $text ) ;
2107 $users = " <font size='-1'>[".implode("; ",$users)."]</font>" ;
2110 $rci = "RCI{$this->rcCacheIndex}" ;
2111 $rcl = "RCL{$this->rcCacheIndex}" ;
2112 $rcm = "RCM{$this->rcCacheIndex}" ;
2113 $toggleLink = "javascript:toggleVisibility(\"{$rci}\",\"{$rcm}\",\"{$rcl}\")" ;
2114 $arrowdir = $wgLang->isRTL() ?
"l" : "r";
2115 $tl = "<span id='{$rcm}'><a href='$toggleLink'><img src='{$wgStylePath}/images/Arr_{$arrowdir}.png' width='12' height='12' /></a></span>" ;
2116 $tl .= "<span id='{$rcl}' style='display:none'><a href='$toggleLink'><img src='{$wgStylePath}/images/Arr_d.png' width='12' height='12' /></a></span>" ;
2122 if ( $isnew ) $r .= $N ;
2123 else $r .= " " ;
2124 $r .= " " ; # Minor
2127 $r .= " ".$block[0]->timestamp
." " ;
2131 $link = $block[0]->link
;
2132 if ( $block[0]->watched
) $link = "<strong>{$link}</strong>" ;
2135 $curIdEq = "curid=" . $block[0]->mAttribs
['rc_cur_id'];
2136 if ( $block[0]->mAttribs
['rc_type'] != RC_LOG
) {
2138 $r .= " (".count($block)." " ;
2139 if ( $isnew ) $r .= wfMsg("changes");
2140 else $r .= $this->makeKnownLinkObj( $block[0]->getTitle() , wfMsg("changes") ,
2141 "{$curIdEq}&diff=0&oldid=".$oldid ) ;
2145 $r .= $this->makeKnownLinkObj( $block[0]->getTitle(), wfMsg( "history" ), "{$curIdEq}&action=history" );
2153 $r .= "<div id='{$rci}' style='display:none'>" ;
2154 foreach ( $block AS $rcObj ) {
2155 # Get rc_xxxx variables
2156 extract( $rcObj->mAttribs
);
2158 $r .= "<img src='{$wgStylePath}/images/Arr_.png' width=12 height=12 />";
2159 $r .= "<tt> " ;
2160 if ( $rc_new ) $r .= $N ;
2161 else $r .= " " ;
2162 if ( $rc_minor ) $r .= $M ;
2163 else $r .= " " ;
2167 if ( $rc_last_oldid != 0 ) {
2168 $o = "oldid=".$rc_last_oldid ;
2170 if ( $rc_type == RC_LOG
) {
2171 $link = $rcObj->timestamp
;
2173 $link = $this->makeKnownLinkObj( $rcObj->getTitle(), $rcObj->timestamp
, "{$curIdEq}&$o" ) ;
2175 $link = "<tt>{$link}</tt>" ;
2179 $r .= $rcObj->curlink
;
2181 $r .= $rcObj->lastlink
;
2182 $r .= ") . . ".$rcObj->userlink
;
2183 $r .= $rcObj->usertalklink
;
2184 if ( $rc_comment != "" ) {
2185 $rc_comment=$this->formatComment($rc_comment);
2186 $r .= $wgLang->emphasize( " (".$rc_comment.")" ) ;
2192 $this->rcCacheIndex++
;
2196 # If enhanced RC is in use, this function takes the previously cached
2197 # RC lines, arranges them, and outputs the HTML
2198 function recentChangesBlock ()
2200 global $wgStylePath ;
2201 if ( count ( $this->rc_cache
) == 0 ) return "" ;
2203 foreach ( $this->rc_cache
AS $secureName => $block ) {
2204 if ( count ( $block ) < 2 ) {
2205 $blockOut .= $this->recentChangesBlockLine ( array_shift ( $block ) ) ;
2207 $blockOut .= $this->recentChangesBlockGroup ( $block ) ;
2211 return "<div>{$blockOut}</div>" ;
2214 # Called in a loop over all displayed RC entries
2215 # Either returns the line, or caches it for later use
2216 function recentChangesLine( &$rc, $watched = false )
2219 $usenew = $wgUser->getOption( "usenewrc" );
2221 $line = $this->recentChangesLineNew ( $rc, $watched ) ;
2223 $line = $this->recentChangesLineOld ( $rc, $watched ) ;
2227 function recentChangesLineOld( &$rc, $watched = false )
2229 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds;
2231 # Extract DB fields into local scope
2232 extract( $rc->mAttribs
);
2233 $curIdEq = "curid=" . $rc_cur_id;
2235 # Make date header if necessary
2236 $date = $wgLang->date( $rc_timestamp, true);
2238 if ( $date != $this->lastdate
) {
2239 if ( "" != $this->lastdate
) { $s .= "</ul>\n"; }
2240 $s .= "<h4>{$date}</h4>\n<ul class='special'>";
2241 $this->lastdate
= $date;
2242 $this->rclistOpen
= true;
2246 if ( $rc_type == RC_MOVE
) {
2248 $s .= "(" . wfMsg( "diff" ) . ") (";
2250 $s .= $this->makeKnownLinkObj( $rc->getMovedToTitle(), wfMsg( "hist" ), "action=history" ) .
2253 # "[[x]] moved to [[y]]"
2255 $s .= wfMsg( "1movedto2", $this->makeKnownLinkObj( $rc->getTitle(), "", "redirect=no" ),
2256 $this->makeKnownLinkObj( $rc->getMovedToTitle(), "" ) );
2260 if ( $rc_type == RC_NEW ||
$rc_type == RC_LOG
) {
2261 $diffLink = wfMsg( "diff" );
2263 $diffLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( "diff" ),
2264 "{$curIdEq}&diff={$rc_this_oldid}&oldid={$rc_last_oldid}" ,'' ,'' , ' tabindex="'.$rc->counter
.'"');
2266 $s .= "($diffLink) (";
2269 $s .= $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( "hist" ), "{$curIdEq}&action=history" );
2272 # M and N (minor and new)
2273 $M = wfMsg( "minoreditletter" );
2274 $N = wfMsg( "newpageletter" );
2275 if ( $rc_minor ) { $s .= " <strong>{$M}</strong>"; }
2276 if ( $rc_type == RC_NEW
) { $s .= "<strong>{$N}</strong>"; }
2279 $articleLink = $this->makeKnownLinkObj( $rc->getTitle(), "" );
2282 $articleLink = "<strong>{$articleLink}</strong>";
2284 $s .= " $articleLink";
2289 $s .= "; " . $wgLang->time( $rc_timestamp, true, $wgRCSeconds ) . " . . ";
2291 # User link (or contributions for unregistered users)
2292 if ( 0 == $rc_user ) {
2293 $userLink = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
2294 $rc_user_text, "target=" . $rc_user_text );
2296 $userLink = $this->makeLink( $wgLang->getNsText( NS_USER
) . ":{$rc_user_text}", $rc_user_text );
2301 $talkname=$wgLang->getNsText(NS_TALK
); # use the shorter name
2302 global $wgDisableAnonTalk;
2303 if( 0 == $rc_user && $wgDisableAnonTalk ) {
2306 $utns=$wgLang->getNsText(NS_USER_TALK
);
2307 $userTalkLink= $this->makeLink($utns . ":{$rc_user_text}", $talkname );
2311 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2312 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2313 "Blockip" ), wfMsg( "blocklink" ), "ip={$rc_user_text}" );
2317 if($userTalkLink) $userTalkLink .= " | ";
2318 $userTalkLink .= $blockLink;
2320 if($userTalkLink) $s.=" ({$userTalkLink})";
2323 if ( "" != $rc_comment && "*" != $rc_comment && $rc_type != RC_MOVE
) {
2324 $rc_comment=$this->formatComment($rc_comment);
2325 $s .= $wgLang->emphasize(" (" . $rc_comment . ")");
2332 # function recentChangesLineNew( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched = false, $oldid = 0 , $diffid = 0 )
2333 function recentChangesLineNew( &$baseRC, $watched = false )
2335 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds;
2337 # Create a specialised object
2338 $rc = RCCacheEntry
::newFromParent( $baseRC ) ;
2340 # Extract fields from DB into the function scope (rc_xxxx variables)
2341 extract( $rc->mAttribs
);
2342 $curIdEq = "curid=" . $rc_cur_id;
2344 # If it's a new day, add the headline and flush the cache
2345 $date = $wgLang->date( $rc_timestamp, true);
2347 if ( $date != $this->lastdate
) {
2348 # Process current cache
2349 $ret = $this->recentChangesBlock () ;
2350 $this->rc_cache
= array() ;
2351 $ret .= "<h4>{$date}</h4>\n";
2352 $this->lastdate
= $date;
2356 if ( $rc_type == RC_MOVE
) {
2357 $clink = $this->makeKnownLinkObj( $rc->getTitle(), "", "redirect=no" );
2358 $clink .= " " . wfMsg("movedto") . " ";
2359 $clink .= $this->makeKnownLinkObj( $rc->getMovedToTitle(), "" );
2361 $clink = $this->makeKnownLinkObj( $rc->getTitle(), "" ) ;
2364 $time = $wgLang->time( $rc_timestamp, true, $wgRCSeconds );
2365 $rc->watched
= $watched ;
2366 $rc->link
= $clink ;
2367 $rc->timestamp
= $time;
2370 if ( ( $rc_type == RC_NEW
&& $rc_this_oldid == 0 ) ||
$rc_type == RC_LOG ||
$rc_type == RC_MOVE
) {
2371 $curLink = wfMsg( "cur" );
2373 $curLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( "cur" ),
2374 "{$curIdEq}&diff=0&oldid={$rc_this_oldid}" ,'' ,'' , ' tabindex="'.$baseRC->counter
.'"' );
2378 $titleObj = $rc->getTitle();
2379 if ( $rc_last_oldid == 0 ||
$rc_type == RC_LOG ||
$rc_type == RC_MOVE
) {
2380 $lastLink = wfMsg( "last" );
2382 $lastLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( "last" ),
2383 "{$curIdEq}&diff={$rc_this_oldid}&oldid={$rc_last_oldid}" );
2386 # Make user link (or user contributions for unregistered users)
2387 if ( 0 == $rc_user ) {
2388 $userLink = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
2389 $rc_user_text, "target=" . $rc_user_text );
2391 $userLink = $this->makeLink( $wgLang->getNsText(
2392 Namespace::getUser() ) . ":{$rc_user_text}", $rc_user_text );
2395 $rc->userlink
= $userLink ;
2396 $rc->lastlink
= $lastLink ;
2397 $rc->curlink
= $curLink ;
2399 # Make user talk link
2400 $utns=$wgLang->getNsText(NS_USER_TALK
);
2401 $talkname=$wgLang->getNsText(NS_TALK
); # use the shorter name
2402 $userTalkLink= $this->makeLink($utns . ":{$rc_user_text}", $talkname );
2404 global $wgDisableAnonTalk;
2405 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2406 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2407 "Blockip" ), wfMsg( "blocklink" ), "ip={$rc_user_text}" );
2408 if( $wgDisableAnonTalk )
2409 $rc->usertalklink
= " ({$blockLink})";
2411 $rc->usertalklink
= " ({$userTalkLink} | {$blockLink})";
2413 if( $wgDisableAnonTalk && ($rc_user == 0) )
2414 $rc->usertalklink
= "";
2416 $rc->usertalklink
= " ({$userTalkLink})";
2419 # Put accumulated information into the cache, for later display
2420 # Page moves go on their own line
2421 $title = $rc->getTitle();
2422 $secureName = $title->getPrefixedDBkey();
2423 if ( $rc_type == RC_MOVE
) {
2424 # Use an @ character to prevent collision with page names
2425 $this->rc_cache
["@@" . ($this->rcMoveIndex++
)] = array($rc);
2427 if ( !isset ( $this->rc_cache
[$secureName] ) ) $this->rc_cache
[$secureName] = array() ;
2428 array_push ( $this->rc_cache
[$secureName] , $rc ) ;
2433 function endImageHistoryList()
2439 /* This function is called by all recent changes variants, by the page history,
2440 and by the user contributions list. It is responsible for formatting edit
2441 comments. It escapes any HTML in the comment, but adds some CSS to format
2442 auto-generated comments (from section editing) and formats [[wikilinks]].
2443 Main author: Erik Möller (moeller@scireview.de)
2445 function formatComment($comment)
2448 $comment=wfEscapeHTML($comment);
2450 # The pattern for autogen comments is / * foo * /, which makes for
2452 # We look for all comments, match any text before and after the comment,
2453 # add a separator where needed and format the comment itself with CSS
2454 while (preg_match("/(.*)\/\*\s*(.*?)\s*\*\/(.*)/", $comment,$match)) {
2459 if($pre) { $auto="$sep ".$auto; }
2460 if($post) { $auto.=" $sep"; }
2461 $auto="<span class=\"autocomment\">".$auto."</span>";
2462 $comment=$pre.$auto.$post;
2465 # format regular and media links - all other wiki formatting
2467 while(preg_match("/\[\[(.*?)(\|(.*?))*\]\]/",$comment,$match)) {
2469 $medians = $wgLang->getNsText(Namespace::getMedia());
2471 if(preg_match("/^".$medians."/i",$match[1])) {
2472 $func="makeMediaLink";
2474 if(isset($match[3]) ) {
2476 preg_replace("/\[\[(.*?)\]\]/",
2477 $this->$func($match[1],$match[3]),$comment,1);
2480 preg_replace("/\[\[(.*?)\]\]/",
2481 $this->$func($match[1],$match[1]),$comment,1);
2489 function imageHistoryLine( $iscur, $timestamp, $img, $user, $usertext, $size, $description )
2491 global $wgUser, $wgLang, $wgTitle;
2493 $datetime = $wgLang->timeanddate( $timestamp, true );
2494 $del = wfMsg( "deleteimg" );
2495 $cur = wfMsg( "cur" );
2498 $url = Image
::wfImageUrl( $img );
2500 if ( $wgUser->isSysop() ) {
2501 $link = $wgTitle->escapeLocalURL( "image=" . $wgTitle->getPartialURL() .
2503 $style = $this->getInternalLinkAttributes( $link, $del );
2505 $dlink = "<a href=\"{$link}\"{$style}>{$del}</a>";
2510 $url = wfEscapeHTML( wfImageArchiveUrl( $img ) );
2511 if( $wgUser->getID() != 0 ) {
2512 $rlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2513 wfMsg( "revertimg" ), "action=revert&oldimage=" .
2514 urlencode( $img ) );
2515 $dlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2516 $del, "action=delete&oldimage=" . urlencode( $img ) );
2518 # Having live active links for non-logged in users
2519 # means that bots and spiders crawling our site can
2520 # inadvertently change content. Baaaad idea.
2521 $rlink = wfMsg( "revertimg" );
2526 $userlink = $usertext;
2528 $userlink = $this->makeLink( $wgLang->getNsText( Namespace::getUser() ) .
2529 ":{$usertext}", $usertext );
2531 $nbytes = wfMsg( "nbytes", $size );
2532 $style = $this->getInternalLinkAttributes( $url, $datetime );
2534 $s = "<li> ({$dlink}) ({$rlink}) <a href=\"{$url}\"{$style}>{$datetime}</a>"
2535 . " . . {$userlink} ({$nbytes})";
2537 if ( "" != $description && "*" != $description ) {
2538 $sk=$wgUser->getSkin();
2539 $s .= $wgLang->emphasize(" (" . $sk->formatComment($description) . ")");
2545 function tocIndent($level) {
2546 return str_repeat( "<div class='tocindent'>\n", $level>0 ?
$level : 0 );
2549 function tocUnindent($level) {
2550 return str_repeat( "</div>\n", $level>0 ?
$level : 0 );
2553 # parameter level defines if we are on an indentation level
2554 function tocLine( $anchor, $tocline, $level ) {
2555 $link = "<a href=\"#$anchor\">$tocline</a><br />";
2559 return "<div class='tocline'>$link</div>\n";
2564 function tocTable($toc) {
2565 # note to CSS fanatics: putting this in a div does not work -- div won't auto-expand
2566 # try min-width & co when somebody gets a chance
2567 $hideline = " <script type='text/javascript'>showTocToggle(\"" . addslashes( wfMsg("showtoc") ) . "\",\"" . addslashes( wfMsg("hidetoc") ) . "\")</script>";
2569 "<table border=\"0\" id=\"toc\"><tr><td align=\"center\">\n".
2570 "<b>".wfMsg("toc")."</b>" .
2572 "</td></tr><tr id='tocinside'><td>\n".
2573 $toc."</td></tr></table>\n";
2576 # These two do not check for permissions: check $wgTitle->userCanEdit before calling them
2577 function editSectionScript( $section, $head ) {
2578 global $wgTitle, $wgRequest;
2579 if( $wgRequest->getInt( "oldid" ) && ( $wgRequest->getVal( "diff" ) != "0" ) ) {
2582 $url = $wgTitle->escapeLocalURL( "action=edit§ion=$section" );
2583 return "<span oncontextmenu='document.location=\"$url\";return false;'>{$head}</span>";
2586 function editSectionLink( $section ) {
2588 global $wgTitle, $wgUser, $wgLang;
2590 if( $wgRequest->getInt( "oldid" ) && ( $wgRequest->getVal( "diff" ) != "0" ) ) {
2591 # Section edit links would be out of sync on an old page.
2592 # But, if we're diffing to the current page, they'll be
2597 $editurl = "§ion={$section}";
2598 $url = $this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg("editsection"),"action=edit".$editurl);
2600 if( $wgLang->isRTL() ) {
2602 $nearside = "right";
2607 return "<div class=\"editsection\" style=\"float:$farside;margin-$nearside:5px;\">[".$url."]</div>";
2611 // This function is called by EditPage.php and shows a bulletin board style
2612 // toolbar for common editing functions. It can be disabled in the user preferences.
2613 // The necsesary JavaScript code can be found in style/wikibits.js.
2614 function getEditToolbar() {
2615 global $wgStylePath, $wgLang, $wgMimeType;
2617 // toolarray an array of arrays which each include the filename of
2618 // the button image (without path), the opening tag, the closing tag,
2619 // and optionally a sample text that is inserted between the two when no
2620 // selection is highlighted.
2621 // The tip text is shown when the user moves the mouse over the button.
2623 // Already here are accesskeys (key), which are not used yet until someone
2624 // can figure out a way to make them work in IE. However, we should make
2625 // sure these keys are not defined on the edit page.
2627 array( "image"=>"button_bold.png",
2630 "sample"=>wfMsg("bold_sample"),
2631 "tip"=>wfMsg("bold_tip"),
2634 array( "image"=>"button_italic.png",
2637 "sample"=>wfMsg("italic_sample"),
2638 "tip"=>wfMsg("italic_tip"),
2641 array( "image"=>"button_link.png",
2644 "sample"=>wfMsg("link_sample"),
2645 "tip"=>wfMsg("link_tip"),
2648 array( "image"=>"button_extlink.png",
2651 "sample"=>wfMsg("extlink_sample"),
2652 "tip"=>wfMsg("extlink_tip"),
2655 array( "image"=>"button_headline.png",
2658 "sample"=>wfMsg("headline_sample"),
2659 "tip"=>wfMsg("headline_tip"),
2662 array( "image"=>"button_image.png",
2663 "open"=>"[[".$wgLang->getNsText(NS_IMAGE
).":",
2665 "sample"=>wfMsg("image_sample"),
2666 "tip"=>wfMsg("image_tip"),
2669 array( "image"=>"button_media.png",
2670 "open"=>"[[".$wgLang->getNsText(NS_MEDIA
).":",
2672 "sample"=>wfMsg("media_sample"),
2673 "tip"=>wfMsg("media_tip"),
2676 array( "image"=>"button_math.png",
2677 "open"=>"\\<math\\>",
2678 "close"=>"\\</math\\>",
2679 "sample"=>wfMsg("math_sample"),
2680 "tip"=>wfMsg("math_tip"),
2683 array( "image"=>"button_nowiki.png",
2684 "open"=>"\\<nowiki\\>",
2685 "close"=>"\\</nowiki\\>",
2686 "sample"=>wfMsg("nowiki_sample"),
2687 "tip"=>wfMsg("nowiki_tip"),
2690 array( "image"=>"button_sig.png",
2694 "tip"=>wfMsg("sig_tip"),
2697 array( "image"=>"button_hr.png",
2698 "open"=>"\\n----\\n",
2701 "tip"=>wfMsg("hr_tip"),
2705 $toolbar ="<script type='text/javascript'>\n/*<![CDATA[*/\n";
2707 $toolbar.="document.writeln(\"<div id='toolbar'>\");\n";
2708 foreach($toolarray as $tool) {
2710 $image=$wgStylePath."/images/".$tool["image"];
2711 $open=$tool["open"];
2712 $close=$tool["close"];
2713 $sample = addslashes( $tool["sample"] );
2715 // Note that we use the tip both for the ALT tag and the TITLE tag of the image.
2716 // Older browsers show a "speedtip" type message only for ALT.
2717 // Ideally these should be different, realistically they
2718 // probably don't need to be.
2719 $tip = addslashes( $tool["tip"] );
2721 #$key = $tool["key"];
2723 $toolbar.="addButton('$image','$tip','$open','$close','$sample');\n";
2726 $toolbar.="addInfobox('" . addslashes( wfMsg( "infobox" ) ) . "','" . addslashes(wfMsg("infobox_alert")) . "');\n";
2727 $toolbar.="document.writeln(\"</div>\");\n";
2729 $toolbar.="/*]]>*/\n</script>";
2735 require_once( "SkinStandard.php" );
2736 require_once( "SkinNostalgia.php" );
2737 require_once( "SkinCologneBlue.php" );
2739 if( $wgUsePHPTal ) {
2740 require_once( "SkinPHPTal.php" );