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';
27 $wgValidSkinNames['chick'] = 'Chick';
30 require_once( 'RecentChange.php' );
32 class RCCacheEntry
extends RecentChange
34 var $secureName, $link;
35 var $curlink , $difflink, $lastlink , $usertalklink , $versionlink ;
36 var $userlink, $timestamp, $watched;
38 function newFromParent( $rc )
40 $rc2 = new RCCacheEntry
;
41 $rc2->mAttribs
= $rc->mAttribs
;
42 $rc2->mExtra
= $rc->mExtra
;
49 /* private */ var $lastdate, $lastline;
50 var $linktrail ; # linktrail regexp
51 var $rc_cache ; # Cache for Enhanced Recent Changes
52 var $rcCacheIndex ; # Recent Changes Cache Counter for visibility toggle
54 var $postParseLinkColour = true;
58 global $wgUseOldExistenceCheck;
59 $postParseLinkColour = !$wgUseOldExistenceCheck;
60 $this->linktrail
= wfMsg('linktrail');
63 function getSkinNames()
65 global $wgValidSkinNames;
66 return $wgValidSkinNames;
69 function getStylesheet()
71 return 'wikistandard.css';
73 function getSkinName() {
77 # Get/set accessor for delayed link colouring
78 function postParseLinkColour( $setting = NULL ) {
79 return wfSetVar( $this->postParseLinkColour
, $setting );
84 global $wgOut, $wgUser;
86 if ( $wgOut->isQuickbarSuppressed() ) { return 0; }
87 $q = $wgUser->getOption( 'quickbar' );
88 if ( '' == $q ) { $q = 0; }
92 function initPage( &$out )
94 $fname = 'Skin::initPage';
95 wfProfileIn( $fname );
97 $out->addLink( array( 'rel' => 'shortcut icon', 'href' => '/favicon.ico' ) );
99 $this->addMetadataLinks($out);
101 wfProfileOut( $fname );
104 function addMetadataLinks( &$out ) {
105 global $wgTitle, $wgEnableDublinCoreRdf, $wgEnableCreativeCommonsRdf, $wgRdfMimeType, $action;
106 global $wgRightsPage, $wgRightsUrl;
108 if( $out->isArticleRelated() ) {
109 # note: buggy CC software only reads first "meta" link
110 if( $wgEnableCreativeCommonsRdf ) {
111 $out->addMetadataLink( array(
112 'title' => 'Creative Commons',
113 'type' => 'application/rdf+xml',
114 'href' => $wgTitle->getLocalURL( 'action=creativecommons') ) );
116 if( $wgEnableDublinCoreRdf ) {
117 $out->addMetadataLink( array(
118 'title' => 'Dublin Core',
119 'type' => 'application/rdf+xml',
120 'href' => $wgTitle->getLocalURL( 'action=dublincore' ) ) );
124 if( $wgRightsPage ) {
125 $copy = Title
::newFromText( $wgRightsPage );
127 $copyright = $copy->getLocalURL();
130 if( !$copyright && $wgRightsUrl ) {
131 $copyright = $wgRightsUrl;
134 $out->addLink( array(
135 'rel' => 'copyright',
136 'href' => $copyright ) );
140 function outputPage( &$out ) {
141 global $wgDebugComments;
143 wfProfileIn( 'Skin::outputPage' );
144 $this->initPage( $out );
145 $out->out( $out->headElement() );
147 $out->out( "\n<body" );
148 $ops = $this->getBodyOptions();
149 foreach ( $ops as $name => $val ) {
150 $out->out( " $name='$val'" );
153 if ( $wgDebugComments ) {
154 $out->out( "<!-- Wiki debugging output:\n" .
155 $out->mDebugtext
. "-->\n" );
157 $out->out( $this->beforeContent() );
159 $out->out( $out->mBodytext
. "\n" );
161 $out->out( $this->afterContent() );
164 $out->out( $out->reportTime() );
166 $out->out( "\n</body></html>" );
169 function getHeadScripts() {
170 global $wgStylePath, $wgUser, $wgLang, $wgAllowUserJs;
171 $r = "<script type=\"text/javascript\" src=\"{$wgStylePath}/wikibits.js\"></script>\n";
172 if( $wgAllowUserJs && $wgUser->getID() != 0 ) { # logged in
173 $userpage = $wgLang->getNsText( Namespace::getUser() ) . ":" . $wgUser->getName();
174 $userjs = htmlspecialchars($this->makeUrl($userpage.'/'.$this->getSkinName().'.js', 'action=raw&ctype=text/javascript'));
175 $r .= '<script type="text/javascript" src="'.$userjs."\"></script>\n";
180 # get the user/site-specific stylesheet, SkinPHPTal called from RawPage.php (settings are cached that way)
181 function getUserStylesheet() {
182 global $wgOut, $wgStylePath, $wgLang, $wgUser, $wgRequest, $wgTitle, $wgAllowUserCss;
183 $sheet = $this->getStylesheet();
184 $action = $wgRequest->getText('action');
185 $s = "@import \"$wgStylePath/$sheet\";\n";
186 if($wgLang->isRTL()) $s .= "@import \"$wgStylePath/common_rtl.css\";\n";
187 if( $wgAllowUserCss && $wgUser->getID() != 0 ) { # logged in
188 if($wgTitle->isCssSubpage() and $action == 'submit' and $wgTitle->userCanEditCssJsSubpage()) {
189 $s .= $wgRequest->getText('wpTextbox1');
191 $userpage = $wgLang->getNsText( Namespace::getUser() ) . ":" . $wgUser->getName();
192 $s.= '@import "'.$this->makeUrl($userpage.'/'.$this->getSkinName().'.css', 'action=raw&ctype=text/css').'";'."\n";
195 $s .= $this->doGetUserStyles();
198 # placeholder, returns generated js in monobook
199 function getUserJs() {
203 function getUserStyles()
205 global $wgOut, $wgStylePath, $wgLang;
206 $s = "<style type='text/css'>\n";
207 $s .= "/*/*/ /*<![CDATA[*/\n"; # <-- Hide the styles from Netscape 4 without hiding them from IE/Mac
208 $s .= $this->getUserStylesheet();
209 $s .= "/*]]>*/ /* */\n";
214 function doGetUserStyles()
216 global $wgUser, $wgLang;
218 $csspage = $wgLang->getNsText( NS_MEDIAWIKI
) . ":" . $this->getSkinName() . ".css";
219 $s = '@import "'.$this->makeUrl($csspage, 'action=raw&ctype=text/css')."\";\n";
221 if ( 1 == $wgUser->getOption( 'underline' ) ) {
222 # Don't override browser settings
226 $s .= "a { text-decoration: none; }\n";
228 if ( 1 == $wgUser->getOption( 'highlightbroken' ) ) {
229 $s .= "a.new, #quickbar a.new { color: #CC2200; }\n";
231 if ( 1 == $wgUser->getOption( 'justify' ) ) {
232 $s .= "#article { text-align: justify; }\n";
237 function getBodyOptions()
239 global $wgUser, $wgTitle, $wgNamespaceBackgrounds, $wgOut, $wgRequest;
241 extract( $wgRequest->getValues( 'oldid', 'redirect', 'diff' ) );
243 if ( 0 != $wgTitle->getNamespace() ) {
244 $a = array( 'bgcolor' => '#ffffec' );
246 else $a = array( 'bgcolor' => '#FFFFFF' );
247 if($wgOut->isArticle() && $wgUser->getOption('editondblclick') &&
248 (!$wgTitle->isProtected() ||
$wgUser->isSysop()) ) {
249 $t = wfMsg( 'editthispage' );
251 if ( !empty($redirect) ) {
252 $red = "&redirect={$redirect}";
254 if ( !empty($oldid) && ! isset( $diff ) ) {
255 $oid = "&oldid={$oldid}";
257 $s = $wgTitle->getFullURL( "action=edit{$oid}{$red}" );
258 $s = 'document.location = "' .$s .'";';
259 $a +
= array ('ondblclick' => $s);
262 $a['onload'] = $wgOut->getOnloadHandler();
266 function getExternalLinkAttributes( $link, $text, $class='' )
268 global $wgUser, $wgOut, $wgLang;
270 $link = urldecode( $link );
271 $link = $wgLang->checkTitleEncoding( $link );
272 $link = str_replace( '_', ' ', $link );
273 $link = htmlspecialchars( $link );
275 $r = ($class != '') ?
" class='$class'" : " class='external'";
277 if ( 1 == $wgUser->getOption( 'hover' ) ) {
278 $r .= " title=\"{$link}\"";
283 function getInternalLinkAttributes( $link, $text, $broken = false )
285 global $wgUser, $wgOut;
287 $link = urldecode( $link );
288 $link = str_replace( '_', ' ', $link );
289 $link = htmlspecialchars( $link );
291 if ( $broken == 'stub' ) {
292 $r = ' class="stub"';
293 } else if ( $broken == 'yes' ) {
299 if ( 1 == $wgUser->getOption( 'hover' ) ) {
300 $r .= " title=\"{$link}\"";
305 function getInternalLinkAttributesObj( &$nt, $text, $broken = false )
307 global $wgUser, $wgOut;
309 if ( $broken == 'stub' ) {
310 $r = ' class="stub"';
311 } else if ( $broken == 'yes' ) {
317 if ( 1 == $wgUser->getOption( 'hover' ) ) {
318 $r .= ' title ="' . $nt->getEscapedText() . '"';
329 # This will be called immediately after the <body> tag. Split into
330 # two functions to make it easier to subclass.
332 function beforeContent()
334 global $wgUser, $wgOut;
336 return $this->doBeforeContent();
339 function doBeforeContent()
341 global $wgUser, $wgOut, $wgTitle, $wgLang, $wgSiteNotice;
342 $fname = 'Skin::doBeforeContent';
343 wfProfileIn( $fname );
346 $qb = $this->qbSetting();
348 if( $langlinks = $this->otherLanguages() ) {
354 $borderhack = 'class="top"';
357 $s .= "\n<div id='content'>\n<div id='topbar'>\n" .
358 "<table border='0' cellspacing='0' width='98%'>\n<tr>\n";
361 $left = ($qb == 1 ||
$qb == 3);
362 if($wgLang->isRTL()) $left = !$left;
365 $s .= "<td class='top' align='left' valign='top' rowspan='{$rows}'>\n" .
366 $this->logoText() . '</td>';
368 $s .= $this->getQuickbarCompensator( $rows );
370 $l = $wgLang->isRTL() ?
'right' : 'left';
371 $s .= "<td {$borderhack} align='$l' valign='top'>\n";
373 $s .= $this->topLinks() ;
374 $s .= "<p class='subtitle'>" . $this->pageTitleLinks() . "</p>\n";
376 $r = $wgLang->isRTL() ?
"left" : "right";
377 $s .= "</td>\n<td {$borderhack} valign='top' align='$r' nowrap='nowrap'>";
378 $s .= $this->nameAndLogin();
379 $s .= "\n<br />" . $this->searchForm() . "</td>";
382 $s .= "</tr>\n<tr>\n<td class='top' colspan=\"2\">$langlinks</td>\n";
385 if ( $shove && !$left ) { # Right
386 $s .= $this->getQuickbarCompensator( $rows );
388 $s .= "</tr>\n</table>\n</div>\n";
389 $s .= "\n<div id='article'>\n";
391 if( $wgSiteNotice ) {
392 $s .= "\n<div id='siteNotice'>$wgSiteNotice</div>\n";
394 $s .= $this->pageTitle();
395 $s .= $this->pageSubtitle() ;
396 $s .= $this->getCategories();
397 wfProfileOut( $fname );
401 function getCategoryLinks () {
402 global $wgOut, $wgTitle, $wgUser, $wgParser;
403 global $wgUseCategoryMagic, $wgUseCategoryBrowser, $wgLang;
405 if( !$wgUseCategoryMagic ) return '' ;
406 if( count( $wgOut->mCategoryLinks
) == 0 ) return '';
408 # Taken out so that they will be displayed in previews -- TS
409 #if( !$wgOut->isArticle() ) return '';
411 $t = implode ( ' | ' , $wgOut->mCategoryLinks
) ;
412 $s = $this->makeKnownLink( 'Special:Categories',
413 wfMsg( 'categories' ), 'article=' . urlencode( $wgTitle->getPrefixedDBkey() ) )
416 if($wgUseCategoryBrowser) {
419 $s.= $wgTitle->getAllParentCategories($catstack);
425 function getCategories() {
426 $catlinks=$this->getCategoryLinks();
427 if(!empty($catlinks)) {
428 return "<p class='catlinks'>{$catlinks}</p>";
432 function getQuickbarCompensator( $rows = 1 )
434 return "<td width='152' rowspan='{$rows}'> </td>";
437 # This gets called immediately before the </body> tag.
439 function afterContent()
441 global $wgUser, $wgOut, $wgServer;
442 global $wgTitle, $wgLang;
444 $printfooter = "<div class=\"printfooter\">\n" . $this->printFooter() . "</div>\n";
445 return $printfooter . $this->doAfterContent();
448 function printSource() {
450 $url = htmlspecialchars( $wgTitle->getFullURL() );
451 return wfMsg( "retrievedfrom", "<a href=\"$url\">$url</a>" );
454 function printFooter() {
455 return "<p>" . $this->printSource() .
456 "</p>\n\n<p>" . $this->pageStats() . "</p>\n";
459 function doAfterContent()
461 global $wgUser, $wgOut, $wgLang;
462 $fname = 'Skin::doAfterContent';
463 wfProfileIn( $fname );
464 wfProfileIn( $fname.'-1' );
466 $s = "\n</div><br style=\"clear:both\" />\n";
467 $s .= "\n<div id='footer'>";
468 $s .= '<table border="0" cellspacing="0"><tr>';
470 wfProfileOut( $fname.'-1' );
471 wfProfileIn( $fname.'-2' );
473 $qb = $this->qbSetting();
475 $left = ($qb == 1 ||
$qb == 3);
476 if($wgLang->isRTL()) $left = !$left;
478 if ( $shove && $left ) { # Left
479 $s .= $this->getQuickbarCompensator();
481 wfProfileOut( $fname.'-2' );
482 wfProfileIn( $fname.'-3' );
483 $l = $wgLang->isRTL() ?
'right' : 'left';
484 $s .= "<td class='bottom' align='$l' valign='top'>";
486 $s .= $this->bottomLinks();
487 $s .= "\n<br />" . $this->mainPageLink()
488 . ' | ' . $this->aboutLink()
489 . ' | ' . $this->specialLink( 'recentchanges' )
490 . ' | ' . $this->searchForm()
491 . '<br /><span id="pagestats">' . $this->pageStats() . '</span>';
494 if ( $shove && !$left ) { # Right
495 $s .= $this->getQuickbarCompensator();
497 $s .= "</tr></table>\n</div>\n</div>\n";
499 wfProfileOut( $fname.'-3' );
500 wfProfileIn( $fname.'-4' );
501 if ( 0 != $qb ) { $s .= $this->quickBar(); }
502 wfProfileOut( $fname.'-4' );
503 wfProfileOut( $fname );
507 function pageTitleLinks()
509 global $wgOut, $wgTitle, $wgUser, $wgLang, $wgUseApproval, $wgRequest;
511 extract( $wgRequest->getValues( 'oldid', 'diff' ) );
512 $action = $wgRequest->getText( 'action' );
514 $s = $this->printableLink();
515 if ( wfMsg ( 'disclaimers' ) != '-' ) $s .= ' | ' . $this->makeKnownLink( wfMsg( 'disclaimerpage' ), wfMsg( 'disclaimers' ) ) ;
517 if ( $wgOut->isArticleRelated() ) {
518 if ( $wgTitle->getNamespace() == Namespace::getImage() ) {
519 $name = $wgTitle->getDBkey();
520 $link = htmlspecialchars( Image
::wfImageUrl( $name ) );
521 $style = $this->getInternalLinkAttributes( $link, $name );
522 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>";
524 # This will show the "Approve" link if $wgUseApproval=true;
525 if ( isset ( $wgUseApproval ) && $wgUseApproval )
527 $t = $wgTitle->getDBkey();
528 $name = 'Approve this article' ;
529 $link = "http://test.wikipedia.org/w/magnus/wiki.phtml?title={$t}&action=submit&doit=1" ;
530 #htmlspecialchars( wfImageUrl( $name ) );
531 $style = $this->getExternalLinkAttributes( $link, $name );
532 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>" ;
535 if ( 'history' == $action ||
isset( $diff ) ||
isset( $oldid ) ) {
536 $s .= ' | ' . $this->makeKnownLink( $wgTitle->getPrefixedText(),
537 wfMsg( 'currentrev' ) );
540 if ( $wgUser->getNewtalk() ) {
541 # do not show "You have new messages" text when we are viewing our
544 if(!(strcmp($wgTitle->getText(),$wgUser->getName()) == 0 &&
545 $wgTitle->getNamespace()==Namespace::getTalk(Namespace::getUser()))) {
546 $n =$wgUser->getName();
547 $tl = $this->makeKnownLink( $wgLang->getNsText(
548 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
549 wfMsg('newmessageslink') );
550 $s.= ' | <strong>'. wfMsg( 'newmessages', $tl ) . '</strong>';
554 $undelete = $this->getUndeleteLink();
555 if( !empty( $undelete ) ) {
556 $s .= ' | '.$undelete;
561 function getUndeleteLink() {
562 global $wgUser, $wgTitle, $wgLang, $action;
563 if( $wgUser->isSysop() &&
564 (($wgTitle->getArticleId() == 0) ||
($action == "history")) &&
565 ($n = $wgTitle->isDeleted() ) ) {
566 return wfMsg( 'thisisdeleted',
567 $this->makeKnownLink(
568 $wgLang->SpecialPage( 'Undelete/' . $wgTitle->getPrefixedDBkey() ),
569 wfMsg( 'restorelink', $n ) ) );
574 function printableLink()
576 global $wgOut, $wgFeedClasses, $wgRequest;
578 $baseurl = $_SERVER['REQUEST_URI'];
579 if( strpos( '?', $baseurl ) == false ) {
584 $baseurl = htmlspecialchars( $baseurl );
585 $printurl = $wgRequest->escapeAppendQuery( 'printable=yes' );
587 $s = "<a href=\"$printurl\">" . wfMsg( 'printableversion' ) . '</a>';
588 if( $wgOut->isSyndicated() ) {
589 foreach( $wgFeedClasses as $format => $class ) {
590 $feedurl = $wgRequest->escapeAppendQuery( "feed=$format" );
591 $s .= " | <a href=\"$feedurl\">{$format}</a>";
599 global $wgOut, $wgTitle, $wgUser;
601 $s = '<h1 class="pagetitle">' . htmlspecialchars( $wgOut->getPageTitle() ) . '</h1>';
602 if($wgUser->getOption( 'editsectiononrightclick' ) && $wgTitle->userCanEdit()) { $s=$this->editSectionScript(0,$s);}
606 function pageSubtitle()
610 $sub = $wgOut->getSubtitle();
612 global $wgExtraSubtitle;
613 $sub = wfMsg( 'fromwikipedia' ) . $wgExtraSubtitle;
615 $subpages = $this->subPageSubtitle();
616 $sub .= !empty($subpages)?
"</p><p class='subpages'>$subpages":'';
617 $s = "<p class='subtitle'>{$sub}</p>\n";
621 function subPageSubtitle()
623 global $wgOut,$wgTitle,$wgNamespacesWithSubpages;
625 if($wgOut->isArticle() && !empty($wgNamespacesWithSubpages[$wgTitle->getNamespace()])) {
626 $ptext=$wgTitle->getPrefixedText();
627 if(preg_match('/\//',$ptext)) {
628 $links = explode('/',$ptext);
631 foreach($links as $link) {
633 if ($c<count($links)) {
634 $growinglink .= $link;
635 $getlink = $this->makeLink( $growinglink, $link );
636 if(preg_match('/class="new"/i',$getlink)) { break; } # this is a hack, but it saves time
640 $subpages .= '< ';
642 $subpages .= $getlink;
651 function nameAndLogin()
653 global $wgUser, $wgTitle, $wgLang, $wgShowIPinHeader, $wgIP;
655 $li = $wgLang->specialPage( 'Userlogin' );
656 $lo = $wgLang->specialPage( 'Userlogout' );
659 if ( 0 == $wgUser->getID() ) {
660 if( $wgShowIPinHeader && isset( $_COOKIE[ini_get('session.name')] ) ) {
663 $tl = $this->makeKnownLink( $wgLang->getNsText(
664 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
665 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
667 $s .= $n . ' ('.$tl.')';
669 $s .= wfMsg('notloggedin');
672 $rt = $wgTitle->getPrefixedURL();
673 if ( 0 == strcasecmp( urlencode( $lo ), $rt ) ) {
675 } else { $q = "returnto={$rt}"; }
677 $s .= "\n<br />" . $this->makeKnownLink( $li,
678 wfMsg( 'login' ), $q );
680 $n = $wgUser->getName();
681 $rt = $wgTitle->getPrefixedURL();
682 $tl = $this->makeKnownLink( $wgLang->getNsText(
683 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
684 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
688 $s .= $this->makeKnownLink( $wgLang->getNsText(
689 Namespace::getUser() ) . ":{$n}", $n ) . "{$tl}<br />" .
690 $this->makeKnownLink( $lo, wfMsg( 'logout' ),
691 "returnto={$rt}" ) . ' | ' .
692 $this->specialLink( 'preferences' );
694 $s .= ' | ' . $this->makeKnownLink( wfMsg( 'helppage' ),
700 function getSearchLink() {
701 $searchPage =& Title
::makeTitle( NS_SPECIAL
, 'Search' );
702 return $searchPage->getLocalURL();
705 function escapeSearchLink() {
706 return htmlspecialchars( $this->getSearchLink() );
709 function searchForm()
712 $search = $wgRequest->getText( 'search' );
714 $s = '<form name="search" class="inline" method="post" action="'
715 . $this->escapeSearchLink() . "\">\n"
716 . '<input type="text" name="search" size="19" value="'
717 . htmlspecialchars(substr($search,0,256)) . "\" />\n"
718 . '<input type="submit" name="go" value="' . wfMsg ('go') . '" /> '
719 . '<input type="submit" name="fulltext" value="' . wfMsg ('search') . "\" />\n</form>";
729 $s = $this->mainPageLink() . $sep
730 . $this->specialLink( 'recentchanges' );
732 if ( $wgOut->isArticleRelated() ) {
733 $s .= $sep . $this->editThisPage()
734 . $sep . $this->historyLink();
736 # Many people don't like this dropdown box
737 #$s .= $sep . $this->specialPagesList();
742 function bottomLinks()
744 global $wgOut, $wgUser, $wgTitle;
748 if ( $wgOut->isArticleRelated() ) {
749 $s .= '<strong>' . $this->editThisPage() . '</strong>';
750 if ( 0 != $wgUser->getID() ) {
751 $s .= $sep . $this->watchThisPage();
753 $s .= $sep . $this->talkLink()
754 . $sep . $this->historyLink()
755 . $sep . $this->whatLinksHere()
756 . $sep . $this->watchPageLinksLink();
758 if ( $wgTitle->getNamespace() == Namespace::getUser()
759 ||
$wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser()) )
762 $id=User
::idFromName($wgTitle->getText());
763 $ip=User
::isIP($wgTitle->getText());
765 if($id ||
$ip) { # both anons and non-anons have contri list
766 $s .= $sep . $this->userContribsLink();
768 if ( 0 != $wgUser->getID() ) { # show only to signed in users
769 if($id) { # can only email non-anons
770 $s .= $sep . $this->emailUserLink();
774 if ( $wgUser->isSysop() && $wgTitle->getArticleId() ) {
775 $s .= "\n<br />" . $this->deleteThisPage() .
776 $sep . $this->protectThisPage() .
777 $sep . $this->moveThisPage();
779 $s .= "<br />\n" . $this->otherLanguages();
786 global $wgOut, $wgLang, $wgArticle, $wgRequest;
787 global $wgDisableCounters, $wgMaxCredits, $wgShowCreditsIfMax;
789 extract( $wgRequest->getValues( 'oldid', 'diff' ) );
790 if ( ! $wgOut->isArticle() ) { return ''; }
791 if ( isset( $oldid ) ||
isset( $diff ) ) { return ''; }
792 if ( 0 == $wgArticle->getID() ) { return ''; }
795 if ( !$wgDisableCounters ) {
796 $count = $wgLang->formatNum( $wgArticle->getCount() );
798 $s = wfMsg( 'viewcount', $count );
802 if (isset($wgMaxCredits) && $wgMaxCredits != 0) {
803 require_once("Credits.php");
804 $s .= ' ' . getCredits($wgArticle, $wgMaxCredits, $wgShowCreditsIfMax);
806 $s .= $this->lastModified();
809 return $s . ' ' . $this->getCopyright();
812 function getCopyright() {
813 global $wgRightsPage, $wgRightsUrl, $wgRightsText, $wgRequest;
816 $oldid = $wgRequest->getVal( 'oldid' );
817 $diff = $wgRequest->getVal( 'diff' );
819 if ( !is_null( $oldid ) && is_null( $diff ) && wfMsg( 'history_copyright' ) !== '-' ) {
820 $msg = 'history_copyright';
826 if( $wgRightsPage ) {
827 $link = $this->makeKnownLink( $wgRightsPage, $wgRightsText );
828 } elseif( $wgRightsUrl ) {
829 $link = $this->makeExternalLink( $wgRightsUrl, $wgRightsText );
834 $out .= wfMsg( $msg, $link );
838 function getCopyrightIcon() {
839 global $wgRightsPage, $wgRightsUrl, $wgRightsText, $wgRightsIcon;
841 if( $wgRightsIcon ) {
842 $icon = htmlspecialchars( $wgRightsIcon );
844 $url = htmlspecialchars( $wgRightsUrl );
845 $out .= '<a href="'.$url.'">';
847 $text = htmlspecialchars( $wgRightsText );
848 $out .= "<img src=\"$icon\" alt='$text' />";
856 function getPoweredBy() {
858 $url = htmlspecialchars( "$wgStylePath/images/poweredby_mediawiki_88x31.png" );
859 $img = '<a href="http://www.mediawiki.org/"><img src="'.$url.'" alt="MediaWiki" /></a>';
863 function lastModified()
865 global $wgLang, $wgArticle;
867 $timestamp = $wgArticle->getTimestamp();
869 $d = $wgLang->timeanddate( $wgArticle->getTimestamp(), true );
870 $s = ' ' . wfMsg( 'lastmodified', $d );
877 function logoText( $align = '' )
879 if ( '' != $align ) { $a = ' align="'.$align.'"'; }
882 $mp = wfMsg( 'mainpage' );
883 $titleObj = Title
::newFromText( $mp );
884 if ( is_object( $titleObj ) ) {
885 $url = $titleObj->escapeLocalURL();
890 $s = '<a href="' . $url
891 . '"><img'.$a.' src="'
892 . $this->getLogo() . '" alt="' . "[{$mp}]\" /></a>";
898 global $wgOut, $wgTitle, $wgUser, $wgRequest, $wgLang;
899 global $wgDisableUploads, $wgRemoteUploads;
901 $fname = 'Skin::quickBar';
902 wfProfileIn( $fname );
904 $action = $wgRequest->getText( 'action' );
905 $wpPreview = $wgRequest->getBool( 'wpPreview' );
906 $tns=$wgTitle->getNamespace();
908 $s = "\n<div id='quickbar'>";
909 $s .= "\n" . $this->logoText() . "\n<hr class='sep' />";
912 $s .= $this->mainPageLink()
913 . $sep . $this->specialLink( 'recentchanges' )
914 . $sep . $this->specialLink( 'randompage' );
915 if ($wgUser->getID()) {
916 $s.= $sep . $this->specialLink( 'watchlist' ) ;
917 $s .= $sep .$this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
918 wfMsg( 'mycontris' ), 'target=' . wfUrlencode($wgUser->getName() ) );
921 // only show watchlist link if logged in
922 if ( wfMsg ( 'currentevents' ) != '-' ) $s .= $sep . $this->makeKnownLink( wfMsg( 'currentevents' ), '' ) ;
923 $s .= "\n<br /><hr class='sep' />";
924 $articleExists = $wgTitle->getArticleId();
925 if ( $wgOut->isArticle() ||
$action =='edit' ||
$action =='history' ||
$wpPreview) {
926 if($wgOut->isArticle()) {
927 $s .= '<strong>' . $this->editThisPage() . '</strong>';
928 } else { # backlink to the article in edit or history mode
929 if($articleExists){ # no backlink if no article
932 $text = wfMsg('articlepage');
935 $text = wfMsg('viewtalkpage');
938 $text = wfMsg('userpage');
941 $text = wfMsg('viewtalkpage');
944 $text = wfMsg('wikipediapage');
947 $text = wfMsg('viewtalkpage');
950 $text = wfMsg('imagepage');
953 $text = wfMsg('viewtalkpage');
956 $text= wfMsg('articlepage');
959 $link = $wgTitle->getText();
960 if ($nstext = $wgLang->getNsText($tns) ) { # add namespace if necessary
961 $link = $nstext . ':' . $link ;
964 $s .= $this->makeLink( $link, $text );
965 } elseif( $wgTitle->getNamespace() != Namespace::getSpecial() ) {
966 # we just throw in a "New page" text to tell the user that he's in edit mode,
967 # and to avoid messing with the separator that is prepended to the next item
968 $s .= '<strong>' . wfMsg('newpage') . '</strong>';
974 if( $tns%2
&& $action!='edit' && !$wpPreview) {
975 $s.= '<br />'.$this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg('postcomment'),'action=edit§ion=new');
979 watching could cause problems in edit mode:
980 if user edits article, then loads "watch this article" in background and then saves
981 article with "Watch this article" checkbox disabled, the article is transparently
982 unwatched. Therefore we do not show the "Watch this page" link in edit mode
984 if ( 0 != $wgUser->getID() && $articleExists) {
985 if($action!='edit' && $action != 'submit' )
987 $s .= $sep . $this->watchThisPage();
989 if ( $wgTitle->userCanEdit() )
990 $s .= $sep . $this->moveThisPage();
992 if ( $wgUser->isSysop() and $articleExists ) {
993 $s .= $sep . $this->deleteThisPage() .
994 $sep . $this->protectThisPage();
996 $s .= $sep . $this->talkLink();
997 if ($articleExists && $action !='history') {
998 $s .= $sep . $this->historyLink();
1000 $s.=$sep . $this->whatLinksHere();
1002 if($wgOut->isArticleRelated()) {
1003 $s .= $sep . $this->watchPageLinksLink();
1006 if ( Namespace::getUser() == $wgTitle->getNamespace()
1007 ||
$wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser())
1010 $id=User
::idFromName($wgTitle->getText());
1011 $ip=User
::isIP($wgTitle->getText());
1014 $s .= $sep . $this->userContribsLink();
1016 if ( 0 != $wgUser->getID() ) {
1017 if($id) { # can only email real users
1018 $s .= $sep . $this->emailUserLink();
1022 $s .= "\n<br /><hr class='sep' />";
1025 if ( 0 != $wgUser->getID() && ( !$wgDisableUploads ||
$wgRemoteUploads ) ) {
1026 $s .= $this->specialLink( 'upload' ) . $sep;
1028 $s .= $this->specialLink( 'specialpages' )
1029 . $sep . $this->bugReportsLink();
1031 global $wgSiteSupportPage;
1032 if( $wgSiteSupportPage ) {
1033 $s .= "\n<br /><a href=\"" . htmlspecialchars( $wgSiteSupportPage ) .
1034 '" class="internal">' . wfMsg( 'sitesupport' ) . '</a>';
1037 $s .= "\n<br /></div>\n";
1038 wfProfileOut( $fname );
1042 function specialPagesList()
1044 global $wgUser, $wgOut, $wgLang, $wgServer, $wgRedirectScript;
1045 require_once('SpecialPage.php');
1047 $pages = SpecialPage
::getPages();
1049 foreach ( $pages[''] as $name => $page ) {
1050 $a[$name] = $page->getDescription();
1052 if ( $wgUser->isSysop() )
1054 foreach ( $pages['sysop'] as $name => $page ) {
1055 $a[$name] = $page->getDescription();
1058 if ( $wgUser->isDeveloper() )
1060 foreach ( $pages['developer'] as $name => $page ) {
1061 $a[$name] = $page->getDescription() ;
1064 $go = wfMsg( 'go' );
1065 $sp = wfMsg( 'specialpages' );
1066 $spp = $wgLang->specialPage( 'Specialpages' );
1068 $s = '<form id="specialpages" method="get" class="inline" ' .
1069 'action="' . htmlspecialchars( "{$wgServer}{$wgRedirectScript}" ) . "\">\n";
1070 $s .= "<select name=\"wpDropdown\">\n";
1071 $s .= "<option value=\"{$spp}\">{$sp}</option>\n";
1073 foreach ( $a as $name => $desc ) {
1074 $p = $wgLang->specialPage( $name );
1075 $s .= "<option value=\"{$p}\">{$desc}</option>\n";
1077 $s .= "</select>\n";
1078 $s .= "<input type='submit' value=\"{$go}\" name='redirect' />\n";
1083 function mainPageLink()
1085 $mp = wfMsg( 'mainpage' );
1086 $s = $this->makeKnownLink( $mp, $mp );
1090 function copyrightLink()
1092 $s = $this->makeKnownLink( wfMsg( 'copyrightpage' ),
1093 wfMsg( 'copyrightpagename' ) );
1097 function aboutLink()
1099 $s = $this->makeKnownLink( wfMsg( 'aboutpage' ),
1100 wfMsg( 'aboutwikipedia' ) );
1105 function disclaimerLink()
1107 $s = $this->makeKnownLink( wfMsg( 'disclaimerpage' ),
1108 wfMsg( 'disclaimers' ) );
1112 function editThisPage()
1114 global $wgOut, $wgTitle, $wgRequest;
1116 $oldid = $wgRequest->getVal( 'oldid' );
1117 $diff = $wgRequest->getVal( 'diff' );
1118 $redirect = $wgRequest->getVal( 'redirect' );
1120 if ( ! $wgOut->isArticleRelated() ) {
1121 $s = wfMsg( 'protectedpage' );
1123 $n = $wgTitle->getPrefixedText();
1124 if ( $wgTitle->userCanEdit() ) {
1125 $t = wfMsg( 'editthispage' );
1127 #$t = wfMsg( "protectedpage" );
1128 $t = wfMsg( 'viewsource' );
1132 if ( !is_null( $redirect ) ) { $red = "&redirect={$redirect}"; }
1133 if ( $oldid && ! isset( $diff ) ) {
1134 $oid = "&oldid={$oldid}";
1136 $s = $this->makeKnownLink( $n, $t, "action=edit{$oid}{$red}" );
1141 function deleteThisPage()
1143 global $wgUser, $wgOut, $wgTitle, $wgRequest;
1145 $diff = $wgRequest->getVal( 'diff' );
1146 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
1147 $n = $wgTitle->getPrefixedText();
1148 $t = wfMsg( 'deletethispage' );
1150 $s = $this->makeKnownLink( $n, $t, 'action=delete' );
1157 function protectThisPage()
1159 global $wgUser, $wgOut, $wgTitle, $wgRequest;
1161 $diff = $wgRequest->getVal( 'diff' );
1162 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
1163 $n = $wgTitle->getPrefixedText();
1165 if ( $wgTitle->isProtected() ) {
1166 $t = wfMsg( 'unprotectthispage' );
1167 $q = 'action=unprotect';
1169 $t = wfMsg( 'protectthispage' );
1170 $q = 'action=protect';
1172 $s = $this->makeKnownLink( $n, $t, $q );
1179 function watchThisPage()
1181 global $wgUser, $wgOut, $wgTitle;
1183 if ( $wgOut->isArticleRelated() ) {
1184 $n = $wgTitle->getPrefixedText();
1186 if ( $wgTitle->userIsWatching() ) {
1187 $t = wfMsg( 'unwatchthispage' );
1188 $q = 'action=unwatch';
1190 $t = wfMsg( 'watchthispage' );
1191 $q = 'action=watch';
1193 $s = $this->makeKnownLink( $n, $t, $q );
1195 $s = wfMsg( 'notanarticle' );
1200 function moveThisPage()
1202 global $wgTitle, $wgLang;
1204 if ( $wgTitle->userCanEdit() ) {
1205 $s = $this->makeKnownLink( $wgLang->specialPage( 'Movepage' ),
1206 wfMsg( 'movethispage' ), 'target=' . $wgTitle->getPrefixedURL() );
1207 } // no message if page is protected - would be redundant
1211 function historyLink()
1215 $s = $this->makeKnownLink( $wgTitle->getPrefixedText(),
1216 wfMsg( 'history' ), 'action=history' );
1220 function whatLinksHere()
1222 global $wgTitle, $wgLang;
1224 $s = $this->makeKnownLink( $wgLang->specialPage( 'Whatlinkshere' ),
1225 wfMsg( 'whatlinkshere' ), 'target=' . $wgTitle->getPrefixedURL() );
1229 function userContribsLink()
1231 global $wgTitle, $wgLang;
1233 $s = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
1234 wfMsg( 'contributions' ), 'target=' . $wgTitle->getPartialURL() );
1238 function emailUserLink()
1240 global $wgTitle, $wgLang;
1242 $s = $this->makeKnownLink( $wgLang->specialPage( 'Emailuser' ),
1243 wfMsg( 'emailuser' ), 'target=' . $wgTitle->getPartialURL() );
1247 function watchPageLinksLink()
1249 global $wgOut, $wgTitle, $wgLang;
1251 if ( ! $wgOut->isArticleRelated() ) {
1252 $s = '(' . wfMsg( 'notanarticle' ) . ')';
1254 $s = $this->makeKnownLink( $wgLang->specialPage(
1255 'Recentchangeslinked' ), wfMsg( 'recentchangeslinked' ),
1256 'target=' . $wgTitle->getPrefixedURL() );
1261 function otherLanguages()
1263 global $wgOut, $wgLang, $wgTitle, $wgUseNewInterlanguage;
1265 $a = $wgOut->getLanguageLinks();
1266 if ( 0 == count( $a ) ) {
1267 if ( !$wgUseNewInterlanguage ) return '';
1268 $ns = $wgLang->getNsIndex ( $wgTitle->getNamespace () ) ;
1269 if ( $ns != 0 AND $ns != 1 ) return '' ;
1271 $x = 'mode=addlink&xt='.$wgTitle->getDBkey() ;
1272 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1273 wfMsg( 'intl' ) , $x );
1276 if ( !$wgUseNewInterlanguage ) {
1277 $s = wfMsg( 'otherlanguages' ) . ': ';
1279 global $wgLanguageCode ;
1280 $x = 'mode=zoom&xt='.$wgTitle->getDBkey() ;
1281 $x .= '&xl='.$wgLanguageCode ;
1282 $s = $this->makeKnownLink( $wgLang->specialPage( 'Intl' ),
1283 wfMsg( 'otherlanguages' ) , $x ) . ': ' ;
1286 $s = wfMsg( 'otherlanguages' ) . ': ';
1288 if($wgLang->isRTL()) $s .= '<span dir="LTR">';
1289 foreach( $a as $l ) {
1290 if ( ! $first ) { $s .= ' | '; }
1293 $nt = Title
::newFromText( $l );
1294 $url = $nt->getFullURL();
1295 $text = $wgLang->getLanguageName( $nt->getInterwiki() );
1297 if ( '' == $text ) { $text = $l; }
1298 $style = $this->getExternalLinkAttributes( $l, $text );
1299 $s .= "<a href=\"{$url}\"{$style}>{$text}</a>";
1301 if($wgLang->isRTL()) $s .= '</span>';
1305 function bugReportsLink()
1307 $s = $this->makeKnownLink( wfMsg( 'bugreportspage' ),
1308 wfMsg( 'bugreports' ) );
1314 global $wgLinkCache;
1315 $t1 = Title
::newFromText( gmdate( 'F j' ) );
1316 $t2 = Title
::newFromText( gmdate( 'Y' ) );
1318 $wgLinkCache->suspend();
1319 $id = $t1->getArticleID();
1320 $wgLinkCache->resume();
1323 $s = $this->makeBrokenLink( $t1->getText() );
1325 $s = $this->makeKnownLink( $t1->getText() );
1329 $wgLinkCache->suspend();
1330 $id = $t2->getArticleID();
1331 $wgLinkCache->resume();
1334 $s .= $this->makeBrokenLink( $t2->getText() );
1336 $s .= $this->makeKnownLink( $t2->getText() );
1343 global $wgLang, $wgTitle, $wgLinkCache;
1345 $tns = $wgTitle->getNamespace();
1346 if ( -1 == $tns ) { return ''; }
1348 $pn = $wgTitle->getText();
1349 $tp = wfMsg( 'talkpage' );
1350 if ( Namespace::isTalk( $tns ) ) {
1351 $lns = Namespace::getSubject( $tns );
1354 $text = wfMsg('articlepage');
1357 $text = wfMsg('userpage');
1360 $text = wfMsg('wikipediapage');
1363 $text = wfMsg('imagepage');
1366 $text= wfMsg('articlepage');
1370 $lns = Namespace::getTalk( $tns );
1373 $n = $wgLang->getNsText( $lns );
1374 if ( '' == $n ) { $link = $pn; }
1375 else { $link = $n.':'.$pn; }
1377 $wgLinkCache->suspend();
1378 $s = $this->makeLink( $link, $text );
1379 $wgLinkCache->resume();
1384 function commentLink()
1386 global $wgLang, $wgTitle, $wgLinkCache;
1388 $tns = $wgTitle->getNamespace();
1389 if ( -1 == $tns ) { return ''; }
1391 $lns = ( Namespace::isTalk( $tns ) ) ?
$tns : Namespace::getTalk( $tns );
1393 # assert Namespace::isTalk( $lns )
1395 $n = $wgLang->getNsText( $lns );
1396 $pn = $wgTitle->getText();
1400 $wgLinkCache->suspend();
1401 $s = $this->makeKnownLink($link, wfMsg('postcomment'), 'action=edit§ion=new');
1402 $wgLinkCache->resume();
1407 # After all the page content is transformed into HTML, it makes
1408 # a final pass through here for things like table backgrounds.
1410 function transformContent( $text )
1415 # Note: This function MUST call getArticleID() on the link,
1416 # otherwise the cache won't get updated properly. See LINKCACHE.DOC.
1418 function makeLink( $title, $text = '', $query = '', $trail = '' ) {
1419 wfProfileIn( 'Skin::makeLink' );
1420 $nt = Title
::newFromText( $title );
1422 $result = $this->makeLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1424 wfDebug( 'Invalid title passed to Skin::makeLink(): "'.$title."\"\n" );
1425 $result = $text == "" ?
$title : $text;
1428 wfProfileOut( 'Skin::makeLink' );
1432 function makeKnownLink( $title, $text = '', $query = '', $trail = '', $prefix = '',$aprops = '') {
1433 $nt = Title
::newFromText( $title );
1435 return $this->makeKnownLinkObj( Title
::newFromText( $title ), $text, $query, $trail, $prefix , $aprops );
1437 wfDebug( 'Invalid title passed to Skin::makeKnownLink(): "'.$title."\"\n" );
1438 return $text == '' ?
$title : $text;
1442 function makeBrokenLink( $title, $text = '', $query = '', $trail = '' ) {
1443 $nt = Title
::newFromText( $title );
1445 return $this->makeBrokenLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1447 wfDebug( 'Invalid title passed to Skin::makeBrokenLink(): "'.$title."\"\n" );
1448 return $text == '' ?
$title : $text;
1452 function makeStubLink( $title, $text = '', $query = '', $trail = '' ) {
1453 $nt = Title
::newFromText( $title );
1455 return $this->makeStubLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1457 wfDebug( 'Invalid title passed to Skin::makeStubLink(): "'.$title."\"\n" );
1458 return $text == '' ?
$title : $text;
1462 # Pass a title object, not a title string
1463 function makeLinkObj( &$nt, $text= '', $query = '', $trail = '', $prefix = '' )
1465 global $wgOut, $wgUser;
1466 $fname = 'Skin::makeLinkObj';
1470 return "<!-- ERROR -->{$prefix}{$text}{$trail}";
1472 if ( $nt->isExternal() ) {
1473 $u = $nt->getFullURL();
1474 $link = $nt->getPrefixedURL();
1475 if ( '' == $text ) { $text = $nt->getPrefixedText(); }
1476 $style = $this->getExternalLinkAttributes( $link, $text, 'extiw' );
1479 if ( '' != $trail ) {
1480 if ( preg_match( '/^([a-z]+)(.*)$$/sD', $trail, $m ) ) {
1485 $retVal = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1486 } elseif ( 0 == $nt->getNamespace() && "" == $nt->getText() ) {
1487 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1488 } elseif ( ( -1 == $nt->getNamespace() ) ||
1489 ( Namespace::getImage() == $nt->getNamespace() ) ) {
1490 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1492 if ( $this->postParseLinkColour() ) {
1494 if ( '' != $trail ) {
1495 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1501 # Allows wiki to bypass using linkcache, see OutputPage::parseLinkHolders()
1502 $retVal = '<!--LINK ' . implode( ' ', array( $nt->getNamespace(), $nt->getDBkey(),
1503 $query, $prefix . $text . $inside ) ) . "-->{$trail}";
1505 # Work out link colour immediately
1506 $aid = $nt->getArticleID() ;
1508 $retVal = $this->makeBrokenLinkObj( $nt, $text, $query, $trail, $prefix );
1510 $threshold = $wgUser->getOption('stubthreshold') ;
1511 if ( $threshold > 0 ) {
1512 $dbr =& wfGetDB( DB_SLAVE
);
1513 $s = $dbr->selectRow( 'cur', array( 'LENGTH(cur_text) AS x', 'cur_namespace',
1514 'cur_is_redirect' ), array( 'cur_id' => $aid ), $fname ) ;
1515 if ( $s !== false ) {
1517 if ( $s->cur_is_redirect
OR $s->cur_namespace
!= 0 ) {
1518 $size = $threshold*2 ; # Really big
1520 $dbr->freeResult( $res );
1522 $size = $threshold*2 ; # Really big
1527 if ( $size < $threshold ) {
1528 $retVal = $this->makeStubLinkObj( $nt, $text, $query, $trail, $prefix );
1530 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1538 # Pass a title object, not a title string
1539 function makeKnownLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' , $aprops = '')
1541 global $wgOut, $wgTitle, $wgInputEncoding;
1543 $fname = 'Skin::makeKnownLinkObj';
1544 wfProfileIn( $fname );
1546 if ( !is_object( $nt ) ) {
1549 $link = $nt->getPrefixedURL();
1551 if ( '' == $link ) {
1553 if ( '' == $text ) {
1554 $text = htmlspecialchars( $nt->getFragment() );
1557 $u = $nt->escapeLocalURL( $query );
1559 if ( '' != $nt->getFragment() ) {
1560 $anchor = urlencode( do_html_entity_decode( str_replace(' ', '_', $nt->getFragment()), ENT_COMPAT
, $wgInputEncoding ) );
1561 $replacearray = array(
1565 $u .= '#' . str_replace(array_keys($replacearray),array_values($replacearray),$anchor);
1567 if ( '' == $text ) {
1568 $text = htmlspecialchars( $nt->getPrefixedText() );
1570 $style = $this->getInternalLinkAttributesObj( $nt, $text );
1573 if ( '' != $trail ) {
1574 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1579 $r = "<a href=\"{$u}\"{$style}{$aprops}>{$prefix}{$text}{$inside}</a>{$trail}";
1580 wfProfileOut( $fname );
1584 # Pass a title object, not a title string
1585 function makeBrokenLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
1587 global $wgOut, $wgUser;
1591 return "<!-- ERROR -->{$prefix}{$text}{$trail}";
1593 $fname = 'Skin::makeBrokenLinkObj';
1594 wfProfileIn( $fname );
1596 if ( '' == $query ) {
1599 $q = 'action=edit&'.$query;
1601 $u = $nt->escapeLocalURL( $q );
1603 if ( '' == $text ) {
1604 $text = htmlspecialchars( $nt->getPrefixedText() );
1606 $style = $this->getInternalLinkAttributesObj( $nt, $text, "yes" );
1609 if ( '' != $trail ) {
1610 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1615 if ( $wgUser->getOption( 'highlightbroken' ) ) {
1616 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1618 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>?</a>{$trail}";
1621 wfProfileOut( $fname );
1625 # Pass a title object, not a title string
1626 function makeStubLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
1628 global $wgOut, $wgUser;
1630 $link = $nt->getPrefixedURL();
1632 $u = $nt->escapeLocalURL( $query );
1634 if ( '' == $text ) {
1635 $text = htmlspecialchars( $nt->getPrefixedText() );
1637 $style = $this->getInternalLinkAttributesObj( $nt, $text, 'stub' );
1640 if ( '' != $trail ) {
1641 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1646 if ( $wgUser->getOption( 'highlightbroken' ) ) {
1647 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1649 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>!</a>{$trail}";
1654 function makeSelfLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
1656 $u = $nt->escapeLocalURL( $query );
1657 if ( '' == $text ) {
1658 $text = htmlspecialchars( $nt->getPrefixedText() );
1661 if ( '' != $trail ) {
1662 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1667 return "<strong>{$prefix}{$text}{$inside}</strong>{$trail}";
1670 /* these are used extensively in SkinPHPTal, but also some other places */
1671 /*static*/ function makeSpecialUrl( $name, $urlaction='' ) {
1672 $title = Title
::makeTitle( NS_SPECIAL
, $name );
1673 $this->checkTitle($title, $name);
1674 return $title->getLocalURL( $urlaction );
1676 /*static*/ function makeTalkUrl ( $name, $urlaction='' ) {
1677 $title = Title
::newFromText( $name );
1678 $title = $title->getTalkPage();
1679 $this->checkTitle($title, $name);
1680 return $title->getLocalURL( $urlaction );
1682 /*static*/ function makeArticleUrl ( $name, $urlaction='' ) {
1683 $title = Title
::newFromText( $name );
1684 $title= $title->getSubjectPage();
1685 $this->checkTitle($title, $name);
1686 return $title->getLocalURL( $urlaction );
1688 /*static*/ function makeI18nUrl ( $name, $urlaction='' ) {
1689 $title = Title
::newFromText( wfMsg($name) );
1690 $this->checkTitle($title, $name);
1691 return $title->getLocalURL( $urlaction );
1693 /*static*/ function makeUrl ( $name, $urlaction='' ) {
1694 $title = Title
::newFromText( $name );
1695 $this->checkTitle($title, $name);
1696 return $title->getLocalURL( $urlaction );
1698 # this can be passed the NS number as defined in Language.php
1699 /*static*/ function makeNSUrl( $name, $urlaction='', $namespace=0 ) {
1700 $title = Title
::makeTitle( $namespace, $name );
1701 $this->checkTitle($title, $name);
1702 return $title->getLocalURL( $urlaction );
1705 /* these return an array with the 'href' and boolean 'exists' */
1706 /*static*/ function makeUrlDetails ( $name, $urlaction='' ) {
1707 $title = Title
::newFromText( $name );
1708 $this->checkTitle($title, $name);
1710 'href' => $title->getLocalURL( $urlaction ),
1711 'exists' => $title->getArticleID() != 0?
true:false
1714 /*static*/ function makeTalkUrlDetails ( $name, $urlaction='' ) {
1715 $title = Title
::newFromText( $name );
1716 $title = $title->getTalkPage();
1717 $this->checkTitle($title, $name);
1719 'href' => $title->getLocalURL( $urlaction ),
1720 'exists' => $title->getArticleID() != 0?
true:false
1723 /*static*/ function makeArticleUrlDetails ( $name, $urlaction='' ) {
1724 $title = Title
::newFromText( $name );
1725 $title= $title->getSubjectPage();
1726 $this->checkTitle($title, $name);
1728 'href' => $title->getLocalURL( $urlaction ),
1729 'exists' => $title->getArticleID() != 0?
true:false
1732 /*static*/ function makeI18nUrlDetails ( $name, $urlaction='' ) {
1733 $title = Title
::newFromText( wfMsg($name) );
1734 $this->checkTitle($title, $name);
1736 'href' => $title->getLocalURL( $urlaction ),
1737 'exists' => $title->getArticleID() != 0?
true:false
1741 # make sure we have some title to operate on
1742 /*static*/ function checkTitle ( &$title, &$name ) {
1743 if(!is_object($title)) {
1744 $title = Title
::newFromText( $name );
1745 if(!is_object($title)) {
1746 $title = Title
::newFromText( '--error: link target missing--' );
1751 function fnamePart( $url )
1753 $basename = strrchr( $url, '/' );
1754 if ( false === $basename ) {
1757 $basename = substr( $basename, 1 );
1759 return htmlspecialchars( $basename );
1762 function makeImage( $url, $alt = '' )
1767 $alt = $this->fnamePart( $url );
1769 $s = '<img src="'.$url.'" alt="'.$alt.'" />';
1773 function makeImageLink( $name, $url, $alt = '' ) {
1774 $nt = Title
::makeTitle( Namespace::getImage(), $name );
1775 return $this->makeImageLinkObj( $nt, $alt );
1778 function makeImageLinkObj( $nt, $alt = '' ) {
1779 global $wgLang, $wgUseImageResize;
1780 $img = Image
::newFromTitle( $nt );
1781 $url = $img->getURL();
1784 $prefix = $postfix = '';
1786 if ( $wgUseImageResize ) {
1787 # Check if the alt text is of the form "options|alt text"
1789 # * thumbnail make a thumbnail with enlarge-icon and caption, alignment depends on lang
1790 # * left no resizing, just left align. label is used for alt= only
1791 # * right same, but right aligned
1792 # * none same, but not aligned
1793 # * ___px scale to ___ pixels width, no aligning. e.g. use in taxobox
1794 # * center center the image
1795 # * framed Keep original image size, no magnify-button.
1797 $part = explode( '|', $alt);
1799 $mwThumb =& MagicWord
::get( MAG_IMG_THUMBNAIL
);
1800 $mwLeft =& MagicWord
::get( MAG_IMG_LEFT
);
1801 $mwRight =& MagicWord
::get( MAG_IMG_RIGHT
);
1802 $mwNone =& MagicWord
::get( MAG_IMG_NONE
);
1803 $mwWidth =& MagicWord
::get( MAG_IMG_WIDTH
);
1804 $mwCenter =& MagicWord
::get( MAG_IMG_CENTER
);
1805 $mwFramed =& MagicWord
::get( MAG_IMG_FRAMED
);
1806 $alt = $part[count($part)-1];
1808 $height = $framed = $thumb = false;
1809 $manual_thumb = "" ;
1811 foreach( $part as $key => $val ) {
1812 $val_parts = explode ( "=" , $val , 2 ) ;
1813 $left_part = array_shift ( $val_parts ) ;
1814 if ( ! is_null( $mwThumb->matchVariableStartToEnd($val) ) ) {
1816 } elseif ( count ( $val_parts ) == 1 && ! is_null( $mwThumb->matchVariableStartToEnd($left_part) ) ) {
1817 # use manually specified thumbnail
1819 $manual_thumb = array_shift ( $val_parts ) ;
1820 } elseif ( ! is_null( $mwRight->matchVariableStartToEnd($val) ) ) {
1821 # remember to set an alignment, don't render immediately
1823 } elseif ( ! is_null( $mwLeft->matchVariableStartToEnd($val) ) ) {
1824 # remember to set an alignment, don't render immediately
1826 } elseif ( ! is_null( $mwCenter->matchVariableStartToEnd($val) ) ) {
1827 # remember to set an alignment, don't render immediately
1829 } elseif ( ! is_null( $mwNone->matchVariableStartToEnd($val) ) ) {
1830 # remember to set an alignment, don't render immediately
1832 } elseif ( ! is_null( $match = $mwWidth->matchVariableStartToEnd($val) ) ) {
1833 # $match is the image width in pixels
1834 if ( preg_match( '/^([0-9]*)x([0-9]*)$/', $match, $m ) ) {
1835 $width = intval( $m[1] );
1836 $height = intval( $m[2] );
1838 $width = intval($match);
1840 } elseif ( ! is_null( $mwFramed->matchVariableStartToEnd($val) ) ) {
1844 if ( 'center' == $align )
1846 $prefix = '<span style="text-align: center">';
1847 $postfix = '</span>';
1851 if ( $thumb ||
$framed ) {
1853 # Create a thumbnail. Alignment depends on language
1854 # writing direction, # right aligned for left-to-right-
1855 # languages ("Western languages"), left-aligned
1856 # for right-to-left-languages ("Semitic languages")
1858 # If thumbnail width has not been provided, it is set
1859 # here to 180 pixels
1860 if ( $align == '' ) {
1861 $align = $wgLang->isRTL() ?
'left' : 'right';
1863 if ( ! isset($width) ) {
1866 return $prefix.$this->makeThumbLinkObj( $img, $alt, $align, $width, $height, $framed, $manual_thumb ).$postfix;
1868 } elseif ( isset($width) ) {
1870 # Create a resized image, without the additional thumbnail
1873 if ( ( ! $height === false )
1874 && ( $img->getHeight() * $width / $img->getWidth() > $height ) ) {
1875 print "height=$height<br>\nimg->getHeight() = ".$img->getHeight()."<br>\n";
1876 print 'rescaling by factor '. $height / $img->getHeight() . "<br>\n";
1877 $width = $img->getWidth() * $height / $img->getHeight();
1879 if ( '' == $manual_thumb ) $url = $img->createThumb( $width );
1881 } # endif $wgUseImageResize
1883 if ( empty( $alt ) ) {
1884 $alt = preg_replace( '/\.(.+?)^/', '', $img->getName() );
1886 $alt = htmlspecialchars( $alt );
1888 $u = $nt->escapeLocalURL();
1891 $s = wfMsg( 'missingimage', $img->getName() );
1892 $s .= "<br>{$alt}<br>{$url}<br>\n";
1894 $s = '<a href="'.$u.'" class="image" title="'.$alt.'">' .
1895 '<img src="'.$url.'" alt="'.$alt.'" /></a>';
1897 if ( '' != $align ) {
1898 $s = "<div class=\"float{$align}\"><span>{$s}</span></div>";
1900 return str_replace("\n", ' ',$prefix.$s.$postfix);
1903 # Make HTML for a thumbnail including image, border and caption
1904 # $img is an Image object
1905 function makeThumbLinkObj( $img, $label = '', $align = 'right', $boxwidth = 180, $boxheight=false, $framed=false , $manual_thumb = "" ) {
1906 global $wgStylePath, $wgLang;
1907 # $image = Title::makeTitle( Namespace::getImage(), $name );
1908 $url = $img->getURL();
1910 #$label = htmlspecialchars( $label );
1911 $alt = preg_replace( '/<[^>]*>/', '', $label);
1912 $alt = htmlspecialchars( $alt );
1914 $width = $height = 0;
1915 if ( $img->exists() )
1917 $width = $img->getWidth();
1918 $height = $img->getHeight();
1920 if ( 0 == $width ||
0 == $height )
1922 $width = $height = 200;
1924 if ( $boxwidth == 0 )
1930 // Use image dimensions, don't scale
1932 $oboxwidth = $boxwidth +
2;
1933 $boxheight = $height;
1936 $h = intval( $height/($width/$boxwidth) );
1937 $oboxwidth = $boxwidth +
2;
1938 if ( ( ! $boxheight === false ) && ( $h > $boxheight ) )
1940 $boxwidth *= $boxheight/$h;
1944 if ( '' == $manual_thumb ) $thumbUrl = $img->createThumb( $boxwidth );
1947 if ( $manual_thumb != '' ) # Use manually specified thumbnail
1949 $manual_title = Title
::makeTitle( Namespace::getImage(), $manual_thumb ); #new Title ( $manual_thumb ) ;
1950 $manual_img = Image
::newFromTitle( $manual_title );
1951 $thumbUrl = $manual_img->getURL();
1952 if ( $manual_img->exists() )
1954 $width = $manual_img->getWidth();
1955 $height = $manual_img->getHeight();
1956 $boxwidth = $width ;
1957 $boxheight = $height ;
1958 $oboxwidth = $boxwidth +
2 ;
1962 $u = $img->getEscapeLocalURL();
1964 $more = htmlspecialchars( wfMsg( 'thumbnail-more' ) );
1965 $magnifyalign = $wgLang->isRTL() ?
'left' : 'right';
1966 $textalign = $wgLang->isRTL() ?
' style="text-align:right"' : '';
1968 $s = "<div class=\"thumb t{$align}\"><div style=\"width:{$oboxwidth}px;\">";
1969 if ( $thumbUrl == '' ) {
1970 $s .= wfMsg( 'missingimage', $img->getName() );
1973 $s .= '<a href="'.$u.'" class="internal" title="'.$alt.'">'.
1974 '<img src="'.$thumbUrl.'" alt="'.$alt.'" ' .
1975 'width="'.$boxwidth.'" height="'.$boxheight.'" /></a>';
1979 $zoomicon = '<div class="magnify" style="float:'.$magnifyalign.'">'.
1980 '<a href="'.$u.'" class="internal" title="'.$more.'">'.
1981 '<img src="'.$wgStylePath.'/images/magnify-clip.png" ' .
1982 'width="15" height="11" alt="'.$more.'" /></a></div>';
1985 $s .= ' <div class="thumbcaption" '.$textalign.'>'.$zoomicon.$label."</div></div></div>";
1986 return str_replace("\n", ' ', $s);
1989 function makeMediaLink( $name, $url, $alt = "" ) {
1990 $nt = Title
::makeTitle( Namespace::getMedia(), $name );
1991 return $this->makeMediaLinkObj( $nt, $alt );
1994 function makeMediaLinkObj( $nt, $alt = "" )
1996 if ( ! isset( $nt ) )
1998 ### HOTFIX. Instead of breaking, return empty string.
2001 $name = $nt->getDBKey();
2002 $url = Image
::wfImageUrl( $name );
2003 if ( empty( $alt ) ) {
2004 $alt = preg_replace( '/\.(.+?)^/', '', $name );
2007 $u = htmlspecialchars( $url );
2008 $s = "<a href=\"{$u}\" class='internal' title=\"{$alt}\">{$alt}</a>";
2013 function specialLink( $name, $key = "" )
2017 if ( '' == $key ) { $key = strtolower( $name ); }
2018 $pn = $wgLang->ucfirst( $name );
2019 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
2023 function makeExternalLink( $url, $text, $escape = true ) {
2024 $style = $this->getExternalLinkAttributes( $url, $text );
2025 $url = htmlspecialchars( $url );
2027 $text = htmlspecialchars( $text );
2029 return '<a href="'.$url.'"'.$style.'>'.$text.'</a>';
2032 # Called by history lists and recent changes
2035 # Returns text for the start of the tabular part of RC
2036 function beginRecentChangesList()
2038 $this->rc_cache
= array() ;
2039 $this->rcMoveIndex
= 0;
2040 $this->rcCacheIndex
= 0 ;
2041 $this->lastdate
= '';
2042 $this->rclistOpen
= false;
2046 function beginImageHistoryList()
2048 $s = "\n<h2>" . wfMsg( 'imghistory' ) . "</h2>\n" .
2049 "<p>" . wfMsg( 'imghistlegend' ) . "</p>\n".'<ul class="special">';
2053 # Returns text for the end of RC
2054 # If enhanced RC is in use, returns pretty much all the text
2055 function endRecentChangesList()
2057 $s = $this->recentChangesBlock() ;
2058 if( $this->rclistOpen
) {
2064 # Enhanced RC ungrouped line
2065 function recentChangesBlockLine ( $rcObj )
2067 global $wgStylePath, $wgLang ;
2069 # Get rc_xxxx variables
2070 extract( $rcObj->mAttribs
) ;
2071 $curIdEq = 'curid='.$rc_cur_id;
2076 $r .= '<img src="'.$wgStylePath.'/images/Arr_.png" width="12" height="12" border="0" />' ;
2079 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2080 $r .= ' ';
2082 # M & N (minor & new)
2083 $M = wfMsg( 'minoreditletter' );
2084 $N = wfMsg( 'newpageletter' );
2086 if ( $rc_type == RC_NEW
) {
2099 $r .= ' '.$rcObj->timestamp
.' ' ;
2103 $link = $rcObj->link
;
2104 if ( $rcObj->watched
) $link = '<strong>'.$link.'</strong>' ;
2109 $r .= $rcObj->difflink
;
2113 $r .= $this->makeKnownLinkObj( $rcObj->getTitle(), wfMsg( 'hist' ), $curIdEq.'&action=history' );
2116 $r .= ') . . '.$rcObj->userlink
;
2117 $r .= $rcObj->usertalklink
;
2120 if ( $rc_comment != '' && $rc_type != RC_MOVE
&& $rc_type != RC_MOVE_OVER_REDIRECT
) {
2121 $rc_comment=$this->formatComment($rc_comment);
2122 $r .= $wgLang->emphasize( ' ('.$rc_comment.')' );
2130 function recentChangesBlockGroup ( $block )
2132 global $wgStylePath, $wgLang ;
2135 $M = wfMsg( 'minoreditletter' );
2136 $N = wfMsg( 'newpageletter' );
2138 # Collate list of users
2140 $userlinks = array () ;
2141 foreach ( $block AS $rcObj ) {
2142 $oldid = $rcObj->mAttribs
['rc_last_oldid'];
2143 if ( $rcObj->mAttribs
['rc_new'] ) $isnew = true ;
2144 $u = $rcObj->userlink
;
2145 if ( !isset ( $userlinks[$u] ) ) $userlinks[$u] = 0 ;
2149 # Sort the list and convert to text
2150 krsort ( $userlinks ) ;
2151 asort ( $userlinks ) ;
2153 foreach ( $userlinks as $userlink => $count) {
2155 if ( $count > 1 ) $text .= " ({$count}×)" ;
2156 array_push ( $users , $text ) ;
2158 $users = ' <font size="-1">['.implode('; ',$users).']</font>' ;
2161 $rci = 'RCI'.$this->rcCacheIndex
;
2162 $rcl = 'RCL'.$this->rcCacheIndex
;
2163 $rcm = 'RCM'.$this->rcCacheIndex
;
2164 $toggleLink = "javascript:toggleVisibility('$rci','$rcm','$rcl')" ;
2165 $arrowdir = $wgLang->isRTL() ?
'l' : 'r';
2166 $tl = '<span id="'.$rcm.'"><a href="'.$toggleLink.'"><img src="'.$wgStylePath.'/images/Arr_'.$arrowdir.'.png" width="12" height="12" /></a></span>' ;
2167 $tl .= '<span id="'.$rcl.'" style="display:none"><a href="'.$toggleLink.'"><img src="'.$wgStylePath.'/images/Arr_d.png" width="12" height="12" /></a></span>' ;
2173 if ( $isnew ) $r .= $N ;
2174 else $r .= ' ' ;
2175 $r .= ' ' ; # Minor
2178 $r .= ' '.$block[0]->timestamp
.' ' ;
2182 $link = $block[0]->link
;
2183 if ( $block[0]->watched
) $link = '<strong>'.$link.'</strong>' ;
2186 $curIdEq = 'curid=' . $block[0]->mAttribs
['rc_cur_id'];
2187 if ( $block[0]->mAttribs
['rc_type'] != RC_LOG
) {
2189 $r .= ' ('.count($block).' ' ;
2190 if ( $isnew ) $r .= wfMsg('changes');
2191 else $r .= $this->makeKnownLinkObj( $block[0]->getTitle() , wfMsg('changes') ,
2192 $curIdEq.'&diff=0&oldid='.$oldid ) ;
2196 $r .= $this->makeKnownLinkObj( $block[0]->getTitle(), wfMsg( 'history' ), $curIdEq.'&action=history' );
2204 $r .= '<div id="'.$rci.'" style="display:none">' ;
2205 foreach ( $block AS $rcObj ) {
2206 # Get rc_xxxx variables
2207 extract( $rcObj->mAttribs
);
2209 $r .= '<img src="'.$wgStylePath.'/images/Arr_.png" width="12" height="12" />';
2210 $r .= '<tt> ' ;
2211 if ( $rc_new ) $r .= $N ;
2212 else $r .= ' ' ;
2213 if ( $rc_minor ) $r .= $M ;
2214 else $r .= ' ' ;
2218 if ( $rc_last_oldid != 0 ) {
2219 $o = 'oldid='.$rc_last_oldid ;
2221 if ( $rc_type == RC_LOG
) {
2222 $link = $rcObj->timestamp
;
2224 $link = $this->makeKnownLinkObj( $rcObj->getTitle(), $rcObj->timestamp
, "{$curIdEq}&$o" ) ;
2226 $link = '<tt>'.$link.'</tt>' ;
2230 $r .= $rcObj->curlink
;
2232 $r .= $rcObj->lastlink
;
2233 $r .= ') . . '.$rcObj->userlink
;
2234 $r .= $rcObj->usertalklink
;
2235 if ( $rc_comment != '' ) {
2236 $rc_comment=$this->formatComment($rc_comment);
2237 $r .= $wgLang->emphasize( ' ('.$rc_comment.')' ) ;
2243 $this->rcCacheIndex++
;
2247 # If enhanced RC is in use, this function takes the previously cached
2248 # RC lines, arranges them, and outputs the HTML
2249 function recentChangesBlock ()
2251 global $wgStylePath ;
2252 if ( count ( $this->rc_cache
) == 0 ) return '' ;
2254 foreach ( $this->rc_cache
AS $secureName => $block ) {
2255 if ( count ( $block ) < 2 ) {
2256 $blockOut .= $this->recentChangesBlockLine ( array_shift ( $block ) ) ;
2258 $blockOut .= $this->recentChangesBlockGroup ( $block ) ;
2262 return '<div>'.$blockOut.'</div>' ;
2265 # Called in a loop over all displayed RC entries
2266 # Either returns the line, or caches it for later use
2267 function recentChangesLine( &$rc, $watched = false )
2270 $usenew = $wgUser->getOption( 'usenewrc' );
2272 $line = $this->recentChangesLineNew ( $rc, $watched ) ;
2274 $line = $this->recentChangesLineOld ( $rc, $watched ) ;
2278 function recentChangesLineOld( &$rc, $watched = false )
2280 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds, $wgUseRCPatrol, $wgOnlySysopsCanPatrol;
2282 # Extract DB fields into local scope
2283 extract( $rc->mAttribs
);
2284 $curIdEq = 'curid=' . $rc_cur_id;
2286 # Make date header if necessary
2287 $date = $wgLang->date( $rc_timestamp, true);
2289 if ( $date != $this->lastdate
) {
2290 if ( '' != $this->lastdate
) { $s .= "</ul>\n"; }
2291 $s .= "<h4>{$date}</h4>\n<ul class='special'>";
2292 $this->lastdate
= $date;
2293 $this->rclistOpen
= true;
2296 # If this edit has not yet been patrolled, make it stick out
2297 $s .= ( ! $wgUseRCPatrol ||
$rc_patrolled ) ?
'<li> ' : '<li class="not_patrolled"> ';
2299 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2301 $s .= '(' . wfMsg( 'diff' ) . ') (';
2303 $s .= $this->makeKnownLinkObj( $rc->getMovedToTitle(), wfMsg( 'hist' ), 'action=history' ) .
2306 # "[[x]] moved to [[y]]"
2307 $msg = ( $rc_type == RC_MOVE
) ?
'1movedto2' : '1movedto2_redir';
2308 $s .= wfMsg( $msg, $this->makeKnownLinkObj( $rc->getTitle(), '', 'redirect=no' ),
2309 $this->makeKnownLinkObj( $rc->getMovedToTitle(), '' ) );
2312 if ( $rc_type == RC_NEW ||
$rc_type == RC_LOG
) {
2313 $diffLink = wfMsg( 'diff' );
2315 if ( $wgUseRCPatrol && $rc_patrolled == 0 && $wgUser->getID() != 0 &&
2316 ( $wgUser->isSysop() ||
!$wgOnlySysopsCanPatrol ) )
2317 $rcidparam = "&rcid={$rc_id}";
2320 $diffLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'diff' ),
2321 "{$curIdEq}&diff={$rc_this_oldid}&oldid={$rc_last_oldid}{$rcidparam}",
2322 '', '', ' tabindex="'.$rc->counter
.'"');
2324 $s .= '('.$diffLink.') (';
2327 $s .= $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'hist' ), $curIdEq.'&action=history' );
2330 # M and N (minor and new)
2331 if ( $rc_minor ) { $s .= ' <span class="minor">'.wfMsg( "minoreditletter" ).'</span>'; }
2332 if ( $rc_type == RC_NEW
) { $s .= '<span class="newpage">'.wfMsg( "newpageletter" ).'</span>'; }
2335 # If it's a new article, there is no diff link, but if it hasn't been
2336 # patrolled yet, we need to give users a way to do so
2337 if ( $wgUseRCPatrol && $rc_type == RC_NEW
&& $rc_patrolled == 0 &&
2338 $wgUser->getID() != 0 && ( $wgUser->isSysop() ||
!$wgOnlySysopsCanPatrol ) )
2339 $articleLink = $this->makeKnownLinkObj( $rc->getTitle(), '', "rcid={$rc_id}" );
2341 $articleLink = $this->makeKnownLinkObj( $rc->getTitle(), '' );
2344 $articleLink = '<strong>'.$articleLink.'</strong>';
2346 $s .= ' '.$articleLink;
2351 $s .= '; ' . $wgLang->time( $rc_timestamp, true, $wgRCSeconds ) . ' . . ';
2353 # User link (or contributions for unregistered users)
2354 if ( 0 == $rc_user ) {
2355 $userLink = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
2356 $rc_user_text, 'target=' . $rc_user_text );
2358 $userLink = $this->makeLink( $wgLang->getNsText( NS_USER
) . ':'.$rc_user_text, $rc_user_text );
2363 $talkname=$wgLang->getNsText(NS_TALK
); # use the shorter name
2364 global $wgDisableAnonTalk;
2365 if( 0 == $rc_user && $wgDisableAnonTalk ) {
2368 $utns=$wgLang->getNsText(NS_USER_TALK
);
2369 $userTalkLink= $this->makeLink($utns . ':'.$rc_user_text, $talkname );
2373 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2374 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2375 'Blockip' ), wfMsg( 'blocklink' ), 'ip='.$rc_user_text );
2379 if($userTalkLink) $userTalkLink .= ' | ';
2380 $userTalkLink .= $blockLink;
2382 if($userTalkLink) $s.=' ('.$userTalkLink.')';
2385 if ( '' != $rc_comment && '*' != $rc_comment && $rc_type != RC_MOVE
&& $rc_type != RC_MOVE_OVER_REDIRECT
) {
2386 $rc_comment=$this->formatComment($rc_comment);
2387 $s .= $wgLang->emphasize(' (' . $rc_comment . ')');
2394 function recentChangesLineNew( &$baseRC, $watched = false )
2396 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds;
2398 # Create a specialised object
2399 $rc = RCCacheEntry
::newFromParent( $baseRC ) ;
2401 # Extract fields from DB into the function scope (rc_xxxx variables)
2402 extract( $rc->mAttribs
);
2403 $curIdEq = 'curid=' . $rc_cur_id;
2405 # If it's a new day, add the headline and flush the cache
2406 $date = $wgLang->date( $rc_timestamp, true);
2408 if ( $date != $this->lastdate
) {
2409 # Process current cache
2410 $ret = $this->recentChangesBlock () ;
2411 $this->rc_cache
= array() ;
2412 $ret .= "<h4>{$date}</h4>\n";
2413 $this->lastdate
= $date;
2417 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2418 $msg = ( $rc_type == RC_MOVE
) ?
"1movedto2" : "1movedto2_redir";
2419 $clink = wfMsg( $msg, $this->makeKnownLinkObj( $rc->getTitle(), '', 'redirect=no' ),
2420 $this->makeKnownLinkObj( $rc->getMovedToTitle(), '' ) );
2422 $clink = $this->makeKnownLinkObj( $rc->getTitle(), '' ) ;
2425 $time = $wgLang->time( $rc_timestamp, true, $wgRCSeconds );
2426 $rc->watched
= $watched ;
2427 $rc->link
= $clink ;
2428 $rc->timestamp
= $time;
2430 # Make "cur" and "diff" links
2431 if ( ( $rc_type == RC_NEW
&& $rc_this_oldid == 0 ) ||
$rc_type == RC_LOG ||
$rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2432 $curLink = wfMsg( 'cur' );
2433 $diffLink = wfMsg( 'diff' );
2435 $query = $curIdEq.'&diff=0&oldid='.$rc_this_oldid;
2436 $aprops = ' tabindex="'.$baseRC->counter
.'"';
2437 $curLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'cur' ), $query, '' ,'' , $aprops );
2438 $diffLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'diff'), $query, '' ,'' , $aprops );
2442 $titleObj = $rc->getTitle();
2443 if ( $rc_last_oldid == 0 ||
$rc_type == RC_LOG ||
$rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2444 $lastLink = wfMsg( 'last' );
2446 $lastLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'last' ),
2447 $curIdEq.'&diff='.$rc_this_oldid.'&oldid='.$rc_last_oldid );
2450 # Make user link (or user contributions for unregistered users)
2451 if ( $rc_user == 0 ) {
2452 $userLink = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
2453 $rc_user_text, 'target=' . $rc_user_text );
2455 $userLink = $this->makeLink( $wgLang->getNsText(
2456 Namespace::getUser() ) . ':'.$rc_user_text, $rc_user_text );
2459 $rc->userlink
= $userLink;
2460 $rc->lastlink
= $lastLink;
2461 $rc->curlink
= $curLink;
2462 $rc->difflink
= $diffLink;
2464 # Make user talk link
2465 $utns=$wgLang->getNsText(NS_USER_TALK
);
2466 $talkname=$wgLang->getNsText(NS_TALK
); # use the shorter name
2467 $userTalkLink= $this->makeLink($utns . ':'.$rc_user_text, $talkname );
2469 global $wgDisableAnonTalk;
2470 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2471 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2472 'Blockip' ), wfMsg( 'blocklink' ), 'ip='.$rc_user_text );
2473 if( $wgDisableAnonTalk )
2474 $rc->usertalklink
= ' ('.$blockLink.')';
2476 $rc->usertalklink
= ' ('.$userTalkLink.' | '.$blockLink.')';
2478 if( $wgDisableAnonTalk && ($rc_user == 0) )
2479 $rc->usertalklink
= '';
2481 $rc->usertalklink
= ' ('.$userTalkLink.')';
2484 # Put accumulated information into the cache, for later display
2485 # Page moves go on their own line
2486 $title = $rc->getTitle();
2487 $secureName = $title->getPrefixedDBkey();
2488 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2489 # Use an @ character to prevent collision with page names
2490 $this->rc_cache
['@@' . ($this->rcMoveIndex++
)] = array($rc);
2492 if ( !isset ( $this->rc_cache
[$secureName] ) ) $this->rc_cache
[$secureName] = array() ;
2493 array_push ( $this->rc_cache
[$secureName] , $rc ) ;
2498 function endImageHistoryList()
2504 /* This function is called by all recent changes variants, by the page history,
2505 and by the user contributions list. It is responsible for formatting edit
2506 comments. It escapes any HTML in the comment, but adds some CSS to format
2507 auto-generated comments (from section editing) and formats [[wikilinks]].
2508 Main author: Erik Möller (moeller@scireview.de)
2510 function formatComment($comment)
2513 $comment = htmlspecialchars( $comment );
2515 # The pattern for autogen comments is / * foo * /, which makes for
2517 # We look for all comments, match any text before and after the comment,
2518 # add a separator where needed and format the comment itself with CSS
2519 while (preg_match('/(.*)\/\*\s*(.*?)\s*\*\/(.*)/', $comment,$match)) {
2524 if($pre) { $auto = $sep.' '.$auto; }
2525 if($post) { $auto .= ' '.$sep; }
2526 $auto='<span class="autocomment">'.$auto.'</span>';
2527 $comment=$pre.$auto.$post;
2530 # format regular and media links - all other wiki formatting
2532 $medians = $wgLang->getNsText(Namespace::getMedia()).':';
2533 while(preg_match('/\[\[(.*?)(\|(.*?))*\]\](.*)$/',$comment,$match)) {
2534 # Handle link renaming [[foo|text]] will show link as "text"
2535 if( "" != $match[3] ) {
2540 if( preg_match( '/^' . $medians . '(.*)$/i', $match[1], $submatch ) ) {
2541 # Media link; trail not supported.
2542 $linkRegexp = '/\[\[(.*?)\]\]/';
2543 $thelink = $this->makeMediaLink( $submatch[1], "", $text );
2545 # Other kind of link
2546 if( preg_match( wfMsg( "linktrail" ), $match[4], $submatch ) ) {
2547 $trail = $submatch[1];
2551 $linkRegexp = '/\[\[(.*?)\]\]' . preg_quote( $trail, '/' ) . '/';
2552 if ($match[1][0] == ':')
2553 $match[1] = substr($match[1], 1);
2554 $thelink = $this->makeLink( $match[1], $text, "", $trail );
2556 $comment = preg_replace( $linkRegexp, $thelink, $comment, 1 );
2561 function imageHistoryLine( $iscur, $timestamp, $img, $user, $usertext, $size, $description )
2563 global $wgUser, $wgLang, $wgTitle;
2565 $datetime = $wgLang->timeanddate( $timestamp, true );
2566 $del = wfMsg( 'deleteimg' );
2567 $delall = wfMsg( 'deleteimgcompletely' );
2568 $cur = wfMsg( 'cur' );
2571 $url = Image
::wfImageUrl( $img );
2573 if ( $wgUser->isSysop() ) {
2574 $link = $wgTitle->escapeLocalURL( 'image=' . $wgTitle->getPartialURL() .
2576 $style = $this->getInternalLinkAttributes( $link, $delall );
2578 $dlink = '<a href="'.$link.'"'.$style.'>'.$delall.'</a>';
2583 $url = htmlspecialchars( wfImageArchiveUrl( $img ) );
2584 if( $wgUser->getID() != 0 && $wgTitle->userCanEdit() ) {
2585 $rlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2586 wfMsg( 'revertimg' ), 'action=revert&oldimage=' .
2587 urlencode( $img ) );
2588 $dlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2589 $del, 'action=delete&oldimage=' . urlencode( $img ) );
2591 # Having live active links for non-logged in users
2592 # means that bots and spiders crawling our site can
2593 # inadvertently change content. Baaaad idea.
2594 $rlink = wfMsg( 'revertimg' );
2599 $userlink = $usertext;
2601 $userlink = $this->makeLink( $wgLang->getNsText( Namespace::getUser() ) .
2602 ':'.$usertext, $usertext );
2604 $nbytes = wfMsg( 'nbytes', $size );
2605 $style = $this->getInternalLinkAttributes( $url, $datetime );
2607 $s = "<li> ({$dlink}) ({$rlink}) <a href=\"{$url}\"{$style}>{$datetime}</a>"
2608 . " . . {$userlink} ({$nbytes})";
2610 if ( '' != $description && '*' != $description ) {
2611 $sk=$wgUser->getSkin();
2612 $s .= $wgLang->emphasize(' (' . $sk->formatComment($description) . ')');
2618 function tocIndent($level) {
2619 return str_repeat( '<div class="tocindent">'."\n", $level>0 ?
$level : 0 );
2622 function tocUnindent($level) {
2623 return str_repeat( "</div>\n", $level>0 ?
$level : 0 );
2626 # parameter level defines if we are on an indentation level
2627 function tocLine( $anchor, $tocline, $level ) {
2628 $link = '<a href="#'.$anchor.'">'.$tocline.'</a><br />';
2632 return '<div class="tocline">'.$link."</div>\n";
2637 function tocTable($toc) {
2638 # note to CSS fanatics: putting this in a div does not work -- div won't auto-expand
2639 # try min-width & co when somebody gets a chance
2640 $hideline = ' <script type="text/javascript">showTocToggle("' . addslashes( wfMsg('showtoc') ) . '","' . addslashes( wfMsg('hidetoc') ) . '")</script>';
2642 '<table border="0" id="toc"><tr id="toctitle"><td align="center">'."\n".
2643 '<b>'.wfMsg('toc').'</b>' .
2645 '</td></tr><tr id="tocinside"><td>'."\n".
2646 $toc."</td></tr></table>\n";
2649 # These two do not check for permissions: check $wgTitle->userCanEdit before calling them
2650 function editSectionScript( $section, $head ) {
2651 global $wgTitle, $wgRequest;
2652 if( $wgRequest->getInt( 'oldid' ) && ( $wgRequest->getVal( 'diff' ) != '0' ) ) {
2655 $url = $wgTitle->escapeLocalURL( 'action=edit§ion='.$section );
2656 return '<span oncontextmenu=\'document.location="'.$url.'";return false;\'>'.$head.'</span>';
2659 function editSectionLink( $section ) {
2661 global $wgTitle, $wgUser, $wgLang;
2663 if( $wgRequest->getInt( 'oldid' ) && ( $wgRequest->getVal( 'diff' ) != '0' ) ) {
2664 # Section edit links would be out of sync on an old page.
2665 # But, if we're diffing to the current page, they'll be
2670 $editurl = '§ion='.$section;
2671 $url = $this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg('editsection'),'action=edit'.$editurl);
2673 if( $wgLang->isRTL() ) {
2675 $nearside = 'right';
2680 return "<div class=\"editsection\" style=\"float:$farside;margin-$nearside:5px;\">[".$url."]</div>";
2684 // This function is called by EditPage.php and shows a bulletin board style
2685 // toolbar for common editing functions. It can be disabled in the user preferences.
2686 // The necsesary JavaScript code can be found in style/wikibits.js.
2687 function getEditToolbar() {
2688 global $wgStylePath, $wgLang, $wgMimeType;
2690 // toolarray an array of arrays which each include the filename of
2691 // the button image (without path), the opening tag, the closing tag,
2692 // and optionally a sample text that is inserted between the two when no
2693 // selection is highlighted.
2694 // The tip text is shown when the user moves the mouse over the button.
2696 // Already here are accesskeys (key), which are not used yet until someone
2697 // can figure out a way to make them work in IE. However, we should make
2698 // sure these keys are not defined on the edit page.
2700 array( 'image'=>'button_bold.png',
2703 'sample'=>wfMsg('bold_sample'),
2704 'tip'=>wfMsg('bold_tip'),
2707 array( "image"=>"button_italic.png",
2710 "sample"=>wfMsg("italic_sample"),
2711 "tip"=>wfMsg("italic_tip"),
2714 array( "image"=>"button_link.png",
2717 "sample"=>wfMsg("link_sample"),
2718 "tip"=>wfMsg("link_tip"),
2721 array( "image"=>"button_extlink.png",
2724 "sample"=>wfMsg("extlink_sample"),
2725 "tip"=>wfMsg("extlink_tip"),
2728 array( "image"=>"button_headline.png",
2731 "sample"=>wfMsg("headline_sample"),
2732 "tip"=>wfMsg("headline_tip"),
2735 array( "image"=>"button_image.png",
2736 "open"=>"[[".$wgLang->getNsText(NS_IMAGE
).":",
2738 "sample"=>wfMsg("image_sample"),
2739 "tip"=>wfMsg("image_tip"),
2742 array( "image"=>"button_media.png",
2743 "open"=>"[[".$wgLang->getNsText(NS_MEDIA
).":",
2745 "sample"=>wfMsg("media_sample"),
2746 "tip"=>wfMsg("media_tip"),
2749 array( "image"=>"button_math.png",
2750 "open"=>"\\<math\\>",
2751 "close"=>"\\</math\\>",
2752 "sample"=>wfMsg("math_sample"),
2753 "tip"=>wfMsg("math_tip"),
2756 array( "image"=>"button_nowiki.png",
2757 "open"=>"\\<nowiki\\>",
2758 "close"=>"\\</nowiki\\>",
2759 "sample"=>wfMsg("nowiki_sample"),
2760 "tip"=>wfMsg("nowiki_tip"),
2763 array( "image"=>"button_sig.png",
2767 "tip"=>wfMsg("sig_tip"),
2770 array( "image"=>"button_hr.png",
2771 "open"=>"\\n----\\n",
2774 "tip"=>wfMsg("hr_tip"),
2778 $toolbar ="<script type='text/javascript'>\n/*<![CDATA[*/\n";
2780 $toolbar.="document.writeln(\"<div id='toolbar'>\");\n";
2781 foreach($toolarray as $tool) {
2783 $image=$wgStylePath.'/images/'.$tool['image'];
2784 $open=$tool['open'];
2785 $close=$tool['close'];
2786 $sample = addslashes( $tool['sample'] );
2788 // Note that we use the tip both for the ALT tag and the TITLE tag of the image.
2789 // Older browsers show a "speedtip" type message only for ALT.
2790 // Ideally these should be different, realistically they
2791 // probably don't need to be.
2792 $tip = addslashes( $tool['tip'] );
2794 #$key = $tool["key"];
2796 $toolbar.="addButton('$image','$tip','$open','$close','$sample');\n";
2799 $toolbar.="addInfobox('" . addslashes( wfMsg( "infobox" ) ) . "','" . addslashes(wfMsg("infobox_alert")) . "');\n";
2800 $toolbar.="document.writeln(\"</div>\");\n";
2802 $toolbar.="/*]]>*/\n</script>";
2806 /* public */ function suppressUrlExpansion() {