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 printSource() {
445 $url = htmlspecialchars( $wgTitle->getFullURL() );
446 return wfMsg( "retrievedfrom", "<a href=\"$url\">$url</a>" );
449 function printFooter() {
450 return "<p>" . $this->printSource() .
451 "</p>\n\n<p>" . $this->pageStats() . "</p>\n";
454 function doAfterContent()
456 global $wgUser, $wgOut, $wgLang;
457 $fname = 'Skin::doAfterContent';
458 wfProfileIn( $fname );
459 wfProfileIn( $fname.'-1' );
461 $s = "\n</div><br style=\"clear:both\" />\n";
462 $s .= "\n<div id='footer'>";
463 $s .= '<table border="0" cellspacing="0"><tr>';
465 wfProfileOut( $fname.'-1' );
466 wfProfileIn( $fname.'-2' );
468 $qb = $this->qbSetting();
470 $left = ($qb == 1 ||
$qb == 3);
471 if($wgLang->isRTL()) $left = !$left;
473 if ( $shove && $left ) { # Left
474 $s .= $this->getQuickbarCompensator();
476 wfProfileOut( $fname.'-2' );
477 wfProfileIn( $fname.'-3' );
478 $l = $wgLang->isRTL() ?
'right' : 'left';
479 $s .= "<td class='bottom' align='$l' valign='top'>";
481 $s .= $this->bottomLinks();
482 $s .= "\n<br />" . $this->mainPageLink()
483 . ' | ' . $this->aboutLink()
484 . ' | ' . $this->specialLink( 'recentchanges' )
485 . ' | ' . $this->searchForm()
486 . '<br /><span id="pagestats">' . $this->pageStats() . '</span>';
489 if ( $shove && !$left ) { # Right
490 $s .= $this->getQuickbarCompensator();
492 $s .= "</tr></table>\n</div>\n</div>\n";
494 wfProfileOut( $fname.'-3' );
495 wfProfileIn( $fname.'-4' );
496 if ( 0 != $qb ) { $s .= $this->quickBar(); }
497 wfProfileOut( $fname.'-4' );
498 wfProfileOut( $fname );
502 function pageTitleLinks()
504 global $wgOut, $wgTitle, $wgUser, $wgLang, $wgUseApproval, $wgRequest;
506 extract( $wgRequest->getValues( 'oldid', 'diff' ) );
507 $action = $wgRequest->getText( 'action' );
509 $s = $this->printableLink();
510 if ( wfMsg ( 'disclaimers' ) != '-' ) $s .= ' | ' . $this->makeKnownLink( wfMsg( 'disclaimerpage' ), wfMsg( 'disclaimers' ) ) ;
512 if ( $wgOut->isArticleRelated() ) {
513 if ( $wgTitle->getNamespace() == Namespace::getImage() ) {
514 $name = $wgTitle->getDBkey();
515 $link = wfEscapeHTML( Image
::wfImageUrl( $name ) );
516 $style = $this->getInternalLinkAttributes( $link, $name );
517 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>";
519 # This will show the "Approve" link if $wgUseApproval=true;
520 if ( isset ( $wgUseApproval ) && $wgUseApproval )
522 $t = $wgTitle->getDBkey();
523 $name = 'Approve this article' ;
524 $link = "http://test.wikipedia.org/w/magnus/wiki.phtml?title={$t}&action=submit&doit=1" ;
525 #wfEscapeHTML( wfImageUrl( $name ) );
526 $style = $this->getExternalLinkAttributes( $link, $name );
527 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>" ;
530 if ( 'history' == $action ||
isset( $diff ) ||
isset( $oldid ) ) {
531 $s .= ' | ' . $this->makeKnownLink( $wgTitle->getPrefixedText(),
532 wfMsg( 'currentrev' ) );
535 if ( $wgUser->getNewtalk() ) {
536 # do not show "You have new messages" text when we are viewing our
539 if(!(strcmp($wgTitle->getText(),$wgUser->getName()) == 0 &&
540 $wgTitle->getNamespace()==Namespace::getTalk(Namespace::getUser()))) {
541 $n =$wgUser->getName();
542 $tl = $this->makeKnownLink( $wgLang->getNsText(
543 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
544 wfMsg('newmessageslink') );
545 $s.= ' | <strong>'. wfMsg( 'newmessages', $tl ) . '</strong>';
549 $undelete = $this->getUndeleteLink();
550 if( !empty( $undelete ) ) {
551 $s .= ' | '.$undelete;
556 function getUndeleteLink() {
557 global $wgUser, $wgTitle, $wgLang, $action;
558 if( $wgUser->isSysop() &&
559 (($wgTitle->getArticleId() == 0) ||
($action == "history")) &&
560 ($n = $wgTitle->isDeleted() ) ) {
561 return wfMsg( 'thisisdeleted',
562 $this->makeKnownLink(
563 $wgLang->SpecialPage( 'Undelete/' . $wgTitle->getPrefixedDBkey() ),
564 wfMsg( 'restorelink', $n ) ) );
569 function printableLink()
571 global $wgOut, $wgFeedClasses, $wgRequest;
573 $baseurl = $_SERVER['REQUEST_URI'];
574 if( strpos( '?', $baseurl ) == false ) {
579 $baseurl = htmlspecialchars( $baseurl );
580 $printurl = $wgRequest->escapeAppendQuery( 'printable=yes' );
582 $s = "<a href=\"$printurl\">" . wfMsg( 'printableversion' ) . '</a>';
583 if( $wgOut->isSyndicated() ) {
584 foreach( $wgFeedClasses as $format => $class ) {
585 $feedurl = $wgRequest->escapeAppendQuery( "feed=$format" );
586 $s .= " | <a href=\"$feedurl\">{$format}</a>";
594 global $wgOut, $wgTitle, $wgUser;
596 $s = '<h1 class="pagetitle">' . htmlspecialchars( $wgOut->getPageTitle() ) . '</h1>';
597 if($wgUser->getOption( 'editsectiononrightclick' ) && $wgTitle->userCanEdit()) { $s=$this->editSectionScript(0,$s);}
601 function pageSubtitle()
605 $sub = $wgOut->getSubtitle();
607 global $wgExtraSubtitle;
608 $sub = wfMsg( 'fromwikipedia' ) . $wgExtraSubtitle;
610 $subpages = $this->subPageSubtitle();
611 $sub .= !empty($subpages)?
"</p><p class='subpages'>$subpages":'';
612 $s = "<p class='subtitle'>{$sub}</p>\n";
616 function subPageSubtitle()
618 global $wgOut,$wgTitle,$wgNamespacesWithSubpages;
620 if($wgOut->isArticle() && !empty($wgNamespacesWithSubpages[$wgTitle->getNamespace()])) {
621 $ptext=$wgTitle->getPrefixedText();
622 if(preg_match('/\//',$ptext)) {
623 $links = explode('/',$ptext);
626 foreach($links as $link) {
628 if ($c<count($links)) {
629 $growinglink .= $link;
630 $getlink = $this->makeLink( $growinglink, $link );
631 if(preg_match('/class="new"/i',$getlink)) { break; } # this is a hack, but it saves time
635 $subpages .= '< ';
637 $subpages .= $getlink;
646 function nameAndLogin()
648 global $wgUser, $wgTitle, $wgLang, $wgShowIPinHeader, $wgIP;
650 $li = $wgLang->specialPage( 'Userlogin' );
651 $lo = $wgLang->specialPage( 'Userlogout' );
654 if ( 0 == $wgUser->getID() ) {
655 if( $wgShowIPinHeader && isset( $_COOKIE[ini_get('session.name')] ) ) {
658 $tl = $this->makeKnownLink( $wgLang->getNsText(
659 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
660 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
662 $s .= $n . ' ('.$tl.')';
664 $s .= wfMsg('notloggedin');
667 $rt = $wgTitle->getPrefixedURL();
668 if ( 0 == strcasecmp( urlencode( $lo ), $rt ) ) {
670 } else { $q = "returnto={$rt}"; }
672 $s .= "\n<br />" . $this->makeKnownLink( $li,
673 wfMsg( 'login' ), $q );
675 $n = $wgUser->getName();
676 $rt = $wgTitle->getPrefixedURL();
677 $tl = $this->makeKnownLink( $wgLang->getNsText(
678 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
679 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
683 $s .= $this->makeKnownLink( $wgLang->getNsText(
684 Namespace::getUser() ) . ":{$n}", $n ) . "{$tl}<br />" .
685 $this->makeKnownLink( $lo, wfMsg( 'logout' ),
686 "returnto={$rt}" ) . ' | ' .
687 $this->specialLink( 'preferences' );
689 $s .= ' | ' . $this->makeKnownLink( wfMsg( 'helppage' ),
695 function getSearchLink() {
696 $searchPage =& Title
::makeTitle( NS_SPECIAL
, 'Search' );
697 return $searchPage->getLocalURL();
700 function escapeSearchLink() {
701 return htmlspecialchars( $this->getSearchLink() );
704 function searchForm()
707 $search = $wgRequest->getText( 'search' );
709 $s = '<form name="search" class="inline" method="post" action="'
710 . $this->escapeSearchLink() . "\">\n"
711 . '<input type="text" name="search" size="19" value="'
712 . htmlspecialchars(substr($search,0,256)) . "\" />\n"
713 . '<input type="submit" name="go" value="' . wfMsg ('go') . '" /> '
714 . '<input type="submit" name="fulltext" value="' . wfMsg ('search') . "\" />\n</form>";
724 $s = $this->mainPageLink() . $sep
725 . $this->specialLink( 'recentchanges' );
727 if ( $wgOut->isArticleRelated() ) {
728 $s .= $sep . $this->editThisPage()
729 . $sep . $this->historyLink();
731 # Many people don't like this dropdown box
732 #$s .= $sep . $this->specialPagesList();
737 function bottomLinks()
739 global $wgOut, $wgUser, $wgTitle;
743 if ( $wgOut->isArticleRelated() ) {
744 $s .= '<strong>' . $this->editThisPage() . '</strong>';
745 if ( 0 != $wgUser->getID() ) {
746 $s .= $sep . $this->watchThisPage();
748 $s .= $sep . $this->talkLink()
749 . $sep . $this->historyLink()
750 . $sep . $this->whatLinksHere()
751 . $sep . $this->watchPageLinksLink();
753 if ( $wgTitle->getNamespace() == Namespace::getUser()
754 ||
$wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser()) )
757 $id=User
::idFromName($wgTitle->getText());
758 $ip=User
::isIP($wgTitle->getText());
760 if($id ||
$ip) { # both anons and non-anons have contri list
761 $s .= $sep . $this->userContribsLink();
763 if ( 0 != $wgUser->getID() ) { # show only to signed in users
764 if($id) { # can only email non-anons
765 $s .= $sep . $this->emailUserLink();
769 if ( $wgUser->isSysop() && $wgTitle->getArticleId() ) {
770 $s .= "\n<br />" . $this->deleteThisPage() .
771 $sep . $this->protectThisPage() .
772 $sep . $this->moveThisPage();
774 $s .= "<br />\n" . $this->otherLanguages();
781 global $wgOut, $wgLang, $wgArticle, $wgRequest;
782 global $wgDisableCounters, $wgMaxCredits, $wgShowCreditsIfMax;
784 extract( $wgRequest->getValues( 'oldid', 'diff' ) );
785 if ( ! $wgOut->isArticle() ) { return ''; }
786 if ( isset( $oldid ) ||
isset( $diff ) ) { return ''; }
787 if ( 0 == $wgArticle->getID() ) { return ''; }
790 if ( !$wgDisableCounters ) {
791 $count = $wgLang->formatNum( $wgArticle->getCount() );
793 $s = wfMsg( 'viewcount', $count );
797 if (isset($wgMaxCredits) && $wgMaxCredits != 0) {
798 require_once("Credits.php");
799 $s .= ' ' . getCredits($wgArticle, $wgMaxCredits, $wgShowCreditsIfMax);
801 $s .= $this->lastModified();
804 return $s . ' ' . $this->getCopyright();
807 function getCopyright() {
808 global $wgRightsPage, $wgRightsUrl, $wgRightsText, $wgRequest;
811 $oldid = $wgRequest->getVal( 'oldid' );
812 $diff = $wgRequest->getVal( 'diff' );
814 if ( !is_null( $oldid ) && is_null( $diff ) && wfMsg( 'history_copyright' ) !== '-' ) {
815 $msg = 'history_copyright';
821 if( $wgRightsPage ) {
822 $link = $this->makeKnownLink( $wgRightsPage, $wgRightsText );
823 } elseif( $wgRightsUrl ) {
824 $link = $this->makeExternalLink( $wgRightsUrl, $wgRightsText );
829 $out .= wfMsg( $msg, $link );
833 function getCopyrightIcon() {
834 global $wgRightsPage, $wgRightsUrl, $wgRightsText, $wgRightsIcon;
836 if( $wgRightsIcon ) {
837 $icon = htmlspecialchars( $wgRightsIcon );
839 $url = htmlspecialchars( $wgRightsUrl );
840 $out .= '<a href="'.$url.'">';
842 $text = htmlspecialchars( $wgRightsText );
843 $out .= "<img src=\"$icon\" alt='$text' />";
851 function getPoweredBy() {
853 $url = htmlspecialchars( "$wgStylePath/images/poweredby_mediawiki_88x31.png" );
854 $img = '<a href="http://www.mediawiki.org/"><img src="'.$url.'" alt="MediaWiki" /></a>';
858 function lastModified()
860 global $wgLang, $wgArticle;
862 $timestamp = $wgArticle->getTimestamp();
864 $d = $wgLang->timeanddate( $wgArticle->getTimestamp(), true );
865 $s = ' ' . wfMsg( 'lastmodified', $d );
872 function logoText( $align = '' )
874 if ( '' != $align ) { $a = ' align="'.$align.'"'; }
877 $mp = wfMsg( 'mainpage' );
878 $titleObj = Title
::newFromText( $mp );
879 $s = '<a href="' . $titleObj->escapeLocalURL()
880 . '"><img'.$a.' src="'
881 . $this->getLogo() . '" alt="' . "[{$mp}]\" /></a>";
887 global $wgOut, $wgTitle, $wgUser, $wgRequest, $wgLang;
888 global $wgDisableUploads, $wgRemoteUploads;
890 $fname = 'Skin::quickBar';
891 wfProfileIn( $fname );
893 $action = $wgRequest->getText( 'action' );
894 $wpPreview = $wgRequest->getBool( 'wpPreview' );
895 $tns=$wgTitle->getNamespace();
897 $s = "\n<div id='quickbar'>";
898 $s .= "\n" . $this->logoText() . "\n<hr class='sep' />";
901 $s .= $this->mainPageLink()
902 . $sep . $this->specialLink( 'recentchanges' )
903 . $sep . $this->specialLink( 'randompage' );
904 if ($wgUser->getID()) {
905 $s.= $sep . $this->specialLink( 'watchlist' ) ;
906 $s .= $sep .$this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
907 wfMsg( 'mycontris' ), 'target=' . wfUrlencode($wgUser->getName() ) );
910 // only show watchlist link if logged in
911 if ( wfMsg ( 'currentevents' ) != '-' ) $s .= $sep . $this->makeKnownLink( wfMsg( 'currentevents' ), '' ) ;
912 $s .= "\n<br /><hr class='sep' />";
913 $articleExists = $wgTitle->getArticleId();
914 if ( $wgOut->isArticle() ||
$action =='edit' ||
$action =='history' ||
$wpPreview) {
915 if($wgOut->isArticle()) {
916 $s .= '<strong>' . $this->editThisPage() . '</strong>';
917 } else { # backlink to the article in edit or history mode
918 if($articleExists){ # no backlink if no article
921 $text = wfMsg('articlepage');
924 $text = wfMsg('viewtalkpage');
927 $text = wfMsg('userpage');
930 $text = wfMsg('viewtalkpage');
933 $text = wfMsg('wikipediapage');
936 $text = wfMsg('viewtalkpage');
939 $text = wfMsg('imagepage');
942 $text = wfMsg('viewtalkpage');
945 $text= wfMsg('articlepage');
948 $link = $wgTitle->getText();
949 if ($nstext = $wgLang->getNsText($tns) ) { # add namespace if necessary
950 $link = $nstext . ':' . $link ;
953 $s .= $this->makeLink( $link, $text );
954 } elseif( $wgTitle->getNamespace() != Namespace::getSpecial() ) {
955 # we just throw in a "New page" text to tell the user that he's in edit mode,
956 # and to avoid messing with the separator that is prepended to the next item
957 $s .= '<strong>' . wfMsg('newpage') . '</strong>';
963 if( $tns%2
&& $action!='edit' && !$wpPreview) {
964 $s.= '<br />'.$this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg('postcomment'),'action=edit§ion=new');
968 watching could cause problems in edit mode:
969 if user edits article, then loads "watch this article" in background and then saves
970 article with "Watch this article" checkbox disabled, the article is transparently
971 unwatched. Therefore we do not show the "Watch this page" link in edit mode
973 if ( 0 != $wgUser->getID() && $articleExists) {
974 if($action!='edit' && $action != 'submit' )
976 $s .= $sep . $this->watchThisPage();
978 if ( $wgTitle->userCanEdit() )
979 $s .= $sep . $this->moveThisPage();
981 if ( $wgUser->isSysop() and $articleExists ) {
982 $s .= $sep . $this->deleteThisPage() .
983 $sep . $this->protectThisPage();
985 $s .= $sep . $this->talkLink();
986 if ($articleExists && $action !='history') {
987 $s .= $sep . $this->historyLink();
989 $s.=$sep . $this->whatLinksHere();
991 if($wgOut->isArticleRelated()) {
992 $s .= $sep . $this->watchPageLinksLink();
995 if ( Namespace::getUser() == $wgTitle->getNamespace()
996 ||
$wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser())
999 $id=User
::idFromName($wgTitle->getText());
1000 $ip=User
::isIP($wgTitle->getText());
1003 $s .= $sep . $this->userContribsLink();
1005 if ( 0 != $wgUser->getID() ) {
1006 if($id) { # can only email real users
1007 $s .= $sep . $this->emailUserLink();
1011 $s .= "\n<br /><hr class='sep' />";
1014 if ( 0 != $wgUser->getID() && ( !$wgDisableUploads ||
$wgRemoteUploads ) ) {
1015 $s .= $this->specialLink( 'upload' ) . $sep;
1017 $s .= $this->specialLink( 'specialpages' )
1018 . $sep . $this->bugReportsLink();
1020 global $wgSiteSupportPage;
1021 if( $wgSiteSupportPage ) {
1022 $s .= "\n<br /><a href=\"" . htmlspecialchars( $wgSiteSupportPage ) .
1023 '" class="internal">' . wfMsg( 'sitesupport' ) . '</a>';
1026 $s .= "\n<br /></div>\n";
1027 wfProfileOut( $fname );
1031 function specialPagesList()
1033 global $wgUser, $wgOut, $wgLang, $wgServer, $wgRedirectScript;
1034 require_once('SpecialPage.php');
1036 $pages = SpecialPage
::getPages();
1038 foreach ( $pages[''] as $name => $page ) {
1039 $a[$name] = $page->getDescription();
1041 if ( $wgUser->isSysop() )
1043 foreach ( $pages['sysop'] as $name => $page ) {
1044 $a[$name] = $page->getDescription();
1047 if ( $wgUser->isDeveloper() )
1049 foreach ( $pages['developer'] as $name => $page ) {
1050 $a[$name] = $page->getDescription() ;
1053 $go = wfMsg( 'go' );
1054 $sp = wfMsg( 'specialpages' );
1055 $spp = $wgLang->specialPage( 'Specialpages' );
1057 $s = '<form id="specialpages" method="get" class="inline" ' .
1058 'action="' . htmlspecialchars( "{$wgServer}{$wgRedirectScript}" ) . "\">\n";
1059 $s .= "<select name=\"wpDropdown\">\n";
1060 $s .= "<option value=\"{$spp}\">{$sp}</option>\n";
1062 foreach ( $a as $name => $desc ) {
1063 $p = $wgLang->specialPage( $name );
1064 $s .= "<option value=\"{$p}\">{$desc}</option>\n";
1066 $s .= "</select>\n";
1067 $s .= "<input type='submit' value=\"{$go}\" name='redirect' />\n";
1072 function mainPageLink()
1074 $mp = wfMsg( 'mainpage' );
1075 $s = $this->makeKnownLink( $mp, $mp );
1079 function copyrightLink()
1081 $s = $this->makeKnownLink( wfMsg( 'copyrightpage' ),
1082 wfMsg( 'copyrightpagename' ) );
1086 function aboutLink()
1088 $s = $this->makeKnownLink( wfMsg( 'aboutpage' ),
1089 wfMsg( 'aboutwikipedia' ) );
1094 function disclaimerLink()
1096 $s = $this->makeKnownLink( wfMsg( 'disclaimerpage' ),
1097 wfMsg( 'disclaimers' ) );
1101 function editThisPage()
1103 global $wgOut, $wgTitle, $wgRequest;
1105 $oldid = $wgRequest->getVal( 'oldid' );
1106 $diff = $wgRequest->getVal( 'diff' );
1107 $redirect = $wgRequest->getVal( 'redirect' );
1109 if ( ! $wgOut->isArticleRelated() ) {
1110 $s = wfMsg( 'protectedpage' );
1112 $n = $wgTitle->getPrefixedText();
1113 if ( $wgTitle->userCanEdit() ) {
1114 $t = wfMsg( 'editthispage' );
1116 #$t = wfMsg( "protectedpage" );
1117 $t = wfMsg( 'viewsource' );
1121 if ( !is_null( $redirect ) ) { $red = "&redirect={$redirect}"; }
1122 if ( $oldid && ! isset( $diff ) ) {
1123 $oid = "&oldid={$oldid}";
1125 $s = $this->makeKnownLink( $n, $t, "action=edit{$oid}{$red}" );
1130 function deleteThisPage()
1132 global $wgUser, $wgOut, $wgTitle, $wgRequest;
1134 $diff = $wgRequest->getVal( 'diff' );
1135 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
1136 $n = $wgTitle->getPrefixedText();
1137 $t = wfMsg( 'deletethispage' );
1139 $s = $this->makeKnownLink( $n, $t, 'action=delete' );
1146 function protectThisPage()
1148 global $wgUser, $wgOut, $wgTitle, $wgRequest;
1150 $diff = $wgRequest->getVal( 'diff' );
1151 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
1152 $n = $wgTitle->getPrefixedText();
1154 if ( $wgTitle->isProtected() ) {
1155 $t = wfMsg( 'unprotectthispage' );
1156 $q = 'action=unprotect';
1158 $t = wfMsg( 'protectthispage' );
1159 $q = 'action=protect';
1161 $s = $this->makeKnownLink( $n, $t, $q );
1168 function watchThisPage()
1170 global $wgUser, $wgOut, $wgTitle;
1172 if ( $wgOut->isArticleRelated() ) {
1173 $n = $wgTitle->getPrefixedText();
1175 if ( $wgTitle->userIsWatching() ) {
1176 $t = wfMsg( 'unwatchthispage' );
1177 $q = 'action=unwatch';
1179 $t = wfMsg( 'watchthispage' );
1180 $q = 'action=watch';
1182 $s = $this->makeKnownLink( $n, $t, $q );
1184 $s = wfMsg( 'notanarticle' );
1189 function moveThisPage()
1191 global $wgTitle, $wgLang;
1193 if ( $wgTitle->userCanEdit() ) {
1194 $s = $this->makeKnownLink( $wgLang->specialPage( 'Movepage' ),
1195 wfMsg( 'movethispage' ), 'target=' . $wgTitle->getPrefixedURL() );
1196 } // no message if page is protected - would be redundant
1200 function historyLink()
1204 $s = $this->makeKnownLink( $wgTitle->getPrefixedText(),
1205 wfMsg( 'history' ), 'action=history' );
1209 function whatLinksHere()
1211 global $wgTitle, $wgLang;
1213 $s = $this->makeKnownLink( $wgLang->specialPage( 'Whatlinkshere' ),
1214 wfMsg( 'whatlinkshere' ), 'target=' . $wgTitle->getPrefixedURL() );
1218 function userContribsLink()
1220 global $wgTitle, $wgLang;
1222 $s = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
1223 wfMsg( 'contributions' ), 'target=' . $wgTitle->getPartialURL() );
1227 function emailUserLink()
1229 global $wgTitle, $wgLang;
1231 $s = $this->makeKnownLink( $wgLang->specialPage( 'Emailuser' ),
1232 wfMsg( 'emailuser' ), 'target=' . $wgTitle->getPartialURL() );
1236 function watchPageLinksLink()
1238 global $wgOut, $wgTitle, $wgLang;
1240 if ( ! $wgOut->isArticleRelated() ) {
1241 $s = '(' . wfMsg( 'notanarticle' ) . ')';
1243 $s = $this->makeKnownLink( $wgLang->specialPage(
1244 'Recentchangeslinked' ), wfMsg( 'recentchangeslinked' ),
1245 'target=' . $wgTitle->getPrefixedURL() );
1250 function otherLanguages()
1252 global $wgOut, $wgLang, $wgTitle, $wgUseNewInterlanguage;
1254 $a = $wgOut->getLanguageLinks();
1255 if ( 0 == count( $a ) ) {
1256 if ( !$wgUseNewInterlanguage ) return '';
1257 $ns = $wgLang->getNsIndex ( $wgTitle->getNamespace () ) ;
1258 if ( $ns != 0 AND $ns != 1 ) return '' ;
1260 $x = 'mode=addlink&xt='.$wgTitle->getDBkey() ;
1261 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1262 wfMsg( 'intl' ) , $x );
1265 if ( !$wgUseNewInterlanguage ) {
1266 $s = wfMsg( 'otherlanguages' ) . ': ';
1268 global $wgLanguageCode ;
1269 $x = 'mode=zoom&xt='.$wgTitle->getDBkey() ;
1270 $x .= '&xl='.$wgLanguageCode ;
1271 $s = $this->makeKnownLink( $wgLang->specialPage( 'Intl' ),
1272 wfMsg( 'otherlanguages' ) , $x ) . ': ' ;
1275 $s = wfMsg( 'otherlanguages' ) . ': ';
1277 if($wgLang->isRTL()) $s .= '<span dir="LTR">';
1278 foreach( $a as $l ) {
1279 if ( ! $first ) { $s .= ' | '; }
1282 $nt = Title
::newFromText( $l );
1283 $url = $nt->getFullURL();
1284 $text = $wgLang->getLanguageName( $nt->getInterwiki() );
1286 if ( '' == $text ) { $text = $l; }
1287 $style = $this->getExternalLinkAttributes( $l, $text );
1288 $s .= "<a href=\"{$url}\"{$style}>{$text}</a>";
1290 if($wgLang->isRTL()) $s .= '</span>';
1294 function bugReportsLink()
1296 $s = $this->makeKnownLink( wfMsg( 'bugreportspage' ),
1297 wfMsg( 'bugreports' ) );
1303 global $wgLinkCache;
1304 $t1 = Title
::newFromText( gmdate( 'F j' ) );
1305 $t2 = Title
::newFromText( gmdate( 'Y' ) );
1307 $wgLinkCache->suspend();
1308 $id = $t1->getArticleID();
1309 $wgLinkCache->resume();
1312 $s = $this->makeBrokenLink( $t1->getText() );
1314 $s = $this->makeKnownLink( $t1->getText() );
1318 $wgLinkCache->suspend();
1319 $id = $t2->getArticleID();
1320 $wgLinkCache->resume();
1323 $s .= $this->makeBrokenLink( $t2->getText() );
1325 $s .= $this->makeKnownLink( $t2->getText() );
1332 global $wgLang, $wgTitle, $wgLinkCache;
1334 $tns = $wgTitle->getNamespace();
1335 if ( -1 == $tns ) { return ''; }
1337 $pn = $wgTitle->getText();
1338 $tp = wfMsg( 'talkpage' );
1339 if ( Namespace::isTalk( $tns ) ) {
1340 $lns = Namespace::getSubject( $tns );
1343 $text = wfMsg('articlepage');
1346 $text = wfMsg('userpage');
1349 $text = wfMsg('wikipediapage');
1352 $text = wfMsg('imagepage');
1355 $text= wfMsg('articlepage');
1359 $lns = Namespace::getTalk( $tns );
1362 $n = $wgLang->getNsText( $lns );
1363 if ( '' == $n ) { $link = $pn; }
1364 else { $link = $n.':'.$pn; }
1366 $wgLinkCache->suspend();
1367 $s = $this->makeLink( $link, $text );
1368 $wgLinkCache->resume();
1373 function commentLink()
1375 global $wgLang, $wgTitle, $wgLinkCache;
1377 $tns = $wgTitle->getNamespace();
1378 if ( -1 == $tns ) { return ''; }
1380 $lns = ( Namespace::isTalk( $tns ) ) ?
$tns : Namespace::getTalk( $tns );
1382 # assert Namespace::isTalk( $lns )
1384 $n = $wgLang->getNsText( $lns );
1385 $pn = $wgTitle->getText();
1389 $wgLinkCache->suspend();
1390 $s = $this->makeKnownLink($link, wfMsg('postcomment'), 'action=edit§ion=new');
1391 $wgLinkCache->resume();
1396 # After all the page content is transformed into HTML, it makes
1397 # a final pass through here for things like table backgrounds.
1399 function transformContent( $text )
1404 # Note: This function MUST call getArticleID() on the link,
1405 # otherwise the cache won't get updated properly. See LINKCACHE.DOC.
1407 function makeLink( $title, $text = '', $query = '', $trail = '' ) {
1408 wfProfileIn( 'Skin::makeLink' );
1409 $nt = Title
::newFromText( $title );
1411 $result = $this->makeLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1413 wfDebug( 'Invalid title passed to Skin::makeLink(): "'.$title."\"\n" );
1414 $result = $text == "" ?
$title : $text;
1417 wfProfileOut( 'Skin::makeLink' );
1421 function makeKnownLink( $title, $text = '', $query = '', $trail = '', $prefix = '',$aprops = '') {
1422 $nt = Title
::newFromText( $title );
1424 return $this->makeKnownLinkObj( Title
::newFromText( $title ), $text, $query, $trail, $prefix , $aprops );
1426 wfDebug( 'Invalid title passed to Skin::makeKnownLink(): "'.$title."\"\n" );
1427 return $text == '' ?
$title : $text;
1431 function makeBrokenLink( $title, $text = '', $query = '', $trail = '' ) {
1432 $nt = Title
::newFromText( $title );
1434 return $this->makeBrokenLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1436 wfDebug( 'Invalid title passed to Skin::makeBrokenLink(): "'.$title."\"\n" );
1437 return $text == '' ?
$title : $text;
1441 function makeStubLink( $title, $text = '', $query = '', $trail = '' ) {
1442 $nt = Title
::newFromText( $title );
1444 return $this->makeStubLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1446 wfDebug( 'Invalid title passed to Skin::makeStubLink(): "'.$title."\"\n" );
1447 return $text == '' ?
$title : $text;
1451 # Pass a title object, not a title string
1452 function makeLinkObj( &$nt, $text= '', $query = '', $trail = '', $prefix = '' )
1454 global $wgOut, $wgUser;
1455 $fname = 'Skin::makeLinkObj';
1459 return "<!-- ERROR -->{$prefix}{$text}{$trail}";
1461 if ( $nt->isExternal() ) {
1462 $u = $nt->getFullURL();
1463 $link = $nt->getPrefixedURL();
1464 if ( '' == $text ) { $text = $nt->getPrefixedText(); }
1465 $style = $this->getExternalLinkAttributes( $link, $text, 'extiw' );
1468 if ( '' != $trail ) {
1469 if ( preg_match( '/^([a-z]+)(.*)$$/sD', $trail, $m ) ) {
1474 $retVal = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1475 } elseif ( 0 == $nt->getNamespace() && "" == $nt->getText() ) {
1476 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1477 } elseif ( ( -1 == $nt->getNamespace() ) ||
1478 ( Namespace::getImage() == $nt->getNamespace() ) ) {
1479 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1481 if ( $this->postParseLinkColour() ) {
1483 if ( '' != $trail ) {
1484 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1490 # Allows wiki to bypass using linkcache, see OutputPage::parseLinkHolders()
1491 $retVal = '<!--LINK ' . implode( ' ', array( $nt->getNamespace(), $nt->getDBkey(),
1492 $query, $prefix . $text . $inside ) ) . "-->{$trail}";
1494 # Work out link colour immediately
1495 $aid = $nt->getArticleID() ;
1497 $retVal = $this->makeBrokenLinkObj( $nt, $text, $query, $trail, $prefix );
1499 $threshold = $wgUser->getOption('stubthreshold') ;
1500 if ( $threshold > 0 ) {
1501 $dbr =& wfGetDB( DB_SLAVE
);
1502 $s = $dbr->selectRow( 'cur', array( 'LENGTH(cur_text) AS x', 'cur_namespace',
1503 'cur_is_redirect' ), array( 'cur_id' => $aid ), $fname ) ;
1504 if ( $s !== false ) {
1506 if ( $s->cur_is_redirect
OR $s->cur_namespace
!= 0 ) {
1507 $size = $threshold*2 ; # Really big
1509 $dbr->freeResult( $res );
1511 $size = $threshold*2 ; # Really big
1516 if ( $size < $threshold ) {
1517 $retVal = $this->makeStubLinkObj( $nt, $text, $query, $trail, $prefix );
1519 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1527 # Pass a title object, not a title string
1528 function makeKnownLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' , $aprops = '')
1530 global $wgOut, $wgTitle, $wgInputEncoding;
1532 $fname = 'Skin::makeKnownLinkObj';
1533 wfProfileIn( $fname );
1535 if ( !is_object( $nt ) ) {
1538 $link = $nt->getPrefixedURL();
1540 if ( '' == $link ) {
1542 if ( '' == $text ) {
1543 $text = htmlspecialchars( $nt->getFragment() );
1546 $u = $nt->escapeLocalURL( $query );
1548 if ( '' != $nt->getFragment() ) {
1549 $anchor = urlencode( do_html_entity_decode( str_replace(' ', '_', $nt->getFragment()), ENT_COMPAT
, $wgInputEncoding ) );
1550 $replacearray = array(
1554 $u .= '#' . str_replace(array_keys($replacearray),array_values($replacearray),$anchor);
1556 if ( '' == $text ) {
1557 $text = htmlspecialchars( $nt->getPrefixedText() );
1559 $style = $this->getInternalLinkAttributesObj( $nt, $text );
1562 if ( '' != $trail ) {
1563 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1568 $r = "<a href=\"{$u}\"{$style}{$aprops}>{$prefix}{$text}{$inside}</a>{$trail}";
1569 wfProfileOut( $fname );
1573 # Pass a title object, not a title string
1574 function makeBrokenLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
1576 global $wgOut, $wgUser;
1578 $fname = 'Skin::makeBrokenLinkObj';
1579 wfProfileIn( $fname );
1581 if ( '' == $query ) {
1584 $q = 'action=edit&'.$query;
1586 $u = $nt->escapeLocalURL( $q );
1588 if ( '' == $text ) {
1589 $text = htmlspecialchars( $nt->getPrefixedText() );
1591 $style = $this->getInternalLinkAttributesObj( $nt, $text, "yes" );
1594 if ( '' != $trail ) {
1595 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1600 if ( $wgUser->getOption( 'highlightbroken' ) ) {
1601 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1603 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>?</a>{$trail}";
1606 wfProfileOut( $fname );
1610 # Pass a title object, not a title string
1611 function makeStubLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
1613 global $wgOut, $wgUser;
1615 $link = $nt->getPrefixedURL();
1617 $u = $nt->escapeLocalURL( $query );
1619 if ( '' == $text ) {
1620 $text = htmlspecialchars( $nt->getPrefixedText() );
1622 $style = $this->getInternalLinkAttributesObj( $nt, $text, 'stub' );
1625 if ( '' != $trail ) {
1626 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1631 if ( $wgUser->getOption( 'highlightbroken' ) ) {
1632 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1634 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>!</a>{$trail}";
1639 function makeSelfLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
1641 $u = $nt->escapeLocalURL( $query );
1642 if ( '' == $text ) {
1643 $text = htmlspecialchars( $nt->getPrefixedText() );
1646 if ( '' != $trail ) {
1647 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1652 return "<strong>{$prefix}{$text}{$inside}</strong>{$trail}";
1655 /* these are used extensively in SkinPHPTal, but also some other places */
1656 /*static*/ function makeSpecialUrl( $name, $urlaction='' ) {
1657 $title = Title
::makeTitle( NS_SPECIAL
, $name );
1658 $this->checkTitle($title, $name);
1659 return $title->getLocalURL( $urlaction );
1661 /*static*/ function makeTalkUrl ( $name, $urlaction='' ) {
1662 $title = Title
::newFromText( $name );
1663 $title = $title->getTalkPage();
1664 $this->checkTitle($title, $name);
1665 return $title->getLocalURL( $urlaction );
1667 /*static*/ function makeArticleUrl ( $name, $urlaction='' ) {
1668 $title = Title
::newFromText( $name );
1669 $title= $title->getSubjectPage();
1670 $this->checkTitle($title, $name);
1671 return $title->getLocalURL( $urlaction );
1673 /*static*/ function makeI18nUrl ( $name, $urlaction='' ) {
1674 $title = Title
::newFromText( wfMsg($name) );
1675 $this->checkTitle($title, $name);
1676 return $title->getLocalURL( $urlaction );
1678 /*static*/ function makeUrl ( $name, $urlaction='' ) {
1679 $title = Title
::newFromText( $name );
1680 $this->checkTitle($title, $name);
1681 return $title->getLocalURL( $urlaction );
1683 # this can be passed the NS number as defined in Language.php
1684 /*static*/ function makeNSUrl( $name, $urlaction='', $namespace=0 ) {
1685 $title = Title
::makeTitle( $namespace, $name );
1686 $this->checkTitle($title, $name);
1687 return $title->getLocalURL( $urlaction );
1690 /* these return an array with the 'href' and boolean 'exists' */
1691 /*static*/ function makeUrlDetails ( $name, $urlaction='' ) {
1692 $title = Title
::newFromText( $name );
1693 $this->checkTitle($title, $name);
1695 'href' => $title->getLocalURL( $urlaction ),
1696 'exists' => $title->getArticleID() != 0?
true:false
1699 /*static*/ function makeTalkUrlDetails ( $name, $urlaction='' ) {
1700 $title = Title
::newFromText( $name );
1701 $title = $title->getTalkPage();
1702 $this->checkTitle($title, $name);
1704 'href' => $title->getLocalURL( $urlaction ),
1705 'exists' => $title->getArticleID() != 0?
true:false
1708 /*static*/ function makeArticleUrlDetails ( $name, $urlaction='' ) {
1709 $title = Title
::newFromText( $name );
1710 $title= $title->getSubjectPage();
1711 $this->checkTitle($title, $name);
1713 'href' => $title->getLocalURL( $urlaction ),
1714 'exists' => $title->getArticleID() != 0?
true:false
1717 /*static*/ function makeI18nUrlDetails ( $name, $urlaction='' ) {
1718 $title = Title
::newFromText( wfMsg($name) );
1719 $this->checkTitle($title, $name);
1721 'href' => $title->getLocalURL( $urlaction ),
1722 'exists' => $title->getArticleID() != 0?
true:false
1726 # make sure we have some title to operate on
1727 /*static*/ function checkTitle ( &$title, &$name ) {
1728 if(!is_object($title)) {
1729 $title = Title
::newFromText( $name );
1730 if(!is_object($title)) {
1731 $title = Title
::newFromText( '--error: link target missing--' );
1736 function fnamePart( $url )
1738 $basename = strrchr( $url, '/' );
1739 if ( false === $basename ) { $basename = $url; }
1740 else { $basename = substr( $basename, 1 ); }
1741 return wfEscapeHTML( $basename );
1744 function makeImage( $url, $alt = '' )
1748 if ( '' == $alt ) { $alt = $this->fnamePart( $url ); }
1749 $s = '<img src="'.$url.'" alt="'.$alt.'" />';
1753 function makeImageLink( $name, $url, $alt = '' ) {
1754 $nt = Title
::makeTitle( Namespace::getImage(), $name );
1755 return $this->makeImageLinkObj( $nt, $alt );
1758 function makeImageLinkObj( $nt, $alt = '' ) {
1759 global $wgLang, $wgUseImageResize;
1760 $img = Image
::newFromTitle( $nt );
1761 $url = $img->getURL();
1764 $prefix = $postfix = '';
1766 if ( $wgUseImageResize ) {
1767 # Check if the alt text is of the form "options|alt text"
1769 # * thumbnail make a thumbnail with enlarge-icon and caption, alignment depends on lang
1770 # * left no resizing, just left align. label is used for alt= only
1771 # * right same, but right aligned
1772 # * none same, but not aligned
1773 # * ___px scale to ___ pixels width, no aligning. e.g. use in taxobox
1774 # * center center the image
1775 # * framed Keep original image size, no magnify-button.
1777 $part = explode( '|', $alt);
1779 $mwThumb =& MagicWord
::get( MAG_IMG_THUMBNAIL
);
1780 $mwLeft =& MagicWord
::get( MAG_IMG_LEFT
);
1781 $mwRight =& MagicWord
::get( MAG_IMG_RIGHT
);
1782 $mwNone =& MagicWord
::get( MAG_IMG_NONE
);
1783 $mwWidth =& MagicWord
::get( MAG_IMG_WIDTH
);
1784 $mwCenter =& MagicWord
::get( MAG_IMG_CENTER
);
1785 $mwFramed =& MagicWord
::get( MAG_IMG_FRAMED
);
1786 $alt = $part[count($part)-1];
1788 $height = $framed = $thumb = false;
1789 $manual_thumb = "" ;
1791 foreach( $part as $key => $val ) {
1792 $val_parts = explode ( "=" , $val , 2 ) ;
1793 $left_part = array_shift ( $val_parts ) ;
1794 if ( ! is_null( $mwThumb->matchVariableStartToEnd($val) ) ) {
1796 } elseif ( count ( $val_parts ) == 1 && ! is_null( $mwThumb->matchVariableStartToEnd($left_part) ) ) {
1797 # use manually specified thumbnail
1799 $manual_thumb = array_shift ( $val_parts ) ;
1800 } elseif ( ! is_null( $mwRight->matchVariableStartToEnd($val) ) ) {
1801 # remember to set an alignment, don't render immediately
1803 } elseif ( ! is_null( $mwLeft->matchVariableStartToEnd($val) ) ) {
1804 # remember to set an alignment, don't render immediately
1806 } elseif ( ! is_null( $mwCenter->matchVariableStartToEnd($val) ) ) {
1807 # remember to set an alignment, don't render immediately
1809 } elseif ( ! is_null( $mwNone->matchVariableStartToEnd($val) ) ) {
1810 # remember to set an alignment, don't render immediately
1812 } elseif ( ! is_null( $match = $mwWidth->matchVariableStartToEnd($val) ) ) {
1813 # $match is the image width in pixels
1814 if ( preg_match( '/^([0-9]*)x([0-9]*)$/', $match, $m ) ) {
1815 $width = intval( $m[1] );
1816 $height = intval( $m[2] );
1818 $width = intval($match);
1820 } elseif ( ! is_null( $mwFramed->matchVariableStartToEnd($val) ) ) {
1824 if ( 'center' == $align )
1826 $prefix = '<span style="text-align: center">';
1827 $postfix = '</span>';
1831 if ( $thumb ||
$framed ) {
1833 # Create a thumbnail. Alignment depends on language
1834 # writing direction, # right aligned for left-to-right-
1835 # languages ("Western languages"), left-aligned
1836 # for right-to-left-languages ("Semitic languages")
1838 # If thumbnail width has not been provided, it is set
1839 # here to 180 pixels
1840 if ( $align == '' ) {
1841 $align = $wgLang->isRTL() ?
'left' : 'right';
1843 if ( ! isset($width) ) {
1846 return $prefix.$this->makeThumbLinkObj( $img, $alt, $align, $width, $height, $framed, $manual_thumb ).$postfix;
1848 } elseif ( isset($width) ) {
1850 # Create a resized image, without the additional thumbnail
1853 if ( ( ! $height === false )
1854 && ( $img->getHeight() * $width / $img->getWidth() > $height ) ) {
1855 print "height=$height<br>\nimg->getHeight() = ".$img->getHeight()."<br>\n";
1856 print 'rescaling by factor '. $height / $img->getHeight() . "<br>\n";
1857 $width = $img->getWidth() * $height / $img->getHeight();
1859 if ( '' == $manual_thumb ) $url = $img->createThumb( $width );
1861 } # endif $wgUseImageResize
1863 if ( empty( $alt ) ) {
1864 $alt = preg_replace( '/\.(.+?)^/', '', $img->getName() );
1866 $alt = htmlspecialchars( $alt );
1868 $u = $nt->escapeLocalURL();
1871 $s = wfMsg( 'missingimage', $img->getName() );
1872 $s .= "<br>{$alt}<br>{$url}<br>\n";
1874 $s = '<a href="'.$u.'" class="image" title="'.$alt.'">' .
1875 '<img src="'.$url.'" alt="'.$alt.'" /></a>';
1877 if ( '' != $align ) {
1878 $s = "<div class=\"float{$align}\"><span>{$s}</span></div>";
1880 return str_replace("\n", ' ',$prefix.$s.$postfix);
1883 # Make HTML for a thumbnail including image, border and caption
1884 # $img is an Image object
1885 function makeThumbLinkObj( $img, $label = '', $align = 'right', $boxwidth = 180, $boxheight=false, $framed=false , $manual_thumb = "" ) {
1886 global $wgStylePath, $wgLang;
1887 # $image = Title::makeTitle( Namespace::getImage(), $name );
1888 $url = $img->getURL();
1890 #$label = htmlspecialchars( $label );
1891 $alt = preg_replace( '/<[^>]*>/', '', $label);
1892 $alt = htmlspecialchars( $alt );
1894 $width = $height = 0;
1895 if ( $img->exists() )
1897 $width = $img->getWidth();
1898 $height = $img->getHeight();
1900 if ( 0 == $width ||
0 == $height )
1902 $width = $height = 200;
1904 if ( $boxwidth == 0 )
1910 // Use image dimensions, don't scale
1912 $oboxwidth = $boxwidth +
2;
1913 $boxheight = $height;
1916 $h = intval( $height/($width/$boxwidth) );
1917 $oboxwidth = $boxwidth +
2;
1918 if ( ( ! $boxheight === false ) && ( $h > $boxheight ) )
1920 $boxwidth *= $boxheight/$h;
1924 if ( '' == $manual_thumb ) $thumbUrl = $img->createThumb( $boxwidth );
1927 if ( $manual_thumb != '' ) # Use manually specified thumbnail
1929 $manual_title = Title
::makeTitle( Namespace::getImage(), $manual_thumb ); #new Title ( $manual_thumb ) ;
1930 $manual_img = Image
::newFromTitle( $manual_title );
1931 $thumbUrl = $manual_img->getURL();
1932 if ( $manual_img->exists() )
1934 $width = $manual_img->getWidth();
1935 $height = $manual_img->getHeight();
1936 $boxwidth = $width ;
1937 $boxheight = $height ;
1938 $oboxwidth = $boxwidth +
2 ;
1942 $u = $img->getEscapeLocalURL();
1944 $more = htmlspecialchars( wfMsg( 'thumbnail-more' ) );
1945 $magnifyalign = $wgLang->isRTL() ?
'left' : 'right';
1946 $textalign = $wgLang->isRTL() ?
' style="text-align:right"' : '';
1948 $s = "<div class=\"thumb t{$align}\"><div style=\"width:{$oboxwidth}px;\">";
1949 if ( $thumbUrl == '' ) {
1950 $s .= wfMsg( 'missingimage', $img->getName() );
1953 $s .= '<a href="'.$u.'" class="internal" title="'.$alt.'">'.
1954 '<img src="'.$thumbUrl.'" alt="'.$alt.'" ' .
1955 'width="'.$boxwidth.'" height="'.$boxheight.'" /></a>';
1959 $zoomicon = '<div class="magnify" style="float:'.$magnifyalign.'">'.
1960 '<a href="'.$u.'" class="internal" title="'.$more.'">'.
1961 '<img src="'.$wgStylePath.'/images/magnify-clip.png" ' .
1962 'width="15" height="11" alt="'.$more.'" /></a></div>';
1965 $s .= ' <div class="thumbcaption" '.$textalign.'>'.$zoomicon.$label."</div></div></div>";
1966 return str_replace("\n", ' ', $s);
1969 function makeMediaLink( $name, $url, $alt = "" ) {
1970 $nt = Title
::makeTitle( Namespace::getMedia(), $name );
1971 return $this->makeMediaLinkObj( $nt, $alt );
1974 function makeMediaLinkObj( $nt, $alt = "" )
1976 if ( ! isset( $nt ) )
1978 ### HOTFIX. Instead of breaking, return empty string.
1981 $name = $nt->getDBKey();
1982 $url = Image
::wfImageUrl( $name );
1983 if ( empty( $alt ) ) {
1984 $alt = preg_replace( '/\.(.+?)^/', '', $name );
1987 $u = htmlspecialchars( $url );
1988 $s = "<a href=\"{$u}\" class='internal' title=\"{$alt}\">{$alt}</a>";
1993 function specialLink( $name, $key = "" )
1997 if ( '' == $key ) { $key = strtolower( $name ); }
1998 $pn = $wgLang->ucfirst( $name );
1999 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
2003 function makeExternalLink( $url, $text, $escape = true ) {
2004 $style = $this->getExternalLinkAttributes( $url, $text );
2005 $url = htmlspecialchars( $url );
2007 $text = htmlspecialchars( $text );
2009 return '<a href="'.$url.'"'.$style.'>'.$text.'</a>';
2012 # Called by history lists and recent changes
2015 # Returns text for the start of the tabular part of RC
2016 function beginRecentChangesList()
2018 $this->rc_cache
= array() ;
2019 $this->rcMoveIndex
= 0;
2020 $this->rcCacheIndex
= 0 ;
2021 $this->lastdate
= '';
2022 $this->rclistOpen
= false;
2026 function beginImageHistoryList()
2028 $s = "\n<h2>" . wfMsg( 'imghistory' ) . "</h2>\n" .
2029 "<p>" . wfMsg( 'imghistlegend' ) . "</p>\n".'<ul class="special">';
2033 # Returns text for the end of RC
2034 # If enhanced RC is in use, returns pretty much all the text
2035 function endRecentChangesList()
2037 $s = $this->recentChangesBlock() ;
2038 if( $this->rclistOpen
) {
2044 # Enhanced RC ungrouped line
2045 function recentChangesBlockLine ( $rcObj )
2047 global $wgStylePath, $wgLang ;
2049 # Get rc_xxxx variables
2050 extract( $rcObj->mAttribs
) ;
2051 $curIdEq = 'curid='.$rc_cur_id;
2056 $r .= '<img src="'.$wgStylePath.'/images/Arr_.png" width="12" height="12" border="0" />' ;
2059 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2060 $r .= ' ';
2062 # M & N (minor & new)
2063 $M = wfMsg( 'minoreditletter' );
2064 $N = wfMsg( 'newpageletter' );
2066 if ( $rc_type == RC_NEW
) {
2079 $r .= ' '.$rcObj->timestamp
.' ' ;
2083 $link = $rcObj->link
;
2084 if ( $rcObj->watched
) $link = '<strong>'.$link.'</strong>' ;
2089 $r .= $rcObj->difflink
;
2093 $r .= $this->makeKnownLinkObj( $rcObj->getTitle(), wfMsg( 'hist' ), $curIdEq.'&action=history' );
2096 $r .= ') . . '.$rcObj->userlink
;
2097 $r .= $rcObj->usertalklink
;
2100 if ( $rc_comment != '' && $rc_type != RC_MOVE
&& $rc_type != RC_MOVE_OVER_REDIRECT
) {
2101 $rc_comment=$this->formatComment($rc_comment);
2102 $r .= $wgLang->emphasize( ' ('.$rc_comment.')' );
2110 function recentChangesBlockGroup ( $block )
2112 global $wgStylePath, $wgLang ;
2115 $M = wfMsg( 'minoreditletter' );
2116 $N = wfMsg( 'newpageletter' );
2118 # Collate list of users
2120 $userlinks = array () ;
2121 foreach ( $block AS $rcObj ) {
2122 $oldid = $rcObj->mAttribs
['rc_last_oldid'];
2123 if ( $rcObj->mAttribs
['rc_new'] ) $isnew = true ;
2124 $u = $rcObj->userlink
;
2125 if ( !isset ( $userlinks[$u] ) ) $userlinks[$u] = 0 ;
2129 # Sort the list and convert to text
2130 krsort ( $userlinks ) ;
2131 asort ( $userlinks ) ;
2133 foreach ( $userlinks as $userlink => $count) {
2135 if ( $count > 1 ) $text .= " ({$count}×)" ;
2136 array_push ( $users , $text ) ;
2138 $users = ' <font size="-1">['.implode('; ',$users).']</font>' ;
2141 $rci = 'RCI'.$this->rcCacheIndex
;
2142 $rcl = 'RCL'.$this->rcCacheIndex
;
2143 $rcm = 'RCM'.$this->rcCacheIndex
;
2144 $toggleLink = "javascript:toggleVisibility('$rci','$rcm','$rcl')" ;
2145 $arrowdir = $wgLang->isRTL() ?
'l' : 'r';
2146 $tl = '<span id="'.$rcm.'"><a href="'.$toggleLink.'"><img src="'.$wgStylePath.'/images/Arr_'.$arrowdir.'.png" width="12" height="12" /></a></span>' ;
2147 $tl .= '<span id="'.$rcl.'" style="display:none"><a href="'.$toggleLink.'"><img src="'.$wgStylePath.'/images/Arr_d.png" width="12" height="12" /></a></span>' ;
2153 if ( $isnew ) $r .= $N ;
2154 else $r .= ' ' ;
2155 $r .= ' ' ; # Minor
2158 $r .= ' '.$block[0]->timestamp
.' ' ;
2162 $link = $block[0]->link
;
2163 if ( $block[0]->watched
) $link = '<strong>'.$link.'</strong>' ;
2166 $curIdEq = 'curid=' . $block[0]->mAttribs
['rc_cur_id'];
2167 if ( $block[0]->mAttribs
['rc_type'] != RC_LOG
) {
2169 $r .= ' ('.count($block).' ' ;
2170 if ( $isnew ) $r .= wfMsg('changes');
2171 else $r .= $this->makeKnownLinkObj( $block[0]->getTitle() , wfMsg('changes') ,
2172 $curIdEq.'&diff=0&oldid='.$oldid ) ;
2176 $r .= $this->makeKnownLinkObj( $block[0]->getTitle(), wfMsg( 'history' ), $curIdEq.'&action=history' );
2184 $r .= '<div id="'.$rci.'" style="display:none">' ;
2185 foreach ( $block AS $rcObj ) {
2186 # Get rc_xxxx variables
2187 extract( $rcObj->mAttribs
);
2189 $r .= '<img src="'.$wgStylePath.'/images/Arr_.png" width="12" height="12" />';
2190 $r .= '<tt> ' ;
2191 if ( $rc_new ) $r .= $N ;
2192 else $r .= ' ' ;
2193 if ( $rc_minor ) $r .= $M ;
2194 else $r .= ' ' ;
2198 if ( $rc_last_oldid != 0 ) {
2199 $o = 'oldid='.$rc_last_oldid ;
2201 if ( $rc_type == RC_LOG
) {
2202 $link = $rcObj->timestamp
;
2204 $link = $this->makeKnownLinkObj( $rcObj->getTitle(), $rcObj->timestamp
, "{$curIdEq}&$o" ) ;
2206 $link = '<tt>'.$link.'</tt>' ;
2210 $r .= $rcObj->curlink
;
2212 $r .= $rcObj->lastlink
;
2213 $r .= ') . . '.$rcObj->userlink
;
2214 $r .= $rcObj->usertalklink
;
2215 if ( $rc_comment != '' ) {
2216 $rc_comment=$this->formatComment($rc_comment);
2217 $r .= $wgLang->emphasize( ' ('.$rc_comment.')' ) ;
2223 $this->rcCacheIndex++
;
2227 # If enhanced RC is in use, this function takes the previously cached
2228 # RC lines, arranges them, and outputs the HTML
2229 function recentChangesBlock ()
2231 global $wgStylePath ;
2232 if ( count ( $this->rc_cache
) == 0 ) return '' ;
2234 foreach ( $this->rc_cache
AS $secureName => $block ) {
2235 if ( count ( $block ) < 2 ) {
2236 $blockOut .= $this->recentChangesBlockLine ( array_shift ( $block ) ) ;
2238 $blockOut .= $this->recentChangesBlockGroup ( $block ) ;
2242 return '<div>'.$blockOut.'</div>' ;
2245 # Called in a loop over all displayed RC entries
2246 # Either returns the line, or caches it for later use
2247 function recentChangesLine( &$rc, $watched = false )
2250 $usenew = $wgUser->getOption( 'usenewrc' );
2252 $line = $this->recentChangesLineNew ( $rc, $watched ) ;
2254 $line = $this->recentChangesLineOld ( $rc, $watched ) ;
2258 function recentChangesLineOld( &$rc, $watched = false )
2260 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds, $wgUseRCPatrol, $wgOnlySysopsCanPatrol;
2262 # Extract DB fields into local scope
2263 extract( $rc->mAttribs
);
2264 $curIdEq = 'curid=' . $rc_cur_id;
2266 # Make date header if necessary
2267 $date = $wgLang->date( $rc_timestamp, true);
2269 if ( $date != $this->lastdate
) {
2270 if ( '' != $this->lastdate
) { $s .= "</ul>\n"; }
2271 $s .= "<h4>{$date}</h4>\n<ul class='special'>";
2272 $this->lastdate
= $date;
2273 $this->rclistOpen
= true;
2276 # If this edit has not yet been patrolled, make it stick out
2277 $s .= ( ! $wgUseRCPatrol ||
$rc_patrolled ) ?
'<li> ' : '<li class="not_patrolled"> ';
2279 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2281 $s .= '(' . wfMsg( 'diff' ) . ') (';
2283 $s .= $this->makeKnownLinkObj( $rc->getMovedToTitle(), wfMsg( 'hist' ), 'action=history' ) .
2286 # "[[x]] moved to [[y]]"
2287 $msg = ( $rc_type == RC_MOVE
) ?
'1movedto2' : '1movedto2_redir';
2288 $s .= wfMsg( $msg, $this->makeKnownLinkObj( $rc->getTitle(), '', 'redirect=no' ),
2289 $this->makeKnownLinkObj( $rc->getMovedToTitle(), '' ) );
2292 if ( $rc_type == RC_NEW ||
$rc_type == RC_LOG
) {
2293 $diffLink = wfMsg( 'diff' );
2295 if ( $wgUseRCPatrol && $rc_patrolled == 0 && $wgUser->getID() != 0 &&
2296 ( $wgUser->isSysop() ||
!$wgOnlySysopsCanPatrol ) )
2297 $rcidparam = "&rcid={$rc_id}";
2300 $diffLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'diff' ),
2301 "{$curIdEq}&diff={$rc_this_oldid}&oldid={$rc_last_oldid}{$rcidparam}",
2302 '', '', ' tabindex="'.$rc->counter
.'"');
2304 $s .= '('.$diffLink.') (';
2307 $s .= $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'hist' ), $curIdEq.'&action=history' );
2310 # M and N (minor and new)
2311 if ( $rc_minor ) { $s .= ' <span class="minor">'.wfMsg( "minoreditletter" ).'</span>'; }
2312 if ( $rc_type == RC_NEW
) { $s .= '<span class="newpage">'.wfMsg( "newpageletter" ).'</span>'; }
2315 # If it's a new article, there is no diff link, but if it hasn't been
2316 # patrolled yet, we need to give users a way to do so
2317 if ( $wgUseRCPatrol && $rc_type == RC_NEW
&& $rc_patrolled == 0 &&
2318 $wgUser->getID() != 0 && ( $wgUser->isSysop() ||
!$wgOnlySysopsCanPatrol ) )
2319 $articleLink = $this->makeKnownLinkObj( $rc->getTitle(), '', "rcid={$rc_id}" );
2321 $articleLink = $this->makeKnownLinkObj( $rc->getTitle(), '' );
2324 $articleLink = '<strong>'.$articleLink.'</strong>';
2326 $s .= ' '.$articleLink;
2331 $s .= '; ' . $wgLang->time( $rc_timestamp, true, $wgRCSeconds ) . ' . . ';
2333 # User link (or contributions for unregistered users)
2334 if ( 0 == $rc_user ) {
2335 $userLink = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
2336 $rc_user_text, 'target=' . $rc_user_text );
2338 $userLink = $this->makeLink( $wgLang->getNsText( NS_USER
) . ':'.$rc_user_text, $rc_user_text );
2343 $talkname=$wgLang->getNsText(NS_TALK
); # use the shorter name
2344 global $wgDisableAnonTalk;
2345 if( 0 == $rc_user && $wgDisableAnonTalk ) {
2348 $utns=$wgLang->getNsText(NS_USER_TALK
);
2349 $userTalkLink= $this->makeLink($utns . ':'.$rc_user_text, $talkname );
2353 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2354 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2355 'Blockip' ), wfMsg( 'blocklink' ), 'ip='.$rc_user_text );
2359 if($userTalkLink) $userTalkLink .= ' | ';
2360 $userTalkLink .= $blockLink;
2362 if($userTalkLink) $s.=' ('.$userTalkLink.')';
2365 if ( '' != $rc_comment && '*' != $rc_comment && $rc_type != RC_MOVE
&& $rc_type != RC_MOVE_OVER_REDIRECT
) {
2366 $rc_comment=$this->formatComment($rc_comment);
2367 $s .= $wgLang->emphasize(' (' . $rc_comment . ')');
2374 function recentChangesLineNew( &$baseRC, $watched = false )
2376 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds;
2378 # Create a specialised object
2379 $rc = RCCacheEntry
::newFromParent( $baseRC ) ;
2381 # Extract fields from DB into the function scope (rc_xxxx variables)
2382 extract( $rc->mAttribs
);
2383 $curIdEq = 'curid=' . $rc_cur_id;
2385 # If it's a new day, add the headline and flush the cache
2386 $date = $wgLang->date( $rc_timestamp, true);
2388 if ( $date != $this->lastdate
) {
2389 # Process current cache
2390 $ret = $this->recentChangesBlock () ;
2391 $this->rc_cache
= array() ;
2392 $ret .= "<h4>{$date}</h4>\n";
2393 $this->lastdate
= $date;
2397 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2398 $msg = ( $rc_type == RC_MOVE
) ?
"1movedto2" : "1movedto2_redir";
2399 $clink = wfMsg( $msg, $this->makeKnownLinkObj( $rc->getTitle(), '', 'redirect=no' ),
2400 $this->makeKnownLinkObj( $rc->getMovedToTitle(), '' ) );
2402 $clink = $this->makeKnownLinkObj( $rc->getTitle(), '' ) ;
2405 $time = $wgLang->time( $rc_timestamp, true, $wgRCSeconds );
2406 $rc->watched
= $watched ;
2407 $rc->link
= $clink ;
2408 $rc->timestamp
= $time;
2410 # Make "cur" and "diff" links
2411 if ( ( $rc_type == RC_NEW
&& $rc_this_oldid == 0 ) ||
$rc_type == RC_LOG ||
$rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2412 $curLink = wfMsg( 'cur' );
2413 $diffLink = wfMsg( 'diff' );
2415 $query = $curIdEq.'&diff=0&oldid='.$rc_this_oldid;
2416 $aprops = ' tabindex="'.$baseRC->counter
.'"';
2417 $curLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'cur' ), $query, '' ,'' , $aprops );
2418 $diffLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'diff'), $query, '' ,'' , $aprops );
2422 $titleObj = $rc->getTitle();
2423 if ( $rc_last_oldid == 0 ||
$rc_type == RC_LOG ||
$rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2424 $lastLink = wfMsg( 'last' );
2426 $lastLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'last' ),
2427 $curIdEq.'&diff='.$rc_this_oldid.'&oldid='.$rc_last_oldid );
2430 # Make user link (or user contributions for unregistered users)
2431 if ( $rc_user == 0 ) {
2432 $userLink = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
2433 $rc_user_text, 'target=' . $rc_user_text );
2435 $userLink = $this->makeLink( $wgLang->getNsText(
2436 Namespace::getUser() ) . ':'.$rc_user_text, $rc_user_text );
2439 $rc->userlink
= $userLink;
2440 $rc->lastlink
= $lastLink;
2441 $rc->curlink
= $curLink;
2442 $rc->difflink
= $diffLink;
2444 # Make user talk link
2445 $utns=$wgLang->getNsText(NS_USER_TALK
);
2446 $talkname=$wgLang->getNsText(NS_TALK
); # use the shorter name
2447 $userTalkLink= $this->makeLink($utns . ':'.$rc_user_text, $talkname );
2449 global $wgDisableAnonTalk;
2450 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2451 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2452 'Blockip' ), wfMsg( 'blocklink' ), 'ip='.$rc_user_text );
2453 if( $wgDisableAnonTalk )
2454 $rc->usertalklink
= ' ('.$blockLink.')';
2456 $rc->usertalklink
= ' ('.$userTalkLink.' | '.$blockLink.')';
2458 if( $wgDisableAnonTalk && ($rc_user == 0) )
2459 $rc->usertalklink
= '';
2461 $rc->usertalklink
= ' ('.$userTalkLink.')';
2464 # Put accumulated information into the cache, for later display
2465 # Page moves go on their own line
2466 $title = $rc->getTitle();
2467 $secureName = $title->getPrefixedDBkey();
2468 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2469 # Use an @ character to prevent collision with page names
2470 $this->rc_cache
['@@' . ($this->rcMoveIndex++
)] = array($rc);
2472 if ( !isset ( $this->rc_cache
[$secureName] ) ) $this->rc_cache
[$secureName] = array() ;
2473 array_push ( $this->rc_cache
[$secureName] , $rc ) ;
2478 function endImageHistoryList()
2484 /* This function is called by all recent changes variants, by the page history,
2485 and by the user contributions list. It is responsible for formatting edit
2486 comments. It escapes any HTML in the comment, but adds some CSS to format
2487 auto-generated comments (from section editing) and formats [[wikilinks]].
2488 Main author: Erik Möller (moeller@scireview.de)
2490 function formatComment($comment)
2493 $comment=wfEscapeHTML($comment);
2495 # The pattern for autogen comments is / * foo * /, which makes for
2497 # We look for all comments, match any text before and after the comment,
2498 # add a separator where needed and format the comment itself with CSS
2499 while (preg_match('/(.*)\/\*\s*(.*?)\s*\*\/(.*)/', $comment,$match)) {
2504 if($pre) { $auto = $sep.' '.$auto; }
2505 if($post) { $auto .= ' '.$sep; }
2506 $auto='<span class="autocomment">'.$auto.'</span>';
2507 $comment=$pre.$auto.$post;
2510 # format regular and media links - all other wiki formatting
2512 $medians = $wgLang->getNsText(Namespace::getMedia()).':';
2513 while(preg_match('/\[\[(.*?)(\|(.*?))*\]\](.*)$/',$comment,$match)) {
2514 # Handle link renaming [[foo|text]] will show link as "text"
2515 if( "" != $match[3] ) {
2520 if( preg_match( '/^' . $medians . '(.*)$/i', $match[1], $submatch ) ) {
2521 # Media link; trail not supported.
2522 $linkRegexp = '/\[\[(.*?)\]\]/';
2523 $thelink = $this->makeMediaLink( $submatch[1], "", $text );
2525 # Other kind of link
2526 if( preg_match( wfMsg( "linktrail" ), $match[4], $submatch ) ) {
2527 $trail = $submatch[1];
2531 $linkRegexp = '/\[\[(.*?)\]\]' . preg_quote( $trail, '/' ) . '/';
2532 $thelink = $this->makeLink( $match[1], $text, "", $trail );
2534 $comment = preg_replace( $linkRegexp, $thelink, $comment, 1 );
2539 function imageHistoryLine( $iscur, $timestamp, $img, $user, $usertext, $size, $description )
2541 global $wgUser, $wgLang, $wgTitle;
2543 $datetime = $wgLang->timeanddate( $timestamp, true );
2544 $del = wfMsg( 'deleteimg' );
2545 $delall = wfMsg( 'deleteimgcompletely' );
2546 $cur = wfMsg( 'cur' );
2549 $url = Image
::wfImageUrl( $img );
2551 if ( $wgUser->isSysop() ) {
2552 $link = $wgTitle->escapeLocalURL( 'image=' . $wgTitle->getPartialURL() .
2554 $style = $this->getInternalLinkAttributes( $link, $delall );
2556 $dlink = '<a href="'.$link.'"'.$style.'>'.$delall.'</a>';
2561 $url = wfEscapeHTML( wfImageArchiveUrl( $img ) );
2562 if( $wgUser->getID() != 0 && $wgTitle->userCanEdit() ) {
2563 $rlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2564 wfMsg( 'revertimg' ), 'action=revert&oldimage=' .
2565 urlencode( $img ) );
2566 $dlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2567 $del, 'action=delete&oldimage=' . urlencode( $img ) );
2569 # Having live active links for non-logged in users
2570 # means that bots and spiders crawling our site can
2571 # inadvertently change content. Baaaad idea.
2572 $rlink = wfMsg( 'revertimg' );
2577 $userlink = $usertext;
2579 $userlink = $this->makeLink( $wgLang->getNsText( Namespace::getUser() ) .
2580 ':'.$usertext, $usertext );
2582 $nbytes = wfMsg( 'nbytes', $size );
2583 $style = $this->getInternalLinkAttributes( $url, $datetime );
2585 $s = "<li> ({$dlink}) ({$rlink}) <a href=\"{$url}\"{$style}>{$datetime}</a>"
2586 . " . . {$userlink} ({$nbytes})";
2588 if ( '' != $description && '*' != $description ) {
2589 $sk=$wgUser->getSkin();
2590 $s .= $wgLang->emphasize(' (' . $sk->formatComment($description) . ')');
2596 function tocIndent($level) {
2597 return str_repeat( '<div class="tocindent">'."\n", $level>0 ?
$level : 0 );
2600 function tocUnindent($level) {
2601 return str_repeat( "</div>\n", $level>0 ?
$level : 0 );
2604 # parameter level defines if we are on an indentation level
2605 function tocLine( $anchor, $tocline, $level ) {
2606 $link = '<a href="#'.$anchor.'">'.$tocline.'</a><br />';
2610 return '<div class="tocline">'.$link."</div>\n";
2615 function tocTable($toc) {
2616 # note to CSS fanatics: putting this in a div does not work -- div won't auto-expand
2617 # try min-width & co when somebody gets a chance
2618 $hideline = ' <script type="text/javascript">showTocToggle("' . addslashes( wfMsg('showtoc') ) . '","' . addslashes( wfMsg('hidetoc') ) . '")</script>';
2620 '<table border="0" id="toc"><tr id="toctitle"><td align="center">'."\n".
2621 '<b>'.wfMsg('toc').'</b>' .
2623 '</td></tr><tr id="tocinside"><td>'."\n".
2624 $toc."</td></tr></table>\n";
2627 # These two do not check for permissions: check $wgTitle->userCanEdit before calling them
2628 function editSectionScript( $section, $head ) {
2629 global $wgTitle, $wgRequest;
2630 if( $wgRequest->getInt( 'oldid' ) && ( $wgRequest->getVal( 'diff' ) != '0' ) ) {
2633 $url = $wgTitle->escapeLocalURL( 'action=edit§ion='.$section );
2634 return '<span oncontextmenu=\'document.location="'.$url.'";return false;\'>'.$head.'</span>';
2637 function editSectionLink( $section ) {
2639 global $wgTitle, $wgUser, $wgLang;
2641 if( $wgRequest->getInt( 'oldid' ) && ( $wgRequest->getVal( 'diff' ) != '0' ) ) {
2642 # Section edit links would be out of sync on an old page.
2643 # But, if we're diffing to the current page, they'll be
2648 $editurl = '§ion='.$section;
2649 $url = $this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg('editsection'),'action=edit'.$editurl);
2651 if( $wgLang->isRTL() ) {
2653 $nearside = 'right';
2658 return "<div class=\"editsection\" style=\"float:$farside;margin-$nearside:5px;\">[".$url."]</div>";
2662 // This function is called by EditPage.php and shows a bulletin board style
2663 // toolbar for common editing functions. It can be disabled in the user preferences.
2664 // The necsesary JavaScript code can be found in style/wikibits.js.
2665 function getEditToolbar() {
2666 global $wgStylePath, $wgLang, $wgMimeType;
2668 // toolarray an array of arrays which each include the filename of
2669 // the button image (without path), the opening tag, the closing tag,
2670 // and optionally a sample text that is inserted between the two when no
2671 // selection is highlighted.
2672 // The tip text is shown when the user moves the mouse over the button.
2674 // Already here are accesskeys (key), which are not used yet until someone
2675 // can figure out a way to make them work in IE. However, we should make
2676 // sure these keys are not defined on the edit page.
2678 array( 'image'=>'button_bold.png',
2681 'sample'=>wfMsg('bold_sample'),
2682 'tip'=>wfMsg('bold_tip'),
2685 array( "image"=>"button_italic.png",
2688 "sample"=>wfMsg("italic_sample"),
2689 "tip"=>wfMsg("italic_tip"),
2692 array( "image"=>"button_link.png",
2695 "sample"=>wfMsg("link_sample"),
2696 "tip"=>wfMsg("link_tip"),
2699 array( "image"=>"button_extlink.png",
2702 "sample"=>wfMsg("extlink_sample"),
2703 "tip"=>wfMsg("extlink_tip"),
2706 array( "image"=>"button_headline.png",
2709 "sample"=>wfMsg("headline_sample"),
2710 "tip"=>wfMsg("headline_tip"),
2713 array( "image"=>"button_image.png",
2714 "open"=>"[[".$wgLang->getNsText(NS_IMAGE
).":",
2716 "sample"=>wfMsg("image_sample"),
2717 "tip"=>wfMsg("image_tip"),
2720 array( "image"=>"button_media.png",
2721 "open"=>"[[".$wgLang->getNsText(NS_MEDIA
).":",
2723 "sample"=>wfMsg("media_sample"),
2724 "tip"=>wfMsg("media_tip"),
2727 array( "image"=>"button_math.png",
2728 "open"=>"\\<math\\>",
2729 "close"=>"\\</math\\>",
2730 "sample"=>wfMsg("math_sample"),
2731 "tip"=>wfMsg("math_tip"),
2734 array( "image"=>"button_nowiki.png",
2735 "open"=>"\\<nowiki\\>",
2736 "close"=>"\\</nowiki\\>",
2737 "sample"=>wfMsg("nowiki_sample"),
2738 "tip"=>wfMsg("nowiki_tip"),
2741 array( "image"=>"button_sig.png",
2745 "tip"=>wfMsg("sig_tip"),
2748 array( "image"=>"button_hr.png",
2749 "open"=>"\\n----\\n",
2752 "tip"=>wfMsg("hr_tip"),
2756 $toolbar ="<script type='text/javascript'>\n/*<![CDATA[*/\n";
2758 $toolbar.="document.writeln(\"<div id='toolbar'>\");\n";
2759 foreach($toolarray as $tool) {
2761 $image=$wgStylePath.'/images/'.$tool['image'];
2762 $open=$tool['open'];
2763 $close=$tool['close'];
2764 $sample = addslashes( $tool['sample'] );
2766 // Note that we use the tip both for the ALT tag and the TITLE tag of the image.
2767 // Older browsers show a "speedtip" type message only for ALT.
2768 // Ideally these should be different, realistically they
2769 // probably don't need to be.
2770 $tip = addslashes( $tool['tip'] );
2772 #$key = $tool["key"];
2774 $toolbar.="addButton('$image','$tip','$open','$close','$sample');\n";
2777 $toolbar.="addInfobox('" . addslashes( wfMsg( "infobox" ) ) . "','" . addslashes(wfMsg("infobox_alert")) . "');\n";
2778 $toolbar.="document.writeln(\"</div>\");\n";
2780 $toolbar.="/*]]>*/\n</script>";