2 if( defined( "MEDIAWIKI" ) ) {
6 require_once( 'Feed.php' ); // should not be called if the actual page isn't feed enabled
7 require_once( 'Image.php' );
9 # These are the INTERNAL names, which get mapped
10 # directly to class names. For display purposes, the
11 # Language class has internationalized names
13 /* private */ $wgValidSkinNames = array(
14 'standard' => 'Standard',
15 'nostalgia' => 'Nostalgia',
16 'cologneblue' => 'CologneBlue'
19 #$wgValidSkinNames[] = 'PHPTal';
20 #$wgValidSkinNames['davinci'] = 'DaVinci';
21 #$wgValidSkinNames['mono'] = 'Mono';
22 $wgValidSkinNames['monobook'] = 'MonoBook';
23 $wgValidSkinNames['myskin'] = 'MySkin';
24 #$wgValidSkinNames['monobookminimal'] = 'MonoBookMinimal';
27 require_once( 'RecentChange.php' );
29 class RCCacheEntry
extends RecentChange
31 var $secureName, $link;
32 var $curlink , $difflink, $lastlink , $usertalklink , $versionlink ;
33 var $userlink, $timestamp, $watched;
35 function newFromParent( $rc )
37 $rc2 = new RCCacheEntry
;
38 $rc2->mAttribs
= $rc->mAttribs
;
39 $rc2->mExtra
= $rc->mExtra
;
46 /* private */ var $lastdate, $lastline;
47 var $linktrail ; # linktrail regexp
48 var $rc_cache ; # Cache for Enhanced Recent Changes
49 var $rcCacheIndex ; # Recent Changes Cache Counter for visibility toggle
51 var $postParseLinkColour = true;
55 $this->linktrail
= wfMsg('linktrail');
58 function getSkinNames()
60 global $wgValidSkinNames;
61 return $wgValidSkinNames;
64 function getStylesheet()
66 return 'wikistandard.css';
68 function getSkinName() {
72 # Get/set accessor for delayed link colouring
73 function postParseLinkColour( $setting = NULL ) {
74 return wfSetVar( $this->postParseLinkColour
, $setting );
79 global $wgOut, $wgUser;
81 if ( $wgOut->isQuickbarSuppressed() ) { return 0; }
82 $q = $wgUser->getOption( 'quickbar' );
83 if ( '' == $q ) { $q = 0; }
87 function initPage( &$out )
89 $fname = 'Skin::initPage';
90 wfProfileIn( $fname );
92 $out->addLink( array( 'rel' => 'shortcut icon', 'href' => '/favicon.ico' ) );
94 $this->addMetadataLinks($out);
96 wfProfileOut( $fname );
99 function addMetadataLinks( &$out ) {
100 global $wgTitle, $wgEnableDublinCoreRdf, $wgEnableCreativeCommonsRdf, $wgRdfMimeType, $action;
101 global $wgRightsPage, $wgRightsUrl;
103 if( $out->isArticleRelated() ) {
104 # note: buggy CC software only reads first "meta" link
105 if( $wgEnableCreativeCommonsRdf ) {
106 $out->addMetadataLink( array(
107 'title' => 'Creative Commons',
108 'type' => 'application/rdf+xml',
109 'href' => $wgTitle->getLocalURL( 'action=creativecommons') ) );
111 if( $wgEnableDublinCoreRdf ) {
112 $out->addMetadataLink( array(
113 'title' => 'Dublin Core',
114 'type' => 'application/rdf+xml',
115 'href' => $wgTitle->getLocalURL( 'action=dublincore' ) ) );
119 if( $wgRightsPage ) {
120 $copy = Title
::newFromText( $wgRightsPage );
122 $copyright = $copy->getLocalURL();
125 if( !$copyright && $wgRightsUrl ) {
126 $copyright = $wgRightsUrl;
129 $out->addLink( array(
130 'rel' => 'copyright',
131 'href' => $copyright ) );
135 function outputPage( &$out ) {
136 global $wgDebugComments;
138 wfProfileIn( 'Skin::outputPage' );
139 $this->initPage( $out );
140 $out->out( $out->headElement() );
142 $out->out( "\n<body" );
143 $ops = $this->getBodyOptions();
144 foreach ( $ops as $name => $val ) {
145 $out->out( " $name='$val'" );
148 if ( $wgDebugComments ) {
149 $out->out( "<!-- Wiki debugging output:\n" .
150 $out->mDebugtext
. "-->\n" );
152 $out->out( $this->beforeContent() );
154 $out->out( $out->mBodytext
. "\n" );
156 $out->out( $this->afterContent() );
159 $out->out( $out->reportTime() );
161 $out->out( "\n</body></html>" );
164 function getHeadScripts() {
165 global $wgStylePath, $wgUser, $wgLang, $wgAllowUserJs;
166 $r = "<script type=\"text/javascript\" src=\"{$wgStylePath}/wikibits.js\"></script>\n";
167 if( $wgAllowUserJs && $wgUser->getID() != 0 ) { # logged in
168 $userpage = $wgLang->getNsText( Namespace::getUser() ) . ":" . $wgUser->getName();
169 $userjs = htmlspecialchars($this->makeUrl($userpage.'/'.$this->getSkinName().'.js', 'action=raw&ctype=text/javascript'));
170 $r .= '<script type="text/javascript" src="'.$userjs."\"></script>\n";
175 # get the user/site-specific stylesheet, SkinPHPTal called from RawPage.php (settings are cached that way)
176 function getUserStylesheet() {
177 global $wgOut, $wgStylePath, $wgLang, $wgUser, $wgRequest, $wgTitle, $wgAllowUserCss;
178 $sheet = $this->getStylesheet();
179 $action = $wgRequest->getText('action');
180 $s = "@import \"$wgStylePath/$sheet\";\n";
181 if($wgLang->isRTL()) $s .= "@import \"$wgStylePath/common_rtl.css\";\n";
182 if( $wgAllowUserCss && $wgUser->getID() != 0 ) { # logged in
183 if($wgTitle->isCssSubpage() and $action == 'submit' and $wgTitle->userCanEditCssJsSubpage()) {
184 $s .= $wgRequest->getText('wpTextbox1');
186 $userpage = $wgLang->getNsText( Namespace::getUser() ) . ":" . $wgUser->getName();
187 $s.= '@import "'.$this->makeUrl($userpage.'/'.$this->getSkinName().'.css', 'action=raw&ctype=text/css').'";'."\n";
190 $s .= $this->doGetUserStyles();
193 # placeholder, returns generated js in monobook
194 function getUserJs() {
198 function getUserStyles()
200 global $wgOut, $wgStylePath, $wgLang;
201 $s = "<style type='text/css'>\n";
202 $s .= "/*/*/\n"; # <-- Hide the styles from Netscape 4 without hiding them from IE/Mac
203 $s .= $this->getUserStylesheet();
209 function doGetUserStyles()
211 global $wgUser, $wgLang;
213 $csspage = $wgLang->getNsText( NS_MEDIAWIKI
) . ":" . $this->getSkinName() . ".css";
214 $s = '@import "'.$this->makeUrl($csspage, 'action=raw&ctype=text/css')."\";\n";
216 if ( 1 == $wgUser->getOption( 'underline' ) ) {
217 # Don't override browser settings
221 $s .= "a { text-decoration: none; }\n";
223 if ( 1 == $wgUser->getOption( 'highlightbroken' ) ) {
224 $s .= "a.new, #quickbar a.new { color: #CC2200; }\n";
226 if ( 1 == $wgUser->getOption( 'justify' ) ) {
227 $s .= "#article { text-align: justify; }\n";
232 function getBodyOptions()
234 global $wgUser, $wgTitle, $wgNamespaceBackgrounds, $wgOut, $wgRequest;
236 extract( $wgRequest->getValues( 'oldid', 'redirect', 'diff' ) );
238 if ( 0 != $wgTitle->getNamespace() ) {
239 $a = array( 'bgcolor' => '#ffffec' );
241 else $a = array( 'bgcolor' => '#FFFFFF' );
242 if($wgOut->isArticle() && $wgUser->getOption('editondblclick') &&
243 (!$wgTitle->isProtected() ||
$wgUser->isSysop()) ) {
244 $t = wfMsg( 'editthispage' );
246 if ( !empty($redirect) ) {
247 $red = "&redirect={$redirect}";
249 if ( !empty($oldid) && ! isset( $diff ) ) {
250 $oid = "&oldid={$oldid}";
252 $s = $wgTitle->getFullURL( "action=edit{$oid}{$red}" );
253 $s = 'document.location = "' .$s .'";';
254 $a +
= array ('ondblclick' => $s);
257 $a['onload'] = $wgOut->getOnloadHandler();
261 function getExternalLinkAttributes( $link, $text, $class='' )
263 global $wgUser, $wgOut, $wgLang;
265 $link = urldecode( $link );
266 $link = $wgLang->checkTitleEncoding( $link );
267 $link = str_replace( '_', ' ', $link );
268 $link = wfEscapeHTML( $link );
270 $r = ($class != '') ?
" class='$class'" : " class='external'";
272 if ( 1 == $wgUser->getOption( 'hover' ) ) {
273 $r .= " title=\"{$link}\"";
278 function getInternalLinkAttributes( $link, $text, $broken = false )
280 global $wgUser, $wgOut;
282 $link = urldecode( $link );
283 $link = str_replace( '_', ' ', $link );
284 $link = wfEscapeHTML( $link );
286 if ( $broken == 'stub' ) {
287 $r = ' class="stub"';
288 } else if ( $broken == 'yes' ) {
294 if ( 1 == $wgUser->getOption( 'hover' ) ) {
295 $r .= " title=\"{$link}\"";
300 function getInternalLinkAttributesObj( &$nt, $text, $broken = false )
302 global $wgUser, $wgOut;
304 if ( $broken == 'stub' ) {
305 $r = ' class="stub"';
306 } else if ( $broken == 'yes' ) {
312 if ( 1 == $wgUser->getOption( 'hover' ) ) {
313 $r .= ' title ="' . $nt->getEscapedText() . '"';
324 # This will be called immediately after the <body> tag. Split into
325 # two functions to make it easier to subclass.
327 function beforeContent()
329 global $wgUser, $wgOut;
331 return $this->doBeforeContent();
334 function doBeforeContent()
336 global $wgUser, $wgOut, $wgTitle, $wgLang, $wgSiteNotice;
337 $fname = 'Skin::doBeforeContent';
338 wfProfileIn( $fname );
341 $qb = $this->qbSetting();
343 if( $langlinks = $this->otherLanguages() ) {
349 $borderhack = 'class="top"';
352 $s .= "\n<div id='content'>\n<div id='topbar'>\n" .
353 "<table border='0' cellspacing='0' width='98%'>\n<tr>\n";
356 $left = ($qb == 1 ||
$qb == 3);
357 if($wgLang->isRTL()) $left = !$left;
360 $s .= "<td class='top' align='left' valign='top' rowspan='{$rows}'>\n" .
361 $this->logoText() . '</td>';
363 $s .= $this->getQuickbarCompensator( $rows );
365 $l = $wgLang->isRTL() ?
'right' : 'left';
366 $s .= "<td {$borderhack} align='$l' valign='top'>\n";
368 $s .= $this->topLinks() ;
369 $s .= "<p class='subtitle'>" . $this->pageTitleLinks() . "</p>\n";
371 $r = $wgLang->isRTL() ?
"left" : "right";
372 $s .= "</td>\n<td {$borderhack} valign='top' align='$r' nowrap='nowrap'>";
373 $s .= $this->nameAndLogin();
374 $s .= "\n<br />" . $this->searchForm() . "</td>";
377 $s .= "</tr>\n<tr>\n<td class='top' colspan=\"2\">$langlinks</td>\n";
380 if ( $shove && !$left ) { # Right
381 $s .= $this->getQuickbarCompensator( $rows );
383 $s .= "</tr>\n</table>\n</div>\n";
384 $s .= "\n<div id='article'>\n";
386 if( $wgSiteNotice ) {
387 $s .= "\n<div id='siteNotice'>$wgSiteNotice</div>\n";
389 $s .= $this->pageTitle();
390 $s .= $this->pageSubtitle() ;
391 $s .= $this->getCategories();
392 wfProfileOut( $fname );
396 function getCategoryLinks () {
397 global $wgOut, $wgTitle, $wgUser, $wgParser;
398 global $wgUseCategoryMagic, $wgUseCategoryBrowser, $wgLang;
400 if( !$wgUseCategoryMagic ) return '' ;
401 if( count( $wgOut->mCategoryLinks
) == 0 ) return '';
403 # Taken out so that they will be displayed in previews -- TS
404 #if( !$wgOut->isArticle() ) return '';
406 $t = implode ( ' | ' , $wgOut->mCategoryLinks
) ;
407 $s = $this->makeKnownLink( 'Special:Categories',
408 wfMsg( 'categories' ), 'article=' . urlencode( $wgTitle->getPrefixedDBkey() ) )
411 if($wgUseCategoryBrowser) {
414 $s.= $wgTitle->getAllParentCategories($catstack);
420 function getCategories() {
421 $catlinks=$this->getCategoryLinks();
422 if(!empty($catlinks)) {
423 return "<p class='catlinks'>{$catlinks}</p>";
427 function getQuickbarCompensator( $rows = 1 )
429 return "<td width='152' rowspan='{$rows}'> </td>";
432 # This gets called immediately before the </body> tag.
434 function afterContent()
436 global $wgUser, $wgOut, $wgServer;
437 global $wgTitle, $wgLang;
439 $printfooter = "<div class=\"printfooter\">\n" . $this->printFooter() . "</div>\n";
440 return $printfooter . $this->doAfterContent();
443 function printFooter() {
445 $url = htmlspecialchars( $wgTitle->getFullURL() );
446 return "<p>" . wfMsg( "retrievedfrom", "<a href=\"$url\">$url</a>" ) .
447 "</p>\n\n<p>" . $this->pageStats() . "</p>\n";
450 function doAfterContent()
452 global $wgUser, $wgOut, $wgLang;
453 $fname = 'Skin::doAfterContent';
454 wfProfileIn( $fname );
455 wfProfileIn( $fname.'-1' );
457 $s = "\n</div><br style=\"clear:both\" />\n";
458 $s .= "\n<div id='footer'>";
459 $s .= '<table border="0" cellspacing="0"><tr>';
461 wfProfileOut( $fname.'-1' );
462 wfProfileIn( $fname.'-2' );
464 $qb = $this->qbSetting();
466 $left = ($qb == 1 ||
$qb == 3);
467 if($wgLang->isRTL()) $left = !$left;
469 if ( $shove && $left ) { # Left
470 $s .= $this->getQuickbarCompensator();
472 wfProfileOut( $fname.'-2' );
473 wfProfileIn( $fname.'-3' );
474 $l = $wgLang->isRTL() ?
'right' : 'left';
475 $s .= "<td class='bottom' align='$l' valign='top'>";
477 $s .= $this->bottomLinks();
478 $s .= "\n<br />" . $this->mainPageLink()
479 . ' | ' . $this->aboutLink()
480 . ' | ' . $this->specialLink( 'recentchanges' )
481 . ' | ' . $this->searchForm()
482 . '<br /><span id="pagestats">' . $this->pageStats() . '</span>';
485 if ( $shove && !$left ) { # Right
486 $s .= $this->getQuickbarCompensator();
488 $s .= "</tr></table>\n</div>\n</div>\n";
490 wfProfileOut( $fname.'-3' );
491 wfProfileIn( $fname.'-4' );
492 if ( 0 != $qb ) { $s .= $this->quickBar(); }
493 wfProfileOut( $fname.'-4' );
494 wfProfileOut( $fname );
498 function pageTitleLinks()
500 global $wgOut, $wgTitle, $wgUser, $wgLang, $wgUseApproval, $wgRequest;
502 extract( $wgRequest->getValues( 'oldid', 'diff' ) );
503 $action = $wgRequest->getText( 'action' );
505 $s = $this->printableLink();
506 if ( wfMsg ( 'disclaimers' ) != '-' ) $s .= ' | ' . $this->makeKnownLink( wfMsg( 'disclaimerpage' ), wfMsg( 'disclaimers' ) ) ;
508 if ( $wgOut->isArticleRelated() ) {
509 if ( $wgTitle->getNamespace() == Namespace::getImage() ) {
510 $name = $wgTitle->getDBkey();
511 $link = wfEscapeHTML( Image
::wfImageUrl( $name ) );
512 $style = $this->getInternalLinkAttributes( $link, $name );
513 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>";
515 # This will show the "Approve" link if $wgUseApproval=true;
516 if ( isset ( $wgUseApproval ) && $wgUseApproval )
518 $t = $wgTitle->getDBkey();
519 $name = 'Approve this article' ;
520 $link = "http://test.wikipedia.org/w/magnus/wiki.phtml?title={$t}&action=submit&doit=1" ;
521 #wfEscapeHTML( wfImageUrl( $name ) );
522 $style = $this->getExternalLinkAttributes( $link, $name );
523 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>" ;
526 if ( 'history' == $action ||
isset( $diff ) ||
isset( $oldid ) ) {
527 $s .= ' | ' . $this->makeKnownLink( $wgTitle->getPrefixedText(),
528 wfMsg( 'currentrev' ) );
531 if ( $wgUser->getNewtalk() ) {
532 # do not show "You have new messages" text when we are viewing our
535 if(!(strcmp($wgTitle->getText(),$wgUser->getName()) == 0 &&
536 $wgTitle->getNamespace()==Namespace::getTalk(Namespace::getUser()))) {
537 $n =$wgUser->getName();
538 $tl = $this->makeKnownLink( $wgLang->getNsText(
539 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
540 wfMsg('newmessageslink') );
541 $s.= ' | <strong>'. wfMsg( 'newmessages', $tl ) . '</strong>';
545 $undelete = $this->getUndeleteLink();
546 if( !empty( $undelete ) ) {
547 $s .= ' | '.$undelete;
552 function getUndeleteLink() {
553 global $wgUser, $wgTitle, $wgLang, $action;
554 if( $wgUser->isSysop() &&
555 (($wgTitle->getArticleId() == 0) ||
($action == "history")) &&
556 ($n = $wgTitle->isDeleted() ) ) {
557 return wfMsg( 'thisisdeleted',
558 $this->makeKnownLink(
559 $wgLang->SpecialPage( 'Undelete/' . $wgTitle->getPrefixedDBkey() ),
560 wfMsg( 'restorelink', $n ) ) );
565 function printableLink()
567 global $wgOut, $wgFeedClasses, $wgRequest;
569 $baseurl = $_SERVER['REQUEST_URI'];
570 if( strpos( '?', $baseurl ) == false ) {
575 $baseurl = htmlspecialchars( $baseurl );
576 $printurl = $wgRequest->escapeAppendQuery( 'printable=yes' );
578 $s = "<a href=\"$printurl\">" . wfMsg( 'printableversion' ) . '</a>';
579 if( $wgOut->isSyndicated() ) {
580 foreach( $wgFeedClasses as $format => $class ) {
581 $feedurl = $wgRequest->escapeAppendQuery( "feed=$format" );
582 $s .= " | <a href=\"$feedurl\">{$format}</a>";
590 global $wgOut, $wgTitle, $wgUser;
592 $s = '<h1 class="pagetitle">' . htmlspecialchars( $wgOut->getPageTitle() ) . '</h1>';
593 if($wgUser->getOption( 'editsectiononrightclick' ) && $wgTitle->userCanEdit()) { $s=$this->editSectionScript(0,$s);}
597 function pageSubtitle()
601 $sub = $wgOut->getSubtitle();
603 global $wgExtraSubtitle;
604 $sub = wfMsg( 'fromwikipedia' ) . $wgExtraSubtitle;
606 $subpages = $this->subPageSubtitle();
607 $sub .= !empty($subpages)?
"</p><p class='subpages'>$subpages":'';
608 $s = "<p class='subtitle'>{$sub}</p>\n";
612 function subPageSubtitle()
614 global $wgOut,$wgTitle,$wgNamespacesWithSubpages;
616 if($wgOut->isArticle() && !empty($wgNamespacesWithSubpages[$wgTitle->getNamespace()])) {
617 $ptext=$wgTitle->getPrefixedText();
618 if(preg_match('/\//',$ptext)) {
619 $links = explode('/',$ptext);
622 foreach($links as $link) {
624 if ($c<count($links)) {
625 $growinglink .= $link;
626 $getlink = $this->makeLink( $growinglink, $link );
627 if(preg_match('/class="new"/i',$getlink)) { break; } # this is a hack, but it saves time
631 $subpages .= '< ';
633 $subpages .= $getlink;
642 function nameAndLogin()
644 global $wgUser, $wgTitle, $wgLang, $wgShowIPinHeader, $wgIP;
646 $li = $wgLang->specialPage( 'Userlogin' );
647 $lo = $wgLang->specialPage( 'Userlogout' );
650 if ( 0 == $wgUser->getID() ) {
651 if( $wgShowIPinHeader && isset( $_COOKIE[ini_get('session.name')] ) ) {
654 $tl = $this->makeKnownLink( $wgLang->getNsText(
655 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
656 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
658 $s .= $n . ' ('.$tl.')';
660 $s .= wfMsg('notloggedin');
663 $rt = $wgTitle->getPrefixedURL();
664 if ( 0 == strcasecmp( urlencode( $lo ), $rt ) ) {
666 } else { $q = "returnto={$rt}"; }
668 $s .= "\n<br />" . $this->makeKnownLink( $li,
669 wfMsg( 'login' ), $q );
671 $n = $wgUser->getName();
672 $rt = $wgTitle->getPrefixedURL();
673 $tl = $this->makeKnownLink( $wgLang->getNsText(
674 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
675 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
679 $s .= $this->makeKnownLink( $wgLang->getNsText(
680 Namespace::getUser() ) . ":{$n}", $n ) . "{$tl}<br />" .
681 $this->makeKnownLink( $lo, wfMsg( 'logout' ),
682 "returnto={$rt}" ) . ' | ' .
683 $this->specialLink( 'preferences' );
685 $s .= ' | ' . $this->makeKnownLink( wfMsg( 'helppage' ),
691 function getSearchLink() {
692 $searchPage =& Title
::makeTitle( NS_SPECIAL
, 'Search' );
693 return $searchPage->getLocalURL();
696 function escapeSearchLink() {
697 return htmlspecialchars( $this->getSearchLink() );
700 function searchForm()
703 $search = $wgRequest->getText( 'search' );
705 $s = '<form name="search" class="inline" method="post" action="'
706 . $this->escapeSearchLink() . "\">\n"
707 . '<input type="text" name="search" size="19" value="'
708 . htmlspecialchars(substr($search,0,256)) . "\" />\n"
709 . '<input type="submit" name="go" value="' . wfMsg ('go') . '" /> '
710 . '<input type="submit" name="fulltext" value="' . wfMsg ('search') . "\" />\n</form>";
720 $s = $this->mainPageLink() . $sep
721 . $this->specialLink( 'recentchanges' );
723 if ( $wgOut->isArticleRelated() ) {
724 $s .= $sep . $this->editThisPage()
725 . $sep . $this->historyLink();
727 # Many people don't like this dropdown box
728 #$s .= $sep . $this->specialPagesList();
733 function bottomLinks()
735 global $wgOut, $wgUser, $wgTitle;
739 if ( $wgOut->isArticleRelated() ) {
740 $s .= '<strong>' . $this->editThisPage() . '</strong>';
741 if ( 0 != $wgUser->getID() ) {
742 $s .= $sep . $this->watchThisPage();
744 $s .= $sep . $this->talkLink()
745 . $sep . $this->historyLink()
746 . $sep . $this->whatLinksHere()
747 . $sep . $this->watchPageLinksLink();
749 if ( $wgTitle->getNamespace() == Namespace::getUser()
750 ||
$wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser()) )
753 $id=User
::idFromName($wgTitle->getText());
754 $ip=User
::isIP($wgTitle->getText());
756 if($id ||
$ip) { # both anons and non-anons have contri list
757 $s .= $sep . $this->userContribsLink();
759 if ( 0 != $wgUser->getID() ) { # show only to signed in users
760 if($id) { # can only email non-anons
761 $s .= $sep . $this->emailUserLink();
765 if ( $wgUser->isSysop() && $wgTitle->getArticleId() ) {
766 $s .= "\n<br />" . $this->deleteThisPage() .
767 $sep . $this->protectThisPage() .
768 $sep . $this->moveThisPage();
770 $s .= "<br />\n" . $this->otherLanguages();
777 global $wgOut, $wgLang, $wgArticle, $wgRequest;
778 global $wgDisableCounters, $wgMaxCredits, $wgShowCreditsIfMax;
780 extract( $wgRequest->getValues( 'oldid', 'diff' ) );
781 if ( ! $wgOut->isArticle() ) { return ''; }
782 if ( isset( $oldid ) ||
isset( $diff ) ) { return ''; }
783 if ( 0 == $wgArticle->getID() ) { return ''; }
786 if ( !$wgDisableCounters ) {
787 $count = $wgLang->formatNum( $wgArticle->getCount() );
789 $s = wfMsg( 'viewcount', $count );
793 if (isset($wgMaxCredits) && $wgMaxCredits != 0) {
794 require_once("Credits.php");
795 $s .= ' ' . getCredits($wgArticle, $wgMaxCredits, $wgShowCreditsIfMax);
797 $s .= $this->lastModified();
800 return $s . ' ' . $this->getCopyright();
803 function getCopyright() {
804 global $wgRightsPage, $wgRightsUrl, $wgRightsText, $wgRequest;
807 $oldid = $wgRequest->getVal( 'oldid' );
808 $diff = $wgRequest->getVal( 'diff' );
810 if ( !is_null( $oldid ) && is_null( $diff ) && wfMsg( 'history_copyright' ) !== '-' ) {
811 $msg = 'history_copyright';
817 if( $wgRightsPage ) {
818 $link = $this->makeKnownLink( $wgRightsPage, $wgRightsText );
819 } elseif( $wgRightsUrl ) {
820 $link = $this->makeExternalLink( $wgRightsUrl, $wgRightsText );
825 $out .= wfMsg( $msg, $link );
829 function getCopyrightIcon() {
830 global $wgRightsPage, $wgRightsUrl, $wgRightsText, $wgRightsIcon;
832 if( $wgRightsIcon ) {
833 $icon = htmlspecialchars( $wgRightsIcon );
835 $url = htmlspecialchars( $wgRightsUrl );
836 $out .= '<a href="'.$url.'">';
838 $text = htmlspecialchars( $wgRightsText );
839 $out .= "<img src=\"$icon\" alt='$text' />";
847 function getPoweredBy() {
849 $url = htmlspecialchars( "$wgStylePath/images/poweredby_mediawiki_88x31.png" );
850 $img = '<a href="http://www.mediawiki.org/"><img src="'.$url.'" alt="MediaWiki" /></a>';
854 function lastModified()
856 global $wgLang, $wgArticle;
858 $timestamp = $wgArticle->getTimestamp();
860 $d = $wgLang->timeanddate( $wgArticle->getTimestamp(), true );
861 $s = ' ' . wfMsg( 'lastmodified', $d );
868 function logoText( $align = '' )
870 if ( '' != $align ) { $a = ' align="'.$align.'"'; }
873 $mp = wfMsg( 'mainpage' );
874 $titleObj = Title
::newFromText( $mp );
875 $s = '<a href="' . $titleObj->escapeLocalURL()
876 . '"><img'.$a.' src="'
877 . $this->getLogo() . '" alt="' . "[{$mp}]\" /></a>";
883 global $wgOut, $wgTitle, $wgUser, $wgRequest, $wgLang;
884 global $wgDisableUploads, $wgRemoteUploads;
886 $fname = 'Skin::quickBar';
887 wfProfileIn( $fname );
889 $action = $wgRequest->getText( 'action' );
890 $wpPreview = $wgRequest->getBool( 'wpPreview' );
891 $tns=$wgTitle->getNamespace();
893 $s = "\n<div id='quickbar'>";
894 $s .= "\n" . $this->logoText() . "\n<hr class='sep' />";
897 $s .= $this->mainPageLink()
898 . $sep . $this->specialLink( 'recentchanges' )
899 . $sep . $this->specialLink( 'randompage' );
900 if ($wgUser->getID()) {
901 $s.= $sep . $this->specialLink( 'watchlist' ) ;
902 $s .= $sep .$this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
903 wfMsg( 'mycontris' ), 'target=' . wfUrlencode($wgUser->getName() ) );
906 // only show watchlist link if logged in
907 if ( wfMsg ( 'currentevents' ) != '-' ) $s .= $sep . $this->makeKnownLink( wfMsg( 'currentevents' ), '' ) ;
908 $s .= "\n<br /><hr class='sep' />";
909 $articleExists = $wgTitle->getArticleId();
910 if ( $wgOut->isArticle() ||
$action =='edit' ||
$action =='history' ||
$wpPreview) {
911 if($wgOut->isArticle()) {
912 $s .= '<strong>' . $this->editThisPage() . '</strong>';
913 } else { # backlink to the article in edit or history mode
914 if($articleExists){ # no backlink if no article
917 $text = wfMsg('articlepage');
920 $text = wfMsg('viewtalkpage');
923 $text = wfMsg('userpage');
926 $text = wfMsg('viewtalkpage');
929 $text = wfMsg('wikipediapage');
932 $text = wfMsg('viewtalkpage');
935 $text = wfMsg('imagepage');
938 $text = wfMsg('viewtalkpage');
941 $text= wfMsg('articlepage');
944 $link = $wgTitle->getText();
945 if ($nstext = $wgLang->getNsText($tns) ) { # add namespace if necessary
946 $link = $nstext . ':' . $link ;
949 $s .= $this->makeLink( $link, $text );
950 } elseif( $wgTitle->getNamespace() != Namespace::getSpecial() ) {
951 # we just throw in a "New page" text to tell the user that he's in edit mode,
952 # and to avoid messing with the separator that is prepended to the next item
953 $s .= '<strong>' . wfMsg('newpage') . '</strong>';
959 if( $tns%2
&& $action!='edit' && !$wpPreview) {
960 $s.= '<br />'.$this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg('postcomment'),'action=edit§ion=new');
964 watching could cause problems in edit mode:
965 if user edits article, then loads "watch this article" in background and then saves
966 article with "Watch this article" checkbox disabled, the article is transparently
967 unwatched. Therefore we do not show the "Watch this page" link in edit mode
969 if ( 0 != $wgUser->getID() && $articleExists) {
970 if($action!='edit' && $action != 'submit' )
972 $s .= $sep . $this->watchThisPage();
974 if ( $wgTitle->userCanEdit() )
975 $s .= $sep . $this->moveThisPage();
977 if ( $wgUser->isSysop() and $articleExists ) {
978 $s .= $sep . $this->deleteThisPage() .
979 $sep . $this->protectThisPage();
981 $s .= $sep . $this->talkLink();
982 if ($articleExists && $action !='history') {
983 $s .= $sep . $this->historyLink();
985 $s.=$sep . $this->whatLinksHere();
987 if($wgOut->isArticleRelated()) {
988 $s .= $sep . $this->watchPageLinksLink();
991 if ( Namespace::getUser() == $wgTitle->getNamespace()
992 ||
$wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser())
995 $id=User
::idFromName($wgTitle->getText());
996 $ip=User
::isIP($wgTitle->getText());
999 $s .= $sep . $this->userContribsLink();
1001 if ( 0 != $wgUser->getID() ) {
1002 if($id) { # can only email real users
1003 $s .= $sep . $this->emailUserLink();
1007 $s .= "\n<br /><hr class='sep' />";
1010 if ( 0 != $wgUser->getID() && ( !$wgDisableUploads ||
$wgRemoteUploads ) ) {
1011 $s .= $this->specialLink( 'upload' ) . $sep;
1013 $s .= $this->specialLink( 'specialpages' )
1014 . $sep . $this->bugReportsLink();
1016 global $wgSiteSupportPage;
1017 if( $wgSiteSupportPage ) {
1018 $s .= "\n<br /><a href=\"" . htmlspecialchars( $wgSiteSupportPage ) .
1019 '" class="internal">' . wfMsg( 'sitesupport' ) . '</a>';
1022 $s .= "\n<br /></div>\n";
1023 wfProfileOut( $fname );
1027 function specialPagesList()
1029 global $wgUser, $wgOut, $wgLang, $wgServer, $wgRedirectScript;
1030 require_once('SpecialPage.php');
1032 $pages = SpecialPage
::getPages();
1034 foreach ( $pages[''] as $name => $page ) {
1035 $a[$name] = $page->getDescription();
1037 if ( $wgUser->isSysop() )
1039 foreach ( $pages['sysop'] as $name => $page ) {
1040 $a[$name] = $page->getDescription();
1043 if ( $wgUser->isDeveloper() )
1045 foreach ( $pages['developer'] as $name => $page ) {
1046 $a[$name] = $page->getDescription() ;
1049 $go = wfMsg( 'go' );
1050 $sp = wfMsg( 'specialpages' );
1051 $spp = $wgLang->specialPage( 'Specialpages' );
1053 $s = '<form id="specialpages" method="get" class="inline" ' .
1054 'action="' . htmlspecialchars( "{$wgServer}{$wgRedirectScript}" ) . "\">\n";
1055 $s .= "<select name=\"wpDropdown\">\n";
1056 $s .= "<option value=\"{$spp}\">{$sp}</option>\n";
1058 foreach ( $a as $name => $desc ) {
1059 $p = $wgLang->specialPage( $name );
1060 $s .= "<option value=\"{$p}\">{$desc}</option>\n";
1062 $s .= "</select>\n";
1063 $s .= "<input type='submit' value=\"{$go}\" name='redirect' />\n";
1068 function mainPageLink()
1070 $mp = wfMsg( 'mainpage' );
1071 $s = $this->makeKnownLink( $mp, $mp );
1075 function copyrightLink()
1077 $s = $this->makeKnownLink( wfMsg( 'copyrightpage' ),
1078 wfMsg( 'copyrightpagename' ) );
1082 function aboutLink()
1084 $s = $this->makeKnownLink( wfMsg( 'aboutpage' ),
1085 wfMsg( 'aboutwikipedia' ) );
1090 function disclaimerLink()
1092 $s = $this->makeKnownLink( wfMsg( 'disclaimerpage' ),
1093 wfMsg( 'disclaimers' ) );
1097 function editThisPage()
1099 global $wgOut, $wgTitle, $wgRequest;
1101 $oldid = $wgRequest->getVal( 'oldid' );
1102 $diff = $wgRequest->getVal( 'diff' );
1103 $redirect = $wgRequest->getVal( 'redirect' );
1105 if ( ! $wgOut->isArticleRelated() ) {
1106 $s = wfMsg( 'protectedpage' );
1108 $n = $wgTitle->getPrefixedText();
1109 if ( $wgTitle->userCanEdit() ) {
1110 $t = wfMsg( 'editthispage' );
1112 #$t = wfMsg( "protectedpage" );
1113 $t = wfMsg( 'viewsource' );
1117 if ( !is_null( $redirect ) ) { $red = "&redirect={$redirect}"; }
1118 if ( $oldid && ! isset( $diff ) ) {
1119 $oid = "&oldid={$oldid}";
1121 $s = $this->makeKnownLink( $n, $t, "action=edit{$oid}{$red}" );
1126 function deleteThisPage()
1128 global $wgUser, $wgOut, $wgTitle, $wgRequest;
1130 $diff = $wgRequest->getVal( 'diff' );
1131 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
1132 $n = $wgTitle->getPrefixedText();
1133 $t = wfMsg( 'deletethispage' );
1135 $s = $this->makeKnownLink( $n, $t, 'action=delete' );
1142 function protectThisPage()
1144 global $wgUser, $wgOut, $wgTitle, $wgRequest;
1146 $diff = $wgRequest->getVal( 'diff' );
1147 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
1148 $n = $wgTitle->getPrefixedText();
1150 if ( $wgTitle->isProtected() ) {
1151 $t = wfMsg( 'unprotectthispage' );
1152 $q = 'action=unprotect';
1154 $t = wfMsg( 'protectthispage' );
1155 $q = 'action=protect';
1157 $s = $this->makeKnownLink( $n, $t, $q );
1164 function watchThisPage()
1166 global $wgUser, $wgOut, $wgTitle;
1168 if ( $wgOut->isArticleRelated() ) {
1169 $n = $wgTitle->getPrefixedText();
1171 if ( $wgTitle->userIsWatching() ) {
1172 $t = wfMsg( 'unwatchthispage' );
1173 $q = 'action=unwatch';
1175 $t = wfMsg( 'watchthispage' );
1176 $q = 'action=watch';
1178 $s = $this->makeKnownLink( $n, $t, $q );
1180 $s = wfMsg( 'notanarticle' );
1185 function moveThisPage()
1187 global $wgTitle, $wgLang;
1189 if ( $wgTitle->userCanEdit() ) {
1190 $s = $this->makeKnownLink( $wgLang->specialPage( 'Movepage' ),
1191 wfMsg( 'movethispage' ), 'target=' . $wgTitle->getPrefixedURL() );
1192 } // no message if page is protected - would be redundant
1196 function historyLink()
1200 $s = $this->makeKnownLink( $wgTitle->getPrefixedText(),
1201 wfMsg( 'history' ), 'action=history' );
1205 function whatLinksHere()
1207 global $wgTitle, $wgLang;
1209 $s = $this->makeKnownLink( $wgLang->specialPage( 'Whatlinkshere' ),
1210 wfMsg( 'whatlinkshere' ), 'target=' . $wgTitle->getPrefixedURL() );
1214 function userContribsLink()
1216 global $wgTitle, $wgLang;
1218 $s = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
1219 wfMsg( 'contributions' ), 'target=' . $wgTitle->getPartialURL() );
1223 function emailUserLink()
1225 global $wgTitle, $wgLang;
1227 $s = $this->makeKnownLink( $wgLang->specialPage( 'Emailuser' ),
1228 wfMsg( 'emailuser' ), 'target=' . $wgTitle->getPartialURL() );
1232 function watchPageLinksLink()
1234 global $wgOut, $wgTitle, $wgLang;
1236 if ( ! $wgOut->isArticleRelated() ) {
1237 $s = '(' . wfMsg( 'notanarticle' ) . ')';
1239 $s = $this->makeKnownLink( $wgLang->specialPage(
1240 'Recentchangeslinked' ), wfMsg( 'recentchangeslinked' ),
1241 'target=' . $wgTitle->getPrefixedURL() );
1246 function otherLanguages()
1248 global $wgOut, $wgLang, $wgTitle, $wgUseNewInterlanguage;
1250 $a = $wgOut->getLanguageLinks();
1251 if ( 0 == count( $a ) ) {
1252 if ( !$wgUseNewInterlanguage ) return '';
1253 $ns = $wgLang->getNsIndex ( $wgTitle->getNamespace () ) ;
1254 if ( $ns != 0 AND $ns != 1 ) return '' ;
1256 $x = 'mode=addlink&xt='.$wgTitle->getDBkey() ;
1257 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1258 wfMsg( 'intl' ) , $x );
1261 if ( !$wgUseNewInterlanguage ) {
1262 $s = wfMsg( 'otherlanguages' ) . ': ';
1264 global $wgLanguageCode ;
1265 $x = 'mode=zoom&xt='.$wgTitle->getDBkey() ;
1266 $x .= '&xl='.$wgLanguageCode ;
1267 $s = $this->makeKnownLink( $wgLang->specialPage( 'Intl' ),
1268 wfMsg( 'otherlanguages' ) , $x ) . ': ' ;
1271 $s = wfMsg( 'otherlanguages' ) . ': ';
1273 if($wgLang->isRTL()) $s .= '<span dir="LTR">';
1274 foreach( $a as $l ) {
1275 if ( ! $first ) { $s .= ' | '; }
1278 $nt = Title
::newFromText( $l );
1279 $url = $nt->getFullURL();
1280 $text = $wgLang->getLanguageName( $nt->getInterwiki() );
1282 if ( '' == $text ) { $text = $l; }
1283 $style = $this->getExternalLinkAttributes( $l, $text );
1284 $s .= "<a href=\"{$url}\"{$style}>{$text}</a>";
1286 if($wgLang->isRTL()) $s .= '</span>';
1290 function bugReportsLink()
1292 $s = $this->makeKnownLink( wfMsg( 'bugreportspage' ),
1293 wfMsg( 'bugreports' ) );
1299 global $wgLinkCache;
1300 $t1 = Title
::newFromText( gmdate( 'F j' ) );
1301 $t2 = Title
::newFromText( gmdate( 'Y' ) );
1303 $wgLinkCache->suspend();
1304 $id = $t1->getArticleID();
1305 $wgLinkCache->resume();
1308 $s = $this->makeBrokenLink( $t1->getText() );
1310 $s = $this->makeKnownLink( $t1->getText() );
1314 $wgLinkCache->suspend();
1315 $id = $t2->getArticleID();
1316 $wgLinkCache->resume();
1319 $s .= $this->makeBrokenLink( $t2->getText() );
1321 $s .= $this->makeKnownLink( $t2->getText() );
1328 global $wgLang, $wgTitle, $wgLinkCache;
1330 $tns = $wgTitle->getNamespace();
1331 if ( -1 == $tns ) { return ''; }
1333 $pn = $wgTitle->getText();
1334 $tp = wfMsg( 'talkpage' );
1335 if ( Namespace::isTalk( $tns ) ) {
1336 $lns = Namespace::getSubject( $tns );
1339 $text = wfMsg('articlepage');
1342 $text = wfMsg('userpage');
1345 $text = wfMsg('wikipediapage');
1348 $text = wfMsg('imagepage');
1351 $text= wfMsg('articlepage');
1355 $lns = Namespace::getTalk( $tns );
1358 $n = $wgLang->getNsText( $lns );
1359 if ( '' == $n ) { $link = $pn; }
1360 else { $link = $n.':'.$pn; }
1362 $wgLinkCache->suspend();
1363 $s = $this->makeLink( $link, $text );
1364 $wgLinkCache->resume();
1369 function commentLink()
1371 global $wgLang, $wgTitle, $wgLinkCache;
1373 $tns = $wgTitle->getNamespace();
1374 if ( -1 == $tns ) { return ''; }
1376 $lns = ( Namespace::isTalk( $tns ) ) ?
$tns : Namespace::getTalk( $tns );
1378 # assert Namespace::isTalk( $lns )
1380 $n = $wgLang->getNsText( $lns );
1381 $pn = $wgTitle->getText();
1385 $wgLinkCache->suspend();
1386 $s = $this->makeKnownLink($link, wfMsg('postcomment'), 'action=edit§ion=new');
1387 $wgLinkCache->resume();
1392 # After all the page content is transformed into HTML, it makes
1393 # a final pass through here for things like table backgrounds.
1395 function transformContent( $text )
1400 # Note: This function MUST call getArticleID() on the link,
1401 # otherwise the cache won't get updated properly. See LINKCACHE.DOC.
1403 function makeLink( $title, $text = '', $query = '', $trail = '' ) {
1404 wfProfileIn( 'Skin::makeLink' );
1405 $nt = Title
::newFromText( $title );
1407 $result = $this->makeLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1409 wfDebug( 'Invalid title passed to Skin::makeLink(): "'.$title."\"\n" );
1410 $result = $text == "" ?
$title : $text;
1413 wfProfileOut( 'Skin::makeLink' );
1417 function makeKnownLink( $title, $text = '', $query = '', $trail = '', $prefix = '',$aprops = '') {
1418 $nt = Title
::newFromText( $title );
1420 return $this->makeKnownLinkObj( Title
::newFromText( $title ), $text, $query, $trail, $prefix , $aprops );
1422 wfDebug( 'Invalid title passed to Skin::makeKnownLink(): "'.$title."\"\n" );
1423 return $text == '' ?
$title : $text;
1427 function makeBrokenLink( $title, $text = '', $query = '', $trail = '' ) {
1428 $nt = Title
::newFromText( $title );
1430 return $this->makeBrokenLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1432 wfDebug( 'Invalid title passed to Skin::makeBrokenLink(): "'.$title."\"\n" );
1433 return $text == '' ?
$title : $text;
1437 function makeStubLink( $title, $text = '', $query = '', $trail = '' ) {
1438 $nt = Title
::newFromText( $title );
1440 return $this->makeStubLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1442 wfDebug( 'Invalid title passed to Skin::makeStubLink(): "'.$title."\"\n" );
1443 return $text == '' ?
$title : $text;
1447 # Pass a title object, not a title string
1448 function makeLinkObj( &$nt, $text= '', $query = '', $trail = '', $prefix = '' )
1450 global $wgOut, $wgUser;
1451 $fname = 'Skin::makeLinkObj';
1455 return "<!-- ERROR -->{$prefix}{$text}{$trail}";
1457 if ( $nt->isExternal() ) {
1458 $u = $nt->getFullURL();
1459 $link = $nt->getPrefixedURL();
1460 if ( '' == $text ) { $text = $nt->getPrefixedText(); }
1461 $style = $this->getExternalLinkAttributes( $link, $text, 'extiw' );
1464 if ( '' != $trail ) {
1465 if ( preg_match( '/^([a-z]+)(.*)$$/sD', $trail, $m ) ) {
1470 $retVal = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1471 } elseif ( 0 == $nt->getNamespace() && "" == $nt->getText() ) {
1472 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1473 } elseif ( ( -1 == $nt->getNamespace() ) ||
1474 ( Namespace::getImage() == $nt->getNamespace() ) ) {
1475 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1477 if ( $this->postParseLinkColour() ) {
1479 if ( '' != $trail ) {
1480 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1486 # Allows wiki to bypass using linkcache, see OutputPage::parseLinkHolders()
1487 $retVal = '<!--LINK ' . implode( ' ', array( $nt->getNamespace(), $nt->getDBkey(),
1488 $query, $prefix . $text . $inside ) ) . "-->{$trail}";
1490 # Work out link colour immediately
1491 $aid = $nt->getArticleID() ;
1493 $retVal = $this->makeBrokenLinkObj( $nt, $text, $query, $trail, $prefix );
1495 $threshold = $wgUser->getOption('stubthreshold') ;
1496 if ( $threshold > 0 ) {
1497 $dbr =& wfGetDB( DB_SLAVE
);
1498 $s = $dbr->selectRow( 'cur', array( 'LENGTH(cur_text) AS x', 'cur_namespace',
1499 'cur_is_redirect' ), array( 'cur_id' => $aid ), $fname ) ;
1500 if ( $s !== false ) {
1502 if ( $s->cur_is_redirect
OR $s->cur_namespace
!= 0 ) {
1503 $size = $threshold*2 ; # Really big
1505 $dbr->freeResult( $res );
1507 $size = $threshold*2 ; # Really big
1512 if ( $size < $threshold ) {
1513 $retVal = $this->makeStubLinkObj( $nt, $text, $query, $trail, $prefix );
1515 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1523 # Pass a title object, not a title string
1524 function makeKnownLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' , $aprops = '')
1526 global $wgOut, $wgTitle, $wgInputEncoding;
1528 $fname = 'Skin::makeKnownLinkObj';
1529 wfProfileIn( $fname );
1531 if ( !is_object( $nt ) ) {
1534 $link = $nt->getPrefixedURL();
1536 if ( '' == $link ) {
1538 if ( '' == $text ) {
1539 $text = htmlspecialchars( $nt->getFragment() );
1542 $u = $nt->escapeLocalURL( $query );
1544 if ( '' != $nt->getFragment() ) {
1545 $anchor = urlencode( do_html_entity_decode( str_replace(' ', '_', $nt->getFragment()), ENT_COMPAT
, $wgInputEncoding ) );
1546 $replacearray = array(
1550 $u .= '#' . str_replace(array_keys($replacearray),array_values($replacearray),$anchor);
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;
1785 $manual_thumb = "" ;
1787 foreach( $part as $key => $val ) {
1788 $val_parts = explode ( "=" , $val , 2 ) ;
1789 $left_part = array_shift ( $val_parts ) ;
1790 if ( ! is_null( $mwThumb->matchVariableStartToEnd($val) ) ) {
1792 } elseif ( count ( $val_parts ) == 1 && ! is_null( $mwThumb->matchVariableStartToEnd($left_part) ) ) {
1793 # use manually specified thumbnail
1795 $manual_thumb = array_shift ( $val_parts ) ;
1796 } elseif ( ! is_null( $mwRight->matchVariableStartToEnd($val) ) ) {
1797 # remember to set an alignment, don't render immediately
1799 } elseif ( ! is_null( $mwLeft->matchVariableStartToEnd($val) ) ) {
1800 # remember to set an alignment, don't render immediately
1802 } elseif ( ! is_null( $mwCenter->matchVariableStartToEnd($val) ) ) {
1803 # remember to set an alignment, don't render immediately
1805 } elseif ( ! is_null( $mwNone->matchVariableStartToEnd($val) ) ) {
1806 # remember to set an alignment, don't render immediately
1808 } elseif ( ! is_null( $match = $mwWidth->matchVariableStartToEnd($val) ) ) {
1809 # $match is the image width in pixels
1810 if ( preg_match( '/^([0-9]*)x([0-9]*)$/', $match, $m ) ) {
1811 $width = intval( $m[1] );
1812 $height = intval( $m[2] );
1814 $width = intval($match);
1816 } elseif ( ! is_null( $mwFramed->matchVariableStartToEnd($val) ) ) {
1820 if ( 'center' == $align )
1822 $prefix = '<span style="text-align: center">';
1823 $postfix = '</span>';
1827 if ( $thumb ||
$framed ) {
1829 # Create a thumbnail. Alignment depends on language
1830 # writing direction, # right aligned for left-to-right-
1831 # languages ("Western languages"), left-aligned
1832 # for right-to-left-languages ("Semitic languages")
1834 # If thumbnail width has not been provided, it is set
1835 # here to 180 pixels
1836 if ( $align == '' ) {
1837 $align = $wgLang->isRTL() ?
'left' : 'right';
1839 if ( ! isset($width) ) {
1842 return $prefix.$this->makeThumbLinkObj( $img, $alt, $align, $width, $height, $framed, $manual_thumb ).$postfix;
1844 } elseif ( isset($width) ) {
1846 # Create a resized image, without the additional thumbnail
1849 if ( ( ! $height === false )
1850 && ( $img->getHeight() * $width / $img->getWidth() > $height ) ) {
1851 print "height=$height<br>\nimg->getHeight() = ".$img->getHeight()."<br>\n";
1852 print 'rescaling by factor '. $height / $img->getHeight() . "<br>\n";
1853 $width = $img->getWidth() * $height / $img->getHeight();
1855 if ( '' == $manual_thumb ) $url = $img->createThumb( $width );
1857 } # endif $wgUseImageResize
1859 if ( empty( $alt ) ) {
1860 $alt = preg_replace( '/\.(.+?)^/', '', $img->getName() );
1862 $alt = htmlspecialchars( $alt );
1864 $u = $nt->escapeLocalURL();
1867 $s = wfMsg( 'missingimage', $img->getName() );
1868 $s .= "<br>{$alt}<br>{$url}<br>\n";
1870 $s = '<a href="'.$u.'" class="image" title="'.$alt.'">' .
1871 '<img src="'.$url.'" alt="'.$alt.'" /></a>';
1873 if ( '' != $align ) {
1874 $s = "<div class=\"float{$align}\"><span>{$s}</span></div>";
1876 return str_replace("\n", ' ',$prefix.$s.$postfix);
1879 # Make HTML for a thumbnail including image, border and caption
1880 # $img is an Image object
1881 function makeThumbLinkObj( $img, $label = '', $align = 'right', $boxwidth = 180, $boxheight=false, $framed=false , $manual_thumb = "" ) {
1882 global $wgStylePath, $wgLang;
1883 # $image = Title::makeTitle( Namespace::getImage(), $name );
1884 $url = $img->getURL();
1886 #$label = htmlspecialchars( $label );
1887 $alt = preg_replace( '/<[^>]*>/', '', $label);
1888 $alt = htmlspecialchars( $alt );
1890 if ( $img->exists() )
1892 $width = $img->getWidth();
1893 $height = $img->getHeight();
1895 $width = $height = 200;
1899 // Use image dimensions, don't scale
1901 $oboxwidth = $boxwidth +
2;
1902 $boxheight = $height;
1905 $h = intval( $height/($width/$boxwidth) );
1906 $oboxwidth = $boxwidth +
2;
1907 if ( ( ! $boxheight === false ) && ( $h > $boxheight ) )
1909 $boxwidth *= $boxheight/$h;
1913 if ( '' == $manual_thumb ) $thumbUrl = $img->createThumb( $boxwidth );
1916 if ( $manual_thumb != '' ) # Use manually specified thumbnail
1918 $manual_title = Title
::makeTitle( Namespace::getImage(), $manual_thumb ); #new Title ( $manual_thumb ) ;
1919 $manual_img = Image
::newFromTitle( $manual_title );
1920 $thumbUrl = $manual_img->getURL();
1921 if ( $manual_img->exists() )
1923 $width = $manual_img->getWidth();
1924 $height = $manual_img->getHeight();
1925 $boxwidth = $width ;
1926 $boxheight = $height ;
1927 $oboxwidth = $boxwidth +
2 ;
1931 $u = $img->getEscapeLocalURL();
1933 $more = htmlspecialchars( wfMsg( 'thumbnail-more' ) );
1934 $magnifyalign = $wgLang->isRTL() ?
'left' : 'right';
1935 $textalign = $wgLang->isRTL() ?
' style="text-align:right"' : '';
1937 $s = "<div class=\"thumb t{$align}\"><div style=\"width:{$oboxwidth}px;\">";
1938 if ( $thumbUrl == '' ) {
1939 $s .= wfMsg( 'missingimage', $img->getName() );
1942 $s .= '<a href="'.$u.'" class="internal" title="'.$alt.'">'.
1943 '<img src="'.$thumbUrl.'" alt="'.$alt.'" ' .
1944 'width="'.$boxwidth.'" height="'.$boxheight.'" /></a>';
1948 $zoomicon = '<div class="magnify" style="float:'.$magnifyalign.'">'.
1949 '<a href="'.$u.'" class="internal" title="'.$more.'">'.
1950 '<img src="'.$wgStylePath.'/images/magnify-clip.png" ' .
1951 'width="15" height="11" alt="'.$more.'" /></a></div>';
1954 $s .= ' <div class="thumbcaption" '.$textalign.'>'.$zoomicon.$label."</div></div></div>";
1955 return str_replace("\n", ' ', $s);
1958 function makeMediaLink( $name, $url, $alt = "" ) {
1959 $nt = Title
::makeTitle( Namespace::getMedia(), $name );
1960 return $this->makeMediaLinkObj( $nt, $alt );
1963 function makeMediaLinkObj( $nt, $alt = "" )
1965 if ( ! isset( $nt ) )
1967 ### HOTFIX. Instead of breaking, return empty string.
1970 $name = $nt->getDBKey();
1971 $url = Image
::wfImageUrl( $name );
1972 if ( empty( $alt ) ) {
1973 $alt = preg_replace( '/\.(.+?)^/', '', $name );
1976 $u = htmlspecialchars( $url );
1977 $s = "<a href=\"{$u}\" class='internal' title=\"{$alt}\">{$alt}</a>";
1982 function specialLink( $name, $key = "" )
1986 if ( '' == $key ) { $key = strtolower( $name ); }
1987 $pn = $wgLang->ucfirst( $name );
1988 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1992 function makeExternalLink( $url, $text, $escape = true ) {
1993 $style = $this->getExternalLinkAttributes( $url, $text );
1994 $url = htmlspecialchars( $url );
1996 $text = htmlspecialchars( $text );
1998 return '<a href="'.$url.'"'.$style.'>'.$text.'</a>';
2001 # Called by history lists and recent changes
2004 # Returns text for the start of the tabular part of RC
2005 function beginRecentChangesList()
2007 $this->rc_cache
= array() ;
2008 $this->rcMoveIndex
= 0;
2009 $this->rcCacheIndex
= 0 ;
2010 $this->lastdate
= '';
2011 $this->rclistOpen
= false;
2015 function beginImageHistoryList()
2017 $s = "\n<h2>" . wfMsg( 'imghistory' ) . "</h2>\n" .
2018 "<p>" . wfMsg( 'imghistlegend' ) . "</p>\n".'<ul class="special">';
2022 # Returns text for the end of RC
2023 # If enhanced RC is in use, returns pretty much all the text
2024 function endRecentChangesList()
2026 $s = $this->recentChangesBlock() ;
2027 if( $this->rclistOpen
) {
2033 # Enhanced RC ungrouped line
2034 function recentChangesBlockLine ( $rcObj )
2036 global $wgStylePath, $wgLang ;
2038 # Get rc_xxxx variables
2039 extract( $rcObj->mAttribs
) ;
2040 $curIdEq = 'curid='.$rc_cur_id;
2045 $r .= '<img src="'.$wgStylePath.'/images/Arr_.png" width="12" height="12" border="0" />' ;
2048 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2049 $r .= ' ';
2051 # M & N (minor & new)
2052 $M = wfMsg( 'minoreditletter' );
2053 $N = wfMsg( 'newpageletter' );
2055 if ( $rc_type == RC_NEW
) {
2068 $r .= ' '.$rcObj->timestamp
.' ' ;
2072 $link = $rcObj->link
;
2073 if ( $rcObj->watched
) $link = '<strong>'.$link.'</strong>' ;
2078 $r .= $rcObj->difflink
;
2082 $r .= $this->makeKnownLinkObj( $rcObj->getTitle(), wfMsg( 'hist' ), $curIdEq.'&action=history' );
2085 $r .= ') . . '.$rcObj->userlink
;
2086 $r .= $rcObj->usertalklink
;
2089 if ( $rc_comment != '' && $rc_type != RC_MOVE
&& $rc_type != RC_MOVE_OVER_REDIRECT
) {
2090 $rc_comment=$this->formatComment($rc_comment);
2091 $r .= $wgLang->emphasize( ' ('.$rc_comment.')' );
2099 function recentChangesBlockGroup ( $block )
2101 global $wgStylePath, $wgLang ;
2104 $M = wfMsg( 'minoreditletter' );
2105 $N = wfMsg( 'newpageletter' );
2107 # Collate list of users
2109 $userlinks = array () ;
2110 foreach ( $block AS $rcObj ) {
2111 $oldid = $rcObj->mAttribs
['rc_last_oldid'];
2112 if ( $rcObj->mAttribs
['rc_new'] ) $isnew = true ;
2113 $u = $rcObj->userlink
;
2114 if ( !isset ( $userlinks[$u] ) ) $userlinks[$u] = 0 ;
2118 # Sort the list and convert to text
2119 krsort ( $userlinks ) ;
2120 asort ( $userlinks ) ;
2122 foreach ( $userlinks as $userlink => $count) {
2124 if ( $count > 1 ) $text .= " ({$count}×)" ;
2125 array_push ( $users , $text ) ;
2127 $users = ' <font size="-1">['.implode('; ',$users).']</font>' ;
2130 $rci = 'RCI'.$this->rcCacheIndex
;
2131 $rcl = 'RCL'.$this->rcCacheIndex
;
2132 $rcm = 'RCM'.$this->rcCacheIndex
;
2133 $toggleLink = "javascript:toggleVisibility('$rci','$rcm','$rcl')" ;
2134 $arrowdir = $wgLang->isRTL() ?
'l' : 'r';
2135 $tl = '<span id="'.$rcm.'"><a href="'.$toggleLink.'"><img src="'.$wgStylePath.'/images/Arr_'.$arrowdir.'.png" width="12" height="12" /></a></span>' ;
2136 $tl .= '<span id="'.$rcl.'" style="display:none"><a href="'.$toggleLink.'"><img src="'.$wgStylePath.'/images/Arr_d.png" width="12" height="12" /></a></span>' ;
2142 if ( $isnew ) $r .= $N ;
2143 else $r .= ' ' ;
2144 $r .= ' ' ; # Minor
2147 $r .= ' '.$block[0]->timestamp
.' ' ;
2151 $link = $block[0]->link
;
2152 if ( $block[0]->watched
) $link = '<strong>'.$link.'</strong>' ;
2155 $curIdEq = 'curid=' . $block[0]->mAttribs
['rc_cur_id'];
2156 if ( $block[0]->mAttribs
['rc_type'] != RC_LOG
) {
2158 $r .= ' ('.count($block).' ' ;
2159 if ( $isnew ) $r .= wfMsg('changes');
2160 else $r .= $this->makeKnownLinkObj( $block[0]->getTitle() , wfMsg('changes') ,
2161 $curIdEq.'&diff=0&oldid='.$oldid ) ;
2165 $r .= $this->makeKnownLinkObj( $block[0]->getTitle(), wfMsg( 'history' ), $curIdEq.'&action=history' );
2173 $r .= '<div id="'.$rci.'" style="display:none">' ;
2174 foreach ( $block AS $rcObj ) {
2175 # Get rc_xxxx variables
2176 extract( $rcObj->mAttribs
);
2178 $r .= '<img src="'.$wgStylePath.'/images/Arr_.png" width="12" height="12" />';
2179 $r .= '<tt> ' ;
2180 if ( $rc_new ) $r .= $N ;
2181 else $r .= ' ' ;
2182 if ( $rc_minor ) $r .= $M ;
2183 else $r .= ' ' ;
2187 if ( $rc_last_oldid != 0 ) {
2188 $o = 'oldid='.$rc_last_oldid ;
2190 if ( $rc_type == RC_LOG
) {
2191 $link = $rcObj->timestamp
;
2193 $link = $this->makeKnownLinkObj( $rcObj->getTitle(), $rcObj->timestamp
, "{$curIdEq}&$o" ) ;
2195 $link = '<tt>'.$link.'</tt>' ;
2199 $r .= $rcObj->curlink
;
2201 $r .= $rcObj->lastlink
;
2202 $r .= ') . . '.$rcObj->userlink
;
2203 $r .= $rcObj->usertalklink
;
2204 if ( $rc_comment != '' ) {
2205 $rc_comment=$this->formatComment($rc_comment);
2206 $r .= $wgLang->emphasize( ' ('.$rc_comment.')' ) ;
2212 $this->rcCacheIndex++
;
2216 # If enhanced RC is in use, this function takes the previously cached
2217 # RC lines, arranges them, and outputs the HTML
2218 function recentChangesBlock ()
2220 global $wgStylePath ;
2221 if ( count ( $this->rc_cache
) == 0 ) return '' ;
2223 foreach ( $this->rc_cache
AS $secureName => $block ) {
2224 if ( count ( $block ) < 2 ) {
2225 $blockOut .= $this->recentChangesBlockLine ( array_shift ( $block ) ) ;
2227 $blockOut .= $this->recentChangesBlockGroup ( $block ) ;
2231 return '<div>'.$blockOut.'</div>' ;
2234 # Called in a loop over all displayed RC entries
2235 # Either returns the line, or caches it for later use
2236 function recentChangesLine( &$rc, $watched = false )
2239 $usenew = $wgUser->getOption( 'usenewrc' );
2241 $line = $this->recentChangesLineNew ( $rc, $watched ) ;
2243 $line = $this->recentChangesLineOld ( $rc, $watched ) ;
2247 function recentChangesLineOld( &$rc, $watched = false )
2249 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds;
2251 # Extract DB fields into local scope
2252 extract( $rc->mAttribs
);
2253 $curIdEq = 'curid=' . $rc_cur_id;
2255 # Make date header if necessary
2256 $date = $wgLang->date( $rc_timestamp, true);
2258 if ( $date != $this->lastdate
) {
2259 if ( '' != $this->lastdate
) { $s .= "</ul>\n"; }
2260 $s .= "<h4>{$date}</h4>\n<ul class='special'>";
2261 $this->lastdate
= $date;
2262 $this->rclistOpen
= true;
2266 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2268 $s .= '(' . wfMsg( 'diff' ) . ') (';
2270 $s .= $this->makeKnownLinkObj( $rc->getMovedToTitle(), wfMsg( 'hist' ), 'action=history' ) .
2273 # "[[x]] moved to [[y]]"
2274 if ( $rc_type == RC_MOVE
) {
2277 $msg = '1movedto2_redir';
2279 $s .= wfMsg( $msg, $this->makeKnownLinkObj( $rc->getTitle(), '', 'redirect=no' ),
2280 $this->makeKnownLinkObj( $rc->getMovedToTitle(), '' ) );
2283 if ( $rc_type == RC_NEW ||
$rc_type == RC_LOG
) {
2284 $diffLink = wfMsg( 'diff' );
2286 $diffLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'diff' ),
2287 $curIdEq.'&diff='.$rc_this_oldid.'&oldid='.$rc_last_oldid ,'' ,'' , ' tabindex="'.$rc->counter
.'"');
2289 $s .= '('.$diffLink.') (';
2292 $s .= $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'hist' ), $curIdEq.'&action=history' );
2295 # M and N (minor and new)
2296 $M = wfMsg( 'minoreditletter' );
2297 $N = wfMsg( 'newpageletter' );
2298 if ( $rc_minor ) { $s .= ' <strong>'.$M.'</strong>'; }
2299 if ( $rc_type == RC_NEW
) { $s .= '<strong>'.$N.'</strong>'; }
2302 $articleLink = $this->makeKnownLinkObj( $rc->getTitle(), '' );
2305 $articleLink = '<strong>'.$articleLink.'</strong>';
2307 $s .= ' '.$articleLink;
2312 $s .= '; ' . $wgLang->time( $rc_timestamp, true, $wgRCSeconds ) . ' . . ';
2314 # User link (or contributions for unregistered users)
2315 if ( 0 == $rc_user ) {
2316 $userLink = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
2317 $rc_user_text, 'target=' . $rc_user_text );
2319 $userLink = $this->makeLink( $wgLang->getNsText( NS_USER
) . ':'.$rc_user_text, $rc_user_text );
2324 $talkname=$wgLang->getNsText(NS_TALK
); # use the shorter name
2325 global $wgDisableAnonTalk;
2326 if( 0 == $rc_user && $wgDisableAnonTalk ) {
2329 $utns=$wgLang->getNsText(NS_USER_TALK
);
2330 $userTalkLink= $this->makeLink($utns . ':'.$rc_user_text, $talkname );
2334 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2335 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2336 'Blockip' ), wfMsg( 'blocklink' ), 'ip='.$rc_user_text );
2340 if($userTalkLink) $userTalkLink .= ' | ';
2341 $userTalkLink .= $blockLink;
2343 if($userTalkLink) $s.=' ('.$userTalkLink.')';
2346 if ( '' != $rc_comment && '*' != $rc_comment && $rc_type != RC_MOVE
&& $rc_type != RC_MOVE_OVER_REDIRECT
) {
2347 $rc_comment=$this->formatComment($rc_comment);
2348 $s .= $wgLang->emphasize(' (' . $rc_comment . ')');
2355 # function recentChangesLineNew( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched = false, $oldid = 0 , $diffid = 0 )
2356 function recentChangesLineNew( &$baseRC, $watched = false )
2358 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds;
2360 # Create a specialised object
2361 $rc = RCCacheEntry
::newFromParent( $baseRC ) ;
2363 # Extract fields from DB into the function scope (rc_xxxx variables)
2364 extract( $rc->mAttribs
);
2365 $curIdEq = 'curid=' . $rc_cur_id;
2367 # If it's a new day, add the headline and flush the cache
2368 $date = $wgLang->date( $rc_timestamp, true);
2370 if ( $date != $this->lastdate
) {
2371 # Process current cache
2372 $ret = $this->recentChangesBlock () ;
2373 $this->rc_cache
= array() ;
2374 $ret .= "<h4>{$date}</h4>\n";
2375 $this->lastdate
= $date;
2379 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2380 if ( $rc_type == RC_MOVE
) {
2383 $msg = "1movedto2_redir";
2385 $clink = wfMsg( $msg, $this->makeKnownLinkObj( $rc->getTitle(), '', 'redirect=no' ),
2386 $this->makeKnownLinkObj( $rc->getMovedToTitle(), '' ) );
2388 $clink = $this->makeKnownLinkObj( $rc->getTitle(), '' ) ;
2391 $time = $wgLang->time( $rc_timestamp, true, $wgRCSeconds );
2392 $rc->watched
= $watched ;
2393 $rc->link
= $clink ;
2394 $rc->timestamp
= $time;
2396 # Make "cur" and "diff" links
2397 if ( ( $rc_type == RC_NEW
&& $rc_this_oldid == 0 ) ||
$rc_type == RC_LOG ||
$rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2398 $curLink = wfMsg( 'cur' );
2399 $diffLink = wfMsg( 'diff' );
2401 $query = $curIdEq.'&diff=0&oldid='.$rc_this_oldid;
2402 $aprops = ' tabindex="'.$baseRC->counter
.'"';
2403 $curLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'cur' ), $query, '' ,'' , $aprops );
2404 $diffLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'diff'), $query, '' ,'' , $aprops );
2408 $titleObj = $rc->getTitle();
2409 if ( $rc_last_oldid == 0 ||
$rc_type == RC_LOG ||
$rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2410 $lastLink = wfMsg( 'last' );
2412 $lastLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'last' ),
2413 $curIdEq.'&diff='.$rc_this_oldid.'&oldid='.$rc_last_oldid );
2416 # Make user link (or user contributions for unregistered users)
2417 if ( 0 == $rc_user ) {
2418 $userLink = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
2419 $rc_user_text, 'target=' . $rc_user_text );
2421 $userLink = $this->makeLink( $wgLang->getNsText(
2422 Namespace::getUser() ) . ':'.$rc_user_text, $rc_user_text );
2425 $rc->userlink
= $userLink ;
2426 $rc->lastlink
= $lastLink ;
2427 $rc->curlink
= $curLink ;
2428 $rc->difflink
= $diffLink;
2431 # Make user talk link
2432 $utns=$wgLang->getNsText(NS_USER_TALK
);
2433 $talkname=$wgLang->getNsText(NS_TALK
); # use the shorter name
2434 $userTalkLink= $this->makeLink($utns . ':'.$rc_user_text, $talkname );
2436 global $wgDisableAnonTalk;
2437 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2438 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2439 'Blockip' ), wfMsg( 'blocklink' ), 'ip='.$rc_user_text );
2440 if( $wgDisableAnonTalk )
2441 $rc->usertalklink
= ' ('.$blockLink.')';
2443 $rc->usertalklink
= ' ('.$userTalkLink.' | '.$blockLink.')';
2445 if( $wgDisableAnonTalk && ($rc_user == 0) )
2446 $rc->usertalklink
= '';
2448 $rc->usertalklink
= ' ('.$userTalkLink.')';
2451 # Put accumulated information into the cache, for later display
2452 # Page moves go on their own line
2453 $title = $rc->getTitle();
2454 $secureName = $title->getPrefixedDBkey();
2455 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2456 # Use an @ character to prevent collision with page names
2457 $this->rc_cache
['@@' . ($this->rcMoveIndex++
)] = array($rc);
2459 if ( !isset ( $this->rc_cache
[$secureName] ) ) $this->rc_cache
[$secureName] = array() ;
2460 array_push ( $this->rc_cache
[$secureName] , $rc ) ;
2465 function endImageHistoryList()
2471 /* This function is called by all recent changes variants, by the page history,
2472 and by the user contributions list. It is responsible for formatting edit
2473 comments. It escapes any HTML in the comment, but adds some CSS to format
2474 auto-generated comments (from section editing) and formats [[wikilinks]].
2475 Main author: Erik Möller (moeller@scireview.de)
2477 function formatComment($comment)
2480 $comment=wfEscapeHTML($comment);
2482 # The pattern for autogen comments is / * foo * /, which makes for
2484 # We look for all comments, match any text before and after the comment,
2485 # add a separator where needed and format the comment itself with CSS
2486 while (preg_match('/(.*)\/\*\s*(.*?)\s*\*\/(.*)/', $comment,$match)) {
2491 if($pre) { $auto = $sep.' '.$auto; }
2492 if($post) { $auto .= ' '.$sep; }
2493 $auto='<span class="autocomment">'.$auto.'</span>';
2494 $comment=$pre.$auto.$post;
2497 # format regular and media links - all other wiki formatting
2499 $medians = $wgLang->getNsText(Namespace::getMedia()).':';
2500 while(preg_match('/\[\[(.*?)(\|(.*?))*\]\]/',$comment,$match)) {
2501 # Handle link renaming [[foo|text]] will show link as "text"
2502 if(isset($match[3]) ) {
2507 if ( preg_match( '/^' . $medians . '(.*)$/i', $match[1], $submatch ) ) {
2509 $comment = preg_replace( '/\[\[(.*?)\]\]/', $this->makeMediaLink( $submatch[1], "", $text ),
2512 # Other kind of link
2513 $comment = preg_replace('/\[\[(.*?)\]\]/', $this->makeLink( $match[1], $match[1] ),
2520 function imageHistoryLine( $iscur, $timestamp, $img, $user, $usertext, $size, $description )
2522 global $wgUser, $wgLang, $wgTitle;
2524 $datetime = $wgLang->timeanddate( $timestamp, true );
2525 $del = wfMsg( 'deleteimg' );
2526 $delall = wfMsg( 'deleteimgcompletely' );
2527 $cur = wfMsg( 'cur' );
2530 $url = Image
::wfImageUrl( $img );
2532 if ( $wgUser->isSysop() ) {
2533 $link = $wgTitle->escapeLocalURL( 'image=' . $wgTitle->getPartialURL() .
2535 $style = $this->getInternalLinkAttributes( $link, $delall );
2537 $dlink = '<a href="'.$link.'"'.$style.'>'.$delall.'</a>';
2542 $url = wfEscapeHTML( wfImageArchiveUrl( $img ) );
2543 if( $wgUser->getID() != 0 && $wgTitle->userCanEdit() ) {
2544 $rlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2545 wfMsg( 'revertimg' ), 'action=revert&oldimage=' .
2546 urlencode( $img ) );
2547 $dlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2548 $del, 'action=delete&oldimage=' . urlencode( $img ) );
2550 # Having live active links for non-logged in users
2551 # means that bots and spiders crawling our site can
2552 # inadvertently change content. Baaaad idea.
2553 $rlink = wfMsg( 'revertimg' );
2558 $userlink = $usertext;
2560 $userlink = $this->makeLink( $wgLang->getNsText( Namespace::getUser() ) .
2561 ':'.$usertext, $usertext );
2563 $nbytes = wfMsg( 'nbytes', $size );
2564 $style = $this->getInternalLinkAttributes( $url, $datetime );
2566 $s = "<li> ({$dlink}) ({$rlink}) <a href=\"{$url}\"{$style}>{$datetime}</a>"
2567 . " . . {$userlink} ({$nbytes})";
2569 if ( '' != $description && '*' != $description ) {
2570 $sk=$wgUser->getSkin();
2571 $s .= $wgLang->emphasize(' (' . $sk->formatComment($description) . ')');
2577 function tocIndent($level) {
2578 return str_repeat( '<div class="tocindent">'."\n", $level>0 ?
$level : 0 );
2581 function tocUnindent($level) {
2582 return str_repeat( "</div>\n", $level>0 ?
$level : 0 );
2585 # parameter level defines if we are on an indentation level
2586 function tocLine( $anchor, $tocline, $level ) {
2587 $link = '<a href="#'.$anchor.'">'.$tocline.'</a><br />';
2591 return '<div class="tocline">'.$link."</div>\n";
2596 function tocTable($toc) {
2597 # note to CSS fanatics: putting this in a div does not work -- div won't auto-expand
2598 # try min-width & co when somebody gets a chance
2599 $hideline = ' <script type="text/javascript">showTocToggle("' . addslashes( wfMsg('showtoc') ) . '","' . addslashes( wfMsg('hidetoc') ) . '")</script>';
2601 '<table border="0" id="toc"><tr id="toctitle"><td align="center">'."\n".
2602 '<b>'.wfMsg('toc').'</b>' .
2604 '</td></tr><tr id="tocinside"><td>'."\n".
2605 $toc."</td></tr></table>\n";
2608 # These two do not check for permissions: check $wgTitle->userCanEdit before calling them
2609 function editSectionScript( $section, $head ) {
2610 global $wgTitle, $wgRequest;
2611 if( $wgRequest->getInt( 'oldid' ) && ( $wgRequest->getVal( 'diff' ) != '0' ) ) {
2614 $url = $wgTitle->escapeLocalURL( 'action=edit§ion='.$section );
2615 return '<span oncontextmenu=\'document.location="'.$url.'";return false;\'>'.$head.'</span>';
2618 function editSectionLink( $section ) {
2620 global $wgTitle, $wgUser, $wgLang;
2622 if( $wgRequest->getInt( 'oldid' ) && ( $wgRequest->getVal( 'diff' ) != '0' ) ) {
2623 # Section edit links would be out of sync on an old page.
2624 # But, if we're diffing to the current page, they'll be
2629 $editurl = '§ion='.$section;
2630 $url = $this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg('editsection'),'action=edit'.$editurl);
2632 if( $wgLang->isRTL() ) {
2634 $nearside = 'right';
2639 return "<div class=\"editsection\" style=\"float:$farside;margin-$nearside:5px;\">[".$url."]</div>";
2643 // This function is called by EditPage.php and shows a bulletin board style
2644 // toolbar for common editing functions. It can be disabled in the user preferences.
2645 // The necsesary JavaScript code can be found in style/wikibits.js.
2646 function getEditToolbar() {
2647 global $wgStylePath, $wgLang, $wgMimeType;
2649 // toolarray an array of arrays which each include the filename of
2650 // the button image (without path), the opening tag, the closing tag,
2651 // and optionally a sample text that is inserted between the two when no
2652 // selection is highlighted.
2653 // The tip text is shown when the user moves the mouse over the button.
2655 // Already here are accesskeys (key), which are not used yet until someone
2656 // can figure out a way to make them work in IE. However, we should make
2657 // sure these keys are not defined on the edit page.
2659 array( 'image'=>'button_bold.png',
2662 'sample'=>wfMsg('bold_sample'),
2663 'tip'=>wfMsg('bold_tip'),
2666 array( "image"=>"button_italic.png",
2669 "sample"=>wfMsg("italic_sample"),
2670 "tip"=>wfMsg("italic_tip"),
2673 array( "image"=>"button_link.png",
2676 "sample"=>wfMsg("link_sample"),
2677 "tip"=>wfMsg("link_tip"),
2680 array( "image"=>"button_extlink.png",
2683 "sample"=>wfMsg("extlink_sample"),
2684 "tip"=>wfMsg("extlink_tip"),
2687 array( "image"=>"button_headline.png",
2690 "sample"=>wfMsg("headline_sample"),
2691 "tip"=>wfMsg("headline_tip"),
2694 array( "image"=>"button_image.png",
2695 "open"=>"[[".$wgLang->getNsText(NS_IMAGE
).":",
2697 "sample"=>wfMsg("image_sample"),
2698 "tip"=>wfMsg("image_tip"),
2701 array( "image"=>"button_media.png",
2702 "open"=>"[[".$wgLang->getNsText(NS_MEDIA
).":",
2704 "sample"=>wfMsg("media_sample"),
2705 "tip"=>wfMsg("media_tip"),
2708 array( "image"=>"button_math.png",
2709 "open"=>"\\<math\\>",
2710 "close"=>"\\</math\\>",
2711 "sample"=>wfMsg("math_sample"),
2712 "tip"=>wfMsg("math_tip"),
2715 array( "image"=>"button_nowiki.png",
2716 "open"=>"\\<nowiki\\>",
2717 "close"=>"\\</nowiki\\>",
2718 "sample"=>wfMsg("nowiki_sample"),
2719 "tip"=>wfMsg("nowiki_tip"),
2722 array( "image"=>"button_sig.png",
2726 "tip"=>wfMsg("sig_tip"),
2729 array( "image"=>"button_hr.png",
2730 "open"=>"\\n----\\n",
2733 "tip"=>wfMsg("hr_tip"),
2737 $toolbar ="<script type='text/javascript'>\n/*<![CDATA[*/\n";
2739 $toolbar.="document.writeln(\"<div id='toolbar'>\");\n";
2740 foreach($toolarray as $tool) {
2742 $image=$wgStylePath.'/images/'.$tool['image'];
2743 $open=$tool['open'];
2744 $close=$tool['close'];
2745 $sample = addslashes( $tool['sample'] );
2747 // Note that we use the tip both for the ALT tag and the TITLE tag of the image.
2748 // Older browsers show a "speedtip" type message only for ALT.
2749 // Ideally these should be different, realistically they
2750 // probably don't need to be.
2751 $tip = addslashes( $tool['tip'] );
2753 #$key = $tool["key"];
2755 $toolbar.="addButton('$image','$tip','$open','$close','$sample');\n";
2758 $toolbar.="addInfobox('" . addslashes( wfMsg( "infobox" ) ) . "','" . addslashes(wfMsg("infobox_alert")) . "');\n";
2759 $toolbar.="document.writeln(\"</div>\");\n";
2761 $toolbar.="/*]]>*/\n</script>";