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;
1585 return "<!-- ERROR -->{$prefix}{$text}{$trail}";
1587 $fname = 'Skin::makeBrokenLinkObj';
1588 wfProfileIn( $fname );
1590 if ( '' == $query ) {
1593 $q = 'action=edit&'.$query;
1595 $u = $nt->escapeLocalURL( $q );
1597 if ( '' == $text ) {
1598 $text = htmlspecialchars( $nt->getPrefixedText() );
1600 $style = $this->getInternalLinkAttributesObj( $nt, $text, "yes" );
1603 if ( '' != $trail ) {
1604 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1609 if ( $wgUser->getOption( 'highlightbroken' ) ) {
1610 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1612 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>?</a>{$trail}";
1615 wfProfileOut( $fname );
1619 # Pass a title object, not a title string
1620 function makeStubLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
1622 global $wgOut, $wgUser;
1624 $link = $nt->getPrefixedURL();
1626 $u = $nt->escapeLocalURL( $query );
1628 if ( '' == $text ) {
1629 $text = htmlspecialchars( $nt->getPrefixedText() );
1631 $style = $this->getInternalLinkAttributesObj( $nt, $text, 'stub' );
1634 if ( '' != $trail ) {
1635 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1640 if ( $wgUser->getOption( 'highlightbroken' ) ) {
1641 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1643 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>!</a>{$trail}";
1648 function makeSelfLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
1650 $u = $nt->escapeLocalURL( $query );
1651 if ( '' == $text ) {
1652 $text = htmlspecialchars( $nt->getPrefixedText() );
1655 if ( '' != $trail ) {
1656 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1661 return "<strong>{$prefix}{$text}{$inside}</strong>{$trail}";
1664 /* these are used extensively in SkinPHPTal, but also some other places */
1665 /*static*/ function makeSpecialUrl( $name, $urlaction='' ) {
1666 $title = Title
::makeTitle( NS_SPECIAL
, $name );
1667 $this->checkTitle($title, $name);
1668 return $title->getLocalURL( $urlaction );
1670 /*static*/ function makeTalkUrl ( $name, $urlaction='' ) {
1671 $title = Title
::newFromText( $name );
1672 $title = $title->getTalkPage();
1673 $this->checkTitle($title, $name);
1674 return $title->getLocalURL( $urlaction );
1676 /*static*/ function makeArticleUrl ( $name, $urlaction='' ) {
1677 $title = Title
::newFromText( $name );
1678 $title= $title->getSubjectPage();
1679 $this->checkTitle($title, $name);
1680 return $title->getLocalURL( $urlaction );
1682 /*static*/ function makeI18nUrl ( $name, $urlaction='' ) {
1683 $title = Title
::newFromText( wfMsg($name) );
1684 $this->checkTitle($title, $name);
1685 return $title->getLocalURL( $urlaction );
1687 /*static*/ function makeUrl ( $name, $urlaction='' ) {
1688 $title = Title
::newFromText( $name );
1689 $this->checkTitle($title, $name);
1690 return $title->getLocalURL( $urlaction );
1692 # this can be passed the NS number as defined in Language.php
1693 /*static*/ function makeNSUrl( $name, $urlaction='', $namespace=0 ) {
1694 $title = Title
::makeTitle( $namespace, $name );
1695 $this->checkTitle($title, $name);
1696 return $title->getLocalURL( $urlaction );
1699 /* these return an array with the 'href' and boolean 'exists' */
1700 /*static*/ function makeUrlDetails ( $name, $urlaction='' ) {
1701 $title = Title
::newFromText( $name );
1702 $this->checkTitle($title, $name);
1704 'href' => $title->getLocalURL( $urlaction ),
1705 'exists' => $title->getArticleID() != 0?
true:false
1708 /*static*/ function makeTalkUrlDetails ( $name, $urlaction='' ) {
1709 $title = Title
::newFromText( $name );
1710 $title = $title->getTalkPage();
1711 $this->checkTitle($title, $name);
1713 'href' => $title->getLocalURL( $urlaction ),
1714 'exists' => $title->getArticleID() != 0?
true:false
1717 /*static*/ function makeArticleUrlDetails ( $name, $urlaction='' ) {
1718 $title = Title
::newFromText( $name );
1719 $title= $title->getSubjectPage();
1720 $this->checkTitle($title, $name);
1722 'href' => $title->getLocalURL( $urlaction ),
1723 'exists' => $title->getArticleID() != 0?
true:false
1726 /*static*/ function makeI18nUrlDetails ( $name, $urlaction='' ) {
1727 $title = Title
::newFromText( wfMsg($name) );
1728 $this->checkTitle($title, $name);
1730 'href' => $title->getLocalURL( $urlaction ),
1731 'exists' => $title->getArticleID() != 0?
true:false
1735 # make sure we have some title to operate on
1736 /*static*/ function checkTitle ( &$title, &$name ) {
1737 if(!is_object($title)) {
1738 $title = Title
::newFromText( $name );
1739 if(!is_object($title)) {
1740 $title = Title
::newFromText( '--error: link target missing--' );
1745 function fnamePart( $url )
1747 $basename = strrchr( $url, '/' );
1748 if ( false === $basename ) {
1751 $basename = substr( $basename, 1 );
1753 return htmlspecialchars( $basename );
1756 function makeImage( $url, $alt = '' )
1761 $alt = $this->fnamePart( $url );
1763 $s = '<img src="'.$url.'" alt="'.$alt.'" />';
1767 function makeImageLink( $name, $url, $alt = '' ) {
1768 $nt = Title
::makeTitle( Namespace::getImage(), $name );
1769 return $this->makeImageLinkObj( $nt, $alt );
1772 function makeImageLinkObj( $nt, $alt = '' ) {
1773 global $wgLang, $wgUseImageResize;
1774 $img = Image
::newFromTitle( $nt );
1775 $url = $img->getURL();
1778 $prefix = $postfix = '';
1780 if ( $wgUseImageResize ) {
1781 # Check if the alt text is of the form "options|alt text"
1783 # * thumbnail make a thumbnail with enlarge-icon and caption, alignment depends on lang
1784 # * left no resizing, just left align. label is used for alt= only
1785 # * right same, but right aligned
1786 # * none same, but not aligned
1787 # * ___px scale to ___ pixels width, no aligning. e.g. use in taxobox
1788 # * center center the image
1789 # * framed Keep original image size, no magnify-button.
1791 $part = explode( '|', $alt);
1793 $mwThumb =& MagicWord
::get( MAG_IMG_THUMBNAIL
);
1794 $mwLeft =& MagicWord
::get( MAG_IMG_LEFT
);
1795 $mwRight =& MagicWord
::get( MAG_IMG_RIGHT
);
1796 $mwNone =& MagicWord
::get( MAG_IMG_NONE
);
1797 $mwWidth =& MagicWord
::get( MAG_IMG_WIDTH
);
1798 $mwCenter =& MagicWord
::get( MAG_IMG_CENTER
);
1799 $mwFramed =& MagicWord
::get( MAG_IMG_FRAMED
);
1800 $alt = $part[count($part)-1];
1802 $height = $framed = $thumb = false;
1803 $manual_thumb = "" ;
1805 foreach( $part as $key => $val ) {
1806 $val_parts = explode ( "=" , $val , 2 ) ;
1807 $left_part = array_shift ( $val_parts ) ;
1808 if ( ! is_null( $mwThumb->matchVariableStartToEnd($val) ) ) {
1810 } elseif ( count ( $val_parts ) == 1 && ! is_null( $mwThumb->matchVariableStartToEnd($left_part) ) ) {
1811 # use manually specified thumbnail
1813 $manual_thumb = array_shift ( $val_parts ) ;
1814 } elseif ( ! is_null( $mwRight->matchVariableStartToEnd($val) ) ) {
1815 # remember to set an alignment, don't render immediately
1817 } elseif ( ! is_null( $mwLeft->matchVariableStartToEnd($val) ) ) {
1818 # remember to set an alignment, don't render immediately
1820 } elseif ( ! is_null( $mwCenter->matchVariableStartToEnd($val) ) ) {
1821 # remember to set an alignment, don't render immediately
1823 } elseif ( ! is_null( $mwNone->matchVariableStartToEnd($val) ) ) {
1824 # remember to set an alignment, don't render immediately
1826 } elseif ( ! is_null( $match = $mwWidth->matchVariableStartToEnd($val) ) ) {
1827 # $match is the image width in pixels
1828 if ( preg_match( '/^([0-9]*)x([0-9]*)$/', $match, $m ) ) {
1829 $width = intval( $m[1] );
1830 $height = intval( $m[2] );
1832 $width = intval($match);
1834 } elseif ( ! is_null( $mwFramed->matchVariableStartToEnd($val) ) ) {
1838 if ( 'center' == $align )
1840 $prefix = '<span style="text-align: center">';
1841 $postfix = '</span>';
1845 if ( $thumb ||
$framed ) {
1847 # Create a thumbnail. Alignment depends on language
1848 # writing direction, # right aligned for left-to-right-
1849 # languages ("Western languages"), left-aligned
1850 # for right-to-left-languages ("Semitic languages")
1852 # If thumbnail width has not been provided, it is set
1853 # here to 180 pixels
1854 if ( $align == '' ) {
1855 $align = $wgLang->isRTL() ?
'left' : 'right';
1857 if ( ! isset($width) ) {
1860 return $prefix.$this->makeThumbLinkObj( $img, $alt, $align, $width, $height, $framed, $manual_thumb ).$postfix;
1862 } elseif ( isset($width) ) {
1864 # Create a resized image, without the additional thumbnail
1867 if ( ( ! $height === false )
1868 && ( $img->getHeight() * $width / $img->getWidth() > $height ) ) {
1869 print "height=$height<br>\nimg->getHeight() = ".$img->getHeight()."<br>\n";
1870 print 'rescaling by factor '. $height / $img->getHeight() . "<br>\n";
1871 $width = $img->getWidth() * $height / $img->getHeight();
1873 if ( '' == $manual_thumb ) $url = $img->createThumb( $width );
1875 } # endif $wgUseImageResize
1877 if ( empty( $alt ) ) {
1878 $alt = preg_replace( '/\.(.+?)^/', '', $img->getName() );
1880 $alt = htmlspecialchars( $alt );
1882 $u = $nt->escapeLocalURL();
1885 $s = wfMsg( 'missingimage', $img->getName() );
1886 $s .= "<br>{$alt}<br>{$url}<br>\n";
1888 $s = '<a href="'.$u.'" class="image" title="'.$alt.'">' .
1889 '<img src="'.$url.'" alt="'.$alt.'" /></a>';
1891 if ( '' != $align ) {
1892 $s = "<div class=\"float{$align}\"><span>{$s}</span></div>";
1894 return str_replace("\n", ' ',$prefix.$s.$postfix);
1897 # Make HTML for a thumbnail including image, border and caption
1898 # $img is an Image object
1899 function makeThumbLinkObj( $img, $label = '', $align = 'right', $boxwidth = 180, $boxheight=false, $framed=false , $manual_thumb = "" ) {
1900 global $wgStylePath, $wgLang;
1901 # $image = Title::makeTitle( Namespace::getImage(), $name );
1902 $url = $img->getURL();
1904 #$label = htmlspecialchars( $label );
1905 $alt = preg_replace( '/<[^>]*>/', '', $label);
1906 $alt = htmlspecialchars( $alt );
1908 $width = $height = 0;
1909 if ( $img->exists() )
1911 $width = $img->getWidth();
1912 $height = $img->getHeight();
1914 if ( 0 == $width ||
0 == $height )
1916 $width = $height = 200;
1918 if ( $boxwidth == 0 )
1924 // Use image dimensions, don't scale
1926 $oboxwidth = $boxwidth +
2;
1927 $boxheight = $height;
1930 $h = intval( $height/($width/$boxwidth) );
1931 $oboxwidth = $boxwidth +
2;
1932 if ( ( ! $boxheight === false ) && ( $h > $boxheight ) )
1934 $boxwidth *= $boxheight/$h;
1938 if ( '' == $manual_thumb ) $thumbUrl = $img->createThumb( $boxwidth );
1941 if ( $manual_thumb != '' ) # Use manually specified thumbnail
1943 $manual_title = Title
::makeTitle( Namespace::getImage(), $manual_thumb ); #new Title ( $manual_thumb ) ;
1944 $manual_img = Image
::newFromTitle( $manual_title );
1945 $thumbUrl = $manual_img->getURL();
1946 if ( $manual_img->exists() )
1948 $width = $manual_img->getWidth();
1949 $height = $manual_img->getHeight();
1950 $boxwidth = $width ;
1951 $boxheight = $height ;
1952 $oboxwidth = $boxwidth +
2 ;
1956 $u = $img->getEscapeLocalURL();
1958 $more = htmlspecialchars( wfMsg( 'thumbnail-more' ) );
1959 $magnifyalign = $wgLang->isRTL() ?
'left' : 'right';
1960 $textalign = $wgLang->isRTL() ?
' style="text-align:right"' : '';
1962 $s = "<div class=\"thumb t{$align}\"><div style=\"width:{$oboxwidth}px;\">";
1963 if ( $thumbUrl == '' ) {
1964 $s .= wfMsg( 'missingimage', $img->getName() );
1967 $s .= '<a href="'.$u.'" class="internal" title="'.$alt.'">'.
1968 '<img src="'.$thumbUrl.'" alt="'.$alt.'" ' .
1969 'width="'.$boxwidth.'" height="'.$boxheight.'" /></a>';
1973 $zoomicon = '<div class="magnify" style="float:'.$magnifyalign.'">'.
1974 '<a href="'.$u.'" class="internal" title="'.$more.'">'.
1975 '<img src="'.$wgStylePath.'/images/magnify-clip.png" ' .
1976 'width="15" height="11" alt="'.$more.'" /></a></div>';
1979 $s .= ' <div class="thumbcaption" '.$textalign.'>'.$zoomicon.$label."</div></div></div>";
1980 return str_replace("\n", ' ', $s);
1983 function makeMediaLink( $name, $url, $alt = "" ) {
1984 $nt = Title
::makeTitle( Namespace::getMedia(), $name );
1985 return $this->makeMediaLinkObj( $nt, $alt );
1988 function makeMediaLinkObj( $nt, $alt = "" )
1990 if ( ! isset( $nt ) )
1992 ### HOTFIX. Instead of breaking, return empty string.
1995 $name = $nt->getDBKey();
1996 $url = Image
::wfImageUrl( $name );
1997 if ( empty( $alt ) ) {
1998 $alt = preg_replace( '/\.(.+?)^/', '', $name );
2001 $u = htmlspecialchars( $url );
2002 $s = "<a href=\"{$u}\" class='internal' title=\"{$alt}\">{$alt}</a>";
2007 function specialLink( $name, $key = "" )
2011 if ( '' == $key ) { $key = strtolower( $name ); }
2012 $pn = $wgLang->ucfirst( $name );
2013 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
2017 function makeExternalLink( $url, $text, $escape = true ) {
2018 $style = $this->getExternalLinkAttributes( $url, $text );
2019 $url = htmlspecialchars( $url );
2021 $text = htmlspecialchars( $text );
2023 return '<a href="'.$url.'"'.$style.'>'.$text.'</a>';
2026 # Called by history lists and recent changes
2029 # Returns text for the start of the tabular part of RC
2030 function beginRecentChangesList()
2032 $this->rc_cache
= array() ;
2033 $this->rcMoveIndex
= 0;
2034 $this->rcCacheIndex
= 0 ;
2035 $this->lastdate
= '';
2036 $this->rclistOpen
= false;
2040 function beginImageHistoryList()
2042 $s = "\n<h2>" . wfMsg( 'imghistory' ) . "</h2>\n" .
2043 "<p>" . wfMsg( 'imghistlegend' ) . "</p>\n".'<ul class="special">';
2047 # Returns text for the end of RC
2048 # If enhanced RC is in use, returns pretty much all the text
2049 function endRecentChangesList()
2051 $s = $this->recentChangesBlock() ;
2052 if( $this->rclistOpen
) {
2058 # Enhanced RC ungrouped line
2059 function recentChangesBlockLine ( $rcObj )
2061 global $wgStylePath, $wgLang ;
2063 # Get rc_xxxx variables
2064 extract( $rcObj->mAttribs
) ;
2065 $curIdEq = 'curid='.$rc_cur_id;
2070 $r .= '<img src="'.$wgStylePath.'/images/Arr_.png" width="12" height="12" border="0" />' ;
2073 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2074 $r .= ' ';
2076 # M & N (minor & new)
2077 $M = wfMsg( 'minoreditletter' );
2078 $N = wfMsg( 'newpageletter' );
2080 if ( $rc_type == RC_NEW
) {
2093 $r .= ' '.$rcObj->timestamp
.' ' ;
2097 $link = $rcObj->link
;
2098 if ( $rcObj->watched
) $link = '<strong>'.$link.'</strong>' ;
2103 $r .= $rcObj->difflink
;
2107 $r .= $this->makeKnownLinkObj( $rcObj->getTitle(), wfMsg( 'hist' ), $curIdEq.'&action=history' );
2110 $r .= ') . . '.$rcObj->userlink
;
2111 $r .= $rcObj->usertalklink
;
2114 if ( $rc_comment != '' && $rc_type != RC_MOVE
&& $rc_type != RC_MOVE_OVER_REDIRECT
) {
2115 $rc_comment=$this->formatComment($rc_comment);
2116 $r .= $wgLang->emphasize( ' ('.$rc_comment.')' );
2124 function recentChangesBlockGroup ( $block )
2126 global $wgStylePath, $wgLang ;
2129 $M = wfMsg( 'minoreditletter' );
2130 $N = wfMsg( 'newpageletter' );
2132 # Collate list of users
2134 $userlinks = array () ;
2135 foreach ( $block AS $rcObj ) {
2136 $oldid = $rcObj->mAttribs
['rc_last_oldid'];
2137 if ( $rcObj->mAttribs
['rc_new'] ) $isnew = true ;
2138 $u = $rcObj->userlink
;
2139 if ( !isset ( $userlinks[$u] ) ) $userlinks[$u] = 0 ;
2143 # Sort the list and convert to text
2144 krsort ( $userlinks ) ;
2145 asort ( $userlinks ) ;
2147 foreach ( $userlinks as $userlink => $count) {
2149 if ( $count > 1 ) $text .= " ({$count}×)" ;
2150 array_push ( $users , $text ) ;
2152 $users = ' <font size="-1">['.implode('; ',$users).']</font>' ;
2155 $rci = 'RCI'.$this->rcCacheIndex
;
2156 $rcl = 'RCL'.$this->rcCacheIndex
;
2157 $rcm = 'RCM'.$this->rcCacheIndex
;
2158 $toggleLink = "javascript:toggleVisibility('$rci','$rcm','$rcl')" ;
2159 $arrowdir = $wgLang->isRTL() ?
'l' : 'r';
2160 $tl = '<span id="'.$rcm.'"><a href="'.$toggleLink.'"><img src="'.$wgStylePath.'/images/Arr_'.$arrowdir.'.png" width="12" height="12" /></a></span>' ;
2161 $tl .= '<span id="'.$rcl.'" style="display:none"><a href="'.$toggleLink.'"><img src="'.$wgStylePath.'/images/Arr_d.png" width="12" height="12" /></a></span>' ;
2167 if ( $isnew ) $r .= $N ;
2168 else $r .= ' ' ;
2169 $r .= ' ' ; # Minor
2172 $r .= ' '.$block[0]->timestamp
.' ' ;
2176 $link = $block[0]->link
;
2177 if ( $block[0]->watched
) $link = '<strong>'.$link.'</strong>' ;
2180 $curIdEq = 'curid=' . $block[0]->mAttribs
['rc_cur_id'];
2181 if ( $block[0]->mAttribs
['rc_type'] != RC_LOG
) {
2183 $r .= ' ('.count($block).' ' ;
2184 if ( $isnew ) $r .= wfMsg('changes');
2185 else $r .= $this->makeKnownLinkObj( $block[0]->getTitle() , wfMsg('changes') ,
2186 $curIdEq.'&diff=0&oldid='.$oldid ) ;
2190 $r .= $this->makeKnownLinkObj( $block[0]->getTitle(), wfMsg( 'history' ), $curIdEq.'&action=history' );
2198 $r .= '<div id="'.$rci.'" style="display:none">' ;
2199 foreach ( $block AS $rcObj ) {
2200 # Get rc_xxxx variables
2201 extract( $rcObj->mAttribs
);
2203 $r .= '<img src="'.$wgStylePath.'/images/Arr_.png" width="12" height="12" />';
2204 $r .= '<tt> ' ;
2205 if ( $rc_new ) $r .= $N ;
2206 else $r .= ' ' ;
2207 if ( $rc_minor ) $r .= $M ;
2208 else $r .= ' ' ;
2212 if ( $rc_last_oldid != 0 ) {
2213 $o = 'oldid='.$rc_last_oldid ;
2215 if ( $rc_type == RC_LOG
) {
2216 $link = $rcObj->timestamp
;
2218 $link = $this->makeKnownLinkObj( $rcObj->getTitle(), $rcObj->timestamp
, "{$curIdEq}&$o" ) ;
2220 $link = '<tt>'.$link.'</tt>' ;
2224 $r .= $rcObj->curlink
;
2226 $r .= $rcObj->lastlink
;
2227 $r .= ') . . '.$rcObj->userlink
;
2228 $r .= $rcObj->usertalklink
;
2229 if ( $rc_comment != '' ) {
2230 $rc_comment=$this->formatComment($rc_comment);
2231 $r .= $wgLang->emphasize( ' ('.$rc_comment.')' ) ;
2237 $this->rcCacheIndex++
;
2241 # If enhanced RC is in use, this function takes the previously cached
2242 # RC lines, arranges them, and outputs the HTML
2243 function recentChangesBlock ()
2245 global $wgStylePath ;
2246 if ( count ( $this->rc_cache
) == 0 ) return '' ;
2248 foreach ( $this->rc_cache
AS $secureName => $block ) {
2249 if ( count ( $block ) < 2 ) {
2250 $blockOut .= $this->recentChangesBlockLine ( array_shift ( $block ) ) ;
2252 $blockOut .= $this->recentChangesBlockGroup ( $block ) ;
2256 return '<div>'.$blockOut.'</div>' ;
2259 # Called in a loop over all displayed RC entries
2260 # Either returns the line, or caches it for later use
2261 function recentChangesLine( &$rc, $watched = false )
2264 $usenew = $wgUser->getOption( 'usenewrc' );
2266 $line = $this->recentChangesLineNew ( $rc, $watched ) ;
2268 $line = $this->recentChangesLineOld ( $rc, $watched ) ;
2272 function recentChangesLineOld( &$rc, $watched = false )
2274 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds, $wgUseRCPatrol, $wgOnlySysopsCanPatrol;
2276 # Extract DB fields into local scope
2277 extract( $rc->mAttribs
);
2278 $curIdEq = 'curid=' . $rc_cur_id;
2280 # Make date header if necessary
2281 $date = $wgLang->date( $rc_timestamp, true);
2283 if ( $date != $this->lastdate
) {
2284 if ( '' != $this->lastdate
) { $s .= "</ul>\n"; }
2285 $s .= "<h4>{$date}</h4>\n<ul class='special'>";
2286 $this->lastdate
= $date;
2287 $this->rclistOpen
= true;
2290 # If this edit has not yet been patrolled, make it stick out
2291 $s .= ( ! $wgUseRCPatrol ||
$rc_patrolled ) ?
'<li> ' : '<li class="not_patrolled"> ';
2293 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2295 $s .= '(' . wfMsg( 'diff' ) . ') (';
2297 $s .= $this->makeKnownLinkObj( $rc->getMovedToTitle(), wfMsg( 'hist' ), 'action=history' ) .
2300 # "[[x]] moved to [[y]]"
2301 $msg = ( $rc_type == RC_MOVE
) ?
'1movedto2' : '1movedto2_redir';
2302 $s .= wfMsg( $msg, $this->makeKnownLinkObj( $rc->getTitle(), '', 'redirect=no' ),
2303 $this->makeKnownLinkObj( $rc->getMovedToTitle(), '' ) );
2306 if ( $rc_type == RC_NEW ||
$rc_type == RC_LOG
) {
2307 $diffLink = wfMsg( 'diff' );
2309 if ( $wgUseRCPatrol && $rc_patrolled == 0 && $wgUser->getID() != 0 &&
2310 ( $wgUser->isSysop() ||
!$wgOnlySysopsCanPatrol ) )
2311 $rcidparam = "&rcid={$rc_id}";
2314 $diffLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'diff' ),
2315 "{$curIdEq}&diff={$rc_this_oldid}&oldid={$rc_last_oldid}{$rcidparam}",
2316 '', '', ' tabindex="'.$rc->counter
.'"');
2318 $s .= '('.$diffLink.') (';
2321 $s .= $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'hist' ), $curIdEq.'&action=history' );
2324 # M and N (minor and new)
2325 if ( $rc_minor ) { $s .= ' <span class="minor">'.wfMsg( "minoreditletter" ).'</span>'; }
2326 if ( $rc_type == RC_NEW
) { $s .= '<span class="newpage">'.wfMsg( "newpageletter" ).'</span>'; }
2329 # If it's a new article, there is no diff link, but if it hasn't been
2330 # patrolled yet, we need to give users a way to do so
2331 if ( $wgUseRCPatrol && $rc_type == RC_NEW
&& $rc_patrolled == 0 &&
2332 $wgUser->getID() != 0 && ( $wgUser->isSysop() ||
!$wgOnlySysopsCanPatrol ) )
2333 $articleLink = $this->makeKnownLinkObj( $rc->getTitle(), '', "rcid={$rc_id}" );
2335 $articleLink = $this->makeKnownLinkObj( $rc->getTitle(), '' );
2338 $articleLink = '<strong>'.$articleLink.'</strong>';
2340 $s .= ' '.$articleLink;
2345 $s .= '; ' . $wgLang->time( $rc_timestamp, true, $wgRCSeconds ) . ' . . ';
2347 # User link (or contributions for unregistered users)
2348 if ( 0 == $rc_user ) {
2349 $userLink = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
2350 $rc_user_text, 'target=' . $rc_user_text );
2352 $userLink = $this->makeLink( $wgLang->getNsText( NS_USER
) . ':'.$rc_user_text, $rc_user_text );
2357 $talkname=$wgLang->getNsText(NS_TALK
); # use the shorter name
2358 global $wgDisableAnonTalk;
2359 if( 0 == $rc_user && $wgDisableAnonTalk ) {
2362 $utns=$wgLang->getNsText(NS_USER_TALK
);
2363 $userTalkLink= $this->makeLink($utns . ':'.$rc_user_text, $talkname );
2367 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2368 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2369 'Blockip' ), wfMsg( 'blocklink' ), 'ip='.$rc_user_text );
2373 if($userTalkLink) $userTalkLink .= ' | ';
2374 $userTalkLink .= $blockLink;
2376 if($userTalkLink) $s.=' ('.$userTalkLink.')';
2379 if ( '' != $rc_comment && '*' != $rc_comment && $rc_type != RC_MOVE
&& $rc_type != RC_MOVE_OVER_REDIRECT
) {
2380 $rc_comment=$this->formatComment($rc_comment);
2381 $s .= $wgLang->emphasize(' (' . $rc_comment . ')');
2388 function recentChangesLineNew( &$baseRC, $watched = false )
2390 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds;
2392 # Create a specialised object
2393 $rc = RCCacheEntry
::newFromParent( $baseRC ) ;
2395 # Extract fields from DB into the function scope (rc_xxxx variables)
2396 extract( $rc->mAttribs
);
2397 $curIdEq = 'curid=' . $rc_cur_id;
2399 # If it's a new day, add the headline and flush the cache
2400 $date = $wgLang->date( $rc_timestamp, true);
2402 if ( $date != $this->lastdate
) {
2403 # Process current cache
2404 $ret = $this->recentChangesBlock () ;
2405 $this->rc_cache
= array() ;
2406 $ret .= "<h4>{$date}</h4>\n";
2407 $this->lastdate
= $date;
2411 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2412 $msg = ( $rc_type == RC_MOVE
) ?
"1movedto2" : "1movedto2_redir";
2413 $clink = wfMsg( $msg, $this->makeKnownLinkObj( $rc->getTitle(), '', 'redirect=no' ),
2414 $this->makeKnownLinkObj( $rc->getMovedToTitle(), '' ) );
2416 $clink = $this->makeKnownLinkObj( $rc->getTitle(), '' ) ;
2419 $time = $wgLang->time( $rc_timestamp, true, $wgRCSeconds );
2420 $rc->watched
= $watched ;
2421 $rc->link
= $clink ;
2422 $rc->timestamp
= $time;
2424 # Make "cur" and "diff" links
2425 if ( ( $rc_type == RC_NEW
&& $rc_this_oldid == 0 ) ||
$rc_type == RC_LOG ||
$rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2426 $curLink = wfMsg( 'cur' );
2427 $diffLink = wfMsg( 'diff' );
2429 $query = $curIdEq.'&diff=0&oldid='.$rc_this_oldid;
2430 $aprops = ' tabindex="'.$baseRC->counter
.'"';
2431 $curLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'cur' ), $query, '' ,'' , $aprops );
2432 $diffLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'diff'), $query, '' ,'' , $aprops );
2436 $titleObj = $rc->getTitle();
2437 if ( $rc_last_oldid == 0 ||
$rc_type == RC_LOG ||
$rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2438 $lastLink = wfMsg( 'last' );
2440 $lastLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'last' ),
2441 $curIdEq.'&diff='.$rc_this_oldid.'&oldid='.$rc_last_oldid );
2444 # Make user link (or user contributions for unregistered users)
2445 if ( $rc_user == 0 ) {
2446 $userLink = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
2447 $rc_user_text, 'target=' . $rc_user_text );
2449 $userLink = $this->makeLink( $wgLang->getNsText(
2450 Namespace::getUser() ) . ':'.$rc_user_text, $rc_user_text );
2453 $rc->userlink
= $userLink;
2454 $rc->lastlink
= $lastLink;
2455 $rc->curlink
= $curLink;
2456 $rc->difflink
= $diffLink;
2458 # Make user talk link
2459 $utns=$wgLang->getNsText(NS_USER_TALK
);
2460 $talkname=$wgLang->getNsText(NS_TALK
); # use the shorter name
2461 $userTalkLink= $this->makeLink($utns . ':'.$rc_user_text, $talkname );
2463 global $wgDisableAnonTalk;
2464 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2465 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2466 'Blockip' ), wfMsg( 'blocklink' ), 'ip='.$rc_user_text );
2467 if( $wgDisableAnonTalk )
2468 $rc->usertalklink
= ' ('.$blockLink.')';
2470 $rc->usertalklink
= ' ('.$userTalkLink.' | '.$blockLink.')';
2472 if( $wgDisableAnonTalk && ($rc_user == 0) )
2473 $rc->usertalklink
= '';
2475 $rc->usertalklink
= ' ('.$userTalkLink.')';
2478 # Put accumulated information into the cache, for later display
2479 # Page moves go on their own line
2480 $title = $rc->getTitle();
2481 $secureName = $title->getPrefixedDBkey();
2482 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2483 # Use an @ character to prevent collision with page names
2484 $this->rc_cache
['@@' . ($this->rcMoveIndex++
)] = array($rc);
2486 if ( !isset ( $this->rc_cache
[$secureName] ) ) $this->rc_cache
[$secureName] = array() ;
2487 array_push ( $this->rc_cache
[$secureName] , $rc ) ;
2492 function endImageHistoryList()
2498 /* This function is called by all recent changes variants, by the page history,
2499 and by the user contributions list. It is responsible for formatting edit
2500 comments. It escapes any HTML in the comment, but adds some CSS to format
2501 auto-generated comments (from section editing) and formats [[wikilinks]].
2502 Main author: Erik Möller (moeller@scireview.de)
2504 function formatComment($comment)
2507 $comment = htmlspecialchars( $comment );
2509 # The pattern for autogen comments is / * foo * /, which makes for
2511 # We look for all comments, match any text before and after the comment,
2512 # add a separator where needed and format the comment itself with CSS
2513 while (preg_match('/(.*)\/\*\s*(.*?)\s*\*\/(.*)/', $comment,$match)) {
2518 if($pre) { $auto = $sep.' '.$auto; }
2519 if($post) { $auto .= ' '.$sep; }
2520 $auto='<span class="autocomment">'.$auto.'</span>';
2521 $comment=$pre.$auto.$post;
2524 # format regular and media links - all other wiki formatting
2526 $medians = $wgLang->getNsText(Namespace::getMedia()).':';
2527 while(preg_match('/\[\[(.*?)(\|(.*?))*\]\](.*)$/',$comment,$match)) {
2528 # Handle link renaming [[foo|text]] will show link as "text"
2529 if( "" != $match[3] ) {
2534 if( preg_match( '/^' . $medians . '(.*)$/i', $match[1], $submatch ) ) {
2535 # Media link; trail not supported.
2536 $linkRegexp = '/\[\[(.*?)\]\]/';
2537 $thelink = $this->makeMediaLink( $submatch[1], "", $text );
2539 # Other kind of link
2540 if( preg_match( wfMsg( "linktrail" ), $match[4], $submatch ) ) {
2541 $trail = $submatch[1];
2545 $linkRegexp = '/\[\[(.*?)\]\]' . preg_quote( $trail, '/' ) . '/';
2546 $thelink = $this->makeLink( $match[1], $text, "", $trail );
2548 $comment = preg_replace( $linkRegexp, $thelink, $comment, 1 );
2553 function imageHistoryLine( $iscur, $timestamp, $img, $user, $usertext, $size, $description )
2555 global $wgUser, $wgLang, $wgTitle;
2557 $datetime = $wgLang->timeanddate( $timestamp, true );
2558 $del = wfMsg( 'deleteimg' );
2559 $delall = wfMsg( 'deleteimgcompletely' );
2560 $cur = wfMsg( 'cur' );
2563 $url = Image
::wfImageUrl( $img );
2565 if ( $wgUser->isSysop() ) {
2566 $link = $wgTitle->escapeLocalURL( 'image=' . $wgTitle->getPartialURL() .
2568 $style = $this->getInternalLinkAttributes( $link, $delall );
2570 $dlink = '<a href="'.$link.'"'.$style.'>'.$delall.'</a>';
2575 $url = htmlspecialchars( wfImageArchiveUrl( $img ) );
2576 if( $wgUser->getID() != 0 && $wgTitle->userCanEdit() ) {
2577 $rlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2578 wfMsg( 'revertimg' ), 'action=revert&oldimage=' .
2579 urlencode( $img ) );
2580 $dlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2581 $del, 'action=delete&oldimage=' . urlencode( $img ) );
2583 # Having live active links for non-logged in users
2584 # means that bots and spiders crawling our site can
2585 # inadvertently change content. Baaaad idea.
2586 $rlink = wfMsg( 'revertimg' );
2591 $userlink = $usertext;
2593 $userlink = $this->makeLink( $wgLang->getNsText( Namespace::getUser() ) .
2594 ':'.$usertext, $usertext );
2596 $nbytes = wfMsg( 'nbytes', $size );
2597 $style = $this->getInternalLinkAttributes( $url, $datetime );
2599 $s = "<li> ({$dlink}) ({$rlink}) <a href=\"{$url}\"{$style}>{$datetime}</a>"
2600 . " . . {$userlink} ({$nbytes})";
2602 if ( '' != $description && '*' != $description ) {
2603 $sk=$wgUser->getSkin();
2604 $s .= $wgLang->emphasize(' (' . $sk->formatComment($description) . ')');
2610 function tocIndent($level) {
2611 return str_repeat( '<div class="tocindent">'."\n", $level>0 ?
$level : 0 );
2614 function tocUnindent($level) {
2615 return str_repeat( "</div>\n", $level>0 ?
$level : 0 );
2618 # parameter level defines if we are on an indentation level
2619 function tocLine( $anchor, $tocline, $level ) {
2620 $link = '<a href="#'.$anchor.'">'.$tocline.'</a><br />';
2624 return '<div class="tocline">'.$link."</div>\n";
2629 function tocTable($toc) {
2630 # note to CSS fanatics: putting this in a div does not work -- div won't auto-expand
2631 # try min-width & co when somebody gets a chance
2632 $hideline = ' <script type="text/javascript">showTocToggle("' . addslashes( wfMsg('showtoc') ) . '","' . addslashes( wfMsg('hidetoc') ) . '")</script>';
2634 '<table border="0" id="toc"><tr id="toctitle"><td align="center">'."\n".
2635 '<b>'.wfMsg('toc').'</b>' .
2637 '</td></tr><tr id="tocinside"><td>'."\n".
2638 $toc."</td></tr></table>\n";
2641 # These two do not check for permissions: check $wgTitle->userCanEdit before calling them
2642 function editSectionScript( $section, $head ) {
2643 global $wgTitle, $wgRequest;
2644 if( $wgRequest->getInt( 'oldid' ) && ( $wgRequest->getVal( 'diff' ) != '0' ) ) {
2647 $url = $wgTitle->escapeLocalURL( 'action=edit§ion='.$section );
2648 return '<span oncontextmenu=\'document.location="'.$url.'";return false;\'>'.$head.'</span>';
2651 function editSectionLink( $section ) {
2653 global $wgTitle, $wgUser, $wgLang;
2655 if( $wgRequest->getInt( 'oldid' ) && ( $wgRequest->getVal( 'diff' ) != '0' ) ) {
2656 # Section edit links would be out of sync on an old page.
2657 # But, if we're diffing to the current page, they'll be
2662 $editurl = '§ion='.$section;
2663 $url = $this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg('editsection'),'action=edit'.$editurl);
2665 if( $wgLang->isRTL() ) {
2667 $nearside = 'right';
2672 return "<div class=\"editsection\" style=\"float:$farside;margin-$nearside:5px;\">[".$url."]</div>";
2676 // This function is called by EditPage.php and shows a bulletin board style
2677 // toolbar for common editing functions. It can be disabled in the user preferences.
2678 // The necsesary JavaScript code can be found in style/wikibits.js.
2679 function getEditToolbar() {
2680 global $wgStylePath, $wgLang, $wgMimeType;
2682 // toolarray an array of arrays which each include the filename of
2683 // the button image (without path), the opening tag, the closing tag,
2684 // and optionally a sample text that is inserted between the two when no
2685 // selection is highlighted.
2686 // The tip text is shown when the user moves the mouse over the button.
2688 // Already here are accesskeys (key), which are not used yet until someone
2689 // can figure out a way to make them work in IE. However, we should make
2690 // sure these keys are not defined on the edit page.
2692 array( 'image'=>'button_bold.png',
2695 'sample'=>wfMsg('bold_sample'),
2696 'tip'=>wfMsg('bold_tip'),
2699 array( "image"=>"button_italic.png",
2702 "sample"=>wfMsg("italic_sample"),
2703 "tip"=>wfMsg("italic_tip"),
2706 array( "image"=>"button_link.png",
2709 "sample"=>wfMsg("link_sample"),
2710 "tip"=>wfMsg("link_tip"),
2713 array( "image"=>"button_extlink.png",
2716 "sample"=>wfMsg("extlink_sample"),
2717 "tip"=>wfMsg("extlink_tip"),
2720 array( "image"=>"button_headline.png",
2723 "sample"=>wfMsg("headline_sample"),
2724 "tip"=>wfMsg("headline_tip"),
2727 array( "image"=>"button_image.png",
2728 "open"=>"[[".$wgLang->getNsText(NS_IMAGE
).":",
2730 "sample"=>wfMsg("image_sample"),
2731 "tip"=>wfMsg("image_tip"),
2734 array( "image"=>"button_media.png",
2735 "open"=>"[[".$wgLang->getNsText(NS_MEDIA
).":",
2737 "sample"=>wfMsg("media_sample"),
2738 "tip"=>wfMsg("media_tip"),
2741 array( "image"=>"button_math.png",
2742 "open"=>"\\<math\\>",
2743 "close"=>"\\</math\\>",
2744 "sample"=>wfMsg("math_sample"),
2745 "tip"=>wfMsg("math_tip"),
2748 array( "image"=>"button_nowiki.png",
2749 "open"=>"\\<nowiki\\>",
2750 "close"=>"\\</nowiki\\>",
2751 "sample"=>wfMsg("nowiki_sample"),
2752 "tip"=>wfMsg("nowiki_tip"),
2755 array( "image"=>"button_sig.png",
2759 "tip"=>wfMsg("sig_tip"),
2762 array( "image"=>"button_hr.png",
2763 "open"=>"\\n----\\n",
2766 "tip"=>wfMsg("hr_tip"),
2770 $toolbar ="<script type='text/javascript'>\n/*<![CDATA[*/\n";
2772 $toolbar.="document.writeln(\"<div id='toolbar'>\");\n";
2773 foreach($toolarray as $tool) {
2775 $image=$wgStylePath.'/images/'.$tool['image'];
2776 $open=$tool['open'];
2777 $close=$tool['close'];
2778 $sample = addslashes( $tool['sample'] );
2780 // Note that we use the tip both for the ALT tag and the TITLE tag of the image.
2781 // Older browsers show a "speedtip" type message only for ALT.
2782 // Ideally these should be different, realistically they
2783 // probably don't need to be.
2784 $tip = addslashes( $tool['tip'] );
2786 #$key = $tool["key"];
2788 $toolbar.="addButton('$image','$tip','$open','$close','$sample');\n";
2791 $toolbar.="addInfobox('" . addslashes( wfMsg( "infobox" ) ) . "','" . addslashes(wfMsg("infobox_alert")) . "');\n";
2792 $toolbar.="document.writeln(\"</div>\");\n";
2794 $toolbar.="/*]]>*/\n</script>";
2798 /* public */ function suppressUrlExpansion() {