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 $s.= $wgTitle->getAllParentCategories(&$catstack);
383 function getCategories() {
384 $catlinks=$this->getCategoryLinks();
385 if(!empty($catlinks)) {
386 return "<p class='catlinks'>{$catlinks}</p>";
390 function getQuickbarCompensator( $rows = 1 )
392 return "<td width='152' rowspan='{$rows}'> </td>";
395 # This gets called immediately before the </body> tag.
397 function afterContent()
399 global $wgUser, $wgOut, $wgServer;
400 global $wgTitle, $wgLang;
402 $printfooter = "<div class=\"printfooter\">\n" . $this->printFooter() . "</div>\n";
403 return $printfooter . $this->doAfterContent();
406 function printFooter() {
408 $url = htmlspecialchars( $wgTitle->getFullURL() );
409 return "<p>" . wfMsg( "retrievedfrom", "<a href=\"$url\">$url</a>" ) .
410 "</p>\n\n<p>" . $this->pageStats() . "</p>\n";
413 function doAfterContent()
415 global $wgUser, $wgOut, $wgLang;
416 $fname = 'Skin::doAfterContent';
417 wfProfileIn( $fname );
418 wfProfileIn( $fname.'-1' );
420 $s = "\n</div><br style=\"clear:both\" />\n";
421 $s .= "\n<div id='footer'>";
422 $s .= '<table border="0" cellspacing="0"><tr>';
424 wfProfileOut( $fname.'-1' );
425 wfProfileIn( $fname.'-2' );
427 $qb = $this->qbSetting();
429 $left = ($qb == 1 ||
$qb == 3);
430 if($wgLang->isRTL()) $left = !$left;
432 if ( $shove && $left ) { # Left
433 $s .= $this->getQuickbarCompensator();
435 wfProfileOut( $fname.'-2' );
436 wfProfileIn( $fname.'-3' );
437 $l = $wgLang->isRTL() ?
'right' : 'left';
438 $s .= "<td class='bottom' align='$l' valign='top'>";
440 $s .= $this->bottomLinks();
441 $s .= "\n<br />" . $this->mainPageLink()
442 . ' | ' . $this->aboutLink()
443 . ' | ' . $this->specialLink( 'recentchanges' )
444 . ' | ' . $this->searchForm()
445 . '<br /><span id="pagestats">' . $this->pageStats() . '</span>';
448 if ( $shove && !$left ) { # Right
449 $s .= $this->getQuickbarCompensator();
451 $s .= "</tr></table>\n</div>\n</div>\n";
453 wfProfileOut( $fname.'-3' );
454 wfProfileIn( $fname.'-4' );
455 if ( 0 != $qb ) { $s .= $this->quickBar(); }
456 wfProfileOut( $fname.'-4' );
457 wfProfileOut( $fname );
461 function pageTitleLinks()
463 global $wgOut, $wgTitle, $wgUser, $wgLang, $wgUseApproval, $wgRequest;
465 extract( $wgRequest->getValues( 'oldid', 'diff' ) );
466 $action = $wgRequest->getText( 'action' );
468 $s = $this->printableLink();
469 if ( wfMsg ( 'disclaimers' ) != '-' ) $s .= ' | ' . $this->makeKnownLink( wfMsg( 'disclaimerpage' ), wfMsg( 'disclaimers' ) ) ;
471 if ( $wgOut->isArticleRelated() ) {
472 if ( $wgTitle->getNamespace() == Namespace::getImage() ) {
473 $name = $wgTitle->getDBkey();
474 $link = wfEscapeHTML( Image
::wfImageUrl( $name ) );
475 $style = $this->getInternalLinkAttributes( $link, $name );
476 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>";
478 # This will show the "Approve" link if $wgUseApproval=true;
479 if ( isset ( $wgUseApproval ) && $wgUseApproval )
481 $t = $wgTitle->getDBkey();
482 $name = 'Approve this article' ;
483 $link = "http://test.wikipedia.org/w/magnus/wiki.phtml?title={$t}&action=submit&doit=1" ;
484 #wfEscapeHTML( wfImageUrl( $name ) );
485 $style = $this->getExternalLinkAttributes( $link, $name );
486 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>" ;
489 if ( 'history' == $action ||
isset( $diff ) ||
isset( $oldid ) ) {
490 $s .= ' | ' . $this->makeKnownLink( $wgTitle->getPrefixedText(),
491 wfMsg( 'currentrev' ) );
494 if ( $wgUser->getNewtalk() ) {
495 # do not show "You have new messages" text when we are viewing our
498 if(!(strcmp($wgTitle->getText(),$wgUser->getName()) == 0 &&
499 $wgTitle->getNamespace()==Namespace::getTalk(Namespace::getUser()))) {
500 $n =$wgUser->getName();
501 $tl = $this->makeKnownLink( $wgLang->getNsText(
502 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
503 wfMsg('newmessageslink') );
504 $s.= ' | <strong>'. wfMsg( 'newmessages', $tl ) . '</strong>';
508 $undelete = $this->getUndeleteLink();
509 if( !empty( $undelete ) ) {
510 $s .= ' | '.$undelete;
515 function getUndeleteLink() {
516 global $wgUser, $wgTitle, $wgLang, $action;
517 if( $wgUser->isSysop() &&
518 (($wgTitle->getArticleId() == 0) ||
($action == "history")) &&
519 ($n = $wgTitle->isDeleted() ) ) {
520 return wfMsg( 'thisisdeleted',
521 $this->makeKnownLink(
522 $wgLang->SpecialPage( 'Undelete/' . $wgTitle->getPrefixedDBkey() ),
523 wfMsg( 'restorelink', $n ) ) );
528 function printableLink()
530 global $wgOut, $wgFeedClasses, $wgRequest;
532 $baseurl = $_SERVER['REQUEST_URI'];
533 if( strpos( '?', $baseurl ) == false ) {
538 $baseurl = htmlspecialchars( $baseurl );
539 $printurl = $wgRequest->escapeAppendQuery( 'printable=yes' );
541 $s = "<a href=\"$printurl\">" . wfMsg( 'printableversion' ) . '</a>';
542 if( $wgOut->isSyndicated() ) {
543 foreach( $wgFeedClasses as $format => $class ) {
544 $feedurl = $wgRequest->escapeAppendQuery( "feed=$format" );
545 $s .= " | <a href=\"$feedurl\">{$format}</a>";
553 global $wgOut, $wgTitle, $wgUser;
555 $s = '<h1 class="pagetitle">' . htmlspecialchars( $wgOut->getPageTitle() ) . '</h1>';
556 if($wgUser->getOption( 'editsectiononrightclick' ) && $wgTitle->userCanEdit()) { $s=$this->editSectionScript(0,$s);}
560 function pageSubtitle()
564 $sub = $wgOut->getSubtitle();
566 global $wgExtraSubtitle;
567 $sub = wfMsg( 'fromwikipedia' ) . $wgExtraSubtitle;
569 $subpages = $this->subPageSubtitle();
570 $sub .= !empty($subpages)?
"</p><p class='subpages'>$subpages":'';
571 $s = "<p class='subtitle'>{$sub}</p>\n";
575 function subPageSubtitle()
577 global $wgOut,$wgTitle,$wgNamespacesWithSubpages;
579 if($wgOut->isArticle() && !empty($wgNamespacesWithSubpages[$wgTitle->getNamespace()])) {
580 $ptext=$wgTitle->getPrefixedText();
581 if(preg_match('/\//',$ptext)) {
582 $links = explode('/',$ptext);
585 foreach($links as $link) {
587 if ($c<count($links)) {
588 $growinglink .= $link;
589 $getlink = $this->makeLink( $growinglink, $link );
590 if(preg_match('/class="new"/i',$getlink)) { break; } # this is a hack, but it saves time
594 $subpages .= '< ';
596 $subpages .= $getlink;
605 function nameAndLogin()
607 global $wgUser, $wgTitle, $wgLang, $wgShowIPinHeader, $wgIP;
609 $li = $wgLang->specialPage( 'Userlogin' );
610 $lo = $wgLang->specialPage( 'Userlogout' );
613 if ( 0 == $wgUser->getID() ) {
614 if( $wgShowIPinHeader && isset( $_COOKIE[ini_get('session.name')] ) ) {
617 $tl = $this->makeKnownLink( $wgLang->getNsText(
618 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
619 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
621 $s .= $n . ' ('.$tl.')';
623 $s .= wfMsg('notloggedin');
626 $rt = $wgTitle->getPrefixedURL();
627 if ( 0 == strcasecmp( urlencode( $lo ), $rt ) ) {
629 } else { $q = "returnto={$rt}"; }
631 $s .= "\n<br />" . $this->makeKnownLink( $li,
632 wfMsg( 'login' ), $q );
634 $n = $wgUser->getName();
635 $rt = $wgTitle->getPrefixedURL();
636 $tl = $this->makeKnownLink( $wgLang->getNsText(
637 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
638 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
642 $s .= $this->makeKnownLink( $wgLang->getNsText(
643 Namespace::getUser() ) . ":{$n}", $n ) . "{$tl}<br />" .
644 $this->makeKnownLink( $lo, wfMsg( 'logout' ),
645 "returnto={$rt}" ) . ' | ' .
646 $this->specialLink( 'preferences' );
648 $s .= ' | ' . $this->makeKnownLink( wfMsg( 'helppage' ),
654 function getSearchLink() {
655 $searchPage =& Title
::makeTitle( NS_SPECIAL
, 'Search' );
656 return $searchPage->getLocalURL();
659 function escapeSearchLink() {
660 return htmlspecialchars( $this->getSearchLink() );
663 function searchForm()
666 $search = $wgRequest->getText( 'search' );
668 $s = '<form name="search" class="inline" method="post" action="'
669 . $this->escapeSearchLink() . "\">\n"
670 . '<input type="text" name="search" size="19" value="'
671 . htmlspecialchars(substr($search,0,256)) . "\" />\n"
672 . '<input type="submit" name="go" value="' . wfMsg ('go') . '" /> '
673 . '<input type="submit" name="fulltext" value="' . wfMsg ('search') . "\" />\n</form>";
683 $s = $this->mainPageLink() . $sep
684 . $this->specialLink( 'recentchanges' );
686 if ( $wgOut->isArticleRelated() ) {
687 $s .= $sep . $this->editThisPage()
688 . $sep . $this->historyLink();
690 # Many people don't like this dropdown box
691 #$s .= $sep . $this->specialPagesList();
696 function bottomLinks()
698 global $wgOut, $wgUser, $wgTitle;
702 if ( $wgOut->isArticleRelated() ) {
703 $s .= '<strong>' . $this->editThisPage() . '</strong>';
704 if ( 0 != $wgUser->getID() ) {
705 $s .= $sep . $this->watchThisPage();
707 $s .= $sep . $this->talkLink()
708 . $sep . $this->historyLink()
709 . $sep . $this->whatLinksHere()
710 . $sep . $this->watchPageLinksLink();
712 if ( $wgTitle->getNamespace() == Namespace::getUser()
713 ||
$wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser()) )
716 $id=User
::idFromName($wgTitle->getText());
717 $ip=User
::isIP($wgTitle->getText());
719 if($id ||
$ip) { # both anons and non-anons have contri list
720 $s .= $sep . $this->userContribsLink();
722 if ( 0 != $wgUser->getID() ) { # show only to signed in users
723 if($id) { # can only email non-anons
724 $s .= $sep . $this->emailUserLink();
728 if ( $wgUser->isSysop() && $wgTitle->getArticleId() ) {
729 $s .= "\n<br />" . $this->deleteThisPage() .
730 $sep . $this->protectThisPage() .
731 $sep . $this->moveThisPage();
733 $s .= "<br />\n" . $this->otherLanguages();
740 global $wgOut, $wgLang, $wgArticle, $wgRequest;
741 global $wgDisableCounters;
743 extract( $wgRequest->getValues( 'oldid', 'diff' ) );
744 if ( ! $wgOut->isArticle() ) { return ''; }
745 if ( isset( $oldid ) ||
isset( $diff ) ) { return ''; }
746 if ( 0 == $wgArticle->getID() ) { return ''; }
749 if ( !$wgDisableCounters ) {
750 $count = $wgLang->formatNum( $wgArticle->getCount() );
752 $s = wfMsg( 'viewcount', $count );
756 $s .= ' ' . $this->getCredits();
758 return $s . ' ' . $this->getCopyright();
761 function getCredits() {
762 global $wgMaxCredits;
766 if (!isset($wgMaxCredits) ||
$wgMaxCredits == 0) {
767 $s = $this->lastModified();
769 $s = $this->getAuthorCredits();
770 if ($wgMaxCredits > 1) {
771 $s .= ' ' . $this->getContributorCredits();
778 function getAuthorCredits() {
779 global $wgLang, $wgArticle;
781 $last_author = $wgArticle->getUser();
783 if ($last_author == 0) {
784 $author_credit = wfMsg('anonymous');
786 $real_name = User
::whoIsReal($last_author);
787 if (!empty($real_name)) {
788 $author_credit = $real_name;
790 $author_credit = wfMsg('siteuser', User
::whoIs($last_author));
794 $timestamp = $wgArticle->getTimestamp();
796 $d = $wgLang->timeanddate( $wgArticle->getTimestamp(), true );
800 return wfMsg('lastmodifiedby', $d, $author_credit);
803 function getContributorCredits() {
805 global $wgArticle, $wgMaxCredits, $wgLang;
807 # don't count last editor
809 $contributors = $wgArticle->getContributors($wgMaxCredits - 1);
811 $real_names = array();
812 $user_names = array();
814 # Sift for real versus user names
816 foreach ($contributors as $user_id => $user_parts) {
818 if (!empty($user_parts[1])) {
819 $real_names[$user_id] = $user_parts[1];
821 $user_names[$user_id] = $user_parts[0];
826 $real = $wgLang->listToText(array_values($real_names));
827 $user = $wgLang->listToText(array_values($user_names));
830 $user = wfMsg('siteusers', $user);
833 if ($contributors[0] && $contributors[0][0] > 0) {
834 $anon = wfMsg('anonymous');
839 $creds = $wgLang->listToText(array($real, $user, $anon));
841 return wfMsg('othercontribs', $creds);
844 function getCopyright() {
845 global $wgRightsPage, $wgRightsUrl, $wgRightsText;
847 if( $wgRightsPage ) {
848 $link = $this->makeKnownLink( $wgRightsPage, $wgRightsText );
849 } elseif( $wgRightsUrl ) {
850 $link = $this->makeExternalLink( $wgRightsUrl, $wgRightsText );
855 $out .= wfMsg( 'copyright', $link );
859 function getCopyrightIcon() {
860 global $wgRightsPage, $wgRightsUrl, $wgRightsText, $wgRightsIcon;
862 if( $wgRightsIcon ) {
863 $icon = htmlspecialchars( $wgRightsIcon );
865 $url = htmlspecialchars( $wgRightsUrl );
866 $out .= '<a href="'.$url.'">';
868 $text = htmlspecialchars( $wgRightsText );
869 $out .= "<img src=\"$icon\" alt='$text' />";
877 function getPoweredBy() {
879 $url = htmlspecialchars( "$wgStylePath/images/poweredby_mediawiki_88x31.png" );
880 $img = '<a href="http://www.mediawiki.org/"><img src="'.$url.'" alt="MediaWiki" /></a>';
884 function lastModified()
886 global $wgLang, $wgArticle;
888 $timestamp = $wgArticle->getTimestamp();
890 $d = $wgLang->timeanddate( $wgArticle->getTimestamp(), true );
891 $s = ' ' . wfMsg( 'lastmodified', $d );
898 function logoText( $align = '' )
900 if ( '' != $align ) { $a = ' align="'.$align.'"'; }
903 $mp = wfMsg( 'mainpage' );
904 $titleObj = Title
::newFromText( $mp );
905 $s = '<a href="' . $titleObj->escapeLocalURL()
906 . '"><img'.$a.' src="'
907 . $this->getLogo() . '" alt="' . "[{$mp}]\" /></a>";
913 global $wgOut, $wgTitle, $wgUser, $wgRequest, $wgLang;
914 global $wgDisableUploads, $wgRemoteUploads;
916 $fname = 'Skin::quickBar';
917 wfProfileIn( $fname );
919 $action = $wgRequest->getText( 'action' );
920 $wpPreview = $wgRequest->getBool( 'wpPreview' );
921 $tns=$wgTitle->getNamespace();
923 $s = "\n<div id='quickbar'>";
924 $s .= "\n" . $this->logoText() . "\n<hr class='sep' />";
927 $s .= $this->mainPageLink()
928 . $sep . $this->specialLink( 'recentchanges' )
929 . $sep . $this->specialLink( 'randompage' );
930 if ($wgUser->getID()) {
931 $s.= $sep . $this->specialLink( 'watchlist' ) ;
932 $s .= $sep .$this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
933 wfMsg( 'mycontris' ), 'target=' . wfUrlencode($wgUser->getName() ) );
936 // only show watchlist link if logged in
937 if ( wfMsg ( 'currentevents' ) != '-' ) $s .= $sep . $this->makeKnownLink( wfMsg( 'currentevents' ), '' ) ;
938 $s .= "\n<br /><hr class='sep' />";
939 $articleExists = $wgTitle->getArticleId();
940 if ( $wgOut->isArticle() ||
$action =='edit' ||
$action =='history' ||
$wpPreview) {
941 if($wgOut->isArticle()) {
942 $s .= '<strong>' . $this->editThisPage() . '</strong>';
943 } else { # backlink to the article in edit or history mode
944 if($articleExists){ # no backlink if no article
947 $text = wfMsg('articlepage');
950 $text = wfMsg('viewtalkpage');
953 $text = wfMsg('userpage');
956 $text = wfMsg('viewtalkpage');
959 $text = wfMsg('wikipediapage');
962 $text = wfMsg('viewtalkpage');
965 $text = wfMsg('imagepage');
968 $text = wfMsg('viewtalkpage');
971 $text= wfMsg('articlepage');
974 $link = $wgTitle->getText();
975 if ($nstext = $wgLang->getNsText($tns) ) { # add namespace if necessary
976 $link = $nstext . ':' . $link ;
979 $s .= $this->makeLink( $link, $text );
980 } elseif( $wgTitle->getNamespace() != Namespace::getSpecial() ) {
981 # we just throw in a "New page" text to tell the user that he's in edit mode,
982 # and to avoid messing with the separator that is prepended to the next item
983 $s .= '<strong>' . wfMsg('newpage') . '</strong>';
989 if( $tns%2
&& $action!='edit' && !$wpPreview) {
990 $s.= '<br />'.$this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg('postcomment'),'action=edit§ion=new');
994 watching could cause problems in edit mode:
995 if user edits article, then loads "watch this article" in background and then saves
996 article with "Watch this article" checkbox disabled, the article is transparently
997 unwatched. Therefore we do not show the "Watch this page" link in edit mode
999 if ( 0 != $wgUser->getID() && $articleExists) {
1000 if($action!='edit' && $action != 'submit' )
1002 $s .= $sep . $this->watchThisPage();
1004 if ( $wgTitle->userCanEdit() )
1005 $s .= $sep . $this->moveThisPage();
1007 if ( $wgUser->isSysop() and $articleExists ) {
1008 $s .= $sep . $this->deleteThisPage() .
1009 $sep . $this->protectThisPage();
1011 $s .= $sep . $this->talkLink();
1012 if ($articleExists && $action !='history') {
1013 $s .= $sep . $this->historyLink();
1015 $s.=$sep . $this->whatLinksHere();
1017 if($wgOut->isArticleRelated()) {
1018 $s .= $sep . $this->watchPageLinksLink();
1021 if ( Namespace::getUser() == $wgTitle->getNamespace()
1022 ||
$wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser())
1025 $id=User
::idFromName($wgTitle->getText());
1026 $ip=User
::isIP($wgTitle->getText());
1029 $s .= $sep . $this->userContribsLink();
1031 if ( 0 != $wgUser->getID() ) {
1032 if($id) { # can only email real users
1033 $s .= $sep . $this->emailUserLink();
1037 $s .= "\n<br /><hr class='sep' />";
1040 if ( 0 != $wgUser->getID() && ( !$wgDisableUploads ||
$wgRemoteUploads ) ) {
1041 $s .= $this->specialLink( 'upload' ) . $sep;
1043 $s .= $this->specialLink( 'specialpages' )
1044 . $sep . $this->bugReportsLink();
1046 global $wgSiteSupportPage;
1047 if( $wgSiteSupportPage ) {
1048 $s .= "\n<br /><a href=\"" . htmlspecialchars( $wgSiteSupportPage ) .
1049 '" class="internal">' . wfMsg( 'sitesupport' ) . '</a>';
1052 $s .= "\n<br /></div>\n";
1053 wfProfileOut( $fname );
1057 function specialPagesList()
1059 global $wgUser, $wgOut, $wgLang, $wgServer, $wgRedirectScript;
1061 $pages = SpecialPage
::getPages();
1063 foreach ( $pages[''] as $name => $page ) {
1064 $a[$name] = $page->getDescription();
1066 if ( $wgUser->isSysop() )
1068 foreach ( $pages['sysop'] as $name => $page ) {
1069 $a[$name] = $page->getDescription();
1072 if ( $wgUser->isDeveloper() )
1074 foreach ( $pages['developer'] as $name => $page ) {
1075 $a[$name] = $page->getDescription() ;
1078 $go = wfMsg( 'go' );
1079 $sp = wfMsg( 'specialpages' );
1080 $spp = $wgLang->specialPage( 'Specialpages' );
1082 $s = '<form id="specialpages" method="get" class="inline" ' .
1083 'action="' . htmlspecialchars( "{$wgServer}{$wgRedirectScript}" ) . "\">\n";
1084 $s .= "<select name=\"wpDropdown\">\n";
1085 $s .= "<option value=\"{$spp}\">{$sp}</option>\n";
1087 foreach ( $a as $name => $desc ) {
1088 $p = $wgLang->specialPage( $name );
1089 $s .= "<option value=\"{$p}\">{$desc}</option>\n";
1091 $s .= "</select>\n";
1092 $s .= "<input type='submit' value=\"{$go}\" name='redirect' />\n";
1097 function mainPageLink()
1099 $mp = wfMsg( 'mainpage' );
1100 $s = $this->makeKnownLink( $mp, $mp );
1104 function copyrightLink()
1106 $s = $this->makeKnownLink( wfMsg( 'copyrightpage' ),
1107 wfMsg( 'copyrightpagename' ) );
1111 function aboutLink()
1113 $s = $this->makeKnownLink( wfMsg( 'aboutpage' ),
1114 wfMsg( 'aboutwikipedia' ) );
1119 function disclaimerLink()
1121 $s = $this->makeKnownLink( wfMsg( 'disclaimerpage' ),
1122 wfMsg( 'disclaimers' ) );
1126 function editThisPage()
1128 global $wgOut, $wgTitle, $wgRequest;
1130 $oldid = $wgRequest->getVal( 'oldid' );
1131 $diff = $wgRequest->getVal( 'diff' );
1132 $redirect = $wgRequest->getVal( 'redirect' );
1134 if ( ! $wgOut->isArticleRelated() ) {
1135 $s = wfMsg( 'protectedpage' );
1137 $n = $wgTitle->getPrefixedText();
1138 if ( $wgTitle->userCanEdit() ) {
1139 $t = wfMsg( 'editthispage' );
1141 #$t = wfMsg( "protectedpage" );
1142 $t = wfMsg( 'viewsource' );
1146 if ( !is_null( $redirect ) ) { $red = "&redirect={$redirect}"; }
1147 if ( $oldid && ! isset( $diff ) ) {
1148 $oid = "&oldid={$oldid}";
1150 $s = $this->makeKnownLink( $n, $t, "action=edit{$oid}{$red}" );
1155 function deleteThisPage()
1157 global $wgUser, $wgOut, $wgTitle, $wgRequest;
1159 $diff = $wgRequest->getVal( 'diff' );
1160 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
1161 $n = $wgTitle->getPrefixedText();
1162 $t = wfMsg( 'deletethispage' );
1164 $s = $this->makeKnownLink( $n, $t, 'action=delete' );
1171 function protectThisPage()
1173 global $wgUser, $wgOut, $wgTitle, $wgRequest;
1175 $diff = $wgRequest->getVal( 'diff' );
1176 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
1177 $n = $wgTitle->getPrefixedText();
1179 if ( $wgTitle->isProtected() ) {
1180 $t = wfMsg( 'unprotectthispage' );
1181 $q = 'action=unprotect';
1183 $t = wfMsg( 'protectthispage' );
1184 $q = 'action=protect';
1186 $s = $this->makeKnownLink( $n, $t, $q );
1193 function watchThisPage()
1195 global $wgUser, $wgOut, $wgTitle;
1197 if ( $wgOut->isArticleRelated() ) {
1198 $n = $wgTitle->getPrefixedText();
1200 if ( $wgTitle->userIsWatching() ) {
1201 $t = wfMsg( 'unwatchthispage' );
1202 $q = 'action=unwatch';
1204 $t = wfMsg( 'watchthispage' );
1205 $q = 'action=watch';
1207 $s = $this->makeKnownLink( $n, $t, $q );
1209 $s = wfMsg( 'notanarticle' );
1214 function moveThisPage()
1216 global $wgTitle, $wgLang;
1218 if ( $wgTitle->userCanEdit() ) {
1219 $s = $this->makeKnownLink( $wgLang->specialPage( 'Movepage' ),
1220 wfMsg( 'movethispage' ), 'target=' . $wgTitle->getPrefixedURL() );
1221 } // no message if page is protected - would be redundant
1225 function historyLink()
1229 $s = $this->makeKnownLink( $wgTitle->getPrefixedText(),
1230 wfMsg( 'history' ), 'action=history' );
1234 function whatLinksHere()
1236 global $wgTitle, $wgLang;
1238 $s = $this->makeKnownLink( $wgLang->specialPage( 'Whatlinkshere' ),
1239 wfMsg( 'whatlinkshere' ), 'target=' . $wgTitle->getPrefixedURL() );
1243 function userContribsLink()
1245 global $wgTitle, $wgLang;
1247 $s = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
1248 wfMsg( 'contributions' ), 'target=' . $wgTitle->getPartialURL() );
1252 function emailUserLink()
1254 global $wgTitle, $wgLang;
1256 $s = $this->makeKnownLink( $wgLang->specialPage( 'Emailuser' ),
1257 wfMsg( 'emailuser' ), 'target=' . $wgTitle->getPartialURL() );
1261 function watchPageLinksLink()
1263 global $wgOut, $wgTitle, $wgLang;
1265 if ( ! $wgOut->isArticleRelated() ) {
1266 $s = '(' . wfMsg( 'notanarticle' ) . ')';
1268 $s = $this->makeKnownLink( $wgLang->specialPage(
1269 'Recentchangeslinked' ), wfMsg( 'recentchangeslinked' ),
1270 'target=' . $wgTitle->getPrefixedURL() );
1275 function otherLanguages()
1277 global $wgOut, $wgLang, $wgTitle, $wgUseNewInterlanguage;
1279 $a = $wgOut->getLanguageLinks();
1280 if ( 0 == count( $a ) ) {
1281 if ( !$wgUseNewInterlanguage ) return '';
1282 $ns = $wgLang->getNsIndex ( $wgTitle->getNamespace () ) ;
1283 if ( $ns != 0 AND $ns != 1 ) return '' ;
1285 $x = 'mode=addlink&xt='.$wgTitle->getDBkey() ;
1286 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1287 wfMsg( 'intl' ) , $x );
1290 if ( !$wgUseNewInterlanguage ) {
1291 $s = wfMsg( 'otherlanguages' ) . ': ';
1293 global $wgLanguageCode ;
1294 $x = 'mode=zoom&xt='.$wgTitle->getDBkey() ;
1295 $x .= '&xl='.$wgLanguageCode ;
1296 $s = $this->makeKnownLink( $wgLang->specialPage( 'Intl' ),
1297 wfMsg( 'otherlanguages' ) , $x ) . ': ' ;
1300 $s = wfMsg( 'otherlanguages' ) . ': ';
1302 if($wgLang->isRTL()) $s .= '<span dir="LTR">';
1303 foreach( $a as $l ) {
1304 if ( ! $first ) { $s .= ' | '; }
1307 $nt = Title
::newFromText( $l );
1308 $url = $nt->getFullURL();
1309 $text = $wgLang->getLanguageName( $nt->getInterwiki() );
1311 if ( '' == $text ) { $text = $l; }
1312 $style = $this->getExternalLinkAttributes( $l, $text );
1313 $s .= "<a href=\"{$url}\"{$style}>{$text}</a>";
1315 if($wgLang->isRTL()) $s .= '</span>';
1319 function bugReportsLink()
1321 $s = $this->makeKnownLink( wfMsg( 'bugreportspage' ),
1322 wfMsg( 'bugreports' ) );
1328 global $wgLinkCache;
1329 $t1 = Title
::newFromText( gmdate( 'F j' ) );
1330 $t2 = Title
::newFromText( gmdate( 'Y' ) );
1332 $wgLinkCache->suspend();
1333 $id = $t1->getArticleID();
1334 $wgLinkCache->resume();
1337 $s = $this->makeBrokenLink( $t1->getText() );
1339 $s = $this->makeKnownLink( $t1->getText() );
1343 $wgLinkCache->suspend();
1344 $id = $t2->getArticleID();
1345 $wgLinkCache->resume();
1348 $s .= $this->makeBrokenLink( $t2->getText() );
1350 $s .= $this->makeKnownLink( $t2->getText() );
1357 global $wgLang, $wgTitle, $wgLinkCache;
1359 $tns = $wgTitle->getNamespace();
1360 if ( -1 == $tns ) { return ''; }
1362 $pn = $wgTitle->getText();
1363 $tp = wfMsg( 'talkpage' );
1364 if ( Namespace::isTalk( $tns ) ) {
1365 $lns = Namespace::getSubject( $tns );
1368 $text = wfMsg('articlepage');
1371 $text = wfMsg('userpage');
1374 $text = wfMsg('wikipediapage');
1377 $text = wfMsg('imagepage');
1380 $text= wfMsg('articlepage');
1384 $lns = Namespace::getTalk( $tns );
1387 $n = $wgLang->getNsText( $lns );
1388 if ( '' == $n ) { $link = $pn; }
1389 else { $link = $n.':'.$pn; }
1391 $wgLinkCache->suspend();
1392 $s = $this->makeLink( $link, $text );
1393 $wgLinkCache->resume();
1398 function commentLink()
1400 global $wgLang, $wgTitle, $wgLinkCache;
1402 $tns = $wgTitle->getNamespace();
1403 if ( -1 == $tns ) { return ''; }
1405 $lns = ( Namespace::isTalk( $tns ) ) ?
$tns : Namespace::getTalk( $tns );
1407 # assert Namespace::isTalk( $lns )
1409 $n = $wgLang->getNsText( $lns );
1410 $pn = $wgTitle->getText();
1414 $wgLinkCache->suspend();
1415 $s = $this->makeKnownLink($link, wfMsg('postcomment'), 'action=edit§ion=new');
1416 $wgLinkCache->resume();
1421 # After all the page content is transformed into HTML, it makes
1422 # a final pass through here for things like table backgrounds.
1424 function transformContent( $text )
1429 # Note: This function MUST call getArticleID() on the link,
1430 # otherwise the cache won't get updated properly. See LINKCACHE.DOC.
1432 function makeLink( $title, $text = '', $query = '', $trail = '' ) {
1433 wfProfileIn( 'Skin::makeLink' );
1434 $nt = Title
::newFromText( $title );
1436 $result = $this->makeLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1438 wfDebug( 'Invalid title passed to Skin::makeLink(): "'.$title."\"\n" );
1439 $result = $text == "" ?
$title : $text;
1442 wfProfileOut( 'Skin::makeLink' );
1446 function makeKnownLink( $title, $text = '', $query = '', $trail = '', $prefix = '',$aprops = '') {
1447 $nt = Title
::newFromText( $title );
1449 return $this->makeKnownLinkObj( Title
::newFromText( $title ), $text, $query, $trail, $prefix , $aprops );
1451 wfDebug( 'Invalid title passed to Skin::makeKnownLink(): "'.$title."\"\n" );
1452 return $text == '' ?
$title : $text;
1456 function makeBrokenLink( $title, $text = '', $query = '', $trail = '' ) {
1457 $nt = Title
::newFromText( $title );
1459 return $this->makeBrokenLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1461 wfDebug( 'Invalid title passed to Skin::makeBrokenLink(): "'.$title."\"\n" );
1462 return $text == '' ?
$title : $text;
1466 function makeStubLink( $title, $text = '', $query = '', $trail = '' ) {
1467 $nt = Title
::newFromText( $title );
1469 return $this->makeStubLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1471 wfDebug( 'Invalid title passed to Skin::makeStubLink(): "'.$title."\"\n" );
1472 return $text == '' ?
$title : $text;
1476 # Pass a title object, not a title string
1477 function makeLinkObj( &$nt, $text= '', $query = '', $trail = '', $prefix = '' )
1479 global $wgOut, $wgUser;
1480 if ( $nt->isExternal() ) {
1481 $u = $nt->getFullURL();
1482 $link = $nt->getPrefixedURL();
1483 if ( '' == $text ) { $text = $nt->getPrefixedText(); }
1484 $style = $this->getExternalLinkAttributes( $link, $text, 'extiw' );
1487 if ( '' != $trail ) {
1488 if ( preg_match( '/^([a-z]+)(.*)$$/sD', $trail, $m ) ) {
1493 $retVal = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1494 } elseif ( 0 == $nt->getNamespace() && "" == $nt->getText() ) {
1495 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1496 } elseif ( ( -1 == $nt->getNamespace() ) ||
1497 ( Namespace::getImage() == $nt->getNamespace() ) ) {
1498 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1500 $aid = $nt->getArticleID() ;
1502 $retVal = $this->makeBrokenLinkObj( $nt, $text, $query, $trail, $prefix );
1504 $threshold = $wgUser->getOption('stubthreshold') ;
1505 if ( $threshold > 0 ) {
1506 $res = wfQuery ( "SELECT LENGTH(cur_text) AS x, cur_namespace, cur_is_redirect FROM cur WHERE cur_id='{$aid}'", DB_READ
) ;
1508 if ( wfNumRows( $res ) > 0 ) {
1509 $s = wfFetchObject( $res );
1511 if ( $s->cur_is_redirect
OR $s->cur_namespace
!= 0 ) {
1512 $size = $threshold*2 ; # Really big
1514 wfFreeResult( $res );
1516 $size = $threshold*2 ; # Really big
1521 if ( $size < $threshold ) {
1522 $retVal = $this->makeStubLinkObj( $nt, $text, $query, $trail, $prefix );
1524 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1531 # Pass a title object, not a title string
1532 function makeKnownLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' , $aprops = '')
1534 global $wgOut, $wgTitle;
1536 $fname = 'Skin::makeKnownLinkObj';
1537 wfProfileIn( $fname );
1539 $link = $nt->getPrefixedURL();
1541 if ( '' == $link ) {
1543 if ( '' == $text ) {
1544 $text = htmlspecialchars( $nt->getFragment() );
1547 $u = $nt->escapeLocalURL( $query );
1549 if ( '' != $nt->getFragment() ) {
1550 $u .= '#' . htmlspecialchars( $nt->getFragment() );
1552 if ( '' == $text ) {
1553 $text = htmlspecialchars( $nt->getPrefixedText() );
1555 $style = $this->getInternalLinkAttributesObj( $nt, $text );
1558 if ( '' != $trail ) {
1559 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1564 $r = "<a href=\"{$u}\"{$style}{$aprops}>{$prefix}{$text}{$inside}</a>{$trail}";
1565 wfProfileOut( $fname );
1569 # Pass a title object, not a title string
1570 function makeBrokenLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
1572 global $wgOut, $wgUser;
1574 $fname = 'Skin::makeBrokenLinkObj';
1575 wfProfileIn( $fname );
1577 if ( '' == $query ) {
1580 $q = 'action=edit&'.$query;
1582 $u = $nt->escapeLocalURL( $q );
1584 if ( '' == $text ) {
1585 $text = htmlspecialchars( $nt->getPrefixedText() );
1587 $style = $this->getInternalLinkAttributesObj( $nt, $text, "yes" );
1590 if ( '' != $trail ) {
1591 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1596 if ( $wgUser->getOption( 'highlightbroken' ) ) {
1597 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1599 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>?</a>{$trail}";
1602 wfProfileOut( $fname );
1606 # Pass a title object, not a title string
1607 function makeStubLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
1609 global $wgOut, $wgUser;
1611 $link = $nt->getPrefixedURL();
1613 $u = $nt->escapeLocalURL( $query );
1615 if ( '' == $text ) {
1616 $text = htmlspecialchars( $nt->getPrefixedText() );
1618 $style = $this->getInternalLinkAttributesObj( $nt, $text, 'stub' );
1621 if ( '' != $trail ) {
1622 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1627 if ( $wgUser->getOption( 'highlightbroken' ) ) {
1628 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1630 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>!</a>{$trail}";
1635 function makeSelfLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
1637 $u = $nt->escapeLocalURL( $query );
1638 if ( '' == $text ) {
1639 $text = htmlspecialchars( $nt->getPrefixedText() );
1642 if ( '' != $trail ) {
1643 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1648 return "<strong>{$prefix}{$text}{$inside}</strong>{$trail}";
1651 /* these are used extensively in SkinPHPTal, but also some other places */
1652 /*static*/ function makeSpecialUrl( $name, $urlaction='' ) {
1653 $title = Title
::makeTitle( NS_SPECIAL
, $name );
1654 $this->checkTitle($title, $name);
1655 return $title->getLocalURL( $urlaction );
1657 /*static*/ function makeTalkUrl ( $name, $urlaction='' ) {
1658 $title = Title
::newFromText( $name );
1659 $title = $title->getTalkPage();
1660 $this->checkTitle($title, $name);
1661 return $title->getLocalURL( $urlaction );
1663 /*static*/ function makeArticleUrl ( $name, $urlaction='' ) {
1664 $title = Title
::newFromText( $name );
1665 $title= $title->getSubjectPage();
1666 $this->checkTitle($title, $name);
1667 return $title->getLocalURL( $urlaction );
1669 /*static*/ function makeI18nUrl ( $name, $urlaction='' ) {
1670 $title = Title
::newFromText( wfMsg($name) );
1671 $this->checkTitle($title, $name);
1672 return $title->getLocalURL( $urlaction );
1674 /*static*/ function makeUrl ( $name, $urlaction='' ) {
1675 $title = Title
::newFromText( $name );
1676 $this->checkTitle($title, $name);
1677 return $title->getLocalURL( $urlaction );
1679 # this can be passed the NS number as defined in Language.php
1680 /*static*/ function makeNSUrl( $name, $urlaction='', $namespace=0 ) {
1681 $title = Title
::makeTitle( $namespace, $name );
1682 $this->checkTitle($title, $name);
1683 return $title->getLocalURL( $urlaction );
1686 /* these return an array with the 'href' and boolean 'exists' */
1687 /*static*/ function makeUrlDetails ( $name, $urlaction='' ) {
1688 $title = Title
::newFromText( $name );
1689 $this->checkTitle($title, $name);
1691 'href' => $title->getLocalURL( $urlaction ),
1692 'exists' => $title->getArticleID() != 0?
true:false
1695 /*static*/ function makeTalkUrlDetails ( $name, $urlaction='' ) {
1696 $title = Title
::newFromText( $name );
1697 $title = $title->getTalkPage();
1698 $this->checkTitle($title, $name);
1700 'href' => $title->getLocalURL( $urlaction ),
1701 'exists' => $title->getArticleID() != 0?
true:false
1704 /*static*/ function makeArticleUrlDetails ( $name, $urlaction='' ) {
1705 $title = Title
::newFromText( $name );
1706 $title= $title->getSubjectPage();
1707 $this->checkTitle($title, $name);
1709 'href' => $title->getLocalURL( $urlaction ),
1710 'exists' => $title->getArticleID() != 0?
true:false
1713 /*static*/ function makeI18nUrlDetails ( $name, $urlaction='' ) {
1714 $title = Title
::newFromText( wfMsg($name) );
1715 $this->checkTitle($title, $name);
1717 'href' => $title->getLocalURL( $urlaction ),
1718 'exists' => $title->getArticleID() != 0?
true:false
1722 # make sure we have some title to operate on
1723 /*static*/ function checkTitle ( &$title, &$name ) {
1724 if(!is_object($title)) {
1725 $title = Title
::newFromText( $name );
1726 if(!is_object($title)) {
1727 $title = Title
::newFromText( '<error: link target missing>' );
1732 function fnamePart( $url )
1734 $basename = strrchr( $url, '/' );
1735 if ( false === $basename ) { $basename = $url; }
1736 else { $basename = substr( $basename, 1 ); }
1737 return wfEscapeHTML( $basename );
1740 function makeImage( $url, $alt = '' )
1744 if ( '' == $alt ) { $alt = $this->fnamePart( $url ); }
1745 $s = '<img src="'.$url.'" alt="'.$alt.'" />';
1749 function makeImageLink( $name, $url, $alt = '' ) {
1750 $nt = Title
::makeTitle( Namespace::getImage(), $name );
1751 return $this->makeImageLinkObj( $nt, $alt );
1754 function makeImageLinkObj( $nt, $alt = '' ) {
1755 global $wgLang, $wgUseImageResize;
1756 $img = Image
::newFromTitle( $nt );
1757 $url = $img->getURL();
1760 $prefix = $postfix = '';
1762 if ( $wgUseImageResize ) {
1763 # Check if the alt text is of the form "options|alt text"
1765 # * thumbnail make a thumbnail with enlarge-icon and caption, alignment depends on lang
1766 # * left no resizing, just left align. label is used for alt= only
1767 # * right same, but right aligned
1768 # * none same, but not aligned
1769 # * ___px scale to ___ pixels width, no aligning. e.g. use in taxobox
1770 # * center center the image
1771 # * framed Keep original image size, no magnify-button.
1773 $part = explode( '|', $alt);
1775 $mwThumb =& MagicWord
::get( MAG_IMG_THUMBNAIL
);
1776 $mwLeft =& MagicWord
::get( MAG_IMG_LEFT
);
1777 $mwRight =& MagicWord
::get( MAG_IMG_RIGHT
);
1778 $mwNone =& MagicWord
::get( MAG_IMG_NONE
);
1779 $mwWidth =& MagicWord
::get( MAG_IMG_WIDTH
);
1780 $mwCenter =& MagicWord
::get( MAG_IMG_CENTER
);
1781 $mwFramed =& MagicWord
::get( MAG_IMG_FRAMED
);
1782 $alt = $part[count($part)-1];
1784 $height = $framed = $thumb = false;
1786 foreach( $part as $key => $val ) {
1787 if ( ! is_null( $mwThumb->matchVariableStartToEnd($val) ) ) {
1789 } elseif ( ! is_null( $mwRight->matchVariableStartToEnd($val) ) ) {
1790 # remember to set an alignment, don't render immediately
1792 } elseif ( ! is_null( $mwLeft->matchVariableStartToEnd($val) ) ) {
1793 # remember to set an alignment, don't render immediately
1795 } elseif ( ! is_null( $mwCenter->matchVariableStartToEnd($val) ) ) {
1796 # remember to set an alignment, don't render immediately
1798 } elseif ( ! is_null( $mwNone->matchVariableStartToEnd($val) ) ) {
1799 # remember to set an alignment, don't render immediately
1801 } elseif ( ! is_null( $match = $mwWidth->matchVariableStartToEnd($val) ) ) {
1802 # $match is the image width in pixels
1803 if ( preg_match( '/^([0-9]*)x([0-9]*)$/', $match, $m ) ) {
1804 $width = intval( $m[1] );
1805 $height = intval( $m[2] );
1807 $width = intval($match);
1809 } elseif ( ! is_null( $mwFramed->matchVariableStartToEnd($val) ) ) {
1813 if ( 'center' == $align )
1815 $prefix = '<span style="text-align: center">';
1816 $postfix = '</span>';
1820 if ( $thumb ||
$framed ) {
1822 # Create a thumbnail. Alignment depends on language
1823 # writing direction, # right aligned for left-to-right-
1824 # languages ("Western languages"), left-aligned
1825 # for right-to-left-languages ("Semitic languages")
1827 # If thumbnail width has not been provided, it is set
1828 # here to 180 pixels
1829 if ( $align == '' ) {
1830 $align = $wgLang->isRTL() ?
'left' : 'right';
1832 if ( ! isset($width) ) {
1835 return $prefix.$this->makeThumbLinkObj( $img, $alt, $align, $width, $height, $framed ).$postfix;
1837 } elseif ( isset($width) ) {
1839 # Create a resized image, without the additional thumbnail
1842 if ( ( ! $height === false )
1843 && ( $img->getHeight() * $width / $img->getWidth() > $height ) ) {
1844 print "height=$height<br>\nimg->getHeight() = ".$img->getHeight()."<br>\n";
1845 print 'rescaling by factor '. $height / $img->getHeight() . "<br>\n";
1846 $width = $img->getWidth() * $height / $img->getHeight();
1848 $url = $img->createThumb( $width );
1850 } # endif $wgUseImageResize
1852 if ( empty( $alt ) ) {
1853 $alt = preg_replace( '/\.(.+?)^/', '', $img->getName() );
1855 $alt = htmlspecialchars( $alt );
1857 $u = $nt->escapeLocalURL();
1860 $s = str_replace( "$1", $img->getName(), wfMsg('missingimage') );
1861 $s .= "<br>{$alt}<br>{$url}<br>\n";
1863 $s = '<a href="'.$u.'" class="image" title="'.$alt.'">' .
1864 '<img src="'.$url.'" alt="'.$alt.'" /></a>';
1866 if ( '' != $align ) {
1867 $s = "<div class=\"float{$align}\"><span>{$s}</span></div>";
1869 return str_replace("\n", ' ',$prefix.$s.$postfix);
1873 function makeThumbLinkObj( $img, $label = '', $align = 'right', $boxwidth = 180, $boxheight=false, $framed=false ) {
1874 global $wgStylePath, $wgLang;
1875 # $image = Title::makeTitle( Namespace::getImage(), $name );
1876 $url = $img->getURL();
1878 #$label = htmlspecialchars( $label );
1879 $alt = preg_replace( '/<[^>]*>/', '', $label);
1880 $alt = htmlspecialchars( $alt );
1882 if ( $img->exists() )
1884 $width = $img->getWidth();
1885 $height = $img->getHeight();
1887 $width = $height = 200;
1891 // Use image dimensions, don't scale
1893 $oboxwidth = $boxwidth +
2;
1894 $boxheight = $height;
1897 $h = intval( $height/($width/$boxwidth) );
1898 $oboxwidth = $boxwidth +
2;
1899 if ( ( ! $boxheight === false ) && ( $h > $boxheight ) )
1901 $boxwidth *= $boxheight/$h;
1905 $thumbUrl = $img->createThumb( $boxwidth );
1908 $u = $img->getEscapeLocalURL();
1910 $more = htmlspecialchars( wfMsg( 'thumbnail-more' ) );
1911 $magnifyalign = $wgLang->isRTL() ?
'left' : 'right';
1912 $textalign = $wgLang->isRTL() ?
' style="text-align:right"' : '';
1914 $s = "<div class=\"thumb t{$align}\"><div style=\"width:{$oboxwidth}px;\">";
1915 if ( $thumbUrl == '' ) {
1916 $s .= str_replace( "$1", $img->getName(), wfMsg('missingimage') );
1919 $s .= '<a href="'.$u.'" class="internal" title="'.$alt.'">'.
1920 '<img src="'.$thumbUrl.'" alt="'.$alt.'" ' .
1921 'width="'.$boxwidth.'" height="'.$boxheight.'" /></a>';
1925 $zoomicon = '<div class="magnify" style="float:'.$magnifyalign.'">'.
1926 '<a href="'.$u.'" class="internal" title="'.$more.'">'.
1927 '<img src="'.$wgStylePath.'/images/magnify-clip.png" ' .
1928 'width="15" height="11" alt="'.$more.'" /></a></div>';
1931 $s .= ' <div class="thumbcaption" '.$textalign.'>'.$zoomicon.$label."</div></div></div>";
1932 return str_replace("\n", ' ', $s);
1935 function makeMediaLink( $name, $url, $alt = "" ) {
1936 $nt = Title
::makeTitle( Namespace::getMedia(), $name );
1937 return $this->makeMediaLinkObj( $nt, $alt );
1940 function makeMediaLinkObj( $nt, $alt = "" )
1942 if ( ! isset( $nt ) )
1944 ### HOTFIX. Instead of breaking, return empry string.
1947 $name = $nt->getDBKey();
1948 $url = Image
::wfImageUrl( $name );
1949 if ( empty( $alt ) ) {
1950 $alt = preg_replace( '/\.(.+?)^/', '', $name );
1953 $u = htmlspecialchars( $url );
1954 $s = "<a href=\"{$u}\" class='internal' title=\"{$alt}\">{$alt}</a>";
1959 function specialLink( $name, $key = "" )
1963 if ( '' == $key ) { $key = strtolower( $name ); }
1964 $pn = $wgLang->ucfirst( $name );
1965 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1969 function makeExternalLink( $url, $text, $escape = true ) {
1970 $style = $this->getExternalLinkAttributes( $url, $text );
1971 $url = htmlspecialchars( $url );
1973 $text = htmlspecialchars( $text );
1975 return '<a href="'.$url.'"'.$style.'>'.$text.'</a>';
1978 # Called by history lists and recent changes
1981 # Returns text for the start of the tabular part of RC
1982 function beginRecentChangesList()
1984 $this->rc_cache
= array() ;
1985 $this->rcMoveIndex
= 0;
1986 $this->rcCacheIndex
= 0 ;
1987 $this->lastdate
= '';
1988 $this->rclistOpen
= false;
1992 function beginImageHistoryList()
1994 $s = "\n<h2>" . wfMsg( 'imghistory' ) . "</h2>\n" .
1995 "<p>" . wfMsg( 'imghistlegend' ) . "</p>\n".'<ul class="special">';
1999 # Returns text for the end of RC
2000 # If enhanced RC is in use, returns pretty much all the text
2001 function endRecentChangesList()
2003 $s = $this->recentChangesBlock() ;
2004 if( $this->rclistOpen
) {
2010 # Enhanced RC ungrouped line
2011 function recentChangesBlockLine ( $rcObj )
2013 global $wgStylePath, $wgLang ;
2015 # Get rc_xxxx variables
2016 extract( $rcObj->mAttribs
) ;
2017 $curIdEq = 'curid='.$rc_cur_id;
2022 $r .= '<img src="'.$wgStylePath.'/images/Arr_.png" width="12" height="12" border="0" />' ;
2025 if ( $rc_type == RC_MOVE
) {
2026 $r .= ' ';
2028 # M & N (minor & new)
2029 $M = wfMsg( 'minoreditletter' );
2030 $N = wfMsg( 'newpageletter' );
2032 if ( $rc_type == RC_NEW
) {
2045 $r .= ' '.$rcObj->timestamp
.' ' ;
2049 $link = $rcObj->link
;
2050 if ( $rcObj->watched
) $link = '<strong>'.$link.'</strong>' ;
2055 $r .= $rcObj->curlink
;
2059 $r .= $this->makeKnownLinkObj( $rcObj->getTitle(), wfMsg( 'hist' ), $curIdEq.'&action=history' );
2062 $r .= ') . . '.$rcObj->userlink
;
2063 $r .= $rcObj->usertalklink
;
2066 if ( $rc_comment != '' && $rc_type != RC_MOVE
) {
2067 $rc_comment=$this->formatComment($rc_comment);
2068 $r .= $wgLang->emphasize( ' ('.$rc_comment.')' );
2076 function recentChangesBlockGroup ( $block )
2078 global $wgStylePath, $wgLang ;
2081 $M = wfMsg( 'minoreditletter' );
2082 $N = wfMsg( 'newpageletter' );
2084 # Collate list of users
2086 $userlinks = array () ;
2087 foreach ( $block AS $rcObj ) {
2088 $oldid = $rcObj->mAttribs
['rc_last_oldid'];
2089 if ( $rcObj->mAttribs
['rc_new'] ) $isnew = true ;
2090 $u = $rcObj->userlink
;
2091 if ( !isset ( $userlinks[$u] ) ) $userlinks[$u] = 0 ;
2095 # Sort the list and convert to text
2096 krsort ( $userlinks ) ;
2097 asort ( $userlinks ) ;
2099 foreach ( $userlinks as $userlink => $count) {
2101 if ( $count > 1 ) $text .= " ({$count}×)" ;
2102 array_push ( $users , $text ) ;
2104 $users = ' <font size="-1">['.implode('; ',$users).']</font>' ;
2107 $rci = 'RCI'.$this->rcCacheIndex
;
2108 $rcl = 'RCL'.$this->rcCacheIndex
;
2109 $rcm = 'RCM'.$this->rcCacheIndex
;
2110 $toggleLink = 'javascript:toggleVisibility("'.$rci.'","'.$rcm.'","'.$rcl.'")' ;
2111 $arrowdir = $wgLang->isRTL() ?
'l' : 'r';
2112 $tl = '<span id="'.$rcm.'"><a href="'.$toggleLink.'"><img src="'.$wgStylePath.'"/images/Arr_'.$arrowdir.png
.'" width="12" height="12" /></a></span>' ;
2113 $tl .= '<span id="'.$rcl.'" style="display:none"><a href="'.$toggleLink.'"><img src="'.$wgStylePath.'/images/Arr_d.png" width="12" height="12" /></a></span>' ;
2119 if ( $isnew ) $r .= $N ;
2120 else $r .= ' ' ;
2121 $r .= ' ' ; # Minor
2124 $r .= ' '.$block[0]->timestamp
.' ' ;
2128 $link = $block[0]->link
;
2129 if ( $block[0]->watched
) $link = '<strong>'.$link.'</strong>' ;
2132 $curIdEq = 'curid=' . $block[0]->mAttribs
['rc_cur_id'];
2133 if ( $block[0]->mAttribs
['rc_type'] != RC_LOG
) {
2135 $r .= ' ('.count($block).' ' ;
2136 if ( $isnew ) $r .= wfMsg('changes');
2137 else $r .= $this->makeKnownLinkObj( $block[0]->getTitle() , wfMsg('changes') ,
2138 $curIdEq.'&diff=0&oldid='.$oldid ) ;
2142 $r .= $this->makeKnownLinkObj( $block[0]->getTitle(), wfMsg( 'history' ), $curIdEq.'&action=history' );
2150 $r .= '<div id="'.$rci.'" style="display:none">' ;
2151 foreach ( $block AS $rcObj ) {
2152 # Get rc_xxxx variables
2153 extract( $rcObj->mAttribs
);
2155 $r .= '<img src="'.$wgStylePath.'/images/Arr_.png" width="12" height="12" />';
2156 $r .= '<tt> ' ;
2157 if ( $rc_new ) $r .= $N ;
2158 else $r .= ' ' ;
2159 if ( $rc_minor ) $r .= $M ;
2160 else $r .= ' ' ;
2164 if ( $rc_last_oldid != 0 ) {
2165 $o = 'oldid='.$rc_last_oldid ;
2167 if ( $rc_type == RC_LOG
) {
2168 $link = $rcObj->timestamp
;
2170 $link = $this->makeKnownLinkObj( $rcObj->getTitle(), $rcObj->timestamp
, "{$curIdEq}&$o" ) ;
2172 $link = '<tt>'.$link.'</tt>' ;
2176 $r .= $rcObj->curlink
;
2178 $r .= $rcObj->lastlink
;
2179 $r .= ') . . '.$rcObj->userlink
;
2180 $r .= $rcObj->usertalklink
;
2181 if ( $rc_comment != '' ) {
2182 $rc_comment=$this->formatComment($rc_comment);
2183 $r .= $wgLang->emphasize( ' ('.$rc_comment.')' ) ;
2189 $this->rcCacheIndex++
;
2193 # If enhanced RC is in use, this function takes the previously cached
2194 # RC lines, arranges them, and outputs the HTML
2195 function recentChangesBlock ()
2197 global $wgStylePath ;
2198 if ( count ( $this->rc_cache
) == 0 ) return '' ;
2200 foreach ( $this->rc_cache
AS $secureName => $block ) {
2201 if ( count ( $block ) < 2 ) {
2202 $blockOut .= $this->recentChangesBlockLine ( array_shift ( $block ) ) ;
2204 $blockOut .= $this->recentChangesBlockGroup ( $block ) ;
2208 return '<div>'.$blockOut.'</div>' ;
2211 # Called in a loop over all displayed RC entries
2212 # Either returns the line, or caches it for later use
2213 function recentChangesLine( &$rc, $watched = false )
2216 $usenew = $wgUser->getOption( 'usenewrc' );
2218 $line = $this->recentChangesLineNew ( $rc, $watched ) ;
2220 $line = $this->recentChangesLineOld ( $rc, $watched ) ;
2224 function recentChangesLineOld( &$rc, $watched = false )
2226 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds;
2228 # Extract DB fields into local scope
2229 extract( $rc->mAttribs
);
2230 $curIdEq = 'curid=' . $rc_cur_id;
2232 # Make date header if necessary
2233 $date = $wgLang->date( $rc_timestamp, true);
2235 if ( $date != $this->lastdate
) {
2236 if ( '' != $this->lastdate
) { $s .= "</ul>\n"; }
2237 $s .= "<h4>{$date}</h4>\n<ul class='special'>";
2238 $this->lastdate
= $date;
2239 $this->rclistOpen
= true;
2243 if ( $rc_type == RC_MOVE
) {
2245 $s .= '(' . wfMsg( 'diff' ) . ') (';
2247 $s .= $this->makeKnownLinkObj( $rc->getMovedToTitle(), wfMsg( 'hist' ), 'action=history' ) .
2250 # "[[x]] moved to [[y]]"
2252 $s .= wfMsg( '1movedto2', $this->makeKnownLinkObj( $rc->getTitle(), '', 'redirect=no' ),
2253 $this->makeKnownLinkObj( $rc->getMovedToTitle(), '' ) );
2257 if ( $rc_type == RC_NEW ||
$rc_type == RC_LOG
) {
2258 $diffLink = wfMsg( 'diff' );
2260 $diffLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'diff' ),
2261 $curIdEq.'&diff='.$rc_this_oldid.'&oldid='.$rc_last_oldid ,'' ,'' , ' tabindex="'.$rc->counter
.'"');
2263 $s .= '('.$diffLink.') (';
2266 $s .= $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'hist' ), $curIdEq.'&action=history' );
2269 # M and N (minor and new)
2270 $M = wfMsg( 'minoreditletter' );
2271 $N = wfMsg( 'newpageletter' );
2272 if ( $rc_minor ) { $s .= ' <strong>'.$M.'</strong>'; }
2273 if ( $rc_type == RC_NEW
) { $s .= '<strong>'.$N.'</strong>'; }
2276 $articleLink = $this->makeKnownLinkObj( $rc->getTitle(), '' );
2279 $articleLink = '<strong>'.$articleLink.'</strong>';
2281 $s .= ' '.$articleLink;
2286 $s .= '; ' . $wgLang->time( $rc_timestamp, true, $wgRCSeconds ) . ' . . ';
2288 # User link (or contributions for unregistered users)
2289 if ( 0 == $rc_user ) {
2290 $userLink = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
2291 $rc_user_text, 'target=' . $rc_user_text );
2293 $userLink = $this->makeLink( $wgLang->getNsText( NS_USER
) . ':'.$rc_user_text, $rc_user_text );
2298 $talkname=$wgLang->getNsText(NS_TALK
); # use the shorter name
2299 global $wgDisableAnonTalk;
2300 if( 0 == $rc_user && $wgDisableAnonTalk ) {
2303 $utns=$wgLang->getNsText(NS_USER_TALK
);
2304 $userTalkLink= $this->makeLink($utns . ':'.$rc_user_text, $talkname );
2308 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2309 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2310 'Blockip' ), wfMsg( 'blocklink' ), 'ip='.$rc_user_text );
2314 if($userTalkLink) $userTalkLink .= ' | ';
2315 $userTalkLink .= $blockLink;
2317 if($userTalkLink) $s.=' ('.$userTalkLink.')';
2320 if ( '' != $rc_comment && '*' != $rc_comment && $rc_type != RC_MOVE
) {
2321 $rc_comment=$this->formatComment($rc_comment);
2322 $s .= $wgLang->emphasize(' (' . $rc_comment . ')');
2329 # function recentChangesLineNew( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched = false, $oldid = 0 , $diffid = 0 )
2330 function recentChangesLineNew( &$baseRC, $watched = false )
2332 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds;
2334 # Create a specialised object
2335 $rc = RCCacheEntry
::newFromParent( $baseRC ) ;
2337 # Extract fields from DB into the function scope (rc_xxxx variables)
2338 extract( $rc->mAttribs
);
2339 $curIdEq = 'curid=' . $rc_cur_id;
2341 # If it's a new day, add the headline and flush the cache
2342 $date = $wgLang->date( $rc_timestamp, true);
2344 if ( $date != $this->lastdate
) {
2345 # Process current cache
2346 $ret = $this->recentChangesBlock () ;
2347 $this->rc_cache
= array() ;
2348 $ret .= "<h4>{$date}</h4>\n";
2349 $this->lastdate
= $date;
2353 if ( $rc_type == RC_MOVE
) {
2354 $clink = $this->makeKnownLinkObj( $rc->getTitle(), '', 'redirect=no' );
2355 $clink .= ' ' . wfMsg('movedto') . ' ';
2356 $clink .= $this->makeKnownLinkObj( $rc->getMovedToTitle(), '' );
2358 $clink = $this->makeKnownLinkObj( $rc->getTitle(), '' ) ;
2361 $time = $wgLang->time( $rc_timestamp, true, $wgRCSeconds );
2362 $rc->watched
= $watched ;
2363 $rc->link
= $clink ;
2364 $rc->timestamp
= $time;
2367 if ( ( $rc_type == RC_NEW
&& $rc_this_oldid == 0 ) ||
$rc_type == RC_LOG ||
$rc_type == RC_MOVE
) {
2368 $curLink = wfMsg( 'cur' );
2370 $curLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'cur' ),
2371 $curIdEq.'&diff=0&oldid='.$rc_this_oldid ,'' ,'' , ' tabindex="'.$baseRC->counter
.'"' );
2375 $titleObj = $rc->getTitle();
2376 if ( $rc_last_oldid == 0 ||
$rc_type == RC_LOG ||
$rc_type == RC_MOVE
) {
2377 $lastLink = wfMsg( 'last' );
2379 $lastLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'last' ),
2380 $curIdEq.'&diff='.$rc_this_oldid.'&oldid='.$rc_last_oldid );
2383 # Make user link (or user contributions for unregistered users)
2384 if ( 0 == $rc_user ) {
2385 $userLink = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
2386 $rc_user_text, 'target=' . $rc_user_text );
2388 $userLink = $this->makeLink( $wgLang->getNsText(
2389 Namespace::getUser() ) . ':'.$rc_user_text, $rc_user_text );
2392 $rc->userlink
= $userLink ;
2393 $rc->lastlink
= $lastLink ;
2394 $rc->curlink
= $curLink ;
2396 # Make user talk link
2397 $utns=$wgLang->getNsText(NS_USER_TALK
);
2398 $talkname=$wgLang->getNsText(NS_TALK
); # use the shorter name
2399 $userTalkLink= $this->makeLink($utns . ':'.$rc_user_text, $talkname );
2401 global $wgDisableAnonTalk;
2402 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2403 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2404 'Blockip' ), wfMsg( 'blocklink' ), 'ip='.$rc_user_text );
2405 if( $wgDisableAnonTalk )
2406 $rc->usertalklink
= ' ('.$blockLink.')';
2408 $rc->usertalklink
= ' ('.$userTalkLink.' | '.$blockLink.')';
2410 if( $wgDisableAnonTalk && ($rc_user == 0) )
2411 $rc->usertalklink
= '';
2413 $rc->usertalklink
= ' ('.$userTalkLink.')';
2416 # Put accumulated information into the cache, for later display
2417 # Page moves go on their own line
2418 $title = $rc->getTitle();
2419 $secureName = $title->getPrefixedDBkey();
2420 if ( $rc_type == RC_MOVE
) {
2421 # Use an @ character to prevent collision with page names
2422 $this->rc_cache
['@@' . ($this->rcMoveIndex++
)] = array($rc);
2424 if ( !isset ( $this->rc_cache
[$secureName] ) ) $this->rc_cache
[$secureName] = array() ;
2425 array_push ( $this->rc_cache
[$secureName] , $rc ) ;
2430 function endImageHistoryList()
2436 /* This function is called by all recent changes variants, by the page history,
2437 and by the user contributions list. It is responsible for formatting edit
2438 comments. It escapes any HTML in the comment, but adds some CSS to format
2439 auto-generated comments (from section editing) and formats [[wikilinks]].
2440 Main author: Erik Möller (moeller@scireview.de)
2442 function formatComment($comment)
2445 $comment=wfEscapeHTML($comment);
2447 # The pattern for autogen comments is / * foo * /, which makes for
2449 # We look for all comments, match any text before and after the comment,
2450 # add a separator where needed and format the comment itself with CSS
2451 while (preg_match('/(.*)\/\*\s*(.*?)\s*\*\/(.*)/', $comment,$match)) {
2456 if($pre) { $auto = $sep.' '.$auto; }
2457 if($post) { $auto .= ' '.$sep; }
2458 $auto='<span class="autocomment">'.$auto.'</span>';
2459 $comment=$pre.$auto.$post;
2462 # format regular and media links - all other wiki formatting
2464 while(preg_match('/\[\[(.*?)(\|(.*?))*\]\]/',$comment,$match)) {
2466 $medians = $wgLang->getNsText(Namespace::getMedia());
2468 if(preg_match('/^'.$medians.'/i',$match[1])) {
2469 $func='makeMediaLink';
2471 if(isset($match[3]) ) {
2473 preg_replace('/\[\[(.*?)\]\]/',
2474 $this->$func($match[1],$match[3]),$comment,1);
2477 preg_replace('/\[\[(.*?)\]\]/',
2478 $this->$func($match[1],$match[1]),$comment,1);
2486 function imageHistoryLine( $iscur, $timestamp, $img, $user, $usertext, $size, $description )
2488 global $wgUser, $wgLang, $wgTitle;
2490 $datetime = $wgLang->timeanddate( $timestamp, true );
2491 $del = wfMsg( 'deleteimg' );
2492 $cur = wfMsg( 'cur' );
2495 $url = Image
::wfImageUrl( $img );
2497 if ( $wgUser->isSysop() ) {
2498 $link = $wgTitle->escapeLocalURL( 'image=' . $wgTitle->getPartialURL() .
2500 $style = $this->getInternalLinkAttributes( $link, $del );
2502 $dlink = '<a href="'.$link.'"'.$style.'>'.$del.'</a>';
2507 $url = wfEscapeHTML( wfImageArchiveUrl( $img ) );
2508 if( $wgUser->getID() != 0 ) {
2509 $rlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2510 wfMsg( 'revertimg' ), 'action=revert&oldimage=' .
2511 urlencode( $img ) );
2512 $dlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2513 $del, 'action=delete&oldimage=' . urlencode( $img ) );
2515 # Having live active links for non-logged in users
2516 # means that bots and spiders crawling our site can
2517 # inadvertently change content. Baaaad idea.
2518 $rlink = wfMsg( 'revertimg' );
2523 $userlink = $usertext;
2525 $userlink = $this->makeLink( $wgLang->getNsText( Namespace::getUser() ) .
2526 ':'.$usertext, $usertext );
2528 $nbytes = wfMsg( 'nbytes', $size );
2529 $style = $this->getInternalLinkAttributes( $url, $datetime );
2531 $s = "<li> ({$dlink}) ({$rlink}) <a href=\"{$url}\"{$style}>{$datetime}</a>"
2532 . " . . {$userlink} ({$nbytes})";
2534 if ( '' != $description && '*' != $description ) {
2535 $sk=$wgUser->getSkin();
2536 $s .= $wgLang->emphasize(' (' . $sk->formatComment($description) . ')');
2542 function tocIndent($level) {
2543 return str_repeat( '<div class="tocindent">'."\n", $level>0 ?
$level : 0 );
2546 function tocUnindent($level) {
2547 return str_repeat( "</div>\n", $level>0 ?
$level : 0 );
2550 # parameter level defines if we are on an indentation level
2551 function tocLine( $anchor, $tocline, $level ) {
2552 $link = '<a href="#'.$anchor.'">'.$tocline.'</a><br />';
2556 return '<div class="tocline">'.$link."</div>\n";
2561 function tocTable($toc) {
2562 # note to CSS fanatics: putting this in a div does not work -- div won't auto-expand
2563 # try min-width & co when somebody gets a chance
2564 $hideline = ' <script type="text/javascript">showTocToggle("' . addslashes( wfMsg('showtoc') ) . '","' . addslashes( wfMsg('hidetoc') ) . '")</script>';
2566 '<table border="0" id="toc"><tr><td align="center">'."\n".
2567 '<b>'.wfMsg('toc').'</b>' .
2569 '</td></tr><tr id="tocinside"><td>'."\n".
2570 $toc."</td></tr></table>\n";
2573 # These two do not check for permissions: check $wgTitle->userCanEdit before calling them
2574 function editSectionScript( $section, $head ) {
2575 global $wgTitle, $wgRequest;
2576 if( $wgRequest->getInt( 'oldid' ) && ( $wgRequest->getVal( 'diff' ) != '0' ) ) {
2579 $url = $wgTitle->escapeLocalURL( 'action=edit§ion='.$section );
2580 return '<span oncontextmenu="document.location="'.$url.'";return false;">'.$head.'</span>';
2583 function editSectionLink( $section ) {
2585 global $wgTitle, $wgUser, $wgLang;
2587 if( $wgRequest->getInt( 'oldid' ) && ( $wgRequest->getVal( 'diff' ) != '0' ) ) {
2588 # Section edit links would be out of sync on an old page.
2589 # But, if we're diffing to the current page, they'll be
2594 $editurl = '§ion='.$section;
2595 $url = $this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg('editsection'),'action=edit'.$editurl);
2597 if( $wgLang->isRTL() ) {
2599 $nearside = 'right';
2604 return "<div class=\"editsection\" style=\"float:$farside;margin-$nearside:5px;\">[".$url."]</div>";
2608 // This function is called by EditPage.php and shows a bulletin board style
2609 // toolbar for common editing functions. It can be disabled in the user preferences.
2610 // The necsesary JavaScript code can be found in style/wikibits.js.
2611 function getEditToolbar() {
2612 global $wgStylePath, $wgLang, $wgMimeType;
2614 // toolarray an array of arrays which each include the filename of
2615 // the button image (without path), the opening tag, the closing tag,
2616 // and optionally a sample text that is inserted between the two when no
2617 // selection is highlighted.
2618 // The tip text is shown when the user moves the mouse over the button.
2620 // Already here are accesskeys (key), which are not used yet until someone
2621 // can figure out a way to make them work in IE. However, we should make
2622 // sure these keys are not defined on the edit page.
2624 array( 'image'=>'button_bold.png',
2627 'sample'=>wfMsg('bold_sample'),
2628 'tip'=>wfMsg('bold_tip'),
2631 array( "image"=>"button_italic.png",
2634 "sample"=>wfMsg("italic_sample"),
2635 "tip"=>wfMsg("italic_tip"),
2638 array( "image"=>"button_link.png",
2641 "sample"=>wfMsg("link_sample"),
2642 "tip"=>wfMsg("link_tip"),
2645 array( "image"=>"button_extlink.png",
2648 "sample"=>wfMsg("extlink_sample"),
2649 "tip"=>wfMsg("extlink_tip"),
2652 array( "image"=>"button_headline.png",
2655 "sample"=>wfMsg("headline_sample"),
2656 "tip"=>wfMsg("headline_tip"),
2659 array( "image"=>"button_image.png",
2660 "open"=>"[[".$wgLang->getNsText(NS_IMAGE
).":",
2662 "sample"=>wfMsg("image_sample"),
2663 "tip"=>wfMsg("image_tip"),
2666 array( "image"=>"button_media.png",
2667 "open"=>"[[".$wgLang->getNsText(NS_MEDIA
).":",
2669 "sample"=>wfMsg("media_sample"),
2670 "tip"=>wfMsg("media_tip"),
2673 array( "image"=>"button_math.png",
2674 "open"=>"\\<math\\>",
2675 "close"=>"\\</math\\>",
2676 "sample"=>wfMsg("math_sample"),
2677 "tip"=>wfMsg("math_tip"),
2680 array( "image"=>"button_nowiki.png",
2681 "open"=>"\\<nowiki\\>",
2682 "close"=>"\\</nowiki\\>",
2683 "sample"=>wfMsg("nowiki_sample"),
2684 "tip"=>wfMsg("nowiki_tip"),
2687 array( "image"=>"button_sig.png",
2691 "tip"=>wfMsg("sig_tip"),
2694 array( "image"=>"button_hr.png",
2695 "open"=>"\\n----\\n",
2698 "tip"=>wfMsg("hr_tip"),
2702 $toolbar ="<script type='text/javascript'>\n/*<![CDATA[*/\n";
2704 $toolbar.="document.writeln(\"<div id='toolbar'>\");\n";
2705 foreach($toolarray as $tool) {
2707 $image=$wgStylePath.'/images/'.$tool['image'];
2708 $open=$tool['open'];
2709 $close=$tool['close'];
2710 $sample = addslashes( $tool['sample'] );
2712 // Note that we use the tip both for the ALT tag and the TITLE tag of the image.
2713 // Older browsers show a "speedtip" type message only for ALT.
2714 // Ideally these should be different, realistically they
2715 // probably don't need to be.
2716 $tip = addslashes( $tool['tip'] );
2718 #$key = $tool["key"];
2720 $toolbar.="addButton('$image','$tip','$open','$close','$sample');\n";
2723 $toolbar.="addInfobox('" . addslashes( wfMsg( "infobox" ) ) . "','" . addslashes(wfMsg("infobox_alert")) . "');\n";
2724 $toolbar.="document.writeln(\"</div>\");\n";
2726 $toolbar.="/*]]>*/\n</script>";
2732 require_once( 'SkinStandard.php' );
2733 require_once( 'SkinNostalgia.php' );
2734 require_once( 'SkinCologneBlue.php' );
2736 if( $wgUsePHPTal ) {
2737 require_once( 'SkinPHPTal.php' );