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;
322 return $this->doBeforeContent();
325 function doBeforeContent()
327 global $wgUser, $wgOut, $wgTitle, $wgLang, $wgSiteNotice;
328 $fname = 'Skin::doBeforeContent';
329 wfProfileIn( $fname );
332 $qb = $this->qbSetting();
334 if( $langlinks = $this->otherLanguages() ) {
340 $borderhack = 'class="top"';
343 $s .= "\n<div id='content'>\n<div id='topbar'>\n" .
344 "<table border='0' cellspacing='0' width='98%'>\n<tr>\n";
347 $left = ($qb == 1 ||
$qb == 3);
348 if($wgLang->isRTL()) $left = !$left;
351 $s .= "<td class='top' align='left' valign='top' rowspan='{$rows}'>\n" .
352 $this->logoText() . '</td>';
354 $s .= $this->getQuickbarCompensator( $rows );
356 $l = $wgLang->isRTL() ?
'right' : 'left';
357 $s .= "<td {$borderhack} align='$l' valign='top'>\n";
359 $s .= $this->topLinks() ;
360 $s .= "<p class='subtitle'>" . $this->pageTitleLinks() . "</p>\n";
362 $r = $wgLang->isRTL() ?
"left" : "right";
363 $s .= "</td>\n<td {$borderhack} valign='top' align='$r' nowrap='nowrap'>";
364 $s .= $this->nameAndLogin();
365 $s .= "\n<br />" . $this->searchForm() . "</td>";
368 $s .= "</tr>\n<tr>\n<td class='top' colspan=\"2\">$langlinks</td>\n";
371 if ( $shove && !$left ) { # Right
372 $s .= $this->getQuickbarCompensator( $rows );
374 $s .= "</tr>\n</table>\n</div>\n";
375 $s .= "\n<div id='article'>\n";
377 if( $wgSiteNotice ) {
378 $s .= "\n<div id='siteNotice'>$wgSiteNotice</div>\n";
380 $s .= $this->pageTitle();
381 $s .= $this->pageSubtitle() ;
382 $s .= $this->getCategories();
383 wfProfileOut( $fname );
387 function getCategoryLinks () {
388 global $wgOut, $wgTitle, $wgUser, $wgParser;
389 global $wgUseCategoryMagic, $wgUseCategoryBrowser, $wgLang;
391 if( !$wgUseCategoryMagic ) return '' ;
392 if( count( $wgOut->mCategoryLinks
) == 0 ) return '';
394 # Taken out so that they will be displayed in previews -- TS
395 #if( !$wgOut->isArticle() ) return '';
397 $t = implode ( ' | ' , $wgOut->mCategoryLinks
) ;
398 $s = $this->makeKnownLink( 'Special:Categories',
399 wfMsg( 'categories' ), 'article=' . urlencode( $wgTitle->getPrefixedDBkey() ) )
402 if($wgUseCategoryBrowser) {
405 $s.= $wgTitle->getAllParentCategories($catstack);
411 function getCategories() {
412 $catlinks=$this->getCategoryLinks();
413 if(!empty($catlinks)) {
414 return "<p class='catlinks'>{$catlinks}</p>";
418 function getQuickbarCompensator( $rows = 1 )
420 return "<td width='152' rowspan='{$rows}'> </td>";
423 # This gets called immediately before the </body> tag.
425 function afterContent()
427 global $wgUser, $wgOut, $wgServer;
428 global $wgTitle, $wgLang;
430 $printfooter = "<div class=\"printfooter\">\n" . $this->printFooter() . "</div>\n";
431 return $printfooter . $this->doAfterContent();
434 function printFooter() {
436 $url = htmlspecialchars( $wgTitle->getFullURL() );
437 return "<p>" . wfMsg( "retrievedfrom", "<a href=\"$url\">$url</a>" ) .
438 "</p>\n\n<p>" . $this->pageStats() . "</p>\n";
441 function doAfterContent()
443 global $wgUser, $wgOut, $wgLang;
444 $fname = 'Skin::doAfterContent';
445 wfProfileIn( $fname );
446 wfProfileIn( $fname.'-1' );
448 $s = "\n</div><br style=\"clear:both\" />\n";
449 $s .= "\n<div id='footer'>";
450 $s .= '<table border="0" cellspacing="0"><tr>';
452 wfProfileOut( $fname.'-1' );
453 wfProfileIn( $fname.'-2' );
455 $qb = $this->qbSetting();
457 $left = ($qb == 1 ||
$qb == 3);
458 if($wgLang->isRTL()) $left = !$left;
460 if ( $shove && $left ) { # Left
461 $s .= $this->getQuickbarCompensator();
463 wfProfileOut( $fname.'-2' );
464 wfProfileIn( $fname.'-3' );
465 $l = $wgLang->isRTL() ?
'right' : 'left';
466 $s .= "<td class='bottom' align='$l' valign='top'>";
468 $s .= $this->bottomLinks();
469 $s .= "\n<br />" . $this->mainPageLink()
470 . ' | ' . $this->aboutLink()
471 . ' | ' . $this->specialLink( 'recentchanges' )
472 . ' | ' . $this->searchForm()
473 . '<br /><span id="pagestats">' . $this->pageStats() . '</span>';
476 if ( $shove && !$left ) { # Right
477 $s .= $this->getQuickbarCompensator();
479 $s .= "</tr></table>\n</div>\n</div>\n";
481 wfProfileOut( $fname.'-3' );
482 wfProfileIn( $fname.'-4' );
483 if ( 0 != $qb ) { $s .= $this->quickBar(); }
484 wfProfileOut( $fname.'-4' );
485 wfProfileOut( $fname );
489 function pageTitleLinks()
491 global $wgOut, $wgTitle, $wgUser, $wgLang, $wgUseApproval, $wgRequest;
493 extract( $wgRequest->getValues( 'oldid', 'diff' ) );
494 $action = $wgRequest->getText( 'action' );
496 $s = $this->printableLink();
497 if ( wfMsg ( 'disclaimers' ) != '-' ) $s .= ' | ' . $this->makeKnownLink( wfMsg( 'disclaimerpage' ), wfMsg( 'disclaimers' ) ) ;
499 if ( $wgOut->isArticleRelated() ) {
500 if ( $wgTitle->getNamespace() == Namespace::getImage() ) {
501 $name = $wgTitle->getDBkey();
502 $link = wfEscapeHTML( Image
::wfImageUrl( $name ) );
503 $style = $this->getInternalLinkAttributes( $link, $name );
504 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>";
506 # This will show the "Approve" link if $wgUseApproval=true;
507 if ( isset ( $wgUseApproval ) && $wgUseApproval )
509 $t = $wgTitle->getDBkey();
510 $name = 'Approve this article' ;
511 $link = "http://test.wikipedia.org/w/magnus/wiki.phtml?title={$t}&action=submit&doit=1" ;
512 #wfEscapeHTML( wfImageUrl( $name ) );
513 $style = $this->getExternalLinkAttributes( $link, $name );
514 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>" ;
517 if ( 'history' == $action ||
isset( $diff ) ||
isset( $oldid ) ) {
518 $s .= ' | ' . $this->makeKnownLink( $wgTitle->getPrefixedText(),
519 wfMsg( 'currentrev' ) );
522 if ( $wgUser->getNewtalk() ) {
523 # do not show "You have new messages" text when we are viewing our
526 if(!(strcmp($wgTitle->getText(),$wgUser->getName()) == 0 &&
527 $wgTitle->getNamespace()==Namespace::getTalk(Namespace::getUser()))) {
528 $n =$wgUser->getName();
529 $tl = $this->makeKnownLink( $wgLang->getNsText(
530 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
531 wfMsg('newmessageslink') );
532 $s.= ' | <strong>'. wfMsg( 'newmessages', $tl ) . '</strong>';
536 $undelete = $this->getUndeleteLink();
537 if( !empty( $undelete ) ) {
538 $s .= ' | '.$undelete;
543 function getUndeleteLink() {
544 global $wgUser, $wgTitle, $wgLang, $action;
545 if( $wgUser->isSysop() &&
546 (($wgTitle->getArticleId() == 0) ||
($action == "history")) &&
547 ($n = $wgTitle->isDeleted() ) ) {
548 return wfMsg( 'thisisdeleted',
549 $this->makeKnownLink(
550 $wgLang->SpecialPage( 'Undelete/' . $wgTitle->getPrefixedDBkey() ),
551 wfMsg( 'restorelink', $n ) ) );
556 function printableLink()
558 global $wgOut, $wgFeedClasses, $wgRequest;
560 $baseurl = $_SERVER['REQUEST_URI'];
561 if( strpos( '?', $baseurl ) == false ) {
566 $baseurl = htmlspecialchars( $baseurl );
567 $printurl = $wgRequest->escapeAppendQuery( 'printable=yes' );
569 $s = "<a href=\"$printurl\">" . wfMsg( 'printableversion' ) . '</a>';
570 if( $wgOut->isSyndicated() ) {
571 foreach( $wgFeedClasses as $format => $class ) {
572 $feedurl = $wgRequest->escapeAppendQuery( "feed=$format" );
573 $s .= " | <a href=\"$feedurl\">{$format}</a>";
581 global $wgOut, $wgTitle, $wgUser;
583 $s = '<h1 class="pagetitle">' . htmlspecialchars( $wgOut->getPageTitle() ) . '</h1>';
584 if($wgUser->getOption( 'editsectiononrightclick' ) && $wgTitle->userCanEdit()) { $s=$this->editSectionScript(0,$s);}
588 function pageSubtitle()
592 $sub = $wgOut->getSubtitle();
594 global $wgExtraSubtitle;
595 $sub = wfMsg( 'fromwikipedia' ) . $wgExtraSubtitle;
597 $subpages = $this->subPageSubtitle();
598 $sub .= !empty($subpages)?
"</p><p class='subpages'>$subpages":'';
599 $s = "<p class='subtitle'>{$sub}</p>\n";
603 function subPageSubtitle()
605 global $wgOut,$wgTitle,$wgNamespacesWithSubpages;
607 if($wgOut->isArticle() && !empty($wgNamespacesWithSubpages[$wgTitle->getNamespace()])) {
608 $ptext=$wgTitle->getPrefixedText();
609 if(preg_match('/\//',$ptext)) {
610 $links = explode('/',$ptext);
613 foreach($links as $link) {
615 if ($c<count($links)) {
616 $growinglink .= $link;
617 $getlink = $this->makeLink( $growinglink, $link );
618 if(preg_match('/class="new"/i',$getlink)) { break; } # this is a hack, but it saves time
622 $subpages .= '< ';
624 $subpages .= $getlink;
633 function nameAndLogin()
635 global $wgUser, $wgTitle, $wgLang, $wgShowIPinHeader, $wgIP;
637 $li = $wgLang->specialPage( 'Userlogin' );
638 $lo = $wgLang->specialPage( 'Userlogout' );
641 if ( 0 == $wgUser->getID() ) {
642 if( $wgShowIPinHeader && isset( $_COOKIE[ini_get('session.name')] ) ) {
645 $tl = $this->makeKnownLink( $wgLang->getNsText(
646 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
647 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
649 $s .= $n . ' ('.$tl.')';
651 $s .= wfMsg('notloggedin');
654 $rt = $wgTitle->getPrefixedURL();
655 if ( 0 == strcasecmp( urlencode( $lo ), $rt ) ) {
657 } else { $q = "returnto={$rt}"; }
659 $s .= "\n<br />" . $this->makeKnownLink( $li,
660 wfMsg( 'login' ), $q );
662 $n = $wgUser->getName();
663 $rt = $wgTitle->getPrefixedURL();
664 $tl = $this->makeKnownLink( $wgLang->getNsText(
665 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
666 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
670 $s .= $this->makeKnownLink( $wgLang->getNsText(
671 Namespace::getUser() ) . ":{$n}", $n ) . "{$tl}<br />" .
672 $this->makeKnownLink( $lo, wfMsg( 'logout' ),
673 "returnto={$rt}" ) . ' | ' .
674 $this->specialLink( 'preferences' );
676 $s .= ' | ' . $this->makeKnownLink( wfMsg( 'helppage' ),
682 function getSearchLink() {
683 $searchPage =& Title
::makeTitle( NS_SPECIAL
, 'Search' );
684 return $searchPage->getLocalURL();
687 function escapeSearchLink() {
688 return htmlspecialchars( $this->getSearchLink() );
691 function searchForm()
694 $search = $wgRequest->getText( 'search' );
696 $s = '<form name="search" class="inline" method="post" action="'
697 . $this->escapeSearchLink() . "\">\n"
698 . '<input type="text" name="search" size="19" value="'
699 . htmlspecialchars(substr($search,0,256)) . "\" />\n"
700 . '<input type="submit" name="go" value="' . wfMsg ('go') . '" /> '
701 . '<input type="submit" name="fulltext" value="' . wfMsg ('search') . "\" />\n</form>";
711 $s = $this->mainPageLink() . $sep
712 . $this->specialLink( 'recentchanges' );
714 if ( $wgOut->isArticleRelated() ) {
715 $s .= $sep . $this->editThisPage()
716 . $sep . $this->historyLink();
718 # Many people don't like this dropdown box
719 #$s .= $sep . $this->specialPagesList();
724 function bottomLinks()
726 global $wgOut, $wgUser, $wgTitle;
730 if ( $wgOut->isArticleRelated() ) {
731 $s .= '<strong>' . $this->editThisPage() . '</strong>';
732 if ( 0 != $wgUser->getID() ) {
733 $s .= $sep . $this->watchThisPage();
735 $s .= $sep . $this->talkLink()
736 . $sep . $this->historyLink()
737 . $sep . $this->whatLinksHere()
738 . $sep . $this->watchPageLinksLink();
740 if ( $wgTitle->getNamespace() == Namespace::getUser()
741 ||
$wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser()) )
744 $id=User
::idFromName($wgTitle->getText());
745 $ip=User
::isIP($wgTitle->getText());
747 if($id ||
$ip) { # both anons and non-anons have contri list
748 $s .= $sep . $this->userContribsLink();
750 if ( 0 != $wgUser->getID() ) { # show only to signed in users
751 if($id) { # can only email non-anons
752 $s .= $sep . $this->emailUserLink();
756 if ( $wgUser->isSysop() && $wgTitle->getArticleId() ) {
757 $s .= "\n<br />" . $this->deleteThisPage() .
758 $sep . $this->protectThisPage() .
759 $sep . $this->moveThisPage();
761 $s .= "<br />\n" . $this->otherLanguages();
768 global $wgOut, $wgLang, $wgArticle, $wgRequest;
769 global $wgDisableCounters, $wgMaxCredits, $wgShowCreditsIfMax;
771 extract( $wgRequest->getValues( 'oldid', 'diff' ) );
772 if ( ! $wgOut->isArticle() ) { return ''; }
773 if ( isset( $oldid ) ||
isset( $diff ) ) { return ''; }
774 if ( 0 == $wgArticle->getID() ) { return ''; }
777 if ( !$wgDisableCounters ) {
778 $count = $wgLang->formatNum( $wgArticle->getCount() );
780 $s = wfMsg( 'viewcount', $count );
784 if (isset($wgMaxCredits) && $wgMaxCredits != 0) {
785 require_once("Credits.php");
786 $s .= ' ' . getCredits($wgArticle, $wgMaxCredits, $wgShowCreditsIfMax);
788 $s .= $this->lastModified();
791 return $s . ' ' . $this->getCopyright();
794 function getCopyright() {
795 global $wgRightsPage, $wgRightsUrl, $wgRightsText, $wgRequest;
798 $oldid = $wgRequest->getVal( 'oldid' );
799 $diff = $wgRequest->getVal( 'diff' );
801 if ( !is_null( $oldid ) && is_null( $diff ) && wfMsg( 'history_copyright' ) !== '-' ) {
802 $msg = 'history_copyright';
808 if( $wgRightsPage ) {
809 $link = $this->makeKnownLink( $wgRightsPage, $wgRightsText );
810 } elseif( $wgRightsUrl ) {
811 $link = $this->makeExternalLink( $wgRightsUrl, $wgRightsText );
816 $out .= wfMsg( $msg, $link );
820 function getCopyrightIcon() {
821 global $wgRightsPage, $wgRightsUrl, $wgRightsText, $wgRightsIcon;
823 if( $wgRightsIcon ) {
824 $icon = htmlspecialchars( $wgRightsIcon );
826 $url = htmlspecialchars( $wgRightsUrl );
827 $out .= '<a href="'.$url.'">';
829 $text = htmlspecialchars( $wgRightsText );
830 $out .= "<img src=\"$icon\" alt='$text' />";
838 function getPoweredBy() {
840 $url = htmlspecialchars( "$wgStylePath/images/poweredby_mediawiki_88x31.png" );
841 $img = '<a href="http://www.mediawiki.org/"><img src="'.$url.'" alt="MediaWiki" /></a>';
845 function lastModified()
847 global $wgLang, $wgArticle;
849 $timestamp = $wgArticle->getTimestamp();
851 $d = $wgLang->timeanddate( $wgArticle->getTimestamp(), true );
852 $s = ' ' . wfMsg( 'lastmodified', $d );
859 function logoText( $align = '' )
861 if ( '' != $align ) { $a = ' align="'.$align.'"'; }
864 $mp = wfMsg( 'mainpage' );
865 $titleObj = Title
::newFromText( $mp );
866 $s = '<a href="' . $titleObj->escapeLocalURL()
867 . '"><img'.$a.' src="'
868 . $this->getLogo() . '" alt="' . "[{$mp}]\" /></a>";
874 global $wgOut, $wgTitle, $wgUser, $wgRequest, $wgLang;
875 global $wgDisableUploads, $wgRemoteUploads;
877 $fname = 'Skin::quickBar';
878 wfProfileIn( $fname );
880 $action = $wgRequest->getText( 'action' );
881 $wpPreview = $wgRequest->getBool( 'wpPreview' );
882 $tns=$wgTitle->getNamespace();
884 $s = "\n<div id='quickbar'>";
885 $s .= "\n" . $this->logoText() . "\n<hr class='sep' />";
888 $s .= $this->mainPageLink()
889 . $sep . $this->specialLink( 'recentchanges' )
890 . $sep . $this->specialLink( 'randompage' );
891 if ($wgUser->getID()) {
892 $s.= $sep . $this->specialLink( 'watchlist' ) ;
893 $s .= $sep .$this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
894 wfMsg( 'mycontris' ), 'target=' . wfUrlencode($wgUser->getName() ) );
897 // only show watchlist link if logged in
898 if ( wfMsg ( 'currentevents' ) != '-' ) $s .= $sep . $this->makeKnownLink( wfMsg( 'currentevents' ), '' ) ;
899 $s .= "\n<br /><hr class='sep' />";
900 $articleExists = $wgTitle->getArticleId();
901 if ( $wgOut->isArticle() ||
$action =='edit' ||
$action =='history' ||
$wpPreview) {
902 if($wgOut->isArticle()) {
903 $s .= '<strong>' . $this->editThisPage() . '</strong>';
904 } else { # backlink to the article in edit or history mode
905 if($articleExists){ # no backlink if no article
908 $text = wfMsg('articlepage');
911 $text = wfMsg('viewtalkpage');
914 $text = wfMsg('userpage');
917 $text = wfMsg('viewtalkpage');
920 $text = wfMsg('wikipediapage');
923 $text = wfMsg('viewtalkpage');
926 $text = wfMsg('imagepage');
929 $text = wfMsg('viewtalkpage');
932 $text= wfMsg('articlepage');
935 $link = $wgTitle->getText();
936 if ($nstext = $wgLang->getNsText($tns) ) { # add namespace if necessary
937 $link = $nstext . ':' . $link ;
940 $s .= $this->makeLink( $link, $text );
941 } elseif( $wgTitle->getNamespace() != Namespace::getSpecial() ) {
942 # we just throw in a "New page" text to tell the user that he's in edit mode,
943 # and to avoid messing with the separator that is prepended to the next item
944 $s .= '<strong>' . wfMsg('newpage') . '</strong>';
950 if( $tns%2
&& $action!='edit' && !$wpPreview) {
951 $s.= '<br />'.$this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg('postcomment'),'action=edit§ion=new');
955 watching could cause problems in edit mode:
956 if user edits article, then loads "watch this article" in background and then saves
957 article with "Watch this article" checkbox disabled, the article is transparently
958 unwatched. Therefore we do not show the "Watch this page" link in edit mode
960 if ( 0 != $wgUser->getID() && $articleExists) {
961 if($action!='edit' && $action != 'submit' )
963 $s .= $sep . $this->watchThisPage();
965 if ( $wgTitle->userCanEdit() )
966 $s .= $sep . $this->moveThisPage();
968 if ( $wgUser->isSysop() and $articleExists ) {
969 $s .= $sep . $this->deleteThisPage() .
970 $sep . $this->protectThisPage();
972 $s .= $sep . $this->talkLink();
973 if ($articleExists && $action !='history') {
974 $s .= $sep . $this->historyLink();
976 $s.=$sep . $this->whatLinksHere();
978 if($wgOut->isArticleRelated()) {
979 $s .= $sep . $this->watchPageLinksLink();
982 if ( Namespace::getUser() == $wgTitle->getNamespace()
983 ||
$wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser())
986 $id=User
::idFromName($wgTitle->getText());
987 $ip=User
::isIP($wgTitle->getText());
990 $s .= $sep . $this->userContribsLink();
992 if ( 0 != $wgUser->getID() ) {
993 if($id) { # can only email real users
994 $s .= $sep . $this->emailUserLink();
998 $s .= "\n<br /><hr class='sep' />";
1001 if ( 0 != $wgUser->getID() && ( !$wgDisableUploads ||
$wgRemoteUploads ) ) {
1002 $s .= $this->specialLink( 'upload' ) . $sep;
1004 $s .= $this->specialLink( 'specialpages' )
1005 . $sep . $this->bugReportsLink();
1007 global $wgSiteSupportPage;
1008 if( $wgSiteSupportPage ) {
1009 $s .= "\n<br /><a href=\"" . htmlspecialchars( $wgSiteSupportPage ) .
1010 '" class="internal">' . wfMsg( 'sitesupport' ) . '</a>';
1013 $s .= "\n<br /></div>\n";
1014 wfProfileOut( $fname );
1018 function specialPagesList()
1020 global $wgUser, $wgOut, $wgLang, $wgServer, $wgRedirectScript;
1021 require_once('SpecialPage.php');
1023 $pages = SpecialPage
::getPages();
1025 foreach ( $pages[''] as $name => $page ) {
1026 $a[$name] = $page->getDescription();
1028 if ( $wgUser->isSysop() )
1030 foreach ( $pages['sysop'] as $name => $page ) {
1031 $a[$name] = $page->getDescription();
1034 if ( $wgUser->isDeveloper() )
1036 foreach ( $pages['developer'] as $name => $page ) {
1037 $a[$name] = $page->getDescription() ;
1040 $go = wfMsg( 'go' );
1041 $sp = wfMsg( 'specialpages' );
1042 $spp = $wgLang->specialPage( 'Specialpages' );
1044 $s = '<form id="specialpages" method="get" class="inline" ' .
1045 'action="' . htmlspecialchars( "{$wgServer}{$wgRedirectScript}" ) . "\">\n";
1046 $s .= "<select name=\"wpDropdown\">\n";
1047 $s .= "<option value=\"{$spp}\">{$sp}</option>\n";
1049 foreach ( $a as $name => $desc ) {
1050 $p = $wgLang->specialPage( $name );
1051 $s .= "<option value=\"{$p}\">{$desc}</option>\n";
1053 $s .= "</select>\n";
1054 $s .= "<input type='submit' value=\"{$go}\" name='redirect' />\n";
1059 function mainPageLink()
1061 $mp = wfMsg( 'mainpage' );
1062 $s = $this->makeKnownLink( $mp, $mp );
1066 function copyrightLink()
1068 $s = $this->makeKnownLink( wfMsg( 'copyrightpage' ),
1069 wfMsg( 'copyrightpagename' ) );
1073 function aboutLink()
1075 $s = $this->makeKnownLink( wfMsg( 'aboutpage' ),
1076 wfMsg( 'aboutwikipedia' ) );
1081 function disclaimerLink()
1083 $s = $this->makeKnownLink( wfMsg( 'disclaimerpage' ),
1084 wfMsg( 'disclaimers' ) );
1088 function editThisPage()
1090 global $wgOut, $wgTitle, $wgRequest;
1092 $oldid = $wgRequest->getVal( 'oldid' );
1093 $diff = $wgRequest->getVal( 'diff' );
1094 $redirect = $wgRequest->getVal( 'redirect' );
1096 if ( ! $wgOut->isArticleRelated() ) {
1097 $s = wfMsg( 'protectedpage' );
1099 $n = $wgTitle->getPrefixedText();
1100 if ( $wgTitle->userCanEdit() ) {
1101 $t = wfMsg( 'editthispage' );
1103 #$t = wfMsg( "protectedpage" );
1104 $t = wfMsg( 'viewsource' );
1108 if ( !is_null( $redirect ) ) { $red = "&redirect={$redirect}"; }
1109 if ( $oldid && ! isset( $diff ) ) {
1110 $oid = "&oldid={$oldid}";
1112 $s = $this->makeKnownLink( $n, $t, "action=edit{$oid}{$red}" );
1117 function deleteThisPage()
1119 global $wgUser, $wgOut, $wgTitle, $wgRequest;
1121 $diff = $wgRequest->getVal( 'diff' );
1122 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
1123 $n = $wgTitle->getPrefixedText();
1124 $t = wfMsg( 'deletethispage' );
1126 $s = $this->makeKnownLink( $n, $t, 'action=delete' );
1133 function protectThisPage()
1135 global $wgUser, $wgOut, $wgTitle, $wgRequest;
1137 $diff = $wgRequest->getVal( 'diff' );
1138 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
1139 $n = $wgTitle->getPrefixedText();
1141 if ( $wgTitle->isProtected() ) {
1142 $t = wfMsg( 'unprotectthispage' );
1143 $q = 'action=unprotect';
1145 $t = wfMsg( 'protectthispage' );
1146 $q = 'action=protect';
1148 $s = $this->makeKnownLink( $n, $t, $q );
1155 function watchThisPage()
1157 global $wgUser, $wgOut, $wgTitle;
1159 if ( $wgOut->isArticleRelated() ) {
1160 $n = $wgTitle->getPrefixedText();
1162 if ( $wgTitle->userIsWatching() ) {
1163 $t = wfMsg( 'unwatchthispage' );
1164 $q = 'action=unwatch';
1166 $t = wfMsg( 'watchthispage' );
1167 $q = 'action=watch';
1169 $s = $this->makeKnownLink( $n, $t, $q );
1171 $s = wfMsg( 'notanarticle' );
1176 function moveThisPage()
1178 global $wgTitle, $wgLang;
1180 if ( $wgTitle->userCanEdit() ) {
1181 $s = $this->makeKnownLink( $wgLang->specialPage( 'Movepage' ),
1182 wfMsg( 'movethispage' ), 'target=' . $wgTitle->getPrefixedURL() );
1183 } // no message if page is protected - would be redundant
1187 function historyLink()
1191 $s = $this->makeKnownLink( $wgTitle->getPrefixedText(),
1192 wfMsg( 'history' ), 'action=history' );
1196 function whatLinksHere()
1198 global $wgTitle, $wgLang;
1200 $s = $this->makeKnownLink( $wgLang->specialPage( 'Whatlinkshere' ),
1201 wfMsg( 'whatlinkshere' ), 'target=' . $wgTitle->getPrefixedURL() );
1205 function userContribsLink()
1207 global $wgTitle, $wgLang;
1209 $s = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
1210 wfMsg( 'contributions' ), 'target=' . $wgTitle->getPartialURL() );
1214 function emailUserLink()
1216 global $wgTitle, $wgLang;
1218 $s = $this->makeKnownLink( $wgLang->specialPage( 'Emailuser' ),
1219 wfMsg( 'emailuser' ), 'target=' . $wgTitle->getPartialURL() );
1223 function watchPageLinksLink()
1225 global $wgOut, $wgTitle, $wgLang;
1227 if ( ! $wgOut->isArticleRelated() ) {
1228 $s = '(' . wfMsg( 'notanarticle' ) . ')';
1230 $s = $this->makeKnownLink( $wgLang->specialPage(
1231 'Recentchangeslinked' ), wfMsg( 'recentchangeslinked' ),
1232 'target=' . $wgTitle->getPrefixedURL() );
1237 function otherLanguages()
1239 global $wgOut, $wgLang, $wgTitle, $wgUseNewInterlanguage;
1241 $a = $wgOut->getLanguageLinks();
1242 if ( 0 == count( $a ) ) {
1243 if ( !$wgUseNewInterlanguage ) return '';
1244 $ns = $wgLang->getNsIndex ( $wgTitle->getNamespace () ) ;
1245 if ( $ns != 0 AND $ns != 1 ) return '' ;
1247 $x = 'mode=addlink&xt='.$wgTitle->getDBkey() ;
1248 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1249 wfMsg( 'intl' ) , $x );
1252 if ( !$wgUseNewInterlanguage ) {
1253 $s = wfMsg( 'otherlanguages' ) . ': ';
1255 global $wgLanguageCode ;
1256 $x = 'mode=zoom&xt='.$wgTitle->getDBkey() ;
1257 $x .= '&xl='.$wgLanguageCode ;
1258 $s = $this->makeKnownLink( $wgLang->specialPage( 'Intl' ),
1259 wfMsg( 'otherlanguages' ) , $x ) . ': ' ;
1262 $s = wfMsg( 'otherlanguages' ) . ': ';
1264 if($wgLang->isRTL()) $s .= '<span dir="LTR">';
1265 foreach( $a as $l ) {
1266 if ( ! $first ) { $s .= ' | '; }
1269 $nt = Title
::newFromText( $l );
1270 $url = $nt->getFullURL();
1271 $text = $wgLang->getLanguageName( $nt->getInterwiki() );
1273 if ( '' == $text ) { $text = $l; }
1274 $style = $this->getExternalLinkAttributes( $l, $text );
1275 $s .= "<a href=\"{$url}\"{$style}>{$text}</a>";
1277 if($wgLang->isRTL()) $s .= '</span>';
1281 function bugReportsLink()
1283 $s = $this->makeKnownLink( wfMsg( 'bugreportspage' ),
1284 wfMsg( 'bugreports' ) );
1290 global $wgLinkCache;
1291 $t1 = Title
::newFromText( gmdate( 'F j' ) );
1292 $t2 = Title
::newFromText( gmdate( 'Y' ) );
1294 $wgLinkCache->suspend();
1295 $id = $t1->getArticleID();
1296 $wgLinkCache->resume();
1299 $s = $this->makeBrokenLink( $t1->getText() );
1301 $s = $this->makeKnownLink( $t1->getText() );
1305 $wgLinkCache->suspend();
1306 $id = $t2->getArticleID();
1307 $wgLinkCache->resume();
1310 $s .= $this->makeBrokenLink( $t2->getText() );
1312 $s .= $this->makeKnownLink( $t2->getText() );
1319 global $wgLang, $wgTitle, $wgLinkCache;
1321 $tns = $wgTitle->getNamespace();
1322 if ( -1 == $tns ) { return ''; }
1324 $pn = $wgTitle->getText();
1325 $tp = wfMsg( 'talkpage' );
1326 if ( Namespace::isTalk( $tns ) ) {
1327 $lns = Namespace::getSubject( $tns );
1330 $text = wfMsg('articlepage');
1333 $text = wfMsg('userpage');
1336 $text = wfMsg('wikipediapage');
1339 $text = wfMsg('imagepage');
1342 $text= wfMsg('articlepage');
1346 $lns = Namespace::getTalk( $tns );
1349 $n = $wgLang->getNsText( $lns );
1350 if ( '' == $n ) { $link = $pn; }
1351 else { $link = $n.':'.$pn; }
1353 $wgLinkCache->suspend();
1354 $s = $this->makeLink( $link, $text );
1355 $wgLinkCache->resume();
1360 function commentLink()
1362 global $wgLang, $wgTitle, $wgLinkCache;
1364 $tns = $wgTitle->getNamespace();
1365 if ( -1 == $tns ) { return ''; }
1367 $lns = ( Namespace::isTalk( $tns ) ) ?
$tns : Namespace::getTalk( $tns );
1369 # assert Namespace::isTalk( $lns )
1371 $n = $wgLang->getNsText( $lns );
1372 $pn = $wgTitle->getText();
1376 $wgLinkCache->suspend();
1377 $s = $this->makeKnownLink($link, wfMsg('postcomment'), 'action=edit§ion=new');
1378 $wgLinkCache->resume();
1383 # After all the page content is transformed into HTML, it makes
1384 # a final pass through here for things like table backgrounds.
1386 function transformContent( $text )
1391 # Note: This function MUST call getArticleID() on the link,
1392 # otherwise the cache won't get updated properly. See LINKCACHE.DOC.
1394 function makeLink( $title, $text = '', $query = '', $trail = '' ) {
1395 wfProfileIn( 'Skin::makeLink' );
1396 $nt = Title
::newFromText( $title );
1398 $result = $this->makeLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1400 wfDebug( 'Invalid title passed to Skin::makeLink(): "'.$title."\"\n" );
1401 $result = $text == "" ?
$title : $text;
1404 wfProfileOut( 'Skin::makeLink' );
1408 function makeKnownLink( $title, $text = '', $query = '', $trail = '', $prefix = '',$aprops = '') {
1409 $nt = Title
::newFromText( $title );
1411 return $this->makeKnownLinkObj( Title
::newFromText( $title ), $text, $query, $trail, $prefix , $aprops );
1413 wfDebug( 'Invalid title passed to Skin::makeKnownLink(): "'.$title."\"\n" );
1414 return $text == '' ?
$title : $text;
1418 function makeBrokenLink( $title, $text = '', $query = '', $trail = '' ) {
1419 $nt = Title
::newFromText( $title );
1421 return $this->makeBrokenLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1423 wfDebug( 'Invalid title passed to Skin::makeBrokenLink(): "'.$title."\"\n" );
1424 return $text == '' ?
$title : $text;
1428 function makeStubLink( $title, $text = '', $query = '', $trail = '' ) {
1429 $nt = Title
::newFromText( $title );
1431 return $this->makeStubLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1433 wfDebug( 'Invalid title passed to Skin::makeStubLink(): "'.$title."\"\n" );
1434 return $text == '' ?
$title : $text;
1438 # Pass a title object, not a title string
1439 function makeLinkObj( &$nt, $text= '', $query = '', $trail = '', $prefix = '' )
1441 global $wgOut, $wgUser;
1442 $fname = 'Skin::makeLinkObj';
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 $s = $dbr->getArray( 'cur',
1471 array( 'LENGTH(cur_text) AS x', 'cur_namespace', 'cur_is_redirect' ),
1472 array( 'cur_id' => $aid ),
1476 if ( $s !== false ) {
1478 if ( $s->cur_is_redirect
OR $s->cur_namespace
!= 0 ) {
1479 $size = $threshold*2 ; # Really big
1482 $size = $threshold*2 ; # Really big
1487 if ( $size < $threshold ) {
1488 $retVal = $this->makeStubLinkObj( $nt, $text, $query, $trail, $prefix );
1490 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1497 # Pass a title object, not a title string
1498 function makeKnownLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' , $aprops = '')
1500 global $wgOut, $wgTitle, $wgInputEncoding;
1502 $fname = 'Skin::makeKnownLinkObj';
1503 wfProfileIn( $fname );
1505 if ( !is_object( $nt ) ) {
1508 $link = $nt->getPrefixedURL();
1510 if ( '' == $link ) {
1512 if ( '' == $text ) {
1513 $text = htmlspecialchars( $nt->getFragment() );
1516 $u = $nt->escapeLocalURL( $query );
1518 if ( '' != $nt->getFragment() ) {
1519 $anchor = urlencode( do_html_entity_decode( str_replace(' ', '_', $nt->getFragment()), ENT_COMPAT
, $wgInputEncoding ) );
1520 $replacearray = array(
1524 $u .= '#' . str_replace(array_keys($replacearray),array_values($replacearray),$anchor);
1526 if ( '' == $text ) {
1527 $text = htmlspecialchars( $nt->getPrefixedText() );
1529 $style = $this->getInternalLinkAttributesObj( $nt, $text );
1532 if ( '' != $trail ) {
1533 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1538 $r = "<a href=\"{$u}\"{$style}{$aprops}>{$prefix}{$text}{$inside}</a>{$trail}";
1539 wfProfileOut( $fname );
1543 # Pass a title object, not a title string
1544 function makeBrokenLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
1546 global $wgOut, $wgUser;
1548 $fname = 'Skin::makeBrokenLinkObj';
1549 wfProfileIn( $fname );
1551 if ( '' == $query ) {
1554 $q = 'action=edit&'.$query;
1556 $u = $nt->escapeLocalURL( $q );
1558 if ( '' == $text ) {
1559 $text = htmlspecialchars( $nt->getPrefixedText() );
1561 $style = $this->getInternalLinkAttributesObj( $nt, $text, "yes" );
1564 if ( '' != $trail ) {
1565 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1570 if ( $wgUser->getOption( 'highlightbroken' ) ) {
1571 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1573 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>?</a>{$trail}";
1576 wfProfileOut( $fname );
1580 # Pass a title object, not a title string
1581 function makeStubLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
1583 global $wgOut, $wgUser;
1585 $link = $nt->getPrefixedURL();
1587 $u = $nt->escapeLocalURL( $query );
1589 if ( '' == $text ) {
1590 $text = htmlspecialchars( $nt->getPrefixedText() );
1592 $style = $this->getInternalLinkAttributesObj( $nt, $text, 'stub' );
1595 if ( '' != $trail ) {
1596 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1601 if ( $wgUser->getOption( 'highlightbroken' ) ) {
1602 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1604 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>!</a>{$trail}";
1609 function makeSelfLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
1611 $u = $nt->escapeLocalURL( $query );
1612 if ( '' == $text ) {
1613 $text = htmlspecialchars( $nt->getPrefixedText() );
1616 if ( '' != $trail ) {
1617 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1622 return "<strong>{$prefix}{$text}{$inside}</strong>{$trail}";
1625 /* these are used extensively in SkinPHPTal, but also some other places */
1626 /*static*/ function makeSpecialUrl( $name, $urlaction='' ) {
1627 $title = Title
::makeTitle( NS_SPECIAL
, $name );
1628 $this->checkTitle($title, $name);
1629 return $title->getLocalURL( $urlaction );
1631 /*static*/ function makeTalkUrl ( $name, $urlaction='' ) {
1632 $title = Title
::newFromText( $name );
1633 $title = $title->getTalkPage();
1634 $this->checkTitle($title, $name);
1635 return $title->getLocalURL( $urlaction );
1637 /*static*/ function makeArticleUrl ( $name, $urlaction='' ) {
1638 $title = Title
::newFromText( $name );
1639 $title= $title->getSubjectPage();
1640 $this->checkTitle($title, $name);
1641 return $title->getLocalURL( $urlaction );
1643 /*static*/ function makeI18nUrl ( $name, $urlaction='' ) {
1644 $title = Title
::newFromText( wfMsg($name) );
1645 $this->checkTitle($title, $name);
1646 return $title->getLocalURL( $urlaction );
1648 /*static*/ function makeUrl ( $name, $urlaction='' ) {
1649 $title = Title
::newFromText( $name );
1650 $this->checkTitle($title, $name);
1651 return $title->getLocalURL( $urlaction );
1653 # this can be passed the NS number as defined in Language.php
1654 /*static*/ function makeNSUrl( $name, $urlaction='', $namespace=0 ) {
1655 $title = Title
::makeTitle( $namespace, $name );
1656 $this->checkTitle($title, $name);
1657 return $title->getLocalURL( $urlaction );
1660 /* these return an array with the 'href' and boolean 'exists' */
1661 /*static*/ function makeUrlDetails ( $name, $urlaction='' ) {
1662 $title = Title
::newFromText( $name );
1663 $this->checkTitle($title, $name);
1665 'href' => $title->getLocalURL( $urlaction ),
1666 'exists' => $title->getArticleID() != 0?
true:false
1669 /*static*/ function makeTalkUrlDetails ( $name, $urlaction='' ) {
1670 $title = Title
::newFromText( $name );
1671 $title = $title->getTalkPage();
1672 $this->checkTitle($title, $name);
1674 'href' => $title->getLocalURL( $urlaction ),
1675 'exists' => $title->getArticleID() != 0?
true:false
1678 /*static*/ function makeArticleUrlDetails ( $name, $urlaction='' ) {
1679 $title = Title
::newFromText( $name );
1680 $title= $title->getSubjectPage();
1681 $this->checkTitle($title, $name);
1683 'href' => $title->getLocalURL( $urlaction ),
1684 'exists' => $title->getArticleID() != 0?
true:false
1687 /*static*/ function makeI18nUrlDetails ( $name, $urlaction='' ) {
1688 $title = Title
::newFromText( wfMsg($name) );
1689 $this->checkTitle($title, $name);
1691 'href' => $title->getLocalURL( $urlaction ),
1692 'exists' => $title->getArticleID() != 0?
true:false
1696 # make sure we have some title to operate on
1697 /*static*/ function checkTitle ( &$title, &$name ) {
1698 if(!is_object($title)) {
1699 $title = Title
::newFromText( $name );
1700 if(!is_object($title)) {
1701 $title = Title
::newFromText( '--error: link target missing--' );
1706 function fnamePart( $url )
1708 $basename = strrchr( $url, '/' );
1709 if ( false === $basename ) { $basename = $url; }
1710 else { $basename = substr( $basename, 1 ); }
1711 return wfEscapeHTML( $basename );
1714 function makeImage( $url, $alt = '' )
1718 if ( '' == $alt ) { $alt = $this->fnamePart( $url ); }
1719 $s = '<img src="'.$url.'" alt="'.$alt.'" />';
1723 function makeImageLink( $name, $url, $alt = '' ) {
1724 $nt = Title
::makeTitle( Namespace::getImage(), $name );
1725 return $this->makeImageLinkObj( $nt, $alt );
1728 function makeImageLinkObj( $nt, $alt = '' ) {
1729 global $wgLang, $wgUseImageResize;
1730 $img = Image
::newFromTitle( $nt );
1731 $url = $img->getURL();
1734 $prefix = $postfix = '';
1736 if ( $wgUseImageResize ) {
1737 # Check if the alt text is of the form "options|alt text"
1739 # * thumbnail make a thumbnail with enlarge-icon and caption, alignment depends on lang
1740 # * left no resizing, just left align. label is used for alt= only
1741 # * right same, but right aligned
1742 # * none same, but not aligned
1743 # * ___px scale to ___ pixels width, no aligning. e.g. use in taxobox
1744 # * center center the image
1745 # * framed Keep original image size, no magnify-button.
1747 $part = explode( '|', $alt);
1749 $mwThumb =& MagicWord
::get( MAG_IMG_THUMBNAIL
);
1750 $mwLeft =& MagicWord
::get( MAG_IMG_LEFT
);
1751 $mwRight =& MagicWord
::get( MAG_IMG_RIGHT
);
1752 $mwNone =& MagicWord
::get( MAG_IMG_NONE
);
1753 $mwWidth =& MagicWord
::get( MAG_IMG_WIDTH
);
1754 $mwCenter =& MagicWord
::get( MAG_IMG_CENTER
);
1755 $mwFramed =& MagicWord
::get( MAG_IMG_FRAMED
);
1756 $alt = $part[count($part)-1];
1758 $height = $framed = $thumb = false;
1759 $manual_thumb = "" ;
1761 foreach( $part as $key => $val ) {
1762 $val_parts = explode ( "=" , $val , 2 ) ;
1763 $left_part = array_shift ( $val_parts ) ;
1764 if ( ! is_null( $mwThumb->matchVariableStartToEnd($val) ) ) {
1766 } elseif ( count ( $val_parts ) == 1 && ! is_null( $mwThumb->matchVariableStartToEnd($left_part) ) ) {
1767 # use manually specified thumbnail
1769 $manual_thumb = array_shift ( $val_parts ) ;
1770 } elseif ( ! is_null( $mwRight->matchVariableStartToEnd($val) ) ) {
1771 # remember to set an alignment, don't render immediately
1773 } elseif ( ! is_null( $mwLeft->matchVariableStartToEnd($val) ) ) {
1774 # remember to set an alignment, don't render immediately
1776 } elseif ( ! is_null( $mwCenter->matchVariableStartToEnd($val) ) ) {
1777 # remember to set an alignment, don't render immediately
1779 } elseif ( ! is_null( $mwNone->matchVariableStartToEnd($val) ) ) {
1780 # remember to set an alignment, don't render immediately
1782 } elseif ( ! is_null( $match = $mwWidth->matchVariableStartToEnd($val) ) ) {
1783 # $match is the image width in pixels
1784 if ( preg_match( '/^([0-9]*)x([0-9]*)$/', $match, $m ) ) {
1785 $width = intval( $m[1] );
1786 $height = intval( $m[2] );
1788 $width = intval($match);
1790 } elseif ( ! is_null( $mwFramed->matchVariableStartToEnd($val) ) ) {
1794 if ( 'center' == $align )
1796 $prefix = '<span style="text-align: center">';
1797 $postfix = '</span>';
1801 if ( $thumb ||
$framed ) {
1803 # Create a thumbnail. Alignment depends on language
1804 # writing direction, # right aligned for left-to-right-
1805 # languages ("Western languages"), left-aligned
1806 # for right-to-left-languages ("Semitic languages")
1808 # If thumbnail width has not been provided, it is set
1809 # here to 180 pixels
1810 if ( $align == '' ) {
1811 $align = $wgLang->isRTL() ?
'left' : 'right';
1813 if ( ! isset($width) ) {
1816 return $prefix.$this->makeThumbLinkObj( $img, $alt, $align, $width, $height, $framed, $manual_thumb ).$postfix;
1818 } elseif ( isset($width) ) {
1820 # Create a resized image, without the additional thumbnail
1823 if ( ( ! $height === false )
1824 && ( $img->getHeight() * $width / $img->getWidth() > $height ) ) {
1825 print "height=$height<br>\nimg->getHeight() = ".$img->getHeight()."<br>\n";
1826 print 'rescaling by factor '. $height / $img->getHeight() . "<br>\n";
1827 $width = $img->getWidth() * $height / $img->getHeight();
1829 if ( '' == $manual_thumb ) $url = $img->createThumb( $width );
1831 } # endif $wgUseImageResize
1833 if ( empty( $alt ) ) {
1834 $alt = preg_replace( '/\.(.+?)^/', '', $img->getName() );
1836 $alt = htmlspecialchars( $alt );
1838 $u = $nt->escapeLocalURL();
1841 $s = str_replace( "$1", $img->getName(), wfMsg('missingimage') );
1842 $s .= "<br>{$alt}<br>{$url}<br>\n";
1844 $s = '<a href="'.$u.'" class="image" title="'.$alt.'">' .
1845 '<img src="'.$url.'" alt="'.$alt.'" /></a>';
1847 if ( '' != $align ) {
1848 $s = "<div class=\"float{$align}\"><span>{$s}</span></div>";
1850 return str_replace("\n", ' ',$prefix.$s.$postfix);
1854 function makeThumbLinkObj( $img, $label = '', $align = 'right', $boxwidth = 180, $boxheight=false, $framed=false , $manual_thumb = "" ) {
1855 global $wgStylePath, $wgLang;
1856 # $image = Title::makeTitle( Namespace::getImage(), $name );
1857 $url = $img->getURL();
1859 #$label = htmlspecialchars( $label );
1860 $alt = preg_replace( '/<[^>]*>/', '', $label);
1861 $alt = htmlspecialchars( $alt );
1863 if ( $img->exists() )
1865 $width = $img->getWidth();
1866 $height = $img->getHeight();
1868 $width = $height = 200;
1872 // Use image dimensions, don't scale
1874 $oboxwidth = $boxwidth +
2;
1875 $boxheight = $height;
1878 $h = intval( $height/($width/$boxwidth) );
1879 $oboxwidth = $boxwidth +
2;
1880 if ( ( ! $boxheight === false ) && ( $h > $boxheight ) )
1882 $boxwidth *= $boxheight/$h;
1886 if ( '' == $manual_thumb ) $thumbUrl = $img->createThumb( $boxwidth );
1889 if ( $manual_thumb != '' ) # Use manually specified thumbnail
1891 $manual_title = Title
::makeTitle( Namespace::getImage(), $manual_thumb ); #new Title ( $manual_thumb ) ;
1892 $manual_img = Image
::newFromTitle( $manual_title );
1893 $thumbUrl = $manual_img->getURL();
1894 if ( $manual_img->exists() )
1896 $width = $manual_img->getWidth();
1897 $height = $manual_img->getHeight();
1898 $boxwidth = $width ;
1899 $boxheight = $height ;
1900 $oboxwidth = $boxwidth +
2 ;
1904 $u = $img->getEscapeLocalURL();
1906 $more = htmlspecialchars( wfMsg( 'thumbnail-more' ) );
1907 $magnifyalign = $wgLang->isRTL() ?
'left' : 'right';
1908 $textalign = $wgLang->isRTL() ?
' style="text-align:right"' : '';
1910 $s = "<div class=\"thumb t{$align}\"><div style=\"width:{$oboxwidth}px;\">";
1911 if ( $thumbUrl == '' ) {
1912 $s .= str_replace( "$1", $img->getName(), wfMsg('missingimage') );
1915 $s .= '<a href="'.$u.'" class="internal" title="'.$alt.'">'.
1916 '<img src="'.$thumbUrl.'" alt="'.$alt.'" ' .
1917 'width="'.$boxwidth.'" height="'.$boxheight.'" /></a>';
1921 $zoomicon = '<div class="magnify" style="float:'.$magnifyalign.'">'.
1922 '<a href="'.$u.'" class="internal" title="'.$more.'">'.
1923 '<img src="'.$wgStylePath.'/images/magnify-clip.png" ' .
1924 'width="15" height="11" alt="'.$more.'" /></a></div>';
1927 $s .= ' <div class="thumbcaption" '.$textalign.'>'.$zoomicon.$label."</div></div></div>";
1928 return str_replace("\n", ' ', $s);
1931 function makeMediaLink( $name, $url, $alt = "" ) {
1932 $nt = Title
::makeTitle( Namespace::getMedia(), $name );
1933 return $this->makeMediaLinkObj( $nt, $alt );
1936 function makeMediaLinkObj( $nt, $alt = "" )
1938 if ( ! isset( $nt ) )
1940 ### HOTFIX. Instead of breaking, return empry string.
1943 $name = $nt->getDBKey();
1944 $url = Image
::wfImageUrl( $name );
1945 if ( empty( $alt ) ) {
1946 $alt = preg_replace( '/\.(.+?)^/', '', $name );
1949 $u = htmlspecialchars( $url );
1950 $s = "<a href=\"{$u}\" class='internal' title=\"{$alt}\">{$alt}</a>";
1955 function specialLink( $name, $key = "" )
1959 if ( '' == $key ) { $key = strtolower( $name ); }
1960 $pn = $wgLang->ucfirst( $name );
1961 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1965 function makeExternalLink( $url, $text, $escape = true ) {
1966 $style = $this->getExternalLinkAttributes( $url, $text );
1967 $url = htmlspecialchars( $url );
1969 $text = htmlspecialchars( $text );
1971 return '<a href="'.$url.'"'.$style.'>'.$text.'</a>';
1974 # Called by history lists and recent changes
1977 # Returns text for the start of the tabular part of RC
1978 function beginRecentChangesList()
1980 $this->rc_cache
= array() ;
1981 $this->rcMoveIndex
= 0;
1982 $this->rcCacheIndex
= 0 ;
1983 $this->lastdate
= '';
1984 $this->rclistOpen
= false;
1988 function beginImageHistoryList()
1990 $s = "\n<h2>" . wfMsg( 'imghistory' ) . "</h2>\n" .
1991 "<p>" . wfMsg( 'imghistlegend' ) . "</p>\n".'<ul class="special">';
1995 # Returns text for the end of RC
1996 # If enhanced RC is in use, returns pretty much all the text
1997 function endRecentChangesList()
1999 $s = $this->recentChangesBlock() ;
2000 if( $this->rclistOpen
) {
2006 # Enhanced RC ungrouped line
2007 function recentChangesBlockLine ( $rcObj )
2009 global $wgStylePath, $wgLang ;
2011 # Get rc_xxxx variables
2012 extract( $rcObj->mAttribs
) ;
2013 $curIdEq = 'curid='.$rc_cur_id;
2018 $r .= '<img src="'.$wgStylePath.'/images/Arr_.png" width="12" height="12" border="0" />' ;
2021 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2022 $r .= ' ';
2024 # M & N (minor & new)
2025 $M = wfMsg( 'minoreditletter' );
2026 $N = wfMsg( 'newpageletter' );
2028 if ( $rc_type == RC_NEW
) {
2041 $r .= ' '.$rcObj->timestamp
.' ' ;
2045 $link = $rcObj->link
;
2046 if ( $rcObj->watched
) $link = '<strong>'.$link.'</strong>' ;
2051 $r .= $rcObj->difflink
;
2055 $r .= $this->makeKnownLinkObj( $rcObj->getTitle(), wfMsg( 'hist' ), $curIdEq.'&action=history' );
2058 $r .= ') . . '.$rcObj->userlink
;
2059 $r .= $rcObj->usertalklink
;
2062 if ( $rc_comment != '' && $rc_type != RC_MOVE
&& $rc_type != RC_MOVE_OVER_REDIRECT
) {
2063 $rc_comment=$this->formatComment($rc_comment);
2064 $r .= $wgLang->emphasize( ' ('.$rc_comment.')' );
2072 function recentChangesBlockGroup ( $block )
2074 global $wgStylePath, $wgLang ;
2077 $M = wfMsg( 'minoreditletter' );
2078 $N = wfMsg( 'newpageletter' );
2080 # Collate list of users
2082 $userlinks = array () ;
2083 foreach ( $block AS $rcObj ) {
2084 $oldid = $rcObj->mAttribs
['rc_last_oldid'];
2085 if ( $rcObj->mAttribs
['rc_new'] ) $isnew = true ;
2086 $u = $rcObj->userlink
;
2087 if ( !isset ( $userlinks[$u] ) ) $userlinks[$u] = 0 ;
2091 # Sort the list and convert to text
2092 krsort ( $userlinks ) ;
2093 asort ( $userlinks ) ;
2095 foreach ( $userlinks as $userlink => $count) {
2097 if ( $count > 1 ) $text .= " ({$count}×)" ;
2098 array_push ( $users , $text ) ;
2100 $users = ' <font size="-1">['.implode('; ',$users).']</font>' ;
2103 $rci = 'RCI'.$this->rcCacheIndex
;
2104 $rcl = 'RCL'.$this->rcCacheIndex
;
2105 $rcm = 'RCM'.$this->rcCacheIndex
;
2106 $toggleLink = "javascript:toggleVisibility('$rci','$rcm','$rcl')" ;
2107 $arrowdir = $wgLang->isRTL() ?
'l' : 'r';
2108 $tl = '<span id="'.$rcm.'"><a href="'.$toggleLink.'"><img src="'.$wgStylePath.'/images/Arr_'.$arrowdir.'.png" width="12" height="12" /></a></span>' ;
2109 $tl .= '<span id="'.$rcl.'" style="display:none"><a href="'.$toggleLink.'"><img src="'.$wgStylePath.'/images/Arr_d.png" width="12" height="12" /></a></span>' ;
2115 if ( $isnew ) $r .= $N ;
2116 else $r .= ' ' ;
2117 $r .= ' ' ; # Minor
2120 $r .= ' '.$block[0]->timestamp
.' ' ;
2124 $link = $block[0]->link
;
2125 if ( $block[0]->watched
) $link = '<strong>'.$link.'</strong>' ;
2128 $curIdEq = 'curid=' . $block[0]->mAttribs
['rc_cur_id'];
2129 if ( $block[0]->mAttribs
['rc_type'] != RC_LOG
) {
2131 $r .= ' ('.count($block).' ' ;
2132 if ( $isnew ) $r .= wfMsg('changes');
2133 else $r .= $this->makeKnownLinkObj( $block[0]->getTitle() , wfMsg('changes') ,
2134 $curIdEq.'&diff=0&oldid='.$oldid ) ;
2138 $r .= $this->makeKnownLinkObj( $block[0]->getTitle(), wfMsg( 'history' ), $curIdEq.'&action=history' );
2146 $r .= '<div id="'.$rci.'" style="display:none">' ;
2147 foreach ( $block AS $rcObj ) {
2148 # Get rc_xxxx variables
2149 extract( $rcObj->mAttribs
);
2151 $r .= '<img src="'.$wgStylePath.'/images/Arr_.png" width="12" height="12" />';
2152 $r .= '<tt> ' ;
2153 if ( $rc_new ) $r .= $N ;
2154 else $r .= ' ' ;
2155 if ( $rc_minor ) $r .= $M ;
2156 else $r .= ' ' ;
2160 if ( $rc_last_oldid != 0 ) {
2161 $o = 'oldid='.$rc_last_oldid ;
2163 if ( $rc_type == RC_LOG
) {
2164 $link = $rcObj->timestamp
;
2166 $link = $this->makeKnownLinkObj( $rcObj->getTitle(), $rcObj->timestamp
, "{$curIdEq}&$o" ) ;
2168 $link = '<tt>'.$link.'</tt>' ;
2172 $r .= $rcObj->curlink
;
2174 $r .= $rcObj->lastlink
;
2175 $r .= ') . . '.$rcObj->userlink
;
2176 $r .= $rcObj->usertalklink
;
2177 if ( $rc_comment != '' ) {
2178 $rc_comment=$this->formatComment($rc_comment);
2179 $r .= $wgLang->emphasize( ' ('.$rc_comment.')' ) ;
2185 $this->rcCacheIndex++
;
2189 # If enhanced RC is in use, this function takes the previously cached
2190 # RC lines, arranges them, and outputs the HTML
2191 function recentChangesBlock ()
2193 global $wgStylePath ;
2194 if ( count ( $this->rc_cache
) == 0 ) return '' ;
2196 foreach ( $this->rc_cache
AS $secureName => $block ) {
2197 if ( count ( $block ) < 2 ) {
2198 $blockOut .= $this->recentChangesBlockLine ( array_shift ( $block ) ) ;
2200 $blockOut .= $this->recentChangesBlockGroup ( $block ) ;
2204 return '<div>'.$blockOut.'</div>' ;
2207 # Called in a loop over all displayed RC entries
2208 # Either returns the line, or caches it for later use
2209 function recentChangesLine( &$rc, $watched = false )
2212 $usenew = $wgUser->getOption( 'usenewrc' );
2214 $line = $this->recentChangesLineNew ( $rc, $watched ) ;
2216 $line = $this->recentChangesLineOld ( $rc, $watched ) ;
2220 function recentChangesLineOld( &$rc, $watched = false )
2222 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds;
2224 # Extract DB fields into local scope
2225 extract( $rc->mAttribs
);
2226 $curIdEq = 'curid=' . $rc_cur_id;
2228 # Make date header if necessary
2229 $date = $wgLang->date( $rc_timestamp, true);
2231 if ( $date != $this->lastdate
) {
2232 if ( '' != $this->lastdate
) { $s .= "</ul>\n"; }
2233 $s .= "<h4>{$date}</h4>\n<ul class='special'>";
2234 $this->lastdate
= $date;
2235 $this->rclistOpen
= true;
2239 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2241 $s .= '(' . wfMsg( 'diff' ) . ') (';
2243 $s .= $this->makeKnownLinkObj( $rc->getMovedToTitle(), wfMsg( 'hist' ), 'action=history' ) .
2246 # "[[x]] moved to [[y]]"
2247 if ( $rc_type == RC_MOVE
) {
2250 $msg = '1movedto2_redir';
2252 $s .= wfMsg( $msg, $this->makeKnownLinkObj( $rc->getTitle(), '', 'redirect=no' ),
2253 $this->makeKnownLinkObj( $rc->getMovedToTitle(), '' ) );
2256 if ( $rc_type == RC_NEW ||
$rc_type == RC_LOG
) {
2257 $diffLink = wfMsg( 'diff' );
2259 $diffLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'diff' ),
2260 $curIdEq.'&diff='.$rc_this_oldid.'&oldid='.$rc_last_oldid ,'' ,'' , ' tabindex="'.$rc->counter
.'"');
2262 $s .= '('.$diffLink.') (';
2265 $s .= $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'hist' ), $curIdEq.'&action=history' );
2268 # M and N (minor and new)
2269 $M = wfMsg( 'minoreditletter' );
2270 $N = wfMsg( 'newpageletter' );
2271 if ( $rc_minor ) { $s .= ' <strong>'.$M.'</strong>'; }
2272 if ( $rc_type == RC_NEW
) { $s .= '<strong>'.$N.'</strong>'; }
2275 $articleLink = $this->makeKnownLinkObj( $rc->getTitle(), '' );
2278 $articleLink = '<strong>'.$articleLink.'</strong>';
2280 $s .= ' '.$articleLink;
2285 $s .= '; ' . $wgLang->time( $rc_timestamp, true, $wgRCSeconds ) . ' . . ';
2287 # User link (or contributions for unregistered users)
2288 if ( 0 == $rc_user ) {
2289 $userLink = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
2290 $rc_user_text, 'target=' . $rc_user_text );
2292 $userLink = $this->makeLink( $wgLang->getNsText( NS_USER
) . ':'.$rc_user_text, $rc_user_text );
2297 $talkname=$wgLang->getNsText(NS_TALK
); # use the shorter name
2298 global $wgDisableAnonTalk;
2299 if( 0 == $rc_user && $wgDisableAnonTalk ) {
2302 $utns=$wgLang->getNsText(NS_USER_TALK
);
2303 $userTalkLink= $this->makeLink($utns . ':'.$rc_user_text, $talkname );
2307 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2308 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2309 'Blockip' ), wfMsg( 'blocklink' ), 'ip='.$rc_user_text );
2313 if($userTalkLink) $userTalkLink .= ' | ';
2314 $userTalkLink .= $blockLink;
2316 if($userTalkLink) $s.=' ('.$userTalkLink.')';
2319 if ( '' != $rc_comment && '*' != $rc_comment && $rc_type != RC_MOVE
&& $rc_type != RC_MOVE_OVER_REDIRECT
) {
2320 $rc_comment=$this->formatComment($rc_comment);
2321 $s .= $wgLang->emphasize(' (' . $rc_comment . ')');
2328 # function recentChangesLineNew( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched = false, $oldid = 0 , $diffid = 0 )
2329 function recentChangesLineNew( &$baseRC, $watched = false )
2331 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds;
2333 # Create a specialised object
2334 $rc = RCCacheEntry
::newFromParent( $baseRC ) ;
2336 # Extract fields from DB into the function scope (rc_xxxx variables)
2337 extract( $rc->mAttribs
);
2338 $curIdEq = 'curid=' . $rc_cur_id;
2340 # If it's a new day, add the headline and flush the cache
2341 $date = $wgLang->date( $rc_timestamp, true);
2343 if ( $date != $this->lastdate
) {
2344 # Process current cache
2345 $ret = $this->recentChangesBlock () ;
2346 $this->rc_cache
= array() ;
2347 $ret .= "<h4>{$date}</h4>\n";
2348 $this->lastdate
= $date;
2352 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2353 if ( $rc_type == RC_MOVE
) {
2356 $msg = "1movedto2_redir";
2358 $clink = wfMsg( $msg, $this->makeKnownLinkObj( $rc->getTitle(), '', 'redirect=no' ),
2359 $this->makeKnownLinkObj( $rc->getMovedToTitle(), '' ) );
2361 $clink = $this->makeKnownLinkObj( $rc->getTitle(), '' ) ;
2364 $time = $wgLang->time( $rc_timestamp, true, $wgRCSeconds );
2365 $rc->watched
= $watched ;
2366 $rc->link
= $clink ;
2367 $rc->timestamp
= $time;
2369 # Make "cur" and "diff" links
2370 if ( ( $rc_type == RC_NEW
&& $rc_this_oldid == 0 ) ||
$rc_type == RC_LOG ||
$rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2371 $curLink = wfMsg( 'cur' );
2372 $diffLink = wfMsg( 'diff' );
2374 $query = $curIdEq.'&diff=0&oldid='.$rc_this_oldid;
2375 $aprops = ' tabindex="'.$baseRC->counter
.'"';
2376 $curLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'cur' ), $query, '' ,'' , $aprops );
2377 $diffLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'diff'), $query, '' ,'' , $aprops );
2381 $titleObj = $rc->getTitle();
2382 if ( $rc_last_oldid == 0 ||
$rc_type == RC_LOG ||
$rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2383 $lastLink = wfMsg( 'last' );
2385 $lastLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'last' ),
2386 $curIdEq.'&diff='.$rc_this_oldid.'&oldid='.$rc_last_oldid );
2389 # Make user link (or user contributions for unregistered users)
2390 if ( 0 == $rc_user ) {
2391 $userLink = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
2392 $rc_user_text, 'target=' . $rc_user_text );
2394 $userLink = $this->makeLink( $wgLang->getNsText(
2395 Namespace::getUser() ) . ':'.$rc_user_text, $rc_user_text );
2398 $rc->userlink
= $userLink ;
2399 $rc->lastlink
= $lastLink ;
2400 $rc->curlink
= $curLink ;
2401 $rc->difflink
= $diffLink;
2404 # Make user talk link
2405 $utns=$wgLang->getNsText(NS_USER_TALK
);
2406 $talkname=$wgLang->getNsText(NS_TALK
); # use the shorter name
2407 $userTalkLink= $this->makeLink($utns . ':'.$rc_user_text, $talkname );
2409 global $wgDisableAnonTalk;
2410 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2411 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2412 'Blockip' ), wfMsg( 'blocklink' ), 'ip='.$rc_user_text );
2413 if( $wgDisableAnonTalk )
2414 $rc->usertalklink
= ' ('.$blockLink.')';
2416 $rc->usertalklink
= ' ('.$userTalkLink.' | '.$blockLink.')';
2418 if( $wgDisableAnonTalk && ($rc_user == 0) )
2419 $rc->usertalklink
= '';
2421 $rc->usertalklink
= ' ('.$userTalkLink.')';
2424 # Put accumulated information into the cache, for later display
2425 # Page moves go on their own line
2426 $title = $rc->getTitle();
2427 $secureName = $title->getPrefixedDBkey();
2428 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2429 # Use an @ character to prevent collision with page names
2430 $this->rc_cache
['@@' . ($this->rcMoveIndex++
)] = array($rc);
2432 if ( !isset ( $this->rc_cache
[$secureName] ) ) $this->rc_cache
[$secureName] = array() ;
2433 array_push ( $this->rc_cache
[$secureName] , $rc ) ;
2438 function endImageHistoryList()
2444 /* This function is called by all recent changes variants, by the page history,
2445 and by the user contributions list. It is responsible for formatting edit
2446 comments. It escapes any HTML in the comment, but adds some CSS to format
2447 auto-generated comments (from section editing) and formats [[wikilinks]].
2448 Main author: Erik Möller (moeller@scireview.de)
2450 function formatComment($comment)
2453 $comment=wfEscapeHTML($comment);
2455 # The pattern for autogen comments is / * foo * /, which makes for
2457 # We look for all comments, match any text before and after the comment,
2458 # add a separator where needed and format the comment itself with CSS
2459 while (preg_match('/(.*)\/\*\s*(.*?)\s*\*\/(.*)/', $comment,$match)) {
2464 if($pre) { $auto = $sep.' '.$auto; }
2465 if($post) { $auto .= ' '.$sep; }
2466 $auto='<span class="autocomment">'.$auto.'</span>';
2467 $comment=$pre.$auto.$post;
2470 # format regular and media links - all other wiki formatting
2472 while(preg_match('/\[\[(.*?)(\|(.*?))*\]\]/',$comment,$match)) {
2474 $medians = $wgLang->getNsText(Namespace::getMedia()).':';
2476 if(preg_match('/^'.$medians.'/i',$match[1])) {
2477 $func='makeMediaLink';
2479 # Handle link renaming [[foo|text]] will show link as "text"
2480 if(isset($match[3]) ) {
2482 preg_replace('/\[\[(.*?)\]\]/',
2483 $this->$func($match[1],$match[3]),$comment,1);
2486 preg_replace('/\[\[(.*?)\]\]/',
2487 $this->$func($match[1],$match[1]),$comment,1);
2495 function imageHistoryLine( $iscur, $timestamp, $img, $user, $usertext, $size, $description )
2497 global $wgUser, $wgLang, $wgTitle;
2499 $datetime = $wgLang->timeanddate( $timestamp, true );
2500 $del = wfMsg( 'deleteimg' );
2501 $cur = wfMsg( 'cur' );
2504 $url = Image
::wfImageUrl( $img );
2506 if ( $wgUser->isSysop() ) {
2507 $link = $wgTitle->escapeLocalURL( 'image=' . $wgTitle->getPartialURL() .
2509 $style = $this->getInternalLinkAttributes( $link, $del );
2511 $dlink = '<a href="'.$link.'"'.$style.'>'.$del.'</a>';
2516 $url = wfEscapeHTML( wfImageArchiveUrl( $img ) );
2517 if( $wgUser->getID() != 0 ) {
2518 $rlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2519 wfMsg( 'revertimg' ), 'action=revert&oldimage=' .
2520 urlencode( $img ) );
2521 $dlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2522 $del, 'action=delete&oldimage=' . urlencode( $img ) );
2524 # Having live active links for non-logged in users
2525 # means that bots and spiders crawling our site can
2526 # inadvertently change content. Baaaad idea.
2527 $rlink = wfMsg( 'revertimg' );
2532 $userlink = $usertext;
2534 $userlink = $this->makeLink( $wgLang->getNsText( Namespace::getUser() ) .
2535 ':'.$usertext, $usertext );
2537 $nbytes = wfMsg( 'nbytes', $size );
2538 $style = $this->getInternalLinkAttributes( $url, $datetime );
2540 $s = "<li> ({$dlink}) ({$rlink}) <a href=\"{$url}\"{$style}>{$datetime}</a>"
2541 . " . . {$userlink} ({$nbytes})";
2543 if ( '' != $description && '*' != $description ) {
2544 $sk=$wgUser->getSkin();
2545 $s .= $wgLang->emphasize(' (' . $sk->formatComment($description) . ')');
2551 function tocIndent($level) {
2552 return str_repeat( '<div class="tocindent">'."\n", $level>0 ?
$level : 0 );
2555 function tocUnindent($level) {
2556 return str_repeat( "</div>\n", $level>0 ?
$level : 0 );
2559 # parameter level defines if we are on an indentation level
2560 function tocLine( $anchor, $tocline, $level ) {
2561 $link = '<a href="#'.$anchor.'">'.$tocline.'</a><br />';
2565 return '<div class="tocline">'.$link."</div>\n";
2570 function tocTable($toc) {
2571 # note to CSS fanatics: putting this in a div does not work -- div won't auto-expand
2572 # try min-width & co when somebody gets a chance
2573 $hideline = ' <script type="text/javascript">showTocToggle("' . addslashes( wfMsg('showtoc') ) . '","' . addslashes( wfMsg('hidetoc') ) . '")</script>';
2575 '<table border="0" id="toc"><tr id="toctitle"><td align="center">'."\n".
2576 '<b>'.wfMsg('toc').'</b>' .
2578 '</td></tr><tr id="tocinside"><td>'."\n".
2579 $toc."</td></tr></table>\n";
2582 # These two do not check for permissions: check $wgTitle->userCanEdit before calling them
2583 function editSectionScript( $section, $head ) {
2584 global $wgTitle, $wgRequest;
2585 if( $wgRequest->getInt( 'oldid' ) && ( $wgRequest->getVal( 'diff' ) != '0' ) ) {
2588 $url = $wgTitle->escapeLocalURL( 'action=edit§ion='.$section );
2589 return '<span oncontextmenu=\'document.location="'.$url.'";return false;\'>'.$head.'</span>';
2592 function editSectionLink( $section ) {
2594 global $wgTitle, $wgUser, $wgLang;
2596 if( $wgRequest->getInt( 'oldid' ) && ( $wgRequest->getVal( 'diff' ) != '0' ) ) {
2597 # Section edit links would be out of sync on an old page.
2598 # But, if we're diffing to the current page, they'll be
2603 $editurl = '§ion='.$section;
2604 $url = $this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg('editsection'),'action=edit'.$editurl);
2606 if( $wgLang->isRTL() ) {
2608 $nearside = 'right';
2613 return "<div class=\"editsection\" style=\"float:$farside;margin-$nearside:5px;\">[".$url."]</div>";
2617 // This function is called by EditPage.php and shows a bulletin board style
2618 // toolbar for common editing functions. It can be disabled in the user preferences.
2619 // The necsesary JavaScript code can be found in style/wikibits.js.
2620 function getEditToolbar() {
2621 global $wgStylePath, $wgLang, $wgMimeType;
2623 // toolarray an array of arrays which each include the filename of
2624 // the button image (without path), the opening tag, the closing tag,
2625 // and optionally a sample text that is inserted between the two when no
2626 // selection is highlighted.
2627 // The tip text is shown when the user moves the mouse over the button.
2629 // Already here are accesskeys (key), which are not used yet until someone
2630 // can figure out a way to make them work in IE. However, we should make
2631 // sure these keys are not defined on the edit page.
2633 array( 'image'=>'button_bold.png',
2636 'sample'=>wfMsg('bold_sample'),
2637 'tip'=>wfMsg('bold_tip'),
2640 array( "image"=>"button_italic.png",
2643 "sample"=>wfMsg("italic_sample"),
2644 "tip"=>wfMsg("italic_tip"),
2647 array( "image"=>"button_link.png",
2650 "sample"=>wfMsg("link_sample"),
2651 "tip"=>wfMsg("link_tip"),
2654 array( "image"=>"button_extlink.png",
2657 "sample"=>wfMsg("extlink_sample"),
2658 "tip"=>wfMsg("extlink_tip"),
2661 array( "image"=>"button_headline.png",
2664 "sample"=>wfMsg("headline_sample"),
2665 "tip"=>wfMsg("headline_tip"),
2668 array( "image"=>"button_image.png",
2669 "open"=>"[[".$wgLang->getNsText(NS_IMAGE
).":",
2671 "sample"=>wfMsg("image_sample"),
2672 "tip"=>wfMsg("image_tip"),
2675 array( "image"=>"button_media.png",
2676 "open"=>"[[".$wgLang->getNsText(NS_MEDIA
).":",
2678 "sample"=>wfMsg("media_sample"),
2679 "tip"=>wfMsg("media_tip"),
2682 array( "image"=>"button_math.png",
2683 "open"=>"\\<math\\>",
2684 "close"=>"\\</math\\>",
2685 "sample"=>wfMsg("math_sample"),
2686 "tip"=>wfMsg("math_tip"),
2689 array( "image"=>"button_nowiki.png",
2690 "open"=>"\\<nowiki\\>",
2691 "close"=>"\\</nowiki\\>",
2692 "sample"=>wfMsg("nowiki_sample"),
2693 "tip"=>wfMsg("nowiki_tip"),
2696 array( "image"=>"button_sig.png",
2700 "tip"=>wfMsg("sig_tip"),
2703 array( "image"=>"button_hr.png",
2704 "open"=>"\\n----\\n",
2707 "tip"=>wfMsg("hr_tip"),
2711 $toolbar ="<script type='text/javascript'>\n/*<![CDATA[*/\n";
2713 $toolbar.="document.writeln(\"<div id='toolbar'>\");\n";
2714 foreach($toolarray as $tool) {
2716 $image=$wgStylePath.'/images/'.$tool['image'];
2717 $open=$tool['open'];
2718 $close=$tool['close'];
2719 $sample = addslashes( $tool['sample'] );
2721 // Note that we use the tip both for the ALT tag and the TITLE tag of the image.
2722 // Older browsers show a "speedtip" type message only for ALT.
2723 // Ideally these should be different, realistically they
2724 // probably don't need to be.
2725 $tip = addslashes( $tool['tip'] );
2727 #$key = $tool["key"];
2729 $toolbar.="addButton('$image','$tip','$open','$close','$sample');\n";
2732 $toolbar.="addInfobox('" . addslashes( wfMsg( "infobox" ) ) . "','" . addslashes(wfMsg("infobox_alert")) . "');\n";
2733 $toolbar.="document.writeln(\"</div>\");\n";
2735 $toolbar.="/*]]>*/\n</script>";