4 require_once( 'Feed.php' ); // should not be called if the actual page isn't feed enabled
5 require_once( 'Image.php' );
7 # These are the INTERNAL names, which get mapped
8 # directly to class names. For display purposes, the
9 # Language class has internationalized names
11 /* private */ $wgValidSkinNames = array(
12 'standard' => 'Standard',
13 'nostalgia' => 'Nostalgia',
14 'cologneblue' => 'CologneBlue'
17 #$wgValidSkinNames[] = 'PHPTal';
18 #$wgValidSkinNames['davinci'] = 'DaVinci';
19 #$wgValidSkinNames['mono'] = 'Mono';
20 $wgValidSkinNames['monobook'] = 'MonoBook';
21 $wgValidSkinNames['myskin'] = 'MySkin';
22 #$wgValidSkinNames['monobookminimal'] = 'MonoBookMinimal';
25 require_once( 'RecentChange.php' );
27 class RCCacheEntry
extends RecentChange
29 var $secureName, $link;
30 var $curlink , $difflink, $lastlink , $usertalklink , $versionlink ;
31 var $userlink, $timestamp, $watched;
33 function newFromParent( $rc )
35 $rc2 = new RCCacheEntry
;
36 $rc2->mAttribs
= $rc->mAttribs
;
37 $rc2->mExtra
= $rc->mExtra
;
44 /* private */ var $lastdate, $lastline;
45 var $linktrail ; # linktrail regexp
46 var $rc_cache ; # Cache for Enhanced Recent Changes
47 var $rcCacheIndex ; # Recent Changes Cache Counter for visibility toggle
52 $this->linktrail
= wfMsg('linktrail');
55 function getSkinNames()
57 global $wgValidSkinNames;
58 return $wgValidSkinNames;
61 function getStylesheet()
63 return 'wikistandard.css';
65 function getSkinName() {
71 global $wgOut, $wgUser;
73 if ( $wgOut->isQuickbarSuppressed() ) { return 0; }
74 $q = $wgUser->getOption( 'quickbar' );
75 if ( '' == $q ) { $q = 0; }
79 function initPage( &$out )
81 $fname = 'Skin::initPage';
82 wfProfileIn( $fname );
84 $out->addLink( array( 'rel' => 'shortcut icon', 'href' => '/favicon.ico' ) );
86 $this->addMetadataLinks($out);
88 wfProfileOut( $fname );
91 function addMetadataLinks( &$out ) {
92 global $wgTitle, $wgEnableDublinCoreRdf, $wgEnableCreativeCommonsRdf, $wgRdfMimeType, $action;
93 global $wgRightsPage, $wgRightsUrl;
95 if( $out->isArticleRelated() ) {
96 # note: buggy CC software only reads first "meta" link
97 if( $wgEnableCreativeCommonsRdf ) {
98 $out->addMetadataLink( array(
99 'title' => 'Creative Commons',
100 'type' => 'application/rdf+xml',
101 'href' => $wgTitle->getLocalURL( 'action=creativecommons') ) );
103 if( $wgEnableDublinCoreRdf ) {
104 $out->addMetadataLink( array(
105 'title' => 'Dublin Core',
106 'type' => 'application/rdf+xml',
107 'href' => $wgTitle->getLocalURL( 'action=dublincore' ) ) );
111 if( $wgRightsPage ) {
112 $copy = Title
::newFromText( $wgRightsPage );
114 $copyright = $copy->getLocalURL();
117 if( !$copyright && $wgRightsUrl ) {
118 $copyright = $wgRightsUrl;
121 $out->addLink( array(
122 'rel' => 'copyright',
123 'href' => $copyright ) );
127 function outputPage( &$out ) {
128 global $wgDebugComments;
130 wfProfileIn( 'Skin::outputPage' );
131 $this->initPage( $out );
132 $out->out( $out->headElement() );
134 $out->out( "\n<body" );
135 $ops = $this->getBodyOptions();
136 foreach ( $ops as $name => $val ) {
137 $out->out( " $name='$val'" );
140 if ( $wgDebugComments ) {
141 $out->out( "<!-- Wiki debugging output:\n" .
142 $out->mDebugtext
. "-->\n" );
144 $out->out( $this->beforeContent() );
146 $out->out( $out->mBodytext
. "\n" );
148 $out->out( $this->afterContent() );
151 $out->out( $out->reportTime() );
153 $out->out( "\n</body></html>" );
156 function getHeadScripts() {
157 global $wgStylePath, $wgUser, $wgLang, $wgAllowUserJs;
158 $r = "<script type=\"text/javascript\" src=\"{$wgStylePath}/wikibits.js\"></script>\n";
159 if( $wgAllowUserJs && $wgUser->getID() != 0 ) { # logged in
160 $userpage = $wgLang->getNsText( Namespace::getUser() ) . ":" . $wgUser->getName();
161 $userjs = htmlspecialchars($this->makeUrl($userpage.'/'.$this->getSkinName().'.js', 'action=raw&ctype=text/javascript'));
162 $r .= '<script type="text/javascript" src="'.$userjs."\"></script>\n";
167 # get the user/site-specific stylesheet, SkinPHPTal called from RawPage.php (settings are cached that way)
168 function getUserStylesheet() {
169 global $wgOut, $wgStylePath, $wgLang, $wgUser, $wgRequest, $wgTitle, $wgAllowUserCss;
170 $sheet = $this->getStylesheet();
171 $action = $wgRequest->getText('action');
172 $s = "@import \"$wgStylePath/$sheet\";\n";
173 if($wgLang->isRTL()) $s .= "@import \"$wgStylePath/common_rtl.css\";\n";
174 if( $wgAllowUserCss && $wgUser->getID() != 0 ) { # logged in
175 if($wgTitle->isCssSubpage() and $action == 'submit' and $wgTitle->userCanEditCssJsSubpage()) {
176 $s .= $wgRequest->getText('wpTextbox1');
178 $userpage = $wgLang->getNsText( Namespace::getUser() ) . ":" . $wgUser->getName();
179 $s.= '@import "'.$this->makeUrl($userpage.'/'.$this->getSkinName().'.css', 'action=raw&ctype=text/css').'";'."\n";
182 $s .= $this->doGetUserStyles();
185 # placeholder, returns generated js in monobook
186 function getUserJs() {
190 function getUserStyles()
192 global $wgOut, $wgStylePath, $wgLang;
193 $s = "<style type='text/css'>\n";
194 $s .= "/*/*/\n"; # <-- Hide the styles from Netscape 4 without hiding them from IE/Mac
195 $s .= $this->getUserStylesheet();
201 function doGetUserStyles()
206 if ( 1 == $wgUser->getOption( 'underline' ) ) {
207 # Don't override browser settings
212 "text-decoration: none; }\n";
214 if ( 1 == $wgUser->getOption( 'highlightbroken' ) ) {
215 $s .= "a.new, #quickbar a.new { color: #CC2200; }\n";
217 if ( 1 == $wgUser->getOption( 'justify' ) ) {
218 $s .= "#article { text-align: justify; }\n";
223 function getBodyOptions()
225 global $wgUser, $wgTitle, $wgNamespaceBackgrounds, $wgOut, $wgRequest;
227 extract( $wgRequest->getValues( 'oldid', 'redirect', 'diff' ) );
229 if ( 0 != $wgTitle->getNamespace() ) {
230 $a = array( 'bgcolor' => '#ffffec' );
232 else $a = array( 'bgcolor' => '#FFFFFF' );
233 if($wgOut->isArticle() && $wgUser->getOption('editondblclick') &&
234 (!$wgTitle->isProtected() ||
$wgUser->isSysop()) ) {
235 $t = wfMsg( 'editthispage' );
237 if ( !empty($redirect) ) {
238 $red = "&redirect={$redirect}";
240 if ( !empty($oldid) && ! isset( $diff ) ) {
241 $oid = "&oldid={$oldid}";
243 $s = $wgTitle->getFullURL( "action=edit{$oid}{$red}" );
244 $s = 'document.location = "' .$s .'";';
245 $a +
= array ('ondblclick' => $s);
248 $a['onload'] = $wgOut->getOnloadHandler();
252 function getExternalLinkAttributes( $link, $text, $class='' )
254 global $wgUser, $wgOut, $wgLang;
256 $link = urldecode( $link );
257 $link = $wgLang->checkTitleEncoding( $link );
258 $link = str_replace( '_', ' ', $link );
259 $link = wfEscapeHTML( $link );
261 $r = ($class != '') ?
" class='$class'" : " class='external'";
263 if ( 1 == $wgUser->getOption( 'hover' ) ) {
264 $r .= " title=\"{$link}\"";
269 function getInternalLinkAttributes( $link, $text, $broken = false )
271 global $wgUser, $wgOut;
273 $link = urldecode( $link );
274 $link = str_replace( '_', ' ', $link );
275 $link = wfEscapeHTML( $link );
277 if ( $broken == 'stub' ) {
278 $r = ' class="stub"';
279 } else if ( $broken == 'yes' ) {
285 if ( 1 == $wgUser->getOption( 'hover' ) ) {
286 $r .= " title=\"{$link}\"";
291 function getInternalLinkAttributesObj( &$nt, $text, $broken = false )
293 global $wgUser, $wgOut;
295 if ( $broken == 'stub' ) {
296 $r = ' class="stub"';
297 } else if ( $broken == 'yes' ) {
303 if ( 1 == $wgUser->getOption( 'hover' ) ) {
304 $r .= ' title ="' . $nt->getEscapedText() . '"';
315 # This will be called immediately after the <body> tag. Split into
316 # two functions to make it easier to subclass.
318 function beforeContent()
320 global $wgUser, $wgOut, $wgSiteNotice;
322 if( $wgSiteNotice ) {
323 $note = "\n<div id='siteNotice'>$wgSiteNotice</div>\n";
327 return $this->doBeforeContent() . $note;
330 function doBeforeContent()
332 global $wgUser, $wgOut, $wgTitle, $wgLang;
333 $fname = 'Skin::doBeforeContent';
334 wfProfileIn( $fname );
337 $qb = $this->qbSetting();
339 if( $langlinks = $this->otherLanguages() ) {
345 $borderhack = 'class="top"';
348 $s .= "\n<div id='content'>\n<div id='topbar'>\n" .
349 "<table border='0' cellspacing='0' width='98%'>\n<tr>\n";
352 $left = ($qb == 1 ||
$qb == 3);
353 if($wgLang->isRTL()) $left = !$left;
356 $s .= "<td class='top' align='left' valign='top' rowspan='{$rows}'>\n" .
357 $this->logoText() . '</td>';
359 $s .= $this->getQuickbarCompensator( $rows );
361 $l = $wgLang->isRTL() ?
'right' : 'left';
362 $s .= "<td {$borderhack} align='$l' valign='top'>\n";
364 $s .= $this->topLinks() ;
365 $s .= "<p class='subtitle'>" . $this->pageTitleLinks() . "</p>\n";
367 $r = $wgLang->isRTL() ?
"left" : "right";
368 $s .= "</td>\n<td {$borderhack} valign='top' align='$r' nowrap='nowrap'>";
369 $s .= $this->nameAndLogin();
370 $s .= "\n<br />" . $this->searchForm() . "</td>";
373 $s .= "</tr>\n<tr>\n<td class='top' colspan=\"2\">$langlinks</td>\n";
376 if ( $shove && !$left ) { # Right
377 $s .= $this->getQuickbarCompensator( $rows );
379 $s .= "</tr>\n</table>\n</div>\n";
380 $s .= "\n<div id='article'>\n";
382 $s .= $this->pageTitle();
383 $s .= $this->pageSubtitle() ;
384 $s .= $this->getCategories();
385 wfProfileOut( $fname );
389 function getCategoryLinks () {
390 global $wgOut, $wgTitle, $wgUser, $wgParser;
391 global $wgUseCategoryMagic, $wgUseCategoryBrowser, $wgLang;
393 if( !$wgUseCategoryMagic ) return '' ;
394 if( count( $wgOut->mCategoryLinks
) == 0 ) return '';
396 # Taken out so that they will be displayed in previews -- TS
397 #if( !$wgOut->isArticle() ) return '';
399 $t = implode ( ' | ' , $wgOut->mCategoryLinks
) ;
400 $s = $this->makeKnownLink( 'Special:Categories',
401 wfMsg( 'categories' ), 'article=' . urlencode( $wgTitle->getPrefixedDBkey() ) )
404 if($wgUseCategoryBrowser) {
407 $s.= $wgTitle->getAllParentCategories($catstack);
413 function getCategories() {
414 $catlinks=$this->getCategoryLinks();
415 if(!empty($catlinks)) {
416 return "<p class='catlinks'>{$catlinks}</p>";
420 function getQuickbarCompensator( $rows = 1 )
422 return "<td width='152' rowspan='{$rows}'> </td>";
425 # This gets called immediately before the </body> tag.
427 function afterContent()
429 global $wgUser, $wgOut, $wgServer;
430 global $wgTitle, $wgLang;
432 $printfooter = "<div class=\"printfooter\">\n" . $this->printFooter() . "</div>\n";
433 return $printfooter . $this->doAfterContent();
436 function printFooter() {
438 $url = htmlspecialchars( $wgTitle->getFullURL() );
439 return "<p>" . wfMsg( "retrievedfrom", "<a href=\"$url\">$url</a>" ) .
440 "</p>\n\n<p>" . $this->pageStats() . "</p>\n";
443 function doAfterContent()
445 global $wgUser, $wgOut, $wgLang;
446 $fname = 'Skin::doAfterContent';
447 wfProfileIn( $fname );
448 wfProfileIn( $fname.'-1' );
450 $s = "\n</div><br style=\"clear:both\" />\n";
451 $s .= "\n<div id='footer'>";
452 $s .= '<table border="0" cellspacing="0"><tr>';
454 wfProfileOut( $fname.'-1' );
455 wfProfileIn( $fname.'-2' );
457 $qb = $this->qbSetting();
459 $left = ($qb == 1 ||
$qb == 3);
460 if($wgLang->isRTL()) $left = !$left;
462 if ( $shove && $left ) { # Left
463 $s .= $this->getQuickbarCompensator();
465 wfProfileOut( $fname.'-2' );
466 wfProfileIn( $fname.'-3' );
467 $l = $wgLang->isRTL() ?
'right' : 'left';
468 $s .= "<td class='bottom' align='$l' valign='top'>";
470 $s .= $this->bottomLinks();
471 $s .= "\n<br />" . $this->mainPageLink()
472 . ' | ' . $this->aboutLink()
473 . ' | ' . $this->specialLink( 'recentchanges' )
474 . ' | ' . $this->searchForm()
475 . '<br /><span id="pagestats">' . $this->pageStats() . '</span>';
478 if ( $shove && !$left ) { # Right
479 $s .= $this->getQuickbarCompensator();
481 $s .= "</tr></table>\n</div>\n</div>\n";
483 wfProfileOut( $fname.'-3' );
484 wfProfileIn( $fname.'-4' );
485 if ( 0 != $qb ) { $s .= $this->quickBar(); }
486 wfProfileOut( $fname.'-4' );
487 wfProfileOut( $fname );
491 function pageTitleLinks()
493 global $wgOut, $wgTitle, $wgUser, $wgLang, $wgUseApproval, $wgRequest;
495 extract( $wgRequest->getValues( 'oldid', 'diff' ) );
496 $action = $wgRequest->getText( 'action' );
498 $s = $this->printableLink();
499 if ( wfMsg ( 'disclaimers' ) != '-' ) $s .= ' | ' . $this->makeKnownLink( wfMsg( 'disclaimerpage' ), wfMsg( 'disclaimers' ) ) ;
501 if ( $wgOut->isArticleRelated() ) {
502 if ( $wgTitle->getNamespace() == Namespace::getImage() ) {
503 $name = $wgTitle->getDBkey();
504 $link = wfEscapeHTML( Image
::wfImageUrl( $name ) );
505 $style = $this->getInternalLinkAttributes( $link, $name );
506 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>";
508 # This will show the "Approve" link if $wgUseApproval=true;
509 if ( isset ( $wgUseApproval ) && $wgUseApproval )
511 $t = $wgTitle->getDBkey();
512 $name = 'Approve this article' ;
513 $link = "http://test.wikipedia.org/w/magnus/wiki.phtml?title={$t}&action=submit&doit=1" ;
514 #wfEscapeHTML( wfImageUrl( $name ) );
515 $style = $this->getExternalLinkAttributes( $link, $name );
516 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>" ;
519 if ( 'history' == $action ||
isset( $diff ) ||
isset( $oldid ) ) {
520 $s .= ' | ' . $this->makeKnownLink( $wgTitle->getPrefixedText(),
521 wfMsg( 'currentrev' ) );
524 if ( $wgUser->getNewtalk() ) {
525 # do not show "You have new messages" text when we are viewing our
528 if(!(strcmp($wgTitle->getText(),$wgUser->getName()) == 0 &&
529 $wgTitle->getNamespace()==Namespace::getTalk(Namespace::getUser()))) {
530 $n =$wgUser->getName();
531 $tl = $this->makeKnownLink( $wgLang->getNsText(
532 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
533 wfMsg('newmessageslink') );
534 $s.= ' | <strong>'. wfMsg( 'newmessages', $tl ) . '</strong>';
538 $undelete = $this->getUndeleteLink();
539 if( !empty( $undelete ) ) {
540 $s .= ' | '.$undelete;
545 function getUndeleteLink() {
546 global $wgUser, $wgTitle, $wgLang, $action;
547 if( $wgUser->isSysop() &&
548 (($wgTitle->getArticleId() == 0) ||
($action == "history")) &&
549 ($n = $wgTitle->isDeleted() ) ) {
550 return wfMsg( 'thisisdeleted',
551 $this->makeKnownLink(
552 $wgLang->SpecialPage( 'Undelete/' . $wgTitle->getPrefixedDBkey() ),
553 wfMsg( 'restorelink', $n ) ) );
558 function printableLink()
560 global $wgOut, $wgFeedClasses, $wgRequest;
562 $baseurl = $_SERVER['REQUEST_URI'];
563 if( strpos( '?', $baseurl ) == false ) {
568 $baseurl = htmlspecialchars( $baseurl );
569 $printurl = $wgRequest->escapeAppendQuery( 'printable=yes' );
571 $s = "<a href=\"$printurl\">" . wfMsg( 'printableversion' ) . '</a>';
572 if( $wgOut->isSyndicated() ) {
573 foreach( $wgFeedClasses as $format => $class ) {
574 $feedurl = $wgRequest->escapeAppendQuery( "feed=$format" );
575 $s .= " | <a href=\"$feedurl\">{$format}</a>";
583 global $wgOut, $wgTitle, $wgUser;
585 $s = '<h1 class="pagetitle">' . htmlspecialchars( $wgOut->getPageTitle() ) . '</h1>';
586 if($wgUser->getOption( 'editsectiononrightclick' ) && $wgTitle->userCanEdit()) { $s=$this->editSectionScript(0,$s);}
590 function pageSubtitle()
594 $sub = $wgOut->getSubtitle();
596 global $wgExtraSubtitle;
597 $sub = wfMsg( 'fromwikipedia' ) . $wgExtraSubtitle;
599 $subpages = $this->subPageSubtitle();
600 $sub .= !empty($subpages)?
"</p><p class='subpages'>$subpages":'';
601 $s = "<p class='subtitle'>{$sub}</p>\n";
605 function subPageSubtitle()
607 global $wgOut,$wgTitle,$wgNamespacesWithSubpages;
609 if($wgOut->isArticle() && !empty($wgNamespacesWithSubpages[$wgTitle->getNamespace()])) {
610 $ptext=$wgTitle->getPrefixedText();
611 if(preg_match('/\//',$ptext)) {
612 $links = explode('/',$ptext);
615 foreach($links as $link) {
617 if ($c<count($links)) {
618 $growinglink .= $link;
619 $getlink = $this->makeLink( $growinglink, $link );
620 if(preg_match('/class="new"/i',$getlink)) { break; } # this is a hack, but it saves time
624 $subpages .= '< ';
626 $subpages .= $getlink;
635 function nameAndLogin()
637 global $wgUser, $wgTitle, $wgLang, $wgShowIPinHeader, $wgIP;
639 $li = $wgLang->specialPage( 'Userlogin' );
640 $lo = $wgLang->specialPage( 'Userlogout' );
643 if ( 0 == $wgUser->getID() ) {
644 if( $wgShowIPinHeader && isset( $_COOKIE[ini_get('session.name')] ) ) {
647 $tl = $this->makeKnownLink( $wgLang->getNsText(
648 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
649 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
651 $s .= $n . ' ('.$tl.')';
653 $s .= wfMsg('notloggedin');
656 $rt = $wgTitle->getPrefixedURL();
657 if ( 0 == strcasecmp( urlencode( $lo ), $rt ) ) {
659 } else { $q = "returnto={$rt}"; }
661 $s .= "\n<br />" . $this->makeKnownLink( $li,
662 wfMsg( 'login' ), $q );
664 $n = $wgUser->getName();
665 $rt = $wgTitle->getPrefixedURL();
666 $tl = $this->makeKnownLink( $wgLang->getNsText(
667 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
668 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
672 $s .= $this->makeKnownLink( $wgLang->getNsText(
673 Namespace::getUser() ) . ":{$n}", $n ) . "{$tl}<br />" .
674 $this->makeKnownLink( $lo, wfMsg( 'logout' ),
675 "returnto={$rt}" ) . ' | ' .
676 $this->specialLink( 'preferences' );
678 $s .= ' | ' . $this->makeKnownLink( wfMsg( 'helppage' ),
684 function getSearchLink() {
685 $searchPage =& Title
::makeTitle( NS_SPECIAL
, 'Search' );
686 return $searchPage->getLocalURL();
689 function escapeSearchLink() {
690 return htmlspecialchars( $this->getSearchLink() );
693 function searchForm()
696 $search = $wgRequest->getText( 'search' );
698 $s = '<form name="search" class="inline" method="post" action="'
699 . $this->escapeSearchLink() . "\">\n"
700 . '<input type="text" name="search" size="19" value="'
701 . htmlspecialchars(substr($search,0,256)) . "\" />\n"
702 . '<input type="submit" name="go" value="' . wfMsg ('go') . '" /> '
703 . '<input type="submit" name="fulltext" value="' . wfMsg ('search') . "\" />\n</form>";
713 $s = $this->mainPageLink() . $sep
714 . $this->specialLink( 'recentchanges' );
716 if ( $wgOut->isArticleRelated() ) {
717 $s .= $sep . $this->editThisPage()
718 . $sep . $this->historyLink();
720 # Many people don't like this dropdown box
721 #$s .= $sep . $this->specialPagesList();
726 function bottomLinks()
728 global $wgOut, $wgUser, $wgTitle;
732 if ( $wgOut->isArticleRelated() ) {
733 $s .= '<strong>' . $this->editThisPage() . '</strong>';
734 if ( 0 != $wgUser->getID() ) {
735 $s .= $sep . $this->watchThisPage();
737 $s .= $sep . $this->talkLink()
738 . $sep . $this->historyLink()
739 . $sep . $this->whatLinksHere()
740 . $sep . $this->watchPageLinksLink();
742 if ( $wgTitle->getNamespace() == Namespace::getUser()
743 ||
$wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser()) )
746 $id=User
::idFromName($wgTitle->getText());
747 $ip=User
::isIP($wgTitle->getText());
749 if($id ||
$ip) { # both anons and non-anons have contri list
750 $s .= $sep . $this->userContribsLink();
752 if ( 0 != $wgUser->getID() ) { # show only to signed in users
753 if($id) { # can only email non-anons
754 $s .= $sep . $this->emailUserLink();
758 if ( $wgUser->isSysop() && $wgTitle->getArticleId() ) {
759 $s .= "\n<br />" . $this->deleteThisPage() .
760 $sep . $this->protectThisPage() .
761 $sep . $this->moveThisPage();
763 $s .= "<br />\n" . $this->otherLanguages();
770 global $wgOut, $wgLang, $wgArticle, $wgRequest;
771 global $wgDisableCounters, $wgMaxCredits, $wgShowCreditsIfMax;
773 extract( $wgRequest->getValues( 'oldid', 'diff' ) );
774 if ( ! $wgOut->isArticle() ) { return ''; }
775 if ( isset( $oldid ) ||
isset( $diff ) ) { return ''; }
776 if ( 0 == $wgArticle->getID() ) { return ''; }
779 if ( !$wgDisableCounters ) {
780 $count = $wgLang->formatNum( $wgArticle->getCount() );
782 $s = wfMsg( 'viewcount', $count );
786 if (isset($wgMaxCredits) && $wgMaxCredits != 0) {
787 require_once("Credits.php");
788 $s .= ' ' . getCredits($wgArticle, $wgMaxCredits, $wgShowCreditsIfMax);
790 $s .= $this->lastModified();
793 return $s . ' ' . $this->getCopyright();
796 function getCopyright() {
797 global $wgRightsPage, $wgRightsUrl, $wgRightsText, $wgRequest;
800 $oldid = $wgRequest->getVal( 'oldid' );
801 $diff = $wgRequest->getVal( 'diff' );
803 if ( !is_null( $oldid ) && is_null( $diff ) && wfMsg( 'history_copyright' ) !== '-' ) {
804 $msg = 'history_copyright';
810 if( $wgRightsPage ) {
811 $link = $this->makeKnownLink( $wgRightsPage, $wgRightsText );
812 } elseif( $wgRightsUrl ) {
813 $link = $this->makeExternalLink( $wgRightsUrl, $wgRightsText );
818 $out .= wfMsg( $msg, $link );
822 function getCopyrightIcon() {
823 global $wgRightsPage, $wgRightsUrl, $wgRightsText, $wgRightsIcon;
825 if( $wgRightsIcon ) {
826 $icon = htmlspecialchars( $wgRightsIcon );
828 $url = htmlspecialchars( $wgRightsUrl );
829 $out .= '<a href="'.$url.'">';
831 $text = htmlspecialchars( $wgRightsText );
832 $out .= "<img src=\"$icon\" alt='$text' />";
840 function getPoweredBy() {
842 $url = htmlspecialchars( "$wgStylePath/images/poweredby_mediawiki_88x31.png" );
843 $img = '<a href="http://www.mediawiki.org/"><img src="'.$url.'" alt="MediaWiki" /></a>';
847 function lastModified()
849 global $wgLang, $wgArticle;
851 $timestamp = $wgArticle->getTimestamp();
853 $d = $wgLang->timeanddate( $wgArticle->getTimestamp(), true );
854 $s = ' ' . wfMsg( 'lastmodified', $d );
861 function logoText( $align = '' )
863 if ( '' != $align ) { $a = ' align="'.$align.'"'; }
866 $mp = wfMsg( 'mainpage' );
867 $titleObj = Title
::newFromText( $mp );
868 $s = '<a href="' . $titleObj->escapeLocalURL()
869 . '"><img'.$a.' src="'
870 . $this->getLogo() . '" alt="' . "[{$mp}]\" /></a>";
876 global $wgOut, $wgTitle, $wgUser, $wgRequest, $wgLang;
877 global $wgDisableUploads, $wgRemoteUploads;
879 $fname = 'Skin::quickBar';
880 wfProfileIn( $fname );
882 $action = $wgRequest->getText( 'action' );
883 $wpPreview = $wgRequest->getBool( 'wpPreview' );
884 $tns=$wgTitle->getNamespace();
886 $s = "\n<div id='quickbar'>";
887 $s .= "\n" . $this->logoText() . "\n<hr class='sep' />";
890 $s .= $this->mainPageLink()
891 . $sep . $this->specialLink( 'recentchanges' )
892 . $sep . $this->specialLink( 'randompage' );
893 if ($wgUser->getID()) {
894 $s.= $sep . $this->specialLink( 'watchlist' ) ;
895 $s .= $sep .$this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
896 wfMsg( 'mycontris' ), 'target=' . wfUrlencode($wgUser->getName() ) );
899 // only show watchlist link if logged in
900 if ( wfMsg ( 'currentevents' ) != '-' ) $s .= $sep . $this->makeKnownLink( wfMsg( 'currentevents' ), '' ) ;
901 $s .= "\n<br /><hr class='sep' />";
902 $articleExists = $wgTitle->getArticleId();
903 if ( $wgOut->isArticle() ||
$action =='edit' ||
$action =='history' ||
$wpPreview) {
904 if($wgOut->isArticle()) {
905 $s .= '<strong>' . $this->editThisPage() . '</strong>';
906 } else { # backlink to the article in edit or history mode
907 if($articleExists){ # no backlink if no article
910 $text = wfMsg('articlepage');
913 $text = wfMsg('viewtalkpage');
916 $text = wfMsg('userpage');
919 $text = wfMsg('viewtalkpage');
922 $text = wfMsg('wikipediapage');
925 $text = wfMsg('viewtalkpage');
928 $text = wfMsg('imagepage');
931 $text = wfMsg('viewtalkpage');
934 $text= wfMsg('articlepage');
937 $link = $wgTitle->getText();
938 if ($nstext = $wgLang->getNsText($tns) ) { # add namespace if necessary
939 $link = $nstext . ':' . $link ;
942 $s .= $this->makeLink( $link, $text );
943 } elseif( $wgTitle->getNamespace() != Namespace::getSpecial() ) {
944 # we just throw in a "New page" text to tell the user that he's in edit mode,
945 # and to avoid messing with the separator that is prepended to the next item
946 $s .= '<strong>' . wfMsg('newpage') . '</strong>';
952 if( $tns%2
&& $action!='edit' && !$wpPreview) {
953 $s.= '<br />'.$this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg('postcomment'),'action=edit§ion=new');
957 watching could cause problems in edit mode:
958 if user edits article, then loads "watch this article" in background and then saves
959 article with "Watch this article" checkbox disabled, the article is transparently
960 unwatched. Therefore we do not show the "Watch this page" link in edit mode
962 if ( 0 != $wgUser->getID() && $articleExists) {
963 if($action!='edit' && $action != 'submit' )
965 $s .= $sep . $this->watchThisPage();
967 if ( $wgTitle->userCanEdit() )
968 $s .= $sep . $this->moveThisPage();
970 if ( $wgUser->isSysop() and $articleExists ) {
971 $s .= $sep . $this->deleteThisPage() .
972 $sep . $this->protectThisPage();
974 $s .= $sep . $this->talkLink();
975 if ($articleExists && $action !='history') {
976 $s .= $sep . $this->historyLink();
978 $s.=$sep . $this->whatLinksHere();
980 if($wgOut->isArticleRelated()) {
981 $s .= $sep . $this->watchPageLinksLink();
984 if ( Namespace::getUser() == $wgTitle->getNamespace()
985 ||
$wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser())
988 $id=User
::idFromName($wgTitle->getText());
989 $ip=User
::isIP($wgTitle->getText());
992 $s .= $sep . $this->userContribsLink();
994 if ( 0 != $wgUser->getID() ) {
995 if($id) { # can only email real users
996 $s .= $sep . $this->emailUserLink();
1000 $s .= "\n<br /><hr class='sep' />";
1003 if ( 0 != $wgUser->getID() && ( !$wgDisableUploads ||
$wgRemoteUploads ) ) {
1004 $s .= $this->specialLink( 'upload' ) . $sep;
1006 $s .= $this->specialLink( 'specialpages' )
1007 . $sep . $this->bugReportsLink();
1009 global $wgSiteSupportPage;
1010 if( $wgSiteSupportPage ) {
1011 $s .= "\n<br /><a href=\"" . htmlspecialchars( $wgSiteSupportPage ) .
1012 '" class="internal">' . wfMsg( 'sitesupport' ) . '</a>';
1015 $s .= "\n<br /></div>\n";
1016 wfProfileOut( $fname );
1020 function specialPagesList()
1022 global $wgUser, $wgOut, $wgLang, $wgServer, $wgRedirectScript;
1023 require_once('SpecialPage.php');
1025 $pages = SpecialPage
::getPages();
1027 foreach ( $pages[''] as $name => $page ) {
1028 $a[$name] = $page->getDescription();
1030 if ( $wgUser->isSysop() )
1032 foreach ( $pages['sysop'] as $name => $page ) {
1033 $a[$name] = $page->getDescription();
1036 if ( $wgUser->isDeveloper() )
1038 foreach ( $pages['developer'] as $name => $page ) {
1039 $a[$name] = $page->getDescription() ;
1042 $go = wfMsg( 'go' );
1043 $sp = wfMsg( 'specialpages' );
1044 $spp = $wgLang->specialPage( 'Specialpages' );
1046 $s = '<form id="specialpages" method="get" class="inline" ' .
1047 'action="' . htmlspecialchars( "{$wgServer}{$wgRedirectScript}" ) . "\">\n";
1048 $s .= "<select name=\"wpDropdown\">\n";
1049 $s .= "<option value=\"{$spp}\">{$sp}</option>\n";
1051 foreach ( $a as $name => $desc ) {
1052 $p = $wgLang->specialPage( $name );
1053 $s .= "<option value=\"{$p}\">{$desc}</option>\n";
1055 $s .= "</select>\n";
1056 $s .= "<input type='submit' value=\"{$go}\" name='redirect' />\n";
1061 function mainPageLink()
1063 $mp = wfMsg( 'mainpage' );
1064 $s = $this->makeKnownLink( $mp, $mp );
1068 function copyrightLink()
1070 $s = $this->makeKnownLink( wfMsg( 'copyrightpage' ),
1071 wfMsg( 'copyrightpagename' ) );
1075 function aboutLink()
1077 $s = $this->makeKnownLink( wfMsg( 'aboutpage' ),
1078 wfMsg( 'aboutwikipedia' ) );
1083 function disclaimerLink()
1085 $s = $this->makeKnownLink( wfMsg( 'disclaimerpage' ),
1086 wfMsg( 'disclaimers' ) );
1090 function editThisPage()
1092 global $wgOut, $wgTitle, $wgRequest;
1094 $oldid = $wgRequest->getVal( 'oldid' );
1095 $diff = $wgRequest->getVal( 'diff' );
1096 $redirect = $wgRequest->getVal( 'redirect' );
1098 if ( ! $wgOut->isArticleRelated() ) {
1099 $s = wfMsg( 'protectedpage' );
1101 $n = $wgTitle->getPrefixedText();
1102 if ( $wgTitle->userCanEdit() ) {
1103 $t = wfMsg( 'editthispage' );
1105 #$t = wfMsg( "protectedpage" );
1106 $t = wfMsg( 'viewsource' );
1110 if ( !is_null( $redirect ) ) { $red = "&redirect={$redirect}"; }
1111 if ( $oldid && ! isset( $diff ) ) {
1112 $oid = "&oldid={$oldid}";
1114 $s = $this->makeKnownLink( $n, $t, "action=edit{$oid}{$red}" );
1119 function deleteThisPage()
1121 global $wgUser, $wgOut, $wgTitle, $wgRequest;
1123 $diff = $wgRequest->getVal( 'diff' );
1124 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
1125 $n = $wgTitle->getPrefixedText();
1126 $t = wfMsg( 'deletethispage' );
1128 $s = $this->makeKnownLink( $n, $t, 'action=delete' );
1135 function protectThisPage()
1137 global $wgUser, $wgOut, $wgTitle, $wgRequest;
1139 $diff = $wgRequest->getVal( 'diff' );
1140 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
1141 $n = $wgTitle->getPrefixedText();
1143 if ( $wgTitle->isProtected() ) {
1144 $t = wfMsg( 'unprotectthispage' );
1145 $q = 'action=unprotect';
1147 $t = wfMsg( 'protectthispage' );
1148 $q = 'action=protect';
1150 $s = $this->makeKnownLink( $n, $t, $q );
1157 function watchThisPage()
1159 global $wgUser, $wgOut, $wgTitle;
1161 if ( $wgOut->isArticleRelated() ) {
1162 $n = $wgTitle->getPrefixedText();
1164 if ( $wgTitle->userIsWatching() ) {
1165 $t = wfMsg( 'unwatchthispage' );
1166 $q = 'action=unwatch';
1168 $t = wfMsg( 'watchthispage' );
1169 $q = 'action=watch';
1171 $s = $this->makeKnownLink( $n, $t, $q );
1173 $s = wfMsg( 'notanarticle' );
1178 function moveThisPage()
1180 global $wgTitle, $wgLang;
1182 if ( $wgTitle->userCanEdit() ) {
1183 $s = $this->makeKnownLink( $wgLang->specialPage( 'Movepage' ),
1184 wfMsg( 'movethispage' ), 'target=' . $wgTitle->getPrefixedURL() );
1185 } // no message if page is protected - would be redundant
1189 function historyLink()
1193 $s = $this->makeKnownLink( $wgTitle->getPrefixedText(),
1194 wfMsg( 'history' ), 'action=history' );
1198 function whatLinksHere()
1200 global $wgTitle, $wgLang;
1202 $s = $this->makeKnownLink( $wgLang->specialPage( 'Whatlinkshere' ),
1203 wfMsg( 'whatlinkshere' ), 'target=' . $wgTitle->getPrefixedURL() );
1207 function userContribsLink()
1209 global $wgTitle, $wgLang;
1211 $s = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
1212 wfMsg( 'contributions' ), 'target=' . $wgTitle->getPartialURL() );
1216 function emailUserLink()
1218 global $wgTitle, $wgLang;
1220 $s = $this->makeKnownLink( $wgLang->specialPage( 'Emailuser' ),
1221 wfMsg( 'emailuser' ), 'target=' . $wgTitle->getPartialURL() );
1225 function watchPageLinksLink()
1227 global $wgOut, $wgTitle, $wgLang;
1229 if ( ! $wgOut->isArticleRelated() ) {
1230 $s = '(' . wfMsg( 'notanarticle' ) . ')';
1232 $s = $this->makeKnownLink( $wgLang->specialPage(
1233 'Recentchangeslinked' ), wfMsg( 'recentchangeslinked' ),
1234 'target=' . $wgTitle->getPrefixedURL() );
1239 function otherLanguages()
1241 global $wgOut, $wgLang, $wgTitle, $wgUseNewInterlanguage;
1243 $a = $wgOut->getLanguageLinks();
1244 if ( 0 == count( $a ) ) {
1245 if ( !$wgUseNewInterlanguage ) return '';
1246 $ns = $wgLang->getNsIndex ( $wgTitle->getNamespace () ) ;
1247 if ( $ns != 0 AND $ns != 1 ) return '' ;
1249 $x = 'mode=addlink&xt='.$wgTitle->getDBkey() ;
1250 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1251 wfMsg( 'intl' ) , $x );
1254 if ( !$wgUseNewInterlanguage ) {
1255 $s = wfMsg( 'otherlanguages' ) . ': ';
1257 global $wgLanguageCode ;
1258 $x = 'mode=zoom&xt='.$wgTitle->getDBkey() ;
1259 $x .= '&xl='.$wgLanguageCode ;
1260 $s = $this->makeKnownLink( $wgLang->specialPage( 'Intl' ),
1261 wfMsg( 'otherlanguages' ) , $x ) . ': ' ;
1264 $s = wfMsg( 'otherlanguages' ) . ': ';
1266 if($wgLang->isRTL()) $s .= '<span dir="LTR">';
1267 foreach( $a as $l ) {
1268 if ( ! $first ) { $s .= ' | '; }
1271 $nt = Title
::newFromText( $l );
1272 $url = $nt->getFullURL();
1273 $text = $wgLang->getLanguageName( $nt->getInterwiki() );
1275 if ( '' == $text ) { $text = $l; }
1276 $style = $this->getExternalLinkAttributes( $l, $text );
1277 $s .= "<a href=\"{$url}\"{$style}>{$text}</a>";
1279 if($wgLang->isRTL()) $s .= '</span>';
1283 function bugReportsLink()
1285 $s = $this->makeKnownLink( wfMsg( 'bugreportspage' ),
1286 wfMsg( 'bugreports' ) );
1292 global $wgLinkCache;
1293 $t1 = Title
::newFromText( gmdate( 'F j' ) );
1294 $t2 = Title
::newFromText( gmdate( 'Y' ) );
1296 $wgLinkCache->suspend();
1297 $id = $t1->getArticleID();
1298 $wgLinkCache->resume();
1301 $s = $this->makeBrokenLink( $t1->getText() );
1303 $s = $this->makeKnownLink( $t1->getText() );
1307 $wgLinkCache->suspend();
1308 $id = $t2->getArticleID();
1309 $wgLinkCache->resume();
1312 $s .= $this->makeBrokenLink( $t2->getText() );
1314 $s .= $this->makeKnownLink( $t2->getText() );
1321 global $wgLang, $wgTitle, $wgLinkCache;
1323 $tns = $wgTitle->getNamespace();
1324 if ( -1 == $tns ) { return ''; }
1326 $pn = $wgTitle->getText();
1327 $tp = wfMsg( 'talkpage' );
1328 if ( Namespace::isTalk( $tns ) ) {
1329 $lns = Namespace::getSubject( $tns );
1332 $text = wfMsg('articlepage');
1335 $text = wfMsg('userpage');
1338 $text = wfMsg('wikipediapage');
1341 $text = wfMsg('imagepage');
1344 $text= wfMsg('articlepage');
1348 $lns = Namespace::getTalk( $tns );
1351 $n = $wgLang->getNsText( $lns );
1352 if ( '' == $n ) { $link = $pn; }
1353 else { $link = $n.':'.$pn; }
1355 $wgLinkCache->suspend();
1356 $s = $this->makeLink( $link, $text );
1357 $wgLinkCache->resume();
1362 function commentLink()
1364 global $wgLang, $wgTitle, $wgLinkCache;
1366 $tns = $wgTitle->getNamespace();
1367 if ( -1 == $tns ) { return ''; }
1369 $lns = ( Namespace::isTalk( $tns ) ) ?
$tns : Namespace::getTalk( $tns );
1371 # assert Namespace::isTalk( $lns )
1373 $n = $wgLang->getNsText( $lns );
1374 $pn = $wgTitle->getText();
1378 $wgLinkCache->suspend();
1379 $s = $this->makeKnownLink($link, wfMsg('postcomment'), 'action=edit§ion=new');
1380 $wgLinkCache->resume();
1385 # After all the page content is transformed into HTML, it makes
1386 # a final pass through here for things like table backgrounds.
1388 function transformContent( $text )
1393 # Note: This function MUST call getArticleID() on the link,
1394 # otherwise the cache won't get updated properly. See LINKCACHE.DOC.
1396 function makeLink( $title, $text = '', $query = '', $trail = '' ) {
1397 wfProfileIn( 'Skin::makeLink' );
1398 $nt = Title
::newFromText( $title );
1400 $result = $this->makeLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1402 wfDebug( 'Invalid title passed to Skin::makeLink(): "'.$title."\"\n" );
1403 $result = $text == "" ?
$title : $text;
1406 wfProfileOut( 'Skin::makeLink' );
1410 function makeKnownLink( $title, $text = '', $query = '', $trail = '', $prefix = '',$aprops = '') {
1411 $nt = Title
::newFromText( $title );
1413 return $this->makeKnownLinkObj( Title
::newFromText( $title ), $text, $query, $trail, $prefix , $aprops );
1415 wfDebug( 'Invalid title passed to Skin::makeKnownLink(): "'.$title."\"\n" );
1416 return $text == '' ?
$title : $text;
1420 function makeBrokenLink( $title, $text = '', $query = '', $trail = '' ) {
1421 $nt = Title
::newFromText( $title );
1423 return $this->makeBrokenLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1425 wfDebug( 'Invalid title passed to Skin::makeBrokenLink(): "'.$title."\"\n" );
1426 return $text == '' ?
$title : $text;
1430 function makeStubLink( $title, $text = '', $query = '', $trail = '' ) {
1431 $nt = Title
::newFromText( $title );
1433 return $this->makeStubLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1435 wfDebug( 'Invalid title passed to Skin::makeStubLink(): "'.$title."\"\n" );
1436 return $text == '' ?
$title : $text;
1440 # Pass a title object, not a title string
1441 function makeLinkObj( &$nt, $text= '', $query = '', $trail = '', $prefix = '' )
1443 global $wgOut, $wgUser, $wgLoadBalancer;
1444 if ( $nt->isExternal() ) {
1445 $u = $nt->getFullURL();
1446 $link = $nt->getPrefixedURL();
1447 if ( '' == $text ) { $text = $nt->getPrefixedText(); }
1448 $style = $this->getExternalLinkAttributes( $link, $text, 'extiw' );
1451 if ( '' != $trail ) {
1452 if ( preg_match( '/^([a-z]+)(.*)$$/sD', $trail, $m ) ) {
1457 $retVal = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1458 } elseif ( 0 == $nt->getNamespace() && "" == $nt->getText() ) {
1459 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1460 } elseif ( ( -1 == $nt->getNamespace() ) ||
1461 ( Namespace::getImage() == $nt->getNamespace() ) ) {
1462 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1464 $aid = $nt->getArticleID() ;
1466 $retVal = $this->makeBrokenLinkObj( $nt, $text, $query, $trail, $prefix );
1468 $threshold = $wgUser->getOption('stubthreshold') ;
1469 if ( $threshold > 0 ) {
1470 $wgLoadBalancer->force(-1);
1471 $res = wfQuery ( "SELECT LENGTH(cur_text) AS x, cur_namespace, cur_is_redirect FROM cur WHERE cur_id='{$aid}'", DB_READ
) ;
1472 $wgLoadBalancer->force(0);
1473 if ( wfNumRows( $res ) > 0 ) {
1474 $s = wfFetchObject( $res );
1476 if ( $s->cur_is_redirect
OR $s->cur_namespace
!= 0 ) {
1477 $size = $threshold*2 ; # Really big
1479 wfFreeResult( $res );
1481 $size = $threshold*2 ; # Really big
1486 if ( $size < $threshold ) {
1487 $retVal = $this->makeStubLinkObj( $nt, $text, $query, $trail, $prefix );
1489 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1496 # Pass a title object, not a title string
1497 function makeKnownLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' , $aprops = '')
1499 global $wgOut, $wgTitle, $wgInputEncoding;
1501 $fname = 'Skin::makeKnownLinkObj';
1502 wfProfileIn( $fname );
1504 if ( !is_object( $nt ) ) {
1507 $link = $nt->getPrefixedURL();
1509 if ( '' == $link ) {
1511 if ( '' == $text ) {
1512 $text = htmlspecialchars( $nt->getFragment() );
1515 $u = $nt->escapeLocalURL( $query );
1517 if ( '' != $nt->getFragment() ) {
1518 $anchor = urlencode( do_html_entity_decode( str_replace(' ', '_', $nt->getFragment()), ENT_COMPAT
, $wgInputEncoding ) );
1519 $replacearray = array(
1523 $u .= '#' . str_replace(array_keys($replacearray),array_values($replacearray),$anchor);
1525 if ( '' == $text ) {
1526 $text = htmlspecialchars( $nt->getPrefixedText() );
1528 $style = $this->getInternalLinkAttributesObj( $nt, $text );
1531 if ( '' != $trail ) {
1532 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1537 $r = "<a href=\"{$u}\"{$style}{$aprops}>{$prefix}{$text}{$inside}</a>{$trail}";
1538 wfProfileOut( $fname );
1542 # Pass a title object, not a title string
1543 function makeBrokenLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
1545 global $wgOut, $wgUser;
1547 $fname = 'Skin::makeBrokenLinkObj';
1548 wfProfileIn( $fname );
1550 if ( '' == $query ) {
1553 $q = 'action=edit&'.$query;
1555 $u = $nt->escapeLocalURL( $q );
1557 if ( '' == $text ) {
1558 $text = htmlspecialchars( $nt->getPrefixedText() );
1560 $style = $this->getInternalLinkAttributesObj( $nt, $text, "yes" );
1563 if ( '' != $trail ) {
1564 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1569 if ( $wgUser->getOption( 'highlightbroken' ) ) {
1570 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1572 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>?</a>{$trail}";
1575 wfProfileOut( $fname );
1579 # Pass a title object, not a title string
1580 function makeStubLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
1582 global $wgOut, $wgUser;
1584 $link = $nt->getPrefixedURL();
1586 $u = $nt->escapeLocalURL( $query );
1588 if ( '' == $text ) {
1589 $text = htmlspecialchars( $nt->getPrefixedText() );
1591 $style = $this->getInternalLinkAttributesObj( $nt, $text, 'stub' );
1594 if ( '' != $trail ) {
1595 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1600 if ( $wgUser->getOption( 'highlightbroken' ) ) {
1601 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1603 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>!</a>{$trail}";
1608 function makeSelfLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
1610 $u = $nt->escapeLocalURL( $query );
1611 if ( '' == $text ) {
1612 $text = htmlspecialchars( $nt->getPrefixedText() );
1615 if ( '' != $trail ) {
1616 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1621 return "<strong>{$prefix}{$text}{$inside}</strong>{$trail}";
1624 /* these are used extensively in SkinPHPTal, but also some other places */
1625 /*static*/ function makeSpecialUrl( $name, $urlaction='' ) {
1626 $title = Title
::makeTitle( NS_SPECIAL
, $name );
1627 $this->checkTitle($title, $name);
1628 return $title->getLocalURL( $urlaction );
1630 /*static*/ function makeTalkUrl ( $name, $urlaction='' ) {
1631 $title = Title
::newFromText( $name );
1632 $title = $title->getTalkPage();
1633 $this->checkTitle($title, $name);
1634 return $title->getLocalURL( $urlaction );
1636 /*static*/ function makeArticleUrl ( $name, $urlaction='' ) {
1637 $title = Title
::newFromText( $name );
1638 $title= $title->getSubjectPage();
1639 $this->checkTitle($title, $name);
1640 return $title->getLocalURL( $urlaction );
1642 /*static*/ function makeI18nUrl ( $name, $urlaction='' ) {
1643 $title = Title
::newFromText( wfMsg($name) );
1644 $this->checkTitle($title, $name);
1645 return $title->getLocalURL( $urlaction );
1647 /*static*/ function makeUrl ( $name, $urlaction='' ) {
1648 $title = Title
::newFromText( $name );
1649 $this->checkTitle($title, $name);
1650 return $title->getLocalURL( $urlaction );
1652 # this can be passed the NS number as defined in Language.php
1653 /*static*/ function makeNSUrl( $name, $urlaction='', $namespace=0 ) {
1654 $title = Title
::makeTitle( $namespace, $name );
1655 $this->checkTitle($title, $name);
1656 return $title->getLocalURL( $urlaction );
1659 /* these return an array with the 'href' and boolean 'exists' */
1660 /*static*/ function makeUrlDetails ( $name, $urlaction='' ) {
1661 $title = Title
::newFromText( $name );
1662 $this->checkTitle($title, $name);
1664 'href' => $title->getLocalURL( $urlaction ),
1665 'exists' => $title->getArticleID() != 0?
true:false
1668 /*static*/ function makeTalkUrlDetails ( $name, $urlaction='' ) {
1669 $title = Title
::newFromText( $name );
1670 $title = $title->getTalkPage();
1671 $this->checkTitle($title, $name);
1673 'href' => $title->getLocalURL( $urlaction ),
1674 'exists' => $title->getArticleID() != 0?
true:false
1677 /*static*/ function makeArticleUrlDetails ( $name, $urlaction='' ) {
1678 $title = Title
::newFromText( $name );
1679 $title= $title->getSubjectPage();
1680 $this->checkTitle($title, $name);
1682 'href' => $title->getLocalURL( $urlaction ),
1683 'exists' => $title->getArticleID() != 0?
true:false
1686 /*static*/ function makeI18nUrlDetails ( $name, $urlaction='' ) {
1687 $title = Title
::newFromText( wfMsg($name) );
1688 $this->checkTitle($title, $name);
1690 'href' => $title->getLocalURL( $urlaction ),
1691 'exists' => $title->getArticleID() != 0?
true:false
1695 # make sure we have some title to operate on
1696 /*static*/ function checkTitle ( &$title, &$name ) {
1697 if(!is_object($title)) {
1698 $title = Title
::newFromText( $name );
1699 if(!is_object($title)) {
1700 $title = Title
::newFromText( '--error: link target missing--' );
1705 function fnamePart( $url )
1707 $basename = strrchr( $url, '/' );
1708 if ( false === $basename ) { $basename = $url; }
1709 else { $basename = substr( $basename, 1 ); }
1710 return wfEscapeHTML( $basename );
1713 function makeImage( $url, $alt = '' )
1717 if ( '' == $alt ) { $alt = $this->fnamePart( $url ); }
1718 $s = '<img src="'.$url.'" alt="'.$alt.'" />';
1722 function makeImageLink( $name, $url, $alt = '' ) {
1723 $nt = Title
::makeTitle( Namespace::getImage(), $name );
1724 return $this->makeImageLinkObj( $nt, $alt );
1727 function makeImageLinkObj( $nt, $alt = '' ) {
1728 global $wgLang, $wgUseImageResize;
1729 $img = Image
::newFromTitle( $nt );
1730 $url = $img->getURL();
1733 $prefix = $postfix = '';
1735 if ( $wgUseImageResize ) {
1736 # Check if the alt text is of the form "options|alt text"
1738 # * thumbnail make a thumbnail with enlarge-icon and caption, alignment depends on lang
1739 # * left no resizing, just left align. label is used for alt= only
1740 # * right same, but right aligned
1741 # * none same, but not aligned
1742 # * ___px scale to ___ pixels width, no aligning. e.g. use in taxobox
1743 # * center center the image
1744 # * framed Keep original image size, no magnify-button.
1746 $part = explode( '|', $alt);
1748 $mwThumb =& MagicWord
::get( MAG_IMG_THUMBNAIL
);
1749 $mwLeft =& MagicWord
::get( MAG_IMG_LEFT
);
1750 $mwRight =& MagicWord
::get( MAG_IMG_RIGHT
);
1751 $mwNone =& MagicWord
::get( MAG_IMG_NONE
);
1752 $mwWidth =& MagicWord
::get( MAG_IMG_WIDTH
);
1753 $mwCenter =& MagicWord
::get( MAG_IMG_CENTER
);
1754 $mwFramed =& MagicWord
::get( MAG_IMG_FRAMED
);
1755 $alt = $part[count($part)-1];
1757 $height = $framed = $thumb = false;
1759 foreach( $part as $key => $val ) {
1760 if ( ! is_null( $mwThumb->matchVariableStartToEnd($val) ) ) {
1762 } elseif ( ! is_null( $mwRight->matchVariableStartToEnd($val) ) ) {
1763 # remember to set an alignment, don't render immediately
1765 } elseif ( ! is_null( $mwLeft->matchVariableStartToEnd($val) ) ) {
1766 # remember to set an alignment, don't render immediately
1768 } elseif ( ! is_null( $mwCenter->matchVariableStartToEnd($val) ) ) {
1769 # remember to set an alignment, don't render immediately
1771 } elseif ( ! is_null( $mwNone->matchVariableStartToEnd($val) ) ) {
1772 # remember to set an alignment, don't render immediately
1774 } elseif ( ! is_null( $match = $mwWidth->matchVariableStartToEnd($val) ) ) {
1775 # $match is the image width in pixels
1776 if ( preg_match( '/^([0-9]*)x([0-9]*)$/', $match, $m ) ) {
1777 $width = intval( $m[1] );
1778 $height = intval( $m[2] );
1780 $width = intval($match);
1782 } elseif ( ! is_null( $mwFramed->matchVariableStartToEnd($val) ) ) {
1786 if ( 'center' == $align )
1788 $prefix = '<span style="text-align: center">';
1789 $postfix = '</span>';
1793 if ( $thumb ||
$framed ) {
1795 # Create a thumbnail. Alignment depends on language
1796 # writing direction, # right aligned for left-to-right-
1797 # languages ("Western languages"), left-aligned
1798 # for right-to-left-languages ("Semitic languages")
1800 # If thumbnail width has not been provided, it is set
1801 # here to 180 pixels
1802 if ( $align == '' ) {
1803 $align = $wgLang->isRTL() ?
'left' : 'right';
1805 if ( ! isset($width) ) {
1808 return $prefix.$this->makeThumbLinkObj( $img, $alt, $align, $width, $height, $framed ).$postfix;
1810 } elseif ( isset($width) ) {
1812 # Create a resized image, without the additional thumbnail
1815 if ( ( ! $height === false )
1816 && ( $img->getHeight() * $width / $img->getWidth() > $height ) ) {
1817 print "height=$height<br>\nimg->getHeight() = ".$img->getHeight()."<br>\n";
1818 print 'rescaling by factor '. $height / $img->getHeight() . "<br>\n";
1819 $width = $img->getWidth() * $height / $img->getHeight();
1821 $url = $img->createThumb( $width );
1823 } # endif $wgUseImageResize
1825 if ( empty( $alt ) ) {
1826 $alt = preg_replace( '/\.(.+?)^/', '', $img->getName() );
1828 $alt = htmlspecialchars( $alt );
1830 $u = $nt->escapeLocalURL();
1833 $s = str_replace( "$1", $img->getName(), wfMsg('missingimage') );
1834 $s .= "<br>{$alt}<br>{$url}<br>\n";
1836 $s = '<a href="'.$u.'" class="image" title="'.$alt.'">' .
1837 '<img src="'.$url.'" alt="'.$alt.'" /></a>';
1839 if ( '' != $align ) {
1840 $s = "<div class=\"float{$align}\"><span>{$s}</span></div>";
1842 return str_replace("\n", ' ',$prefix.$s.$postfix);
1846 function makeThumbLinkObj( $img, $label = '', $align = 'right', $boxwidth = 180, $boxheight=false, $framed=false ) {
1847 global $wgStylePath, $wgLang;
1848 # $image = Title::makeTitle( Namespace::getImage(), $name );
1849 $url = $img->getURL();
1851 #$label = htmlspecialchars( $label );
1852 $alt = preg_replace( '/<[^>]*>/', '', $label);
1853 $alt = htmlspecialchars( $alt );
1855 if ( $img->exists() )
1857 $width = $img->getWidth();
1858 $height = $img->getHeight();
1860 $width = $height = 200;
1864 // Use image dimensions, don't scale
1866 $oboxwidth = $boxwidth +
2;
1867 $boxheight = $height;
1870 $h = intval( $height/($width/$boxwidth) );
1871 $oboxwidth = $boxwidth +
2;
1872 if ( ( ! $boxheight === false ) && ( $h > $boxheight ) )
1874 $boxwidth *= $boxheight/$h;
1878 $thumbUrl = $img->createThumb( $boxwidth );
1881 $u = $img->getEscapeLocalURL();
1883 $more = htmlspecialchars( wfMsg( 'thumbnail-more' ) );
1884 $magnifyalign = $wgLang->isRTL() ?
'left' : 'right';
1885 $textalign = $wgLang->isRTL() ?
' style="text-align:right"' : '';
1887 $s = "<div class=\"thumb t{$align}\"><div style=\"width:{$oboxwidth}px;\">";
1888 if ( $thumbUrl == '' ) {
1889 $s .= str_replace( "$1", $img->getName(), wfMsg('missingimage') );
1892 $s .= '<a href="'.$u.'" class="internal" title="'.$alt.'">'.
1893 '<img src="'.$thumbUrl.'" alt="'.$alt.'" ' .
1894 'width="'.$boxwidth.'" height="'.$boxheight.'" /></a>';
1898 $zoomicon = '<div class="magnify" style="float:'.$magnifyalign.'">'.
1899 '<a href="'.$u.'" class="internal" title="'.$more.'">'.
1900 '<img src="'.$wgStylePath.'/images/magnify-clip.png" ' .
1901 'width="15" height="11" alt="'.$more.'" /></a></div>';
1904 $s .= ' <div class="thumbcaption" '.$textalign.'>'.$zoomicon.$label."</div></div></div>";
1905 return str_replace("\n", ' ', $s);
1908 function makeMediaLink( $name, $url, $alt = "" ) {
1909 $nt = Title
::makeTitle( Namespace::getMedia(), $name );
1910 return $this->makeMediaLinkObj( $nt, $alt );
1913 function makeMediaLinkObj( $nt, $alt = "" )
1915 if ( ! isset( $nt ) )
1917 ### HOTFIX. Instead of breaking, return empry string.
1920 $name = $nt->getDBKey();
1921 $url = Image
::wfImageUrl( $name );
1922 if ( empty( $alt ) ) {
1923 $alt = preg_replace( '/\.(.+?)^/', '', $name );
1926 $u = htmlspecialchars( $url );
1927 $s = "<a href=\"{$u}\" class='internal' title=\"{$alt}\">{$alt}</a>";
1932 function specialLink( $name, $key = "" )
1936 if ( '' == $key ) { $key = strtolower( $name ); }
1937 $pn = $wgLang->ucfirst( $name );
1938 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1942 function makeExternalLink( $url, $text, $escape = true ) {
1943 $style = $this->getExternalLinkAttributes( $url, $text );
1944 $url = htmlspecialchars( $url );
1946 $text = htmlspecialchars( $text );
1948 return '<a href="'.$url.'"'.$style.'>'.$text.'</a>';
1951 # Called by history lists and recent changes
1954 # Returns text for the start of the tabular part of RC
1955 function beginRecentChangesList()
1957 $this->rc_cache
= array() ;
1958 $this->rcMoveIndex
= 0;
1959 $this->rcCacheIndex
= 0 ;
1960 $this->lastdate
= '';
1961 $this->rclistOpen
= false;
1965 function beginImageHistoryList()
1967 $s = "\n<h2>" . wfMsg( 'imghistory' ) . "</h2>\n" .
1968 "<p>" . wfMsg( 'imghistlegend' ) . "</p>\n".'<ul class="special">';
1972 # Returns text for the end of RC
1973 # If enhanced RC is in use, returns pretty much all the text
1974 function endRecentChangesList()
1976 $s = $this->recentChangesBlock() ;
1977 if( $this->rclistOpen
) {
1983 # Enhanced RC ungrouped line
1984 function recentChangesBlockLine ( $rcObj )
1986 global $wgStylePath, $wgLang ;
1988 # Get rc_xxxx variables
1989 extract( $rcObj->mAttribs
) ;
1990 $curIdEq = 'curid='.$rc_cur_id;
1995 $r .= '<img src="'.$wgStylePath.'/images/Arr_.png" width="12" height="12" border="0" />' ;
1998 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
1999 $r .= ' ';
2001 # M & N (minor & new)
2002 $M = wfMsg( 'minoreditletter' );
2003 $N = wfMsg( 'newpageletter' );
2005 if ( $rc_type == RC_NEW
) {
2018 $r .= ' '.$rcObj->timestamp
.' ' ;
2022 $link = $rcObj->link
;
2023 if ( $rcObj->watched
) $link = '<strong>'.$link.'</strong>' ;
2028 $r .= $rcObj->difflink
;
2032 $r .= $this->makeKnownLinkObj( $rcObj->getTitle(), wfMsg( 'hist' ), $curIdEq.'&action=history' );
2035 $r .= ') . . '.$rcObj->userlink
;
2036 $r .= $rcObj->usertalklink
;
2039 if ( $rc_comment != '' && $rc_type != RC_MOVE
&& $rc_type != RC_MOVE_OVER_REDIRECT
) {
2040 $rc_comment=$this->formatComment($rc_comment);
2041 $r .= $wgLang->emphasize( ' ('.$rc_comment.')' );
2049 function recentChangesBlockGroup ( $block )
2051 global $wgStylePath, $wgLang ;
2054 $M = wfMsg( 'minoreditletter' );
2055 $N = wfMsg( 'newpageletter' );
2057 # Collate list of users
2059 $userlinks = array () ;
2060 foreach ( $block AS $rcObj ) {
2061 $oldid = $rcObj->mAttribs
['rc_last_oldid'];
2062 if ( $rcObj->mAttribs
['rc_new'] ) $isnew = true ;
2063 $u = $rcObj->userlink
;
2064 if ( !isset ( $userlinks[$u] ) ) $userlinks[$u] = 0 ;
2068 # Sort the list and convert to text
2069 krsort ( $userlinks ) ;
2070 asort ( $userlinks ) ;
2072 foreach ( $userlinks as $userlink => $count) {
2074 if ( $count > 1 ) $text .= " ({$count}×)" ;
2075 array_push ( $users , $text ) ;
2077 $users = ' <font size="-1">['.implode('; ',$users).']</font>' ;
2080 $rci = 'RCI'.$this->rcCacheIndex
;
2081 $rcl = 'RCL'.$this->rcCacheIndex
;
2082 $rcm = 'RCM'.$this->rcCacheIndex
;
2083 $toggleLink = "javascript:toggleVisibility('$rci','$rcm','$rcl')" ;
2084 $arrowdir = $wgLang->isRTL() ?
'l' : 'r';
2085 $tl = '<span id="'.$rcm.'"><a href="'.$toggleLink.'"><img src="'.$wgStylePath.'/images/Arr_'.$arrowdir.'.png" width="12" height="12" /></a></span>' ;
2086 $tl .= '<span id="'.$rcl.'" style="display:none"><a href="'.$toggleLink.'"><img src="'.$wgStylePath.'/images/Arr_d.png" width="12" height="12" /></a></span>' ;
2092 if ( $isnew ) $r .= $N ;
2093 else $r .= ' ' ;
2094 $r .= ' ' ; # Minor
2097 $r .= ' '.$block[0]->timestamp
.' ' ;
2101 $link = $block[0]->link
;
2102 if ( $block[0]->watched
) $link = '<strong>'.$link.'</strong>' ;
2105 $curIdEq = 'curid=' . $block[0]->mAttribs
['rc_cur_id'];
2106 if ( $block[0]->mAttribs
['rc_type'] != RC_LOG
) {
2108 $r .= ' ('.count($block).' ' ;
2109 if ( $isnew ) $r .= wfMsg('changes');
2110 else $r .= $this->makeKnownLinkObj( $block[0]->getTitle() , wfMsg('changes') ,
2111 $curIdEq.'&diff=0&oldid='.$oldid ) ;
2115 $r .= $this->makeKnownLinkObj( $block[0]->getTitle(), wfMsg( 'history' ), $curIdEq.'&action=history' );
2123 $r .= '<div id="'.$rci.'" style="display:none">' ;
2124 foreach ( $block AS $rcObj ) {
2125 # Get rc_xxxx variables
2126 extract( $rcObj->mAttribs
);
2128 $r .= '<img src="'.$wgStylePath.'/images/Arr_.png" width="12" height="12" />';
2129 $r .= '<tt> ' ;
2130 if ( $rc_new ) $r .= $N ;
2131 else $r .= ' ' ;
2132 if ( $rc_minor ) $r .= $M ;
2133 else $r .= ' ' ;
2137 if ( $rc_last_oldid != 0 ) {
2138 $o = 'oldid='.$rc_last_oldid ;
2140 if ( $rc_type == RC_LOG
) {
2141 $link = $rcObj->timestamp
;
2143 $link = $this->makeKnownLinkObj( $rcObj->getTitle(), $rcObj->timestamp
, "{$curIdEq}&$o" ) ;
2145 $link = '<tt>'.$link.'</tt>' ;
2149 $r .= $rcObj->curlink
;
2151 $r .= $rcObj->lastlink
;
2152 $r .= ') . . '.$rcObj->userlink
;
2153 $r .= $rcObj->usertalklink
;
2154 if ( $rc_comment != '' ) {
2155 $rc_comment=$this->formatComment($rc_comment);
2156 $r .= $wgLang->emphasize( ' ('.$rc_comment.')' ) ;
2162 $this->rcCacheIndex++
;
2166 # If enhanced RC is in use, this function takes the previously cached
2167 # RC lines, arranges them, and outputs the HTML
2168 function recentChangesBlock ()
2170 global $wgStylePath ;
2171 if ( count ( $this->rc_cache
) == 0 ) return '' ;
2173 foreach ( $this->rc_cache
AS $secureName => $block ) {
2174 if ( count ( $block ) < 2 ) {
2175 $blockOut .= $this->recentChangesBlockLine ( array_shift ( $block ) ) ;
2177 $blockOut .= $this->recentChangesBlockGroup ( $block ) ;
2181 return '<div>'.$blockOut.'</div>' ;
2184 # Called in a loop over all displayed RC entries
2185 # Either returns the line, or caches it for later use
2186 function recentChangesLine( &$rc, $watched = false )
2189 $usenew = $wgUser->getOption( 'usenewrc' );
2191 $line = $this->recentChangesLineNew ( $rc, $watched ) ;
2193 $line = $this->recentChangesLineOld ( $rc, $watched ) ;
2197 function recentChangesLineOld( &$rc, $watched = false )
2199 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds;
2201 # Extract DB fields into local scope
2202 extract( $rc->mAttribs
);
2203 $curIdEq = 'curid=' . $rc_cur_id;
2205 # Make date header if necessary
2206 $date = $wgLang->date( $rc_timestamp, true);
2208 if ( $date != $this->lastdate
) {
2209 if ( '' != $this->lastdate
) { $s .= "</ul>\n"; }
2210 $s .= "<h4>{$date}</h4>\n<ul class='special'>";
2211 $this->lastdate
= $date;
2212 $this->rclistOpen
= true;
2216 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2218 $s .= '(' . wfMsg( 'diff' ) . ') (';
2220 $s .= $this->makeKnownLinkObj( $rc->getMovedToTitle(), wfMsg( 'hist' ), 'action=history' ) .
2223 # "[[x]] moved to [[y]]"
2224 if ( $rc_type == RC_MOVE
) {
2227 $msg = '1movedto2_redir';
2229 $s .= wfMsg( $msg, $this->makeKnownLinkObj( $rc->getTitle(), '', 'redirect=no' ),
2230 $this->makeKnownLinkObj( $rc->getMovedToTitle(), '' ) );
2233 if ( $rc_type == RC_NEW ||
$rc_type == RC_LOG
) {
2234 $diffLink = wfMsg( 'diff' );
2236 $diffLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'diff' ),
2237 $curIdEq.'&diff='.$rc_this_oldid.'&oldid='.$rc_last_oldid ,'' ,'' , ' tabindex="'.$rc->counter
.'"');
2239 $s .= '('.$diffLink.') (';
2242 $s .= $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'hist' ), $curIdEq.'&action=history' );
2245 # M and N (minor and new)
2246 $M = wfMsg( 'minoreditletter' );
2247 $N = wfMsg( 'newpageletter' );
2248 if ( $rc_minor ) { $s .= ' <strong>'.$M.'</strong>'; }
2249 if ( $rc_type == RC_NEW
) { $s .= '<strong>'.$N.'</strong>'; }
2252 $articleLink = $this->makeKnownLinkObj( $rc->getTitle(), '' );
2255 $articleLink = '<strong>'.$articleLink.'</strong>';
2257 $s .= ' '.$articleLink;
2262 $s .= '; ' . $wgLang->time( $rc_timestamp, true, $wgRCSeconds ) . ' . . ';
2264 # User link (or contributions for unregistered users)
2265 if ( 0 == $rc_user ) {
2266 $userLink = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
2267 $rc_user_text, 'target=' . $rc_user_text );
2269 $userLink = $this->makeLink( $wgLang->getNsText( NS_USER
) . ':'.$rc_user_text, $rc_user_text );
2274 $talkname=$wgLang->getNsText(NS_TALK
); # use the shorter name
2275 global $wgDisableAnonTalk;
2276 if( 0 == $rc_user && $wgDisableAnonTalk ) {
2279 $utns=$wgLang->getNsText(NS_USER_TALK
);
2280 $userTalkLink= $this->makeLink($utns . ':'.$rc_user_text, $talkname );
2284 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2285 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2286 'Blockip' ), wfMsg( 'blocklink' ), 'ip='.$rc_user_text );
2290 if($userTalkLink) $userTalkLink .= ' | ';
2291 $userTalkLink .= $blockLink;
2293 if($userTalkLink) $s.=' ('.$userTalkLink.')';
2296 if ( '' != $rc_comment && '*' != $rc_comment && $rc_type != RC_MOVE
&& $rc_type != RC_MOVE_OVER_REDIRECT
) {
2297 $rc_comment=$this->formatComment($rc_comment);
2298 $s .= $wgLang->emphasize(' (' . $rc_comment . ')');
2305 # function recentChangesLineNew( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched = false, $oldid = 0 , $diffid = 0 )
2306 function recentChangesLineNew( &$baseRC, $watched = false )
2308 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds;
2310 # Create a specialised object
2311 $rc = RCCacheEntry
::newFromParent( $baseRC ) ;
2313 # Extract fields from DB into the function scope (rc_xxxx variables)
2314 extract( $rc->mAttribs
);
2315 $curIdEq = 'curid=' . $rc_cur_id;
2317 # If it's a new day, add the headline and flush the cache
2318 $date = $wgLang->date( $rc_timestamp, true);
2320 if ( $date != $this->lastdate
) {
2321 # Process current cache
2322 $ret = $this->recentChangesBlock () ;
2323 $this->rc_cache
= array() ;
2324 $ret .= "<h4>{$date}</h4>\n";
2325 $this->lastdate
= $date;
2329 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2330 if ( $rc_type == RC_MOVE
) {
2333 $msg = "1movedto2_redir";
2335 $clink = wfMsg( $msg, $this->makeKnownLinkObj( $rc->getTitle(), '', 'redirect=no' ),
2336 $this->makeKnownLinkObj( $rc->getMovedToTitle(), '' ) );
2338 $clink = $this->makeKnownLinkObj( $rc->getTitle(), '' ) ;
2341 $time = $wgLang->time( $rc_timestamp, true, $wgRCSeconds );
2342 $rc->watched
= $watched ;
2343 $rc->link
= $clink ;
2344 $rc->timestamp
= $time;
2346 # Make "cur" and "diff" links
2347 if ( ( $rc_type == RC_NEW
&& $rc_this_oldid == 0 ) ||
$rc_type == RC_LOG ||
$rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2348 $curLink = wfMsg( 'cur' );
2349 $diffLink = wfMsg( 'diff' );
2351 $query = $curIdEq.'&diff=0&oldid='.$rc_this_oldid;
2352 $aprops = ' tabindex="'.$baseRC->counter
.'"';
2353 $curLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'cur' ), $query, '' ,'' , $aprops );
2354 $diffLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'diff'), $query, '' ,'' , $aprops );
2358 $titleObj = $rc->getTitle();
2359 if ( $rc_last_oldid == 0 ||
$rc_type == RC_LOG ||
$rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2360 $lastLink = wfMsg( 'last' );
2362 $lastLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'last' ),
2363 $curIdEq.'&diff='.$rc_this_oldid.'&oldid='.$rc_last_oldid );
2366 # Make user link (or user contributions for unregistered users)
2367 if ( 0 == $rc_user ) {
2368 $userLink = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
2369 $rc_user_text, 'target=' . $rc_user_text );
2371 $userLink = $this->makeLink( $wgLang->getNsText(
2372 Namespace::getUser() ) . ':'.$rc_user_text, $rc_user_text );
2375 $rc->userlink
= $userLink ;
2376 $rc->lastlink
= $lastLink ;
2377 $rc->curlink
= $curLink ;
2378 $rc->difflink
= $diffLink;
2381 # Make user talk link
2382 $utns=$wgLang->getNsText(NS_USER_TALK
);
2383 $talkname=$wgLang->getNsText(NS_TALK
); # use the shorter name
2384 $userTalkLink= $this->makeLink($utns . ':'.$rc_user_text, $talkname );
2386 global $wgDisableAnonTalk;
2387 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2388 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2389 'Blockip' ), wfMsg( 'blocklink' ), 'ip='.$rc_user_text );
2390 if( $wgDisableAnonTalk )
2391 $rc->usertalklink
= ' ('.$blockLink.')';
2393 $rc->usertalklink
= ' ('.$userTalkLink.' | '.$blockLink.')';
2395 if( $wgDisableAnonTalk && ($rc_user == 0) )
2396 $rc->usertalklink
= '';
2398 $rc->usertalklink
= ' ('.$userTalkLink.')';
2401 # Put accumulated information into the cache, for later display
2402 # Page moves go on their own line
2403 $title = $rc->getTitle();
2404 $secureName = $title->getPrefixedDBkey();
2405 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2406 # Use an @ character to prevent collision with page names
2407 $this->rc_cache
['@@' . ($this->rcMoveIndex++
)] = array($rc);
2409 if ( !isset ( $this->rc_cache
[$secureName] ) ) $this->rc_cache
[$secureName] = array() ;
2410 array_push ( $this->rc_cache
[$secureName] , $rc ) ;
2415 function endImageHistoryList()
2421 /* This function is called by all recent changes variants, by the page history,
2422 and by the user contributions list. It is responsible for formatting edit
2423 comments. It escapes any HTML in the comment, but adds some CSS to format
2424 auto-generated comments (from section editing) and formats [[wikilinks]].
2425 Main author: Erik Möller (moeller@scireview.de)
2427 function formatComment($comment)
2430 $comment=wfEscapeHTML($comment);
2432 # The pattern for autogen comments is / * foo * /, which makes for
2434 # We look for all comments, match any text before and after the comment,
2435 # add a separator where needed and format the comment itself with CSS
2436 while (preg_match('/(.*)\/\*\s*(.*?)\s*\*\/(.*)/', $comment,$match)) {
2441 if($pre) { $auto = $sep.' '.$auto; }
2442 if($post) { $auto .= ' '.$sep; }
2443 $auto='<span class="autocomment">'.$auto.'</span>';
2444 $comment=$pre.$auto.$post;
2447 # format regular and media links - all other wiki formatting
2449 while(preg_match('/\[\[(.*?)(\|(.*?))*\]\]/',$comment,$match)) {
2451 $medians = $wgLang->getNsText(Namespace::getMedia()).':';
2453 if(preg_match('/^'.$medians.'/i',$match[1])) {
2454 $func='makeMediaLink';
2456 # Handle link renaming [[foo|text]] will show link as "text"
2457 if(isset($match[3]) ) {
2459 preg_replace('/\[\[(.*?)\]\]/',
2460 $this->$func($match[1],$match[3]),$comment,1);
2463 preg_replace('/\[\[(.*?)\]\]/',
2464 $this->$func($match[1],$match[1]),$comment,1);
2472 function imageHistoryLine( $iscur, $timestamp, $img, $user, $usertext, $size, $description )
2474 global $wgUser, $wgLang, $wgTitle;
2476 $datetime = $wgLang->timeanddate( $timestamp, true );
2477 $del = wfMsg( 'deleteimg' );
2478 $cur = wfMsg( 'cur' );
2481 $url = Image
::wfImageUrl( $img );
2483 if ( $wgUser->isSysop() ) {
2484 $link = $wgTitle->escapeLocalURL( 'image=' . $wgTitle->getPartialURL() .
2486 $style = $this->getInternalLinkAttributes( $link, $del );
2488 $dlink = '<a href="'.$link.'"'.$style.'>'.$del.'</a>';
2493 $url = wfEscapeHTML( wfImageArchiveUrl( $img ) );
2494 if( $wgUser->getID() != 0 ) {
2495 $rlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2496 wfMsg( 'revertimg' ), 'action=revert&oldimage=' .
2497 urlencode( $img ) );
2498 $dlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2499 $del, 'action=delete&oldimage=' . urlencode( $img ) );
2501 # Having live active links for non-logged in users
2502 # means that bots and spiders crawling our site can
2503 # inadvertently change content. Baaaad idea.
2504 $rlink = wfMsg( 'revertimg' );
2509 $userlink = $usertext;
2511 $userlink = $this->makeLink( $wgLang->getNsText( Namespace::getUser() ) .
2512 ':'.$usertext, $usertext );
2514 $nbytes = wfMsg( 'nbytes', $size );
2515 $style = $this->getInternalLinkAttributes( $url, $datetime );
2517 $s = "<li> ({$dlink}) ({$rlink}) <a href=\"{$url}\"{$style}>{$datetime}</a>"
2518 . " . . {$userlink} ({$nbytes})";
2520 if ( '' != $description && '*' != $description ) {
2521 $sk=$wgUser->getSkin();
2522 $s .= $wgLang->emphasize(' (' . $sk->formatComment($description) . ')');
2528 function tocIndent($level) {
2529 return str_repeat( '<div class="tocindent">'."\n", $level>0 ?
$level : 0 );
2532 function tocUnindent($level) {
2533 return str_repeat( "</div>\n", $level>0 ?
$level : 0 );
2536 # parameter level defines if we are on an indentation level
2537 function tocLine( $anchor, $tocline, $level ) {
2538 $link = '<a href="#'.$anchor.'">'.$tocline.'</a><br />';
2542 return '<div class="tocline">'.$link."</div>\n";
2547 function tocTable($toc) {
2548 # note to CSS fanatics: putting this in a div does not work -- div won't auto-expand
2549 # try min-width & co when somebody gets a chance
2550 $hideline = ' <script type="text/javascript">showTocToggle("' . addslashes( wfMsg('showtoc') ) . '","' . addslashes( wfMsg('hidetoc') ) . '")</script>';
2552 '<table border="0" id="toc"><tr id="toctitle"><td align="center">'."\n".
2553 '<b>'.wfMsg('toc').'</b>' .
2555 '</td></tr><tr id="tocinside"><td>'."\n".
2556 $toc."</td></tr></table>\n";
2559 # These two do not check for permissions: check $wgTitle->userCanEdit before calling them
2560 function editSectionScript( $section, $head ) {
2561 global $wgTitle, $wgRequest;
2562 if( $wgRequest->getInt( 'oldid' ) && ( $wgRequest->getVal( 'diff' ) != '0' ) ) {
2565 $url = $wgTitle->escapeLocalURL( 'action=edit§ion='.$section );
2566 return '<span oncontextmenu=\'document.location="'.$url.'";return false;\'>'.$head.'</span>';
2569 function editSectionLink( $section ) {
2571 global $wgTitle, $wgUser, $wgLang;
2573 if( $wgRequest->getInt( 'oldid' ) && ( $wgRequest->getVal( 'diff' ) != '0' ) ) {
2574 # Section edit links would be out of sync on an old page.
2575 # But, if we're diffing to the current page, they'll be
2580 $editurl = '§ion='.$section;
2581 $url = $this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg('editsection'),'action=edit'.$editurl);
2583 if( $wgLang->isRTL() ) {
2585 $nearside = 'right';
2590 return "<div class=\"editsection\" style=\"float:$farside;margin-$nearside:5px;\">[".$url."]</div>";
2594 // This function is called by EditPage.php and shows a bulletin board style
2595 // toolbar for common editing functions. It can be disabled in the user preferences.
2596 // The necsesary JavaScript code can be found in style/wikibits.js.
2597 function getEditToolbar() {
2598 global $wgStylePath, $wgLang, $wgMimeType;
2600 // toolarray an array of arrays which each include the filename of
2601 // the button image (without path), the opening tag, the closing tag,
2602 // and optionally a sample text that is inserted between the two when no
2603 // selection is highlighted.
2604 // The tip text is shown when the user moves the mouse over the button.
2606 // Already here are accesskeys (key), which are not used yet until someone
2607 // can figure out a way to make them work in IE. However, we should make
2608 // sure these keys are not defined on the edit page.
2610 array( 'image'=>'button_bold.png',
2613 'sample'=>wfMsg('bold_sample'),
2614 'tip'=>wfMsg('bold_tip'),
2617 array( "image"=>"button_italic.png",
2620 "sample"=>wfMsg("italic_sample"),
2621 "tip"=>wfMsg("italic_tip"),
2624 array( "image"=>"button_link.png",
2627 "sample"=>wfMsg("link_sample"),
2628 "tip"=>wfMsg("link_tip"),
2631 array( "image"=>"button_extlink.png",
2634 "sample"=>wfMsg("extlink_sample"),
2635 "tip"=>wfMsg("extlink_tip"),
2638 array( "image"=>"button_headline.png",
2641 "sample"=>wfMsg("headline_sample"),
2642 "tip"=>wfMsg("headline_tip"),
2645 array( "image"=>"button_image.png",
2646 "open"=>"[[".$wgLang->getNsText(NS_IMAGE
).":",
2648 "sample"=>wfMsg("image_sample"),
2649 "tip"=>wfMsg("image_tip"),
2652 array( "image"=>"button_media.png",
2653 "open"=>"[[".$wgLang->getNsText(NS_MEDIA
).":",
2655 "sample"=>wfMsg("media_sample"),
2656 "tip"=>wfMsg("media_tip"),
2659 array( "image"=>"button_math.png",
2660 "open"=>"\\<math\\>",
2661 "close"=>"\\</math\\>",
2662 "sample"=>wfMsg("math_sample"),
2663 "tip"=>wfMsg("math_tip"),
2666 array( "image"=>"button_nowiki.png",
2667 "open"=>"\\<nowiki\\>",
2668 "close"=>"\\</nowiki\\>",
2669 "sample"=>wfMsg("nowiki_sample"),
2670 "tip"=>wfMsg("nowiki_tip"),
2673 array( "image"=>"button_sig.png",
2677 "tip"=>wfMsg("sig_tip"),
2680 array( "image"=>"button_hr.png",
2681 "open"=>"\\n----\\n",
2684 "tip"=>wfMsg("hr_tip"),
2688 $toolbar ="<script type='text/javascript'>\n/*<![CDATA[*/\n";
2690 $toolbar.="document.writeln(\"<div id='toolbar'>\");\n";
2691 foreach($toolarray as $tool) {
2693 $image=$wgStylePath.'/images/'.$tool['image'];
2694 $open=$tool['open'];
2695 $close=$tool['close'];
2696 $sample = addslashes( $tool['sample'] );
2698 // Note that we use the tip both for the ALT tag and the TITLE tag of the image.
2699 // Older browsers show a "speedtip" type message only for ALT.
2700 // Ideally these should be different, realistically they
2701 // probably don't need to be.
2702 $tip = addslashes( $tool['tip'] );
2704 #$key = $tool["key"];
2706 $toolbar.="addButton('$image','$tip','$open','$close','$sample');\n";
2709 $toolbar.="addInfobox('" . addslashes( wfMsg( "infobox" ) ) . "','" . addslashes(wfMsg("infobox_alert")) . "');\n";
2710 $toolbar.="document.writeln(\"</div>\");\n";
2712 $toolbar.="/*]]>*/\n</script>";