3 # This is not a valid entry point, perform no further processing unless MEDIAWIKI is defined
4 if( defined( "MEDIAWIKI" ) ) {
8 require_once( 'Feed.php' ); // should not be called if the actual page isn't feed enabled
9 require_once( 'Image.php' );
11 # These are the INTERNAL names, which get mapped
12 # directly to class names. For display purposes, the
13 # Language class has internationalized names
15 /* private */ $wgValidSkinNames = array(
16 'standard' => 'Standard',
17 'nostalgia' => 'Nostalgia',
18 'cologneblue' => 'CologneBlue'
21 #$wgValidSkinNames[] = 'PHPTal';
22 #$wgValidSkinNames['davinci'] = 'DaVinci';
23 #$wgValidSkinNames['mono'] = 'Mono';
24 $wgValidSkinNames['monobook'] = 'MonoBook';
25 $wgValidSkinNames['myskin'] = 'MySkin';
26 #$wgValidSkinNames['monobookminimal'] = 'MonoBookMinimal';
29 require_once( 'RecentChange.php' );
31 class RCCacheEntry
extends RecentChange
33 var $secureName, $link;
34 var $curlink , $difflink, $lastlink , $usertalklink , $versionlink ;
35 var $userlink, $timestamp, $watched;
37 function newFromParent( $rc )
39 $rc2 = new RCCacheEntry
;
40 $rc2->mAttribs
= $rc->mAttribs
;
41 $rc2->mExtra
= $rc->mExtra
;
48 /* private */ var $lastdate, $lastline;
49 var $linktrail ; # linktrail regexp
50 var $rc_cache ; # Cache for Enhanced Recent Changes
51 var $rcCacheIndex ; # Recent Changes Cache Counter for visibility toggle
53 var $postParseLinkColour = true;
57 $this->linktrail
= wfMsg('linktrail');
60 function getSkinNames()
62 global $wgValidSkinNames;
63 return $wgValidSkinNames;
66 function getStylesheet()
68 return 'wikistandard.css';
70 function getSkinName() {
74 # Get/set accessor for delayed link colouring
75 function postParseLinkColour( $setting = NULL ) {
76 return wfSetVar( $this->postParseLinkColour
, $setting );
81 global $wgOut, $wgUser;
83 if ( $wgOut->isQuickbarSuppressed() ) { return 0; }
84 $q = $wgUser->getOption( 'quickbar' );
85 if ( '' == $q ) { $q = 0; }
89 function initPage( &$out )
91 $fname = 'Skin::initPage';
92 wfProfileIn( $fname );
94 $out->addLink( array( 'rel' => 'shortcut icon', 'href' => '/favicon.ico' ) );
96 $this->addMetadataLinks($out);
98 wfProfileOut( $fname );
101 function addMetadataLinks( &$out ) {
102 global $wgTitle, $wgEnableDublinCoreRdf, $wgEnableCreativeCommonsRdf, $wgRdfMimeType, $action;
103 global $wgRightsPage, $wgRightsUrl;
105 if( $out->isArticleRelated() ) {
106 # note: buggy CC software only reads first "meta" link
107 if( $wgEnableCreativeCommonsRdf ) {
108 $out->addMetadataLink( array(
109 'title' => 'Creative Commons',
110 'type' => 'application/rdf+xml',
111 'href' => $wgTitle->getLocalURL( 'action=creativecommons') ) );
113 if( $wgEnableDublinCoreRdf ) {
114 $out->addMetadataLink( array(
115 'title' => 'Dublin Core',
116 'type' => 'application/rdf+xml',
117 'href' => $wgTitle->getLocalURL( 'action=dublincore' ) ) );
121 if( $wgRightsPage ) {
122 $copy = Title
::newFromText( $wgRightsPage );
124 $copyright = $copy->getLocalURL();
127 if( !$copyright && $wgRightsUrl ) {
128 $copyright = $wgRightsUrl;
131 $out->addLink( array(
132 'rel' => 'copyright',
133 'href' => $copyright ) );
137 function outputPage( &$out ) {
138 global $wgDebugComments;
140 wfProfileIn( 'Skin::outputPage' );
141 $this->initPage( $out );
142 $out->out( $out->headElement() );
144 $out->out( "\n<body" );
145 $ops = $this->getBodyOptions();
146 foreach ( $ops as $name => $val ) {
147 $out->out( " $name='$val'" );
150 if ( $wgDebugComments ) {
151 $out->out( "<!-- Wiki debugging output:\n" .
152 $out->mDebugtext
. "-->\n" );
154 $out->out( $this->beforeContent() );
156 $out->out( $out->mBodytext
. "\n" );
158 $out->out( $this->afterContent() );
161 $out->out( $out->reportTime() );
163 $out->out( "\n</body></html>" );
166 function getHeadScripts() {
167 global $wgStylePath, $wgUser, $wgLang, $wgAllowUserJs;
168 $r = "<script type=\"text/javascript\" src=\"{$wgStylePath}/wikibits.js\"></script>\n";
169 if( $wgAllowUserJs && $wgUser->getID() != 0 ) { # logged in
170 $userpage = $wgLang->getNsText( Namespace::getUser() ) . ":" . $wgUser->getName();
171 $userjs = htmlspecialchars($this->makeUrl($userpage.'/'.$this->getSkinName().'.js', 'action=raw&ctype=text/javascript'));
172 $r .= '<script type="text/javascript" src="'.$userjs."\"></script>\n";
177 # get the user/site-specific stylesheet, SkinPHPTal called from RawPage.php (settings are cached that way)
178 function getUserStylesheet() {
179 global $wgOut, $wgStylePath, $wgLang, $wgUser, $wgRequest, $wgTitle, $wgAllowUserCss;
180 $sheet = $this->getStylesheet();
181 $action = $wgRequest->getText('action');
182 $s = "@import \"$wgStylePath/$sheet\";\n";
183 if($wgLang->isRTL()) $s .= "@import \"$wgStylePath/common_rtl.css\";\n";
184 if( $wgAllowUserCss && $wgUser->getID() != 0 ) { # logged in
185 if($wgTitle->isCssSubpage() and $action == 'submit' and $wgTitle->userCanEditCssJsSubpage()) {
186 $s .= $wgRequest->getText('wpTextbox1');
188 $userpage = $wgLang->getNsText( Namespace::getUser() ) . ":" . $wgUser->getName();
189 $s.= '@import "'.$this->makeUrl($userpage.'/'.$this->getSkinName().'.css', 'action=raw&ctype=text/css').'";'."\n";
192 $s .= $this->doGetUserStyles();
195 # placeholder, returns generated js in monobook
196 function getUserJs() {
200 function getUserStyles()
202 global $wgOut, $wgStylePath, $wgLang;
203 $s = "<style type='text/css'>\n";
204 $s .= "/*/*/\n"; # <-- Hide the styles from Netscape 4 without hiding them from IE/Mac
205 $s .= $this->getUserStylesheet();
211 function doGetUserStyles()
213 global $wgUser, $wgLang;
215 $csspage = $wgLang->getNsText( NS_MEDIAWIKI
) . ":" . $this->getSkinName() . ".css";
216 $s = '@import "'.$this->makeUrl($csspage, 'action=raw&ctype=text/css')."\";\n";
218 if ( 1 == $wgUser->getOption( 'underline' ) ) {
219 # Don't override browser settings
223 $s .= "a { text-decoration: none; }\n";
225 if ( 1 == $wgUser->getOption( 'highlightbroken' ) ) {
226 $s .= "a.new, #quickbar a.new { color: #CC2200; }\n";
228 if ( 1 == $wgUser->getOption( 'justify' ) ) {
229 $s .= "#article { text-align: justify; }\n";
234 function getBodyOptions()
236 global $wgUser, $wgTitle, $wgNamespaceBackgrounds, $wgOut, $wgRequest;
238 extract( $wgRequest->getValues( 'oldid', 'redirect', 'diff' ) );
240 if ( 0 != $wgTitle->getNamespace() ) {
241 $a = array( 'bgcolor' => '#ffffec' );
243 else $a = array( 'bgcolor' => '#FFFFFF' );
244 if($wgOut->isArticle() && $wgUser->getOption('editondblclick') &&
245 (!$wgTitle->isProtected() ||
$wgUser->isSysop()) ) {
246 $t = wfMsg( 'editthispage' );
248 if ( !empty($redirect) ) {
249 $red = "&redirect={$redirect}";
251 if ( !empty($oldid) && ! isset( $diff ) ) {
252 $oid = "&oldid={$oldid}";
254 $s = $wgTitle->getFullURL( "action=edit{$oid}{$red}" );
255 $s = 'document.location = "' .$s .'";';
256 $a +
= array ('ondblclick' => $s);
259 $a['onload'] = $wgOut->getOnloadHandler();
263 function getExternalLinkAttributes( $link, $text, $class='' )
265 global $wgUser, $wgOut, $wgLang;
267 $link = urldecode( $link );
268 $link = $wgLang->checkTitleEncoding( $link );
269 $link = str_replace( '_', ' ', $link );
270 $link = wfEscapeHTML( $link );
272 $r = ($class != '') ?
" class='$class'" : " class='external'";
274 if ( 1 == $wgUser->getOption( 'hover' ) ) {
275 $r .= " title=\"{$link}\"";
280 function getInternalLinkAttributes( $link, $text, $broken = false )
282 global $wgUser, $wgOut;
284 $link = urldecode( $link );
285 $link = str_replace( '_', ' ', $link );
286 $link = wfEscapeHTML( $link );
288 if ( $broken == 'stub' ) {
289 $r = ' class="stub"';
290 } else if ( $broken == 'yes' ) {
296 if ( 1 == $wgUser->getOption( 'hover' ) ) {
297 $r .= " title=\"{$link}\"";
302 function getInternalLinkAttributesObj( &$nt, $text, $broken = false )
304 global $wgUser, $wgOut;
306 if ( $broken == 'stub' ) {
307 $r = ' class="stub"';
308 } else if ( $broken == 'yes' ) {
314 if ( 1 == $wgUser->getOption( 'hover' ) ) {
315 $r .= ' title ="' . $nt->getEscapedText() . '"';
326 # This will be called immediately after the <body> tag. Split into
327 # two functions to make it easier to subclass.
329 function beforeContent()
331 global $wgUser, $wgOut;
333 return $this->doBeforeContent();
336 function doBeforeContent()
338 global $wgUser, $wgOut, $wgTitle, $wgLang, $wgSiteNotice;
339 $fname = 'Skin::doBeforeContent';
340 wfProfileIn( $fname );
343 $qb = $this->qbSetting();
345 if( $langlinks = $this->otherLanguages() ) {
351 $borderhack = 'class="top"';
354 $s .= "\n<div id='content'>\n<div id='topbar'>\n" .
355 "<table border='0' cellspacing='0' width='98%'>\n<tr>\n";
358 $left = ($qb == 1 ||
$qb == 3);
359 if($wgLang->isRTL()) $left = !$left;
362 $s .= "<td class='top' align='left' valign='top' rowspan='{$rows}'>\n" .
363 $this->logoText() . '</td>';
365 $s .= $this->getQuickbarCompensator( $rows );
367 $l = $wgLang->isRTL() ?
'right' : 'left';
368 $s .= "<td {$borderhack} align='$l' valign='top'>\n";
370 $s .= $this->topLinks() ;
371 $s .= "<p class='subtitle'>" . $this->pageTitleLinks() . "</p>\n";
373 $r = $wgLang->isRTL() ?
"left" : "right";
374 $s .= "</td>\n<td {$borderhack} valign='top' align='$r' nowrap='nowrap'>";
375 $s .= $this->nameAndLogin();
376 $s .= "\n<br />" . $this->searchForm() . "</td>";
379 $s .= "</tr>\n<tr>\n<td class='top' colspan=\"2\">$langlinks</td>\n";
382 if ( $shove && !$left ) { # Right
383 $s .= $this->getQuickbarCompensator( $rows );
385 $s .= "</tr>\n</table>\n</div>\n";
386 $s .= "\n<div id='article'>\n";
388 if( $wgSiteNotice ) {
389 $s .= "\n<div id='siteNotice'>$wgSiteNotice</div>\n";
391 $s .= $this->pageTitle();
392 $s .= $this->pageSubtitle() ;
393 $s .= $this->getCategories();
394 wfProfileOut( $fname );
398 function getCategoryLinks () {
399 global $wgOut, $wgTitle, $wgUser, $wgParser;
400 global $wgUseCategoryMagic, $wgUseCategoryBrowser, $wgLang;
402 if( !$wgUseCategoryMagic ) return '' ;
403 if( count( $wgOut->mCategoryLinks
) == 0 ) return '';
405 # Taken out so that they will be displayed in previews -- TS
406 #if( !$wgOut->isArticle() ) return '';
408 $t = implode ( ' | ' , $wgOut->mCategoryLinks
) ;
409 $s = $this->makeKnownLink( 'Special:Categories',
410 wfMsg( 'categories' ), 'article=' . urlencode( $wgTitle->getPrefixedDBkey() ) )
413 if($wgUseCategoryBrowser) {
416 $s.= $wgTitle->getAllParentCategories($catstack);
422 function getCategories() {
423 $catlinks=$this->getCategoryLinks();
424 if(!empty($catlinks)) {
425 return "<p class='catlinks'>{$catlinks}</p>";
429 function getQuickbarCompensator( $rows = 1 )
431 return "<td width='152' rowspan='{$rows}'> </td>";
434 # This gets called immediately before the </body> tag.
436 function afterContent()
438 global $wgUser, $wgOut, $wgServer;
439 global $wgTitle, $wgLang;
441 $printfooter = "<div class=\"printfooter\">\n" . $this->printFooter() . "</div>\n";
442 return $printfooter . $this->doAfterContent();
445 function printSource() {
447 $url = htmlspecialchars( $wgTitle->getFullURL() );
448 return wfMsg( "retrievedfrom", "<a href=\"$url\">$url</a>" );
451 function printFooter() {
452 return "<p>" . $this->printSource() .
453 "</p>\n\n<p>" . $this->pageStats() . "</p>\n";
456 function doAfterContent()
458 global $wgUser, $wgOut, $wgLang;
459 $fname = 'Skin::doAfterContent';
460 wfProfileIn( $fname );
461 wfProfileIn( $fname.'-1' );
463 $s = "\n</div><br style=\"clear:both\" />\n";
464 $s .= "\n<div id='footer'>";
465 $s .= '<table border="0" cellspacing="0"><tr>';
467 wfProfileOut( $fname.'-1' );
468 wfProfileIn( $fname.'-2' );
470 $qb = $this->qbSetting();
472 $left = ($qb == 1 ||
$qb == 3);
473 if($wgLang->isRTL()) $left = !$left;
475 if ( $shove && $left ) { # Left
476 $s .= $this->getQuickbarCompensator();
478 wfProfileOut( $fname.'-2' );
479 wfProfileIn( $fname.'-3' );
480 $l = $wgLang->isRTL() ?
'right' : 'left';
481 $s .= "<td class='bottom' align='$l' valign='top'>";
483 $s .= $this->bottomLinks();
484 $s .= "\n<br />" . $this->mainPageLink()
485 . ' | ' . $this->aboutLink()
486 . ' | ' . $this->specialLink( 'recentchanges' )
487 . ' | ' . $this->searchForm()
488 . '<br /><span id="pagestats">' . $this->pageStats() . '</span>';
491 if ( $shove && !$left ) { # Right
492 $s .= $this->getQuickbarCompensator();
494 $s .= "</tr></table>\n</div>\n</div>\n";
496 wfProfileOut( $fname.'-3' );
497 wfProfileIn( $fname.'-4' );
498 if ( 0 != $qb ) { $s .= $this->quickBar(); }
499 wfProfileOut( $fname.'-4' );
500 wfProfileOut( $fname );
504 function pageTitleLinks()
506 global $wgOut, $wgTitle, $wgUser, $wgLang, $wgUseApproval, $wgRequest;
508 extract( $wgRequest->getValues( 'oldid', 'diff' ) );
509 $action = $wgRequest->getText( 'action' );
511 $s = $this->printableLink();
512 if ( wfMsg ( 'disclaimers' ) != '-' ) $s .= ' | ' . $this->makeKnownLink( wfMsg( 'disclaimerpage' ), wfMsg( 'disclaimers' ) ) ;
514 if ( $wgOut->isArticleRelated() ) {
515 if ( $wgTitle->getNamespace() == Namespace::getImage() ) {
516 $name = $wgTitle->getDBkey();
517 $link = wfEscapeHTML( Image
::wfImageUrl( $name ) );
518 $style = $this->getInternalLinkAttributes( $link, $name );
519 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>";
521 # This will show the "Approve" link if $wgUseApproval=true;
522 if ( isset ( $wgUseApproval ) && $wgUseApproval )
524 $t = $wgTitle->getDBkey();
525 $name = 'Approve this article' ;
526 $link = "http://test.wikipedia.org/w/magnus/wiki.phtml?title={$t}&action=submit&doit=1" ;
527 #wfEscapeHTML( wfImageUrl( $name ) );
528 $style = $this->getExternalLinkAttributes( $link, $name );
529 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>" ;
532 if ( 'history' == $action ||
isset( $diff ) ||
isset( $oldid ) ) {
533 $s .= ' | ' . $this->makeKnownLink( $wgTitle->getPrefixedText(),
534 wfMsg( 'currentrev' ) );
537 if ( $wgUser->getNewtalk() ) {
538 # do not show "You have new messages" text when we are viewing our
541 if(!(strcmp($wgTitle->getText(),$wgUser->getName()) == 0 &&
542 $wgTitle->getNamespace()==Namespace::getTalk(Namespace::getUser()))) {
543 $n =$wgUser->getName();
544 $tl = $this->makeKnownLink( $wgLang->getNsText(
545 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
546 wfMsg('newmessageslink') );
547 $s.= ' | <strong>'. wfMsg( 'newmessages', $tl ) . '</strong>';
551 $undelete = $this->getUndeleteLink();
552 if( !empty( $undelete ) ) {
553 $s .= ' | '.$undelete;
558 function getUndeleteLink() {
559 global $wgUser, $wgTitle, $wgLang, $action;
560 if( $wgUser->isSysop() &&
561 (($wgTitle->getArticleId() == 0) ||
($action == "history")) &&
562 ($n = $wgTitle->isDeleted() ) ) {
563 return wfMsg( 'thisisdeleted',
564 $this->makeKnownLink(
565 $wgLang->SpecialPage( 'Undelete/' . $wgTitle->getPrefixedDBkey() ),
566 wfMsg( 'restorelink', $n ) ) );
571 function printableLink()
573 global $wgOut, $wgFeedClasses, $wgRequest;
575 $baseurl = $_SERVER['REQUEST_URI'];
576 if( strpos( '?', $baseurl ) == false ) {
581 $baseurl = htmlspecialchars( $baseurl );
582 $printurl = $wgRequest->escapeAppendQuery( 'printable=yes' );
584 $s = "<a href=\"$printurl\">" . wfMsg( 'printableversion' ) . '</a>';
585 if( $wgOut->isSyndicated() ) {
586 foreach( $wgFeedClasses as $format => $class ) {
587 $feedurl = $wgRequest->escapeAppendQuery( "feed=$format" );
588 $s .= " | <a href=\"$feedurl\">{$format}</a>";
596 global $wgOut, $wgTitle, $wgUser;
598 $s = '<h1 class="pagetitle">' . htmlspecialchars( $wgOut->getPageTitle() ) . '</h1>';
599 if($wgUser->getOption( 'editsectiononrightclick' ) && $wgTitle->userCanEdit()) { $s=$this->editSectionScript(0,$s);}
603 function pageSubtitle()
607 $sub = $wgOut->getSubtitle();
609 global $wgExtraSubtitle;
610 $sub = wfMsg( 'fromwikipedia' ) . $wgExtraSubtitle;
612 $subpages = $this->subPageSubtitle();
613 $sub .= !empty($subpages)?
"</p><p class='subpages'>$subpages":'';
614 $s = "<p class='subtitle'>{$sub}</p>\n";
618 function subPageSubtitle()
620 global $wgOut,$wgTitle,$wgNamespacesWithSubpages;
622 if($wgOut->isArticle() && !empty($wgNamespacesWithSubpages[$wgTitle->getNamespace()])) {
623 $ptext=$wgTitle->getPrefixedText();
624 if(preg_match('/\//',$ptext)) {
625 $links = explode('/',$ptext);
628 foreach($links as $link) {
630 if ($c<count($links)) {
631 $growinglink .= $link;
632 $getlink = $this->makeLink( $growinglink, $link );
633 if(preg_match('/class="new"/i',$getlink)) { break; } # this is a hack, but it saves time
637 $subpages .= '< ';
639 $subpages .= $getlink;
648 function nameAndLogin()
650 global $wgUser, $wgTitle, $wgLang, $wgShowIPinHeader, $wgIP;
652 $li = $wgLang->specialPage( 'Userlogin' );
653 $lo = $wgLang->specialPage( 'Userlogout' );
656 if ( 0 == $wgUser->getID() ) {
657 if( $wgShowIPinHeader && isset( $_COOKIE[ini_get('session.name')] ) ) {
660 $tl = $this->makeKnownLink( $wgLang->getNsText(
661 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
662 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
664 $s .= $n . ' ('.$tl.')';
666 $s .= wfMsg('notloggedin');
669 $rt = $wgTitle->getPrefixedURL();
670 if ( 0 == strcasecmp( urlencode( $lo ), $rt ) ) {
672 } else { $q = "returnto={$rt}"; }
674 $s .= "\n<br />" . $this->makeKnownLink( $li,
675 wfMsg( 'login' ), $q );
677 $n = $wgUser->getName();
678 $rt = $wgTitle->getPrefixedURL();
679 $tl = $this->makeKnownLink( $wgLang->getNsText(
680 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
681 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
685 $s .= $this->makeKnownLink( $wgLang->getNsText(
686 Namespace::getUser() ) . ":{$n}", $n ) . "{$tl}<br />" .
687 $this->makeKnownLink( $lo, wfMsg( 'logout' ),
688 "returnto={$rt}" ) . ' | ' .
689 $this->specialLink( 'preferences' );
691 $s .= ' | ' . $this->makeKnownLink( wfMsg( 'helppage' ),
697 function getSearchLink() {
698 $searchPage =& Title
::makeTitle( NS_SPECIAL
, 'Search' );
699 return $searchPage->getLocalURL();
702 function escapeSearchLink() {
703 return htmlspecialchars( $this->getSearchLink() );
706 function searchForm()
709 $search = $wgRequest->getText( 'search' );
711 $s = '<form name="search" class="inline" method="post" action="'
712 . $this->escapeSearchLink() . "\">\n"
713 . '<input type="text" name="search" size="19" value="'
714 . htmlspecialchars(substr($search,0,256)) . "\" />\n"
715 . '<input type="submit" name="go" value="' . wfMsg ('go') . '" /> '
716 . '<input type="submit" name="fulltext" value="' . wfMsg ('search') . "\" />\n</form>";
726 $s = $this->mainPageLink() . $sep
727 . $this->specialLink( 'recentchanges' );
729 if ( $wgOut->isArticleRelated() ) {
730 $s .= $sep . $this->editThisPage()
731 . $sep . $this->historyLink();
733 # Many people don't like this dropdown box
734 #$s .= $sep . $this->specialPagesList();
739 function bottomLinks()
741 global $wgOut, $wgUser, $wgTitle;
745 if ( $wgOut->isArticleRelated() ) {
746 $s .= '<strong>' . $this->editThisPage() . '</strong>';
747 if ( 0 != $wgUser->getID() ) {
748 $s .= $sep . $this->watchThisPage();
750 $s .= $sep . $this->talkLink()
751 . $sep . $this->historyLink()
752 . $sep . $this->whatLinksHere()
753 . $sep . $this->watchPageLinksLink();
755 if ( $wgTitle->getNamespace() == Namespace::getUser()
756 ||
$wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser()) )
759 $id=User
::idFromName($wgTitle->getText());
760 $ip=User
::isIP($wgTitle->getText());
762 if($id ||
$ip) { # both anons and non-anons have contri list
763 $s .= $sep . $this->userContribsLink();
765 if ( 0 != $wgUser->getID() ) { # show only to signed in users
766 if($id) { # can only email non-anons
767 $s .= $sep . $this->emailUserLink();
771 if ( $wgUser->isSysop() && $wgTitle->getArticleId() ) {
772 $s .= "\n<br />" . $this->deleteThisPage() .
773 $sep . $this->protectThisPage() .
774 $sep . $this->moveThisPage();
776 $s .= "<br />\n" . $this->otherLanguages();
783 global $wgOut, $wgLang, $wgArticle, $wgRequest;
784 global $wgDisableCounters, $wgMaxCredits, $wgShowCreditsIfMax;
786 extract( $wgRequest->getValues( 'oldid', 'diff' ) );
787 if ( ! $wgOut->isArticle() ) { return ''; }
788 if ( isset( $oldid ) ||
isset( $diff ) ) { return ''; }
789 if ( 0 == $wgArticle->getID() ) { return ''; }
792 if ( !$wgDisableCounters ) {
793 $count = $wgLang->formatNum( $wgArticle->getCount() );
795 $s = wfMsg( 'viewcount', $count );
799 if (isset($wgMaxCredits) && $wgMaxCredits != 0) {
800 require_once("Credits.php");
801 $s .= ' ' . getCredits($wgArticle, $wgMaxCredits, $wgShowCreditsIfMax);
803 $s .= $this->lastModified();
806 return $s . ' ' . $this->getCopyright();
809 function getCopyright() {
810 global $wgRightsPage, $wgRightsUrl, $wgRightsText, $wgRequest;
813 $oldid = $wgRequest->getVal( 'oldid' );
814 $diff = $wgRequest->getVal( 'diff' );
816 if ( !is_null( $oldid ) && is_null( $diff ) && wfMsg( 'history_copyright' ) !== '-' ) {
817 $msg = 'history_copyright';
823 if( $wgRightsPage ) {
824 $link = $this->makeKnownLink( $wgRightsPage, $wgRightsText );
825 } elseif( $wgRightsUrl ) {
826 $link = $this->makeExternalLink( $wgRightsUrl, $wgRightsText );
831 $out .= wfMsg( $msg, $link );
835 function getCopyrightIcon() {
836 global $wgRightsPage, $wgRightsUrl, $wgRightsText, $wgRightsIcon;
838 if( $wgRightsIcon ) {
839 $icon = htmlspecialchars( $wgRightsIcon );
841 $url = htmlspecialchars( $wgRightsUrl );
842 $out .= '<a href="'.$url.'">';
844 $text = htmlspecialchars( $wgRightsText );
845 $out .= "<img src=\"$icon\" alt='$text' />";
853 function getPoweredBy() {
855 $url = htmlspecialchars( "$wgStylePath/images/poweredby_mediawiki_88x31.png" );
856 $img = '<a href="http://www.mediawiki.org/"><img src="'.$url.'" alt="MediaWiki" /></a>';
860 function lastModified()
862 global $wgLang, $wgArticle;
864 $timestamp = $wgArticle->getTimestamp();
866 $d = $wgLang->timeanddate( $wgArticle->getTimestamp(), true );
867 $s = ' ' . wfMsg( 'lastmodified', $d );
874 function logoText( $align = '' )
876 if ( '' != $align ) { $a = ' align="'.$align.'"'; }
879 $mp = wfMsg( 'mainpage' );
880 $titleObj = Title
::newFromText( $mp );
881 $s = '<a href="' . $titleObj->escapeLocalURL()
882 . '"><img'.$a.' src="'
883 . $this->getLogo() . '" alt="' . "[{$mp}]\" /></a>";
889 global $wgOut, $wgTitle, $wgUser, $wgRequest, $wgLang;
890 global $wgDisableUploads, $wgRemoteUploads;
892 $fname = 'Skin::quickBar';
893 wfProfileIn( $fname );
895 $action = $wgRequest->getText( 'action' );
896 $wpPreview = $wgRequest->getBool( 'wpPreview' );
897 $tns=$wgTitle->getNamespace();
899 $s = "\n<div id='quickbar'>";
900 $s .= "\n" . $this->logoText() . "\n<hr class='sep' />";
903 $s .= $this->mainPageLink()
904 . $sep . $this->specialLink( 'recentchanges' )
905 . $sep . $this->specialLink( 'randompage' );
906 if ($wgUser->getID()) {
907 $s.= $sep . $this->specialLink( 'watchlist' ) ;
908 $s .= $sep .$this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
909 wfMsg( 'mycontris' ), 'target=' . wfUrlencode($wgUser->getName() ) );
912 // only show watchlist link if logged in
913 if ( wfMsg ( 'currentevents' ) != '-' ) $s .= $sep . $this->makeKnownLink( wfMsg( 'currentevents' ), '' ) ;
914 $s .= "\n<br /><hr class='sep' />";
915 $articleExists = $wgTitle->getArticleId();
916 if ( $wgOut->isArticle() ||
$action =='edit' ||
$action =='history' ||
$wpPreview) {
917 if($wgOut->isArticle()) {
918 $s .= '<strong>' . $this->editThisPage() . '</strong>';
919 } else { # backlink to the article in edit or history mode
920 if($articleExists){ # no backlink if no article
923 $text = wfMsg('articlepage');
926 $text = wfMsg('viewtalkpage');
929 $text = wfMsg('userpage');
932 $text = wfMsg('viewtalkpage');
935 $text = wfMsg('wikipediapage');
938 $text = wfMsg('viewtalkpage');
941 $text = wfMsg('imagepage');
944 $text = wfMsg('viewtalkpage');
947 $text= wfMsg('articlepage');
950 $link = $wgTitle->getText();
951 if ($nstext = $wgLang->getNsText($tns) ) { # add namespace if necessary
952 $link = $nstext . ':' . $link ;
955 $s .= $this->makeLink( $link, $text );
956 } elseif( $wgTitle->getNamespace() != Namespace::getSpecial() ) {
957 # we just throw in a "New page" text to tell the user that he's in edit mode,
958 # and to avoid messing with the separator that is prepended to the next item
959 $s .= '<strong>' . wfMsg('newpage') . '</strong>';
965 if( $tns%2
&& $action!='edit' && !$wpPreview) {
966 $s.= '<br />'.$this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg('postcomment'),'action=edit§ion=new');
970 watching could cause problems in edit mode:
971 if user edits article, then loads "watch this article" in background and then saves
972 article with "Watch this article" checkbox disabled, the article is transparently
973 unwatched. Therefore we do not show the "Watch this page" link in edit mode
975 if ( 0 != $wgUser->getID() && $articleExists) {
976 if($action!='edit' && $action != 'submit' )
978 $s .= $sep . $this->watchThisPage();
980 if ( $wgTitle->userCanEdit() )
981 $s .= $sep . $this->moveThisPage();
983 if ( $wgUser->isSysop() and $articleExists ) {
984 $s .= $sep . $this->deleteThisPage() .
985 $sep . $this->protectThisPage();
987 $s .= $sep . $this->talkLink();
988 if ($articleExists && $action !='history') {
989 $s .= $sep . $this->historyLink();
991 $s.=$sep . $this->whatLinksHere();
993 if($wgOut->isArticleRelated()) {
994 $s .= $sep . $this->watchPageLinksLink();
997 if ( Namespace::getUser() == $wgTitle->getNamespace()
998 ||
$wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser())
1001 $id=User
::idFromName($wgTitle->getText());
1002 $ip=User
::isIP($wgTitle->getText());
1005 $s .= $sep . $this->userContribsLink();
1007 if ( 0 != $wgUser->getID() ) {
1008 if($id) { # can only email real users
1009 $s .= $sep . $this->emailUserLink();
1013 $s .= "\n<br /><hr class='sep' />";
1016 if ( 0 != $wgUser->getID() && ( !$wgDisableUploads ||
$wgRemoteUploads ) ) {
1017 $s .= $this->specialLink( 'upload' ) . $sep;
1019 $s .= $this->specialLink( 'specialpages' )
1020 . $sep . $this->bugReportsLink();
1022 global $wgSiteSupportPage;
1023 if( $wgSiteSupportPage ) {
1024 $s .= "\n<br /><a href=\"" . htmlspecialchars( $wgSiteSupportPage ) .
1025 '" class="internal">' . wfMsg( 'sitesupport' ) . '</a>';
1028 $s .= "\n<br /></div>\n";
1029 wfProfileOut( $fname );
1033 function specialPagesList()
1035 global $wgUser, $wgOut, $wgLang, $wgServer, $wgRedirectScript;
1036 require_once('SpecialPage.php');
1038 $pages = SpecialPage
::getPages();
1040 foreach ( $pages[''] as $name => $page ) {
1041 $a[$name] = $page->getDescription();
1043 if ( $wgUser->isSysop() )
1045 foreach ( $pages['sysop'] as $name => $page ) {
1046 $a[$name] = $page->getDescription();
1049 if ( $wgUser->isDeveloper() )
1051 foreach ( $pages['developer'] as $name => $page ) {
1052 $a[$name] = $page->getDescription() ;
1055 $go = wfMsg( 'go' );
1056 $sp = wfMsg( 'specialpages' );
1057 $spp = $wgLang->specialPage( 'Specialpages' );
1059 $s = '<form id="specialpages" method="get" class="inline" ' .
1060 'action="' . htmlspecialchars( "{$wgServer}{$wgRedirectScript}" ) . "\">\n";
1061 $s .= "<select name=\"wpDropdown\">\n";
1062 $s .= "<option value=\"{$spp}\">{$sp}</option>\n";
1064 foreach ( $a as $name => $desc ) {
1065 $p = $wgLang->specialPage( $name );
1066 $s .= "<option value=\"{$p}\">{$desc}</option>\n";
1068 $s .= "</select>\n";
1069 $s .= "<input type='submit' value=\"{$go}\" name='redirect' />\n";
1074 function mainPageLink()
1076 $mp = wfMsg( 'mainpage' );
1077 $s = $this->makeKnownLink( $mp, $mp );
1081 function copyrightLink()
1083 $s = $this->makeKnownLink( wfMsg( 'copyrightpage' ),
1084 wfMsg( 'copyrightpagename' ) );
1088 function aboutLink()
1090 $s = $this->makeKnownLink( wfMsg( 'aboutpage' ),
1091 wfMsg( 'aboutwikipedia' ) );
1096 function disclaimerLink()
1098 $s = $this->makeKnownLink( wfMsg( 'disclaimerpage' ),
1099 wfMsg( 'disclaimers' ) );
1103 function editThisPage()
1105 global $wgOut, $wgTitle, $wgRequest;
1107 $oldid = $wgRequest->getVal( 'oldid' );
1108 $diff = $wgRequest->getVal( 'diff' );
1109 $redirect = $wgRequest->getVal( 'redirect' );
1111 if ( ! $wgOut->isArticleRelated() ) {
1112 $s = wfMsg( 'protectedpage' );
1114 $n = $wgTitle->getPrefixedText();
1115 if ( $wgTitle->userCanEdit() ) {
1116 $t = wfMsg( 'editthispage' );
1118 #$t = wfMsg( "protectedpage" );
1119 $t = wfMsg( 'viewsource' );
1123 if ( !is_null( $redirect ) ) { $red = "&redirect={$redirect}"; }
1124 if ( $oldid && ! isset( $diff ) ) {
1125 $oid = "&oldid={$oldid}";
1127 $s = $this->makeKnownLink( $n, $t, "action=edit{$oid}{$red}" );
1132 function deleteThisPage()
1134 global $wgUser, $wgOut, $wgTitle, $wgRequest;
1136 $diff = $wgRequest->getVal( 'diff' );
1137 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
1138 $n = $wgTitle->getPrefixedText();
1139 $t = wfMsg( 'deletethispage' );
1141 $s = $this->makeKnownLink( $n, $t, 'action=delete' );
1148 function protectThisPage()
1150 global $wgUser, $wgOut, $wgTitle, $wgRequest;
1152 $diff = $wgRequest->getVal( 'diff' );
1153 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
1154 $n = $wgTitle->getPrefixedText();
1156 if ( $wgTitle->isProtected() ) {
1157 $t = wfMsg( 'unprotectthispage' );
1158 $q = 'action=unprotect';
1160 $t = wfMsg( 'protectthispage' );
1161 $q = 'action=protect';
1163 $s = $this->makeKnownLink( $n, $t, $q );
1170 function watchThisPage()
1172 global $wgUser, $wgOut, $wgTitle;
1174 if ( $wgOut->isArticleRelated() ) {
1175 $n = $wgTitle->getPrefixedText();
1177 if ( $wgTitle->userIsWatching() ) {
1178 $t = wfMsg( 'unwatchthispage' );
1179 $q = 'action=unwatch';
1181 $t = wfMsg( 'watchthispage' );
1182 $q = 'action=watch';
1184 $s = $this->makeKnownLink( $n, $t, $q );
1186 $s = wfMsg( 'notanarticle' );
1191 function moveThisPage()
1193 global $wgTitle, $wgLang;
1195 if ( $wgTitle->userCanEdit() ) {
1196 $s = $this->makeKnownLink( $wgLang->specialPage( 'Movepage' ),
1197 wfMsg( 'movethispage' ), 'target=' . $wgTitle->getPrefixedURL() );
1198 } // no message if page is protected - would be redundant
1202 function historyLink()
1206 $s = $this->makeKnownLink( $wgTitle->getPrefixedText(),
1207 wfMsg( 'history' ), 'action=history' );
1211 function whatLinksHere()
1213 global $wgTitle, $wgLang;
1215 $s = $this->makeKnownLink( $wgLang->specialPage( 'Whatlinkshere' ),
1216 wfMsg( 'whatlinkshere' ), 'target=' . $wgTitle->getPrefixedURL() );
1220 function userContribsLink()
1222 global $wgTitle, $wgLang;
1224 $s = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
1225 wfMsg( 'contributions' ), 'target=' . $wgTitle->getPartialURL() );
1229 function emailUserLink()
1231 global $wgTitle, $wgLang;
1233 $s = $this->makeKnownLink( $wgLang->specialPage( 'Emailuser' ),
1234 wfMsg( 'emailuser' ), 'target=' . $wgTitle->getPartialURL() );
1238 function watchPageLinksLink()
1240 global $wgOut, $wgTitle, $wgLang;
1242 if ( ! $wgOut->isArticleRelated() ) {
1243 $s = '(' . wfMsg( 'notanarticle' ) . ')';
1245 $s = $this->makeKnownLink( $wgLang->specialPage(
1246 'Recentchangeslinked' ), wfMsg( 'recentchangeslinked' ),
1247 'target=' . $wgTitle->getPrefixedURL() );
1252 function otherLanguages()
1254 global $wgOut, $wgLang, $wgTitle, $wgUseNewInterlanguage;
1256 $a = $wgOut->getLanguageLinks();
1257 if ( 0 == count( $a ) ) {
1258 if ( !$wgUseNewInterlanguage ) return '';
1259 $ns = $wgLang->getNsIndex ( $wgTitle->getNamespace () ) ;
1260 if ( $ns != 0 AND $ns != 1 ) return '' ;
1262 $x = 'mode=addlink&xt='.$wgTitle->getDBkey() ;
1263 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1264 wfMsg( 'intl' ) , $x );
1267 if ( !$wgUseNewInterlanguage ) {
1268 $s = wfMsg( 'otherlanguages' ) . ': ';
1270 global $wgLanguageCode ;
1271 $x = 'mode=zoom&xt='.$wgTitle->getDBkey() ;
1272 $x .= '&xl='.$wgLanguageCode ;
1273 $s = $this->makeKnownLink( $wgLang->specialPage( 'Intl' ),
1274 wfMsg( 'otherlanguages' ) , $x ) . ': ' ;
1277 $s = wfMsg( 'otherlanguages' ) . ': ';
1279 if($wgLang->isRTL()) $s .= '<span dir="LTR">';
1280 foreach( $a as $l ) {
1281 if ( ! $first ) { $s .= ' | '; }
1284 $nt = Title
::newFromText( $l );
1285 $url = $nt->getFullURL();
1286 $text = $wgLang->getLanguageName( $nt->getInterwiki() );
1288 if ( '' == $text ) { $text = $l; }
1289 $style = $this->getExternalLinkAttributes( $l, $text );
1290 $s .= "<a href=\"{$url}\"{$style}>{$text}</a>";
1292 if($wgLang->isRTL()) $s .= '</span>';
1296 function bugReportsLink()
1298 $s = $this->makeKnownLink( wfMsg( 'bugreportspage' ),
1299 wfMsg( 'bugreports' ) );
1305 global $wgLinkCache;
1306 $t1 = Title
::newFromText( gmdate( 'F j' ) );
1307 $t2 = Title
::newFromText( gmdate( 'Y' ) );
1309 $wgLinkCache->suspend();
1310 $id = $t1->getArticleID();
1311 $wgLinkCache->resume();
1314 $s = $this->makeBrokenLink( $t1->getText() );
1316 $s = $this->makeKnownLink( $t1->getText() );
1320 $wgLinkCache->suspend();
1321 $id = $t2->getArticleID();
1322 $wgLinkCache->resume();
1325 $s .= $this->makeBrokenLink( $t2->getText() );
1327 $s .= $this->makeKnownLink( $t2->getText() );
1334 global $wgLang, $wgTitle, $wgLinkCache;
1336 $tns = $wgTitle->getNamespace();
1337 if ( -1 == $tns ) { return ''; }
1339 $pn = $wgTitle->getText();
1340 $tp = wfMsg( 'talkpage' );
1341 if ( Namespace::isTalk( $tns ) ) {
1342 $lns = Namespace::getSubject( $tns );
1345 $text = wfMsg('articlepage');
1348 $text = wfMsg('userpage');
1351 $text = wfMsg('wikipediapage');
1354 $text = wfMsg('imagepage');
1357 $text= wfMsg('articlepage');
1361 $lns = Namespace::getTalk( $tns );
1364 $n = $wgLang->getNsText( $lns );
1365 if ( '' == $n ) { $link = $pn; }
1366 else { $link = $n.':'.$pn; }
1368 $wgLinkCache->suspend();
1369 $s = $this->makeLink( $link, $text );
1370 $wgLinkCache->resume();
1375 function commentLink()
1377 global $wgLang, $wgTitle, $wgLinkCache;
1379 $tns = $wgTitle->getNamespace();
1380 if ( -1 == $tns ) { return ''; }
1382 $lns = ( Namespace::isTalk( $tns ) ) ?
$tns : Namespace::getTalk( $tns );
1384 # assert Namespace::isTalk( $lns )
1386 $n = $wgLang->getNsText( $lns );
1387 $pn = $wgTitle->getText();
1391 $wgLinkCache->suspend();
1392 $s = $this->makeKnownLink($link, wfMsg('postcomment'), 'action=edit§ion=new');
1393 $wgLinkCache->resume();
1398 # After all the page content is transformed into HTML, it makes
1399 # a final pass through here for things like table backgrounds.
1401 function transformContent( $text )
1406 # Note: This function MUST call getArticleID() on the link,
1407 # otherwise the cache won't get updated properly. See LINKCACHE.DOC.
1409 function makeLink( $title, $text = '', $query = '', $trail = '' ) {
1410 wfProfileIn( 'Skin::makeLink' );
1411 $nt = Title
::newFromText( $title );
1413 $result = $this->makeLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1415 wfDebug( 'Invalid title passed to Skin::makeLink(): "'.$title."\"\n" );
1416 $result = $text == "" ?
$title : $text;
1419 wfProfileOut( 'Skin::makeLink' );
1423 function makeKnownLink( $title, $text = '', $query = '', $trail = '', $prefix = '',$aprops = '') {
1424 $nt = Title
::newFromText( $title );
1426 return $this->makeKnownLinkObj( Title
::newFromText( $title ), $text, $query, $trail, $prefix , $aprops );
1428 wfDebug( 'Invalid title passed to Skin::makeKnownLink(): "'.$title."\"\n" );
1429 return $text == '' ?
$title : $text;
1433 function makeBrokenLink( $title, $text = '', $query = '', $trail = '' ) {
1434 $nt = Title
::newFromText( $title );
1436 return $this->makeBrokenLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1438 wfDebug( 'Invalid title passed to Skin::makeBrokenLink(): "'.$title."\"\n" );
1439 return $text == '' ?
$title : $text;
1443 function makeStubLink( $title, $text = '', $query = '', $trail = '' ) {
1444 $nt = Title
::newFromText( $title );
1446 return $this->makeStubLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1448 wfDebug( 'Invalid title passed to Skin::makeStubLink(): "'.$title."\"\n" );
1449 return $text == '' ?
$title : $text;
1453 # Pass a title object, not a title string
1454 function makeLinkObj( &$nt, $text= '', $query = '', $trail = '', $prefix = '' )
1456 global $wgOut, $wgUser;
1457 $fname = 'Skin::makeLinkObj';
1461 return "<!-- ERROR -->{$prefix}{$text}{$trail}";
1463 if ( $nt->isExternal() ) {
1464 $u = $nt->getFullURL();
1465 $link = $nt->getPrefixedURL();
1466 if ( '' == $text ) { $text = $nt->getPrefixedText(); }
1467 $style = $this->getExternalLinkAttributes( $link, $text, 'extiw' );
1470 if ( '' != $trail ) {
1471 if ( preg_match( '/^([a-z]+)(.*)$$/sD', $trail, $m ) ) {
1476 $retVal = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1477 } elseif ( 0 == $nt->getNamespace() && "" == $nt->getText() ) {
1478 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1479 } elseif ( ( -1 == $nt->getNamespace() ) ||
1480 ( Namespace::getImage() == $nt->getNamespace() ) ) {
1481 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1483 if ( $this->postParseLinkColour() ) {
1485 if ( '' != $trail ) {
1486 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1492 # Allows wiki to bypass using linkcache, see OutputPage::parseLinkHolders()
1493 $retVal = '<!--LINK ' . implode( ' ', array( $nt->getNamespace(), $nt->getDBkey(),
1494 $query, $prefix . $text . $inside ) ) . "-->{$trail}";
1496 # Work out link colour immediately
1497 $aid = $nt->getArticleID() ;
1499 $retVal = $this->makeBrokenLinkObj( $nt, $text, $query, $trail, $prefix );
1501 $threshold = $wgUser->getOption('stubthreshold') ;
1502 if ( $threshold > 0 ) {
1503 $dbr =& wfGetDB( DB_SLAVE
);
1504 $s = $dbr->selectRow( 'cur', array( 'LENGTH(cur_text) AS x', 'cur_namespace',
1505 'cur_is_redirect' ), array( 'cur_id' => $aid ), $fname ) ;
1506 if ( $s !== false ) {
1508 if ( $s->cur_is_redirect
OR $s->cur_namespace
!= 0 ) {
1509 $size = $threshold*2 ; # Really big
1511 $dbr->freeResult( $res );
1513 $size = $threshold*2 ; # Really big
1518 if ( $size < $threshold ) {
1519 $retVal = $this->makeStubLinkObj( $nt, $text, $query, $trail, $prefix );
1521 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1529 # Pass a title object, not a title string
1530 function makeKnownLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' , $aprops = '')
1532 global $wgOut, $wgTitle, $wgInputEncoding;
1534 $fname = 'Skin::makeKnownLinkObj';
1535 wfProfileIn( $fname );
1537 if ( !is_object( $nt ) ) {
1540 $link = $nt->getPrefixedURL();
1542 if ( '' == $link ) {
1544 if ( '' == $text ) {
1545 $text = htmlspecialchars( $nt->getFragment() );
1548 $u = $nt->escapeLocalURL( $query );
1550 if ( '' != $nt->getFragment() ) {
1551 $anchor = urlencode( do_html_entity_decode( str_replace(' ', '_', $nt->getFragment()), ENT_COMPAT
, $wgInputEncoding ) );
1552 $replacearray = array(
1556 $u .= '#' . str_replace(array_keys($replacearray),array_values($replacearray),$anchor);
1558 if ( '' == $text ) {
1559 $text = htmlspecialchars( $nt->getPrefixedText() );
1561 $style = $this->getInternalLinkAttributesObj( $nt, $text );
1564 if ( '' != $trail ) {
1565 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1570 $r = "<a href=\"{$u}\"{$style}{$aprops}>{$prefix}{$text}{$inside}</a>{$trail}";
1571 wfProfileOut( $fname );
1575 # Pass a title object, not a title string
1576 function makeBrokenLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
1578 global $wgOut, $wgUser;
1580 $fname = 'Skin::makeBrokenLinkObj';
1581 wfProfileIn( $fname );
1583 if ( '' == $query ) {
1586 $q = 'action=edit&'.$query;
1588 $u = $nt->escapeLocalURL( $q );
1590 if ( '' == $text ) {
1591 $text = htmlspecialchars( $nt->getPrefixedText() );
1593 $style = $this->getInternalLinkAttributesObj( $nt, $text, "yes" );
1596 if ( '' != $trail ) {
1597 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1602 if ( $wgUser->getOption( 'highlightbroken' ) ) {
1603 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1605 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>?</a>{$trail}";
1608 wfProfileOut( $fname );
1612 # Pass a title object, not a title string
1613 function makeStubLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
1615 global $wgOut, $wgUser;
1617 $link = $nt->getPrefixedURL();
1619 $u = $nt->escapeLocalURL( $query );
1621 if ( '' == $text ) {
1622 $text = htmlspecialchars( $nt->getPrefixedText() );
1624 $style = $this->getInternalLinkAttributesObj( $nt, $text, 'stub' );
1627 if ( '' != $trail ) {
1628 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1633 if ( $wgUser->getOption( 'highlightbroken' ) ) {
1634 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1636 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>!</a>{$trail}";
1641 function makeSelfLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
1643 $u = $nt->escapeLocalURL( $query );
1644 if ( '' == $text ) {
1645 $text = htmlspecialchars( $nt->getPrefixedText() );
1648 if ( '' != $trail ) {
1649 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1654 return "<strong>{$prefix}{$text}{$inside}</strong>{$trail}";
1657 /* these are used extensively in SkinPHPTal, but also some other places */
1658 /*static*/ function makeSpecialUrl( $name, $urlaction='' ) {
1659 $title = Title
::makeTitle( NS_SPECIAL
, $name );
1660 $this->checkTitle($title, $name);
1661 return $title->getLocalURL( $urlaction );
1663 /*static*/ function makeTalkUrl ( $name, $urlaction='' ) {
1664 $title = Title
::newFromText( $name );
1665 $title = $title->getTalkPage();
1666 $this->checkTitle($title, $name);
1667 return $title->getLocalURL( $urlaction );
1669 /*static*/ function makeArticleUrl ( $name, $urlaction='' ) {
1670 $title = Title
::newFromText( $name );
1671 $title= $title->getSubjectPage();
1672 $this->checkTitle($title, $name);
1673 return $title->getLocalURL( $urlaction );
1675 /*static*/ function makeI18nUrl ( $name, $urlaction='' ) {
1676 $title = Title
::newFromText( wfMsg($name) );
1677 $this->checkTitle($title, $name);
1678 return $title->getLocalURL( $urlaction );
1680 /*static*/ function makeUrl ( $name, $urlaction='' ) {
1681 $title = Title
::newFromText( $name );
1682 $this->checkTitle($title, $name);
1683 return $title->getLocalURL( $urlaction );
1685 # this can be passed the NS number as defined in Language.php
1686 /*static*/ function makeNSUrl( $name, $urlaction='', $namespace=0 ) {
1687 $title = Title
::makeTitle( $namespace, $name );
1688 $this->checkTitle($title, $name);
1689 return $title->getLocalURL( $urlaction );
1692 /* these return an array with the 'href' and boolean 'exists' */
1693 /*static*/ function makeUrlDetails ( $name, $urlaction='' ) {
1694 $title = Title
::newFromText( $name );
1695 $this->checkTitle($title, $name);
1697 'href' => $title->getLocalURL( $urlaction ),
1698 'exists' => $title->getArticleID() != 0?
true:false
1701 /*static*/ function makeTalkUrlDetails ( $name, $urlaction='' ) {
1702 $title = Title
::newFromText( $name );
1703 $title = $title->getTalkPage();
1704 $this->checkTitle($title, $name);
1706 'href' => $title->getLocalURL( $urlaction ),
1707 'exists' => $title->getArticleID() != 0?
true:false
1710 /*static*/ function makeArticleUrlDetails ( $name, $urlaction='' ) {
1711 $title = Title
::newFromText( $name );
1712 $title= $title->getSubjectPage();
1713 $this->checkTitle($title, $name);
1715 'href' => $title->getLocalURL( $urlaction ),
1716 'exists' => $title->getArticleID() != 0?
true:false
1719 /*static*/ function makeI18nUrlDetails ( $name, $urlaction='' ) {
1720 $title = Title
::newFromText( wfMsg($name) );
1721 $this->checkTitle($title, $name);
1723 'href' => $title->getLocalURL( $urlaction ),
1724 'exists' => $title->getArticleID() != 0?
true:false
1728 # make sure we have some title to operate on
1729 /*static*/ function checkTitle ( &$title, &$name ) {
1730 if(!is_object($title)) {
1731 $title = Title
::newFromText( $name );
1732 if(!is_object($title)) {
1733 $title = Title
::newFromText( '--error: link target missing--' );
1738 function fnamePart( $url )
1740 $basename = strrchr( $url, '/' );
1741 if ( false === $basename ) { $basename = $url; }
1742 else { $basename = substr( $basename, 1 ); }
1743 return wfEscapeHTML( $basename );
1746 function makeImage( $url, $alt = '' )
1750 if ( '' == $alt ) { $alt = $this->fnamePart( $url ); }
1751 $s = '<img src="'.$url.'" alt="'.$alt.'" />';
1755 function makeImageLink( $name, $url, $alt = '' ) {
1756 $nt = Title
::makeTitle( Namespace::getImage(), $name );
1757 return $this->makeImageLinkObj( $nt, $alt );
1760 function makeImageLinkObj( $nt, $alt = '' ) {
1761 global $wgLang, $wgUseImageResize;
1762 $img = Image
::newFromTitle( $nt );
1763 $url = $img->getURL();
1766 $prefix = $postfix = '';
1768 if ( $wgUseImageResize ) {
1769 # Check if the alt text is of the form "options|alt text"
1771 # * thumbnail make a thumbnail with enlarge-icon and caption, alignment depends on lang
1772 # * left no resizing, just left align. label is used for alt= only
1773 # * right same, but right aligned
1774 # * none same, but not aligned
1775 # * ___px scale to ___ pixels width, no aligning. e.g. use in taxobox
1776 # * center center the image
1777 # * framed Keep original image size, no magnify-button.
1779 $part = explode( '|', $alt);
1781 $mwThumb =& MagicWord
::get( MAG_IMG_THUMBNAIL
);
1782 $mwLeft =& MagicWord
::get( MAG_IMG_LEFT
);
1783 $mwRight =& MagicWord
::get( MAG_IMG_RIGHT
);
1784 $mwNone =& MagicWord
::get( MAG_IMG_NONE
);
1785 $mwWidth =& MagicWord
::get( MAG_IMG_WIDTH
);
1786 $mwCenter =& MagicWord
::get( MAG_IMG_CENTER
);
1787 $mwFramed =& MagicWord
::get( MAG_IMG_FRAMED
);
1788 $alt = $part[count($part)-1];
1790 $height = $framed = $thumb = false;
1791 $manual_thumb = "" ;
1793 foreach( $part as $key => $val ) {
1794 $val_parts = explode ( "=" , $val , 2 ) ;
1795 $left_part = array_shift ( $val_parts ) ;
1796 if ( ! is_null( $mwThumb->matchVariableStartToEnd($val) ) ) {
1798 } elseif ( count ( $val_parts ) == 1 && ! is_null( $mwThumb->matchVariableStartToEnd($left_part) ) ) {
1799 # use manually specified thumbnail
1801 $manual_thumb = array_shift ( $val_parts ) ;
1802 } elseif ( ! is_null( $mwRight->matchVariableStartToEnd($val) ) ) {
1803 # remember to set an alignment, don't render immediately
1805 } elseif ( ! is_null( $mwLeft->matchVariableStartToEnd($val) ) ) {
1806 # remember to set an alignment, don't render immediately
1808 } elseif ( ! is_null( $mwCenter->matchVariableStartToEnd($val) ) ) {
1809 # remember to set an alignment, don't render immediately
1811 } elseif ( ! is_null( $mwNone->matchVariableStartToEnd($val) ) ) {
1812 # remember to set an alignment, don't render immediately
1814 } elseif ( ! is_null( $match = $mwWidth->matchVariableStartToEnd($val) ) ) {
1815 # $match is the image width in pixels
1816 if ( preg_match( '/^([0-9]*)x([0-9]*)$/', $match, $m ) ) {
1817 $width = intval( $m[1] );
1818 $height = intval( $m[2] );
1820 $width = intval($match);
1822 } elseif ( ! is_null( $mwFramed->matchVariableStartToEnd($val) ) ) {
1826 if ( 'center' == $align )
1828 $prefix = '<span style="text-align: center">';
1829 $postfix = '</span>';
1833 if ( $thumb ||
$framed ) {
1835 # Create a thumbnail. Alignment depends on language
1836 # writing direction, # right aligned for left-to-right-
1837 # languages ("Western languages"), left-aligned
1838 # for right-to-left-languages ("Semitic languages")
1840 # If thumbnail width has not been provided, it is set
1841 # here to 180 pixels
1842 if ( $align == '' ) {
1843 $align = $wgLang->isRTL() ?
'left' : 'right';
1845 if ( ! isset($width) ) {
1848 return $prefix.$this->makeThumbLinkObj( $img, $alt, $align, $width, $height, $framed, $manual_thumb ).$postfix;
1850 } elseif ( isset($width) ) {
1852 # Create a resized image, without the additional thumbnail
1855 if ( ( ! $height === false )
1856 && ( $img->getHeight() * $width / $img->getWidth() > $height ) ) {
1857 print "height=$height<br>\nimg->getHeight() = ".$img->getHeight()."<br>\n";
1858 print 'rescaling by factor '. $height / $img->getHeight() . "<br>\n";
1859 $width = $img->getWidth() * $height / $img->getHeight();
1861 if ( '' == $manual_thumb ) $url = $img->createThumb( $width );
1863 } # endif $wgUseImageResize
1865 if ( empty( $alt ) ) {
1866 $alt = preg_replace( '/\.(.+?)^/', '', $img->getName() );
1868 $alt = htmlspecialchars( $alt );
1870 $u = $nt->escapeLocalURL();
1873 $s = wfMsg( 'missingimage', $img->getName() );
1874 $s .= "<br>{$alt}<br>{$url}<br>\n";
1876 $s = '<a href="'.$u.'" class="image" title="'.$alt.'">' .
1877 '<img src="'.$url.'" alt="'.$alt.'" /></a>';
1879 if ( '' != $align ) {
1880 $s = "<div class=\"float{$align}\"><span>{$s}</span></div>";
1882 return str_replace("\n", ' ',$prefix.$s.$postfix);
1885 # Make HTML for a thumbnail including image, border and caption
1886 # $img is an Image object
1887 function makeThumbLinkObj( $img, $label = '', $align = 'right', $boxwidth = 180, $boxheight=false, $framed=false , $manual_thumb = "" ) {
1888 global $wgStylePath, $wgLang;
1889 # $image = Title::makeTitle( Namespace::getImage(), $name );
1890 $url = $img->getURL();
1892 #$label = htmlspecialchars( $label );
1893 $alt = preg_replace( '/<[^>]*>/', '', $label);
1894 $alt = htmlspecialchars( $alt );
1896 $width = $height = 0;
1897 if ( $img->exists() )
1899 $width = $img->getWidth();
1900 $height = $img->getHeight();
1902 if ( 0 == $width ||
0 == $height )
1904 $width = $height = 200;
1906 if ( $boxwidth == 0 )
1912 // Use image dimensions, don't scale
1914 $oboxwidth = $boxwidth +
2;
1915 $boxheight = $height;
1918 $h = intval( $height/($width/$boxwidth) );
1919 $oboxwidth = $boxwidth +
2;
1920 if ( ( ! $boxheight === false ) && ( $h > $boxheight ) )
1922 $boxwidth *= $boxheight/$h;
1926 if ( '' == $manual_thumb ) $thumbUrl = $img->createThumb( $boxwidth );
1929 if ( $manual_thumb != '' ) # Use manually specified thumbnail
1931 $manual_title = Title
::makeTitle( Namespace::getImage(), $manual_thumb ); #new Title ( $manual_thumb ) ;
1932 $manual_img = Image
::newFromTitle( $manual_title );
1933 $thumbUrl = $manual_img->getURL();
1934 if ( $manual_img->exists() )
1936 $width = $manual_img->getWidth();
1937 $height = $manual_img->getHeight();
1938 $boxwidth = $width ;
1939 $boxheight = $height ;
1940 $oboxwidth = $boxwidth +
2 ;
1944 $u = $img->getEscapeLocalURL();
1946 $more = htmlspecialchars( wfMsg( 'thumbnail-more' ) );
1947 $magnifyalign = $wgLang->isRTL() ?
'left' : 'right';
1948 $textalign = $wgLang->isRTL() ?
' style="text-align:right"' : '';
1950 $s = "<div class=\"thumb t{$align}\"><div style=\"width:{$oboxwidth}px;\">";
1951 if ( $thumbUrl == '' ) {
1952 $s .= wfMsg( 'missingimage', $img->getName() );
1955 $s .= '<a href="'.$u.'" class="internal" title="'.$alt.'">'.
1956 '<img src="'.$thumbUrl.'" alt="'.$alt.'" ' .
1957 'width="'.$boxwidth.'" height="'.$boxheight.'" /></a>';
1961 $zoomicon = '<div class="magnify" style="float:'.$magnifyalign.'">'.
1962 '<a href="'.$u.'" class="internal" title="'.$more.'">'.
1963 '<img src="'.$wgStylePath.'/images/magnify-clip.png" ' .
1964 'width="15" height="11" alt="'.$more.'" /></a></div>';
1967 $s .= ' <div class="thumbcaption" '.$textalign.'>'.$zoomicon.$label."</div></div></div>";
1968 return str_replace("\n", ' ', $s);
1971 function makeMediaLink( $name, $url, $alt = "" ) {
1972 $nt = Title
::makeTitle( Namespace::getMedia(), $name );
1973 return $this->makeMediaLinkObj( $nt, $alt );
1976 function makeMediaLinkObj( $nt, $alt = "" )
1978 if ( ! isset( $nt ) )
1980 ### HOTFIX. Instead of breaking, return empty string.
1983 $name = $nt->getDBKey();
1984 $url = Image
::wfImageUrl( $name );
1985 if ( empty( $alt ) ) {
1986 $alt = preg_replace( '/\.(.+?)^/', '', $name );
1989 $u = htmlspecialchars( $url );
1990 $s = "<a href=\"{$u}\" class='internal' title=\"{$alt}\">{$alt}</a>";
1995 function specialLink( $name, $key = "" )
1999 if ( '' == $key ) { $key = strtolower( $name ); }
2000 $pn = $wgLang->ucfirst( $name );
2001 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
2005 function makeExternalLink( $url, $text, $escape = true ) {
2006 $style = $this->getExternalLinkAttributes( $url, $text );
2007 $url = htmlspecialchars( $url );
2009 $text = htmlspecialchars( $text );
2011 return '<a href="'.$url.'"'.$style.'>'.$text.'</a>';
2014 # Called by history lists and recent changes
2017 # Returns text for the start of the tabular part of RC
2018 function beginRecentChangesList()
2020 $this->rc_cache
= array() ;
2021 $this->rcMoveIndex
= 0;
2022 $this->rcCacheIndex
= 0 ;
2023 $this->lastdate
= '';
2024 $this->rclistOpen
= false;
2028 function beginImageHistoryList()
2030 $s = "\n<h2>" . wfMsg( 'imghistory' ) . "</h2>\n" .
2031 "<p>" . wfMsg( 'imghistlegend' ) . "</p>\n".'<ul class="special">';
2035 # Returns text for the end of RC
2036 # If enhanced RC is in use, returns pretty much all the text
2037 function endRecentChangesList()
2039 $s = $this->recentChangesBlock() ;
2040 if( $this->rclistOpen
) {
2046 # Enhanced RC ungrouped line
2047 function recentChangesBlockLine ( $rcObj )
2049 global $wgStylePath, $wgLang ;
2051 # Get rc_xxxx variables
2052 extract( $rcObj->mAttribs
) ;
2053 $curIdEq = 'curid='.$rc_cur_id;
2058 $r .= '<img src="'.$wgStylePath.'/images/Arr_.png" width="12" height="12" border="0" />' ;
2061 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2062 $r .= ' ';
2064 # M & N (minor & new)
2065 $M = wfMsg( 'minoreditletter' );
2066 $N = wfMsg( 'newpageletter' );
2068 if ( $rc_type == RC_NEW
) {
2081 $r .= ' '.$rcObj->timestamp
.' ' ;
2085 $link = $rcObj->link
;
2086 if ( $rcObj->watched
) $link = '<strong>'.$link.'</strong>' ;
2091 $r .= $rcObj->difflink
;
2095 $r .= $this->makeKnownLinkObj( $rcObj->getTitle(), wfMsg( 'hist' ), $curIdEq.'&action=history' );
2098 $r .= ') . . '.$rcObj->userlink
;
2099 $r .= $rcObj->usertalklink
;
2102 if ( $rc_comment != '' && $rc_type != RC_MOVE
&& $rc_type != RC_MOVE_OVER_REDIRECT
) {
2103 $rc_comment=$this->formatComment($rc_comment);
2104 $r .= $wgLang->emphasize( ' ('.$rc_comment.')' );
2112 function recentChangesBlockGroup ( $block )
2114 global $wgStylePath, $wgLang ;
2117 $M = wfMsg( 'minoreditletter' );
2118 $N = wfMsg( 'newpageletter' );
2120 # Collate list of users
2122 $userlinks = array () ;
2123 foreach ( $block AS $rcObj ) {
2124 $oldid = $rcObj->mAttribs
['rc_last_oldid'];
2125 if ( $rcObj->mAttribs
['rc_new'] ) $isnew = true ;
2126 $u = $rcObj->userlink
;
2127 if ( !isset ( $userlinks[$u] ) ) $userlinks[$u] = 0 ;
2131 # Sort the list and convert to text
2132 krsort ( $userlinks ) ;
2133 asort ( $userlinks ) ;
2135 foreach ( $userlinks as $userlink => $count) {
2137 if ( $count > 1 ) $text .= " ({$count}×)" ;
2138 array_push ( $users , $text ) ;
2140 $users = ' <font size="-1">['.implode('; ',$users).']</font>' ;
2143 $rci = 'RCI'.$this->rcCacheIndex
;
2144 $rcl = 'RCL'.$this->rcCacheIndex
;
2145 $rcm = 'RCM'.$this->rcCacheIndex
;
2146 $toggleLink = "javascript:toggleVisibility('$rci','$rcm','$rcl')" ;
2147 $arrowdir = $wgLang->isRTL() ?
'l' : 'r';
2148 $tl = '<span id="'.$rcm.'"><a href="'.$toggleLink.'"><img src="'.$wgStylePath.'/images/Arr_'.$arrowdir.'.png" width="12" height="12" /></a></span>' ;
2149 $tl .= '<span id="'.$rcl.'" style="display:none"><a href="'.$toggleLink.'"><img src="'.$wgStylePath.'/images/Arr_d.png" width="12" height="12" /></a></span>' ;
2155 if ( $isnew ) $r .= $N ;
2156 else $r .= ' ' ;
2157 $r .= ' ' ; # Minor
2160 $r .= ' '.$block[0]->timestamp
.' ' ;
2164 $link = $block[0]->link
;
2165 if ( $block[0]->watched
) $link = '<strong>'.$link.'</strong>' ;
2168 $curIdEq = 'curid=' . $block[0]->mAttribs
['rc_cur_id'];
2169 if ( $block[0]->mAttribs
['rc_type'] != RC_LOG
) {
2171 $r .= ' ('.count($block).' ' ;
2172 if ( $isnew ) $r .= wfMsg('changes');
2173 else $r .= $this->makeKnownLinkObj( $block[0]->getTitle() , wfMsg('changes') ,
2174 $curIdEq.'&diff=0&oldid='.$oldid ) ;
2178 $r .= $this->makeKnownLinkObj( $block[0]->getTitle(), wfMsg( 'history' ), $curIdEq.'&action=history' );
2186 $r .= '<div id="'.$rci.'" style="display:none">' ;
2187 foreach ( $block AS $rcObj ) {
2188 # Get rc_xxxx variables
2189 extract( $rcObj->mAttribs
);
2191 $r .= '<img src="'.$wgStylePath.'/images/Arr_.png" width="12" height="12" />';
2192 $r .= '<tt> ' ;
2193 if ( $rc_new ) $r .= $N ;
2194 else $r .= ' ' ;
2195 if ( $rc_minor ) $r .= $M ;
2196 else $r .= ' ' ;
2200 if ( $rc_last_oldid != 0 ) {
2201 $o = 'oldid='.$rc_last_oldid ;
2203 if ( $rc_type == RC_LOG
) {
2204 $link = $rcObj->timestamp
;
2206 $link = $this->makeKnownLinkObj( $rcObj->getTitle(), $rcObj->timestamp
, "{$curIdEq}&$o" ) ;
2208 $link = '<tt>'.$link.'</tt>' ;
2212 $r .= $rcObj->curlink
;
2214 $r .= $rcObj->lastlink
;
2215 $r .= ') . . '.$rcObj->userlink
;
2216 $r .= $rcObj->usertalklink
;
2217 if ( $rc_comment != '' ) {
2218 $rc_comment=$this->formatComment($rc_comment);
2219 $r .= $wgLang->emphasize( ' ('.$rc_comment.')' ) ;
2225 $this->rcCacheIndex++
;
2229 # If enhanced RC is in use, this function takes the previously cached
2230 # RC lines, arranges them, and outputs the HTML
2231 function recentChangesBlock ()
2233 global $wgStylePath ;
2234 if ( count ( $this->rc_cache
) == 0 ) return '' ;
2236 foreach ( $this->rc_cache
AS $secureName => $block ) {
2237 if ( count ( $block ) < 2 ) {
2238 $blockOut .= $this->recentChangesBlockLine ( array_shift ( $block ) ) ;
2240 $blockOut .= $this->recentChangesBlockGroup ( $block ) ;
2244 return '<div>'.$blockOut.'</div>' ;
2247 # Called in a loop over all displayed RC entries
2248 # Either returns the line, or caches it for later use
2249 function recentChangesLine( &$rc, $watched = false )
2252 $usenew = $wgUser->getOption( 'usenewrc' );
2254 $line = $this->recentChangesLineNew ( $rc, $watched ) ;
2256 $line = $this->recentChangesLineOld ( $rc, $watched ) ;
2260 function recentChangesLineOld( &$rc, $watched = false )
2262 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds, $wgUseRCPatrol, $wgOnlySysopsCanPatrol;
2264 # Extract DB fields into local scope
2265 extract( $rc->mAttribs
);
2266 $curIdEq = 'curid=' . $rc_cur_id;
2268 # Make date header if necessary
2269 $date = $wgLang->date( $rc_timestamp, true);
2271 if ( $date != $this->lastdate
) {
2272 if ( '' != $this->lastdate
) { $s .= "</ul>\n"; }
2273 $s .= "<h4>{$date}</h4>\n<ul class='special'>";
2274 $this->lastdate
= $date;
2275 $this->rclistOpen
= true;
2278 # If this edit has not yet been patrolled, make it stick out
2279 $s .= ( ! $wgUseRCPatrol ||
$rc_patrolled ) ?
'<li> ' : '<li class="not_patrolled"> ';
2281 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2283 $s .= '(' . wfMsg( 'diff' ) . ') (';
2285 $s .= $this->makeKnownLinkObj( $rc->getMovedToTitle(), wfMsg( 'hist' ), 'action=history' ) .
2288 # "[[x]] moved to [[y]]"
2289 $msg = ( $rc_type == RC_MOVE
) ?
'1movedto2' : '1movedto2_redir';
2290 $s .= wfMsg( $msg, $this->makeKnownLinkObj( $rc->getTitle(), '', 'redirect=no' ),
2291 $this->makeKnownLinkObj( $rc->getMovedToTitle(), '' ) );
2294 if ( $rc_type == RC_NEW ||
$rc_type == RC_LOG
) {
2295 $diffLink = wfMsg( 'diff' );
2297 if ( $wgUseRCPatrol && $rc_patrolled == 0 && $wgUser->getID() != 0 &&
2298 ( $wgUser->isSysop() ||
!$wgOnlySysopsCanPatrol ) )
2299 $rcidparam = "&rcid={$rc_id}";
2302 $diffLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'diff' ),
2303 "{$curIdEq}&diff={$rc_this_oldid}&oldid={$rc_last_oldid}{$rcidparam}",
2304 '', '', ' tabindex="'.$rc->counter
.'"');
2306 $s .= '('.$diffLink.') (';
2309 $s .= $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'hist' ), $curIdEq.'&action=history' );
2312 # M and N (minor and new)
2313 if ( $rc_minor ) { $s .= ' <span class="minor">'.wfMsg( "minoreditletter" ).'</span>'; }
2314 if ( $rc_type == RC_NEW
) { $s .= '<span class="newpage">'.wfMsg( "newpageletter" ).'</span>'; }
2317 # If it's a new article, there is no diff link, but if it hasn't been
2318 # patrolled yet, we need to give users a way to do so
2319 if ( $wgUseRCPatrol && $rc_type == RC_NEW
&& $rc_patrolled == 0 &&
2320 $wgUser->getID() != 0 && ( $wgUser->isSysop() ||
!$wgOnlySysopsCanPatrol ) )
2321 $articleLink = $this->makeKnownLinkObj( $rc->getTitle(), '', "rcid={$rc_id}" );
2323 $articleLink = $this->makeKnownLinkObj( $rc->getTitle(), '' );
2326 $articleLink = '<strong>'.$articleLink.'</strong>';
2328 $s .= ' '.$articleLink;
2333 $s .= '; ' . $wgLang->time( $rc_timestamp, true, $wgRCSeconds ) . ' . . ';
2335 # User link (or contributions for unregistered users)
2336 if ( 0 == $rc_user ) {
2337 $userLink = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
2338 $rc_user_text, 'target=' . $rc_user_text );
2340 $userLink = $this->makeLink( $wgLang->getNsText( NS_USER
) . ':'.$rc_user_text, $rc_user_text );
2345 $talkname=$wgLang->getNsText(NS_TALK
); # use the shorter name
2346 global $wgDisableAnonTalk;
2347 if( 0 == $rc_user && $wgDisableAnonTalk ) {
2350 $utns=$wgLang->getNsText(NS_USER_TALK
);
2351 $userTalkLink= $this->makeLink($utns . ':'.$rc_user_text, $talkname );
2355 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2356 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2357 'Blockip' ), wfMsg( 'blocklink' ), 'ip='.$rc_user_text );
2361 if($userTalkLink) $userTalkLink .= ' | ';
2362 $userTalkLink .= $blockLink;
2364 if($userTalkLink) $s.=' ('.$userTalkLink.')';
2367 if ( '' != $rc_comment && '*' != $rc_comment && $rc_type != RC_MOVE
&& $rc_type != RC_MOVE_OVER_REDIRECT
) {
2368 $rc_comment=$this->formatComment($rc_comment);
2369 $s .= $wgLang->emphasize(' (' . $rc_comment . ')');
2376 function recentChangesLineNew( &$baseRC, $watched = false )
2378 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds;
2380 # Create a specialised object
2381 $rc = RCCacheEntry
::newFromParent( $baseRC ) ;
2383 # Extract fields from DB into the function scope (rc_xxxx variables)
2384 extract( $rc->mAttribs
);
2385 $curIdEq = 'curid=' . $rc_cur_id;
2387 # If it's a new day, add the headline and flush the cache
2388 $date = $wgLang->date( $rc_timestamp, true);
2390 if ( $date != $this->lastdate
) {
2391 # Process current cache
2392 $ret = $this->recentChangesBlock () ;
2393 $this->rc_cache
= array() ;
2394 $ret .= "<h4>{$date}</h4>\n";
2395 $this->lastdate
= $date;
2399 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2400 $msg = ( $rc_type == RC_MOVE
) ?
"1movedto2" : "1movedto2_redir";
2401 $clink = wfMsg( $msg, $this->makeKnownLinkObj( $rc->getTitle(), '', 'redirect=no' ),
2402 $this->makeKnownLinkObj( $rc->getMovedToTitle(), '' ) );
2404 $clink = $this->makeKnownLinkObj( $rc->getTitle(), '' ) ;
2407 $time = $wgLang->time( $rc_timestamp, true, $wgRCSeconds );
2408 $rc->watched
= $watched ;
2409 $rc->link
= $clink ;
2410 $rc->timestamp
= $time;
2412 # Make "cur" and "diff" links
2413 if ( ( $rc_type == RC_NEW
&& $rc_this_oldid == 0 ) ||
$rc_type == RC_LOG ||
$rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2414 $curLink = wfMsg( 'cur' );
2415 $diffLink = wfMsg( 'diff' );
2417 $query = $curIdEq.'&diff=0&oldid='.$rc_this_oldid;
2418 $aprops = ' tabindex="'.$baseRC->counter
.'"';
2419 $curLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'cur' ), $query, '' ,'' , $aprops );
2420 $diffLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'diff'), $query, '' ,'' , $aprops );
2424 $titleObj = $rc->getTitle();
2425 if ( $rc_last_oldid == 0 ||
$rc_type == RC_LOG ||
$rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2426 $lastLink = wfMsg( 'last' );
2428 $lastLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'last' ),
2429 $curIdEq.'&diff='.$rc_this_oldid.'&oldid='.$rc_last_oldid );
2432 # Make user link (or user contributions for unregistered users)
2433 if ( $rc_user == 0 ) {
2434 $userLink = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
2435 $rc_user_text, 'target=' . $rc_user_text );
2437 $userLink = $this->makeLink( $wgLang->getNsText(
2438 Namespace::getUser() ) . ':'.$rc_user_text, $rc_user_text );
2441 $rc->userlink
= $userLink;
2442 $rc->lastlink
= $lastLink;
2443 $rc->curlink
= $curLink;
2444 $rc->difflink
= $diffLink;
2446 # Make user talk link
2447 $utns=$wgLang->getNsText(NS_USER_TALK
);
2448 $talkname=$wgLang->getNsText(NS_TALK
); # use the shorter name
2449 $userTalkLink= $this->makeLink($utns . ':'.$rc_user_text, $talkname );
2451 global $wgDisableAnonTalk;
2452 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2453 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2454 'Blockip' ), wfMsg( 'blocklink' ), 'ip='.$rc_user_text );
2455 if( $wgDisableAnonTalk )
2456 $rc->usertalklink
= ' ('.$blockLink.')';
2458 $rc->usertalklink
= ' ('.$userTalkLink.' | '.$blockLink.')';
2460 if( $wgDisableAnonTalk && ($rc_user == 0) )
2461 $rc->usertalklink
= '';
2463 $rc->usertalklink
= ' ('.$userTalkLink.')';
2466 # Put accumulated information into the cache, for later display
2467 # Page moves go on their own line
2468 $title = $rc->getTitle();
2469 $secureName = $title->getPrefixedDBkey();
2470 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2471 # Use an @ character to prevent collision with page names
2472 $this->rc_cache
['@@' . ($this->rcMoveIndex++
)] = array($rc);
2474 if ( !isset ( $this->rc_cache
[$secureName] ) ) $this->rc_cache
[$secureName] = array() ;
2475 array_push ( $this->rc_cache
[$secureName] , $rc ) ;
2480 function endImageHistoryList()
2486 /* This function is called by all recent changes variants, by the page history,
2487 and by the user contributions list. It is responsible for formatting edit
2488 comments. It escapes any HTML in the comment, but adds some CSS to format
2489 auto-generated comments (from section editing) and formats [[wikilinks]].
2490 Main author: Erik Möller (moeller@scireview.de)
2492 function formatComment($comment)
2495 $comment=wfEscapeHTML($comment);
2497 # The pattern for autogen comments is / * foo * /, which makes for
2499 # We look for all comments, match any text before and after the comment,
2500 # add a separator where needed and format the comment itself with CSS
2501 while (preg_match('/(.*)\/\*\s*(.*?)\s*\*\/(.*)/', $comment,$match)) {
2506 if($pre) { $auto = $sep.' '.$auto; }
2507 if($post) { $auto .= ' '.$sep; }
2508 $auto='<span class="autocomment">'.$auto.'</span>';
2509 $comment=$pre.$auto.$post;
2512 # format regular and media links - all other wiki formatting
2514 $medians = $wgLang->getNsText(Namespace::getMedia()).':';
2515 while(preg_match('/\[\[(.*?)(\|(.*?))*\]\](.*)$/',$comment,$match)) {
2516 # Handle link renaming [[foo|text]] will show link as "text"
2517 if( "" != $match[3] ) {
2522 if( preg_match( '/^' . $medians . '(.*)$/i', $match[1], $submatch ) ) {
2523 # Media link; trail not supported.
2524 $linkRegexp = '/\[\[(.*?)\]\]/';
2525 $thelink = $this->makeMediaLink( $submatch[1], "", $text );
2527 # Other kind of link
2528 if( preg_match( wfMsg( "linktrail" ), $match[4], $submatch ) ) {
2529 $trail = $submatch[1];
2533 $linkRegexp = '/\[\[(.*?)\]\]' . preg_quote( $trail, '/' ) . '/';
2534 $thelink = $this->makeLink( $match[1], $text, "", $trail );
2536 $comment = preg_replace( $linkRegexp, $thelink, $comment, 1 );
2541 function imageHistoryLine( $iscur, $timestamp, $img, $user, $usertext, $size, $description )
2543 global $wgUser, $wgLang, $wgTitle;
2545 $datetime = $wgLang->timeanddate( $timestamp, true );
2546 $del = wfMsg( 'deleteimg' );
2547 $delall = wfMsg( 'deleteimgcompletely' );
2548 $cur = wfMsg( 'cur' );
2551 $url = Image
::wfImageUrl( $img );
2553 if ( $wgUser->isSysop() ) {
2554 $link = $wgTitle->escapeLocalURL( 'image=' . $wgTitle->getPartialURL() .
2556 $style = $this->getInternalLinkAttributes( $link, $delall );
2558 $dlink = '<a href="'.$link.'"'.$style.'>'.$delall.'</a>';
2563 $url = wfEscapeHTML( wfImageArchiveUrl( $img ) );
2564 if( $wgUser->getID() != 0 && $wgTitle->userCanEdit() ) {
2565 $rlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2566 wfMsg( 'revertimg' ), 'action=revert&oldimage=' .
2567 urlencode( $img ) );
2568 $dlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2569 $del, 'action=delete&oldimage=' . urlencode( $img ) );
2571 # Having live active links for non-logged in users
2572 # means that bots and spiders crawling our site can
2573 # inadvertently change content. Baaaad idea.
2574 $rlink = wfMsg( 'revertimg' );
2579 $userlink = $usertext;
2581 $userlink = $this->makeLink( $wgLang->getNsText( Namespace::getUser() ) .
2582 ':'.$usertext, $usertext );
2584 $nbytes = wfMsg( 'nbytes', $size );
2585 $style = $this->getInternalLinkAttributes( $url, $datetime );
2587 $s = "<li> ({$dlink}) ({$rlink}) <a href=\"{$url}\"{$style}>{$datetime}</a>"
2588 . " . . {$userlink} ({$nbytes})";
2590 if ( '' != $description && '*' != $description ) {
2591 $sk=$wgUser->getSkin();
2592 $s .= $wgLang->emphasize(' (' . $sk->formatComment($description) . ')');
2598 function tocIndent($level) {
2599 return str_repeat( '<div class="tocindent">'."\n", $level>0 ?
$level : 0 );
2602 function tocUnindent($level) {
2603 return str_repeat( "</div>\n", $level>0 ?
$level : 0 );
2606 # parameter level defines if we are on an indentation level
2607 function tocLine( $anchor, $tocline, $level ) {
2608 $link = '<a href="#'.$anchor.'">'.$tocline.'</a><br />';
2612 return '<div class="tocline">'.$link."</div>\n";
2617 function tocTable($toc) {
2618 # note to CSS fanatics: putting this in a div does not work -- div won't auto-expand
2619 # try min-width & co when somebody gets a chance
2620 $hideline = ' <script type="text/javascript">showTocToggle("' . addslashes( wfMsg('showtoc') ) . '","' . addslashes( wfMsg('hidetoc') ) . '")</script>';
2622 '<table border="0" id="toc"><tr id="toctitle"><td align="center">'."\n".
2623 '<b>'.wfMsg('toc').'</b>' .
2625 '</td></tr><tr id="tocinside"><td>'."\n".
2626 $toc."</td></tr></table>\n";
2629 # These two do not check for permissions: check $wgTitle->userCanEdit before calling them
2630 function editSectionScript( $section, $head ) {
2631 global $wgTitle, $wgRequest;
2632 if( $wgRequest->getInt( 'oldid' ) && ( $wgRequest->getVal( 'diff' ) != '0' ) ) {
2635 $url = $wgTitle->escapeLocalURL( 'action=edit§ion='.$section );
2636 return '<span oncontextmenu=\'document.location="'.$url.'";return false;\'>'.$head.'</span>';
2639 function editSectionLink( $section ) {
2641 global $wgTitle, $wgUser, $wgLang;
2643 if( $wgRequest->getInt( 'oldid' ) && ( $wgRequest->getVal( 'diff' ) != '0' ) ) {
2644 # Section edit links would be out of sync on an old page.
2645 # But, if we're diffing to the current page, they'll be
2650 $editurl = '§ion='.$section;
2651 $url = $this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg('editsection'),'action=edit'.$editurl);
2653 if( $wgLang->isRTL() ) {
2655 $nearside = 'right';
2660 return "<div class=\"editsection\" style=\"float:$farside;margin-$nearside:5px;\">[".$url."]</div>";
2664 // This function is called by EditPage.php and shows a bulletin board style
2665 // toolbar for common editing functions. It can be disabled in the user preferences.
2666 // The necsesary JavaScript code can be found in style/wikibits.js.
2667 function getEditToolbar() {
2668 global $wgStylePath, $wgLang, $wgMimeType;
2670 // toolarray an array of arrays which each include the filename of
2671 // the button image (without path), the opening tag, the closing tag,
2672 // and optionally a sample text that is inserted between the two when no
2673 // selection is highlighted.
2674 // The tip text is shown when the user moves the mouse over the button.
2676 // Already here are accesskeys (key), which are not used yet until someone
2677 // can figure out a way to make them work in IE. However, we should make
2678 // sure these keys are not defined on the edit page.
2680 array( 'image'=>'button_bold.png',
2683 'sample'=>wfMsg('bold_sample'),
2684 'tip'=>wfMsg('bold_tip'),
2687 array( "image"=>"button_italic.png",
2690 "sample"=>wfMsg("italic_sample"),
2691 "tip"=>wfMsg("italic_tip"),
2694 array( "image"=>"button_link.png",
2697 "sample"=>wfMsg("link_sample"),
2698 "tip"=>wfMsg("link_tip"),
2701 array( "image"=>"button_extlink.png",
2704 "sample"=>wfMsg("extlink_sample"),
2705 "tip"=>wfMsg("extlink_tip"),
2708 array( "image"=>"button_headline.png",
2711 "sample"=>wfMsg("headline_sample"),
2712 "tip"=>wfMsg("headline_tip"),
2715 array( "image"=>"button_image.png",
2716 "open"=>"[[".$wgLang->getNsText(NS_IMAGE
).":",
2718 "sample"=>wfMsg("image_sample"),
2719 "tip"=>wfMsg("image_tip"),
2722 array( "image"=>"button_media.png",
2723 "open"=>"[[".$wgLang->getNsText(NS_MEDIA
).":",
2725 "sample"=>wfMsg("media_sample"),
2726 "tip"=>wfMsg("media_tip"),
2729 array( "image"=>"button_math.png",
2730 "open"=>"\\<math\\>",
2731 "close"=>"\\</math\\>",
2732 "sample"=>wfMsg("math_sample"),
2733 "tip"=>wfMsg("math_tip"),
2736 array( "image"=>"button_nowiki.png",
2737 "open"=>"\\<nowiki\\>",
2738 "close"=>"\\</nowiki\\>",
2739 "sample"=>wfMsg("nowiki_sample"),
2740 "tip"=>wfMsg("nowiki_tip"),
2743 array( "image"=>"button_sig.png",
2747 "tip"=>wfMsg("sig_tip"),
2750 array( "image"=>"button_hr.png",
2751 "open"=>"\\n----\\n",
2754 "tip"=>wfMsg("hr_tip"),
2758 $toolbar ="<script type='text/javascript'>\n/*<![CDATA[*/\n";
2760 $toolbar.="document.writeln(\"<div id='toolbar'>\");\n";
2761 foreach($toolarray as $tool) {
2763 $image=$wgStylePath.'/images/'.$tool['image'];
2764 $open=$tool['open'];
2765 $close=$tool['close'];
2766 $sample = addslashes( $tool['sample'] );
2768 // Note that we use the tip both for the ALT tag and the TITLE tag of the image.
2769 // Older browsers show a "speedtip" type message only for ALT.
2770 // Ideally these should be different, realistically they
2771 // probably don't need to be.
2772 $tip = addslashes( $tool['tip'] );
2774 #$key = $tool["key"];
2776 $toolbar.="addButton('$image','$tip','$open','$close','$sample');\n";
2779 $toolbar.="addInfobox('" . addslashes( wfMsg( "infobox" ) ) . "','" . addslashes(wfMsg("infobox_alert")) . "');\n";
2780 $toolbar.="document.writeln(\"</div>\");\n";
2782 $toolbar.="/*]]>*/\n</script>";