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;
158 $r = "<script type=\"text/javascript\" src=\"{$wgStylePath}/wikibits.js\"></script>\n";
159 if( $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;
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( $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;
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 $s .= ' ' . $this->getCredits();
788 return $s . ' ' . $this->getCopyright();
791 function getCredits() {
792 global $wgMaxCredits;
796 if (!isset($wgMaxCredits) ||
$wgMaxCredits == 0) {
797 $s = $this->lastModified();
799 $s = $this->getAuthorCredits();
800 if ($wgMaxCredits > 1) {
801 $s .= ' ' . $this->getContributorCredits();
808 function getAuthorCredits() {
809 global $wgLang, $wgArticle;
811 $last_author = $wgArticle->getUser();
813 if ($last_author == 0) {
814 $author_credit = wfMsg('anonymous');
816 $real_name = User
::whoIsReal($last_author);
817 if (!empty($real_name)) {
818 $author_credit = $real_name;
820 $author_credit = wfMsg('siteuser', User
::whoIs($last_author));
824 $timestamp = $wgArticle->getTimestamp();
826 $d = $wgLang->timeanddate( $wgArticle->getTimestamp(), true );
830 return wfMsg('lastmodifiedby', $d, $author_credit);
833 function getContributorCredits() {
835 global $wgArticle, $wgMaxCredits, $wgLang;
837 # don't count last editor
839 $contributors = $wgArticle->getContributors($wgMaxCredits - 1);
841 $real_names = array();
842 $user_names = array();
844 # Sift for real versus user names
846 foreach ($contributors as $user_id => $user_parts) {
848 if (!empty($user_parts[1])) {
849 $real_names[$user_id] = $user_parts[1];
851 $user_names[$user_id] = $user_parts[0];
856 $real = $wgLang->listToText(array_values($real_names));
857 $user = $wgLang->listToText(array_values($user_names));
860 $user = wfMsg('siteusers', $user);
863 if ($contributors[0] && $contributors[0][0] > 0) {
864 $anon = wfMsg('anonymous');
869 $creds = $wgLang->listToText(array($real, $user, $anon));
871 return wfMsg('othercontribs', $creds);
874 function getCopyright() {
875 global $wgRightsPage, $wgRightsUrl, $wgRightsText, $wgRequest;
878 $oldid = $wgRequest->getVal( 'oldid' );
879 $diff = $wgRequest->getVal( 'diff' );
881 if ( !is_null( $oldid ) && is_null( $diff ) && wfMsg( 'history_copyright' ) !== '-' ) {
882 $msg = 'history_copyright';
888 if( $wgRightsPage ) {
889 $link = $this->makeKnownLink( $wgRightsPage, $wgRightsText );
890 } elseif( $wgRightsUrl ) {
891 $link = $this->makeExternalLink( $wgRightsUrl, $wgRightsText );
896 $out .= wfMsg( $msg, $link );
900 function getCopyrightIcon() {
901 global $wgRightsPage, $wgRightsUrl, $wgRightsText, $wgRightsIcon;
903 if( $wgRightsIcon ) {
904 $icon = htmlspecialchars( $wgRightsIcon );
906 $url = htmlspecialchars( $wgRightsUrl );
907 $out .= '<a href="'.$url.'">';
909 $text = htmlspecialchars( $wgRightsText );
910 $out .= "<img src=\"$icon\" alt='$text' />";
918 function getPoweredBy() {
920 $url = htmlspecialchars( "$wgStylePath/images/poweredby_mediawiki_88x31.png" );
921 $img = '<a href="http://www.mediawiki.org/"><img src="'.$url.'" alt="MediaWiki" /></a>';
925 function lastModified()
927 global $wgLang, $wgArticle;
929 $timestamp = $wgArticle->getTimestamp();
931 $d = $wgLang->timeanddate( $wgArticle->getTimestamp(), true );
932 $s = ' ' . wfMsg( 'lastmodified', $d );
939 function logoText( $align = '' )
941 if ( '' != $align ) { $a = ' align="'.$align.'"'; }
944 $mp = wfMsg( 'mainpage' );
945 $titleObj = Title
::newFromText( $mp );
946 $s = '<a href="' . $titleObj->escapeLocalURL()
947 . '"><img'.$a.' src="'
948 . $this->getLogo() . '" alt="' . "[{$mp}]\" /></a>";
954 global $wgOut, $wgTitle, $wgUser, $wgRequest, $wgLang;
955 global $wgDisableUploads, $wgRemoteUploads;
957 $fname = 'Skin::quickBar';
958 wfProfileIn( $fname );
960 $action = $wgRequest->getText( 'action' );
961 $wpPreview = $wgRequest->getBool( 'wpPreview' );
962 $tns=$wgTitle->getNamespace();
964 $s = "\n<div id='quickbar'>";
965 $s .= "\n" . $this->logoText() . "\n<hr class='sep' />";
968 $s .= $this->mainPageLink()
969 . $sep . $this->specialLink( 'recentchanges' )
970 . $sep . $this->specialLink( 'randompage' );
971 if ($wgUser->getID()) {
972 $s.= $sep . $this->specialLink( 'watchlist' ) ;
973 $s .= $sep .$this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
974 wfMsg( 'mycontris' ), 'target=' . wfUrlencode($wgUser->getName() ) );
977 // only show watchlist link if logged in
978 if ( wfMsg ( 'currentevents' ) != '-' ) $s .= $sep . $this->makeKnownLink( wfMsg( 'currentevents' ), '' ) ;
979 $s .= "\n<br /><hr class='sep' />";
980 $articleExists = $wgTitle->getArticleId();
981 if ( $wgOut->isArticle() ||
$action =='edit' ||
$action =='history' ||
$wpPreview) {
982 if($wgOut->isArticle()) {
983 $s .= '<strong>' . $this->editThisPage() . '</strong>';
984 } else { # backlink to the article in edit or history mode
985 if($articleExists){ # no backlink if no article
988 $text = wfMsg('articlepage');
991 $text = wfMsg('viewtalkpage');
994 $text = wfMsg('userpage');
997 $text = wfMsg('viewtalkpage');
1000 $text = wfMsg('wikipediapage');
1003 $text = wfMsg('viewtalkpage');
1006 $text = wfMsg('imagepage');
1009 $text = wfMsg('viewtalkpage');
1012 $text= wfMsg('articlepage');
1015 $link = $wgTitle->getText();
1016 if ($nstext = $wgLang->getNsText($tns) ) { # add namespace if necessary
1017 $link = $nstext . ':' . $link ;
1020 $s .= $this->makeLink( $link, $text );
1021 } elseif( $wgTitle->getNamespace() != Namespace::getSpecial() ) {
1022 # we just throw in a "New page" text to tell the user that he's in edit mode,
1023 # and to avoid messing with the separator that is prepended to the next item
1024 $s .= '<strong>' . wfMsg('newpage') . '</strong>';
1030 if( $tns%2
&& $action!='edit' && !$wpPreview) {
1031 $s.= '<br />'.$this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg('postcomment'),'action=edit§ion=new');
1035 watching could cause problems in edit mode:
1036 if user edits article, then loads "watch this article" in background and then saves
1037 article with "Watch this article" checkbox disabled, the article is transparently
1038 unwatched. Therefore we do not show the "Watch this page" link in edit mode
1040 if ( 0 != $wgUser->getID() && $articleExists) {
1041 if($action!='edit' && $action != 'submit' )
1043 $s .= $sep . $this->watchThisPage();
1045 if ( $wgTitle->userCanEdit() )
1046 $s .= $sep . $this->moveThisPage();
1048 if ( $wgUser->isSysop() and $articleExists ) {
1049 $s .= $sep . $this->deleteThisPage() .
1050 $sep . $this->protectThisPage();
1052 $s .= $sep . $this->talkLink();
1053 if ($articleExists && $action !='history') {
1054 $s .= $sep . $this->historyLink();
1056 $s.=$sep . $this->whatLinksHere();
1058 if($wgOut->isArticleRelated()) {
1059 $s .= $sep . $this->watchPageLinksLink();
1062 if ( Namespace::getUser() == $wgTitle->getNamespace()
1063 ||
$wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser())
1066 $id=User
::idFromName($wgTitle->getText());
1067 $ip=User
::isIP($wgTitle->getText());
1070 $s .= $sep . $this->userContribsLink();
1072 if ( 0 != $wgUser->getID() ) {
1073 if($id) { # can only email real users
1074 $s .= $sep . $this->emailUserLink();
1078 $s .= "\n<br /><hr class='sep' />";
1081 if ( 0 != $wgUser->getID() && ( !$wgDisableUploads ||
$wgRemoteUploads ) ) {
1082 $s .= $this->specialLink( 'upload' ) . $sep;
1084 $s .= $this->specialLink( 'specialpages' )
1085 . $sep . $this->bugReportsLink();
1087 global $wgSiteSupportPage;
1088 if( $wgSiteSupportPage ) {
1089 $s .= "\n<br /><a href=\"" . htmlspecialchars( $wgSiteSupportPage ) .
1090 '" class="internal">' . wfMsg( 'sitesupport' ) . '</a>';
1093 $s .= "\n<br /></div>\n";
1094 wfProfileOut( $fname );
1098 function specialPagesList()
1100 global $wgUser, $wgOut, $wgLang, $wgServer, $wgRedirectScript;
1101 require_once('SpecialPage.php');
1103 $pages = SpecialPage
::getPages();
1105 foreach ( $pages[''] as $name => $page ) {
1106 $a[$name] = $page->getDescription();
1108 if ( $wgUser->isSysop() )
1110 foreach ( $pages['sysop'] as $name => $page ) {
1111 $a[$name] = $page->getDescription();
1114 if ( $wgUser->isDeveloper() )
1116 foreach ( $pages['developer'] as $name => $page ) {
1117 $a[$name] = $page->getDescription() ;
1120 $go = wfMsg( 'go' );
1121 $sp = wfMsg( 'specialpages' );
1122 $spp = $wgLang->specialPage( 'Specialpages' );
1124 $s = '<form id="specialpages" method="get" class="inline" ' .
1125 'action="' . htmlspecialchars( "{$wgServer}{$wgRedirectScript}" ) . "\">\n";
1126 $s .= "<select name=\"wpDropdown\">\n";
1127 $s .= "<option value=\"{$spp}\">{$sp}</option>\n";
1129 foreach ( $a as $name => $desc ) {
1130 $p = $wgLang->specialPage( $name );
1131 $s .= "<option value=\"{$p}\">{$desc}</option>\n";
1133 $s .= "</select>\n";
1134 $s .= "<input type='submit' value=\"{$go}\" name='redirect' />\n";
1139 function mainPageLink()
1141 $mp = wfMsg( 'mainpage' );
1142 $s = $this->makeKnownLink( $mp, $mp );
1146 function copyrightLink()
1148 $s = $this->makeKnownLink( wfMsg( 'copyrightpage' ),
1149 wfMsg( 'copyrightpagename' ) );
1153 function aboutLink()
1155 $s = $this->makeKnownLink( wfMsg( 'aboutpage' ),
1156 wfMsg( 'aboutwikipedia' ) );
1161 function disclaimerLink()
1163 $s = $this->makeKnownLink( wfMsg( 'disclaimerpage' ),
1164 wfMsg( 'disclaimers' ) );
1168 function editThisPage()
1170 global $wgOut, $wgTitle, $wgRequest;
1172 $oldid = $wgRequest->getVal( 'oldid' );
1173 $diff = $wgRequest->getVal( 'diff' );
1174 $redirect = $wgRequest->getVal( 'redirect' );
1176 if ( ! $wgOut->isArticleRelated() ) {
1177 $s = wfMsg( 'protectedpage' );
1179 $n = $wgTitle->getPrefixedText();
1180 if ( $wgTitle->userCanEdit() ) {
1181 $t = wfMsg( 'editthispage' );
1183 #$t = wfMsg( "protectedpage" );
1184 $t = wfMsg( 'viewsource' );
1188 if ( !is_null( $redirect ) ) { $red = "&redirect={$redirect}"; }
1189 if ( $oldid && ! isset( $diff ) ) {
1190 $oid = "&oldid={$oldid}";
1192 $s = $this->makeKnownLink( $n, $t, "action=edit{$oid}{$red}" );
1197 function deleteThisPage()
1199 global $wgUser, $wgOut, $wgTitle, $wgRequest;
1201 $diff = $wgRequest->getVal( 'diff' );
1202 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
1203 $n = $wgTitle->getPrefixedText();
1204 $t = wfMsg( 'deletethispage' );
1206 $s = $this->makeKnownLink( $n, $t, 'action=delete' );
1213 function protectThisPage()
1215 global $wgUser, $wgOut, $wgTitle, $wgRequest;
1217 $diff = $wgRequest->getVal( 'diff' );
1218 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
1219 $n = $wgTitle->getPrefixedText();
1221 if ( $wgTitle->isProtected() ) {
1222 $t = wfMsg( 'unprotectthispage' );
1223 $q = 'action=unprotect';
1225 $t = wfMsg( 'protectthispage' );
1226 $q = 'action=protect';
1228 $s = $this->makeKnownLink( $n, $t, $q );
1235 function watchThisPage()
1237 global $wgUser, $wgOut, $wgTitle;
1239 if ( $wgOut->isArticleRelated() ) {
1240 $n = $wgTitle->getPrefixedText();
1242 if ( $wgTitle->userIsWatching() ) {
1243 $t = wfMsg( 'unwatchthispage' );
1244 $q = 'action=unwatch';
1246 $t = wfMsg( 'watchthispage' );
1247 $q = 'action=watch';
1249 $s = $this->makeKnownLink( $n, $t, $q );
1251 $s = wfMsg( 'notanarticle' );
1256 function moveThisPage()
1258 global $wgTitle, $wgLang;
1260 if ( $wgTitle->userCanEdit() ) {
1261 $s = $this->makeKnownLink( $wgLang->specialPage( 'Movepage' ),
1262 wfMsg( 'movethispage' ), 'target=' . $wgTitle->getPrefixedURL() );
1263 } // no message if page is protected - would be redundant
1267 function historyLink()
1271 $s = $this->makeKnownLink( $wgTitle->getPrefixedText(),
1272 wfMsg( 'history' ), 'action=history' );
1276 function whatLinksHere()
1278 global $wgTitle, $wgLang;
1280 $s = $this->makeKnownLink( $wgLang->specialPage( 'Whatlinkshere' ),
1281 wfMsg( 'whatlinkshere' ), 'target=' . $wgTitle->getPrefixedURL() );
1285 function userContribsLink()
1287 global $wgTitle, $wgLang;
1289 $s = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
1290 wfMsg( 'contributions' ), 'target=' . $wgTitle->getPartialURL() );
1294 function emailUserLink()
1296 global $wgTitle, $wgLang;
1298 $s = $this->makeKnownLink( $wgLang->specialPage( 'Emailuser' ),
1299 wfMsg( 'emailuser' ), 'target=' . $wgTitle->getPartialURL() );
1303 function watchPageLinksLink()
1305 global $wgOut, $wgTitle, $wgLang;
1307 if ( ! $wgOut->isArticleRelated() ) {
1308 $s = '(' . wfMsg( 'notanarticle' ) . ')';
1310 $s = $this->makeKnownLink( $wgLang->specialPage(
1311 'Recentchangeslinked' ), wfMsg( 'recentchangeslinked' ),
1312 'target=' . $wgTitle->getPrefixedURL() );
1317 function otherLanguages()
1319 global $wgOut, $wgLang, $wgTitle, $wgUseNewInterlanguage;
1321 $a = $wgOut->getLanguageLinks();
1322 if ( 0 == count( $a ) ) {
1323 if ( !$wgUseNewInterlanguage ) return '';
1324 $ns = $wgLang->getNsIndex ( $wgTitle->getNamespace () ) ;
1325 if ( $ns != 0 AND $ns != 1 ) return '' ;
1327 $x = 'mode=addlink&xt='.$wgTitle->getDBkey() ;
1328 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1329 wfMsg( 'intl' ) , $x );
1332 if ( !$wgUseNewInterlanguage ) {
1333 $s = wfMsg( 'otherlanguages' ) . ': ';
1335 global $wgLanguageCode ;
1336 $x = 'mode=zoom&xt='.$wgTitle->getDBkey() ;
1337 $x .= '&xl='.$wgLanguageCode ;
1338 $s = $this->makeKnownLink( $wgLang->specialPage( 'Intl' ),
1339 wfMsg( 'otherlanguages' ) , $x ) . ': ' ;
1342 $s = wfMsg( 'otherlanguages' ) . ': ';
1344 if($wgLang->isRTL()) $s .= '<span dir="LTR">';
1345 foreach( $a as $l ) {
1346 if ( ! $first ) { $s .= ' | '; }
1349 $nt = Title
::newFromText( $l );
1350 $url = $nt->getFullURL();
1351 $text = $wgLang->getLanguageName( $nt->getInterwiki() );
1353 if ( '' == $text ) { $text = $l; }
1354 $style = $this->getExternalLinkAttributes( $l, $text );
1355 $s .= "<a href=\"{$url}\"{$style}>{$text}</a>";
1357 if($wgLang->isRTL()) $s .= '</span>';
1361 function bugReportsLink()
1363 $s = $this->makeKnownLink( wfMsg( 'bugreportspage' ),
1364 wfMsg( 'bugreports' ) );
1370 global $wgLinkCache;
1371 $t1 = Title
::newFromText( gmdate( 'F j' ) );
1372 $t2 = Title
::newFromText( gmdate( 'Y' ) );
1374 $wgLinkCache->suspend();
1375 $id = $t1->getArticleID();
1376 $wgLinkCache->resume();
1379 $s = $this->makeBrokenLink( $t1->getText() );
1381 $s = $this->makeKnownLink( $t1->getText() );
1385 $wgLinkCache->suspend();
1386 $id = $t2->getArticleID();
1387 $wgLinkCache->resume();
1390 $s .= $this->makeBrokenLink( $t2->getText() );
1392 $s .= $this->makeKnownLink( $t2->getText() );
1399 global $wgLang, $wgTitle, $wgLinkCache;
1401 $tns = $wgTitle->getNamespace();
1402 if ( -1 == $tns ) { return ''; }
1404 $pn = $wgTitle->getText();
1405 $tp = wfMsg( 'talkpage' );
1406 if ( Namespace::isTalk( $tns ) ) {
1407 $lns = Namespace::getSubject( $tns );
1410 $text = wfMsg('articlepage');
1413 $text = wfMsg('userpage');
1416 $text = wfMsg('wikipediapage');
1419 $text = wfMsg('imagepage');
1422 $text= wfMsg('articlepage');
1426 $lns = Namespace::getTalk( $tns );
1429 $n = $wgLang->getNsText( $lns );
1430 if ( '' == $n ) { $link = $pn; }
1431 else { $link = $n.':'.$pn; }
1433 $wgLinkCache->suspend();
1434 $s = $this->makeLink( $link, $text );
1435 $wgLinkCache->resume();
1440 function commentLink()
1442 global $wgLang, $wgTitle, $wgLinkCache;
1444 $tns = $wgTitle->getNamespace();
1445 if ( -1 == $tns ) { return ''; }
1447 $lns = ( Namespace::isTalk( $tns ) ) ?
$tns : Namespace::getTalk( $tns );
1449 # assert Namespace::isTalk( $lns )
1451 $n = $wgLang->getNsText( $lns );
1452 $pn = $wgTitle->getText();
1456 $wgLinkCache->suspend();
1457 $s = $this->makeKnownLink($link, wfMsg('postcomment'), 'action=edit§ion=new');
1458 $wgLinkCache->resume();
1463 # After all the page content is transformed into HTML, it makes
1464 # a final pass through here for things like table backgrounds.
1466 function transformContent( $text )
1471 # Note: This function MUST call getArticleID() on the link,
1472 # otherwise the cache won't get updated properly. See LINKCACHE.DOC.
1474 function makeLink( $title, $text = '', $query = '', $trail = '' ) {
1475 wfProfileIn( 'Skin::makeLink' );
1476 $nt = Title
::newFromText( $title );
1478 $result = $this->makeLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1480 wfDebug( 'Invalid title passed to Skin::makeLink(): "'.$title."\"\n" );
1481 $result = $text == "" ?
$title : $text;
1484 wfProfileOut( 'Skin::makeLink' );
1488 function makeKnownLink( $title, $text = '', $query = '', $trail = '', $prefix = '',$aprops = '') {
1489 $nt = Title
::newFromText( $title );
1491 return $this->makeKnownLinkObj( Title
::newFromText( $title ), $text, $query, $trail, $prefix , $aprops );
1493 wfDebug( 'Invalid title passed to Skin::makeKnownLink(): "'.$title."\"\n" );
1494 return $text == '' ?
$title : $text;
1498 function makeBrokenLink( $title, $text = '', $query = '', $trail = '' ) {
1499 $nt = Title
::newFromText( $title );
1501 return $this->makeBrokenLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1503 wfDebug( 'Invalid title passed to Skin::makeBrokenLink(): "'.$title."\"\n" );
1504 return $text == '' ?
$title : $text;
1508 function makeStubLink( $title, $text = '', $query = '', $trail = '' ) {
1509 $nt = Title
::newFromText( $title );
1511 return $this->makeStubLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1513 wfDebug( 'Invalid title passed to Skin::makeStubLink(): "'.$title."\"\n" );
1514 return $text == '' ?
$title : $text;
1518 # Pass a title object, not a title string
1519 function makeLinkObj( &$nt, $text= '', $query = '', $trail = '', $prefix = '' )
1521 global $wgOut, $wgUser;
1522 if ( $nt->isExternal() ) {
1523 $u = $nt->getFullURL();
1524 $link = $nt->getPrefixedURL();
1525 if ( '' == $text ) { $text = $nt->getPrefixedText(); }
1526 $style = $this->getExternalLinkAttributes( $link, $text, 'extiw' );
1529 if ( '' != $trail ) {
1530 if ( preg_match( '/^([a-z]+)(.*)$$/sD', $trail, $m ) ) {
1535 $retVal = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1536 } elseif ( 0 == $nt->getNamespace() && "" == $nt->getText() ) {
1537 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1538 } elseif ( ( -1 == $nt->getNamespace() ) ||
1539 ( Namespace::getImage() == $nt->getNamespace() ) ) {
1540 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1542 $aid = $nt->getArticleID() ;
1544 $retVal = $this->makeBrokenLinkObj( $nt, $text, $query, $trail, $prefix );
1546 $threshold = $wgUser->getOption('stubthreshold') ;
1547 if ( $threshold > 0 ) {
1548 $res = wfQuery ( "SELECT LENGTH(cur_text) AS x, cur_namespace, cur_is_redirect FROM cur WHERE cur_id='{$aid}'", DB_READ
) ;
1550 if ( wfNumRows( $res ) > 0 ) {
1551 $s = wfFetchObject( $res );
1553 if ( $s->cur_is_redirect
OR $s->cur_namespace
!= 0 ) {
1554 $size = $threshold*2 ; # Really big
1556 wfFreeResult( $res );
1558 $size = $threshold*2 ; # Really big
1563 if ( $size < $threshold ) {
1564 $retVal = $this->makeStubLinkObj( $nt, $text, $query, $trail, $prefix );
1566 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1573 # Pass a title object, not a title string
1574 function makeKnownLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' , $aprops = '')
1576 global $wgOut, $wgTitle, $wgInputEncoding;
1578 $fname = 'Skin::makeKnownLinkObj';
1579 wfProfileIn( $fname );
1581 if ( !is_object( $nt ) ) {
1584 $link = $nt->getPrefixedURL();
1586 if ( '' == $link ) {
1588 if ( '' == $text ) {
1589 $text = htmlspecialchars( $nt->getFragment() );
1592 $u = $nt->escapeLocalURL( $query );
1594 if ( '' != $nt->getFragment() ) {
1595 $anchor = urlencode( do_html_entity_decode( str_replace(' ', '_', $nt->getFragment()), ENT_COMPAT
, $wgInputEncoding ) );
1596 $replacearray = array(
1600 $u .= '#' . str_replace(array_keys($replacearray),array_values($replacearray),$anchor);
1602 if ( '' == $text ) {
1603 $text = htmlspecialchars( $nt->getPrefixedText() );
1605 $style = $this->getInternalLinkAttributesObj( $nt, $text );
1608 if ( '' != $trail ) {
1609 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1614 $r = "<a href=\"{$u}\"{$style}{$aprops}>{$prefix}{$text}{$inside}</a>{$trail}";
1615 wfProfileOut( $fname );
1619 # Pass a title object, not a title string
1620 function makeBrokenLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
1622 global $wgOut, $wgUser;
1624 $fname = 'Skin::makeBrokenLinkObj';
1625 wfProfileIn( $fname );
1627 if ( '' == $query ) {
1630 $q = 'action=edit&'.$query;
1632 $u = $nt->escapeLocalURL( $q );
1634 if ( '' == $text ) {
1635 $text = htmlspecialchars( $nt->getPrefixedText() );
1637 $style = $this->getInternalLinkAttributesObj( $nt, $text, "yes" );
1640 if ( '' != $trail ) {
1641 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1646 if ( $wgUser->getOption( 'highlightbroken' ) ) {
1647 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1649 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>?</a>{$trail}";
1652 wfProfileOut( $fname );
1656 # Pass a title object, not a title string
1657 function makeStubLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
1659 global $wgOut, $wgUser;
1661 $link = $nt->getPrefixedURL();
1663 $u = $nt->escapeLocalURL( $query );
1665 if ( '' == $text ) {
1666 $text = htmlspecialchars( $nt->getPrefixedText() );
1668 $style = $this->getInternalLinkAttributesObj( $nt, $text, 'stub' );
1671 if ( '' != $trail ) {
1672 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1677 if ( $wgUser->getOption( 'highlightbroken' ) ) {
1678 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1680 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>!</a>{$trail}";
1685 function makeSelfLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
1687 $u = $nt->escapeLocalURL( $query );
1688 if ( '' == $text ) {
1689 $text = htmlspecialchars( $nt->getPrefixedText() );
1692 if ( '' != $trail ) {
1693 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1698 return "<strong>{$prefix}{$text}{$inside}</strong>{$trail}";
1701 /* these are used extensively in SkinPHPTal, but also some other places */
1702 /*static*/ function makeSpecialUrl( $name, $urlaction='' ) {
1703 $title = Title
::makeTitle( NS_SPECIAL
, $name );
1704 $this->checkTitle($title, $name);
1705 return $title->getLocalURL( $urlaction );
1707 /*static*/ function makeTalkUrl ( $name, $urlaction='' ) {
1708 $title = Title
::newFromText( $name );
1709 $title = $title->getTalkPage();
1710 $this->checkTitle($title, $name);
1711 return $title->getLocalURL( $urlaction );
1713 /*static*/ function makeArticleUrl ( $name, $urlaction='' ) {
1714 $title = Title
::newFromText( $name );
1715 $title= $title->getSubjectPage();
1716 $this->checkTitle($title, $name);
1717 return $title->getLocalURL( $urlaction );
1719 /*static*/ function makeI18nUrl ( $name, $urlaction='' ) {
1720 $title = Title
::newFromText( wfMsg($name) );
1721 $this->checkTitle($title, $name);
1722 return $title->getLocalURL( $urlaction );
1724 /*static*/ function makeUrl ( $name, $urlaction='' ) {
1725 $title = Title
::newFromText( $name );
1726 $this->checkTitle($title, $name);
1727 return $title->getLocalURL( $urlaction );
1729 # this can be passed the NS number as defined in Language.php
1730 /*static*/ function makeNSUrl( $name, $urlaction='', $namespace=0 ) {
1731 $title = Title
::makeTitle( $namespace, $name );
1732 $this->checkTitle($title, $name);
1733 return $title->getLocalURL( $urlaction );
1736 /* these return an array with the 'href' and boolean 'exists' */
1737 /*static*/ function makeUrlDetails ( $name, $urlaction='' ) {
1738 $title = Title
::newFromText( $name );
1739 $this->checkTitle($title, $name);
1741 'href' => $title->getLocalURL( $urlaction ),
1742 'exists' => $title->getArticleID() != 0?
true:false
1745 /*static*/ function makeTalkUrlDetails ( $name, $urlaction='' ) {
1746 $title = Title
::newFromText( $name );
1747 $title = $title->getTalkPage();
1748 $this->checkTitle($title, $name);
1750 'href' => $title->getLocalURL( $urlaction ),
1751 'exists' => $title->getArticleID() != 0?
true:false
1754 /*static*/ function makeArticleUrlDetails ( $name, $urlaction='' ) {
1755 $title = Title
::newFromText( $name );
1756 $title= $title->getSubjectPage();
1757 $this->checkTitle($title, $name);
1759 'href' => $title->getLocalURL( $urlaction ),
1760 'exists' => $title->getArticleID() != 0?
true:false
1763 /*static*/ function makeI18nUrlDetails ( $name, $urlaction='' ) {
1764 $title = Title
::newFromText( wfMsg($name) );
1765 $this->checkTitle($title, $name);
1767 'href' => $title->getLocalURL( $urlaction ),
1768 'exists' => $title->getArticleID() != 0?
true:false
1772 # make sure we have some title to operate on
1773 /*static*/ function checkTitle ( &$title, &$name ) {
1774 if(!is_object($title)) {
1775 $title = Title
::newFromText( $name );
1776 if(!is_object($title)) {
1777 $title = Title
::newFromText( '<error: link target missing>' );
1782 function fnamePart( $url )
1784 $basename = strrchr( $url, '/' );
1785 if ( false === $basename ) { $basename = $url; }
1786 else { $basename = substr( $basename, 1 ); }
1787 return wfEscapeHTML( $basename );
1790 function makeImage( $url, $alt = '' )
1794 if ( '' == $alt ) { $alt = $this->fnamePart( $url ); }
1795 $s = '<img src="'.$url.'" alt="'.$alt.'" />';
1799 function makeImageLink( $name, $url, $alt = '' ) {
1800 $nt = Title
::makeTitle( Namespace::getImage(), $name );
1801 return $this->makeImageLinkObj( $nt, $alt );
1804 function makeImageLinkObj( $nt, $alt = '' ) {
1805 global $wgLang, $wgUseImageResize;
1806 $img = Image
::newFromTitle( $nt );
1807 $url = $img->getURL();
1810 $prefix = $postfix = '';
1812 if ( $wgUseImageResize ) {
1813 # Check if the alt text is of the form "options|alt text"
1815 # * thumbnail make a thumbnail with enlarge-icon and caption, alignment depends on lang
1816 # * left no resizing, just left align. label is used for alt= only
1817 # * right same, but right aligned
1818 # * none same, but not aligned
1819 # * ___px scale to ___ pixels width, no aligning. e.g. use in taxobox
1820 # * center center the image
1821 # * framed Keep original image size, no magnify-button.
1823 $part = explode( '|', $alt);
1825 $mwThumb =& MagicWord
::get( MAG_IMG_THUMBNAIL
);
1826 $mwLeft =& MagicWord
::get( MAG_IMG_LEFT
);
1827 $mwRight =& MagicWord
::get( MAG_IMG_RIGHT
);
1828 $mwNone =& MagicWord
::get( MAG_IMG_NONE
);
1829 $mwWidth =& MagicWord
::get( MAG_IMG_WIDTH
);
1830 $mwCenter =& MagicWord
::get( MAG_IMG_CENTER
);
1831 $mwFramed =& MagicWord
::get( MAG_IMG_FRAMED
);
1832 $alt = $part[count($part)-1];
1834 $height = $framed = $thumb = false;
1836 foreach( $part as $key => $val ) {
1837 if ( ! is_null( $mwThumb->matchVariableStartToEnd($val) ) ) {
1839 } elseif ( ! is_null( $mwRight->matchVariableStartToEnd($val) ) ) {
1840 # remember to set an alignment, don't render immediately
1842 } elseif ( ! is_null( $mwLeft->matchVariableStartToEnd($val) ) ) {
1843 # remember to set an alignment, don't render immediately
1845 } elseif ( ! is_null( $mwCenter->matchVariableStartToEnd($val) ) ) {
1846 # remember to set an alignment, don't render immediately
1848 } elseif ( ! is_null( $mwNone->matchVariableStartToEnd($val) ) ) {
1849 # remember to set an alignment, don't render immediately
1851 } elseif ( ! is_null( $match = $mwWidth->matchVariableStartToEnd($val) ) ) {
1852 # $match is the image width in pixels
1853 if ( preg_match( '/^([0-9]*)x([0-9]*)$/', $match, $m ) ) {
1854 $width = intval( $m[1] );
1855 $height = intval( $m[2] );
1857 $width = intval($match);
1859 } elseif ( ! is_null( $mwFramed->matchVariableStartToEnd($val) ) ) {
1863 if ( 'center' == $align )
1865 $prefix = '<span style="text-align: center">';
1866 $postfix = '</span>';
1870 if ( $thumb ||
$framed ) {
1872 # Create a thumbnail. Alignment depends on language
1873 # writing direction, # right aligned for left-to-right-
1874 # languages ("Western languages"), left-aligned
1875 # for right-to-left-languages ("Semitic languages")
1877 # If thumbnail width has not been provided, it is set
1878 # here to 180 pixels
1879 if ( $align == '' ) {
1880 $align = $wgLang->isRTL() ?
'left' : 'right';
1882 if ( ! isset($width) ) {
1885 return $prefix.$this->makeThumbLinkObj( $img, $alt, $align, $width, $height, $framed ).$postfix;
1887 } elseif ( isset($width) ) {
1889 # Create a resized image, without the additional thumbnail
1892 if ( ( ! $height === false )
1893 && ( $img->getHeight() * $width / $img->getWidth() > $height ) ) {
1894 print "height=$height<br>\nimg->getHeight() = ".$img->getHeight()."<br>\n";
1895 print 'rescaling by factor '. $height / $img->getHeight() . "<br>\n";
1896 $width = $img->getWidth() * $height / $img->getHeight();
1898 $url = $img->createThumb( $width );
1900 } # endif $wgUseImageResize
1902 if ( empty( $alt ) ) {
1903 $alt = preg_replace( '/\.(.+?)^/', '', $img->getName() );
1905 $alt = htmlspecialchars( $alt );
1907 $u = $nt->escapeLocalURL();
1910 $s = str_replace( "$1", $img->getName(), wfMsg('missingimage') );
1911 $s .= "<br>{$alt}<br>{$url}<br>\n";
1913 $s = '<a href="'.$u.'" class="image" title="'.$alt.'">' .
1914 '<img src="'.$url.'" alt="'.$alt.'" /></a>';
1916 if ( '' != $align ) {
1917 $s = "<div class=\"float{$align}\"><span>{$s}</span></div>";
1919 return str_replace("\n", ' ',$prefix.$s.$postfix);
1923 function makeThumbLinkObj( $img, $label = '', $align = 'right', $boxwidth = 180, $boxheight=false, $framed=false ) {
1924 global $wgStylePath, $wgLang;
1925 # $image = Title::makeTitle( Namespace::getImage(), $name );
1926 $url = $img->getURL();
1928 #$label = htmlspecialchars( $label );
1929 $alt = preg_replace( '/<[^>]*>/', '', $label);
1930 $alt = htmlspecialchars( $alt );
1932 if ( $img->exists() )
1934 $width = $img->getWidth();
1935 $height = $img->getHeight();
1937 $width = $height = 200;
1941 // Use image dimensions, don't scale
1943 $oboxwidth = $boxwidth +
2;
1944 $boxheight = $height;
1947 $h = intval( $height/($width/$boxwidth) );
1948 $oboxwidth = $boxwidth +
2;
1949 if ( ( ! $boxheight === false ) && ( $h > $boxheight ) )
1951 $boxwidth *= $boxheight/$h;
1955 $thumbUrl = $img->createThumb( $boxwidth );
1958 $u = $img->getEscapeLocalURL();
1960 $more = htmlspecialchars( wfMsg( 'thumbnail-more' ) );
1961 $magnifyalign = $wgLang->isRTL() ?
'left' : 'right';
1962 $textalign = $wgLang->isRTL() ?
' style="text-align:right"' : '';
1964 $s = "<div class=\"thumb t{$align}\"><div style=\"width:{$oboxwidth}px;\">";
1965 if ( $thumbUrl == '' ) {
1966 $s .= str_replace( "$1", $img->getName(), wfMsg('missingimage') );
1969 $s .= '<a href="'.$u.'" class="internal" title="'.$alt.'">'.
1970 '<img src="'.$thumbUrl.'" alt="'.$alt.'" ' .
1971 'width="'.$boxwidth.'" height="'.$boxheight.'" /></a>';
1975 $zoomicon = '<div class="magnify" style="float:'.$magnifyalign.'">'.
1976 '<a href="'.$u.'" class="internal" title="'.$more.'">'.
1977 '<img src="'.$wgStylePath.'/images/magnify-clip.png" ' .
1978 'width="15" height="11" alt="'.$more.'" /></a></div>';
1981 $s .= ' <div class="thumbcaption" '.$textalign.'>'.$zoomicon.$label."</div></div></div>";
1982 return str_replace("\n", ' ', $s);
1985 function makeMediaLink( $name, $url, $alt = "" ) {
1986 $nt = Title
::makeTitle( Namespace::getMedia(), $name );
1987 return $this->makeMediaLinkObj( $nt, $alt );
1990 function makeMediaLinkObj( $nt, $alt = "" )
1992 if ( ! isset( $nt ) )
1994 ### HOTFIX. Instead of breaking, return empry string.
1997 $name = $nt->getDBKey();
1998 $url = Image
::wfImageUrl( $name );
1999 if ( empty( $alt ) ) {
2000 $alt = preg_replace( '/\.(.+?)^/', '', $name );
2003 $u = htmlspecialchars( $url );
2004 $s = "<a href=\"{$u}\" class='internal' title=\"{$alt}\">{$alt}</a>";
2009 function specialLink( $name, $key = "" )
2013 if ( '' == $key ) { $key = strtolower( $name ); }
2014 $pn = $wgLang->ucfirst( $name );
2015 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
2019 function makeExternalLink( $url, $text, $escape = true ) {
2020 $style = $this->getExternalLinkAttributes( $url, $text );
2021 $url = htmlspecialchars( $url );
2023 $text = htmlspecialchars( $text );
2025 return '<a href="'.$url.'"'.$style.'>'.$text.'</a>';
2028 # Called by history lists and recent changes
2031 # Returns text for the start of the tabular part of RC
2032 function beginRecentChangesList()
2034 $this->rc_cache
= array() ;
2035 $this->rcMoveIndex
= 0;
2036 $this->rcCacheIndex
= 0 ;
2037 $this->lastdate
= '';
2038 $this->rclistOpen
= false;
2042 function beginImageHistoryList()
2044 $s = "\n<h2>" . wfMsg( 'imghistory' ) . "</h2>\n" .
2045 "<p>" . wfMsg( 'imghistlegend' ) . "</p>\n".'<ul class="special">';
2049 # Returns text for the end of RC
2050 # If enhanced RC is in use, returns pretty much all the text
2051 function endRecentChangesList()
2053 $s = $this->recentChangesBlock() ;
2054 if( $this->rclistOpen
) {
2060 # Enhanced RC ungrouped line
2061 function recentChangesBlockLine ( $rcObj )
2063 global $wgStylePath, $wgLang ;
2065 # Get rc_xxxx variables
2066 extract( $rcObj->mAttribs
) ;
2067 $curIdEq = 'curid='.$rc_cur_id;
2072 $r .= '<img src="'.$wgStylePath.'/images/Arr_.png" width="12" height="12" border="0" />' ;
2075 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2076 $r .= ' ';
2078 # M & N (minor & new)
2079 $M = wfMsg( 'minoreditletter' );
2080 $N = wfMsg( 'newpageletter' );
2082 if ( $rc_type == RC_NEW
) {
2095 $r .= ' '.$rcObj->timestamp
.' ' ;
2099 $link = $rcObj->link
;
2100 if ( $rcObj->watched
) $link = '<strong>'.$link.'</strong>' ;
2105 $r .= $rcObj->difflink
;
2109 $r .= $this->makeKnownLinkObj( $rcObj->getTitle(), wfMsg( 'hist' ), $curIdEq.'&action=history' );
2112 $r .= ') . . '.$rcObj->userlink
;
2113 $r .= $rcObj->usertalklink
;
2116 if ( $rc_comment != '' && $rc_type != RC_MOVE
&& $rc_type != RC_MOVE_OVER_REDIRECT
) {
2117 $rc_comment=$this->formatComment($rc_comment);
2118 $r .= $wgLang->emphasize( ' ('.$rc_comment.')' );
2126 function recentChangesBlockGroup ( $block )
2128 global $wgStylePath, $wgLang ;
2131 $M = wfMsg( 'minoreditletter' );
2132 $N = wfMsg( 'newpageletter' );
2134 # Collate list of users
2136 $userlinks = array () ;
2137 foreach ( $block AS $rcObj ) {
2138 $oldid = $rcObj->mAttribs
['rc_last_oldid'];
2139 if ( $rcObj->mAttribs
['rc_new'] ) $isnew = true ;
2140 $u = $rcObj->userlink
;
2141 if ( !isset ( $userlinks[$u] ) ) $userlinks[$u] = 0 ;
2145 # Sort the list and convert to text
2146 krsort ( $userlinks ) ;
2147 asort ( $userlinks ) ;
2149 foreach ( $userlinks as $userlink => $count) {
2151 if ( $count > 1 ) $text .= " ({$count}×)" ;
2152 array_push ( $users , $text ) ;
2154 $users = ' <font size="-1">['.implode('; ',$users).']</font>' ;
2157 $rci = 'RCI'.$this->rcCacheIndex
;
2158 $rcl = 'RCL'.$this->rcCacheIndex
;
2159 $rcm = 'RCM'.$this->rcCacheIndex
;
2160 $toggleLink = "javascript:toggleVisibility('$rci','$rcm','$rcl')" ;
2161 $arrowdir = $wgLang->isRTL() ?
'l' : 'r';
2162 $tl = '<span id="'.$rcm.'"><a href="'.$toggleLink.'"><img src="'.$wgStylePath.'/images/Arr_'.$arrowdir.'.png" width="12" height="12" /></a></span>' ;
2163 $tl .= '<span id="'.$rcl.'" style="display:none"><a href="'.$toggleLink.'"><img src="'.$wgStylePath.'/images/Arr_d.png" width="12" height="12" /></a></span>' ;
2169 if ( $isnew ) $r .= $N ;
2170 else $r .= ' ' ;
2171 $r .= ' ' ; # Minor
2174 $r .= ' '.$block[0]->timestamp
.' ' ;
2178 $link = $block[0]->link
;
2179 if ( $block[0]->watched
) $link = '<strong>'.$link.'</strong>' ;
2182 $curIdEq = 'curid=' . $block[0]->mAttribs
['rc_cur_id'];
2183 if ( $block[0]->mAttribs
['rc_type'] != RC_LOG
) {
2185 $r .= ' ('.count($block).' ' ;
2186 if ( $isnew ) $r .= wfMsg('changes');
2187 else $r .= $this->makeKnownLinkObj( $block[0]->getTitle() , wfMsg('changes') ,
2188 $curIdEq.'&diff=0&oldid='.$oldid ) ;
2192 $r .= $this->makeKnownLinkObj( $block[0]->getTitle(), wfMsg( 'history' ), $curIdEq.'&action=history' );
2200 $r .= '<div id="'.$rci.'" style="display:none">' ;
2201 foreach ( $block AS $rcObj ) {
2202 # Get rc_xxxx variables
2203 extract( $rcObj->mAttribs
);
2205 $r .= '<img src="'.$wgStylePath.'/images/Arr_.png" width="12" height="12" />';
2206 $r .= '<tt> ' ;
2207 if ( $rc_new ) $r .= $N ;
2208 else $r .= ' ' ;
2209 if ( $rc_minor ) $r .= $M ;
2210 else $r .= ' ' ;
2214 if ( $rc_last_oldid != 0 ) {
2215 $o = 'oldid='.$rc_last_oldid ;
2217 if ( $rc_type == RC_LOG
) {
2218 $link = $rcObj->timestamp
;
2220 $link = $this->makeKnownLinkObj( $rcObj->getTitle(), $rcObj->timestamp
, "{$curIdEq}&$o" ) ;
2222 $link = '<tt>'.$link.'</tt>' ;
2226 $r .= $rcObj->curlink
;
2228 $r .= $rcObj->lastlink
;
2229 $r .= ') . . '.$rcObj->userlink
;
2230 $r .= $rcObj->usertalklink
;
2231 if ( $rc_comment != '' ) {
2232 $rc_comment=$this->formatComment($rc_comment);
2233 $r .= $wgLang->emphasize( ' ('.$rc_comment.')' ) ;
2239 $this->rcCacheIndex++
;
2243 # If enhanced RC is in use, this function takes the previously cached
2244 # RC lines, arranges them, and outputs the HTML
2245 function recentChangesBlock ()
2247 global $wgStylePath ;
2248 if ( count ( $this->rc_cache
) == 0 ) return '' ;
2250 foreach ( $this->rc_cache
AS $secureName => $block ) {
2251 if ( count ( $block ) < 2 ) {
2252 $blockOut .= $this->recentChangesBlockLine ( array_shift ( $block ) ) ;
2254 $blockOut .= $this->recentChangesBlockGroup ( $block ) ;
2258 return '<div>'.$blockOut.'</div>' ;
2261 # Called in a loop over all displayed RC entries
2262 # Either returns the line, or caches it for later use
2263 function recentChangesLine( &$rc, $watched = false )
2266 $usenew = $wgUser->getOption( 'usenewrc' );
2268 $line = $this->recentChangesLineNew ( $rc, $watched ) ;
2270 $line = $this->recentChangesLineOld ( $rc, $watched ) ;
2274 function recentChangesLineOld( &$rc, $watched = false )
2276 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds;
2278 # Extract DB fields into local scope
2279 extract( $rc->mAttribs
);
2280 $curIdEq = 'curid=' . $rc_cur_id;
2282 # Make date header if necessary
2283 $date = $wgLang->date( $rc_timestamp, true);
2285 if ( $date != $this->lastdate
) {
2286 if ( '' != $this->lastdate
) { $s .= "</ul>\n"; }
2287 $s .= "<h4>{$date}</h4>\n<ul class='special'>";
2288 $this->lastdate
= $date;
2289 $this->rclistOpen
= true;
2293 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2295 $s .= '(' . wfMsg( 'diff' ) . ') (';
2297 $s .= $this->makeKnownLinkObj( $rc->getMovedToTitle(), wfMsg( 'hist' ), 'action=history' ) .
2300 # "[[x]] moved to [[y]]"
2301 if ( $rc_type == RC_MOVE
) {
2304 $msg = '1movedto2_redir';
2306 $s .= wfMsg( $msg, $this->makeKnownLinkObj( $rc->getTitle(), '', 'redirect=no' ),
2307 $this->makeKnownLinkObj( $rc->getMovedToTitle(), '' ) );
2310 if ( $rc_type == RC_NEW ||
$rc_type == RC_LOG
) {
2311 $diffLink = wfMsg( 'diff' );
2313 $diffLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'diff' ),
2314 $curIdEq.'&diff='.$rc_this_oldid.'&oldid='.$rc_last_oldid ,'' ,'' , ' tabindex="'.$rc->counter
.'"');
2316 $s .= '('.$diffLink.') (';
2319 $s .= $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'hist' ), $curIdEq.'&action=history' );
2322 # M and N (minor and new)
2323 $M = wfMsg( 'minoreditletter' );
2324 $N = wfMsg( 'newpageletter' );
2325 if ( $rc_minor ) { $s .= ' <strong>'.$M.'</strong>'; }
2326 if ( $rc_type == RC_NEW
) { $s .= '<strong>'.$N.'</strong>'; }
2329 $articleLink = $this->makeKnownLinkObj( $rc->getTitle(), '' );
2332 $articleLink = '<strong>'.$articleLink.'</strong>';
2334 $s .= ' '.$articleLink;
2339 $s .= '; ' . $wgLang->time( $rc_timestamp, true, $wgRCSeconds ) . ' . . ';
2341 # User link (or contributions for unregistered users)
2342 if ( 0 == $rc_user ) {
2343 $userLink = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
2344 $rc_user_text, 'target=' . $rc_user_text );
2346 $userLink = $this->makeLink( $wgLang->getNsText( NS_USER
) . ':'.$rc_user_text, $rc_user_text );
2351 $talkname=$wgLang->getNsText(NS_TALK
); # use the shorter name
2352 global $wgDisableAnonTalk;
2353 if( 0 == $rc_user && $wgDisableAnonTalk ) {
2356 $utns=$wgLang->getNsText(NS_USER_TALK
);
2357 $userTalkLink= $this->makeLink($utns . ':'.$rc_user_text, $talkname );
2361 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2362 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2363 'Blockip' ), wfMsg( 'blocklink' ), 'ip='.$rc_user_text );
2367 if($userTalkLink) $userTalkLink .= ' | ';
2368 $userTalkLink .= $blockLink;
2370 if($userTalkLink) $s.=' ('.$userTalkLink.')';
2373 if ( '' != $rc_comment && '*' != $rc_comment && $rc_type != RC_MOVE
&& $rc_type != RC_MOVE_OVER_REDIRECT
) {
2374 $rc_comment=$this->formatComment($rc_comment);
2375 $s .= $wgLang->emphasize(' (' . $rc_comment . ')');
2382 # function recentChangesLineNew( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched = false, $oldid = 0 , $diffid = 0 )
2383 function recentChangesLineNew( &$baseRC, $watched = false )
2385 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds;
2387 # Create a specialised object
2388 $rc = RCCacheEntry
::newFromParent( $baseRC ) ;
2390 # Extract fields from DB into the function scope (rc_xxxx variables)
2391 extract( $rc->mAttribs
);
2392 $curIdEq = 'curid=' . $rc_cur_id;
2394 # If it's a new day, add the headline and flush the cache
2395 $date = $wgLang->date( $rc_timestamp, true);
2397 if ( $date != $this->lastdate
) {
2398 # Process current cache
2399 $ret = $this->recentChangesBlock () ;
2400 $this->rc_cache
= array() ;
2401 $ret .= "<h4>{$date}</h4>\n";
2402 $this->lastdate
= $date;
2406 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2407 if ( $rc_type == RC_MOVE
) {
2410 $msg = "1movedto2_redir";
2412 $clink = wfMsg( $msg, $this->makeKnownLinkObj( $rc->getTitle(), '', 'redirect=no' ),
2413 $this->makeKnownLinkObj( $rc->getMovedToTitle(), '' ) );
2415 $clink = $this->makeKnownLinkObj( $rc->getTitle(), '' ) ;
2418 $time = $wgLang->time( $rc_timestamp, true, $wgRCSeconds );
2419 $rc->watched
= $watched ;
2420 $rc->link
= $clink ;
2421 $rc->timestamp
= $time;
2423 # Make "cur" and "diff" links
2424 if ( ( $rc_type == RC_NEW
&& $rc_this_oldid == 0 ) ||
$rc_type == RC_LOG ||
$rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2425 $curLink = wfMsg( 'cur' );
2426 $diffLink = wfMsg( 'diff' );
2428 $query = $curIdEq.'&diff=0&oldid='.$rc_this_oldid;
2429 $aprops = ' tabindex="'.$baseRC->counter
.'"';
2430 $curLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'cur' ), $query, '' ,'' , $aprops );
2431 $diffLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'diff'), $query, '' ,'' , $aprops );
2435 $titleObj = $rc->getTitle();
2436 if ( $rc_last_oldid == 0 ||
$rc_type == RC_LOG ||
$rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2437 $lastLink = wfMsg( 'last' );
2439 $lastLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'last' ),
2440 $curIdEq.'&diff='.$rc_this_oldid.'&oldid='.$rc_last_oldid );
2443 # Make user link (or user contributions for unregistered users)
2444 if ( 0 == $rc_user ) {
2445 $userLink = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
2446 $rc_user_text, 'target=' . $rc_user_text );
2448 $userLink = $this->makeLink( $wgLang->getNsText(
2449 Namespace::getUser() ) . ':'.$rc_user_text, $rc_user_text );
2452 $rc->userlink
= $userLink ;
2453 $rc->lastlink
= $lastLink ;
2454 $rc->curlink
= $curLink ;
2455 $rc->difflink
= $diffLink;
2458 # Make user talk link
2459 $utns=$wgLang->getNsText(NS_USER_TALK
);
2460 $talkname=$wgLang->getNsText(NS_TALK
); # use the shorter name
2461 $userTalkLink= $this->makeLink($utns . ':'.$rc_user_text, $talkname );
2463 global $wgDisableAnonTalk;
2464 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2465 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2466 'Blockip' ), wfMsg( 'blocklink' ), 'ip='.$rc_user_text );
2467 if( $wgDisableAnonTalk )
2468 $rc->usertalklink
= ' ('.$blockLink.')';
2470 $rc->usertalklink
= ' ('.$userTalkLink.' | '.$blockLink.')';
2472 if( $wgDisableAnonTalk && ($rc_user == 0) )
2473 $rc->usertalklink
= '';
2475 $rc->usertalklink
= ' ('.$userTalkLink.')';
2478 # Put accumulated information into the cache, for later display
2479 # Page moves go on their own line
2480 $title = $rc->getTitle();
2481 $secureName = $title->getPrefixedDBkey();
2482 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2483 # Use an @ character to prevent collision with page names
2484 $this->rc_cache
['@@' . ($this->rcMoveIndex++
)] = array($rc);
2486 if ( !isset ( $this->rc_cache
[$secureName] ) ) $this->rc_cache
[$secureName] = array() ;
2487 array_push ( $this->rc_cache
[$secureName] , $rc ) ;
2492 function endImageHistoryList()
2498 /* This function is called by all recent changes variants, by the page history,
2499 and by the user contributions list. It is responsible for formatting edit
2500 comments. It escapes any HTML in the comment, but adds some CSS to format
2501 auto-generated comments (from section editing) and formats [[wikilinks]].
2502 Main author: Erik Möller (moeller@scireview.de)
2504 function formatComment($comment)
2507 $comment=wfEscapeHTML($comment);
2509 # The pattern for autogen comments is / * foo * /, which makes for
2511 # We look for all comments, match any text before and after the comment,
2512 # add a separator where needed and format the comment itself with CSS
2513 while (preg_match('/(.*)\/\*\s*(.*?)\s*\*\/(.*)/', $comment,$match)) {
2518 if($pre) { $auto = $sep.' '.$auto; }
2519 if($post) { $auto .= ' '.$sep; }
2520 $auto='<span class="autocomment">'.$auto.'</span>';
2521 $comment=$pre.$auto.$post;
2524 # format regular and media links - all other wiki formatting
2526 while(preg_match('/\[\[(.*?)(\|(.*?))*\]\]/',$comment,$match)) {
2528 $medians = $wgLang->getNsText(Namespace::getMedia()).':';
2530 if(preg_match('/^'.$medians.'/i',$match[1])) {
2531 $func='makeMediaLink';
2533 # Handle link renaming [[foo|text]] will show link as "text"
2534 if(isset($match[3]) ) {
2536 preg_replace('/\[\[(.*?)\]\]/',
2537 $this->$func($match[1],$match[3]),$comment,1);
2540 preg_replace('/\[\[(.*?)\]\]/',
2541 $this->$func($match[1],$match[1]),$comment,1);
2549 function imageHistoryLine( $iscur, $timestamp, $img, $user, $usertext, $size, $description )
2551 global $wgUser, $wgLang, $wgTitle;
2553 $datetime = $wgLang->timeanddate( $timestamp, true );
2554 $del = wfMsg( 'deleteimg' );
2555 $cur = wfMsg( 'cur' );
2558 $url = Image
::wfImageUrl( $img );
2560 if ( $wgUser->isSysop() ) {
2561 $link = $wgTitle->escapeLocalURL( 'image=' . $wgTitle->getPartialURL() .
2563 $style = $this->getInternalLinkAttributes( $link, $del );
2565 $dlink = '<a href="'.$link.'"'.$style.'>'.$del.'</a>';
2570 $url = wfEscapeHTML( wfImageArchiveUrl( $img ) );
2571 if( $wgUser->getID() != 0 ) {
2572 $rlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2573 wfMsg( 'revertimg' ), 'action=revert&oldimage=' .
2574 urlencode( $img ) );
2575 $dlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2576 $del, 'action=delete&oldimage=' . urlencode( $img ) );
2578 # Having live active links for non-logged in users
2579 # means that bots and spiders crawling our site can
2580 # inadvertently change content. Baaaad idea.
2581 $rlink = wfMsg( 'revertimg' );
2586 $userlink = $usertext;
2588 $userlink = $this->makeLink( $wgLang->getNsText( Namespace::getUser() ) .
2589 ':'.$usertext, $usertext );
2591 $nbytes = wfMsg( 'nbytes', $size );
2592 $style = $this->getInternalLinkAttributes( $url, $datetime );
2594 $s = "<li> ({$dlink}) ({$rlink}) <a href=\"{$url}\"{$style}>{$datetime}</a>"
2595 . " . . {$userlink} ({$nbytes})";
2597 if ( '' != $description && '*' != $description ) {
2598 $sk=$wgUser->getSkin();
2599 $s .= $wgLang->emphasize(' (' . $sk->formatComment($description) . ')');
2605 function tocIndent($level) {
2606 return str_repeat( '<div class="tocindent">'."\n", $level>0 ?
$level : 0 );
2609 function tocUnindent($level) {
2610 return str_repeat( "</div>\n", $level>0 ?
$level : 0 );
2613 # parameter level defines if we are on an indentation level
2614 function tocLine( $anchor, $tocline, $level ) {
2615 $link = '<a href="#'.$anchor.'">'.$tocline.'</a><br />';
2619 return '<div class="tocline">'.$link."</div>\n";
2624 function tocTable($toc) {
2625 # note to CSS fanatics: putting this in a div does not work -- div won't auto-expand
2626 # try min-width & co when somebody gets a chance
2627 $hideline = ' <script type="text/javascript">showTocToggle("' . addslashes( wfMsg('showtoc') ) . '","' . addslashes( wfMsg('hidetoc') ) . '")</script>';
2629 '<table border="0" id="toc"><tr id="toctitle"><td align="center">'."\n".
2630 '<b>'.wfMsg('toc').'</b>' .
2632 '</td></tr><tr id="tocinside"><td>'."\n".
2633 $toc."</td></tr></table>\n";
2636 # These two do not check for permissions: check $wgTitle->userCanEdit before calling them
2637 function editSectionScript( $section, $head ) {
2638 global $wgTitle, $wgRequest;
2639 if( $wgRequest->getInt( 'oldid' ) && ( $wgRequest->getVal( 'diff' ) != '0' ) ) {
2642 $url = $wgTitle->escapeLocalURL( 'action=edit§ion='.$section );
2643 return '<span oncontextmenu=\'document.location="'.$url.'";return false;\'>'.$head.'</span>';
2646 function editSectionLink( $section ) {
2648 global $wgTitle, $wgUser, $wgLang;
2650 if( $wgRequest->getInt( 'oldid' ) && ( $wgRequest->getVal( 'diff' ) != '0' ) ) {
2651 # Section edit links would be out of sync on an old page.
2652 # But, if we're diffing to the current page, they'll be
2657 $editurl = '§ion='.$section;
2658 $url = $this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg('editsection'),'action=edit'.$editurl);
2660 if( $wgLang->isRTL() ) {
2662 $nearside = 'right';
2667 return "<div class=\"editsection\" style=\"float:$farside;margin-$nearside:5px;\">[".$url."]</div>";
2671 // This function is called by EditPage.php and shows a bulletin board style
2672 // toolbar for common editing functions. It can be disabled in the user preferences.
2673 // The necsesary JavaScript code can be found in style/wikibits.js.
2674 function getEditToolbar() {
2675 global $wgStylePath, $wgLang, $wgMimeType;
2677 // toolarray an array of arrays which each include the filename of
2678 // the button image (without path), the opening tag, the closing tag,
2679 // and optionally a sample text that is inserted between the two when no
2680 // selection is highlighted.
2681 // The tip text is shown when the user moves the mouse over the button.
2683 // Already here are accesskeys (key), which are not used yet until someone
2684 // can figure out a way to make them work in IE. However, we should make
2685 // sure these keys are not defined on the edit page.
2687 array( 'image'=>'button_bold.png',
2690 'sample'=>wfMsg('bold_sample'),
2691 'tip'=>wfMsg('bold_tip'),
2694 array( "image"=>"button_italic.png",
2697 "sample"=>wfMsg("italic_sample"),
2698 "tip"=>wfMsg("italic_tip"),
2701 array( "image"=>"button_link.png",
2704 "sample"=>wfMsg("link_sample"),
2705 "tip"=>wfMsg("link_tip"),
2708 array( "image"=>"button_extlink.png",
2711 "sample"=>wfMsg("extlink_sample"),
2712 "tip"=>wfMsg("extlink_tip"),
2715 array( "image"=>"button_headline.png",
2718 "sample"=>wfMsg("headline_sample"),
2719 "tip"=>wfMsg("headline_tip"),
2722 array( "image"=>"button_image.png",
2723 "open"=>"[[".$wgLang->getNsText(NS_IMAGE
).":",
2725 "sample"=>wfMsg("image_sample"),
2726 "tip"=>wfMsg("image_tip"),
2729 array( "image"=>"button_media.png",
2730 "open"=>"[[".$wgLang->getNsText(NS_MEDIA
).":",
2732 "sample"=>wfMsg("media_sample"),
2733 "tip"=>wfMsg("media_tip"),
2736 array( "image"=>"button_math.png",
2737 "open"=>"\\<math\\>",
2738 "close"=>"\\</math\\>",
2739 "sample"=>wfMsg("math_sample"),
2740 "tip"=>wfMsg("math_tip"),
2743 array( "image"=>"button_nowiki.png",
2744 "open"=>"\\<nowiki\\>",
2745 "close"=>"\\</nowiki\\>",
2746 "sample"=>wfMsg("nowiki_sample"),
2747 "tip"=>wfMsg("nowiki_tip"),
2750 array( "image"=>"button_sig.png",
2754 "tip"=>wfMsg("sig_tip"),
2757 array( "image"=>"button_hr.png",
2758 "open"=>"\\n----\\n",
2761 "tip"=>wfMsg("hr_tip"),
2765 $toolbar ="<script type='text/javascript'>\n/*<![CDATA[*/\n";
2767 $toolbar.="document.writeln(\"<div id='toolbar'>\");\n";
2768 foreach($toolarray as $tool) {
2770 $image=$wgStylePath.'/images/'.$tool['image'];
2771 $open=$tool['open'];
2772 $close=$tool['close'];
2773 $sample = addslashes( $tool['sample'] );
2775 // Note that we use the tip both for the ALT tag and the TITLE tag of the image.
2776 // Older browsers show a "speedtip" type message only for ALT.
2777 // Ideally these should be different, realistically they
2778 // probably don't need to be.
2779 $tip = addslashes( $tool['tip'] );
2781 #$key = $tool["key"];
2783 $toolbar.="addButton('$image','$tip','$open','$close','$sample');\n";
2786 $toolbar.="addInfobox('" . addslashes( wfMsg( "infobox" ) ) . "','" . addslashes(wfMsg("infobox_alert")) . "');\n";
2787 $toolbar.="document.writeln(\"</div>\");\n";
2789 $toolbar.="/*]]>*/\n</script>";