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 global $wgUseOldExistenceCheck;
58 $postParseLinkColour = !$wgUseOldExistenceCheck;
59 $this->linktrail
= wfMsg('linktrail');
62 function getSkinNames()
64 global $wgValidSkinNames;
65 return $wgValidSkinNames;
68 function getStylesheet()
70 return 'wikistandard.css';
72 function getSkinName() {
76 # Get/set accessor for delayed link colouring
77 function postParseLinkColour( $setting = NULL ) {
78 return wfSetVar( $this->postParseLinkColour
, $setting );
83 global $wgOut, $wgUser;
85 if ( $wgOut->isQuickbarSuppressed() ) { return 0; }
86 $q = $wgUser->getOption( 'quickbar' );
87 if ( '' == $q ) { $q = 0; }
91 function initPage( &$out )
93 $fname = 'Skin::initPage';
94 wfProfileIn( $fname );
96 $out->addLink( array( 'rel' => 'shortcut icon', 'href' => '/favicon.ico' ) );
98 $this->addMetadataLinks($out);
100 wfProfileOut( $fname );
103 function addMetadataLinks( &$out ) {
104 global $wgTitle, $wgEnableDublinCoreRdf, $wgEnableCreativeCommonsRdf, $wgRdfMimeType, $action;
105 global $wgRightsPage, $wgRightsUrl;
107 if( $out->isArticleRelated() ) {
108 # note: buggy CC software only reads first "meta" link
109 if( $wgEnableCreativeCommonsRdf ) {
110 $out->addMetadataLink( array(
111 'title' => 'Creative Commons',
112 'type' => 'application/rdf+xml',
113 'href' => $wgTitle->getLocalURL( 'action=creativecommons') ) );
115 if( $wgEnableDublinCoreRdf ) {
116 $out->addMetadataLink( array(
117 'title' => 'Dublin Core',
118 'type' => 'application/rdf+xml',
119 'href' => $wgTitle->getLocalURL( 'action=dublincore' ) ) );
123 if( $wgRightsPage ) {
124 $copy = Title
::newFromText( $wgRightsPage );
126 $copyright = $copy->getLocalURL();
129 if( !$copyright && $wgRightsUrl ) {
130 $copyright = $wgRightsUrl;
133 $out->addLink( array(
134 'rel' => 'copyright',
135 'href' => $copyright ) );
139 function outputPage( &$out ) {
140 global $wgDebugComments;
142 wfProfileIn( 'Skin::outputPage' );
143 $this->initPage( $out );
144 $out->out( $out->headElement() );
146 $out->out( "\n<body" );
147 $ops = $this->getBodyOptions();
148 foreach ( $ops as $name => $val ) {
149 $out->out( " $name='$val'" );
152 if ( $wgDebugComments ) {
153 $out->out( "<!-- Wiki debugging output:\n" .
154 $out->mDebugtext
. "-->\n" );
156 $out->out( $this->beforeContent() );
158 $out->out( $out->mBodytext
. "\n" );
160 $out->out( $this->afterContent() );
163 $out->out( $out->reportTime() );
165 $out->out( "\n</body></html>" );
168 function getHeadScripts() {
169 global $wgStylePath, $wgUser, $wgLang, $wgAllowUserJs;
170 $r = "<script type=\"text/javascript\" src=\"{$wgStylePath}/wikibits.js\"></script>\n";
171 if( $wgAllowUserJs && $wgUser->getID() != 0 ) { # logged in
172 $userpage = $wgLang->getNsText( Namespace::getUser() ) . ":" . $wgUser->getName();
173 $userjs = htmlspecialchars($this->makeUrl($userpage.'/'.$this->getSkinName().'.js', 'action=raw&ctype=text/javascript'));
174 $r .= '<script type="text/javascript" src="'.$userjs."\"></script>\n";
179 # get the user/site-specific stylesheet, SkinPHPTal called from RawPage.php (settings are cached that way)
180 function getUserStylesheet() {
181 global $wgOut, $wgStylePath, $wgLang, $wgUser, $wgRequest, $wgTitle, $wgAllowUserCss;
182 $sheet = $this->getStylesheet();
183 $action = $wgRequest->getText('action');
184 $s = "@import \"$wgStylePath/$sheet\";\n";
185 if($wgLang->isRTL()) $s .= "@import \"$wgStylePath/common_rtl.css\";\n";
186 if( $wgAllowUserCss && $wgUser->getID() != 0 ) { # logged in
187 if($wgTitle->isCssSubpage() and $action == 'submit' and $wgTitle->userCanEditCssJsSubpage()) {
188 $s .= $wgRequest->getText('wpTextbox1');
190 $userpage = $wgLang->getNsText( Namespace::getUser() ) . ":" . $wgUser->getName();
191 $s.= '@import "'.$this->makeUrl($userpage.'/'.$this->getSkinName().'.css', 'action=raw&ctype=text/css').'";'."\n";
194 $s .= $this->doGetUserStyles();
197 # placeholder, returns generated js in monobook
198 function getUserJs() {
202 function getUserStyles()
204 global $wgOut, $wgStylePath, $wgLang;
205 $s = "<style type='text/css'>\n";
206 $s .= "/*/*/ /*<![CDATA[*/\n"; # <-- Hide the styles from Netscape 4 without hiding them from IE/Mac
207 $s .= $this->getUserStylesheet();
208 $s .= "/*]]>*/ /* */\n";
213 function doGetUserStyles()
215 global $wgUser, $wgLang;
217 $csspage = $wgLang->getNsText( NS_MEDIAWIKI
) . ":" . $this->getSkinName() . ".css";
218 $s = '@import "'.$this->makeUrl($csspage, 'action=raw&ctype=text/css')."\";\n";
220 if ( 1 == $wgUser->getOption( 'underline' ) ) {
221 # Don't override browser settings
225 $s .= "a { text-decoration: none; }\n";
227 if ( 1 == $wgUser->getOption( 'highlightbroken' ) ) {
228 $s .= "a.new, #quickbar a.new { color: #CC2200; }\n";
230 if ( 1 == $wgUser->getOption( 'justify' ) ) {
231 $s .= "#article { text-align: justify; }\n";
236 function getBodyOptions()
238 global $wgUser, $wgTitle, $wgNamespaceBackgrounds, $wgOut, $wgRequest;
240 extract( $wgRequest->getValues( 'oldid', 'redirect', 'diff' ) );
242 if ( 0 != $wgTitle->getNamespace() ) {
243 $a = array( 'bgcolor' => '#ffffec' );
245 else $a = array( 'bgcolor' => '#FFFFFF' );
246 if($wgOut->isArticle() && $wgUser->getOption('editondblclick') &&
247 (!$wgTitle->isProtected() ||
$wgUser->isSysop()) ) {
248 $t = wfMsg( 'editthispage' );
250 if ( !empty($redirect) ) {
251 $red = "&redirect={$redirect}";
253 if ( !empty($oldid) && ! isset( $diff ) ) {
254 $oid = "&oldid={$oldid}";
256 $s = $wgTitle->getFullURL( "action=edit{$oid}{$red}" );
257 $s = 'document.location = "' .$s .'";';
258 $a +
= array ('ondblclick' => $s);
261 $a['onload'] = $wgOut->getOnloadHandler();
265 function getExternalLinkAttributes( $link, $text, $class='' )
267 global $wgUser, $wgOut, $wgLang;
269 $link = urldecode( $link );
270 $link = $wgLang->checkTitleEncoding( $link );
271 $link = str_replace( '_', ' ', $link );
272 $link = htmlspecialchars( $link );
274 $r = ($class != '') ?
" class='$class'" : " class='external'";
276 if ( 1 == $wgUser->getOption( 'hover' ) ) {
277 $r .= " title=\"{$link}\"";
282 function getInternalLinkAttributes( $link, $text, $broken = false )
284 global $wgUser, $wgOut;
286 $link = urldecode( $link );
287 $link = str_replace( '_', ' ', $link );
288 $link = htmlspecialchars( $link );
290 if ( $broken == 'stub' ) {
291 $r = ' class="stub"';
292 } else if ( $broken == 'yes' ) {
298 if ( 1 == $wgUser->getOption( 'hover' ) ) {
299 $r .= " title=\"{$link}\"";
304 function getInternalLinkAttributesObj( &$nt, $text, $broken = false )
306 global $wgUser, $wgOut;
308 if ( $broken == 'stub' ) {
309 $r = ' class="stub"';
310 } else if ( $broken == 'yes' ) {
316 if ( 1 == $wgUser->getOption( 'hover' ) ) {
317 $r .= ' title ="' . $nt->getEscapedText() . '"';
328 # This will be called immediately after the <body> tag. Split into
329 # two functions to make it easier to subclass.
331 function beforeContent()
333 global $wgUser, $wgOut;
335 return $this->doBeforeContent();
338 function doBeforeContent()
340 global $wgUser, $wgOut, $wgTitle, $wgLang, $wgSiteNotice;
341 $fname = 'Skin::doBeforeContent';
342 wfProfileIn( $fname );
345 $qb = $this->qbSetting();
347 if( $langlinks = $this->otherLanguages() ) {
353 $borderhack = 'class="top"';
356 $s .= "\n<div id='content'>\n<div id='topbar'>\n" .
357 "<table border='0' cellspacing='0' width='98%'>\n<tr>\n";
360 $left = ($qb == 1 ||
$qb == 3);
361 if($wgLang->isRTL()) $left = !$left;
364 $s .= "<td class='top' align='left' valign='top' rowspan='{$rows}'>\n" .
365 $this->logoText() . '</td>';
367 $s .= $this->getQuickbarCompensator( $rows );
369 $l = $wgLang->isRTL() ?
'right' : 'left';
370 $s .= "<td {$borderhack} align='$l' valign='top'>\n";
372 $s .= $this->topLinks() ;
373 $s .= "<p class='subtitle'>" . $this->pageTitleLinks() . "</p>\n";
375 $r = $wgLang->isRTL() ?
"left" : "right";
376 $s .= "</td>\n<td {$borderhack} valign='top' align='$r' nowrap='nowrap'>";
377 $s .= $this->nameAndLogin();
378 $s .= "\n<br />" . $this->searchForm() . "</td>";
381 $s .= "</tr>\n<tr>\n<td class='top' colspan=\"2\">$langlinks</td>\n";
384 if ( $shove && !$left ) { # Right
385 $s .= $this->getQuickbarCompensator( $rows );
387 $s .= "</tr>\n</table>\n</div>\n";
388 $s .= "\n<div id='article'>\n";
390 if( $wgSiteNotice ) {
391 $s .= "\n<div id='siteNotice'>$wgSiteNotice</div>\n";
393 $s .= $this->pageTitle();
394 $s .= $this->pageSubtitle() ;
395 $s .= $this->getCategories();
396 wfProfileOut( $fname );
400 function getCategoryLinks () {
401 global $wgOut, $wgTitle, $wgUser, $wgParser;
402 global $wgUseCategoryMagic, $wgUseCategoryBrowser, $wgLang;
404 if( !$wgUseCategoryMagic ) return '' ;
405 if( count( $wgOut->mCategoryLinks
) == 0 ) return '';
407 # Taken out so that they will be displayed in previews -- TS
408 #if( !$wgOut->isArticle() ) return '';
410 $t = implode ( ' | ' , $wgOut->mCategoryLinks
) ;
411 $s = $this->makeKnownLink( 'Special:Categories',
412 wfMsg( 'categories' ), 'article=' . urlencode( $wgTitle->getPrefixedDBkey() ) )
415 if($wgUseCategoryBrowser) {
418 $s.= $wgTitle->getAllParentCategories($catstack);
424 function getCategories() {
425 $catlinks=$this->getCategoryLinks();
426 if(!empty($catlinks)) {
427 return "<p class='catlinks'>{$catlinks}</p>";
431 function getQuickbarCompensator( $rows = 1 )
433 return "<td width='152' rowspan='{$rows}'> </td>";
436 # This gets called immediately before the </body> tag.
438 function afterContent()
440 global $wgUser, $wgOut, $wgServer;
441 global $wgTitle, $wgLang;
443 $printfooter = "<div class=\"printfooter\">\n" . $this->printFooter() . "</div>\n";
444 return $printfooter . $this->doAfterContent();
447 function printSource() {
449 $url = htmlspecialchars( $wgTitle->getFullURL() );
450 return wfMsg( "retrievedfrom", "<a href=\"$url\">$url</a>" );
453 function printFooter() {
454 return "<p>" . $this->printSource() .
455 "</p>\n\n<p>" . $this->pageStats() . "</p>\n";
458 function doAfterContent()
460 global $wgUser, $wgOut, $wgLang;
461 $fname = 'Skin::doAfterContent';
462 wfProfileIn( $fname );
463 wfProfileIn( $fname.'-1' );
465 $s = "\n</div><br style=\"clear:both\" />\n";
466 $s .= "\n<div id='footer'>";
467 $s .= '<table border="0" cellspacing="0"><tr>';
469 wfProfileOut( $fname.'-1' );
470 wfProfileIn( $fname.'-2' );
472 $qb = $this->qbSetting();
474 $left = ($qb == 1 ||
$qb == 3);
475 if($wgLang->isRTL()) $left = !$left;
477 if ( $shove && $left ) { # Left
478 $s .= $this->getQuickbarCompensator();
480 wfProfileOut( $fname.'-2' );
481 wfProfileIn( $fname.'-3' );
482 $l = $wgLang->isRTL() ?
'right' : 'left';
483 $s .= "<td class='bottom' align='$l' valign='top'>";
485 $s .= $this->bottomLinks();
486 $s .= "\n<br />" . $this->mainPageLink()
487 . ' | ' . $this->aboutLink()
488 . ' | ' . $this->specialLink( 'recentchanges' )
489 . ' | ' . $this->searchForm()
490 . '<br /><span id="pagestats">' . $this->pageStats() . '</span>';
493 if ( $shove && !$left ) { # Right
494 $s .= $this->getQuickbarCompensator();
496 $s .= "</tr></table>\n</div>\n</div>\n";
498 wfProfileOut( $fname.'-3' );
499 wfProfileIn( $fname.'-4' );
500 if ( 0 != $qb ) { $s .= $this->quickBar(); }
501 wfProfileOut( $fname.'-4' );
502 wfProfileOut( $fname );
506 function pageTitleLinks()
508 global $wgOut, $wgTitle, $wgUser, $wgLang, $wgUseApproval, $wgRequest;
510 extract( $wgRequest->getValues( 'oldid', 'diff' ) );
511 $action = $wgRequest->getText( 'action' );
513 $s = $this->printableLink();
514 if ( wfMsg ( 'disclaimers' ) != '-' ) $s .= ' | ' . $this->makeKnownLink( wfMsg( 'disclaimerpage' ), wfMsg( 'disclaimers' ) ) ;
516 if ( $wgOut->isArticleRelated() ) {
517 if ( $wgTitle->getNamespace() == Namespace::getImage() ) {
518 $name = $wgTitle->getDBkey();
519 $link = htmlspecialchars( Image
::wfImageUrl( $name ) );
520 $style = $this->getInternalLinkAttributes( $link, $name );
521 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>";
523 # This will show the "Approve" link if $wgUseApproval=true;
524 if ( isset ( $wgUseApproval ) && $wgUseApproval )
526 $t = $wgTitle->getDBkey();
527 $name = 'Approve this article' ;
528 $link = "http://test.wikipedia.org/w/magnus/wiki.phtml?title={$t}&action=submit&doit=1" ;
529 #htmlspecialchars( wfImageUrl( $name ) );
530 $style = $this->getExternalLinkAttributes( $link, $name );
531 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>" ;
534 if ( 'history' == $action ||
isset( $diff ) ||
isset( $oldid ) ) {
535 $s .= ' | ' . $this->makeKnownLink( $wgTitle->getPrefixedText(),
536 wfMsg( 'currentrev' ) );
539 if ( $wgUser->getNewtalk() ) {
540 # do not show "You have new messages" text when we are viewing our
543 if(!(strcmp($wgTitle->getText(),$wgUser->getName()) == 0 &&
544 $wgTitle->getNamespace()==Namespace::getTalk(Namespace::getUser()))) {
545 $n =$wgUser->getName();
546 $tl = $this->makeKnownLink( $wgLang->getNsText(
547 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
548 wfMsg('newmessageslink') );
549 $s.= ' | <strong>'. wfMsg( 'newmessages', $tl ) . '</strong>';
553 $undelete = $this->getUndeleteLink();
554 if( !empty( $undelete ) ) {
555 $s .= ' | '.$undelete;
560 function getUndeleteLink() {
561 global $wgUser, $wgTitle, $wgLang, $action;
562 if( $wgUser->isSysop() &&
563 (($wgTitle->getArticleId() == 0) ||
($action == "history")) &&
564 ($n = $wgTitle->isDeleted() ) ) {
565 return wfMsg( 'thisisdeleted',
566 $this->makeKnownLink(
567 $wgLang->SpecialPage( 'Undelete/' . $wgTitle->getPrefixedDBkey() ),
568 wfMsg( 'restorelink', $n ) ) );
573 function printableLink()
575 global $wgOut, $wgFeedClasses, $wgRequest;
577 $baseurl = $_SERVER['REQUEST_URI'];
578 if( strpos( '?', $baseurl ) == false ) {
583 $baseurl = htmlspecialchars( $baseurl );
584 $printurl = $wgRequest->escapeAppendQuery( 'printable=yes' );
586 $s = "<a href=\"$printurl\">" . wfMsg( 'printableversion' ) . '</a>';
587 if( $wgOut->isSyndicated() ) {
588 foreach( $wgFeedClasses as $format => $class ) {
589 $feedurl = $wgRequest->escapeAppendQuery( "feed=$format" );
590 $s .= " | <a href=\"$feedurl\">{$format}</a>";
598 global $wgOut, $wgTitle, $wgUser;
600 $s = '<h1 class="pagetitle">' . htmlspecialchars( $wgOut->getPageTitle() ) . '</h1>';
601 if($wgUser->getOption( 'editsectiononrightclick' ) && $wgTitle->userCanEdit()) { $s=$this->editSectionScript(0,$s);}
605 function pageSubtitle()
609 $sub = $wgOut->getSubtitle();
611 global $wgExtraSubtitle;
612 $sub = wfMsg( 'fromwikipedia' ) . $wgExtraSubtitle;
614 $subpages = $this->subPageSubtitle();
615 $sub .= !empty($subpages)?
"</p><p class='subpages'>$subpages":'';
616 $s = "<p class='subtitle'>{$sub}</p>\n";
620 function subPageSubtitle()
622 global $wgOut,$wgTitle,$wgNamespacesWithSubpages;
624 if($wgOut->isArticle() && !empty($wgNamespacesWithSubpages[$wgTitle->getNamespace()])) {
625 $ptext=$wgTitle->getPrefixedText();
626 if(preg_match('/\//',$ptext)) {
627 $links = explode('/',$ptext);
630 foreach($links as $link) {
632 if ($c<count($links)) {
633 $growinglink .= $link;
634 $getlink = $this->makeLink( $growinglink, $link );
635 if(preg_match('/class="new"/i',$getlink)) { break; } # this is a hack, but it saves time
639 $subpages .= '< ';
641 $subpages .= $getlink;
650 function nameAndLogin()
652 global $wgUser, $wgTitle, $wgLang, $wgShowIPinHeader, $wgIP;
654 $li = $wgLang->specialPage( 'Userlogin' );
655 $lo = $wgLang->specialPage( 'Userlogout' );
658 if ( 0 == $wgUser->getID() ) {
659 if( $wgShowIPinHeader && isset( $_COOKIE[ini_get('session.name')] ) ) {
662 $tl = $this->makeKnownLink( $wgLang->getNsText(
663 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
664 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
666 $s .= $n . ' ('.$tl.')';
668 $s .= wfMsg('notloggedin');
671 $rt = $wgTitle->getPrefixedURL();
672 if ( 0 == strcasecmp( urlencode( $lo ), $rt ) ) {
674 } else { $q = "returnto={$rt}"; }
676 $s .= "\n<br />" . $this->makeKnownLink( $li,
677 wfMsg( 'login' ), $q );
679 $n = $wgUser->getName();
680 $rt = $wgTitle->getPrefixedURL();
681 $tl = $this->makeKnownLink( $wgLang->getNsText(
682 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
683 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
687 $s .= $this->makeKnownLink( $wgLang->getNsText(
688 Namespace::getUser() ) . ":{$n}", $n ) . "{$tl}<br />" .
689 $this->makeKnownLink( $lo, wfMsg( 'logout' ),
690 "returnto={$rt}" ) . ' | ' .
691 $this->specialLink( 'preferences' );
693 $s .= ' | ' . $this->makeKnownLink( wfMsg( 'helppage' ),
699 function getSearchLink() {
700 $searchPage =& Title
::makeTitle( NS_SPECIAL
, 'Search' );
701 return $searchPage->getLocalURL();
704 function escapeSearchLink() {
705 return htmlspecialchars( $this->getSearchLink() );
708 function searchForm()
711 $search = $wgRequest->getText( 'search' );
713 $s = '<form name="search" class="inline" method="post" action="'
714 . $this->escapeSearchLink() . "\">\n"
715 . '<input type="text" name="search" size="19" value="'
716 . htmlspecialchars(substr($search,0,256)) . "\" />\n"
717 . '<input type="submit" name="go" value="' . wfMsg ('go') . '" /> '
718 . '<input type="submit" name="fulltext" value="' . wfMsg ('search') . "\" />\n</form>";
728 $s = $this->mainPageLink() . $sep
729 . $this->specialLink( 'recentchanges' );
731 if ( $wgOut->isArticleRelated() ) {
732 $s .= $sep . $this->editThisPage()
733 . $sep . $this->historyLink();
735 # Many people don't like this dropdown box
736 #$s .= $sep . $this->specialPagesList();
741 function bottomLinks()
743 global $wgOut, $wgUser, $wgTitle;
747 if ( $wgOut->isArticleRelated() ) {
748 $s .= '<strong>' . $this->editThisPage() . '</strong>';
749 if ( 0 != $wgUser->getID() ) {
750 $s .= $sep . $this->watchThisPage();
752 $s .= $sep . $this->talkLink()
753 . $sep . $this->historyLink()
754 . $sep . $this->whatLinksHere()
755 . $sep . $this->watchPageLinksLink();
757 if ( $wgTitle->getNamespace() == Namespace::getUser()
758 ||
$wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser()) )
761 $id=User
::idFromName($wgTitle->getText());
762 $ip=User
::isIP($wgTitle->getText());
764 if($id ||
$ip) { # both anons and non-anons have contri list
765 $s .= $sep . $this->userContribsLink();
767 if ( 0 != $wgUser->getID() ) { # show only to signed in users
768 if($id) { # can only email non-anons
769 $s .= $sep . $this->emailUserLink();
773 if ( $wgUser->isSysop() && $wgTitle->getArticleId() ) {
774 $s .= "\n<br />" . $this->deleteThisPage() .
775 $sep . $this->protectThisPage() .
776 $sep . $this->moveThisPage();
778 $s .= "<br />\n" . $this->otherLanguages();
785 global $wgOut, $wgLang, $wgArticle, $wgRequest;
786 global $wgDisableCounters, $wgMaxCredits, $wgShowCreditsIfMax;
788 extract( $wgRequest->getValues( 'oldid', 'diff' ) );
789 if ( ! $wgOut->isArticle() ) { return ''; }
790 if ( isset( $oldid ) ||
isset( $diff ) ) { return ''; }
791 if ( 0 == $wgArticle->getID() ) { return ''; }
794 if ( !$wgDisableCounters ) {
795 $count = $wgLang->formatNum( $wgArticle->getCount() );
797 $s = wfMsg( 'viewcount', $count );
801 if (isset($wgMaxCredits) && $wgMaxCredits != 0) {
802 require_once("Credits.php");
803 $s .= ' ' . getCredits($wgArticle, $wgMaxCredits, $wgShowCreditsIfMax);
805 $s .= $this->lastModified();
808 return $s . ' ' . $this->getCopyright();
811 function getCopyright() {
812 global $wgRightsPage, $wgRightsUrl, $wgRightsText, $wgRequest;
815 $oldid = $wgRequest->getVal( 'oldid' );
816 $diff = $wgRequest->getVal( 'diff' );
818 if ( !is_null( $oldid ) && is_null( $diff ) && wfMsg( 'history_copyright' ) !== '-' ) {
819 $msg = 'history_copyright';
825 if( $wgRightsPage ) {
826 $link = $this->makeKnownLink( $wgRightsPage, $wgRightsText );
827 } elseif( $wgRightsUrl ) {
828 $link = $this->makeExternalLink( $wgRightsUrl, $wgRightsText );
833 $out .= wfMsg( $msg, $link );
837 function getCopyrightIcon() {
838 global $wgRightsPage, $wgRightsUrl, $wgRightsText, $wgRightsIcon;
840 if( $wgRightsIcon ) {
841 $icon = htmlspecialchars( $wgRightsIcon );
843 $url = htmlspecialchars( $wgRightsUrl );
844 $out .= '<a href="'.$url.'">';
846 $text = htmlspecialchars( $wgRightsText );
847 $out .= "<img src=\"$icon\" alt='$text' />";
855 function getPoweredBy() {
857 $url = htmlspecialchars( "$wgStylePath/images/poweredby_mediawiki_88x31.png" );
858 $img = '<a href="http://www.mediawiki.org/"><img src="'.$url.'" alt="MediaWiki" /></a>';
862 function lastModified()
864 global $wgLang, $wgArticle;
866 $timestamp = $wgArticle->getTimestamp();
868 $d = $wgLang->timeanddate( $wgArticle->getTimestamp(), true );
869 $s = ' ' . wfMsg( 'lastmodified', $d );
876 function logoText( $align = '' )
878 if ( '' != $align ) { $a = ' align="'.$align.'"'; }
881 $mp = wfMsg( 'mainpage' );
882 $titleObj = Title
::newFromText( $mp );
883 $s = '<a href="' . $titleObj->escapeLocalURL()
884 . '"><img'.$a.' src="'
885 . $this->getLogo() . '" alt="' . "[{$mp}]\" /></a>";
891 global $wgOut, $wgTitle, $wgUser, $wgRequest, $wgLang;
892 global $wgDisableUploads, $wgRemoteUploads;
894 $fname = 'Skin::quickBar';
895 wfProfileIn( $fname );
897 $action = $wgRequest->getText( 'action' );
898 $wpPreview = $wgRequest->getBool( 'wpPreview' );
899 $tns=$wgTitle->getNamespace();
901 $s = "\n<div id='quickbar'>";
902 $s .= "\n" . $this->logoText() . "\n<hr class='sep' />";
905 $s .= $this->mainPageLink()
906 . $sep . $this->specialLink( 'recentchanges' )
907 . $sep . $this->specialLink( 'randompage' );
908 if ($wgUser->getID()) {
909 $s.= $sep . $this->specialLink( 'watchlist' ) ;
910 $s .= $sep .$this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
911 wfMsg( 'mycontris' ), 'target=' . wfUrlencode($wgUser->getName() ) );
914 // only show watchlist link if logged in
915 if ( wfMsg ( 'currentevents' ) != '-' ) $s .= $sep . $this->makeKnownLink( wfMsg( 'currentevents' ), '' ) ;
916 $s .= "\n<br /><hr class='sep' />";
917 $articleExists = $wgTitle->getArticleId();
918 if ( $wgOut->isArticle() ||
$action =='edit' ||
$action =='history' ||
$wpPreview) {
919 if($wgOut->isArticle()) {
920 $s .= '<strong>' . $this->editThisPage() . '</strong>';
921 } else { # backlink to the article in edit or history mode
922 if($articleExists){ # no backlink if no article
925 $text = wfMsg('articlepage');
928 $text = wfMsg('viewtalkpage');
931 $text = wfMsg('userpage');
934 $text = wfMsg('viewtalkpage');
937 $text = wfMsg('wikipediapage');
940 $text = wfMsg('viewtalkpage');
943 $text = wfMsg('imagepage');
946 $text = wfMsg('viewtalkpage');
949 $text= wfMsg('articlepage');
952 $link = $wgTitle->getText();
953 if ($nstext = $wgLang->getNsText($tns) ) { # add namespace if necessary
954 $link = $nstext . ':' . $link ;
957 $s .= $this->makeLink( $link, $text );
958 } elseif( $wgTitle->getNamespace() != Namespace::getSpecial() ) {
959 # we just throw in a "New page" text to tell the user that he's in edit mode,
960 # and to avoid messing with the separator that is prepended to the next item
961 $s .= '<strong>' . wfMsg('newpage') . '</strong>';
967 if( $tns%2
&& $action!='edit' && !$wpPreview) {
968 $s.= '<br />'.$this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg('postcomment'),'action=edit§ion=new');
972 watching could cause problems in edit mode:
973 if user edits article, then loads "watch this article" in background and then saves
974 article with "Watch this article" checkbox disabled, the article is transparently
975 unwatched. Therefore we do not show the "Watch this page" link in edit mode
977 if ( 0 != $wgUser->getID() && $articleExists) {
978 if($action!='edit' && $action != 'submit' )
980 $s .= $sep . $this->watchThisPage();
982 if ( $wgTitle->userCanEdit() )
983 $s .= $sep . $this->moveThisPage();
985 if ( $wgUser->isSysop() and $articleExists ) {
986 $s .= $sep . $this->deleteThisPage() .
987 $sep . $this->protectThisPage();
989 $s .= $sep . $this->talkLink();
990 if ($articleExists && $action !='history') {
991 $s .= $sep . $this->historyLink();
993 $s.=$sep . $this->whatLinksHere();
995 if($wgOut->isArticleRelated()) {
996 $s .= $sep . $this->watchPageLinksLink();
999 if ( Namespace::getUser() == $wgTitle->getNamespace()
1000 ||
$wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser())
1003 $id=User
::idFromName($wgTitle->getText());
1004 $ip=User
::isIP($wgTitle->getText());
1007 $s .= $sep . $this->userContribsLink();
1009 if ( 0 != $wgUser->getID() ) {
1010 if($id) { # can only email real users
1011 $s .= $sep . $this->emailUserLink();
1015 $s .= "\n<br /><hr class='sep' />";
1018 if ( 0 != $wgUser->getID() && ( !$wgDisableUploads ||
$wgRemoteUploads ) ) {
1019 $s .= $this->specialLink( 'upload' ) . $sep;
1021 $s .= $this->specialLink( 'specialpages' )
1022 . $sep . $this->bugReportsLink();
1024 global $wgSiteSupportPage;
1025 if( $wgSiteSupportPage ) {
1026 $s .= "\n<br /><a href=\"" . htmlspecialchars( $wgSiteSupportPage ) .
1027 '" class="internal">' . wfMsg( 'sitesupport' ) . '</a>';
1030 $s .= "\n<br /></div>\n";
1031 wfProfileOut( $fname );
1035 function specialPagesList()
1037 global $wgUser, $wgOut, $wgLang, $wgServer, $wgRedirectScript;
1038 require_once('SpecialPage.php');
1040 $pages = SpecialPage
::getPages();
1042 foreach ( $pages[''] as $name => $page ) {
1043 $a[$name] = $page->getDescription();
1045 if ( $wgUser->isSysop() )
1047 foreach ( $pages['sysop'] as $name => $page ) {
1048 $a[$name] = $page->getDescription();
1051 if ( $wgUser->isDeveloper() )
1053 foreach ( $pages['developer'] as $name => $page ) {
1054 $a[$name] = $page->getDescription() ;
1057 $go = wfMsg( 'go' );
1058 $sp = wfMsg( 'specialpages' );
1059 $spp = $wgLang->specialPage( 'Specialpages' );
1061 $s = '<form id="specialpages" method="get" class="inline" ' .
1062 'action="' . htmlspecialchars( "{$wgServer}{$wgRedirectScript}" ) . "\">\n";
1063 $s .= "<select name=\"wpDropdown\">\n";
1064 $s .= "<option value=\"{$spp}\">{$sp}</option>\n";
1066 foreach ( $a as $name => $desc ) {
1067 $p = $wgLang->specialPage( $name );
1068 $s .= "<option value=\"{$p}\">{$desc}</option>\n";
1070 $s .= "</select>\n";
1071 $s .= "<input type='submit' value=\"{$go}\" name='redirect' />\n";
1076 function mainPageLink()
1078 $mp = wfMsg( 'mainpage' );
1079 $s = $this->makeKnownLink( $mp, $mp );
1083 function copyrightLink()
1085 $s = $this->makeKnownLink( wfMsg( 'copyrightpage' ),
1086 wfMsg( 'copyrightpagename' ) );
1090 function aboutLink()
1092 $s = $this->makeKnownLink( wfMsg( 'aboutpage' ),
1093 wfMsg( 'aboutwikipedia' ) );
1098 function disclaimerLink()
1100 $s = $this->makeKnownLink( wfMsg( 'disclaimerpage' ),
1101 wfMsg( 'disclaimers' ) );
1105 function editThisPage()
1107 global $wgOut, $wgTitle, $wgRequest;
1109 $oldid = $wgRequest->getVal( 'oldid' );
1110 $diff = $wgRequest->getVal( 'diff' );
1111 $redirect = $wgRequest->getVal( 'redirect' );
1113 if ( ! $wgOut->isArticleRelated() ) {
1114 $s = wfMsg( 'protectedpage' );
1116 $n = $wgTitle->getPrefixedText();
1117 if ( $wgTitle->userCanEdit() ) {
1118 $t = wfMsg( 'editthispage' );
1120 #$t = wfMsg( "protectedpage" );
1121 $t = wfMsg( 'viewsource' );
1125 if ( !is_null( $redirect ) ) { $red = "&redirect={$redirect}"; }
1126 if ( $oldid && ! isset( $diff ) ) {
1127 $oid = "&oldid={$oldid}";
1129 $s = $this->makeKnownLink( $n, $t, "action=edit{$oid}{$red}" );
1134 function deleteThisPage()
1136 global $wgUser, $wgOut, $wgTitle, $wgRequest;
1138 $diff = $wgRequest->getVal( 'diff' );
1139 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
1140 $n = $wgTitle->getPrefixedText();
1141 $t = wfMsg( 'deletethispage' );
1143 $s = $this->makeKnownLink( $n, $t, 'action=delete' );
1150 function protectThisPage()
1152 global $wgUser, $wgOut, $wgTitle, $wgRequest;
1154 $diff = $wgRequest->getVal( 'diff' );
1155 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
1156 $n = $wgTitle->getPrefixedText();
1158 if ( $wgTitle->isProtected() ) {
1159 $t = wfMsg( 'unprotectthispage' );
1160 $q = 'action=unprotect';
1162 $t = wfMsg( 'protectthispage' );
1163 $q = 'action=protect';
1165 $s = $this->makeKnownLink( $n, $t, $q );
1172 function watchThisPage()
1174 global $wgUser, $wgOut, $wgTitle;
1176 if ( $wgOut->isArticleRelated() ) {
1177 $n = $wgTitle->getPrefixedText();
1179 if ( $wgTitle->userIsWatching() ) {
1180 $t = wfMsg( 'unwatchthispage' );
1181 $q = 'action=unwatch';
1183 $t = wfMsg( 'watchthispage' );
1184 $q = 'action=watch';
1186 $s = $this->makeKnownLink( $n, $t, $q );
1188 $s = wfMsg( 'notanarticle' );
1193 function moveThisPage()
1195 global $wgTitle, $wgLang;
1197 if ( $wgTitle->userCanEdit() ) {
1198 $s = $this->makeKnownLink( $wgLang->specialPage( 'Movepage' ),
1199 wfMsg( 'movethispage' ), 'target=' . $wgTitle->getPrefixedURL() );
1200 } // no message if page is protected - would be redundant
1204 function historyLink()
1208 $s = $this->makeKnownLink( $wgTitle->getPrefixedText(),
1209 wfMsg( 'history' ), 'action=history' );
1213 function whatLinksHere()
1215 global $wgTitle, $wgLang;
1217 $s = $this->makeKnownLink( $wgLang->specialPage( 'Whatlinkshere' ),
1218 wfMsg( 'whatlinkshere' ), 'target=' . $wgTitle->getPrefixedURL() );
1222 function userContribsLink()
1224 global $wgTitle, $wgLang;
1226 $s = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
1227 wfMsg( 'contributions' ), 'target=' . $wgTitle->getPartialURL() );
1231 function emailUserLink()
1233 global $wgTitle, $wgLang;
1235 $s = $this->makeKnownLink( $wgLang->specialPage( 'Emailuser' ),
1236 wfMsg( 'emailuser' ), 'target=' . $wgTitle->getPartialURL() );
1240 function watchPageLinksLink()
1242 global $wgOut, $wgTitle, $wgLang;
1244 if ( ! $wgOut->isArticleRelated() ) {
1245 $s = '(' . wfMsg( 'notanarticle' ) . ')';
1247 $s = $this->makeKnownLink( $wgLang->specialPage(
1248 'Recentchangeslinked' ), wfMsg( 'recentchangeslinked' ),
1249 'target=' . $wgTitle->getPrefixedURL() );
1254 function otherLanguages()
1256 global $wgOut, $wgLang, $wgTitle, $wgUseNewInterlanguage;
1258 $a = $wgOut->getLanguageLinks();
1259 if ( 0 == count( $a ) ) {
1260 if ( !$wgUseNewInterlanguage ) return '';
1261 $ns = $wgLang->getNsIndex ( $wgTitle->getNamespace () ) ;
1262 if ( $ns != 0 AND $ns != 1 ) return '' ;
1264 $x = 'mode=addlink&xt='.$wgTitle->getDBkey() ;
1265 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1266 wfMsg( 'intl' ) , $x );
1269 if ( !$wgUseNewInterlanguage ) {
1270 $s = wfMsg( 'otherlanguages' ) . ': ';
1272 global $wgLanguageCode ;
1273 $x = 'mode=zoom&xt='.$wgTitle->getDBkey() ;
1274 $x .= '&xl='.$wgLanguageCode ;
1275 $s = $this->makeKnownLink( $wgLang->specialPage( 'Intl' ),
1276 wfMsg( 'otherlanguages' ) , $x ) . ': ' ;
1279 $s = wfMsg( 'otherlanguages' ) . ': ';
1281 if($wgLang->isRTL()) $s .= '<span dir="LTR">';
1282 foreach( $a as $l ) {
1283 if ( ! $first ) { $s .= ' | '; }
1286 $nt = Title
::newFromText( $l );
1287 $url = $nt->getFullURL();
1288 $text = $wgLang->getLanguageName( $nt->getInterwiki() );
1290 if ( '' == $text ) { $text = $l; }
1291 $style = $this->getExternalLinkAttributes( $l, $text );
1292 $s .= "<a href=\"{$url}\"{$style}>{$text}</a>";
1294 if($wgLang->isRTL()) $s .= '</span>';
1298 function bugReportsLink()
1300 $s = $this->makeKnownLink( wfMsg( 'bugreportspage' ),
1301 wfMsg( 'bugreports' ) );
1307 global $wgLinkCache;
1308 $t1 = Title
::newFromText( gmdate( 'F j' ) );
1309 $t2 = Title
::newFromText( gmdate( 'Y' ) );
1311 $wgLinkCache->suspend();
1312 $id = $t1->getArticleID();
1313 $wgLinkCache->resume();
1316 $s = $this->makeBrokenLink( $t1->getText() );
1318 $s = $this->makeKnownLink( $t1->getText() );
1322 $wgLinkCache->suspend();
1323 $id = $t2->getArticleID();
1324 $wgLinkCache->resume();
1327 $s .= $this->makeBrokenLink( $t2->getText() );
1329 $s .= $this->makeKnownLink( $t2->getText() );
1336 global $wgLang, $wgTitle, $wgLinkCache;
1338 $tns = $wgTitle->getNamespace();
1339 if ( -1 == $tns ) { return ''; }
1341 $pn = $wgTitle->getText();
1342 $tp = wfMsg( 'talkpage' );
1343 if ( Namespace::isTalk( $tns ) ) {
1344 $lns = Namespace::getSubject( $tns );
1347 $text = wfMsg('articlepage');
1350 $text = wfMsg('userpage');
1353 $text = wfMsg('wikipediapage');
1356 $text = wfMsg('imagepage');
1359 $text= wfMsg('articlepage');
1363 $lns = Namespace::getTalk( $tns );
1366 $n = $wgLang->getNsText( $lns );
1367 if ( '' == $n ) { $link = $pn; }
1368 else { $link = $n.':'.$pn; }
1370 $wgLinkCache->suspend();
1371 $s = $this->makeLink( $link, $text );
1372 $wgLinkCache->resume();
1377 function commentLink()
1379 global $wgLang, $wgTitle, $wgLinkCache;
1381 $tns = $wgTitle->getNamespace();
1382 if ( -1 == $tns ) { return ''; }
1384 $lns = ( Namespace::isTalk( $tns ) ) ?
$tns : Namespace::getTalk( $tns );
1386 # assert Namespace::isTalk( $lns )
1388 $n = $wgLang->getNsText( $lns );
1389 $pn = $wgTitle->getText();
1393 $wgLinkCache->suspend();
1394 $s = $this->makeKnownLink($link, wfMsg('postcomment'), 'action=edit§ion=new');
1395 $wgLinkCache->resume();
1400 # After all the page content is transformed into HTML, it makes
1401 # a final pass through here for things like table backgrounds.
1403 function transformContent( $text )
1408 # Note: This function MUST call getArticleID() on the link,
1409 # otherwise the cache won't get updated properly. See LINKCACHE.DOC.
1411 function makeLink( $title, $text = '', $query = '', $trail = '' ) {
1412 wfProfileIn( 'Skin::makeLink' );
1413 $nt = Title
::newFromText( $title );
1415 $result = $this->makeLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1417 wfDebug( 'Invalid title passed to Skin::makeLink(): "'.$title."\"\n" );
1418 $result = $text == "" ?
$title : $text;
1421 wfProfileOut( 'Skin::makeLink' );
1425 function makeKnownLink( $title, $text = '', $query = '', $trail = '', $prefix = '',$aprops = '') {
1426 $nt = Title
::newFromText( $title );
1428 return $this->makeKnownLinkObj( Title
::newFromText( $title ), $text, $query, $trail, $prefix , $aprops );
1430 wfDebug( 'Invalid title passed to Skin::makeKnownLink(): "'.$title."\"\n" );
1431 return $text == '' ?
$title : $text;
1435 function makeBrokenLink( $title, $text = '', $query = '', $trail = '' ) {
1436 $nt = Title
::newFromText( $title );
1438 return $this->makeBrokenLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1440 wfDebug( 'Invalid title passed to Skin::makeBrokenLink(): "'.$title."\"\n" );
1441 return $text == '' ?
$title : $text;
1445 function makeStubLink( $title, $text = '', $query = '', $trail = '' ) {
1446 $nt = Title
::newFromText( $title );
1448 return $this->makeStubLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1450 wfDebug( 'Invalid title passed to Skin::makeStubLink(): "'.$title."\"\n" );
1451 return $text == '' ?
$title : $text;
1455 # Pass a title object, not a title string
1456 function makeLinkObj( &$nt, $text= '', $query = '', $trail = '', $prefix = '' )
1458 global $wgOut, $wgUser;
1459 $fname = 'Skin::makeLinkObj';
1463 return "<!-- ERROR -->{$prefix}{$text}{$trail}";
1465 if ( $nt->isExternal() ) {
1466 $u = $nt->getFullURL();
1467 $link = $nt->getPrefixedURL();
1468 if ( '' == $text ) { $text = $nt->getPrefixedText(); }
1469 $style = $this->getExternalLinkAttributes( $link, $text, 'extiw' );
1472 if ( '' != $trail ) {
1473 if ( preg_match( '/^([a-z]+)(.*)$$/sD', $trail, $m ) ) {
1478 $retVal = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1479 } elseif ( 0 == $nt->getNamespace() && "" == $nt->getText() ) {
1480 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1481 } elseif ( ( -1 == $nt->getNamespace() ) ||
1482 ( Namespace::getImage() == $nt->getNamespace() ) ) {
1483 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1485 if ( $this->postParseLinkColour() ) {
1487 if ( '' != $trail ) {
1488 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1494 # Allows wiki to bypass using linkcache, see OutputPage::parseLinkHolders()
1495 $retVal = '<!--LINK ' . implode( ' ', array( $nt->getNamespace(), $nt->getDBkey(),
1496 $query, $prefix . $text . $inside ) ) . "-->{$trail}";
1498 # Work out link colour immediately
1499 $aid = $nt->getArticleID() ;
1501 $retVal = $this->makeBrokenLinkObj( $nt, $text, $query, $trail, $prefix );
1503 $threshold = $wgUser->getOption('stubthreshold') ;
1504 if ( $threshold > 0 ) {
1505 $dbr =& wfGetDB( DB_SLAVE
);
1506 $s = $dbr->selectRow( 'cur', array( 'LENGTH(cur_text) AS x', 'cur_namespace',
1507 'cur_is_redirect' ), array( 'cur_id' => $aid ), $fname ) ;
1508 if ( $s !== false ) {
1510 if ( $s->cur_is_redirect
OR $s->cur_namespace
!= 0 ) {
1511 $size = $threshold*2 ; # Really big
1513 $dbr->freeResult( $res );
1515 $size = $threshold*2 ; # Really big
1520 if ( $size < $threshold ) {
1521 $retVal = $this->makeStubLinkObj( $nt, $text, $query, $trail, $prefix );
1523 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1531 # Pass a title object, not a title string
1532 function makeKnownLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' , $aprops = '')
1534 global $wgOut, $wgTitle, $wgInputEncoding;
1536 $fname = 'Skin::makeKnownLinkObj';
1537 wfProfileIn( $fname );
1539 if ( !is_object( $nt ) ) {
1542 $link = $nt->getPrefixedURL();
1544 if ( '' == $link ) {
1546 if ( '' == $text ) {
1547 $text = htmlspecialchars( $nt->getFragment() );
1550 $u = $nt->escapeLocalURL( $query );
1552 if ( '' != $nt->getFragment() ) {
1553 $anchor = urlencode( do_html_entity_decode( str_replace(' ', '_', $nt->getFragment()), ENT_COMPAT
, $wgInputEncoding ) );
1554 $replacearray = array(
1558 $u .= '#' . str_replace(array_keys($replacearray),array_values($replacearray),$anchor);
1560 if ( '' == $text ) {
1561 $text = htmlspecialchars( $nt->getPrefixedText() );
1563 $style = $this->getInternalLinkAttributesObj( $nt, $text );
1566 if ( '' != $trail ) {
1567 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1572 $r = "<a href=\"{$u}\"{$style}{$aprops}>{$prefix}{$text}{$inside}</a>{$trail}";
1573 wfProfileOut( $fname );
1577 # Pass a title object, not a title string
1578 function makeBrokenLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
1580 global $wgOut, $wgUser;
1582 $fname = 'Skin::makeBrokenLinkObj';
1583 wfProfileIn( $fname );
1585 if ( '' == $query ) {
1588 $q = 'action=edit&'.$query;
1590 $u = $nt->escapeLocalURL( $q );
1592 if ( '' == $text ) {
1593 $text = htmlspecialchars( $nt->getPrefixedText() );
1595 $style = $this->getInternalLinkAttributesObj( $nt, $text, "yes" );
1598 if ( '' != $trail ) {
1599 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1604 if ( $wgUser->getOption( 'highlightbroken' ) ) {
1605 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1607 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>?</a>{$trail}";
1610 wfProfileOut( $fname );
1614 # Pass a title object, not a title string
1615 function makeStubLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
1617 global $wgOut, $wgUser;
1619 $link = $nt->getPrefixedURL();
1621 $u = $nt->escapeLocalURL( $query );
1623 if ( '' == $text ) {
1624 $text = htmlspecialchars( $nt->getPrefixedText() );
1626 $style = $this->getInternalLinkAttributesObj( $nt, $text, 'stub' );
1629 if ( '' != $trail ) {
1630 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1635 if ( $wgUser->getOption( 'highlightbroken' ) ) {
1636 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1638 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>!</a>{$trail}";
1643 function makeSelfLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
1645 $u = $nt->escapeLocalURL( $query );
1646 if ( '' == $text ) {
1647 $text = htmlspecialchars( $nt->getPrefixedText() );
1650 if ( '' != $trail ) {
1651 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1656 return "<strong>{$prefix}{$text}{$inside}</strong>{$trail}";
1659 /* these are used extensively in SkinPHPTal, but also some other places */
1660 /*static*/ function makeSpecialUrl( $name, $urlaction='' ) {
1661 $title = Title
::makeTitle( NS_SPECIAL
, $name );
1662 $this->checkTitle($title, $name);
1663 return $title->getLocalURL( $urlaction );
1665 /*static*/ function makeTalkUrl ( $name, $urlaction='' ) {
1666 $title = Title
::newFromText( $name );
1667 $title = $title->getTalkPage();
1668 $this->checkTitle($title, $name);
1669 return $title->getLocalURL( $urlaction );
1671 /*static*/ function makeArticleUrl ( $name, $urlaction='' ) {
1672 $title = Title
::newFromText( $name );
1673 $title= $title->getSubjectPage();
1674 $this->checkTitle($title, $name);
1675 return $title->getLocalURL( $urlaction );
1677 /*static*/ function makeI18nUrl ( $name, $urlaction='' ) {
1678 $title = Title
::newFromText( wfMsg($name) );
1679 $this->checkTitle($title, $name);
1680 return $title->getLocalURL( $urlaction );
1682 /*static*/ function makeUrl ( $name, $urlaction='' ) {
1683 $title = Title
::newFromText( $name );
1684 $this->checkTitle($title, $name);
1685 return $title->getLocalURL( $urlaction );
1687 # this can be passed the NS number as defined in Language.php
1688 /*static*/ function makeNSUrl( $name, $urlaction='', $namespace=0 ) {
1689 $title = Title
::makeTitle( $namespace, $name );
1690 $this->checkTitle($title, $name);
1691 return $title->getLocalURL( $urlaction );
1694 /* these return an array with the 'href' and boolean 'exists' */
1695 /*static*/ function makeUrlDetails ( $name, $urlaction='' ) {
1696 $title = Title
::newFromText( $name );
1697 $this->checkTitle($title, $name);
1699 'href' => $title->getLocalURL( $urlaction ),
1700 'exists' => $title->getArticleID() != 0?
true:false
1703 /*static*/ function makeTalkUrlDetails ( $name, $urlaction='' ) {
1704 $title = Title
::newFromText( $name );
1705 $title = $title->getTalkPage();
1706 $this->checkTitle($title, $name);
1708 'href' => $title->getLocalURL( $urlaction ),
1709 'exists' => $title->getArticleID() != 0?
true:false
1712 /*static*/ function makeArticleUrlDetails ( $name, $urlaction='' ) {
1713 $title = Title
::newFromText( $name );
1714 $title= $title->getSubjectPage();
1715 $this->checkTitle($title, $name);
1717 'href' => $title->getLocalURL( $urlaction ),
1718 'exists' => $title->getArticleID() != 0?
true:false
1721 /*static*/ function makeI18nUrlDetails ( $name, $urlaction='' ) {
1722 $title = Title
::newFromText( wfMsg($name) );
1723 $this->checkTitle($title, $name);
1725 'href' => $title->getLocalURL( $urlaction ),
1726 'exists' => $title->getArticleID() != 0?
true:false
1730 # make sure we have some title to operate on
1731 /*static*/ function checkTitle ( &$title, &$name ) {
1732 if(!is_object($title)) {
1733 $title = Title
::newFromText( $name );
1734 if(!is_object($title)) {
1735 $title = Title
::newFromText( '--error: link target missing--' );
1740 function fnamePart( $url )
1742 $basename = strrchr( $url, '/' );
1743 if ( false === $basename ) {
1746 $basename = substr( $basename, 1 );
1748 return htmlspecialchars( $basename );
1751 function makeImage( $url, $alt = '' )
1756 $alt = $this->fnamePart( $url );
1758 $s = '<img src="'.$url.'" alt="'.$alt.'" />';
1762 function makeImageLink( $name, $url, $alt = '' ) {
1763 $nt = Title
::makeTitle( Namespace::getImage(), $name );
1764 return $this->makeImageLinkObj( $nt, $alt );
1767 function makeImageLinkObj( $nt, $alt = '' ) {
1768 global $wgLang, $wgUseImageResize;
1769 $img = Image
::newFromTitle( $nt );
1770 $url = $img->getURL();
1773 $prefix = $postfix = '';
1775 if ( $wgUseImageResize ) {
1776 # Check if the alt text is of the form "options|alt text"
1778 # * thumbnail make a thumbnail with enlarge-icon and caption, alignment depends on lang
1779 # * left no resizing, just left align. label is used for alt= only
1780 # * right same, but right aligned
1781 # * none same, but not aligned
1782 # * ___px scale to ___ pixels width, no aligning. e.g. use in taxobox
1783 # * center center the image
1784 # * framed Keep original image size, no magnify-button.
1786 $part = explode( '|', $alt);
1788 $mwThumb =& MagicWord
::get( MAG_IMG_THUMBNAIL
);
1789 $mwLeft =& MagicWord
::get( MAG_IMG_LEFT
);
1790 $mwRight =& MagicWord
::get( MAG_IMG_RIGHT
);
1791 $mwNone =& MagicWord
::get( MAG_IMG_NONE
);
1792 $mwWidth =& MagicWord
::get( MAG_IMG_WIDTH
);
1793 $mwCenter =& MagicWord
::get( MAG_IMG_CENTER
);
1794 $mwFramed =& MagicWord
::get( MAG_IMG_FRAMED
);
1795 $alt = $part[count($part)-1];
1797 $height = $framed = $thumb = false;
1798 $manual_thumb = "" ;
1800 foreach( $part as $key => $val ) {
1801 $val_parts = explode ( "=" , $val , 2 ) ;
1802 $left_part = array_shift ( $val_parts ) ;
1803 if ( ! is_null( $mwThumb->matchVariableStartToEnd($val) ) ) {
1805 } elseif ( count ( $val_parts ) == 1 && ! is_null( $mwThumb->matchVariableStartToEnd($left_part) ) ) {
1806 # use manually specified thumbnail
1808 $manual_thumb = array_shift ( $val_parts ) ;
1809 } elseif ( ! is_null( $mwRight->matchVariableStartToEnd($val) ) ) {
1810 # remember to set an alignment, don't render immediately
1812 } elseif ( ! is_null( $mwLeft->matchVariableStartToEnd($val) ) ) {
1813 # remember to set an alignment, don't render immediately
1815 } elseif ( ! is_null( $mwCenter->matchVariableStartToEnd($val) ) ) {
1816 # remember to set an alignment, don't render immediately
1818 } elseif ( ! is_null( $mwNone->matchVariableStartToEnd($val) ) ) {
1819 # remember to set an alignment, don't render immediately
1821 } elseif ( ! is_null( $match = $mwWidth->matchVariableStartToEnd($val) ) ) {
1822 # $match is the image width in pixels
1823 if ( preg_match( '/^([0-9]*)x([0-9]*)$/', $match, $m ) ) {
1824 $width = intval( $m[1] );
1825 $height = intval( $m[2] );
1827 $width = intval($match);
1829 } elseif ( ! is_null( $mwFramed->matchVariableStartToEnd($val) ) ) {
1833 if ( 'center' == $align )
1835 $prefix = '<span style="text-align: center">';
1836 $postfix = '</span>';
1840 if ( $thumb ||
$framed ) {
1842 # Create a thumbnail. Alignment depends on language
1843 # writing direction, # right aligned for left-to-right-
1844 # languages ("Western languages"), left-aligned
1845 # for right-to-left-languages ("Semitic languages")
1847 # If thumbnail width has not been provided, it is set
1848 # here to 180 pixels
1849 if ( $align == '' ) {
1850 $align = $wgLang->isRTL() ?
'left' : 'right';
1852 if ( ! isset($width) ) {
1855 return $prefix.$this->makeThumbLinkObj( $img, $alt, $align, $width, $height, $framed, $manual_thumb ).$postfix;
1857 } elseif ( isset($width) ) {
1859 # Create a resized image, without the additional thumbnail
1862 if ( ( ! $height === false )
1863 && ( $img->getHeight() * $width / $img->getWidth() > $height ) ) {
1864 print "height=$height<br>\nimg->getHeight() = ".$img->getHeight()."<br>\n";
1865 print 'rescaling by factor '. $height / $img->getHeight() . "<br>\n";
1866 $width = $img->getWidth() * $height / $img->getHeight();
1868 if ( '' == $manual_thumb ) $url = $img->createThumb( $width );
1870 } # endif $wgUseImageResize
1872 if ( empty( $alt ) ) {
1873 $alt = preg_replace( '/\.(.+?)^/', '', $img->getName() );
1875 $alt = htmlspecialchars( $alt );
1877 $u = $nt->escapeLocalURL();
1880 $s = wfMsg( 'missingimage', $img->getName() );
1881 $s .= "<br>{$alt}<br>{$url}<br>\n";
1883 $s = '<a href="'.$u.'" class="image" title="'.$alt.'">' .
1884 '<img src="'.$url.'" alt="'.$alt.'" /></a>';
1886 if ( '' != $align ) {
1887 $s = "<div class=\"float{$align}\"><span>{$s}</span></div>";
1889 return str_replace("\n", ' ',$prefix.$s.$postfix);
1892 # Make HTML for a thumbnail including image, border and caption
1893 # $img is an Image object
1894 function makeThumbLinkObj( $img, $label = '', $align = 'right', $boxwidth = 180, $boxheight=false, $framed=false , $manual_thumb = "" ) {
1895 global $wgStylePath, $wgLang;
1896 # $image = Title::makeTitle( Namespace::getImage(), $name );
1897 $url = $img->getURL();
1899 #$label = htmlspecialchars( $label );
1900 $alt = preg_replace( '/<[^>]*>/', '', $label);
1901 $alt = htmlspecialchars( $alt );
1903 $width = $height = 0;
1904 if ( $img->exists() )
1906 $width = $img->getWidth();
1907 $height = $img->getHeight();
1909 if ( 0 == $width ||
0 == $height )
1911 $width = $height = 200;
1913 if ( $boxwidth == 0 )
1919 // Use image dimensions, don't scale
1921 $oboxwidth = $boxwidth +
2;
1922 $boxheight = $height;
1925 $h = intval( $height/($width/$boxwidth) );
1926 $oboxwidth = $boxwidth +
2;
1927 if ( ( ! $boxheight === false ) && ( $h > $boxheight ) )
1929 $boxwidth *= $boxheight/$h;
1933 if ( '' == $manual_thumb ) $thumbUrl = $img->createThumb( $boxwidth );
1936 if ( $manual_thumb != '' ) # Use manually specified thumbnail
1938 $manual_title = Title
::makeTitle( Namespace::getImage(), $manual_thumb ); #new Title ( $manual_thumb ) ;
1939 $manual_img = Image
::newFromTitle( $manual_title );
1940 $thumbUrl = $manual_img->getURL();
1941 if ( $manual_img->exists() )
1943 $width = $manual_img->getWidth();
1944 $height = $manual_img->getHeight();
1945 $boxwidth = $width ;
1946 $boxheight = $height ;
1947 $oboxwidth = $boxwidth +
2 ;
1951 $u = $img->getEscapeLocalURL();
1953 $more = htmlspecialchars( wfMsg( 'thumbnail-more' ) );
1954 $magnifyalign = $wgLang->isRTL() ?
'left' : 'right';
1955 $textalign = $wgLang->isRTL() ?
' style="text-align:right"' : '';
1957 $s = "<div class=\"thumb t{$align}\"><div style=\"width:{$oboxwidth}px;\">";
1958 if ( $thumbUrl == '' ) {
1959 $s .= wfMsg( 'missingimage', $img->getName() );
1962 $s .= '<a href="'.$u.'" class="internal" title="'.$alt.'">'.
1963 '<img src="'.$thumbUrl.'" alt="'.$alt.'" ' .
1964 'width="'.$boxwidth.'" height="'.$boxheight.'" /></a>';
1968 $zoomicon = '<div class="magnify" style="float:'.$magnifyalign.'">'.
1969 '<a href="'.$u.'" class="internal" title="'.$more.'">'.
1970 '<img src="'.$wgStylePath.'/images/magnify-clip.png" ' .
1971 'width="15" height="11" alt="'.$more.'" /></a></div>';
1974 $s .= ' <div class="thumbcaption" '.$textalign.'>'.$zoomicon.$label."</div></div></div>";
1975 return str_replace("\n", ' ', $s);
1978 function makeMediaLink( $name, $url, $alt = "" ) {
1979 $nt = Title
::makeTitle( Namespace::getMedia(), $name );
1980 return $this->makeMediaLinkObj( $nt, $alt );
1983 function makeMediaLinkObj( $nt, $alt = "" )
1985 if ( ! isset( $nt ) )
1987 ### HOTFIX. Instead of breaking, return empty string.
1990 $name = $nt->getDBKey();
1991 $url = Image
::wfImageUrl( $name );
1992 if ( empty( $alt ) ) {
1993 $alt = preg_replace( '/\.(.+?)^/', '', $name );
1996 $u = htmlspecialchars( $url );
1997 $s = "<a href=\"{$u}\" class='internal' title=\"{$alt}\">{$alt}</a>";
2002 function specialLink( $name, $key = "" )
2006 if ( '' == $key ) { $key = strtolower( $name ); }
2007 $pn = $wgLang->ucfirst( $name );
2008 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
2012 function makeExternalLink( $url, $text, $escape = true ) {
2013 $style = $this->getExternalLinkAttributes( $url, $text );
2014 $url = htmlspecialchars( $url );
2016 $text = htmlspecialchars( $text );
2018 return '<a href="'.$url.'"'.$style.'>'.$text.'</a>';
2021 # Called by history lists and recent changes
2024 # Returns text for the start of the tabular part of RC
2025 function beginRecentChangesList()
2027 $this->rc_cache
= array() ;
2028 $this->rcMoveIndex
= 0;
2029 $this->rcCacheIndex
= 0 ;
2030 $this->lastdate
= '';
2031 $this->rclistOpen
= false;
2035 function beginImageHistoryList()
2037 $s = "\n<h2>" . wfMsg( 'imghistory' ) . "</h2>\n" .
2038 "<p>" . wfMsg( 'imghistlegend' ) . "</p>\n".'<ul class="special">';
2042 # Returns text for the end of RC
2043 # If enhanced RC is in use, returns pretty much all the text
2044 function endRecentChangesList()
2046 $s = $this->recentChangesBlock() ;
2047 if( $this->rclistOpen
) {
2053 # Enhanced RC ungrouped line
2054 function recentChangesBlockLine ( $rcObj )
2056 global $wgStylePath, $wgLang ;
2058 # Get rc_xxxx variables
2059 extract( $rcObj->mAttribs
) ;
2060 $curIdEq = 'curid='.$rc_cur_id;
2065 $r .= '<img src="'.$wgStylePath.'/images/Arr_.png" width="12" height="12" border="0" />' ;
2068 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2069 $r .= ' ';
2071 # M & N (minor & new)
2072 $M = wfMsg( 'minoreditletter' );
2073 $N = wfMsg( 'newpageletter' );
2075 if ( $rc_type == RC_NEW
) {
2088 $r .= ' '.$rcObj->timestamp
.' ' ;
2092 $link = $rcObj->link
;
2093 if ( $rcObj->watched
) $link = '<strong>'.$link.'</strong>' ;
2098 $r .= $rcObj->difflink
;
2102 $r .= $this->makeKnownLinkObj( $rcObj->getTitle(), wfMsg( 'hist' ), $curIdEq.'&action=history' );
2105 $r .= ') . . '.$rcObj->userlink
;
2106 $r .= $rcObj->usertalklink
;
2109 if ( $rc_comment != '' && $rc_type != RC_MOVE
&& $rc_type != RC_MOVE_OVER_REDIRECT
) {
2110 $rc_comment=$this->formatComment($rc_comment);
2111 $r .= $wgLang->emphasize( ' ('.$rc_comment.')' );
2119 function recentChangesBlockGroup ( $block )
2121 global $wgStylePath, $wgLang ;
2124 $M = wfMsg( 'minoreditletter' );
2125 $N = wfMsg( 'newpageletter' );
2127 # Collate list of users
2129 $userlinks = array () ;
2130 foreach ( $block AS $rcObj ) {
2131 $oldid = $rcObj->mAttribs
['rc_last_oldid'];
2132 if ( $rcObj->mAttribs
['rc_new'] ) $isnew = true ;
2133 $u = $rcObj->userlink
;
2134 if ( !isset ( $userlinks[$u] ) ) $userlinks[$u] = 0 ;
2138 # Sort the list and convert to text
2139 krsort ( $userlinks ) ;
2140 asort ( $userlinks ) ;
2142 foreach ( $userlinks as $userlink => $count) {
2144 if ( $count > 1 ) $text .= " ({$count}×)" ;
2145 array_push ( $users , $text ) ;
2147 $users = ' <font size="-1">['.implode('; ',$users).']</font>' ;
2150 $rci = 'RCI'.$this->rcCacheIndex
;
2151 $rcl = 'RCL'.$this->rcCacheIndex
;
2152 $rcm = 'RCM'.$this->rcCacheIndex
;
2153 $toggleLink = "javascript:toggleVisibility('$rci','$rcm','$rcl')" ;
2154 $arrowdir = $wgLang->isRTL() ?
'l' : 'r';
2155 $tl = '<span id="'.$rcm.'"><a href="'.$toggleLink.'"><img src="'.$wgStylePath.'/images/Arr_'.$arrowdir.'.png" width="12" height="12" /></a></span>' ;
2156 $tl .= '<span id="'.$rcl.'" style="display:none"><a href="'.$toggleLink.'"><img src="'.$wgStylePath.'/images/Arr_d.png" width="12" height="12" /></a></span>' ;
2162 if ( $isnew ) $r .= $N ;
2163 else $r .= ' ' ;
2164 $r .= ' ' ; # Minor
2167 $r .= ' '.$block[0]->timestamp
.' ' ;
2171 $link = $block[0]->link
;
2172 if ( $block[0]->watched
) $link = '<strong>'.$link.'</strong>' ;
2175 $curIdEq = 'curid=' . $block[0]->mAttribs
['rc_cur_id'];
2176 if ( $block[0]->mAttribs
['rc_type'] != RC_LOG
) {
2178 $r .= ' ('.count($block).' ' ;
2179 if ( $isnew ) $r .= wfMsg('changes');
2180 else $r .= $this->makeKnownLinkObj( $block[0]->getTitle() , wfMsg('changes') ,
2181 $curIdEq.'&diff=0&oldid='.$oldid ) ;
2185 $r .= $this->makeKnownLinkObj( $block[0]->getTitle(), wfMsg( 'history' ), $curIdEq.'&action=history' );
2193 $r .= '<div id="'.$rci.'" style="display:none">' ;
2194 foreach ( $block AS $rcObj ) {
2195 # Get rc_xxxx variables
2196 extract( $rcObj->mAttribs
);
2198 $r .= '<img src="'.$wgStylePath.'/images/Arr_.png" width="12" height="12" />';
2199 $r .= '<tt> ' ;
2200 if ( $rc_new ) $r .= $N ;
2201 else $r .= ' ' ;
2202 if ( $rc_minor ) $r .= $M ;
2203 else $r .= ' ' ;
2207 if ( $rc_last_oldid != 0 ) {
2208 $o = 'oldid='.$rc_last_oldid ;
2210 if ( $rc_type == RC_LOG
) {
2211 $link = $rcObj->timestamp
;
2213 $link = $this->makeKnownLinkObj( $rcObj->getTitle(), $rcObj->timestamp
, "{$curIdEq}&$o" ) ;
2215 $link = '<tt>'.$link.'</tt>' ;
2219 $r .= $rcObj->curlink
;
2221 $r .= $rcObj->lastlink
;
2222 $r .= ') . . '.$rcObj->userlink
;
2223 $r .= $rcObj->usertalklink
;
2224 if ( $rc_comment != '' ) {
2225 $rc_comment=$this->formatComment($rc_comment);
2226 $r .= $wgLang->emphasize( ' ('.$rc_comment.')' ) ;
2232 $this->rcCacheIndex++
;
2236 # If enhanced RC is in use, this function takes the previously cached
2237 # RC lines, arranges them, and outputs the HTML
2238 function recentChangesBlock ()
2240 global $wgStylePath ;
2241 if ( count ( $this->rc_cache
) == 0 ) return '' ;
2243 foreach ( $this->rc_cache
AS $secureName => $block ) {
2244 if ( count ( $block ) < 2 ) {
2245 $blockOut .= $this->recentChangesBlockLine ( array_shift ( $block ) ) ;
2247 $blockOut .= $this->recentChangesBlockGroup ( $block ) ;
2251 return '<div>'.$blockOut.'</div>' ;
2254 # Called in a loop over all displayed RC entries
2255 # Either returns the line, or caches it for later use
2256 function recentChangesLine( &$rc, $watched = false )
2259 $usenew = $wgUser->getOption( 'usenewrc' );
2261 $line = $this->recentChangesLineNew ( $rc, $watched ) ;
2263 $line = $this->recentChangesLineOld ( $rc, $watched ) ;
2267 function recentChangesLineOld( &$rc, $watched = false )
2269 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds, $wgUseRCPatrol, $wgOnlySysopsCanPatrol;
2271 # Extract DB fields into local scope
2272 extract( $rc->mAttribs
);
2273 $curIdEq = 'curid=' . $rc_cur_id;
2275 # Make date header if necessary
2276 $date = $wgLang->date( $rc_timestamp, true);
2278 if ( $date != $this->lastdate
) {
2279 if ( '' != $this->lastdate
) { $s .= "</ul>\n"; }
2280 $s .= "<h4>{$date}</h4>\n<ul class='special'>";
2281 $this->lastdate
= $date;
2282 $this->rclistOpen
= true;
2285 # If this edit has not yet been patrolled, make it stick out
2286 $s .= ( ! $wgUseRCPatrol ||
$rc_patrolled ) ?
'<li> ' : '<li class="not_patrolled"> ';
2288 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2290 $s .= '(' . wfMsg( 'diff' ) . ') (';
2292 $s .= $this->makeKnownLinkObj( $rc->getMovedToTitle(), wfMsg( 'hist' ), 'action=history' ) .
2295 # "[[x]] moved to [[y]]"
2296 $msg = ( $rc_type == RC_MOVE
) ?
'1movedto2' : '1movedto2_redir';
2297 $s .= wfMsg( $msg, $this->makeKnownLinkObj( $rc->getTitle(), '', 'redirect=no' ),
2298 $this->makeKnownLinkObj( $rc->getMovedToTitle(), '' ) );
2301 if ( $rc_type == RC_NEW ||
$rc_type == RC_LOG
) {
2302 $diffLink = wfMsg( 'diff' );
2304 if ( $wgUseRCPatrol && $rc_patrolled == 0 && $wgUser->getID() != 0 &&
2305 ( $wgUser->isSysop() ||
!$wgOnlySysopsCanPatrol ) )
2306 $rcidparam = "&rcid={$rc_id}";
2309 $diffLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'diff' ),
2310 "{$curIdEq}&diff={$rc_this_oldid}&oldid={$rc_last_oldid}{$rcidparam}",
2311 '', '', ' tabindex="'.$rc->counter
.'"');
2313 $s .= '('.$diffLink.') (';
2316 $s .= $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'hist' ), $curIdEq.'&action=history' );
2319 # M and N (minor and new)
2320 if ( $rc_minor ) { $s .= ' <span class="minor">'.wfMsg( "minoreditletter" ).'</span>'; }
2321 if ( $rc_type == RC_NEW
) { $s .= '<span class="newpage">'.wfMsg( "newpageletter" ).'</span>'; }
2324 # If it's a new article, there is no diff link, but if it hasn't been
2325 # patrolled yet, we need to give users a way to do so
2326 if ( $wgUseRCPatrol && $rc_type == RC_NEW
&& $rc_patrolled == 0 &&
2327 $wgUser->getID() != 0 && ( $wgUser->isSysop() ||
!$wgOnlySysopsCanPatrol ) )
2328 $articleLink = $this->makeKnownLinkObj( $rc->getTitle(), '', "rcid={$rc_id}" );
2330 $articleLink = $this->makeKnownLinkObj( $rc->getTitle(), '' );
2333 $articleLink = '<strong>'.$articleLink.'</strong>';
2335 $s .= ' '.$articleLink;
2340 $s .= '; ' . $wgLang->time( $rc_timestamp, true, $wgRCSeconds ) . ' . . ';
2342 # User link (or contributions for unregistered users)
2343 if ( 0 == $rc_user ) {
2344 $userLink = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
2345 $rc_user_text, 'target=' . $rc_user_text );
2347 $userLink = $this->makeLink( $wgLang->getNsText( NS_USER
) . ':'.$rc_user_text, $rc_user_text );
2352 $talkname=$wgLang->getNsText(NS_TALK
); # use the shorter name
2353 global $wgDisableAnonTalk;
2354 if( 0 == $rc_user && $wgDisableAnonTalk ) {
2357 $utns=$wgLang->getNsText(NS_USER_TALK
);
2358 $userTalkLink= $this->makeLink($utns . ':'.$rc_user_text, $talkname );
2362 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2363 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2364 'Blockip' ), wfMsg( 'blocklink' ), 'ip='.$rc_user_text );
2368 if($userTalkLink) $userTalkLink .= ' | ';
2369 $userTalkLink .= $blockLink;
2371 if($userTalkLink) $s.=' ('.$userTalkLink.')';
2374 if ( '' != $rc_comment && '*' != $rc_comment && $rc_type != RC_MOVE
&& $rc_type != RC_MOVE_OVER_REDIRECT
) {
2375 $rc_comment=$this->formatComment($rc_comment);
2376 $s .= $wgLang->emphasize(' (' . $rc_comment . ')');
2383 function recentChangesLineNew( &$baseRC, $watched = false )
2385 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds;
2387 # Create a specialised object
2388 $rc = RCCacheEntry
::newFromParent( $baseRC ) ;
2390 # Extract fields from DB into the function scope (rc_xxxx variables)
2391 extract( $rc->mAttribs
);
2392 $curIdEq = 'curid=' . $rc_cur_id;
2394 # If it's a new day, add the headline and flush the cache
2395 $date = $wgLang->date( $rc_timestamp, true);
2397 if ( $date != $this->lastdate
) {
2398 # Process current cache
2399 $ret = $this->recentChangesBlock () ;
2400 $this->rc_cache
= array() ;
2401 $ret .= "<h4>{$date}</h4>\n";
2402 $this->lastdate
= $date;
2406 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2407 $msg = ( $rc_type == RC_MOVE
) ?
"1movedto2" : "1movedto2_redir";
2408 $clink = wfMsg( $msg, $this->makeKnownLinkObj( $rc->getTitle(), '', 'redirect=no' ),
2409 $this->makeKnownLinkObj( $rc->getMovedToTitle(), '' ) );
2411 $clink = $this->makeKnownLinkObj( $rc->getTitle(), '' ) ;
2414 $time = $wgLang->time( $rc_timestamp, true, $wgRCSeconds );
2415 $rc->watched
= $watched ;
2416 $rc->link
= $clink ;
2417 $rc->timestamp
= $time;
2419 # Make "cur" and "diff" links
2420 if ( ( $rc_type == RC_NEW
&& $rc_this_oldid == 0 ) ||
$rc_type == RC_LOG ||
$rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2421 $curLink = wfMsg( 'cur' );
2422 $diffLink = wfMsg( 'diff' );
2424 $query = $curIdEq.'&diff=0&oldid='.$rc_this_oldid;
2425 $aprops = ' tabindex="'.$baseRC->counter
.'"';
2426 $curLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'cur' ), $query, '' ,'' , $aprops );
2427 $diffLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'diff'), $query, '' ,'' , $aprops );
2431 $titleObj = $rc->getTitle();
2432 if ( $rc_last_oldid == 0 ||
$rc_type == RC_LOG ||
$rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2433 $lastLink = wfMsg( 'last' );
2435 $lastLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'last' ),
2436 $curIdEq.'&diff='.$rc_this_oldid.'&oldid='.$rc_last_oldid );
2439 # Make user link (or user contributions for unregistered users)
2440 if ( $rc_user == 0 ) {
2441 $userLink = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
2442 $rc_user_text, 'target=' . $rc_user_text );
2444 $userLink = $this->makeLink( $wgLang->getNsText(
2445 Namespace::getUser() ) . ':'.$rc_user_text, $rc_user_text );
2448 $rc->userlink
= $userLink;
2449 $rc->lastlink
= $lastLink;
2450 $rc->curlink
= $curLink;
2451 $rc->difflink
= $diffLink;
2453 # Make user talk link
2454 $utns=$wgLang->getNsText(NS_USER_TALK
);
2455 $talkname=$wgLang->getNsText(NS_TALK
); # use the shorter name
2456 $userTalkLink= $this->makeLink($utns . ':'.$rc_user_text, $talkname );
2458 global $wgDisableAnonTalk;
2459 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2460 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2461 'Blockip' ), wfMsg( 'blocklink' ), 'ip='.$rc_user_text );
2462 if( $wgDisableAnonTalk )
2463 $rc->usertalklink
= ' ('.$blockLink.')';
2465 $rc->usertalklink
= ' ('.$userTalkLink.' | '.$blockLink.')';
2467 if( $wgDisableAnonTalk && ($rc_user == 0) )
2468 $rc->usertalklink
= '';
2470 $rc->usertalklink
= ' ('.$userTalkLink.')';
2473 # Put accumulated information into the cache, for later display
2474 # Page moves go on their own line
2475 $title = $rc->getTitle();
2476 $secureName = $title->getPrefixedDBkey();
2477 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2478 # Use an @ character to prevent collision with page names
2479 $this->rc_cache
['@@' . ($this->rcMoveIndex++
)] = array($rc);
2481 if ( !isset ( $this->rc_cache
[$secureName] ) ) $this->rc_cache
[$secureName] = array() ;
2482 array_push ( $this->rc_cache
[$secureName] , $rc ) ;
2487 function endImageHistoryList()
2493 /* This function is called by all recent changes variants, by the page history,
2494 and by the user contributions list. It is responsible for formatting edit
2495 comments. It escapes any HTML in the comment, but adds some CSS to format
2496 auto-generated comments (from section editing) and formats [[wikilinks]].
2497 Main author: Erik Möller (moeller@scireview.de)
2499 function formatComment($comment)
2502 $comment = htmlspecialchars( $comment );
2504 # The pattern for autogen comments is / * foo * /, which makes for
2506 # We look for all comments, match any text before and after the comment,
2507 # add a separator where needed and format the comment itself with CSS
2508 while (preg_match('/(.*)\/\*\s*(.*?)\s*\*\/(.*)/', $comment,$match)) {
2513 if($pre) { $auto = $sep.' '.$auto; }
2514 if($post) { $auto .= ' '.$sep; }
2515 $auto='<span class="autocomment">'.$auto.'</span>';
2516 $comment=$pre.$auto.$post;
2519 # format regular and media links - all other wiki formatting
2521 $medians = $wgLang->getNsText(Namespace::getMedia()).':';
2522 while(preg_match('/\[\[(.*?)(\|(.*?))*\]\](.*)$/',$comment,$match)) {
2523 # Handle link renaming [[foo|text]] will show link as "text"
2524 if( "" != $match[3] ) {
2529 if( preg_match( '/^' . $medians . '(.*)$/i', $match[1], $submatch ) ) {
2530 # Media link; trail not supported.
2531 $linkRegexp = '/\[\[(.*?)\]\]/';
2532 $thelink = $this->makeMediaLink( $submatch[1], "", $text );
2534 # Other kind of link
2535 if( preg_match( wfMsg( "linktrail" ), $match[4], $submatch ) ) {
2536 $trail = $submatch[1];
2540 $linkRegexp = '/\[\[(.*?)\]\]' . preg_quote( $trail, '/' ) . '/';
2541 $thelink = $this->makeLink( $match[1], $text, "", $trail );
2543 $comment = preg_replace( $linkRegexp, $thelink, $comment, 1 );
2548 function imageHistoryLine( $iscur, $timestamp, $img, $user, $usertext, $size, $description )
2550 global $wgUser, $wgLang, $wgTitle;
2552 $datetime = $wgLang->timeanddate( $timestamp, true );
2553 $del = wfMsg( 'deleteimg' );
2554 $delall = wfMsg( 'deleteimgcompletely' );
2555 $cur = wfMsg( 'cur' );
2558 $url = Image
::wfImageUrl( $img );
2560 if ( $wgUser->isSysop() ) {
2561 $link = $wgTitle->escapeLocalURL( 'image=' . $wgTitle->getPartialURL() .
2563 $style = $this->getInternalLinkAttributes( $link, $delall );
2565 $dlink = '<a href="'.$link.'"'.$style.'>'.$delall.'</a>';
2570 $url = htmlspecialchars( wfImageArchiveUrl( $img ) );
2571 if( $wgUser->getID() != 0 && $wgTitle->userCanEdit() ) {
2572 $rlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2573 wfMsg( 'revertimg' ), 'action=revert&oldimage=' .
2574 urlencode( $img ) );
2575 $dlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2576 $del, 'action=delete&oldimage=' . urlencode( $img ) );
2578 # Having live active links for non-logged in users
2579 # means that bots and spiders crawling our site can
2580 # inadvertently change content. Baaaad idea.
2581 $rlink = wfMsg( 'revertimg' );
2586 $userlink = $usertext;
2588 $userlink = $this->makeLink( $wgLang->getNsText( Namespace::getUser() ) .
2589 ':'.$usertext, $usertext );
2591 $nbytes = wfMsg( 'nbytes', $size );
2592 $style = $this->getInternalLinkAttributes( $url, $datetime );
2594 $s = "<li> ({$dlink}) ({$rlink}) <a href=\"{$url}\"{$style}>{$datetime}</a>"
2595 . " . . {$userlink} ({$nbytes})";
2597 if ( '' != $description && '*' != $description ) {
2598 $sk=$wgUser->getSkin();
2599 $s .= $wgLang->emphasize(' (' . $sk->formatComment($description) . ')');
2605 function tocIndent($level) {
2606 return str_repeat( '<div class="tocindent">'."\n", $level>0 ?
$level : 0 );
2609 function tocUnindent($level) {
2610 return str_repeat( "</div>\n", $level>0 ?
$level : 0 );
2613 # parameter level defines if we are on an indentation level
2614 function tocLine( $anchor, $tocline, $level ) {
2615 $link = '<a href="#'.$anchor.'">'.$tocline.'</a><br />';
2619 return '<div class="tocline">'.$link."</div>\n";
2624 function tocTable($toc) {
2625 # note to CSS fanatics: putting this in a div does not work -- div won't auto-expand
2626 # try min-width & co when somebody gets a chance
2627 $hideline = ' <script type="text/javascript">showTocToggle("' . addslashes( wfMsg('showtoc') ) . '","' . addslashes( wfMsg('hidetoc') ) . '")</script>';
2629 '<table border="0" id="toc"><tr id="toctitle"><td align="center">'."\n".
2630 '<b>'.wfMsg('toc').'</b>' .
2632 '</td></tr><tr id="tocinside"><td>'."\n".
2633 $toc."</td></tr></table>\n";
2636 # These two do not check for permissions: check $wgTitle->userCanEdit before calling them
2637 function editSectionScript( $section, $head ) {
2638 global $wgTitle, $wgRequest;
2639 if( $wgRequest->getInt( 'oldid' ) && ( $wgRequest->getVal( 'diff' ) != '0' ) ) {
2642 $url = $wgTitle->escapeLocalURL( 'action=edit§ion='.$section );
2643 return '<span oncontextmenu=\'document.location="'.$url.'";return false;\'>'.$head.'</span>';
2646 function editSectionLink( $section ) {
2648 global $wgTitle, $wgUser, $wgLang;
2650 if( $wgRequest->getInt( 'oldid' ) && ( $wgRequest->getVal( 'diff' ) != '0' ) ) {
2651 # Section edit links would be out of sync on an old page.
2652 # But, if we're diffing to the current page, they'll be
2657 $editurl = '§ion='.$section;
2658 $url = $this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg('editsection'),'action=edit'.$editurl);
2660 if( $wgLang->isRTL() ) {
2662 $nearside = 'right';
2667 return "<div class=\"editsection\" style=\"float:$farside;margin-$nearside:5px;\">[".$url."]</div>";
2671 // This function is called by EditPage.php and shows a bulletin board style
2672 // toolbar for common editing functions. It can be disabled in the user preferences.
2673 // The necsesary JavaScript code can be found in style/wikibits.js.
2674 function getEditToolbar() {
2675 global $wgStylePath, $wgLang, $wgMimeType;
2677 // toolarray an array of arrays which each include the filename of
2678 // the button image (without path), the opening tag, the closing tag,
2679 // and optionally a sample text that is inserted between the two when no
2680 // selection is highlighted.
2681 // The tip text is shown when the user moves the mouse over the button.
2683 // Already here are accesskeys (key), which are not used yet until someone
2684 // can figure out a way to make them work in IE. However, we should make
2685 // sure these keys are not defined on the edit page.
2687 array( 'image'=>'button_bold.png',
2690 'sample'=>wfMsg('bold_sample'),
2691 'tip'=>wfMsg('bold_tip'),
2694 array( "image"=>"button_italic.png",
2697 "sample"=>wfMsg("italic_sample"),
2698 "tip"=>wfMsg("italic_tip"),
2701 array( "image"=>"button_link.png",
2704 "sample"=>wfMsg("link_sample"),
2705 "tip"=>wfMsg("link_tip"),
2708 array( "image"=>"button_extlink.png",
2711 "sample"=>wfMsg("extlink_sample"),
2712 "tip"=>wfMsg("extlink_tip"),
2715 array( "image"=>"button_headline.png",
2718 "sample"=>wfMsg("headline_sample"),
2719 "tip"=>wfMsg("headline_tip"),
2722 array( "image"=>"button_image.png",
2723 "open"=>"[[".$wgLang->getNsText(NS_IMAGE
).":",
2725 "sample"=>wfMsg("image_sample"),
2726 "tip"=>wfMsg("image_tip"),
2729 array( "image"=>"button_media.png",
2730 "open"=>"[[".$wgLang->getNsText(NS_MEDIA
).":",
2732 "sample"=>wfMsg("media_sample"),
2733 "tip"=>wfMsg("media_tip"),
2736 array( "image"=>"button_math.png",
2737 "open"=>"\\<math\\>",
2738 "close"=>"\\</math\\>",
2739 "sample"=>wfMsg("math_sample"),
2740 "tip"=>wfMsg("math_tip"),
2743 array( "image"=>"button_nowiki.png",
2744 "open"=>"\\<nowiki\\>",
2745 "close"=>"\\</nowiki\\>",
2746 "sample"=>wfMsg("nowiki_sample"),
2747 "tip"=>wfMsg("nowiki_tip"),
2750 array( "image"=>"button_sig.png",
2754 "tip"=>wfMsg("sig_tip"),
2757 array( "image"=>"button_hr.png",
2758 "open"=>"\\n----\\n",
2761 "tip"=>wfMsg("hr_tip"),
2765 $toolbar ="<script type='text/javascript'>\n/*<![CDATA[*/\n";
2767 $toolbar.="document.writeln(\"<div id='toolbar'>\");\n";
2768 foreach($toolarray as $tool) {
2770 $image=$wgStylePath.'/images/'.$tool['image'];
2771 $open=$tool['open'];
2772 $close=$tool['close'];
2773 $sample = addslashes( $tool['sample'] );
2775 // Note that we use the tip both for the ALT tag and the TITLE tag of the image.
2776 // Older browsers show a "speedtip" type message only for ALT.
2777 // Ideally these should be different, realistically they
2778 // probably don't need to be.
2779 $tip = addslashes( $tool['tip'] );
2781 #$key = $tool["key"];
2783 $toolbar.="addButton('$image','$tip','$open','$close','$sample');\n";
2786 $toolbar.="addInfobox('" . addslashes( wfMsg( "infobox" ) ) . "','" . addslashes(wfMsg("infobox_alert")) . "');\n";
2787 $toolbar.="document.writeln(\"</div>\");\n";
2789 $toolbar.="/*]]>*/\n</script>";