3 require_once( 'Feed.php' );
4 require_once( 'Image.php' );
8 # These are the INTERNAL names, which get mapped
9 # directly to class names. For display purposes, the
10 # Language class has internationalized names
12 /* private */ $wgValidSkinNames = array(
13 'standard' => 'Standard',
14 'nostalgia' => 'Nostalgia',
15 'cologneblue' => 'CologneBlue'
18 #$wgValidSkinNames[] = 'PHPTal';
19 #$wgValidSkinNames['davinci'] = 'DaVinci';
20 #$wgValidSkinNames['mono'] = 'Mono';
21 $wgValidSkinNames['monobook'] = 'MonoBook';
22 $wgValidSkinNames['myskin'] = 'MySkin';
23 #$wgValidSkinNames['monobookminimal'] = 'MonoBookMinimal';
26 require_once( 'RecentChange.php' );
28 class RCCacheEntry
extends RecentChange
30 var $secureName, $link;
31 var $curlink , $lastlink , $usertalklink , $versionlink ;
32 var $userlink, $timestamp, $watched;
34 function newFromParent( $rc )
36 $rc2 = new RCCacheEntry
;
37 $rc2->mAttribs
= $rc->mAttribs
;
38 $rc2->mExtra
= $rc->mExtra
;
45 /* private */ var $lastdate, $lastline;
46 var $linktrail ; # linktrail regexp
47 var $rc_cache ; # Cache for Enhanced Recent Changes
48 var $rcCacheIndex ; # Recent Changes Cache Counter for visibility toggle
53 $this->linktrail
= wfMsg('linktrail');
56 function getSkinNames()
58 global $wgValidSkinNames;
59 return $wgValidSkinNames;
62 function getStylesheet()
64 return 'wikistandard.css';
66 function getSkinName() {
72 global $wgOut, $wgUser;
74 if ( $wgOut->isQuickbarSuppressed() ) { return 0; }
75 $q = $wgUser->getOption( 'quickbar' );
76 if ( '' == $q ) { $q = 0; }
80 function initPage( &$out )
82 $fname = 'Skin::initPage';
83 wfProfileIn( $fname );
85 $out->addLink( array( 'rel' => 'shortcut icon', 'href' => '/favicon.ico' ) );
87 $this->addMetadataLinks($out);
89 wfProfileOut( $fname );
92 function addMetadataLinks( &$out ) {
93 global $wgTitle, $wgEnableDublinCoreRdf, $wgEnableCreativeCommonsRdf, $wgRdfMimeType, $action;
94 global $wgRightsPage, $wgRightsUrl;
96 if( $out->isArticleRelated() ) {
97 # note: buggy CC software only reads first "meta" link
98 if( $wgEnableCreativeCommonsRdf ) {
99 $out->addMetadataLink( array(
100 'title' => 'Creative Commons',
101 'type' => 'application/rdf+xml',
102 'href' => $wgTitle->getLocalURL( 'action=creativecommons') ) );
104 if( $wgEnableDublinCoreRdf ) {
105 $out->addMetadataLink( array(
106 'title' => 'Dublin Core',
107 'type' => 'application/rdf+xml',
108 'href' => $wgTitle->getLocalURL( 'action=dublincore' ) ) );
112 if( $wgRightsPage ) {
113 $copy = Title
::newFromText( $wgRightsPage );
115 $copyright = $copy->getLocalURL();
118 if( !$copyright && $wgRightsUrl ) {
119 $copyright = $wgRightsUrl;
122 $out->addLink( array(
123 'rel' => 'copyright',
124 'href' => $copyright ) );
128 function outputPage( &$out ) {
129 global $wgDebugComments;
131 wfProfileIn( 'Skin::outputPage' );
132 $this->initPage( $out );
133 $out->out( $out->headElement() );
135 $out->out( "\n<body" );
136 $ops = $this->getBodyOptions();
137 foreach ( $ops as $name => $val ) {
138 $out->out( " $name='$val'" );
141 if ( $wgDebugComments ) {
142 $out->out( "<!-- Wiki debugging output:\n" .
143 $out->mDebugtext
. "-->\n" );
145 $out->out( $this->beforeContent() );
147 $out->out( $out->mBodytext
. "\n" );
149 $out->out( $this->afterContent() );
152 $out->out( $out->reportTime() );
154 $out->out( "\n</body></html>" );
157 function getHeadScripts() {
158 global $wgStylePath, $wgUser, $wgLang;
159 $r = "<script type=\"text/javascript\" src=\"{$wgStylePath}/wikibits.js\"></script>\n";
160 if( $wgUser->getID() != 0 ) { # logged in
161 $userpage = $wgLang->getNsText( Namespace::getUser() ) . ":" . $wgUser->getName();
162 $userjs = htmlspecialchars($this->makeUrl($userpage.'/'.$this->getSkinName().'.js', 'action=raw&ctype=text/javascript'));
163 $r .= '<script type="text/javascript" src="'.$userjs."\"></script>\n";
168 # get the user/site-specific stylesheet, SkinPHPTal called from RawPage.php (settings are cached that way)
169 function getUserStylesheet() {
170 global $wgOut, $wgStylePath, $wgLang, $wgUser, $wgRequest, $wgTitle;
171 $sheet = $this->getStylesheet();
172 $action = $wgRequest->getText('action');
173 $s = "@import url(\"$wgStylePath/$sheet\");\n";
174 if($wgLang->isRTL()) $s .= "@import url(\"$wgStylePath/common_rtl.css\");\n";
175 if( $wgUser->getID() != 0 ) { # logged in
176 if($wgTitle->isCssSubpage() and $action == 'submit' and $wgTitle->userCanEditCssJsSubpage()) {
177 $s .= '@import url('.$this->makeUrl('-','action=raw&gen=css&smaxage=0&maxage=0').');'."\n";
178 $s .= $wgRequest->getText('wpTextbox1');
180 $s .= '@import url('.$this->makeUrl('-','action=raw&gen=css&smaxage=0&maxage=0').');'."\n";
181 $userpage = $wgLang->getNsText( Namespace::getUser() ) . ":" . $wgUser->getName();
182 $s.= '@import url("'.$this->makeUrl($userpage.'/'.$this->getSkinName(), 'action=raw&ctype=text/css').'");'."\n";
185 $s .= $this->doGetUserStyles();
188 # placeholder, returns generated js in monobook
189 function getUserJs() {
193 function getUserStyles()
195 global $wgOut, $wgStylePath, $wgLang;
196 $s = "<style type='text/css'>\n";
197 $s .= "/*/*/\n"; # <-- Hide the styles from Netscape 4 without hiding them from IE/Mac
198 $s .= $this->getUserStylesheet();
204 function doGetUserStyles()
209 if ( 1 == $wgUser->getOption( 'underline' ) ) {
210 # Don't override browser settings
215 "text-decoration: none; }\n";
217 if ( 1 == $wgUser->getOption( 'highlightbroken' ) ) {
218 $s .= "a.new, #quickbar a.new { color: #CC2200; }\n";
220 if ( 1 == $wgUser->getOption( 'justify' ) ) {
221 $s .= "#article { text-align: justify; }\n";
226 function getBodyOptions()
228 global $wgUser, $wgTitle, $wgNamespaceBackgrounds, $wgOut, $wgRequest;
230 extract( $wgRequest->getValues( 'oldid', 'redirect', 'diff' ) );
232 if ( 0 != $wgTitle->getNamespace() ) {
233 $a = array( 'bgcolor' => '#ffffec' );
235 else $a = array( 'bgcolor' => '#FFFFFF' );
236 if($wgOut->isArticle() && $wgUser->getOption('editondblclick') &&
237 (!$wgTitle->isProtected() ||
$wgUser->isSysop()) ) {
238 $t = wfMsg( 'editthispage' );
240 if ( !empty($redirect) ) {
241 $red = "&redirect={$redirect}";
243 if ( !empty($oldid) && ! isset( $diff ) ) {
244 $oid = "&oldid={$oldid}";
246 $s = $wgTitle->getFullURL( "action=edit{$oid}{$red}" );
247 $s = 'document.location = "' .$s .'";';
248 $a +
= array ('ondblclick' => $s);
251 $a['onload'] = $wgOut->getOnloadHandler();
255 function getExternalLinkAttributes( $link, $text, $class='' )
257 global $wgUser, $wgOut, $wgLang;
259 $link = urldecode( $link );
260 $link = $wgLang->checkTitleEncoding( $link );
261 $link = str_replace( '_', ' ', $link );
262 $link = wfEscapeHTML( $link );
264 $r = ($class != '') ?
" class='$class'" : " class='external'";
266 if ( 1 == $wgUser->getOption( 'hover' ) ) {
267 $r .= " title=\"{$link}\"";
272 function getInternalLinkAttributes( $link, $text, $broken = false )
274 global $wgUser, $wgOut;
276 $link = urldecode( $link );
277 $link = str_replace( '_', ' ', $link );
278 $link = wfEscapeHTML( $link );
280 if ( $broken == 'stub' ) {
281 $r = ' class="stub"';
282 } else if ( $broken == 'yes' ) {
288 if ( 1 == $wgUser->getOption( 'hover' ) ) {
289 $r .= " title=\"{$link}\"";
294 function getInternalLinkAttributesObj( &$nt, $text, $broken = false )
296 global $wgUser, $wgOut;
298 if ( $broken == 'stub' ) {
299 $r = ' class="stub"';
300 } else if ( $broken == 'yes' ) {
306 if ( 1 == $wgUser->getOption( 'hover' ) ) {
307 $r .= ' title ="' . $nt->getEscapedText() . '"';
318 # This will be called immediately after the <body> tag. Split into
319 # two functions to make it easier to subclass.
321 function beforeContent()
323 global $wgUser, $wgOut, $wgSiteNotice;
325 if( $wgSiteNotice ) {
326 $note = "\n<div id='siteNotice'>$wgSiteNotice</div>\n";
330 return $this->doBeforeContent() . $note;
333 function doBeforeContent()
335 global $wgUser, $wgOut, $wgTitle, $wgLang;
336 $fname = 'Skin::doBeforeContent';
337 wfProfileIn( $fname );
340 $qb = $this->qbSetting();
342 if( $langlinks = $this->otherLanguages() ) {
348 $borderhack = 'class="top"';
351 $s .= "\n<div id='content'>\n<div id='topbar'>\n" .
352 "<table border='0' cellspacing='0' width='98%'>\n<tr>\n";
355 $left = ($qb == 1 ||
$qb == 3);
356 if($wgLang->isRTL()) $left = !$left;
359 $s .= "<td class='top' align='left' valign='top' rowspan='{$rows}'>\n" .
360 $this->logoText() . '</td>';
362 $s .= $this->getQuickbarCompensator( $rows );
364 $l = $wgLang->isRTL() ?
'right' : 'left';
365 $s .= "<td {$borderhack} align='$l' valign='top'>\n";
367 $s .= $this->topLinks() ;
368 $s .= "<p class='subtitle'>" . $this->pageTitleLinks() . "</p>\n";
370 $r = $wgLang->isRTL() ?
"left" : "right";
371 $s .= "</td>\n<td {$borderhack} valign='top' align='$r' nowrap='nowrap'>";
372 $s .= $this->nameAndLogin();
373 $s .= "\n<br />" . $this->searchForm() . "</td>";
376 $s .= "</tr>\n<tr>\n<td class='top' colspan=\"2\">$langlinks</td>\n";
379 if ( $shove && !$left ) { # Right
380 $s .= $this->getQuickbarCompensator( $rows );
382 $s .= "</tr>\n</table>\n</div>\n";
383 $s .= "\n<div id='article'>\n";
385 $s .= $this->pageTitle();
386 $s .= $this->pageSubtitle() ;
387 $s .= $this->getCategories();
388 wfProfileOut( $fname );
392 function getCategoryLinks () {
393 global $wgOut, $wgTitle, $wgUser, $wgParser;
394 global $wgUseCategoryMagic, $wgUseCategoryBrowser, $wgLang;
395 if( !$wgUseCategoryMagic ) return '' ;
396 if( count( $wgOut->mCategoryLinks
) == 0 ) return '';
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;
877 if( $wgRightsPage ) {
878 $link = $this->makeKnownLink( $wgRightsPage, $wgRightsText );
879 } elseif( $wgRightsUrl ) {
880 $link = $this->makeExternalLink( $wgRightsUrl, $wgRightsText );
885 $out .= wfMsg( 'copyright', $link );
889 function getCopyrightIcon() {
890 global $wgRightsPage, $wgRightsUrl, $wgRightsText, $wgRightsIcon;
892 if( $wgRightsIcon ) {
893 $icon = htmlspecialchars( $wgRightsIcon );
895 $url = htmlspecialchars( $wgRightsUrl );
896 $out .= '<a href="'.$url.'">';
898 $text = htmlspecialchars( $wgRightsText );
899 $out .= "<img src=\"$icon\" alt='$text' />";
907 function getPoweredBy() {
909 $url = htmlspecialchars( "$wgStylePath/images/poweredby_mediawiki_88x31.png" );
910 $img = '<a href="http://www.mediawiki.org/"><img src="'.$url.'" alt="MediaWiki" /></a>';
914 function lastModified()
916 global $wgLang, $wgArticle;
918 $timestamp = $wgArticle->getTimestamp();
920 $d = $wgLang->timeanddate( $wgArticle->getTimestamp(), true );
921 $s = ' ' . wfMsg( 'lastmodified', $d );
928 function logoText( $align = '' )
930 if ( '' != $align ) { $a = ' align="'.$align.'"'; }
933 $mp = wfMsg( 'mainpage' );
934 $titleObj = Title
::newFromText( $mp );
935 $s = '<a href="' . $titleObj->escapeLocalURL()
936 . '"><img'.$a.' src="'
937 . $this->getLogo() . '" alt="' . "[{$mp}]\" /></a>";
943 global $wgOut, $wgTitle, $wgUser, $wgRequest, $wgLang;
944 global $wgDisableUploads, $wgRemoteUploads;
946 $fname = 'Skin::quickBar';
947 wfProfileIn( $fname );
949 $action = $wgRequest->getText( 'action' );
950 $wpPreview = $wgRequest->getBool( 'wpPreview' );
951 $tns=$wgTitle->getNamespace();
953 $s = "\n<div id='quickbar'>";
954 $s .= "\n" . $this->logoText() . "\n<hr class='sep' />";
957 $s .= $this->mainPageLink()
958 . $sep . $this->specialLink( 'recentchanges' )
959 . $sep . $this->specialLink( 'randompage' );
960 if ($wgUser->getID()) {
961 $s.= $sep . $this->specialLink( 'watchlist' ) ;
962 $s .= $sep .$this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
963 wfMsg( 'mycontris' ), 'target=' . wfUrlencode($wgUser->getName() ) );
966 // only show watchlist link if logged in
967 if ( wfMsg ( 'currentevents' ) != '-' ) $s .= $sep . $this->makeKnownLink( wfMsg( 'currentevents' ), '' ) ;
968 $s .= "\n<br /><hr class='sep' />";
969 $articleExists = $wgTitle->getArticleId();
970 if ( $wgOut->isArticle() ||
$action =='edit' ||
$action =='history' ||
$wpPreview) {
971 if($wgOut->isArticle()) {
972 $s .= '<strong>' . $this->editThisPage() . '</strong>';
973 } else { # backlink to the article in edit or history mode
974 if($articleExists){ # no backlink if no article
977 $text = wfMsg('articlepage');
980 $text = wfMsg('viewtalkpage');
983 $text = wfMsg('userpage');
986 $text = wfMsg('viewtalkpage');
989 $text = wfMsg('wikipediapage');
992 $text = wfMsg('viewtalkpage');
995 $text = wfMsg('imagepage');
998 $text = wfMsg('viewtalkpage');
1001 $text= wfMsg('articlepage');
1004 $link = $wgTitle->getText();
1005 if ($nstext = $wgLang->getNsText($tns) ) { # add namespace if necessary
1006 $link = $nstext . ':' . $link ;
1009 $s .= $this->makeLink( $link, $text );
1010 } elseif( $wgTitle->getNamespace() != Namespace::getSpecial() ) {
1011 # we just throw in a "New page" text to tell the user that he's in edit mode,
1012 # and to avoid messing with the separator that is prepended to the next item
1013 $s .= '<strong>' . wfMsg('newpage') . '</strong>';
1019 if( $tns%2
&& $action!='edit' && !$wpPreview) {
1020 $s.= '<br />'.$this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg('postcomment'),'action=edit§ion=new');
1024 watching could cause problems in edit mode:
1025 if user edits article, then loads "watch this article" in background and then saves
1026 article with "Watch this article" checkbox disabled, the article is transparently
1027 unwatched. Therefore we do not show the "Watch this page" link in edit mode
1029 if ( 0 != $wgUser->getID() && $articleExists) {
1030 if($action!='edit' && $action != 'submit' )
1032 $s .= $sep . $this->watchThisPage();
1034 if ( $wgTitle->userCanEdit() )
1035 $s .= $sep . $this->moveThisPage();
1037 if ( $wgUser->isSysop() and $articleExists ) {
1038 $s .= $sep . $this->deleteThisPage() .
1039 $sep . $this->protectThisPage();
1041 $s .= $sep . $this->talkLink();
1042 if ($articleExists && $action !='history') {
1043 $s .= $sep . $this->historyLink();
1045 $s.=$sep . $this->whatLinksHere();
1047 if($wgOut->isArticleRelated()) {
1048 $s .= $sep . $this->watchPageLinksLink();
1051 if ( Namespace::getUser() == $wgTitle->getNamespace()
1052 ||
$wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser())
1055 $id=User
::idFromName($wgTitle->getText());
1056 $ip=User
::isIP($wgTitle->getText());
1059 $s .= $sep . $this->userContribsLink();
1061 if ( 0 != $wgUser->getID() ) {
1062 if($id) { # can only email real users
1063 $s .= $sep . $this->emailUserLink();
1067 $s .= "\n<br /><hr class='sep' />";
1070 if ( 0 != $wgUser->getID() && ( !$wgDisableUploads ||
$wgRemoteUploads ) ) {
1071 $s .= $this->specialLink( 'upload' ) . $sep;
1073 $s .= $this->specialLink( 'specialpages' )
1074 . $sep . $this->bugReportsLink();
1076 global $wgSiteSupportPage;
1077 if( $wgSiteSupportPage ) {
1078 $s .= "\n<br /><a href=\"" . htmlspecialchars( $wgSiteSupportPage ) .
1079 '" class="internal">' . wfMsg( 'sitesupport' ) . '</a>';
1082 $s .= "\n<br /></div>\n";
1083 wfProfileOut( $fname );
1087 function specialPagesList()
1089 global $wgUser, $wgOut, $wgLang, $wgServer, $wgRedirectScript;
1091 $pages = SpecialPage
::getPages();
1093 foreach ( $pages[''] as $name => $page ) {
1094 $a[$name] = $page->getDescription();
1096 if ( $wgUser->isSysop() )
1098 foreach ( $pages['sysop'] as $name => $page ) {
1099 $a[$name] = $page->getDescription();
1102 if ( $wgUser->isDeveloper() )
1104 foreach ( $pages['developer'] as $name => $page ) {
1105 $a[$name] = $page->getDescription() ;
1108 $go = wfMsg( 'go' );
1109 $sp = wfMsg( 'specialpages' );
1110 $spp = $wgLang->specialPage( 'Specialpages' );
1112 $s = '<form id="specialpages" method="get" class="inline" ' .
1113 'action="' . htmlspecialchars( "{$wgServer}{$wgRedirectScript}" ) . "\">\n";
1114 $s .= "<select name=\"wpDropdown\">\n";
1115 $s .= "<option value=\"{$spp}\">{$sp}</option>\n";
1117 foreach ( $a as $name => $desc ) {
1118 $p = $wgLang->specialPage( $name );
1119 $s .= "<option value=\"{$p}\">{$desc}</option>\n";
1121 $s .= "</select>\n";
1122 $s .= "<input type='submit' value=\"{$go}\" name='redirect' />\n";
1127 function mainPageLink()
1129 $mp = wfMsg( 'mainpage' );
1130 $s = $this->makeKnownLink( $mp, $mp );
1134 function copyrightLink()
1136 $s = $this->makeKnownLink( wfMsg( 'copyrightpage' ),
1137 wfMsg( 'copyrightpagename' ) );
1141 function aboutLink()
1143 $s = $this->makeKnownLink( wfMsg( 'aboutpage' ),
1144 wfMsg( 'aboutwikipedia' ) );
1149 function disclaimerLink()
1151 $s = $this->makeKnownLink( wfMsg( 'disclaimerpage' ),
1152 wfMsg( 'disclaimers' ) );
1156 function editThisPage()
1158 global $wgOut, $wgTitle, $wgRequest;
1160 $oldid = $wgRequest->getVal( 'oldid' );
1161 $diff = $wgRequest->getVal( 'diff' );
1162 $redirect = $wgRequest->getVal( 'redirect' );
1164 if ( ! $wgOut->isArticleRelated() ) {
1165 $s = wfMsg( 'protectedpage' );
1167 $n = $wgTitle->getPrefixedText();
1168 if ( $wgTitle->userCanEdit() ) {
1169 $t = wfMsg( 'editthispage' );
1171 #$t = wfMsg( "protectedpage" );
1172 $t = wfMsg( 'viewsource' );
1176 if ( !is_null( $redirect ) ) { $red = "&redirect={$redirect}"; }
1177 if ( $oldid && ! isset( $diff ) ) {
1178 $oid = "&oldid={$oldid}";
1180 $s = $this->makeKnownLink( $n, $t, "action=edit{$oid}{$red}" );
1185 function deleteThisPage()
1187 global $wgUser, $wgOut, $wgTitle, $wgRequest;
1189 $diff = $wgRequest->getVal( 'diff' );
1190 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
1191 $n = $wgTitle->getPrefixedText();
1192 $t = wfMsg( 'deletethispage' );
1194 $s = $this->makeKnownLink( $n, $t, 'action=delete' );
1201 function protectThisPage()
1203 global $wgUser, $wgOut, $wgTitle, $wgRequest;
1205 $diff = $wgRequest->getVal( 'diff' );
1206 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
1207 $n = $wgTitle->getPrefixedText();
1209 if ( $wgTitle->isProtected() ) {
1210 $t = wfMsg( 'unprotectthispage' );
1211 $q = 'action=unprotect';
1213 $t = wfMsg( 'protectthispage' );
1214 $q = 'action=protect';
1216 $s = $this->makeKnownLink( $n, $t, $q );
1223 function watchThisPage()
1225 global $wgUser, $wgOut, $wgTitle;
1227 if ( $wgOut->isArticleRelated() ) {
1228 $n = $wgTitle->getPrefixedText();
1230 if ( $wgTitle->userIsWatching() ) {
1231 $t = wfMsg( 'unwatchthispage' );
1232 $q = 'action=unwatch';
1234 $t = wfMsg( 'watchthispage' );
1235 $q = 'action=watch';
1237 $s = $this->makeKnownLink( $n, $t, $q );
1239 $s = wfMsg( 'notanarticle' );
1244 function moveThisPage()
1246 global $wgTitle, $wgLang;
1248 if ( $wgTitle->userCanEdit() ) {
1249 $s = $this->makeKnownLink( $wgLang->specialPage( 'Movepage' ),
1250 wfMsg( 'movethispage' ), 'target=' . $wgTitle->getPrefixedURL() );
1251 } // no message if page is protected - would be redundant
1255 function historyLink()
1259 $s = $this->makeKnownLink( $wgTitle->getPrefixedText(),
1260 wfMsg( 'history' ), 'action=history' );
1264 function whatLinksHere()
1266 global $wgTitle, $wgLang;
1268 $s = $this->makeKnownLink( $wgLang->specialPage( 'Whatlinkshere' ),
1269 wfMsg( 'whatlinkshere' ), 'target=' . $wgTitle->getPrefixedURL() );
1273 function userContribsLink()
1275 global $wgTitle, $wgLang;
1277 $s = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
1278 wfMsg( 'contributions' ), 'target=' . $wgTitle->getPartialURL() );
1282 function emailUserLink()
1284 global $wgTitle, $wgLang;
1286 $s = $this->makeKnownLink( $wgLang->specialPage( 'Emailuser' ),
1287 wfMsg( 'emailuser' ), 'target=' . $wgTitle->getPartialURL() );
1291 function watchPageLinksLink()
1293 global $wgOut, $wgTitle, $wgLang;
1295 if ( ! $wgOut->isArticleRelated() ) {
1296 $s = '(' . wfMsg( 'notanarticle' ) . ')';
1298 $s = $this->makeKnownLink( $wgLang->specialPage(
1299 'Recentchangeslinked' ), wfMsg( 'recentchangeslinked' ),
1300 'target=' . $wgTitle->getPrefixedURL() );
1305 function otherLanguages()
1307 global $wgOut, $wgLang, $wgTitle, $wgUseNewInterlanguage;
1309 $a = $wgOut->getLanguageLinks();
1310 if ( 0 == count( $a ) ) {
1311 if ( !$wgUseNewInterlanguage ) return '';
1312 $ns = $wgLang->getNsIndex ( $wgTitle->getNamespace () ) ;
1313 if ( $ns != 0 AND $ns != 1 ) return '' ;
1315 $x = 'mode=addlink&xt='.$wgTitle->getDBkey() ;
1316 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1317 wfMsg( 'intl' ) , $x );
1320 if ( !$wgUseNewInterlanguage ) {
1321 $s = wfMsg( 'otherlanguages' ) . ': ';
1323 global $wgLanguageCode ;
1324 $x = 'mode=zoom&xt='.$wgTitle->getDBkey() ;
1325 $x .= '&xl='.$wgLanguageCode ;
1326 $s = $this->makeKnownLink( $wgLang->specialPage( 'Intl' ),
1327 wfMsg( 'otherlanguages' ) , $x ) . ': ' ;
1330 $s = wfMsg( 'otherlanguages' ) . ': ';
1332 if($wgLang->isRTL()) $s .= '<span dir="LTR">';
1333 foreach( $a as $l ) {
1334 if ( ! $first ) { $s .= ' | '; }
1337 $nt = Title
::newFromText( $l );
1338 $url = $nt->getFullURL();
1339 $text = $wgLang->getLanguageName( $nt->getInterwiki() );
1341 if ( '' == $text ) { $text = $l; }
1342 $style = $this->getExternalLinkAttributes( $l, $text );
1343 $s .= "<a href=\"{$url}\"{$style}>{$text}</a>";
1345 if($wgLang->isRTL()) $s .= '</span>';
1349 function bugReportsLink()
1351 $s = $this->makeKnownLink( wfMsg( 'bugreportspage' ),
1352 wfMsg( 'bugreports' ) );
1358 global $wgLinkCache;
1359 $t1 = Title
::newFromText( gmdate( 'F j' ) );
1360 $t2 = Title
::newFromText( gmdate( 'Y' ) );
1362 $wgLinkCache->suspend();
1363 $id = $t1->getArticleID();
1364 $wgLinkCache->resume();
1367 $s = $this->makeBrokenLink( $t1->getText() );
1369 $s = $this->makeKnownLink( $t1->getText() );
1373 $wgLinkCache->suspend();
1374 $id = $t2->getArticleID();
1375 $wgLinkCache->resume();
1378 $s .= $this->makeBrokenLink( $t2->getText() );
1380 $s .= $this->makeKnownLink( $t2->getText() );
1387 global $wgLang, $wgTitle, $wgLinkCache;
1389 $tns = $wgTitle->getNamespace();
1390 if ( -1 == $tns ) { return ''; }
1392 $pn = $wgTitle->getText();
1393 $tp = wfMsg( 'talkpage' );
1394 if ( Namespace::isTalk( $tns ) ) {
1395 $lns = Namespace::getSubject( $tns );
1398 $text = wfMsg('articlepage');
1401 $text = wfMsg('userpage');
1404 $text = wfMsg('wikipediapage');
1407 $text = wfMsg('imagepage');
1410 $text= wfMsg('articlepage');
1414 $lns = Namespace::getTalk( $tns );
1417 $n = $wgLang->getNsText( $lns );
1418 if ( '' == $n ) { $link = $pn; }
1419 else { $link = $n.':'.$pn; }
1421 $wgLinkCache->suspend();
1422 $s = $this->makeLink( $link, $text );
1423 $wgLinkCache->resume();
1428 function commentLink()
1430 global $wgLang, $wgTitle, $wgLinkCache;
1432 $tns = $wgTitle->getNamespace();
1433 if ( -1 == $tns ) { return ''; }
1435 $lns = ( Namespace::isTalk( $tns ) ) ?
$tns : Namespace::getTalk( $tns );
1437 # assert Namespace::isTalk( $lns )
1439 $n = $wgLang->getNsText( $lns );
1440 $pn = $wgTitle->getText();
1444 $wgLinkCache->suspend();
1445 $s = $this->makeKnownLink($link, wfMsg('postcomment'), 'action=edit§ion=new');
1446 $wgLinkCache->resume();
1451 # After all the page content is transformed into HTML, it makes
1452 # a final pass through here for things like table backgrounds.
1454 function transformContent( $text )
1459 # Note: This function MUST call getArticleID() on the link,
1460 # otherwise the cache won't get updated properly. See LINKCACHE.DOC.
1462 function makeLink( $title, $text = '', $query = '', $trail = '' ) {
1463 wfProfileIn( 'Skin::makeLink' );
1464 $nt = Title
::newFromText( $title );
1466 $result = $this->makeLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1468 wfDebug( 'Invalid title passed to Skin::makeLink(): "'.$title."\"\n" );
1469 $result = $text == "" ?
$title : $text;
1472 wfProfileOut( 'Skin::makeLink' );
1476 function makeKnownLink( $title, $text = '', $query = '', $trail = '', $prefix = '',$aprops = '') {
1477 $nt = Title
::newFromText( $title );
1479 return $this->makeKnownLinkObj( Title
::newFromText( $title ), $text, $query, $trail, $prefix , $aprops );
1481 wfDebug( 'Invalid title passed to Skin::makeKnownLink(): "'.$title."\"\n" );
1482 return $text == '' ?
$title : $text;
1486 function makeBrokenLink( $title, $text = '', $query = '', $trail = '' ) {
1487 $nt = Title
::newFromText( $title );
1489 return $this->makeBrokenLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1491 wfDebug( 'Invalid title passed to Skin::makeBrokenLink(): "'.$title."\"\n" );
1492 return $text == '' ?
$title : $text;
1496 function makeStubLink( $title, $text = '', $query = '', $trail = '' ) {
1497 $nt = Title
::newFromText( $title );
1499 return $this->makeStubLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1501 wfDebug( 'Invalid title passed to Skin::makeStubLink(): "'.$title."\"\n" );
1502 return $text == '' ?
$title : $text;
1506 # Pass a title object, not a title string
1507 function makeLinkObj( &$nt, $text= '', $query = '', $trail = '', $prefix = '' )
1509 global $wgOut, $wgUser;
1510 if ( $nt->isExternal() ) {
1511 $u = $nt->getFullURL();
1512 $link = $nt->getPrefixedURL();
1513 if ( '' == $text ) { $text = $nt->getPrefixedText(); }
1514 $style = $this->getExternalLinkAttributes( $link, $text, 'extiw' );
1517 if ( '' != $trail ) {
1518 if ( preg_match( '/^([a-z]+)(.*)$$/sD', $trail, $m ) ) {
1523 $retVal = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1524 } elseif ( 0 == $nt->getNamespace() && "" == $nt->getText() ) {
1525 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1526 } elseif ( ( -1 == $nt->getNamespace() ) ||
1527 ( Namespace::getImage() == $nt->getNamespace() ) ) {
1528 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1530 $aid = $nt->getArticleID() ;
1532 $retVal = $this->makeBrokenLinkObj( $nt, $text, $query, $trail, $prefix );
1534 $threshold = $wgUser->getOption('stubthreshold') ;
1535 if ( $threshold > 0 ) {
1536 $res = wfQuery ( "SELECT LENGTH(cur_text) AS x, cur_namespace, cur_is_redirect FROM cur WHERE cur_id='{$aid}'", DB_READ
) ;
1538 if ( wfNumRows( $res ) > 0 ) {
1539 $s = wfFetchObject( $res );
1541 if ( $s->cur_is_redirect
OR $s->cur_namespace
!= 0 ) {
1542 $size = $threshold*2 ; # Really big
1544 wfFreeResult( $res );
1546 $size = $threshold*2 ; # Really big
1551 if ( $size < $threshold ) {
1552 $retVal = $this->makeStubLinkObj( $nt, $text, $query, $trail, $prefix );
1554 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1561 # Pass a title object, not a title string
1562 function makeKnownLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' , $aprops = '')
1564 global $wgOut, $wgTitle;
1566 $fname = 'Skin::makeKnownLinkObj';
1567 wfProfileIn( $fname );
1569 $link = $nt->getPrefixedURL();
1571 if ( '' == $link ) {
1573 if ( '' == $text ) {
1574 $text = htmlspecialchars( $nt->getFragment() );
1577 $u = $nt->escapeLocalURL( $query );
1579 if ( '' != $nt->getFragment() ) {
1580 $u .= '#' . htmlspecialchars( $nt->getFragment() );
1582 if ( '' == $text ) {
1583 $text = htmlspecialchars( $nt->getPrefixedText() );
1585 $style = $this->getInternalLinkAttributesObj( $nt, $text );
1588 if ( '' != $trail ) {
1589 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1594 $r = "<a href=\"{$u}\"{$style}{$aprops}>{$prefix}{$text}{$inside}</a>{$trail}";
1595 wfProfileOut( $fname );
1599 # Pass a title object, not a title string
1600 function makeBrokenLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
1602 global $wgOut, $wgUser;
1604 $fname = 'Skin::makeBrokenLinkObj';
1605 wfProfileIn( $fname );
1607 if ( '' == $query ) {
1610 $q = 'action=edit&'.$query;
1612 $u = $nt->escapeLocalURL( $q );
1614 if ( '' == $text ) {
1615 $text = htmlspecialchars( $nt->getPrefixedText() );
1617 $style = $this->getInternalLinkAttributesObj( $nt, $text, "yes" );
1620 if ( '' != $trail ) {
1621 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1626 if ( $wgUser->getOption( 'highlightbroken' ) ) {
1627 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1629 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>?</a>{$trail}";
1632 wfProfileOut( $fname );
1636 # Pass a title object, not a title string
1637 function makeStubLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
1639 global $wgOut, $wgUser;
1641 $link = $nt->getPrefixedURL();
1643 $u = $nt->escapeLocalURL( $query );
1645 if ( '' == $text ) {
1646 $text = htmlspecialchars( $nt->getPrefixedText() );
1648 $style = $this->getInternalLinkAttributesObj( $nt, $text, 'stub' );
1651 if ( '' != $trail ) {
1652 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1657 if ( $wgUser->getOption( 'highlightbroken' ) ) {
1658 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1660 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>!</a>{$trail}";
1665 function makeSelfLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
1667 $u = $nt->escapeLocalURL( $query );
1668 if ( '' == $text ) {
1669 $text = htmlspecialchars( $nt->getPrefixedText() );
1672 if ( '' != $trail ) {
1673 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1678 return "<strong>{$prefix}{$text}{$inside}</strong>{$trail}";
1681 /* these are used extensively in SkinPHPTal, but also some other places */
1682 /*static*/ function makeSpecialUrl( $name, $urlaction='' ) {
1683 $title = Title
::makeTitle( NS_SPECIAL
, $name );
1684 $this->checkTitle($title, $name);
1685 return $title->getLocalURL( $urlaction );
1687 /*static*/ function makeTalkUrl ( $name, $urlaction='' ) {
1688 $title = Title
::newFromText( $name );
1689 $title = $title->getTalkPage();
1690 $this->checkTitle($title, $name);
1691 return $title->getLocalURL( $urlaction );
1693 /*static*/ function makeArticleUrl ( $name, $urlaction='' ) {
1694 $title = Title
::newFromText( $name );
1695 $title= $title->getSubjectPage();
1696 $this->checkTitle($title, $name);
1697 return $title->getLocalURL( $urlaction );
1699 /*static*/ function makeI18nUrl ( $name, $urlaction='' ) {
1700 $title = Title
::newFromText( wfMsg($name) );
1701 $this->checkTitle($title, $name);
1702 return $title->getLocalURL( $urlaction );
1704 /*static*/ function makeUrl ( $name, $urlaction='' ) {
1705 $title = Title
::newFromText( $name );
1706 $this->checkTitle($title, $name);
1707 return $title->getLocalURL( $urlaction );
1709 # this can be passed the NS number as defined in Language.php
1710 /*static*/ function makeNSUrl( $name, $urlaction='', $namespace=0 ) {
1711 $title = Title
::makeTitle( $namespace, $name );
1712 $this->checkTitle($title, $name);
1713 return $title->getLocalURL( $urlaction );
1716 /* these return an array with the 'href' and boolean 'exists' */
1717 /*static*/ function makeUrlDetails ( $name, $urlaction='' ) {
1718 $title = Title
::newFromText( $name );
1719 $this->checkTitle($title, $name);
1721 'href' => $title->getLocalURL( $urlaction ),
1722 'exists' => $title->getArticleID() != 0?
true:false
1725 /*static*/ function makeTalkUrlDetails ( $name, $urlaction='' ) {
1726 $title = Title
::newFromText( $name );
1727 $title = $title->getTalkPage();
1728 $this->checkTitle($title, $name);
1730 'href' => $title->getLocalURL( $urlaction ),
1731 'exists' => $title->getArticleID() != 0?
true:false
1734 /*static*/ function makeArticleUrlDetails ( $name, $urlaction='' ) {
1735 $title = Title
::newFromText( $name );
1736 $title= $title->getSubjectPage();
1737 $this->checkTitle($title, $name);
1739 'href' => $title->getLocalURL( $urlaction ),
1740 'exists' => $title->getArticleID() != 0?
true:false
1743 /*static*/ function makeI18nUrlDetails ( $name, $urlaction='' ) {
1744 $title = Title
::newFromText( wfMsg($name) );
1745 $this->checkTitle($title, $name);
1747 'href' => $title->getLocalURL( $urlaction ),
1748 'exists' => $title->getArticleID() != 0?
true:false
1752 # make sure we have some title to operate on
1753 /*static*/ function checkTitle ( &$title, &$name ) {
1754 if(!is_object($title)) {
1755 $title = Title
::newFromText( $name );
1756 if(!is_object($title)) {
1757 $title = Title
::newFromText( '<error: link target missing>' );
1762 function fnamePart( $url )
1764 $basename = strrchr( $url, '/' );
1765 if ( false === $basename ) { $basename = $url; }
1766 else { $basename = substr( $basename, 1 ); }
1767 return wfEscapeHTML( $basename );
1770 function makeImage( $url, $alt = '' )
1774 if ( '' == $alt ) { $alt = $this->fnamePart( $url ); }
1775 $s = '<img src="'.$url.'" alt="'.$alt.'" />';
1779 function makeImageLink( $name, $url, $alt = '' ) {
1780 $nt = Title
::makeTitle( Namespace::getImage(), $name );
1781 return $this->makeImageLinkObj( $nt, $alt );
1784 function makeImageLinkObj( $nt, $alt = '' ) {
1785 global $wgLang, $wgUseImageResize;
1786 $img = Image
::newFromTitle( $nt );
1787 $url = $img->getURL();
1790 $prefix = $postfix = '';
1792 if ( $wgUseImageResize ) {
1793 # Check if the alt text is of the form "options|alt text"
1795 # * thumbnail make a thumbnail with enlarge-icon and caption, alignment depends on lang
1796 # * left no resizing, just left align. label is used for alt= only
1797 # * right same, but right aligned
1798 # * none same, but not aligned
1799 # * ___px scale to ___ pixels width, no aligning. e.g. use in taxobox
1800 # * center center the image
1801 # * framed Keep original image size, no magnify-button.
1803 $part = explode( '|', $alt);
1805 $mwThumb =& MagicWord
::get( MAG_IMG_THUMBNAIL
);
1806 $mwLeft =& MagicWord
::get( MAG_IMG_LEFT
);
1807 $mwRight =& MagicWord
::get( MAG_IMG_RIGHT
);
1808 $mwNone =& MagicWord
::get( MAG_IMG_NONE
);
1809 $mwWidth =& MagicWord
::get( MAG_IMG_WIDTH
);
1810 $mwCenter =& MagicWord
::get( MAG_IMG_CENTER
);
1811 $mwFramed =& MagicWord
::get( MAG_IMG_FRAMED
);
1812 $alt = $part[count($part)-1];
1814 $height = $framed = $thumb = false;
1816 foreach( $part as $key => $val ) {
1817 if ( ! is_null( $mwThumb->matchVariableStartToEnd($val) ) ) {
1819 } elseif ( ! is_null( $mwRight->matchVariableStartToEnd($val) ) ) {
1820 # remember to set an alignment, don't render immediately
1822 } elseif ( ! is_null( $mwLeft->matchVariableStartToEnd($val) ) ) {
1823 # remember to set an alignment, don't render immediately
1825 } elseif ( ! is_null( $mwCenter->matchVariableStartToEnd($val) ) ) {
1826 # remember to set an alignment, don't render immediately
1828 } elseif ( ! is_null( $mwNone->matchVariableStartToEnd($val) ) ) {
1829 # remember to set an alignment, don't render immediately
1831 } elseif ( ! is_null( $match = $mwWidth->matchVariableStartToEnd($val) ) ) {
1832 # $match is the image width in pixels
1833 if ( preg_match( '/^([0-9]*)x([0-9]*)$/', $match, $m ) ) {
1834 $width = intval( $m[1] );
1835 $height = intval( $m[2] );
1837 $width = intval($match);
1839 } elseif ( ! is_null( $mwFramed->matchVariableStartToEnd($val) ) ) {
1843 if ( 'center' == $align )
1845 $prefix = '<span style="text-align: center">';
1846 $postfix = '</span>';
1850 if ( $thumb ||
$framed ) {
1852 # Create a thumbnail. Alignment depends on language
1853 # writing direction, # right aligned for left-to-right-
1854 # languages ("Western languages"), left-aligned
1855 # for right-to-left-languages ("Semitic languages")
1857 # If thumbnail width has not been provided, it is set
1858 # here to 180 pixels
1859 if ( $align == '' ) {
1860 $align = $wgLang->isRTL() ?
'left' : 'right';
1862 if ( ! isset($width) ) {
1865 return $prefix.$this->makeThumbLinkObj( $img, $alt, $align, $width, $height, $framed ).$postfix;
1867 } elseif ( isset($width) ) {
1869 # Create a resized image, without the additional thumbnail
1872 if ( ( ! $height === false )
1873 && ( $img->getHeight() * $width / $img->getWidth() > $height ) ) {
1874 print "height=$height<br>\nimg->getHeight() = ".$img->getHeight()."<br>\n";
1875 print 'rescaling by factor '. $height / $img->getHeight() . "<br>\n";
1876 $width = $img->getWidth() * $height / $img->getHeight();
1878 $url = $img->createThumb( $width );
1880 } # endif $wgUseImageResize
1882 if ( empty( $alt ) ) {
1883 $alt = preg_replace( '/\.(.+?)^/', '', $img->getName() );
1885 $alt = htmlspecialchars( $alt );
1887 $u = $nt->escapeLocalURL();
1890 $s = str_replace( "$1", $img->getName(), wfMsg('missingimage') );
1891 $s .= "<br>{$alt}<br>{$url}<br>\n";
1893 $s = '<a href="'.$u.'" class="image" title="'.$alt.'">' .
1894 '<img src="'.$url.'" alt="'.$alt.'" /></a>';
1896 if ( '' != $align ) {
1897 $s = "<div class=\"float{$align}\"><span>{$s}</span></div>";
1899 return str_replace("\n", ' ',$prefix.$s.$postfix);
1903 function makeThumbLinkObj( $img, $label = '', $align = 'right', $boxwidth = 180, $boxheight=false, $framed=false ) {
1904 global $wgStylePath, $wgLang;
1905 # $image = Title::makeTitle( Namespace::getImage(), $name );
1906 $url = $img->getURL();
1908 #$label = htmlspecialchars( $label );
1909 $alt = preg_replace( '/<[^>]*>/', '', $label);
1910 $alt = htmlspecialchars( $alt );
1912 if ( $img->exists() )
1914 $width = $img->getWidth();
1915 $height = $img->getHeight();
1917 $width = $height = 200;
1921 // Use image dimensions, don't scale
1923 $oboxwidth = $boxwidth +
2;
1924 $boxheight = $height;
1927 $h = intval( $height/($width/$boxwidth) );
1928 $oboxwidth = $boxwidth +
2;
1929 if ( ( ! $boxheight === false ) && ( $h > $boxheight ) )
1931 $boxwidth *= $boxheight/$h;
1935 $thumbUrl = $img->createThumb( $boxwidth );
1938 $u = $img->getEscapeLocalURL();
1940 $more = htmlspecialchars( wfMsg( 'thumbnail-more' ) );
1941 $magnifyalign = $wgLang->isRTL() ?
'left' : 'right';
1942 $textalign = $wgLang->isRTL() ?
' style="text-align:right"' : '';
1944 $s = "<div class=\"thumb t{$align}\"><div style=\"width:{$oboxwidth}px;\">";
1945 if ( $thumbUrl == '' ) {
1946 $s .= str_replace( "$1", $img->getName(), wfMsg('missingimage') );
1949 $s .= '<a href="'.$u.'" class="internal" title="'.$alt.'">'.
1950 '<img src="'.$thumbUrl.'" alt="'.$alt.'" ' .
1951 'width="'.$boxwidth.'" height="'.$boxheight.'" /></a>';
1955 $zoomicon = '<div class="magnify" style="float:'.$magnifyalign.'">'.
1956 '<a href="'.$u.'" class="internal" title="'.$more.'">'.
1957 '<img src="'.$wgStylePath.'/images/magnify-clip.png" ' .
1958 'width="15" height="11" alt="'.$more.'" /></a></div>';
1961 $s .= ' <div class="thumbcaption" '.$textalign.'>'.$zoomicon.$label."</div></div></div>";
1962 return str_replace("\n", ' ', $s);
1965 function makeMediaLink( $name, $url, $alt = "" ) {
1966 $nt = Title
::makeTitle( Namespace::getMedia(), $name );
1967 return $this->makeMediaLinkObj( $nt, $alt );
1970 function makeMediaLinkObj( $nt, $alt = "" )
1972 if ( ! isset( $nt ) )
1974 ### HOTFIX. Instead of breaking, return empry string.
1977 $name = $nt->getDBKey();
1978 $url = Image
::wfImageUrl( $name );
1979 if ( empty( $alt ) ) {
1980 $alt = preg_replace( '/\.(.+?)^/', '', $name );
1983 $u = htmlspecialchars( $url );
1984 $s = "<a href=\"{$u}\" class='internal' title=\"{$alt}\">{$alt}</a>";
1989 function specialLink( $name, $key = "" )
1993 if ( '' == $key ) { $key = strtolower( $name ); }
1994 $pn = $wgLang->ucfirst( $name );
1995 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1999 function makeExternalLink( $url, $text, $escape = true ) {
2000 $style = $this->getExternalLinkAttributes( $url, $text );
2001 $url = htmlspecialchars( $url );
2003 $text = htmlspecialchars( $text );
2005 return '<a href="'.$url.'"'.$style.'>'.$text.'</a>';
2008 # Called by history lists and recent changes
2011 # Returns text for the start of the tabular part of RC
2012 function beginRecentChangesList()
2014 $this->rc_cache
= array() ;
2015 $this->rcMoveIndex
= 0;
2016 $this->rcCacheIndex
= 0 ;
2017 $this->lastdate
= '';
2018 $this->rclistOpen
= false;
2022 function beginImageHistoryList()
2024 $s = "\n<h2>" . wfMsg( 'imghistory' ) . "</h2>\n" .
2025 "<p>" . wfMsg( 'imghistlegend' ) . "</p>\n".'<ul class="special">';
2029 # Returns text for the end of RC
2030 # If enhanced RC is in use, returns pretty much all the text
2031 function endRecentChangesList()
2033 $s = $this->recentChangesBlock() ;
2034 if( $this->rclistOpen
) {
2040 # Enhanced RC ungrouped line
2041 function recentChangesBlockLine ( $rcObj )
2043 global $wgStylePath, $wgLang ;
2045 # Get rc_xxxx variables
2046 extract( $rcObj->mAttribs
) ;
2047 $curIdEq = 'curid='.$rc_cur_id;
2052 $r .= '<img src="'.$wgStylePath.'/images/Arr_.png" width="12" height="12" border="0" />' ;
2055 if ( $rc_type == RC_MOVE
) {
2056 $r .= ' ';
2058 # M & N (minor & new)
2059 $M = wfMsg( 'minoreditletter' );
2060 $N = wfMsg( 'newpageletter' );
2062 if ( $rc_type == RC_NEW
) {
2075 $r .= ' '.$rcObj->timestamp
.' ' ;
2079 $link = $rcObj->link
;
2080 if ( $rcObj->watched
) $link = '<strong>'.$link.'</strong>' ;
2085 $r .= $rcObj->curlink
;
2089 $r .= $this->makeKnownLinkObj( $rcObj->getTitle(), wfMsg( 'hist' ), $curIdEq.'&action=history' );
2092 $r .= ') . . '.$rcObj->userlink
;
2093 $r .= $rcObj->usertalklink
;
2096 if ( $rc_comment != '' && $rc_type != RC_MOVE
) {
2097 $rc_comment=$this->formatComment($rc_comment);
2098 $r .= $wgLang->emphasize( ' ('.$rc_comment.')' );
2106 function recentChangesBlockGroup ( $block )
2108 global $wgStylePath, $wgLang ;
2111 $M = wfMsg( 'minoreditletter' );
2112 $N = wfMsg( 'newpageletter' );
2114 # Collate list of users
2116 $userlinks = array () ;
2117 foreach ( $block AS $rcObj ) {
2118 $oldid = $rcObj->mAttribs
['rc_last_oldid'];
2119 if ( $rcObj->mAttribs
['rc_new'] ) $isnew = true ;
2120 $u = $rcObj->userlink
;
2121 if ( !isset ( $userlinks[$u] ) ) $userlinks[$u] = 0 ;
2125 # Sort the list and convert to text
2126 krsort ( $userlinks ) ;
2127 asort ( $userlinks ) ;
2129 foreach ( $userlinks as $userlink => $count) {
2131 if ( $count > 1 ) $text .= " ({$count}×)" ;
2132 array_push ( $users , $text ) ;
2134 $users = ' <font size="-1">['.implode('; ',$users).']</font>' ;
2137 $rci = 'RCI'.$this->rcCacheIndex
;
2138 $rcl = 'RCL'.$this->rcCacheIndex
;
2139 $rcm = 'RCM'.$this->rcCacheIndex
;
2140 $toggleLink = 'javascript:toggleVisibility("'.$rci.'","'.$rcm.'","'.$rcl.'")' ;
2141 $arrowdir = $wgLang->isRTL() ?
'l' : 'r';
2142 $tl = '<span id="'.$rcm.'"><a href="'.$toggleLink.'"><img src="'.$wgStylePath.'"/images/Arr_'.$arrowdir.png
.'" width="12" height="12" /></a></span>' ;
2143 $tl .= '<span id="'.$rcl.'" style="display:none"><a href="'.$toggleLink.'"><img src="'.$wgStylePath.'/images/Arr_d.png" width="12" height="12" /></a></span>' ;
2149 if ( $isnew ) $r .= $N ;
2150 else $r .= ' ' ;
2151 $r .= ' ' ; # Minor
2154 $r .= ' '.$block[0]->timestamp
.' ' ;
2158 $link = $block[0]->link
;
2159 if ( $block[0]->watched
) $link = '<strong>'.$link.'</strong>' ;
2162 $curIdEq = 'curid=' . $block[0]->mAttribs
['rc_cur_id'];
2163 if ( $block[0]->mAttribs
['rc_type'] != RC_LOG
) {
2165 $r .= ' ('.count($block).' ' ;
2166 if ( $isnew ) $r .= wfMsg('changes');
2167 else $r .= $this->makeKnownLinkObj( $block[0]->getTitle() , wfMsg('changes') ,
2168 $curIdEq.'&diff=0&oldid='.$oldid ) ;
2172 $r .= $this->makeKnownLinkObj( $block[0]->getTitle(), wfMsg( 'history' ), $curIdEq.'&action=history' );
2180 $r .= '<div id="'.$rci.'" style="display:none">' ;
2181 foreach ( $block AS $rcObj ) {
2182 # Get rc_xxxx variables
2183 extract( $rcObj->mAttribs
);
2185 $r .= '<img src="'.$wgStylePath.'/images/Arr_.png" width="12" height="12" />';
2186 $r .= '<tt> ' ;
2187 if ( $rc_new ) $r .= $N ;
2188 else $r .= ' ' ;
2189 if ( $rc_minor ) $r .= $M ;
2190 else $r .= ' ' ;
2194 if ( $rc_last_oldid != 0 ) {
2195 $o = 'oldid='.$rc_last_oldid ;
2197 if ( $rc_type == RC_LOG
) {
2198 $link = $rcObj->timestamp
;
2200 $link = $this->makeKnownLinkObj( $rcObj->getTitle(), $rcObj->timestamp
, "{$curIdEq}&$o" ) ;
2202 $link = '<tt>'.$link.'</tt>' ;
2206 $r .= $rcObj->curlink
;
2208 $r .= $rcObj->lastlink
;
2209 $r .= ') . . '.$rcObj->userlink
;
2210 $r .= $rcObj->usertalklink
;
2211 if ( $rc_comment != '' ) {
2212 $rc_comment=$this->formatComment($rc_comment);
2213 $r .= $wgLang->emphasize( ' ('.$rc_comment.')' ) ;
2219 $this->rcCacheIndex++
;
2223 # If enhanced RC is in use, this function takes the previously cached
2224 # RC lines, arranges them, and outputs the HTML
2225 function recentChangesBlock ()
2227 global $wgStylePath ;
2228 if ( count ( $this->rc_cache
) == 0 ) return '' ;
2230 foreach ( $this->rc_cache
AS $secureName => $block ) {
2231 if ( count ( $block ) < 2 ) {
2232 $blockOut .= $this->recentChangesBlockLine ( array_shift ( $block ) ) ;
2234 $blockOut .= $this->recentChangesBlockGroup ( $block ) ;
2238 return '<div>'.$blockOut.'</div>' ;
2241 # Called in a loop over all displayed RC entries
2242 # Either returns the line, or caches it for later use
2243 function recentChangesLine( &$rc, $watched = false )
2246 $usenew = $wgUser->getOption( 'usenewrc' );
2248 $line = $this->recentChangesLineNew ( $rc, $watched ) ;
2250 $line = $this->recentChangesLineOld ( $rc, $watched ) ;
2254 function recentChangesLineOld( &$rc, $watched = false )
2256 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds;
2258 # Extract DB fields into local scope
2259 extract( $rc->mAttribs
);
2260 $curIdEq = 'curid=' . $rc_cur_id;
2262 # Make date header if necessary
2263 $date = $wgLang->date( $rc_timestamp, true);
2265 if ( $date != $this->lastdate
) {
2266 if ( '' != $this->lastdate
) { $s .= "</ul>\n"; }
2267 $s .= "<h4>{$date}</h4>\n<ul class='special'>";
2268 $this->lastdate
= $date;
2269 $this->rclistOpen
= true;
2273 if ( $rc_type == RC_MOVE
) {
2275 $s .= '(' . wfMsg( 'diff' ) . ') (';
2277 $s .= $this->makeKnownLinkObj( $rc->getMovedToTitle(), wfMsg( 'hist' ), 'action=history' ) .
2280 # "[[x]] moved to [[y]]"
2282 $s .= wfMsg( '1movedto2', $this->makeKnownLinkObj( $rc->getTitle(), '', 'redirect=no' ),
2283 $this->makeKnownLinkObj( $rc->getMovedToTitle(), '' ) );
2287 if ( $rc_type == RC_NEW ||
$rc_type == RC_LOG
) {
2288 $diffLink = wfMsg( 'diff' );
2290 $diffLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'diff' ),
2291 $curIdEq.'&diff='.$rc_this_oldid.'&oldid='.$rc_last_oldid ,'' ,'' , ' tabindex="'.$rc->counter
.'"');
2293 $s .= '('.$diffLink.') (';
2296 $s .= $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'hist' ), $curIdEq.'&action=history' );
2299 # M and N (minor and new)
2300 $M = wfMsg( 'minoreditletter' );
2301 $N = wfMsg( 'newpageletter' );
2302 if ( $rc_minor ) { $s .= ' <strong>'.$M.'</strong>'; }
2303 if ( $rc_type == RC_NEW
) { $s .= '<strong>'.$N.'</strong>'; }
2306 $articleLink = $this->makeKnownLinkObj( $rc->getTitle(), '' );
2309 $articleLink = '<strong>'.$articleLink.'</strong>';
2311 $s .= ' '.$articleLink;
2316 $s .= '; ' . $wgLang->time( $rc_timestamp, true, $wgRCSeconds ) . ' . . ';
2318 # User link (or contributions for unregistered users)
2319 if ( 0 == $rc_user ) {
2320 $userLink = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
2321 $rc_user_text, 'target=' . $rc_user_text );
2323 $userLink = $this->makeLink( $wgLang->getNsText( NS_USER
) . ':'.$rc_user_text, $rc_user_text );
2328 $talkname=$wgLang->getNsText(NS_TALK
); # use the shorter name
2329 global $wgDisableAnonTalk;
2330 if( 0 == $rc_user && $wgDisableAnonTalk ) {
2333 $utns=$wgLang->getNsText(NS_USER_TALK
);
2334 $userTalkLink= $this->makeLink($utns . ':'.$rc_user_text, $talkname );
2338 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2339 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2340 'Blockip' ), wfMsg( 'blocklink' ), 'ip='.$rc_user_text );
2344 if($userTalkLink) $userTalkLink .= ' | ';
2345 $userTalkLink .= $blockLink;
2347 if($userTalkLink) $s.=' ('.$userTalkLink.')';
2350 if ( '' != $rc_comment && '*' != $rc_comment && $rc_type != RC_MOVE
) {
2351 $rc_comment=$this->formatComment($rc_comment);
2352 $s .= $wgLang->emphasize(' (' . $rc_comment . ')');
2359 # function recentChangesLineNew( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched = false, $oldid = 0 , $diffid = 0 )
2360 function recentChangesLineNew( &$baseRC, $watched = false )
2362 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds;
2364 # Create a specialised object
2365 $rc = RCCacheEntry
::newFromParent( $baseRC ) ;
2367 # Extract fields from DB into the function scope (rc_xxxx variables)
2368 extract( $rc->mAttribs
);
2369 $curIdEq = 'curid=' . $rc_cur_id;
2371 # If it's a new day, add the headline and flush the cache
2372 $date = $wgLang->date( $rc_timestamp, true);
2374 if ( $date != $this->lastdate
) {
2375 # Process current cache
2376 $ret = $this->recentChangesBlock () ;
2377 $this->rc_cache
= array() ;
2378 $ret .= "<h4>{$date}</h4>\n";
2379 $this->lastdate
= $date;
2383 if ( $rc_type == RC_MOVE
) {
2384 $clink = $this->makeKnownLinkObj( $rc->getTitle(), '', 'redirect=no' );
2385 $clink .= ' ' . wfMsg('movedto') . ' ';
2386 $clink .= $this->makeKnownLinkObj( $rc->getMovedToTitle(), '' );
2388 $clink = $this->makeKnownLinkObj( $rc->getTitle(), '' ) ;
2391 $time = $wgLang->time( $rc_timestamp, true, $wgRCSeconds );
2392 $rc->watched
= $watched ;
2393 $rc->link
= $clink ;
2394 $rc->timestamp
= $time;
2397 if ( ( $rc_type == RC_NEW
&& $rc_this_oldid == 0 ) ||
$rc_type == RC_LOG ||
$rc_type == RC_MOVE
) {
2398 $curLink = wfMsg( 'cur' );
2400 $curLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'cur' ),
2401 $curIdEq.'&diff=0&oldid='.$rc_this_oldid ,'' ,'' , ' tabindex="'.$baseRC->counter
.'"' );
2405 $titleObj = $rc->getTitle();
2406 if ( $rc_last_oldid == 0 ||
$rc_type == RC_LOG ||
$rc_type == RC_MOVE
) {
2407 $lastLink = wfMsg( 'last' );
2409 $lastLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'last' ),
2410 $curIdEq.'&diff='.$rc_this_oldid.'&oldid='.$rc_last_oldid );
2413 # Make user link (or user contributions for unregistered users)
2414 if ( 0 == $rc_user ) {
2415 $userLink = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
2416 $rc_user_text, 'target=' . $rc_user_text );
2418 $userLink = $this->makeLink( $wgLang->getNsText(
2419 Namespace::getUser() ) . ':'.$rc_user_text, $rc_user_text );
2422 $rc->userlink
= $userLink ;
2423 $rc->lastlink
= $lastLink ;
2424 $rc->curlink
= $curLink ;
2426 # Make user talk link
2427 $utns=$wgLang->getNsText(NS_USER_TALK
);
2428 $talkname=$wgLang->getNsText(NS_TALK
); # use the shorter name
2429 $userTalkLink= $this->makeLink($utns . ':'.$rc_user_text, $talkname );
2431 global $wgDisableAnonTalk;
2432 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2433 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2434 'Blockip' ), wfMsg( 'blocklink' ), 'ip='.$rc_user_text );
2435 if( $wgDisableAnonTalk )
2436 $rc->usertalklink
= ' ('.$blockLink.')';
2438 $rc->usertalklink
= ' ('.$userTalkLink.' | '.$blockLink.')';
2440 if( $wgDisableAnonTalk && ($rc_user == 0) )
2441 $rc->usertalklink
= '';
2443 $rc->usertalklink
= ' ('.$userTalkLink.')';
2446 # Put accumulated information into the cache, for later display
2447 # Page moves go on their own line
2448 $title = $rc->getTitle();
2449 $secureName = $title->getPrefixedDBkey();
2450 if ( $rc_type == RC_MOVE
) {
2451 # Use an @ character to prevent collision with page names
2452 $this->rc_cache
['@@' . ($this->rcMoveIndex++
)] = array($rc);
2454 if ( !isset ( $this->rc_cache
[$secureName] ) ) $this->rc_cache
[$secureName] = array() ;
2455 array_push ( $this->rc_cache
[$secureName] , $rc ) ;
2460 function endImageHistoryList()
2466 /* This function is called by all recent changes variants, by the page history,
2467 and by the user contributions list. It is responsible for formatting edit
2468 comments. It escapes any HTML in the comment, but adds some CSS to format
2469 auto-generated comments (from section editing) and formats [[wikilinks]].
2470 Main author: Erik Möller (moeller@scireview.de)
2472 function formatComment($comment)
2475 $comment=wfEscapeHTML($comment);
2477 # The pattern for autogen comments is / * foo * /, which makes for
2479 # We look for all comments, match any text before and after the comment,
2480 # add a separator where needed and format the comment itself with CSS
2481 while (preg_match('/(.*)\/\*\s*(.*?)\s*\*\/(.*)/', $comment,$match)) {
2486 if($pre) { $auto = $sep.' '.$auto; }
2487 if($post) { $auto .= ' '.$sep; }
2488 $auto='<span class="autocomment">'.$auto.'</span>';
2489 $comment=$pre.$auto.$post;
2492 # format regular and media links - all other wiki formatting
2494 while(preg_match('/\[\[(.*?)(\|(.*?))*\]\]/',$comment,$match)) {
2496 $medians = $wgLang->getNsText(Namespace::getMedia());
2498 if(preg_match('/^'.$medians.'/i',$match[1])) {
2499 $func='makeMediaLink';
2501 if(isset($match[3]) ) {
2503 preg_replace('/\[\[(.*?)\]\]/',
2504 $this->$func($match[1],$match[3]),$comment,1);
2507 preg_replace('/\[\[(.*?)\]\]/',
2508 $this->$func($match[1],$match[1]),$comment,1);
2516 function imageHistoryLine( $iscur, $timestamp, $img, $user, $usertext, $size, $description )
2518 global $wgUser, $wgLang, $wgTitle;
2520 $datetime = $wgLang->timeanddate( $timestamp, true );
2521 $del = wfMsg( 'deleteimg' );
2522 $cur = wfMsg( 'cur' );
2525 $url = Image
::wfImageUrl( $img );
2527 if ( $wgUser->isSysop() ) {
2528 $link = $wgTitle->escapeLocalURL( 'image=' . $wgTitle->getPartialURL() .
2530 $style = $this->getInternalLinkAttributes( $link, $del );
2532 $dlink = '<a href="'.$link.'"'.$style.'>'.$del.'</a>';
2537 $url = wfEscapeHTML( wfImageArchiveUrl( $img ) );
2538 if( $wgUser->getID() != 0 ) {
2539 $rlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2540 wfMsg( 'revertimg' ), 'action=revert&oldimage=' .
2541 urlencode( $img ) );
2542 $dlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2543 $del, 'action=delete&oldimage=' . urlencode( $img ) );
2545 # Having live active links for non-logged in users
2546 # means that bots and spiders crawling our site can
2547 # inadvertently change content. Baaaad idea.
2548 $rlink = wfMsg( 'revertimg' );
2553 $userlink = $usertext;
2555 $userlink = $this->makeLink( $wgLang->getNsText( Namespace::getUser() ) .
2556 ':'.$usertext, $usertext );
2558 $nbytes = wfMsg( 'nbytes', $size );
2559 $style = $this->getInternalLinkAttributes( $url, $datetime );
2561 $s = "<li> ({$dlink}) ({$rlink}) <a href=\"{$url}\"{$style}>{$datetime}</a>"
2562 . " . . {$userlink} ({$nbytes})";
2564 if ( '' != $description && '*' != $description ) {
2565 $sk=$wgUser->getSkin();
2566 $s .= $wgLang->emphasize(' (' . $sk->formatComment($description) . ')');
2572 function tocIndent($level) {
2573 return str_repeat( '<div class="tocindent">'."\n", $level>0 ?
$level : 0 );
2576 function tocUnindent($level) {
2577 return str_repeat( "</div>\n", $level>0 ?
$level : 0 );
2580 # parameter level defines if we are on an indentation level
2581 function tocLine( $anchor, $tocline, $level ) {
2582 $link = '<a href="#'.$anchor.'">'.$tocline.'</a><br />';
2586 return '<div class="tocline">'.$link."</div>\n";
2591 function tocTable($toc) {
2592 # note to CSS fanatics: putting this in a div does not work -- div won't auto-expand
2593 # try min-width & co when somebody gets a chance
2594 $hideline = ' <script type="text/javascript">showTocToggle("' . addslashes( wfMsg('showtoc') ) . '","' . addslashes( wfMsg('hidetoc') ) . '")</script>';
2596 '<table border="0" id="toc"><tr><td align="center">'."\n".
2597 '<b>'.wfMsg('toc').'</b>' .
2599 '</td></tr><tr id="tocinside"><td>'."\n".
2600 $toc."</td></tr></table>\n";
2603 # These two do not check for permissions: check $wgTitle->userCanEdit before calling them
2604 function editSectionScript( $section, $head ) {
2605 global $wgTitle, $wgRequest;
2606 if( $wgRequest->getInt( 'oldid' ) && ( $wgRequest->getVal( 'diff' ) != '0' ) ) {
2609 $url = $wgTitle->escapeLocalURL( 'action=edit§ion='.$section );
2610 return '<span oncontextmenu="document.location="'.$url.'";return false;">'.$head.'</span>';
2613 function editSectionLink( $section ) {
2615 global $wgTitle, $wgUser, $wgLang;
2617 if( $wgRequest->getInt( 'oldid' ) && ( $wgRequest->getVal( 'diff' ) != '0' ) ) {
2618 # Section edit links would be out of sync on an old page.
2619 # But, if we're diffing to the current page, they'll be
2624 $editurl = '§ion='.$section;
2625 $url = $this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg('editsection'),'action=edit'.$editurl);
2627 if( $wgLang->isRTL() ) {
2629 $nearside = 'right';
2634 return "<div class=\"editsection\" style=\"float:$farside;margin-$nearside:5px;\">[".$url."]</div>";
2638 // This function is called by EditPage.php and shows a bulletin board style
2639 // toolbar for common editing functions. It can be disabled in the user preferences.
2640 // The necsesary JavaScript code can be found in style/wikibits.js.
2641 function getEditToolbar() {
2642 global $wgStylePath, $wgLang, $wgMimeType;
2644 // toolarray an array of arrays which each include the filename of
2645 // the button image (without path), the opening tag, the closing tag,
2646 // and optionally a sample text that is inserted between the two when no
2647 // selection is highlighted.
2648 // The tip text is shown when the user moves the mouse over the button.
2650 // Already here are accesskeys (key), which are not used yet until someone
2651 // can figure out a way to make them work in IE. However, we should make
2652 // sure these keys are not defined on the edit page.
2654 array( 'image'=>'button_bold.png',
2657 'sample'=>wfMsg('bold_sample'),
2658 'tip'=>wfMsg('bold_tip'),
2661 array( "image"=>"button_italic.png",
2664 "sample"=>wfMsg("italic_sample"),
2665 "tip"=>wfMsg("italic_tip"),
2668 array( "image"=>"button_link.png",
2671 "sample"=>wfMsg("link_sample"),
2672 "tip"=>wfMsg("link_tip"),
2675 array( "image"=>"button_extlink.png",
2678 "sample"=>wfMsg("extlink_sample"),
2679 "tip"=>wfMsg("extlink_tip"),
2682 array( "image"=>"button_headline.png",
2685 "sample"=>wfMsg("headline_sample"),
2686 "tip"=>wfMsg("headline_tip"),
2689 array( "image"=>"button_image.png",
2690 "open"=>"[[".$wgLang->getNsText(NS_IMAGE
).":",
2692 "sample"=>wfMsg("image_sample"),
2693 "tip"=>wfMsg("image_tip"),
2696 array( "image"=>"button_media.png",
2697 "open"=>"[[".$wgLang->getNsText(NS_MEDIA
).":",
2699 "sample"=>wfMsg("media_sample"),
2700 "tip"=>wfMsg("media_tip"),
2703 array( "image"=>"button_math.png",
2704 "open"=>"\\<math\\>",
2705 "close"=>"\\</math\\>",
2706 "sample"=>wfMsg("math_sample"),
2707 "tip"=>wfMsg("math_tip"),
2710 array( "image"=>"button_nowiki.png",
2711 "open"=>"\\<nowiki\\>",
2712 "close"=>"\\</nowiki\\>",
2713 "sample"=>wfMsg("nowiki_sample"),
2714 "tip"=>wfMsg("nowiki_tip"),
2717 array( "image"=>"button_sig.png",
2721 "tip"=>wfMsg("sig_tip"),
2724 array( "image"=>"button_hr.png",
2725 "open"=>"\\n----\\n",
2728 "tip"=>wfMsg("hr_tip"),
2732 $toolbar ="<script type='text/javascript'>\n/*<![CDATA[*/\n";
2734 $toolbar.="document.writeln(\"<div id='toolbar'>\");\n";
2735 foreach($toolarray as $tool) {
2737 $image=$wgStylePath.'/images/'.$tool['image'];
2738 $open=$tool['open'];
2739 $close=$tool['close'];
2740 $sample = addslashes( $tool['sample'] );
2742 // Note that we use the tip both for the ALT tag and the TITLE tag of the image.
2743 // Older browsers show a "speedtip" type message only for ALT.
2744 // Ideally these should be different, realistically they
2745 // probably don't need to be.
2746 $tip = addslashes( $tool['tip'] );
2748 #$key = $tool["key"];
2750 $toolbar.="addButton('$image','$tip','$open','$close','$sample');\n";
2753 $toolbar.="addInfobox('" . addslashes( wfMsg( "infobox" ) ) . "','" . addslashes(wfMsg("infobox_alert")) . "');\n";
2754 $toolbar.="document.writeln(\"</div>\");\n";
2756 $toolbar.="/*]]>*/\n</script>";
2762 require_once( 'SkinStandard.php' );
2763 require_once( 'SkinNostalgia.php' );
2764 require_once( 'SkinCologneBlue.php' );
2766 if( $wgUsePHPTal ) {
2767 require_once( 'SkinPHPTal.php' );