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 $s = '<a href="' . $titleObj->escapeLocalURL()
885 . '"><img'.$a.' src="'
886 . $this->getLogo() . '" alt="' . "[{$mp}]\" /></a>";
892 global $wgOut, $wgTitle, $wgUser, $wgRequest, $wgLang;
893 global $wgDisableUploads, $wgRemoteUploads;
895 $fname = 'Skin::quickBar';
896 wfProfileIn( $fname );
898 $action = $wgRequest->getText( 'action' );
899 $wpPreview = $wgRequest->getBool( 'wpPreview' );
900 $tns=$wgTitle->getNamespace();
902 $s = "\n<div id='quickbar'>";
903 $s .= "\n" . $this->logoText() . "\n<hr class='sep' />";
906 $s .= $this->mainPageLink()
907 . $sep . $this->specialLink( 'recentchanges' )
908 . $sep . $this->specialLink( 'randompage' );
909 if ($wgUser->getID()) {
910 $s.= $sep . $this->specialLink( 'watchlist' ) ;
911 $s .= $sep .$this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
912 wfMsg( 'mycontris' ), 'target=' . wfUrlencode($wgUser->getName() ) );
915 // only show watchlist link if logged in
916 if ( wfMsg ( 'currentevents' ) != '-' ) $s .= $sep . $this->makeKnownLink( wfMsg( 'currentevents' ), '' ) ;
917 $s .= "\n<br /><hr class='sep' />";
918 $articleExists = $wgTitle->getArticleId();
919 if ( $wgOut->isArticle() ||
$action =='edit' ||
$action =='history' ||
$wpPreview) {
920 if($wgOut->isArticle()) {
921 $s .= '<strong>' . $this->editThisPage() . '</strong>';
922 } else { # backlink to the article in edit or history mode
923 if($articleExists){ # no backlink if no article
926 $text = wfMsg('articlepage');
929 $text = wfMsg('viewtalkpage');
932 $text = wfMsg('userpage');
935 $text = wfMsg('viewtalkpage');
938 $text = wfMsg('wikipediapage');
941 $text = wfMsg('viewtalkpage');
944 $text = wfMsg('imagepage');
947 $text = wfMsg('viewtalkpage');
950 $text= wfMsg('articlepage');
953 $link = $wgTitle->getText();
954 if ($nstext = $wgLang->getNsText($tns) ) { # add namespace if necessary
955 $link = $nstext . ':' . $link ;
958 $s .= $this->makeLink( $link, $text );
959 } elseif( $wgTitle->getNamespace() != Namespace::getSpecial() ) {
960 # we just throw in a "New page" text to tell the user that he's in edit mode,
961 # and to avoid messing with the separator that is prepended to the next item
962 $s .= '<strong>' . wfMsg('newpage') . '</strong>';
968 if( $tns%2
&& $action!='edit' && !$wpPreview) {
969 $s.= '<br />'.$this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg('postcomment'),'action=edit§ion=new');
973 watching could cause problems in edit mode:
974 if user edits article, then loads "watch this article" in background and then saves
975 article with "Watch this article" checkbox disabled, the article is transparently
976 unwatched. Therefore we do not show the "Watch this page" link in edit mode
978 if ( 0 != $wgUser->getID() && $articleExists) {
979 if($action!='edit' && $action != 'submit' )
981 $s .= $sep . $this->watchThisPage();
983 if ( $wgTitle->userCanEdit() )
984 $s .= $sep . $this->moveThisPage();
986 if ( $wgUser->isSysop() and $articleExists ) {
987 $s .= $sep . $this->deleteThisPage() .
988 $sep . $this->protectThisPage();
990 $s .= $sep . $this->talkLink();
991 if ($articleExists && $action !='history') {
992 $s .= $sep . $this->historyLink();
994 $s.=$sep . $this->whatLinksHere();
996 if($wgOut->isArticleRelated()) {
997 $s .= $sep . $this->watchPageLinksLink();
1000 if ( Namespace::getUser() == $wgTitle->getNamespace()
1001 ||
$wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser())
1004 $id=User
::idFromName($wgTitle->getText());
1005 $ip=User
::isIP($wgTitle->getText());
1008 $s .= $sep . $this->userContribsLink();
1010 if ( 0 != $wgUser->getID() ) {
1011 if($id) { # can only email real users
1012 $s .= $sep . $this->emailUserLink();
1016 $s .= "\n<br /><hr class='sep' />";
1019 if ( 0 != $wgUser->getID() && ( !$wgDisableUploads ||
$wgRemoteUploads ) ) {
1020 $s .= $this->specialLink( 'upload' ) . $sep;
1022 $s .= $this->specialLink( 'specialpages' )
1023 . $sep . $this->bugReportsLink();
1025 global $wgSiteSupportPage;
1026 if( $wgSiteSupportPage ) {
1027 $s .= "\n<br /><a href=\"" . htmlspecialchars( $wgSiteSupportPage ) .
1028 '" class="internal">' . wfMsg( 'sitesupport' ) . '</a>';
1031 $s .= "\n<br /></div>\n";
1032 wfProfileOut( $fname );
1036 function specialPagesList()
1038 global $wgUser, $wgOut, $wgLang, $wgServer, $wgRedirectScript;
1039 require_once('SpecialPage.php');
1041 $pages = SpecialPage
::getPages();
1043 foreach ( $pages[''] as $name => $page ) {
1044 $a[$name] = $page->getDescription();
1046 if ( $wgUser->isSysop() )
1048 foreach ( $pages['sysop'] as $name => $page ) {
1049 $a[$name] = $page->getDescription();
1052 if ( $wgUser->isDeveloper() )
1054 foreach ( $pages['developer'] as $name => $page ) {
1055 $a[$name] = $page->getDescription() ;
1058 $go = wfMsg( 'go' );
1059 $sp = wfMsg( 'specialpages' );
1060 $spp = $wgLang->specialPage( 'Specialpages' );
1062 $s = '<form id="specialpages" method="get" class="inline" ' .
1063 'action="' . htmlspecialchars( "{$wgServer}{$wgRedirectScript}" ) . "\">\n";
1064 $s .= "<select name=\"wpDropdown\">\n";
1065 $s .= "<option value=\"{$spp}\">{$sp}</option>\n";
1067 foreach ( $a as $name => $desc ) {
1068 $p = $wgLang->specialPage( $name );
1069 $s .= "<option value=\"{$p}\">{$desc}</option>\n";
1071 $s .= "</select>\n";
1072 $s .= "<input type='submit' value=\"{$go}\" name='redirect' />\n";
1077 function mainPageLink()
1079 $mp = wfMsg( 'mainpage' );
1080 $s = $this->makeKnownLink( $mp, $mp );
1084 function copyrightLink()
1086 $s = $this->makeKnownLink( wfMsg( 'copyrightpage' ),
1087 wfMsg( 'copyrightpagename' ) );
1091 function aboutLink()
1093 $s = $this->makeKnownLink( wfMsg( 'aboutpage' ),
1094 wfMsg( 'aboutwikipedia' ) );
1099 function disclaimerLink()
1101 $s = $this->makeKnownLink( wfMsg( 'disclaimerpage' ),
1102 wfMsg( 'disclaimers' ) );
1106 function editThisPage()
1108 global $wgOut, $wgTitle, $wgRequest;
1110 $oldid = $wgRequest->getVal( 'oldid' );
1111 $diff = $wgRequest->getVal( 'diff' );
1112 $redirect = $wgRequest->getVal( 'redirect' );
1114 if ( ! $wgOut->isArticleRelated() ) {
1115 $s = wfMsg( 'protectedpage' );
1117 $n = $wgTitle->getPrefixedText();
1118 if ( $wgTitle->userCanEdit() ) {
1119 $t = wfMsg( 'editthispage' );
1121 #$t = wfMsg( "protectedpage" );
1122 $t = wfMsg( 'viewsource' );
1126 if ( !is_null( $redirect ) ) { $red = "&redirect={$redirect}"; }
1127 if ( $oldid && ! isset( $diff ) ) {
1128 $oid = "&oldid={$oldid}";
1130 $s = $this->makeKnownLink( $n, $t, "action=edit{$oid}{$red}" );
1135 function deleteThisPage()
1137 global $wgUser, $wgOut, $wgTitle, $wgRequest;
1139 $diff = $wgRequest->getVal( 'diff' );
1140 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
1141 $n = $wgTitle->getPrefixedText();
1142 $t = wfMsg( 'deletethispage' );
1144 $s = $this->makeKnownLink( $n, $t, 'action=delete' );
1151 function protectThisPage()
1153 global $wgUser, $wgOut, $wgTitle, $wgRequest;
1155 $diff = $wgRequest->getVal( 'diff' );
1156 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
1157 $n = $wgTitle->getPrefixedText();
1159 if ( $wgTitle->isProtected() ) {
1160 $t = wfMsg( 'unprotectthispage' );
1161 $q = 'action=unprotect';
1163 $t = wfMsg( 'protectthispage' );
1164 $q = 'action=protect';
1166 $s = $this->makeKnownLink( $n, $t, $q );
1173 function watchThisPage()
1175 global $wgUser, $wgOut, $wgTitle;
1177 if ( $wgOut->isArticleRelated() ) {
1178 $n = $wgTitle->getPrefixedText();
1180 if ( $wgTitle->userIsWatching() ) {
1181 $t = wfMsg( 'unwatchthispage' );
1182 $q = 'action=unwatch';
1184 $t = wfMsg( 'watchthispage' );
1185 $q = 'action=watch';
1187 $s = $this->makeKnownLink( $n, $t, $q );
1189 $s = wfMsg( 'notanarticle' );
1194 function moveThisPage()
1196 global $wgTitle, $wgLang;
1198 if ( $wgTitle->userCanEdit() ) {
1199 $s = $this->makeKnownLink( $wgLang->specialPage( 'Movepage' ),
1200 wfMsg( 'movethispage' ), 'target=' . $wgTitle->getPrefixedURL() );
1201 } // no message if page is protected - would be redundant
1205 function historyLink()
1209 $s = $this->makeKnownLink( $wgTitle->getPrefixedText(),
1210 wfMsg( 'history' ), 'action=history' );
1214 function whatLinksHere()
1216 global $wgTitle, $wgLang;
1218 $s = $this->makeKnownLink( $wgLang->specialPage( 'Whatlinkshere' ),
1219 wfMsg( 'whatlinkshere' ), 'target=' . $wgTitle->getPrefixedURL() );
1223 function userContribsLink()
1225 global $wgTitle, $wgLang;
1227 $s = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
1228 wfMsg( 'contributions' ), 'target=' . $wgTitle->getPartialURL() );
1232 function emailUserLink()
1234 global $wgTitle, $wgLang;
1236 $s = $this->makeKnownLink( $wgLang->specialPage( 'Emailuser' ),
1237 wfMsg( 'emailuser' ), 'target=' . $wgTitle->getPartialURL() );
1241 function watchPageLinksLink()
1243 global $wgOut, $wgTitle, $wgLang;
1245 if ( ! $wgOut->isArticleRelated() ) {
1246 $s = '(' . wfMsg( 'notanarticle' ) . ')';
1248 $s = $this->makeKnownLink( $wgLang->specialPage(
1249 'Recentchangeslinked' ), wfMsg( 'recentchangeslinked' ),
1250 'target=' . $wgTitle->getPrefixedURL() );
1255 function otherLanguages()
1257 global $wgOut, $wgLang, $wgTitle, $wgUseNewInterlanguage;
1259 $a = $wgOut->getLanguageLinks();
1260 if ( 0 == count( $a ) ) {
1261 if ( !$wgUseNewInterlanguage ) return '';
1262 $ns = $wgLang->getNsIndex ( $wgTitle->getNamespace () ) ;
1263 if ( $ns != 0 AND $ns != 1 ) return '' ;
1265 $x = 'mode=addlink&xt='.$wgTitle->getDBkey() ;
1266 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1267 wfMsg( 'intl' ) , $x );
1270 if ( !$wgUseNewInterlanguage ) {
1271 $s = wfMsg( 'otherlanguages' ) . ': ';
1273 global $wgLanguageCode ;
1274 $x = 'mode=zoom&xt='.$wgTitle->getDBkey() ;
1275 $x .= '&xl='.$wgLanguageCode ;
1276 $s = $this->makeKnownLink( $wgLang->specialPage( 'Intl' ),
1277 wfMsg( 'otherlanguages' ) , $x ) . ': ' ;
1280 $s = wfMsg( 'otherlanguages' ) . ': ';
1282 if($wgLang->isRTL()) $s .= '<span dir="LTR">';
1283 foreach( $a as $l ) {
1284 if ( ! $first ) { $s .= ' | '; }
1287 $nt = Title
::newFromText( $l );
1288 $url = $nt->getFullURL();
1289 $text = $wgLang->getLanguageName( $nt->getInterwiki() );
1291 if ( '' == $text ) { $text = $l; }
1292 $style = $this->getExternalLinkAttributes( $l, $text );
1293 $s .= "<a href=\"{$url}\"{$style}>{$text}</a>";
1295 if($wgLang->isRTL()) $s .= '</span>';
1299 function bugReportsLink()
1301 $s = $this->makeKnownLink( wfMsg( 'bugreportspage' ),
1302 wfMsg( 'bugreports' ) );
1308 global $wgLinkCache;
1309 $t1 = Title
::newFromText( gmdate( 'F j' ) );
1310 $t2 = Title
::newFromText( gmdate( 'Y' ) );
1312 $wgLinkCache->suspend();
1313 $id = $t1->getArticleID();
1314 $wgLinkCache->resume();
1317 $s = $this->makeBrokenLink( $t1->getText() );
1319 $s = $this->makeKnownLink( $t1->getText() );
1323 $wgLinkCache->suspend();
1324 $id = $t2->getArticleID();
1325 $wgLinkCache->resume();
1328 $s .= $this->makeBrokenLink( $t2->getText() );
1330 $s .= $this->makeKnownLink( $t2->getText() );
1337 global $wgLang, $wgTitle, $wgLinkCache;
1339 $tns = $wgTitle->getNamespace();
1340 if ( -1 == $tns ) { return ''; }
1342 $pn = $wgTitle->getText();
1343 $tp = wfMsg( 'talkpage' );
1344 if ( Namespace::isTalk( $tns ) ) {
1345 $lns = Namespace::getSubject( $tns );
1348 $text = wfMsg('articlepage');
1351 $text = wfMsg('userpage');
1354 $text = wfMsg('wikipediapage');
1357 $text = wfMsg('imagepage');
1360 $text= wfMsg('articlepage');
1364 $lns = Namespace::getTalk( $tns );
1367 $n = $wgLang->getNsText( $lns );
1368 if ( '' == $n ) { $link = $pn; }
1369 else { $link = $n.':'.$pn; }
1371 $wgLinkCache->suspend();
1372 $s = $this->makeLink( $link, $text );
1373 $wgLinkCache->resume();
1378 function commentLink()
1380 global $wgLang, $wgTitle, $wgLinkCache;
1382 $tns = $wgTitle->getNamespace();
1383 if ( -1 == $tns ) { return ''; }
1385 $lns = ( Namespace::isTalk( $tns ) ) ?
$tns : Namespace::getTalk( $tns );
1387 # assert Namespace::isTalk( $lns )
1389 $n = $wgLang->getNsText( $lns );
1390 $pn = $wgTitle->getText();
1394 $wgLinkCache->suspend();
1395 $s = $this->makeKnownLink($link, wfMsg('postcomment'), 'action=edit§ion=new');
1396 $wgLinkCache->resume();
1401 # After all the page content is transformed into HTML, it makes
1402 # a final pass through here for things like table backgrounds.
1404 function transformContent( $text )
1409 # Note: This function MUST call getArticleID() on the link,
1410 # otherwise the cache won't get updated properly. See LINKCACHE.DOC.
1412 function makeLink( $title, $text = '', $query = '', $trail = '' ) {
1413 wfProfileIn( 'Skin::makeLink' );
1414 $nt = Title
::newFromText( $title );
1416 $result = $this->makeLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1418 wfDebug( 'Invalid title passed to Skin::makeLink(): "'.$title."\"\n" );
1419 $result = $text == "" ?
$title : $text;
1422 wfProfileOut( 'Skin::makeLink' );
1426 function makeKnownLink( $title, $text = '', $query = '', $trail = '', $prefix = '',$aprops = '') {
1427 $nt = Title
::newFromText( $title );
1429 return $this->makeKnownLinkObj( Title
::newFromText( $title ), $text, $query, $trail, $prefix , $aprops );
1431 wfDebug( 'Invalid title passed to Skin::makeKnownLink(): "'.$title."\"\n" );
1432 return $text == '' ?
$title : $text;
1436 function makeBrokenLink( $title, $text = '', $query = '', $trail = '' ) {
1437 $nt = Title
::newFromText( $title );
1439 return $this->makeBrokenLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1441 wfDebug( 'Invalid title passed to Skin::makeBrokenLink(): "'.$title."\"\n" );
1442 return $text == '' ?
$title : $text;
1446 function makeStubLink( $title, $text = '', $query = '', $trail = '' ) {
1447 $nt = Title
::newFromText( $title );
1449 return $this->makeStubLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1451 wfDebug( 'Invalid title passed to Skin::makeStubLink(): "'.$title."\"\n" );
1452 return $text == '' ?
$title : $text;
1456 # Pass a title object, not a title string
1457 function makeLinkObj( &$nt, $text= '', $query = '', $trail = '', $prefix = '' )
1459 global $wgOut, $wgUser;
1460 $fname = 'Skin::makeLinkObj';
1464 return "<!-- ERROR -->{$prefix}{$text}{$trail}";
1466 if ( $nt->isExternal() ) {
1467 $u = $nt->getFullURL();
1468 $link = $nt->getPrefixedURL();
1469 if ( '' == $text ) { $text = $nt->getPrefixedText(); }
1470 $style = $this->getExternalLinkAttributes( $link, $text, 'extiw' );
1473 if ( '' != $trail ) {
1474 if ( preg_match( '/^([a-z]+)(.*)$$/sD', $trail, $m ) ) {
1479 $retVal = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1480 } elseif ( 0 == $nt->getNamespace() && "" == $nt->getText() ) {
1481 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1482 } elseif ( ( -1 == $nt->getNamespace() ) ||
1483 ( Namespace::getImage() == $nt->getNamespace() ) ) {
1484 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1486 if ( $this->postParseLinkColour() ) {
1488 if ( '' != $trail ) {
1489 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1495 # Allows wiki to bypass using linkcache, see OutputPage::parseLinkHolders()
1496 $retVal = '<!--LINK ' . implode( ' ', array( $nt->getNamespace(), $nt->getDBkey(),
1497 $query, $prefix . $text . $inside ) ) . "-->{$trail}";
1499 # Work out link colour immediately
1500 $aid = $nt->getArticleID() ;
1502 $retVal = $this->makeBrokenLinkObj( $nt, $text, $query, $trail, $prefix );
1504 $threshold = $wgUser->getOption('stubthreshold') ;
1505 if ( $threshold > 0 ) {
1506 $dbr =& wfGetDB( DB_SLAVE
);
1507 $s = $dbr->selectRow( 'cur', array( 'LENGTH(cur_text) AS x', 'cur_namespace',
1508 'cur_is_redirect' ), array( 'cur_id' => $aid ), $fname ) ;
1509 if ( $s !== false ) {
1511 if ( $s->cur_is_redirect
OR $s->cur_namespace
!= 0 ) {
1512 $size = $threshold*2 ; # Really big
1514 $dbr->freeResult( $res );
1516 $size = $threshold*2 ; # Really big
1521 if ( $size < $threshold ) {
1522 $retVal = $this->makeStubLinkObj( $nt, $text, $query, $trail, $prefix );
1524 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1532 # Pass a title object, not a title string
1533 function makeKnownLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' , $aprops = '')
1535 global $wgOut, $wgTitle, $wgInputEncoding;
1537 $fname = 'Skin::makeKnownLinkObj';
1538 wfProfileIn( $fname );
1540 if ( !is_object( $nt ) ) {
1543 $link = $nt->getPrefixedURL();
1545 if ( '' == $link ) {
1547 if ( '' == $text ) {
1548 $text = htmlspecialchars( $nt->getFragment() );
1551 $u = $nt->escapeLocalURL( $query );
1553 if ( '' != $nt->getFragment() ) {
1554 $anchor = urlencode( do_html_entity_decode( str_replace(' ', '_', $nt->getFragment()), ENT_COMPAT
, $wgInputEncoding ) );
1555 $replacearray = array(
1559 $u .= '#' . str_replace(array_keys($replacearray),array_values($replacearray),$anchor);
1561 if ( '' == $text ) {
1562 $text = htmlspecialchars( $nt->getPrefixedText() );
1564 $style = $this->getInternalLinkAttributesObj( $nt, $text );
1567 if ( '' != $trail ) {
1568 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1573 $r = "<a href=\"{$u}\"{$style}{$aprops}>{$prefix}{$text}{$inside}</a>{$trail}";
1574 wfProfileOut( $fname );
1578 # Pass a title object, not a title string
1579 function makeBrokenLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
1581 global $wgOut, $wgUser;
1583 $fname = 'Skin::makeBrokenLinkObj';
1584 wfProfileIn( $fname );
1586 if ( '' == $query ) {
1589 $q = 'action=edit&'.$query;
1591 $u = $nt->escapeLocalURL( $q );
1593 if ( '' == $text ) {
1594 $text = htmlspecialchars( $nt->getPrefixedText() );
1596 $style = $this->getInternalLinkAttributesObj( $nt, $text, "yes" );
1599 if ( '' != $trail ) {
1600 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1605 if ( $wgUser->getOption( 'highlightbroken' ) ) {
1606 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1608 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>?</a>{$trail}";
1611 wfProfileOut( $fname );
1615 # Pass a title object, not a title string
1616 function makeStubLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
1618 global $wgOut, $wgUser;
1620 $link = $nt->getPrefixedURL();
1622 $u = $nt->escapeLocalURL( $query );
1624 if ( '' == $text ) {
1625 $text = htmlspecialchars( $nt->getPrefixedText() );
1627 $style = $this->getInternalLinkAttributesObj( $nt, $text, 'stub' );
1630 if ( '' != $trail ) {
1631 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1636 if ( $wgUser->getOption( 'highlightbroken' ) ) {
1637 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1639 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>!</a>{$trail}";
1644 function makeSelfLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
1646 $u = $nt->escapeLocalURL( $query );
1647 if ( '' == $text ) {
1648 $text = htmlspecialchars( $nt->getPrefixedText() );
1651 if ( '' != $trail ) {
1652 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1657 return "<strong>{$prefix}{$text}{$inside}</strong>{$trail}";
1660 /* these are used extensively in SkinPHPTal, but also some other places */
1661 /*static*/ function makeSpecialUrl( $name, $urlaction='' ) {
1662 $title = Title
::makeTitle( NS_SPECIAL
, $name );
1663 $this->checkTitle($title, $name);
1664 return $title->getLocalURL( $urlaction );
1666 /*static*/ function makeTalkUrl ( $name, $urlaction='' ) {
1667 $title = Title
::newFromText( $name );
1668 $title = $title->getTalkPage();
1669 $this->checkTitle($title, $name);
1670 return $title->getLocalURL( $urlaction );
1672 /*static*/ function makeArticleUrl ( $name, $urlaction='' ) {
1673 $title = Title
::newFromText( $name );
1674 $title= $title->getSubjectPage();
1675 $this->checkTitle($title, $name);
1676 return $title->getLocalURL( $urlaction );
1678 /*static*/ function makeI18nUrl ( $name, $urlaction='' ) {
1679 $title = Title
::newFromText( wfMsg($name) );
1680 $this->checkTitle($title, $name);
1681 return $title->getLocalURL( $urlaction );
1683 /*static*/ function makeUrl ( $name, $urlaction='' ) {
1684 $title = Title
::newFromText( $name );
1685 $this->checkTitle($title, $name);
1686 return $title->getLocalURL( $urlaction );
1688 # this can be passed the NS number as defined in Language.php
1689 /*static*/ function makeNSUrl( $name, $urlaction='', $namespace=0 ) {
1690 $title = Title
::makeTitle( $namespace, $name );
1691 $this->checkTitle($title, $name);
1692 return $title->getLocalURL( $urlaction );
1695 /* these return an array with the 'href' and boolean 'exists' */
1696 /*static*/ function makeUrlDetails ( $name, $urlaction='' ) {
1697 $title = Title
::newFromText( $name );
1698 $this->checkTitle($title, $name);
1700 'href' => $title->getLocalURL( $urlaction ),
1701 'exists' => $title->getArticleID() != 0?
true:false
1704 /*static*/ function makeTalkUrlDetails ( $name, $urlaction='' ) {
1705 $title = Title
::newFromText( $name );
1706 $title = $title->getTalkPage();
1707 $this->checkTitle($title, $name);
1709 'href' => $title->getLocalURL( $urlaction ),
1710 'exists' => $title->getArticleID() != 0?
true:false
1713 /*static*/ function makeArticleUrlDetails ( $name, $urlaction='' ) {
1714 $title = Title
::newFromText( $name );
1715 $title= $title->getSubjectPage();
1716 $this->checkTitle($title, $name);
1718 'href' => $title->getLocalURL( $urlaction ),
1719 'exists' => $title->getArticleID() != 0?
true:false
1722 /*static*/ function makeI18nUrlDetails ( $name, $urlaction='' ) {
1723 $title = Title
::newFromText( wfMsg($name) );
1724 $this->checkTitle($title, $name);
1726 'href' => $title->getLocalURL( $urlaction ),
1727 'exists' => $title->getArticleID() != 0?
true:false
1731 # make sure we have some title to operate on
1732 /*static*/ function checkTitle ( &$title, &$name ) {
1733 if(!is_object($title)) {
1734 $title = Title
::newFromText( $name );
1735 if(!is_object($title)) {
1736 $title = Title
::newFromText( '--error: link target missing--' );
1741 function fnamePart( $url )
1743 $basename = strrchr( $url, '/' );
1744 if ( false === $basename ) {
1747 $basename = substr( $basename, 1 );
1749 return htmlspecialchars( $basename );
1752 function makeImage( $url, $alt = '' )
1757 $alt = $this->fnamePart( $url );
1759 $s = '<img src="'.$url.'" alt="'.$alt.'" />';
1763 function makeImageLink( $name, $url, $alt = '' ) {
1764 $nt = Title
::makeTitle( Namespace::getImage(), $name );
1765 return $this->makeImageLinkObj( $nt, $alt );
1768 function makeImageLinkObj( $nt, $alt = '' ) {
1769 global $wgLang, $wgUseImageResize;
1770 $img = Image
::newFromTitle( $nt );
1771 $url = $img->getURL();
1774 $prefix = $postfix = '';
1776 if ( $wgUseImageResize ) {
1777 # Check if the alt text is of the form "options|alt text"
1779 # * thumbnail make a thumbnail with enlarge-icon and caption, alignment depends on lang
1780 # * left no resizing, just left align. label is used for alt= only
1781 # * right same, but right aligned
1782 # * none same, but not aligned
1783 # * ___px scale to ___ pixels width, no aligning. e.g. use in taxobox
1784 # * center center the image
1785 # * framed Keep original image size, no magnify-button.
1787 $part = explode( '|', $alt);
1789 $mwThumb =& MagicWord
::get( MAG_IMG_THUMBNAIL
);
1790 $mwLeft =& MagicWord
::get( MAG_IMG_LEFT
);
1791 $mwRight =& MagicWord
::get( MAG_IMG_RIGHT
);
1792 $mwNone =& MagicWord
::get( MAG_IMG_NONE
);
1793 $mwWidth =& MagicWord
::get( MAG_IMG_WIDTH
);
1794 $mwCenter =& MagicWord
::get( MAG_IMG_CENTER
);
1795 $mwFramed =& MagicWord
::get( MAG_IMG_FRAMED
);
1796 $alt = $part[count($part)-1];
1798 $height = $framed = $thumb = false;
1799 $manual_thumb = "" ;
1801 foreach( $part as $key => $val ) {
1802 $val_parts = explode ( "=" , $val , 2 ) ;
1803 $left_part = array_shift ( $val_parts ) ;
1804 if ( ! is_null( $mwThumb->matchVariableStartToEnd($val) ) ) {
1806 } elseif ( count ( $val_parts ) == 1 && ! is_null( $mwThumb->matchVariableStartToEnd($left_part) ) ) {
1807 # use manually specified thumbnail
1809 $manual_thumb = array_shift ( $val_parts ) ;
1810 } elseif ( ! is_null( $mwRight->matchVariableStartToEnd($val) ) ) {
1811 # remember to set an alignment, don't render immediately
1813 } elseif ( ! is_null( $mwLeft->matchVariableStartToEnd($val) ) ) {
1814 # remember to set an alignment, don't render immediately
1816 } elseif ( ! is_null( $mwCenter->matchVariableStartToEnd($val) ) ) {
1817 # remember to set an alignment, don't render immediately
1819 } elseif ( ! is_null( $mwNone->matchVariableStartToEnd($val) ) ) {
1820 # remember to set an alignment, don't render immediately
1822 } elseif ( ! is_null( $match = $mwWidth->matchVariableStartToEnd($val) ) ) {
1823 # $match is the image width in pixels
1824 if ( preg_match( '/^([0-9]*)x([0-9]*)$/', $match, $m ) ) {
1825 $width = intval( $m[1] );
1826 $height = intval( $m[2] );
1828 $width = intval($match);
1830 } elseif ( ! is_null( $mwFramed->matchVariableStartToEnd($val) ) ) {
1834 if ( 'center' == $align )
1836 $prefix = '<span style="text-align: center">';
1837 $postfix = '</span>';
1841 if ( $thumb ||
$framed ) {
1843 # Create a thumbnail. Alignment depends on language
1844 # writing direction, # right aligned for left-to-right-
1845 # languages ("Western languages"), left-aligned
1846 # for right-to-left-languages ("Semitic languages")
1848 # If thumbnail width has not been provided, it is set
1849 # here to 180 pixels
1850 if ( $align == '' ) {
1851 $align = $wgLang->isRTL() ?
'left' : 'right';
1853 if ( ! isset($width) ) {
1856 return $prefix.$this->makeThumbLinkObj( $img, $alt, $align, $width, $height, $framed, $manual_thumb ).$postfix;
1858 } elseif ( isset($width) ) {
1860 # Create a resized image, without the additional thumbnail
1863 if ( ( ! $height === false )
1864 && ( $img->getHeight() * $width / $img->getWidth() > $height ) ) {
1865 print "height=$height<br>\nimg->getHeight() = ".$img->getHeight()."<br>\n";
1866 print 'rescaling by factor '. $height / $img->getHeight() . "<br>\n";
1867 $width = $img->getWidth() * $height / $img->getHeight();
1869 if ( '' == $manual_thumb ) $url = $img->createThumb( $width );
1871 } # endif $wgUseImageResize
1873 if ( empty( $alt ) ) {
1874 $alt = preg_replace( '/\.(.+?)^/', '', $img->getName() );
1876 $alt = htmlspecialchars( $alt );
1878 $u = $nt->escapeLocalURL();
1881 $s = wfMsg( 'missingimage', $img->getName() );
1882 $s .= "<br>{$alt}<br>{$url}<br>\n";
1884 $s = '<a href="'.$u.'" class="image" title="'.$alt.'">' .
1885 '<img src="'.$url.'" alt="'.$alt.'" /></a>';
1887 if ( '' != $align ) {
1888 $s = "<div class=\"float{$align}\"><span>{$s}</span></div>";
1890 return str_replace("\n", ' ',$prefix.$s.$postfix);
1893 # Make HTML for a thumbnail including image, border and caption
1894 # $img is an Image object
1895 function makeThumbLinkObj( $img, $label = '', $align = 'right', $boxwidth = 180, $boxheight=false, $framed=false , $manual_thumb = "" ) {
1896 global $wgStylePath, $wgLang;
1897 # $image = Title::makeTitle( Namespace::getImage(), $name );
1898 $url = $img->getURL();
1900 #$label = htmlspecialchars( $label );
1901 $alt = preg_replace( '/<[^>]*>/', '', $label);
1902 $alt = htmlspecialchars( $alt );
1904 $width = $height = 0;
1905 if ( $img->exists() )
1907 $width = $img->getWidth();
1908 $height = $img->getHeight();
1910 if ( 0 == $width ||
0 == $height )
1912 $width = $height = 200;
1914 if ( $boxwidth == 0 )
1920 // Use image dimensions, don't scale
1922 $oboxwidth = $boxwidth +
2;
1923 $boxheight = $height;
1926 $h = intval( $height/($width/$boxwidth) );
1927 $oboxwidth = $boxwidth +
2;
1928 if ( ( ! $boxheight === false ) && ( $h > $boxheight ) )
1930 $boxwidth *= $boxheight/$h;
1934 if ( '' == $manual_thumb ) $thumbUrl = $img->createThumb( $boxwidth );
1937 if ( $manual_thumb != '' ) # Use manually specified thumbnail
1939 $manual_title = Title
::makeTitle( Namespace::getImage(), $manual_thumb ); #new Title ( $manual_thumb ) ;
1940 $manual_img = Image
::newFromTitle( $manual_title );
1941 $thumbUrl = $manual_img->getURL();
1942 if ( $manual_img->exists() )
1944 $width = $manual_img->getWidth();
1945 $height = $manual_img->getHeight();
1946 $boxwidth = $width ;
1947 $boxheight = $height ;
1948 $oboxwidth = $boxwidth +
2 ;
1952 $u = $img->getEscapeLocalURL();
1954 $more = htmlspecialchars( wfMsg( 'thumbnail-more' ) );
1955 $magnifyalign = $wgLang->isRTL() ?
'left' : 'right';
1956 $textalign = $wgLang->isRTL() ?
' style="text-align:right"' : '';
1958 $s = "<div class=\"thumb t{$align}\"><div style=\"width:{$oboxwidth}px;\">";
1959 if ( $thumbUrl == '' ) {
1960 $s .= wfMsg( 'missingimage', $img->getName() );
1963 $s .= '<a href="'.$u.'" class="internal" title="'.$alt.'">'.
1964 '<img src="'.$thumbUrl.'" alt="'.$alt.'" ' .
1965 'width="'.$boxwidth.'" height="'.$boxheight.'" /></a>';
1969 $zoomicon = '<div class="magnify" style="float:'.$magnifyalign.'">'.
1970 '<a href="'.$u.'" class="internal" title="'.$more.'">'.
1971 '<img src="'.$wgStylePath.'/images/magnify-clip.png" ' .
1972 'width="15" height="11" alt="'.$more.'" /></a></div>';
1975 $s .= ' <div class="thumbcaption" '.$textalign.'>'.$zoomicon.$label."</div></div></div>";
1976 return str_replace("\n", ' ', $s);
1979 function makeMediaLink( $name, $url, $alt = "" ) {
1980 $nt = Title
::makeTitle( Namespace::getMedia(), $name );
1981 return $this->makeMediaLinkObj( $nt, $alt );
1984 function makeMediaLinkObj( $nt, $alt = "" )
1986 if ( ! isset( $nt ) )
1988 ### HOTFIX. Instead of breaking, return empty string.
1991 $name = $nt->getDBKey();
1992 $url = Image
::wfImageUrl( $name );
1993 if ( empty( $alt ) ) {
1994 $alt = preg_replace( '/\.(.+?)^/', '', $name );
1997 $u = htmlspecialchars( $url );
1998 $s = "<a href=\"{$u}\" class='internal' title=\"{$alt}\">{$alt}</a>";
2003 function specialLink( $name, $key = "" )
2007 if ( '' == $key ) { $key = strtolower( $name ); }
2008 $pn = $wgLang->ucfirst( $name );
2009 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
2013 function makeExternalLink( $url, $text, $escape = true ) {
2014 $style = $this->getExternalLinkAttributes( $url, $text );
2015 $url = htmlspecialchars( $url );
2017 $text = htmlspecialchars( $text );
2019 return '<a href="'.$url.'"'.$style.'>'.$text.'</a>';
2022 # Called by history lists and recent changes
2025 # Returns text for the start of the tabular part of RC
2026 function beginRecentChangesList()
2028 $this->rc_cache
= array() ;
2029 $this->rcMoveIndex
= 0;
2030 $this->rcCacheIndex
= 0 ;
2031 $this->lastdate
= '';
2032 $this->rclistOpen
= false;
2036 function beginImageHistoryList()
2038 $s = "\n<h2>" . wfMsg( 'imghistory' ) . "</h2>\n" .
2039 "<p>" . wfMsg( 'imghistlegend' ) . "</p>\n".'<ul class="special">';
2043 # Returns text for the end of RC
2044 # If enhanced RC is in use, returns pretty much all the text
2045 function endRecentChangesList()
2047 $s = $this->recentChangesBlock() ;
2048 if( $this->rclistOpen
) {
2054 # Enhanced RC ungrouped line
2055 function recentChangesBlockLine ( $rcObj )
2057 global $wgStylePath, $wgLang ;
2059 # Get rc_xxxx variables
2060 extract( $rcObj->mAttribs
) ;
2061 $curIdEq = 'curid='.$rc_cur_id;
2066 $r .= '<img src="'.$wgStylePath.'/images/Arr_.png" width="12" height="12" border="0" />' ;
2069 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2070 $r .= ' ';
2072 # M & N (minor & new)
2073 $M = wfMsg( 'minoreditletter' );
2074 $N = wfMsg( 'newpageletter' );
2076 if ( $rc_type == RC_NEW
) {
2089 $r .= ' '.$rcObj->timestamp
.' ' ;
2093 $link = $rcObj->link
;
2094 if ( $rcObj->watched
) $link = '<strong>'.$link.'</strong>' ;
2099 $r .= $rcObj->difflink
;
2103 $r .= $this->makeKnownLinkObj( $rcObj->getTitle(), wfMsg( 'hist' ), $curIdEq.'&action=history' );
2106 $r .= ') . . '.$rcObj->userlink
;
2107 $r .= $rcObj->usertalklink
;
2110 if ( $rc_comment != '' && $rc_type != RC_MOVE
&& $rc_type != RC_MOVE_OVER_REDIRECT
) {
2111 $rc_comment=$this->formatComment($rc_comment);
2112 $r .= $wgLang->emphasize( ' ('.$rc_comment.')' );
2120 function recentChangesBlockGroup ( $block )
2122 global $wgStylePath, $wgLang ;
2125 $M = wfMsg( 'minoreditletter' );
2126 $N = wfMsg( 'newpageletter' );
2128 # Collate list of users
2130 $userlinks = array () ;
2131 foreach ( $block AS $rcObj ) {
2132 $oldid = $rcObj->mAttribs
['rc_last_oldid'];
2133 if ( $rcObj->mAttribs
['rc_new'] ) $isnew = true ;
2134 $u = $rcObj->userlink
;
2135 if ( !isset ( $userlinks[$u] ) ) $userlinks[$u] = 0 ;
2139 # Sort the list and convert to text
2140 krsort ( $userlinks ) ;
2141 asort ( $userlinks ) ;
2143 foreach ( $userlinks as $userlink => $count) {
2145 if ( $count > 1 ) $text .= " ({$count}×)" ;
2146 array_push ( $users , $text ) ;
2148 $users = ' <font size="-1">['.implode('; ',$users).']</font>' ;
2151 $rci = 'RCI'.$this->rcCacheIndex
;
2152 $rcl = 'RCL'.$this->rcCacheIndex
;
2153 $rcm = 'RCM'.$this->rcCacheIndex
;
2154 $toggleLink = "javascript:toggleVisibility('$rci','$rcm','$rcl')" ;
2155 $arrowdir = $wgLang->isRTL() ?
'l' : 'r';
2156 $tl = '<span id="'.$rcm.'"><a href="'.$toggleLink.'"><img src="'.$wgStylePath.'/images/Arr_'.$arrowdir.'.png" width="12" height="12" /></a></span>' ;
2157 $tl .= '<span id="'.$rcl.'" style="display:none"><a href="'.$toggleLink.'"><img src="'.$wgStylePath.'/images/Arr_d.png" width="12" height="12" /></a></span>' ;
2163 if ( $isnew ) $r .= $N ;
2164 else $r .= ' ' ;
2165 $r .= ' ' ; # Minor
2168 $r .= ' '.$block[0]->timestamp
.' ' ;
2172 $link = $block[0]->link
;
2173 if ( $block[0]->watched
) $link = '<strong>'.$link.'</strong>' ;
2176 $curIdEq = 'curid=' . $block[0]->mAttribs
['rc_cur_id'];
2177 if ( $block[0]->mAttribs
['rc_type'] != RC_LOG
) {
2179 $r .= ' ('.count($block).' ' ;
2180 if ( $isnew ) $r .= wfMsg('changes');
2181 else $r .= $this->makeKnownLinkObj( $block[0]->getTitle() , wfMsg('changes') ,
2182 $curIdEq.'&diff=0&oldid='.$oldid ) ;
2186 $r .= $this->makeKnownLinkObj( $block[0]->getTitle(), wfMsg( 'history' ), $curIdEq.'&action=history' );
2194 $r .= '<div id="'.$rci.'" style="display:none">' ;
2195 foreach ( $block AS $rcObj ) {
2196 # Get rc_xxxx variables
2197 extract( $rcObj->mAttribs
);
2199 $r .= '<img src="'.$wgStylePath.'/images/Arr_.png" width="12" height="12" />';
2200 $r .= '<tt> ' ;
2201 if ( $rc_new ) $r .= $N ;
2202 else $r .= ' ' ;
2203 if ( $rc_minor ) $r .= $M ;
2204 else $r .= ' ' ;
2208 if ( $rc_last_oldid != 0 ) {
2209 $o = 'oldid='.$rc_last_oldid ;
2211 if ( $rc_type == RC_LOG
) {
2212 $link = $rcObj->timestamp
;
2214 $link = $this->makeKnownLinkObj( $rcObj->getTitle(), $rcObj->timestamp
, "{$curIdEq}&$o" ) ;
2216 $link = '<tt>'.$link.'</tt>' ;
2220 $r .= $rcObj->curlink
;
2222 $r .= $rcObj->lastlink
;
2223 $r .= ') . . '.$rcObj->userlink
;
2224 $r .= $rcObj->usertalklink
;
2225 if ( $rc_comment != '' ) {
2226 $rc_comment=$this->formatComment($rc_comment);
2227 $r .= $wgLang->emphasize( ' ('.$rc_comment.')' ) ;
2233 $this->rcCacheIndex++
;
2237 # If enhanced RC is in use, this function takes the previously cached
2238 # RC lines, arranges them, and outputs the HTML
2239 function recentChangesBlock ()
2241 global $wgStylePath ;
2242 if ( count ( $this->rc_cache
) == 0 ) return '' ;
2244 foreach ( $this->rc_cache
AS $secureName => $block ) {
2245 if ( count ( $block ) < 2 ) {
2246 $blockOut .= $this->recentChangesBlockLine ( array_shift ( $block ) ) ;
2248 $blockOut .= $this->recentChangesBlockGroup ( $block ) ;
2252 return '<div>'.$blockOut.'</div>' ;
2255 # Called in a loop over all displayed RC entries
2256 # Either returns the line, or caches it for later use
2257 function recentChangesLine( &$rc, $watched = false )
2260 $usenew = $wgUser->getOption( 'usenewrc' );
2262 $line = $this->recentChangesLineNew ( $rc, $watched ) ;
2264 $line = $this->recentChangesLineOld ( $rc, $watched ) ;
2268 function recentChangesLineOld( &$rc, $watched = false )
2270 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds, $wgUseRCPatrol, $wgOnlySysopsCanPatrol;
2272 # Extract DB fields into local scope
2273 extract( $rc->mAttribs
);
2274 $curIdEq = 'curid=' . $rc_cur_id;
2276 # Make date header if necessary
2277 $date = $wgLang->date( $rc_timestamp, true);
2279 if ( $date != $this->lastdate
) {
2280 if ( '' != $this->lastdate
) { $s .= "</ul>\n"; }
2281 $s .= "<h4>{$date}</h4>\n<ul class='special'>";
2282 $this->lastdate
= $date;
2283 $this->rclistOpen
= true;
2286 # If this edit has not yet been patrolled, make it stick out
2287 $s .= ( ! $wgUseRCPatrol ||
$rc_patrolled ) ?
'<li> ' : '<li class="not_patrolled"> ';
2289 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2291 $s .= '(' . wfMsg( 'diff' ) . ') (';
2293 $s .= $this->makeKnownLinkObj( $rc->getMovedToTitle(), wfMsg( 'hist' ), 'action=history' ) .
2296 # "[[x]] moved to [[y]]"
2297 $msg = ( $rc_type == RC_MOVE
) ?
'1movedto2' : '1movedto2_redir';
2298 $s .= wfMsg( $msg, $this->makeKnownLinkObj( $rc->getTitle(), '', 'redirect=no' ),
2299 $this->makeKnownLinkObj( $rc->getMovedToTitle(), '' ) );
2302 if ( $rc_type == RC_NEW ||
$rc_type == RC_LOG
) {
2303 $diffLink = wfMsg( 'diff' );
2305 if ( $wgUseRCPatrol && $rc_patrolled == 0 && $wgUser->getID() != 0 &&
2306 ( $wgUser->isSysop() ||
!$wgOnlySysopsCanPatrol ) )
2307 $rcidparam = "&rcid={$rc_id}";
2310 $diffLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'diff' ),
2311 "{$curIdEq}&diff={$rc_this_oldid}&oldid={$rc_last_oldid}{$rcidparam}",
2312 '', '', ' tabindex="'.$rc->counter
.'"');
2314 $s .= '('.$diffLink.') (';
2317 $s .= $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'hist' ), $curIdEq.'&action=history' );
2320 # M and N (minor and new)
2321 if ( $rc_minor ) { $s .= ' <span class="minor">'.wfMsg( "minoreditletter" ).'</span>'; }
2322 if ( $rc_type == RC_NEW
) { $s .= '<span class="newpage">'.wfMsg( "newpageletter" ).'</span>'; }
2325 # If it's a new article, there is no diff link, but if it hasn't been
2326 # patrolled yet, we need to give users a way to do so
2327 if ( $wgUseRCPatrol && $rc_type == RC_NEW
&& $rc_patrolled == 0 &&
2328 $wgUser->getID() != 0 && ( $wgUser->isSysop() ||
!$wgOnlySysopsCanPatrol ) )
2329 $articleLink = $this->makeKnownLinkObj( $rc->getTitle(), '', "rcid={$rc_id}" );
2331 $articleLink = $this->makeKnownLinkObj( $rc->getTitle(), '' );
2334 $articleLink = '<strong>'.$articleLink.'</strong>';
2336 $s .= ' '.$articleLink;
2341 $s .= '; ' . $wgLang->time( $rc_timestamp, true, $wgRCSeconds ) . ' . . ';
2343 # User link (or contributions for unregistered users)
2344 if ( 0 == $rc_user ) {
2345 $userLink = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
2346 $rc_user_text, 'target=' . $rc_user_text );
2348 $userLink = $this->makeLink( $wgLang->getNsText( NS_USER
) . ':'.$rc_user_text, $rc_user_text );
2353 $talkname=$wgLang->getNsText(NS_TALK
); # use the shorter name
2354 global $wgDisableAnonTalk;
2355 if( 0 == $rc_user && $wgDisableAnonTalk ) {
2358 $utns=$wgLang->getNsText(NS_USER_TALK
);
2359 $userTalkLink= $this->makeLink($utns . ':'.$rc_user_text, $talkname );
2363 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2364 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2365 'Blockip' ), wfMsg( 'blocklink' ), 'ip='.$rc_user_text );
2369 if($userTalkLink) $userTalkLink .= ' | ';
2370 $userTalkLink .= $blockLink;
2372 if($userTalkLink) $s.=' ('.$userTalkLink.')';
2375 if ( '' != $rc_comment && '*' != $rc_comment && $rc_type != RC_MOVE
&& $rc_type != RC_MOVE_OVER_REDIRECT
) {
2376 $rc_comment=$this->formatComment($rc_comment);
2377 $s .= $wgLang->emphasize(' (' . $rc_comment . ')');
2384 function recentChangesLineNew( &$baseRC, $watched = false )
2386 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds;
2388 # Create a specialised object
2389 $rc = RCCacheEntry
::newFromParent( $baseRC ) ;
2391 # Extract fields from DB into the function scope (rc_xxxx variables)
2392 extract( $rc->mAttribs
);
2393 $curIdEq = 'curid=' . $rc_cur_id;
2395 # If it's a new day, add the headline and flush the cache
2396 $date = $wgLang->date( $rc_timestamp, true);
2398 if ( $date != $this->lastdate
) {
2399 # Process current cache
2400 $ret = $this->recentChangesBlock () ;
2401 $this->rc_cache
= array() ;
2402 $ret .= "<h4>{$date}</h4>\n";
2403 $this->lastdate
= $date;
2407 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2408 $msg = ( $rc_type == RC_MOVE
) ?
"1movedto2" : "1movedto2_redir";
2409 $clink = wfMsg( $msg, $this->makeKnownLinkObj( $rc->getTitle(), '', 'redirect=no' ),
2410 $this->makeKnownLinkObj( $rc->getMovedToTitle(), '' ) );
2412 $clink = $this->makeKnownLinkObj( $rc->getTitle(), '' ) ;
2415 $time = $wgLang->time( $rc_timestamp, true, $wgRCSeconds );
2416 $rc->watched
= $watched ;
2417 $rc->link
= $clink ;
2418 $rc->timestamp
= $time;
2420 # Make "cur" and "diff" links
2421 if ( ( $rc_type == RC_NEW
&& $rc_this_oldid == 0 ) ||
$rc_type == RC_LOG ||
$rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2422 $curLink = wfMsg( 'cur' );
2423 $diffLink = wfMsg( 'diff' );
2425 $query = $curIdEq.'&diff=0&oldid='.$rc_this_oldid;
2426 $aprops = ' tabindex="'.$baseRC->counter
.'"';
2427 $curLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'cur' ), $query, '' ,'' , $aprops );
2428 $diffLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'diff'), $query, '' ,'' , $aprops );
2432 $titleObj = $rc->getTitle();
2433 if ( $rc_last_oldid == 0 ||
$rc_type == RC_LOG ||
$rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2434 $lastLink = wfMsg( 'last' );
2436 $lastLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'last' ),
2437 $curIdEq.'&diff='.$rc_this_oldid.'&oldid='.$rc_last_oldid );
2440 # Make user link (or user contributions for unregistered users)
2441 if ( $rc_user == 0 ) {
2442 $userLink = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
2443 $rc_user_text, 'target=' . $rc_user_text );
2445 $userLink = $this->makeLink( $wgLang->getNsText(
2446 Namespace::getUser() ) . ':'.$rc_user_text, $rc_user_text );
2449 $rc->userlink
= $userLink;
2450 $rc->lastlink
= $lastLink;
2451 $rc->curlink
= $curLink;
2452 $rc->difflink
= $diffLink;
2454 # Make user talk link
2455 $utns=$wgLang->getNsText(NS_USER_TALK
);
2456 $talkname=$wgLang->getNsText(NS_TALK
); # use the shorter name
2457 $userTalkLink= $this->makeLink($utns . ':'.$rc_user_text, $talkname );
2459 global $wgDisableAnonTalk;
2460 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2461 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2462 'Blockip' ), wfMsg( 'blocklink' ), 'ip='.$rc_user_text );
2463 if( $wgDisableAnonTalk )
2464 $rc->usertalklink
= ' ('.$blockLink.')';
2466 $rc->usertalklink
= ' ('.$userTalkLink.' | '.$blockLink.')';
2468 if( $wgDisableAnonTalk && ($rc_user == 0) )
2469 $rc->usertalklink
= '';
2471 $rc->usertalklink
= ' ('.$userTalkLink.')';
2474 # Put accumulated information into the cache, for later display
2475 # Page moves go on their own line
2476 $title = $rc->getTitle();
2477 $secureName = $title->getPrefixedDBkey();
2478 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2479 # Use an @ character to prevent collision with page names
2480 $this->rc_cache
['@@' . ($this->rcMoveIndex++
)] = array($rc);
2482 if ( !isset ( $this->rc_cache
[$secureName] ) ) $this->rc_cache
[$secureName] = array() ;
2483 array_push ( $this->rc_cache
[$secureName] , $rc ) ;
2488 function endImageHistoryList()
2494 /* This function is called by all recent changes variants, by the page history,
2495 and by the user contributions list. It is responsible for formatting edit
2496 comments. It escapes any HTML in the comment, but adds some CSS to format
2497 auto-generated comments (from section editing) and formats [[wikilinks]].
2498 Main author: Erik Möller (moeller@scireview.de)
2500 function formatComment($comment)
2503 $comment = htmlspecialchars( $comment );
2505 # The pattern for autogen comments is / * foo * /, which makes for
2507 # We look for all comments, match any text before and after the comment,
2508 # add a separator where needed and format the comment itself with CSS
2509 while (preg_match('/(.*)\/\*\s*(.*?)\s*\*\/(.*)/', $comment,$match)) {
2514 if($pre) { $auto = $sep.' '.$auto; }
2515 if($post) { $auto .= ' '.$sep; }
2516 $auto='<span class="autocomment">'.$auto.'</span>';
2517 $comment=$pre.$auto.$post;
2520 # format regular and media links - all other wiki formatting
2522 $medians = $wgLang->getNsText(Namespace::getMedia()).':';
2523 while(preg_match('/\[\[(.*?)(\|(.*?))*\]\](.*)$/',$comment,$match)) {
2524 # Handle link renaming [[foo|text]] will show link as "text"
2525 if( "" != $match[3] ) {
2530 if( preg_match( '/^' . $medians . '(.*)$/i', $match[1], $submatch ) ) {
2531 # Media link; trail not supported.
2532 $linkRegexp = '/\[\[(.*?)\]\]/';
2533 $thelink = $this->makeMediaLink( $submatch[1], "", $text );
2535 # Other kind of link
2536 if( preg_match( wfMsg( "linktrail" ), $match[4], $submatch ) ) {
2537 $trail = $submatch[1];
2541 $linkRegexp = '/\[\[(.*?)\]\]' . preg_quote( $trail, '/' ) . '/';
2542 $thelink = $this->makeLink( $match[1], $text, "", $trail );
2544 $comment = preg_replace( $linkRegexp, $thelink, $comment, 1 );
2549 function imageHistoryLine( $iscur, $timestamp, $img, $user, $usertext, $size, $description )
2551 global $wgUser, $wgLang, $wgTitle;
2553 $datetime = $wgLang->timeanddate( $timestamp, true );
2554 $del = wfMsg( 'deleteimg' );
2555 $delall = wfMsg( 'deleteimgcompletely' );
2556 $cur = wfMsg( 'cur' );
2559 $url = Image
::wfImageUrl( $img );
2561 if ( $wgUser->isSysop() ) {
2562 $link = $wgTitle->escapeLocalURL( 'image=' . $wgTitle->getPartialURL() .
2564 $style = $this->getInternalLinkAttributes( $link, $delall );
2566 $dlink = '<a href="'.$link.'"'.$style.'>'.$delall.'</a>';
2571 $url = htmlspecialchars( wfImageArchiveUrl( $img ) );
2572 if( $wgUser->getID() != 0 && $wgTitle->userCanEdit() ) {
2573 $rlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2574 wfMsg( 'revertimg' ), 'action=revert&oldimage=' .
2575 urlencode( $img ) );
2576 $dlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2577 $del, 'action=delete&oldimage=' . urlencode( $img ) );
2579 # Having live active links for non-logged in users
2580 # means that bots and spiders crawling our site can
2581 # inadvertently change content. Baaaad idea.
2582 $rlink = wfMsg( 'revertimg' );
2587 $userlink = $usertext;
2589 $userlink = $this->makeLink( $wgLang->getNsText( Namespace::getUser() ) .
2590 ':'.$usertext, $usertext );
2592 $nbytes = wfMsg( 'nbytes', $size );
2593 $style = $this->getInternalLinkAttributes( $url, $datetime );
2595 $s = "<li> ({$dlink}) ({$rlink}) <a href=\"{$url}\"{$style}>{$datetime}</a>"
2596 . " . . {$userlink} ({$nbytes})";
2598 if ( '' != $description && '*' != $description ) {
2599 $sk=$wgUser->getSkin();
2600 $s .= $wgLang->emphasize(' (' . $sk->formatComment($description) . ')');
2606 function tocIndent($level) {
2607 return str_repeat( '<div class="tocindent">'."\n", $level>0 ?
$level : 0 );
2610 function tocUnindent($level) {
2611 return str_repeat( "</div>\n", $level>0 ?
$level : 0 );
2614 # parameter level defines if we are on an indentation level
2615 function tocLine( $anchor, $tocline, $level ) {
2616 $link = '<a href="#'.$anchor.'">'.$tocline.'</a><br />';
2620 return '<div class="tocline">'.$link."</div>\n";
2625 function tocTable($toc) {
2626 # note to CSS fanatics: putting this in a div does not work -- div won't auto-expand
2627 # try min-width & co when somebody gets a chance
2628 $hideline = ' <script type="text/javascript">showTocToggle("' . addslashes( wfMsg('showtoc') ) . '","' . addslashes( wfMsg('hidetoc') ) . '")</script>';
2630 '<table border="0" id="toc"><tr id="toctitle"><td align="center">'."\n".
2631 '<b>'.wfMsg('toc').'</b>' .
2633 '</td></tr><tr id="tocinside"><td>'."\n".
2634 $toc."</td></tr></table>\n";
2637 # These two do not check for permissions: check $wgTitle->userCanEdit before calling them
2638 function editSectionScript( $section, $head ) {
2639 global $wgTitle, $wgRequest;
2640 if( $wgRequest->getInt( 'oldid' ) && ( $wgRequest->getVal( 'diff' ) != '0' ) ) {
2643 $url = $wgTitle->escapeLocalURL( 'action=edit§ion='.$section );
2644 return '<span oncontextmenu=\'document.location="'.$url.'";return false;\'>'.$head.'</span>';
2647 function editSectionLink( $section ) {
2649 global $wgTitle, $wgUser, $wgLang;
2651 if( $wgRequest->getInt( 'oldid' ) && ( $wgRequest->getVal( 'diff' ) != '0' ) ) {
2652 # Section edit links would be out of sync on an old page.
2653 # But, if we're diffing to the current page, they'll be
2658 $editurl = '§ion='.$section;
2659 $url = $this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg('editsection'),'action=edit'.$editurl);
2661 if( $wgLang->isRTL() ) {
2663 $nearside = 'right';
2668 return "<div class=\"editsection\" style=\"float:$farside;margin-$nearside:5px;\">[".$url."]</div>";
2672 // This function is called by EditPage.php and shows a bulletin board style
2673 // toolbar for common editing functions. It can be disabled in the user preferences.
2674 // The necsesary JavaScript code can be found in style/wikibits.js.
2675 function getEditToolbar() {
2676 global $wgStylePath, $wgLang, $wgMimeType;
2678 // toolarray an array of arrays which each include the filename of
2679 // the button image (without path), the opening tag, the closing tag,
2680 // and optionally a sample text that is inserted between the two when no
2681 // selection is highlighted.
2682 // The tip text is shown when the user moves the mouse over the button.
2684 // Already here are accesskeys (key), which are not used yet until someone
2685 // can figure out a way to make them work in IE. However, we should make
2686 // sure these keys are not defined on the edit page.
2688 array( 'image'=>'button_bold.png',
2691 'sample'=>wfMsg('bold_sample'),
2692 'tip'=>wfMsg('bold_tip'),
2695 array( "image"=>"button_italic.png",
2698 "sample"=>wfMsg("italic_sample"),
2699 "tip"=>wfMsg("italic_tip"),
2702 array( "image"=>"button_link.png",
2705 "sample"=>wfMsg("link_sample"),
2706 "tip"=>wfMsg("link_tip"),
2709 array( "image"=>"button_extlink.png",
2712 "sample"=>wfMsg("extlink_sample"),
2713 "tip"=>wfMsg("extlink_tip"),
2716 array( "image"=>"button_headline.png",
2719 "sample"=>wfMsg("headline_sample"),
2720 "tip"=>wfMsg("headline_tip"),
2723 array( "image"=>"button_image.png",
2724 "open"=>"[[".$wgLang->getNsText(NS_IMAGE
).":",
2726 "sample"=>wfMsg("image_sample"),
2727 "tip"=>wfMsg("image_tip"),
2730 array( "image"=>"button_media.png",
2731 "open"=>"[[".$wgLang->getNsText(NS_MEDIA
).":",
2733 "sample"=>wfMsg("media_sample"),
2734 "tip"=>wfMsg("media_tip"),
2737 array( "image"=>"button_math.png",
2738 "open"=>"\\<math\\>",
2739 "close"=>"\\</math\\>",
2740 "sample"=>wfMsg("math_sample"),
2741 "tip"=>wfMsg("math_tip"),
2744 array( "image"=>"button_nowiki.png",
2745 "open"=>"\\<nowiki\\>",
2746 "close"=>"\\</nowiki\\>",
2747 "sample"=>wfMsg("nowiki_sample"),
2748 "tip"=>wfMsg("nowiki_tip"),
2751 array( "image"=>"button_sig.png",
2755 "tip"=>wfMsg("sig_tip"),
2758 array( "image"=>"button_hr.png",
2759 "open"=>"\\n----\\n",
2762 "tip"=>wfMsg("hr_tip"),
2766 $toolbar ="<script type='text/javascript'>\n/*<![CDATA[*/\n";
2768 $toolbar.="document.writeln(\"<div id='toolbar'>\");\n";
2769 foreach($toolarray as $tool) {
2771 $image=$wgStylePath.'/images/'.$tool['image'];
2772 $open=$tool['open'];
2773 $close=$tool['close'];
2774 $sample = addslashes( $tool['sample'] );
2776 // Note that we use the tip both for the ALT tag and the TITLE tag of the image.
2777 // Older browsers show a "speedtip" type message only for ALT.
2778 // Ideally these should be different, realistically they
2779 // probably don't need to be.
2780 $tip = addslashes( $tool['tip'] );
2782 #$key = $tool["key"];
2784 $toolbar.="addButton('$image','$tip','$open','$close','$sample');\n";
2787 $toolbar.="addInfobox('" . addslashes( wfMsg( "infobox" ) ) . "','" . addslashes(wfMsg("infobox_alert")) . "');\n";
2788 $toolbar.="document.writeln(\"</div>\");\n";
2790 $toolbar.="/*]]>*/\n</script>";
2794 /* public */ function suppressUrlExpansion() {