f894425d9aec51c17160b3335ec9a79de1432673
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 , $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;
392 if( !$wgUseCategoryMagic ) return '' ;
393 if( count( $wgOut->mCategoryLinks
) == 0 ) return '';
394 if( !$wgOut->isArticle() ) return '';
396 $t = implode ( ' | ' , $wgOut->mCategoryLinks
) ;
397 $s = $this->makeKnownLink( 'Special:Categories',
398 wfMsg( 'categories' ), 'article=' . urlencode( $wgTitle->getPrefixedDBkey() ) )
401 if($wgUseCategoryBrowser) {
404 $s.= $wgTitle->getAllParentCategories($catstack);
410 function getCategories() {
411 $catlinks=$this->getCategoryLinks();
412 if(!empty($catlinks)) {
413 return "<p class='catlinks'>{$catlinks}</p>";
417 function getQuickbarCompensator( $rows = 1 )
419 return "<td width='152' rowspan='{$rows}'> </td>";
422 # This gets called immediately before the </body> tag.
424 function afterContent()
426 global $wgUser, $wgOut, $wgServer;
427 global $wgTitle, $wgLang;
429 $printfooter = "<div class=\"printfooter\">\n" . $this->printFooter() . "</div>\n";
430 return $printfooter . $this->doAfterContent();
433 function printFooter() {
435 $url = htmlspecialchars( $wgTitle->getFullURL() );
436 return "<p>" . wfMsg( "retrievedfrom", "<a href=\"$url\">$url</a>" ) .
437 "</p>\n\n<p>" . $this->pageStats() . "</p>\n";
440 function doAfterContent()
442 global $wgUser, $wgOut, $wgLang;
443 $fname = 'Skin::doAfterContent';
444 wfProfileIn( $fname );
445 wfProfileIn( $fname.'-1' );
447 $s = "\n</div><br style=\"clear:both\" />\n";
448 $s .= "\n<div id='footer'>";
449 $s .= '<table border="0" cellspacing="0"><tr>';
451 wfProfileOut( $fname.'-1' );
452 wfProfileIn( $fname.'-2' );
454 $qb = $this->qbSetting();
456 $left = ($qb == 1 ||
$qb == 3);
457 if($wgLang->isRTL()) $left = !$left;
459 if ( $shove && $left ) { # Left
460 $s .= $this->getQuickbarCompensator();
462 wfProfileOut( $fname.'-2' );
463 wfProfileIn( $fname.'-3' );
464 $l = $wgLang->isRTL() ?
'right' : 'left';
465 $s .= "<td class='bottom' align='$l' valign='top'>";
467 $s .= $this->bottomLinks();
468 $s .= "\n<br />" . $this->mainPageLink()
469 . ' | ' . $this->aboutLink()
470 . ' | ' . $this->specialLink( 'recentchanges' )
471 . ' | ' . $this->searchForm()
472 . '<br /><span id="pagestats">' . $this->pageStats() . '</span>';
475 if ( $shove && !$left ) { # Right
476 $s .= $this->getQuickbarCompensator();
478 $s .= "</tr></table>\n</div>\n</div>\n";
480 wfProfileOut( $fname.'-3' );
481 wfProfileIn( $fname.'-4' );
482 if ( 0 != $qb ) { $s .= $this->quickBar(); }
483 wfProfileOut( $fname.'-4' );
484 wfProfileOut( $fname );
488 function pageTitleLinks()
490 global $wgOut, $wgTitle, $wgUser, $wgLang, $wgUseApproval, $wgRequest;
492 extract( $wgRequest->getValues( 'oldid', 'diff' ) );
493 $action = $wgRequest->getText( 'action' );
495 $s = $this->printableLink();
496 if ( wfMsg ( 'disclaimers' ) != '-' ) $s .= ' | ' . $this->makeKnownLink( wfMsg( 'disclaimerpage' ), wfMsg( 'disclaimers' ) ) ;
498 if ( $wgOut->isArticleRelated() ) {
499 if ( $wgTitle->getNamespace() == Namespace::getImage() ) {
500 $name = $wgTitle->getDBkey();
501 $link = wfEscapeHTML( Image
::wfImageUrl( $name ) );
502 $style = $this->getInternalLinkAttributes( $link, $name );
503 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>";
505 # This will show the "Approve" link if $wgUseApproval=true;
506 if ( isset ( $wgUseApproval ) && $wgUseApproval )
508 $t = $wgTitle->getDBkey();
509 $name = 'Approve this article' ;
510 $link = "http://test.wikipedia.org/w/magnus/wiki.phtml?title={$t}&action=submit&doit=1" ;
511 #wfEscapeHTML( wfImageUrl( $name ) );
512 $style = $this->getExternalLinkAttributes( $link, $name );
513 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>" ;
516 if ( 'history' == $action ||
isset( $diff ) ||
isset( $oldid ) ) {
517 $s .= ' | ' . $this->makeKnownLink( $wgTitle->getPrefixedText(),
518 wfMsg( 'currentrev' ) );
521 if ( $wgUser->getNewtalk() ) {
522 # do not show "You have new messages" text when we are viewing our
525 if(!(strcmp($wgTitle->getText(),$wgUser->getName()) == 0 &&
526 $wgTitle->getNamespace()==Namespace::getTalk(Namespace::getUser()))) {
527 $n =$wgUser->getName();
528 $tl = $this->makeKnownLink( $wgLang->getNsText(
529 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
530 wfMsg('newmessageslink') );
531 $s.= ' | <strong>'. wfMsg( 'newmessages', $tl ) . '</strong>';
535 $undelete = $this->getUndeleteLink();
536 if( !empty( $undelete ) ) {
537 $s .= ' | '.$undelete;
542 function getUndeleteLink() {
543 global $wgUser, $wgTitle, $wgLang, $action;
544 if( $wgUser->isSysop() &&
545 (($wgTitle->getArticleId() == 0) ||
($action == "history")) &&
546 ($n = $wgTitle->isDeleted() ) ) {
547 return wfMsg( 'thisisdeleted',
548 $this->makeKnownLink(
549 $wgLang->SpecialPage( 'Undelete/' . $wgTitle->getPrefixedDBkey() ),
550 wfMsg( 'restorelink', $n ) ) );
555 function printableLink()
557 global $wgOut, $wgFeedClasses, $wgRequest;
559 $baseurl = $_SERVER['REQUEST_URI'];
560 if( strpos( '?', $baseurl ) == false ) {
565 $baseurl = htmlspecialchars( $baseurl );
566 $printurl = $wgRequest->escapeAppendQuery( 'printable=yes' );
568 $s = "<a href=\"$printurl\">" . wfMsg( 'printableversion' ) . '</a>';
569 if( $wgOut->isSyndicated() ) {
570 foreach( $wgFeedClasses as $format => $class ) {
571 $feedurl = $wgRequest->escapeAppendQuery( "feed=$format" );
572 $s .= " | <a href=\"$feedurl\">{$format}</a>";
580 global $wgOut, $wgTitle, $wgUser;
582 $s = '<h1 class="pagetitle">' . htmlspecialchars( $wgOut->getPageTitle() ) . '</h1>';
583 if($wgUser->getOption( 'editsectiononrightclick' ) && $wgTitle->userCanEdit()) { $s=$this->editSectionScript(0,$s);}
587 function pageSubtitle()
591 $sub = $wgOut->getSubtitle();
593 global $wgExtraSubtitle;
594 $sub = wfMsg( 'fromwikipedia' ) . $wgExtraSubtitle;
596 $subpages = $this->subPageSubtitle();
597 $sub .= !empty($subpages)?
"</p><p class='subpages'>$subpages":'';
598 $s = "<p class='subtitle'>{$sub}</p>\n";
602 function subPageSubtitle()
604 global $wgOut,$wgTitle,$wgNamespacesWithSubpages;
606 if($wgOut->isArticle() && !empty($wgNamespacesWithSubpages[$wgTitle->getNamespace()])) {
607 $ptext=$wgTitle->getPrefixedText();
608 if(preg_match('/\//',$ptext)) {
609 $links = explode('/',$ptext);
612 foreach($links as $link) {
614 if ($c<count($links)) {
615 $growinglink .= $link;
616 $getlink = $this->makeLink( $growinglink, $link );
617 if(preg_match('/class="new"/i',$getlink)) { break; } # this is a hack, but it saves time
621 $subpages .= '< ';
623 $subpages .= $getlink;
632 function nameAndLogin()
634 global $wgUser, $wgTitle, $wgLang, $wgShowIPinHeader, $wgIP;
636 $li = $wgLang->specialPage( 'Userlogin' );
637 $lo = $wgLang->specialPage( 'Userlogout' );
640 if ( 0 == $wgUser->getID() ) {
641 if( $wgShowIPinHeader && isset( $_COOKIE[ini_get('session.name')] ) ) {
644 $tl = $this->makeKnownLink( $wgLang->getNsText(
645 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
646 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
648 $s .= $n . ' ('.$tl.')';
650 $s .= wfMsg('notloggedin');
653 $rt = $wgTitle->getPrefixedURL();
654 if ( 0 == strcasecmp( urlencode( $lo ), $rt ) ) {
656 } else { $q = "returnto={$rt}"; }
658 $s .= "\n<br />" . $this->makeKnownLink( $li,
659 wfMsg( 'login' ), $q );
661 $n = $wgUser->getName();
662 $rt = $wgTitle->getPrefixedURL();
663 $tl = $this->makeKnownLink( $wgLang->getNsText(
664 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
665 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
669 $s .= $this->makeKnownLink( $wgLang->getNsText(
670 Namespace::getUser() ) . ":{$n}", $n ) . "{$tl}<br />" .
671 $this->makeKnownLink( $lo, wfMsg( 'logout' ),
672 "returnto={$rt}" ) . ' | ' .
673 $this->specialLink( 'preferences' );
675 $s .= ' | ' . $this->makeKnownLink( wfMsg( 'helppage' ),
681 function getSearchLink() {
682 $searchPage =& Title
::makeTitle( NS_SPECIAL
, 'Search' );
683 return $searchPage->getLocalURL();
686 function escapeSearchLink() {
687 return htmlspecialchars( $this->getSearchLink() );
690 function searchForm()
693 $search = $wgRequest->getText( 'search' );
695 $s = '<form name="search" class="inline" method="post" action="'
696 . $this->escapeSearchLink() . "\">\n"
697 . '<input type="text" name="search" size="19" value="'
698 . htmlspecialchars(substr($search,0,256)) . "\" />\n"
699 . '<input type="submit" name="go" value="' . wfMsg ('go') . '" /> '
700 . '<input type="submit" name="fulltext" value="' . wfMsg ('search') . "\" />\n</form>";
710 $s = $this->mainPageLink() . $sep
711 . $this->specialLink( 'recentchanges' );
713 if ( $wgOut->isArticleRelated() ) {
714 $s .= $sep . $this->editThisPage()
715 . $sep . $this->historyLink();
717 # Many people don't like this dropdown box
718 #$s .= $sep . $this->specialPagesList();
723 function bottomLinks()
725 global $wgOut, $wgUser, $wgTitle;
729 if ( $wgOut->isArticleRelated() ) {
730 $s .= '<strong>' . $this->editThisPage() . '</strong>';
731 if ( 0 != $wgUser->getID() ) {
732 $s .= $sep . $this->watchThisPage();
734 $s .= $sep . $this->talkLink()
735 . $sep . $this->historyLink()
736 . $sep . $this->whatLinksHere()
737 . $sep . $this->watchPageLinksLink();
739 if ( $wgTitle->getNamespace() == Namespace::getUser()
740 ||
$wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser()) )
743 $id=User
::idFromName($wgTitle->getText());
744 $ip=User
::isIP($wgTitle->getText());
746 if($id ||
$ip) { # both anons and non-anons have contri list
747 $s .= $sep . $this->userContribsLink();
749 if ( 0 != $wgUser->getID() ) { # show only to signed in users
750 if($id) { # can only email non-anons
751 $s .= $sep . $this->emailUserLink();
755 if ( $wgUser->isSysop() && $wgTitle->getArticleId() ) {
756 $s .= "\n<br />" . $this->deleteThisPage() .
757 $sep . $this->protectThisPage() .
758 $sep . $this->moveThisPage();
760 $s .= "<br />\n" . $this->otherLanguages();
767 global $wgOut, $wgLang, $wgArticle, $wgRequest;
768 global $wgDisableCounters;
770 extract( $wgRequest->getValues( 'oldid', 'diff' ) );
771 if ( ! $wgOut->isArticle() ) { return ''; }
772 if ( isset( $oldid ) ||
isset( $diff ) ) { return ''; }
773 if ( 0 == $wgArticle->getID() ) { return ''; }
776 if ( !$wgDisableCounters ) {
777 $count = $wgLang->formatNum( $wgArticle->getCount() );
779 $s = wfMsg( 'viewcount', $count );
783 $s .= ' ' . $this->getCredits();
785 return $s . ' ' . $this->getCopyright();
788 function getCredits() {
789 global $wgMaxCredits;
793 if (!isset($wgMaxCredits) ||
$wgMaxCredits == 0) {
794 $s = $this->lastModified();
796 $s = $this->getAuthorCredits();
797 if ($wgMaxCredits > 1) {
798 $s .= ' ' . $this->getContributorCredits();
805 function getAuthorCredits() {
806 global $wgLang, $wgArticle;
808 $last_author = $wgArticle->getUser();
810 if ($last_author == 0) {
811 $author_credit = wfMsg('anonymous');
813 $real_name = User
::whoIsReal($last_author);
814 if (!empty($real_name)) {
815 $author_credit = $real_name;
817 $author_credit = wfMsg('siteuser', User
::whoIs($last_author));
821 $timestamp = $wgArticle->getTimestamp();
823 $d = $wgLang->timeanddate( $wgArticle->getTimestamp(), true );
827 return wfMsg('lastmodifiedby', $d, $author_credit);
830 function getContributorCredits() {
832 global $wgArticle, $wgMaxCredits, $wgLang;
834 # don't count last editor
836 $contributors = $wgArticle->getContributors($wgMaxCredits - 1);
838 $real_names = array();
839 $user_names = array();
841 # Sift for real versus user names
843 foreach ($contributors as $user_id => $user_parts) {
845 if (!empty($user_parts[1])) {
846 $real_names[$user_id] = $user_parts[1];
848 $user_names[$user_id] = $user_parts[0];
853 $real = $wgLang->listToText(array_values($real_names));
854 $user = $wgLang->listToText(array_values($user_names));
857 $user = wfMsg('siteusers', $user);
860 if ($contributors[0] && $contributors[0][0] > 0) {
861 $anon = wfMsg('anonymous');
866 $creds = $wgLang->listToText(array($real, $user, $anon));
868 return wfMsg('othercontribs', $creds);
871 function getCopyright() {
872 global $wgRightsPage, $wgRightsUrl, $wgRightsText;
874 if( $wgRightsPage ) {
875 $link = $this->makeKnownLink( $wgRightsPage, $wgRightsText );
876 } elseif( $wgRightsUrl ) {
877 $link = $this->makeExternalLink( $wgRightsUrl, $wgRightsText );
882 $out .= wfMsg( 'copyright', $link );
886 function getCopyrightIcon() {
887 global $wgRightsPage, $wgRightsUrl, $wgRightsText, $wgRightsIcon;
889 if( $wgRightsIcon ) {
890 $icon = htmlspecialchars( $wgRightsIcon );
892 $url = htmlspecialchars( $wgRightsUrl );
893 $out .= '<a href="'.$url.'">';
895 $text = htmlspecialchars( $wgRightsText );
896 $out .= "<img src=\"$icon\" alt='$text' />";
904 function getPoweredBy() {
906 $url = htmlspecialchars( "$wgStylePath/images/poweredby_mediawiki_88x31.png" );
907 $img = '<a href="http://www.mediawiki.org/"><img src="'.$url.'" alt="MediaWiki" /></a>';
911 function lastModified()
913 global $wgLang, $wgArticle;
915 $timestamp = $wgArticle->getTimestamp();
917 $d = $wgLang->timeanddate( $wgArticle->getTimestamp(), true );
918 $s = ' ' . wfMsg( 'lastmodified', $d );
925 function logoText( $align = '' )
927 if ( '' != $align ) { $a = ' align="'.$align.'"'; }
930 $mp = wfMsg( 'mainpage' );
931 $titleObj = Title
::newFromText( $mp );
932 $s = '<a href="' . $titleObj->escapeLocalURL()
933 . '"><img'.$a.' src="'
934 . $this->getLogo() . '" alt="' . "[{$mp}]\" /></a>";
940 global $wgOut, $wgTitle, $wgUser, $wgRequest, $wgLang;
941 global $wgDisableUploads, $wgRemoteUploads;
943 $fname = 'Skin::quickBar';
944 wfProfileIn( $fname );
946 $action = $wgRequest->getText( 'action' );
947 $wpPreview = $wgRequest->getBool( 'wpPreview' );
948 $tns=$wgTitle->getNamespace();
950 $s = "\n<div id='quickbar'>";
951 $s .= "\n" . $this->logoText() . "\n<hr class='sep' />";
954 $s .= $this->mainPageLink()
955 . $sep . $this->specialLink( 'recentchanges' )
956 . $sep . $this->specialLink( 'randompage' );
957 if ($wgUser->getID()) {
958 $s.= $sep . $this->specialLink( 'watchlist' ) ;
959 $s .= $sep .$this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
960 wfMsg( 'mycontris' ), 'target=' . wfUrlencode($wgUser->getName() ) );
963 // only show watchlist link if logged in
964 if ( wfMsg ( 'currentevents' ) != '-' ) $s .= $sep . $this->makeKnownLink( wfMsg( 'currentevents' ), '' ) ;
965 $s .= "\n<br /><hr class='sep' />";
966 $articleExists = $wgTitle->getArticleId();
967 if ( $wgOut->isArticle() ||
$action =='edit' ||
$action =='history' ||
$wpPreview) {
968 if($wgOut->isArticle()) {
969 $s .= '<strong>' . $this->editThisPage() . '</strong>';
970 } else { # backlink to the article in edit or history mode
971 if($articleExists){ # no backlink if no article
974 $text = wfMsg('articlepage');
977 $text = wfMsg('viewtalkpage');
980 $text = wfMsg('userpage');
983 $text = wfMsg('viewtalkpage');
986 $text = wfMsg('wikipediapage');
989 $text = wfMsg('viewtalkpage');
992 $text = wfMsg('imagepage');
995 $text = wfMsg('viewtalkpage');
998 $text= wfMsg('articlepage');
1001 $link = $wgTitle->getText();
1002 if ($nstext = $wgLang->getNsText($tns) ) { # add namespace if necessary
1003 $link = $nstext . ':' . $link ;
1006 $s .= $this->makeLink( $link, $text );
1007 } elseif( $wgTitle->getNamespace() != Namespace::getSpecial() ) {
1008 # we just throw in a "New page" text to tell the user that he's in edit mode,
1009 # and to avoid messing with the separator that is prepended to the next item
1010 $s .= '<strong>' . wfMsg('newpage') . '</strong>';
1016 if( $tns%2
&& $action!='edit' && !$wpPreview) {
1017 $s.= '<br />'.$this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg('postcomment'),'action=edit§ion=new');
1021 watching could cause problems in edit mode:
1022 if user edits article, then loads "watch this article" in background and then saves
1023 article with "Watch this article" checkbox disabled, the article is transparently
1024 unwatched. Therefore we do not show the "Watch this page" link in edit mode
1026 if ( 0 != $wgUser->getID() && $articleExists) {
1027 if($action!='edit' && $action != 'submit' )
1029 $s .= $sep . $this->watchThisPage();
1031 if ( $wgTitle->userCanEdit() )
1032 $s .= $sep . $this->moveThisPage();
1034 if ( $wgUser->isSysop() and $articleExists ) {
1035 $s .= $sep . $this->deleteThisPage() .
1036 $sep . $this->protectThisPage();
1038 $s .= $sep . $this->talkLink();
1039 if ($articleExists && $action !='history') {
1040 $s .= $sep . $this->historyLink();
1042 $s.=$sep . $this->whatLinksHere();
1044 if($wgOut->isArticleRelated()) {
1045 $s .= $sep . $this->watchPageLinksLink();
1048 if ( Namespace::getUser() == $wgTitle->getNamespace()
1049 ||
$wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser())
1052 $id=User
::idFromName($wgTitle->getText());
1053 $ip=User
::isIP($wgTitle->getText());
1056 $s .= $sep . $this->userContribsLink();
1058 if ( 0 != $wgUser->getID() ) {
1059 if($id) { # can only email real users
1060 $s .= $sep . $this->emailUserLink();
1064 $s .= "\n<br /><hr class='sep' />";
1067 if ( 0 != $wgUser->getID() && ( !$wgDisableUploads ||
$wgRemoteUploads ) ) {
1068 $s .= $this->specialLink( 'upload' ) . $sep;
1070 $s .= $this->specialLink( 'specialpages' )
1071 . $sep . $this->bugReportsLink();
1073 global $wgSiteSupportPage;
1074 if( $wgSiteSupportPage ) {
1075 $s .= "\n<br /><a href=\"" . htmlspecialchars( $wgSiteSupportPage ) .
1076 '" class="internal">' . wfMsg( 'sitesupport' ) . '</a>';
1079 $s .= "\n<br /></div>\n";
1080 wfProfileOut( $fname );
1084 function specialPagesList()
1086 global $wgUser, $wgOut, $wgLang, $wgServer, $wgRedirectScript;
1088 $pages = SpecialPage
::getPages();
1090 foreach ( $pages[''] as $name => $page ) {
1091 $a[$name] = $page->getDescription();
1093 if ( $wgUser->isSysop() )
1095 foreach ( $pages['sysop'] as $name => $page ) {
1096 $a[$name] = $page->getDescription();
1099 if ( $wgUser->isDeveloper() )
1101 foreach ( $pages['developer'] as $name => $page ) {
1102 $a[$name] = $page->getDescription() ;
1105 $go = wfMsg( 'go' );
1106 $sp = wfMsg( 'specialpages' );
1107 $spp = $wgLang->specialPage( 'Specialpages' );
1109 $s = '<form id="specialpages" method="get" class="inline" ' .
1110 'action="' . htmlspecialchars( "{$wgServer}{$wgRedirectScript}" ) . "\">\n";
1111 $s .= "<select name=\"wpDropdown\">\n";
1112 $s .= "<option value=\"{$spp}\">{$sp}</option>\n";
1114 foreach ( $a as $name => $desc ) {
1115 $p = $wgLang->specialPage( $name );
1116 $s .= "<option value=\"{$p}\">{$desc}</option>\n";
1118 $s .= "</select>\n";
1119 $s .= "<input type='submit' value=\"{$go}\" name='redirect' />\n";
1124 function mainPageLink()
1126 $mp = wfMsg( 'mainpage' );
1127 $s = $this->makeKnownLink( $mp, $mp );
1131 function copyrightLink()
1133 $s = $this->makeKnownLink( wfMsg( 'copyrightpage' ),
1134 wfMsg( 'copyrightpagename' ) );
1138 function aboutLink()
1140 $s = $this->makeKnownLink( wfMsg( 'aboutpage' ),
1141 wfMsg( 'aboutwikipedia' ) );
1146 function disclaimerLink()
1148 $s = $this->makeKnownLink( wfMsg( 'disclaimerpage' ),
1149 wfMsg( 'disclaimers' ) );
1153 function editThisPage()
1155 global $wgOut, $wgTitle, $wgRequest;
1157 $oldid = $wgRequest->getVal( 'oldid' );
1158 $diff = $wgRequest->getVal( 'diff' );
1159 $redirect = $wgRequest->getVal( 'redirect' );
1161 if ( ! $wgOut->isArticleRelated() ) {
1162 $s = wfMsg( 'protectedpage' );
1164 $n = $wgTitle->getPrefixedText();
1165 if ( $wgTitle->userCanEdit() ) {
1166 $t = wfMsg( 'editthispage' );
1168 #$t = wfMsg( "protectedpage" );
1169 $t = wfMsg( 'viewsource' );
1173 if ( !is_null( $redirect ) ) { $red = "&redirect={$redirect}"; }
1174 if ( $oldid && ! isset( $diff ) ) {
1175 $oid = "&oldid={$oldid}";
1177 $s = $this->makeKnownLink( $n, $t, "action=edit{$oid}{$red}" );
1182 function deleteThisPage()
1184 global $wgUser, $wgOut, $wgTitle, $wgRequest;
1186 $diff = $wgRequest->getVal( 'diff' );
1187 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
1188 $n = $wgTitle->getPrefixedText();
1189 $t = wfMsg( 'deletethispage' );
1191 $s = $this->makeKnownLink( $n, $t, 'action=delete' );
1198 function protectThisPage()
1200 global $wgUser, $wgOut, $wgTitle, $wgRequest;
1202 $diff = $wgRequest->getVal( 'diff' );
1203 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
1204 $n = $wgTitle->getPrefixedText();
1206 if ( $wgTitle->isProtected() ) {
1207 $t = wfMsg( 'unprotectthispage' );
1208 $q = 'action=unprotect';
1210 $t = wfMsg( 'protectthispage' );
1211 $q = 'action=protect';
1213 $s = $this->makeKnownLink( $n, $t, $q );
1220 function watchThisPage()
1222 global $wgUser, $wgOut, $wgTitle;
1224 if ( $wgOut->isArticleRelated() ) {
1225 $n = $wgTitle->getPrefixedText();
1227 if ( $wgTitle->userIsWatching() ) {
1228 $t = wfMsg( 'unwatchthispage' );
1229 $q = 'action=unwatch';
1231 $t = wfMsg( 'watchthispage' );
1232 $q = 'action=watch';
1234 $s = $this->makeKnownLink( $n, $t, $q );
1236 $s = wfMsg( 'notanarticle' );
1241 function moveThisPage()
1243 global $wgTitle, $wgLang;
1245 if ( $wgTitle->userCanEdit() ) {
1246 $s = $this->makeKnownLink( $wgLang->specialPage( 'Movepage' ),
1247 wfMsg( 'movethispage' ), 'target=' . $wgTitle->getPrefixedURL() );
1248 } // no message if page is protected - would be redundant
1252 function historyLink()
1256 $s = $this->makeKnownLink( $wgTitle->getPrefixedText(),
1257 wfMsg( 'history' ), 'action=history' );
1261 function whatLinksHere()
1263 global $wgTitle, $wgLang;
1265 $s = $this->makeKnownLink( $wgLang->specialPage( 'Whatlinkshere' ),
1266 wfMsg( 'whatlinkshere' ), 'target=' . $wgTitle->getPrefixedURL() );
1270 function userContribsLink()
1272 global $wgTitle, $wgLang;
1274 $s = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
1275 wfMsg( 'contributions' ), 'target=' . $wgTitle->getPartialURL() );
1279 function emailUserLink()
1281 global $wgTitle, $wgLang;
1283 $s = $this->makeKnownLink( $wgLang->specialPage( 'Emailuser' ),
1284 wfMsg( 'emailuser' ), 'target=' . $wgTitle->getPartialURL() );
1288 function watchPageLinksLink()
1290 global $wgOut, $wgTitle, $wgLang;
1292 if ( ! $wgOut->isArticleRelated() ) {
1293 $s = '(' . wfMsg( 'notanarticle' ) . ')';
1295 $s = $this->makeKnownLink( $wgLang->specialPage(
1296 'Recentchangeslinked' ), wfMsg( 'recentchangeslinked' ),
1297 'target=' . $wgTitle->getPrefixedURL() );
1302 function otherLanguages()
1304 global $wgOut, $wgLang, $wgTitle, $wgUseNewInterlanguage;
1306 $a = $wgOut->getLanguageLinks();
1307 if ( 0 == count( $a ) ) {
1308 if ( !$wgUseNewInterlanguage ) return '';
1309 $ns = $wgLang->getNsIndex ( $wgTitle->getNamespace () ) ;
1310 if ( $ns != 0 AND $ns != 1 ) return '' ;
1312 $x = 'mode=addlink&xt='.$wgTitle->getDBkey() ;
1313 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1314 wfMsg( 'intl' ) , $x );
1317 if ( !$wgUseNewInterlanguage ) {
1318 $s = wfMsg( 'otherlanguages' ) . ': ';
1320 global $wgLanguageCode ;
1321 $x = 'mode=zoom&xt='.$wgTitle->getDBkey() ;
1322 $x .= '&xl='.$wgLanguageCode ;
1323 $s = $this->makeKnownLink( $wgLang->specialPage( 'Intl' ),
1324 wfMsg( 'otherlanguages' ) , $x ) . ': ' ;
1327 $s = wfMsg( 'otherlanguages' ) . ': ';
1329 if($wgLang->isRTL()) $s .= '<span dir="LTR">';
1330 foreach( $a as $l ) {
1331 if ( ! $first ) { $s .= ' | '; }
1334 $nt = Title
::newFromText( $l );
1335 $url = $nt->getFullURL();
1336 $text = $wgLang->getLanguageName( $nt->getInterwiki() );
1338 if ( '' == $text ) { $text = $l; }
1339 $style = $this->getExternalLinkAttributes( $l, $text );
1340 $s .= "<a href=\"{$url}\"{$style}>{$text}</a>";
1342 if($wgLang->isRTL()) $s .= '</span>';
1346 function bugReportsLink()
1348 $s = $this->makeKnownLink( wfMsg( 'bugreportspage' ),
1349 wfMsg( 'bugreports' ) );
1355 global $wgLinkCache;
1356 $t1 = Title
::newFromText( gmdate( 'F j' ) );
1357 $t2 = Title
::newFromText( gmdate( 'Y' ) );
1359 $wgLinkCache->suspend();
1360 $id = $t1->getArticleID();
1361 $wgLinkCache->resume();
1364 $s = $this->makeBrokenLink( $t1->getText() );
1366 $s = $this->makeKnownLink( $t1->getText() );
1370 $wgLinkCache->suspend();
1371 $id = $t2->getArticleID();
1372 $wgLinkCache->resume();
1375 $s .= $this->makeBrokenLink( $t2->getText() );
1377 $s .= $this->makeKnownLink( $t2->getText() );
1384 global $wgLang, $wgTitle, $wgLinkCache;
1386 $tns = $wgTitle->getNamespace();
1387 if ( -1 == $tns ) { return ''; }
1389 $pn = $wgTitle->getText();
1390 $tp = wfMsg( 'talkpage' );
1391 if ( Namespace::isTalk( $tns ) ) {
1392 $lns = Namespace::getSubject( $tns );
1395 $text = wfMsg('articlepage');
1398 $text = wfMsg('userpage');
1401 $text = wfMsg('wikipediapage');
1404 $text = wfMsg('imagepage');
1407 $text= wfMsg('articlepage');
1411 $lns = Namespace::getTalk( $tns );
1414 $n = $wgLang->getNsText( $lns );
1415 if ( '' == $n ) { $link = $pn; }
1416 else { $link = $n.':'.$pn; }
1418 $wgLinkCache->suspend();
1419 $s = $this->makeLink( $link, $text );
1420 $wgLinkCache->resume();
1425 function commentLink()
1427 global $wgLang, $wgTitle, $wgLinkCache;
1429 $tns = $wgTitle->getNamespace();
1430 if ( -1 == $tns ) { return ''; }
1432 $lns = ( Namespace::isTalk( $tns ) ) ?
$tns : Namespace::getTalk( $tns );
1434 # assert Namespace::isTalk( $lns )
1436 $n = $wgLang->getNsText( $lns );
1437 $pn = $wgTitle->getText();
1441 $wgLinkCache->suspend();
1442 $s = $this->makeKnownLink($link, wfMsg('postcomment'), 'action=edit§ion=new');
1443 $wgLinkCache->resume();
1448 # After all the page content is transformed into HTML, it makes
1449 # a final pass through here for things like table backgrounds.
1451 function transformContent( $text )
1456 # Note: This function MUST call getArticleID() on the link,
1457 # otherwise the cache won't get updated properly. See LINKCACHE.DOC.
1459 function makeLink( $title, $text = '', $query = '', $trail = '' ) {
1460 wfProfileIn( 'Skin::makeLink' );
1461 $nt = Title
::newFromText( $title );
1463 $result = $this->makeLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1465 wfDebug( 'Invalid title passed to Skin::makeLink(): "'.$title."\"\n" );
1466 $result = $text == "" ?
$title : $text;
1469 wfProfileOut( 'Skin::makeLink' );
1473 function makeKnownLink( $title, $text = '', $query = '', $trail = '', $prefix = '',$aprops = '') {
1474 $nt = Title
::newFromText( $title );
1476 return $this->makeKnownLinkObj( Title
::newFromText( $title ), $text, $query, $trail, $prefix , $aprops );
1478 wfDebug( 'Invalid title passed to Skin::makeKnownLink(): "'.$title."\"\n" );
1479 return $text == '' ?
$title : $text;
1483 function makeBrokenLink( $title, $text = '', $query = '', $trail = '' ) {
1484 $nt = Title
::newFromText( $title );
1486 return $this->makeBrokenLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1488 wfDebug( 'Invalid title passed to Skin::makeBrokenLink(): "'.$title."\"\n" );
1489 return $text == '' ?
$title : $text;
1493 function makeStubLink( $title, $text = '', $query = '', $trail = '' ) {
1494 $nt = Title
::newFromText( $title );
1496 return $this->makeStubLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1498 wfDebug( 'Invalid title passed to Skin::makeStubLink(): "'.$title."\"\n" );
1499 return $text == '' ?
$title : $text;
1503 # Pass a title object, not a title string
1504 function makeLinkObj( &$nt, $text= '', $query = '', $trail = '', $prefix = '' )
1506 global $wgOut, $wgUser;
1507 if ( $nt->isExternal() ) {
1508 $u = $nt->getFullURL();
1509 $link = $nt->getPrefixedURL();
1510 if ( '' == $text ) { $text = $nt->getPrefixedText(); }
1511 $style = $this->getExternalLinkAttributes( $link, $text, 'extiw' );
1514 if ( '' != $trail ) {
1515 if ( preg_match( '/^([a-z]+)(.*)$$/sD', $trail, $m ) ) {
1520 $retVal = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1521 } elseif ( 0 == $nt->getNamespace() && "" == $nt->getText() ) {
1522 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1523 } elseif ( ( -1 == $nt->getNamespace() ) ||
1524 ( Namespace::getImage() == $nt->getNamespace() ) ) {
1525 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1527 $aid = $nt->getArticleID() ;
1529 $retVal = $this->makeBrokenLinkObj( $nt, $text, $query, $trail, $prefix );
1531 $threshold = $wgUser->getOption('stubthreshold') ;
1532 if ( $threshold > 0 ) {
1533 $res = wfQuery ( "SELECT LENGTH(cur_text) AS x, cur_namespace, cur_is_redirect FROM cur WHERE cur_id='{$aid}'", DB_READ
) ;
1535 if ( wfNumRows( $res ) > 0 ) {
1536 $s = wfFetchObject( $res );
1538 if ( $s->cur_is_redirect
OR $s->cur_namespace
!= 0 ) {
1539 $size = $threshold*2 ; # Really big
1541 wfFreeResult( $res );
1543 $size = $threshold*2 ; # Really big
1548 if ( $size < $threshold ) {
1549 $retVal = $this->makeStubLinkObj( $nt, $text, $query, $trail, $prefix );
1551 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1558 # Pass a title object, not a title string
1559 function makeKnownLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' , $aprops = '')
1561 global $wgOut, $wgTitle, $wgInputEncoding;
1563 $fname = 'Skin::makeKnownLinkObj';
1564 wfProfileIn( $fname );
1566 $link = $nt->getPrefixedURL();
1568 if ( '' == $link ) {
1570 if ( '' == $text ) {
1571 $text = htmlspecialchars( $nt->getFragment() );
1574 $u = $nt->escapeLocalURL( $query );
1576 if ( '' != $nt->getFragment() ) {
1577 $anchor = urlencode( do_html_entity_decode( str_replace(' ', '_', $nt->getFragment()), ENT_COMPAT
, $wgInputEncoding ) );
1578 $replacearray = array(
1582 $u .= '#' . str_replace(array_keys($replacearray),array_values($replacearray),$anchor);
1584 if ( '' == $text ) {
1585 $text = htmlspecialchars( $nt->getPrefixedText() );
1587 $style = $this->getInternalLinkAttributesObj( $nt, $text );
1590 if ( '' != $trail ) {
1591 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1596 $r = "<a href=\"{$u}\"{$style}{$aprops}>{$prefix}{$text}{$inside}</a>{$trail}";
1597 wfProfileOut( $fname );
1601 # Pass a title object, not a title string
1602 function makeBrokenLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
1604 global $wgOut, $wgUser;
1606 $fname = 'Skin::makeBrokenLinkObj';
1607 wfProfileIn( $fname );
1609 if ( '' == $query ) {
1612 $q = 'action=edit&'.$query;
1614 $u = $nt->escapeLocalURL( $q );
1616 if ( '' == $text ) {
1617 $text = htmlspecialchars( $nt->getPrefixedText() );
1619 $style = $this->getInternalLinkAttributesObj( $nt, $text, "yes" );
1622 if ( '' != $trail ) {
1623 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1628 if ( $wgUser->getOption( 'highlightbroken' ) ) {
1629 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1631 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>?</a>{$trail}";
1634 wfProfileOut( $fname );
1638 # Pass a title object, not a title string
1639 function makeStubLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
1641 global $wgOut, $wgUser;
1643 $link = $nt->getPrefixedURL();
1645 $u = $nt->escapeLocalURL( $query );
1647 if ( '' == $text ) {
1648 $text = htmlspecialchars( $nt->getPrefixedText() );
1650 $style = $this->getInternalLinkAttributesObj( $nt, $text, 'stub' );
1653 if ( '' != $trail ) {
1654 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1659 if ( $wgUser->getOption( 'highlightbroken' ) ) {
1660 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1662 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>!</a>{$trail}";
1667 function makeSelfLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
1669 $u = $nt->escapeLocalURL( $query );
1670 if ( '' == $text ) {
1671 $text = htmlspecialchars( $nt->getPrefixedText() );
1674 if ( '' != $trail ) {
1675 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1680 return "<strong>{$prefix}{$text}{$inside}</strong>{$trail}";
1683 /* these are used extensively in SkinPHPTal, but also some other places */
1684 /*static*/ function makeSpecialUrl( $name, $urlaction='' ) {
1685 $title = Title
::makeTitle( NS_SPECIAL
, $name );
1686 $this->checkTitle($title, $name);
1687 return $title->getLocalURL( $urlaction );
1689 /*static*/ function makeTalkUrl ( $name, $urlaction='' ) {
1690 $title = Title
::newFromText( $name );
1691 $title = $title->getTalkPage();
1692 $this->checkTitle($title, $name);
1693 return $title->getLocalURL( $urlaction );
1695 /*static*/ function makeArticleUrl ( $name, $urlaction='' ) {
1696 $title = Title
::newFromText( $name );
1697 $title= $title->getSubjectPage();
1698 $this->checkTitle($title, $name);
1699 return $title->getLocalURL( $urlaction );
1701 /*static*/ function makeI18nUrl ( $name, $urlaction='' ) {
1702 $title = Title
::newFromText( wfMsg($name) );
1703 $this->checkTitle($title, $name);
1704 return $title->getLocalURL( $urlaction );
1706 /*static*/ function makeUrl ( $name, $urlaction='' ) {
1707 $title = Title
::newFromText( $name );
1708 $this->checkTitle($title, $name);
1709 return $title->getLocalURL( $urlaction );
1711 # this can be passed the NS number as defined in Language.php
1712 /*static*/ function makeNSUrl( $name, $urlaction='', $namespace=0 ) {
1713 $title = Title
::makeTitle( $namespace, $name );
1714 $this->checkTitle($title, $name);
1715 return $title->getLocalURL( $urlaction );
1718 /* these return an array with the 'href' and boolean 'exists' */
1719 /*static*/ function makeUrlDetails ( $name, $urlaction='' ) {
1720 $title = Title
::newFromText( $name );
1721 $this->checkTitle($title, $name);
1723 'href' => $title->getLocalURL( $urlaction ),
1724 'exists' => $title->getArticleID() != 0?
true:false
1727 /*static*/ function makeTalkUrlDetails ( $name, $urlaction='' ) {
1728 $title = Title
::newFromText( $name );
1729 $title = $title->getTalkPage();
1730 $this->checkTitle($title, $name);
1732 'href' => $title->getLocalURL( $urlaction ),
1733 'exists' => $title->getArticleID() != 0?
true:false
1736 /*static*/ function makeArticleUrlDetails ( $name, $urlaction='' ) {
1737 $title = Title
::newFromText( $name );
1738 $title= $title->getSubjectPage();
1739 $this->checkTitle($title, $name);
1741 'href' => $title->getLocalURL( $urlaction ),
1742 'exists' => $title->getArticleID() != 0?
true:false
1745 /*static*/ function makeI18nUrlDetails ( $name, $urlaction='' ) {
1746 $title = Title
::newFromText( wfMsg($name) );
1747 $this->checkTitle($title, $name);
1749 'href' => $title->getLocalURL( $urlaction ),
1750 'exists' => $title->getArticleID() != 0?
true:false
1754 # make sure we have some title to operate on
1755 /*static*/ function checkTitle ( &$title, &$name ) {
1756 if(!is_object($title)) {
1757 $title = Title
::newFromText( $name );
1758 if(!is_object($title)) {
1759 $title = Title
::newFromText( '<error: link target missing>' );
1764 function fnamePart( $url )
1766 $basename = strrchr( $url, '/' );
1767 if ( false === $basename ) { $basename = $url; }
1768 else { $basename = substr( $basename, 1 ); }
1769 return wfEscapeHTML( $basename );
1772 function makeImage( $url, $alt = '' )
1776 if ( '' == $alt ) { $alt = $this->fnamePart( $url ); }
1777 $s = '<img src="'.$url.'" alt="'.$alt.'" />';
1781 function makeImageLink( $name, $url, $alt = '' ) {
1782 $nt = Title
::makeTitle( Namespace::getImage(), $name );
1783 return $this->makeImageLinkObj( $nt, $alt );
1786 function makeImageLinkObj( $nt, $alt = '' ) {
1787 global $wgLang, $wgUseImageResize;
1788 $img = Image
::newFromTitle( $nt );
1789 $url = $img->getURL();
1792 $prefix = $postfix = '';
1794 if ( $wgUseImageResize ) {
1795 # Check if the alt text is of the form "options|alt text"
1797 # * thumbnail make a thumbnail with enlarge-icon and caption, alignment depends on lang
1798 # * left no resizing, just left align. label is used for alt= only
1799 # * right same, but right aligned
1800 # * none same, but not aligned
1801 # * ___px scale to ___ pixels width, no aligning. e.g. use in taxobox
1802 # * center center the image
1803 # * framed Keep original image size, no magnify-button.
1805 $part = explode( '|', $alt);
1807 $mwThumb =& MagicWord
::get( MAG_IMG_THUMBNAIL
);
1808 $mwLeft =& MagicWord
::get( MAG_IMG_LEFT
);
1809 $mwRight =& MagicWord
::get( MAG_IMG_RIGHT
);
1810 $mwNone =& MagicWord
::get( MAG_IMG_NONE
);
1811 $mwWidth =& MagicWord
::get( MAG_IMG_WIDTH
);
1812 $mwCenter =& MagicWord
::get( MAG_IMG_CENTER
);
1813 $mwFramed =& MagicWord
::get( MAG_IMG_FRAMED
);
1814 $alt = $part[count($part)-1];
1816 $height = $framed = $thumb = false;
1818 foreach( $part as $key => $val ) {
1819 if ( ! is_null( $mwThumb->matchVariableStartToEnd($val) ) ) {
1821 } elseif ( ! is_null( $mwRight->matchVariableStartToEnd($val) ) ) {
1822 # remember to set an alignment, don't render immediately
1824 } elseif ( ! is_null( $mwLeft->matchVariableStartToEnd($val) ) ) {
1825 # remember to set an alignment, don't render immediately
1827 } elseif ( ! is_null( $mwCenter->matchVariableStartToEnd($val) ) ) {
1828 # remember to set an alignment, don't render immediately
1830 } elseif ( ! is_null( $mwNone->matchVariableStartToEnd($val) ) ) {
1831 # remember to set an alignment, don't render immediately
1833 } elseif ( ! is_null( $match = $mwWidth->matchVariableStartToEnd($val) ) ) {
1834 # $match is the image width in pixels
1835 if ( preg_match( '/^([0-9]*)x([0-9]*)$/', $match, $m ) ) {
1836 $width = intval( $m[1] );
1837 $height = intval( $m[2] );
1839 $width = intval($match);
1841 } elseif ( ! is_null( $mwFramed->matchVariableStartToEnd($val) ) ) {
1845 if ( 'center' == $align )
1847 $prefix = '<span style="text-align: center">';
1848 $postfix = '</span>';
1852 if ( $thumb ||
$framed ) {
1854 # Create a thumbnail. Alignment depends on language
1855 # writing direction, # right aligned for left-to-right-
1856 # languages ("Western languages"), left-aligned
1857 # for right-to-left-languages ("Semitic languages")
1859 # If thumbnail width has not been provided, it is set
1860 # here to 180 pixels
1861 if ( $align == '' ) {
1862 $align = $wgLang->isRTL() ?
'left' : 'right';
1864 if ( ! isset($width) ) {
1867 return $prefix.$this->makeThumbLinkObj( $img, $alt, $align, $width, $height, $framed ).$postfix;
1869 } elseif ( isset($width) ) {
1871 # Create a resized image, without the additional thumbnail
1874 if ( ( ! $height === false )
1875 && ( $img->getHeight() * $width / $img->getWidth() > $height ) ) {
1876 print "height=$height<br>\nimg->getHeight() = ".$img->getHeight()."<br>\n";
1877 print 'rescaling by factor '. $height / $img->getHeight() . "<br>\n";
1878 $width = $img->getWidth() * $height / $img->getHeight();
1880 $url = $img->createThumb( $width );
1882 } # endif $wgUseImageResize
1884 if ( empty( $alt ) ) {
1885 $alt = preg_replace( '/\.(.+?)^/', '', $img->getName() );
1887 $alt = htmlspecialchars( $alt );
1889 $u = $nt->escapeLocalURL();
1892 $s = str_replace( "$1", $img->getName(), wfMsg('missingimage') );
1893 $s .= "<br>{$alt}<br>{$url}<br>\n";
1895 $s = '<a href="'.$u.'" class="image" title="'.$alt.'">' .
1896 '<img src="'.$url.'" alt="'.$alt.'" /></a>';
1898 if ( '' != $align ) {
1899 $s = "<div class=\"float{$align}\"><span>{$s}</span></div>";
1901 return str_replace("\n", ' ',$prefix.$s.$postfix);
1905 function makeThumbLinkObj( $img, $label = '', $align = 'right', $boxwidth = 180, $boxheight=false, $framed=false ) {
1906 global $wgStylePath, $wgLang;
1907 # $image = Title::makeTitle( Namespace::getImage(), $name );
1908 $url = $img->getURL();
1910 #$label = htmlspecialchars( $label );
1911 $alt = preg_replace( '/<[^>]*>/', '', $label);
1912 $alt = htmlspecialchars( $alt );
1914 if ( $img->exists() )
1916 $width = $img->getWidth();
1917 $height = $img->getHeight();
1919 $width = $height = 200;
1923 // Use image dimensions, don't scale
1925 $oboxwidth = $boxwidth +
2;
1926 $boxheight = $height;
1929 $h = intval( $height/($width/$boxwidth) );
1930 $oboxwidth = $boxwidth +
2;
1931 if ( ( ! $boxheight === false ) && ( $h > $boxheight ) )
1933 $boxwidth *= $boxheight/$h;
1937 $thumbUrl = $img->createThumb( $boxwidth );
1940 $u = $img->getEscapeLocalURL();
1942 $more = htmlspecialchars( wfMsg( 'thumbnail-more' ) );
1943 $magnifyalign = $wgLang->isRTL() ?
'left' : 'right';
1944 $textalign = $wgLang->isRTL() ?
' style="text-align:right"' : '';
1946 $s = "<div class=\"thumb t{$align}\"><div style=\"width:{$oboxwidth}px;\">";
1947 if ( $thumbUrl == '' ) {
1948 $s .= str_replace( "$1", $img->getName(), wfMsg('missingimage') );
1951 $s .= '<a href="'.$u.'" class="internal" title="'.$alt.'">'.
1952 '<img src="'.$thumbUrl.'" alt="'.$alt.'" ' .
1953 'width="'.$boxwidth.'" height="'.$boxheight.'" /></a>';
1957 $zoomicon = '<div class="magnify" style="float:'.$magnifyalign.'">'.
1958 '<a href="'.$u.'" class="internal" title="'.$more.'">'.
1959 '<img src="'.$wgStylePath.'/images/magnify-clip.png" ' .
1960 'width="15" height="11" alt="'.$more.'" /></a></div>';
1963 $s .= ' <div class="thumbcaption" '.$textalign.'>'.$zoomicon.$label."</div></div></div>";
1964 return str_replace("\n", ' ', $s);
1967 function makeMediaLink( $name, $url, $alt = "" ) {
1968 $nt = Title
::makeTitle( Namespace::getMedia(), $name );
1969 return $this->makeMediaLinkObj( $nt, $alt );
1972 function makeMediaLinkObj( $nt, $alt = "" )
1974 if ( ! isset( $nt ) )
1976 ### HOTFIX. Instead of breaking, return empry string.
1979 $name = $nt->getDBKey();
1980 $url = Image
::wfImageUrl( $name );
1981 if ( empty( $alt ) ) {
1982 $alt = preg_replace( '/\.(.+?)^/', '', $name );
1985 $u = htmlspecialchars( $url );
1986 $s = "<a href=\"{$u}\" class='internal' title=\"{$alt}\">{$alt}</a>";
1991 function specialLink( $name, $key = "" )
1995 if ( '' == $key ) { $key = strtolower( $name ); }
1996 $pn = $wgLang->ucfirst( $name );
1997 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
2001 function makeExternalLink( $url, $text, $escape = true ) {
2002 $style = $this->getExternalLinkAttributes( $url, $text );
2003 $url = htmlspecialchars( $url );
2005 $text = htmlspecialchars( $text );
2007 return '<a href="'.$url.'"'.$style.'>'.$text.'</a>';
2010 # Called by history lists and recent changes
2013 # Returns text for the start of the tabular part of RC
2014 function beginRecentChangesList()
2016 $this->rc_cache
= array() ;
2017 $this->rcMoveIndex
= 0;
2018 $this->rcCacheIndex
= 0 ;
2019 $this->lastdate
= '';
2020 $this->rclistOpen
= false;
2024 function beginImageHistoryList()
2026 $s = "\n<h2>" . wfMsg( 'imghistory' ) . "</h2>\n" .
2027 "<p>" . wfMsg( 'imghistlegend' ) . "</p>\n".'<ul class="special">';
2031 # Returns text for the end of RC
2032 # If enhanced RC is in use, returns pretty much all the text
2033 function endRecentChangesList()
2035 $s = $this->recentChangesBlock() ;
2036 if( $this->rclistOpen
) {
2042 # Enhanced RC ungrouped line
2043 function recentChangesBlockLine ( $rcObj )
2045 global $wgStylePath, $wgLang ;
2047 # Get rc_xxxx variables
2048 extract( $rcObj->mAttribs
) ;
2049 $curIdEq = 'curid='.$rc_cur_id;
2054 $r .= '<img src="'.$wgStylePath.'/images/Arr_.png" width="12" height="12" border="0" />' ;
2057 if ( $rc_type == RC_MOVE
) {
2058 $r .= ' ';
2060 # M & N (minor & new)
2061 $M = wfMsg( 'minoreditletter' );
2062 $N = wfMsg( 'newpageletter' );
2064 if ( $rc_type == RC_NEW
) {
2077 $r .= ' '.$rcObj->timestamp
.' ' ;
2081 $link = $rcObj->link
;
2082 if ( $rcObj->watched
) $link = '<strong>'.$link.'</strong>' ;
2087 $r .= $rcObj->curlink
;
2091 $r .= $this->makeKnownLinkObj( $rcObj->getTitle(), wfMsg( 'hist' ), $curIdEq.'&action=history' );
2094 $r .= ') . . '.$rcObj->userlink
;
2095 $r .= $rcObj->usertalklink
;
2098 if ( $rc_comment != '' && $rc_type != RC_MOVE
) {
2099 $rc_comment=$this->formatComment($rc_comment);
2100 $r .= $wgLang->emphasize( ' ('.$rc_comment.')' );
2108 function recentChangesBlockGroup ( $block )
2110 global $wgStylePath, $wgLang ;
2113 $M = wfMsg( 'minoreditletter' );
2114 $N = wfMsg( 'newpageletter' );
2116 # Collate list of users
2118 $userlinks = array () ;
2119 foreach ( $block AS $rcObj ) {
2120 $oldid = $rcObj->mAttribs
['rc_last_oldid'];
2121 if ( $rcObj->mAttribs
['rc_new'] ) $isnew = true ;
2122 $u = $rcObj->userlink
;
2123 if ( !isset ( $userlinks[$u] ) ) $userlinks[$u] = 0 ;
2127 # Sort the list and convert to text
2128 krsort ( $userlinks ) ;
2129 asort ( $userlinks ) ;
2131 foreach ( $userlinks as $userlink => $count) {
2133 if ( $count > 1 ) $text .= " ({$count}×)" ;
2134 array_push ( $users , $text ) ;
2136 $users = ' <font size="-1">['.implode('; ',$users).']</font>' ;
2139 $rci = 'RCI'.$this->rcCacheIndex
;
2140 $rcl = 'RCL'.$this->rcCacheIndex
;
2141 $rcm = 'RCM'.$this->rcCacheIndex
;
2142 $toggleLink = "javascript:toggleVisibility('$rci','$rcm','$rcl')" ;
2143 $arrowdir = $wgLang->isRTL() ?
'l' : 'r';
2144 $tl = '<span id="'.$rcm.'"><a href="'.$toggleLink.'"><img src="'.$wgStylePath.'/images/Arr_'.$arrowdir.'.png" width="12" height="12" /></a></span>' ;
2145 $tl .= '<span id="'.$rcl.'" style="display:none"><a href="'.$toggleLink.'"><img src="'.$wgStylePath.'/images/Arr_d.png" width="12" height="12" /></a></span>' ;
2151 if ( $isnew ) $r .= $N ;
2152 else $r .= ' ' ;
2153 $r .= ' ' ; # Minor
2156 $r .= ' '.$block[0]->timestamp
.' ' ;
2160 $link = $block[0]->link
;
2161 if ( $block[0]->watched
) $link = '<strong>'.$link.'</strong>' ;
2164 $curIdEq = 'curid=' . $block[0]->mAttribs
['rc_cur_id'];
2165 if ( $block[0]->mAttribs
['rc_type'] != RC_LOG
) {
2167 $r .= ' ('.count($block).' ' ;
2168 if ( $isnew ) $r .= wfMsg('changes');
2169 else $r .= $this->makeKnownLinkObj( $block[0]->getTitle() , wfMsg('changes') ,
2170 $curIdEq.'&diff=0&oldid='.$oldid ) ;
2174 $r .= $this->makeKnownLinkObj( $block[0]->getTitle(), wfMsg( 'history' ), $curIdEq.'&action=history' );
2182 $r .= '<div id="'.$rci.'" style="display:none">' ;
2183 foreach ( $block AS $rcObj ) {
2184 # Get rc_xxxx variables
2185 extract( $rcObj->mAttribs
);
2187 $r .= '<img src="'.$wgStylePath.'/images/Arr_.png" width="12" height="12" />';
2188 $r .= '<tt> ' ;
2189 if ( $rc_new ) $r .= $N ;
2190 else $r .= ' ' ;
2191 if ( $rc_minor ) $r .= $M ;
2192 else $r .= ' ' ;
2196 if ( $rc_last_oldid != 0 ) {
2197 $o = 'oldid='.$rc_last_oldid ;
2199 if ( $rc_type == RC_LOG
) {
2200 $link = $rcObj->timestamp
;
2202 $link = $this->makeKnownLinkObj( $rcObj->getTitle(), $rcObj->timestamp
, "{$curIdEq}&$o" ) ;
2204 $link = '<tt>'.$link.'</tt>' ;
2208 $r .= $rcObj->curlink
;
2210 $r .= $rcObj->lastlink
;
2211 $r .= ') . . '.$rcObj->userlink
;
2212 $r .= $rcObj->usertalklink
;
2213 if ( $rc_comment != '' ) {
2214 $rc_comment=$this->formatComment($rc_comment);
2215 $r .= $wgLang->emphasize( ' ('.$rc_comment.')' ) ;
2221 $this->rcCacheIndex++
;
2225 # If enhanced RC is in use, this function takes the previously cached
2226 # RC lines, arranges them, and outputs the HTML
2227 function recentChangesBlock ()
2229 global $wgStylePath ;
2230 if ( count ( $this->rc_cache
) == 0 ) return '' ;
2232 foreach ( $this->rc_cache
AS $secureName => $block ) {
2233 if ( count ( $block ) < 2 ) {
2234 $blockOut .= $this->recentChangesBlockLine ( array_shift ( $block ) ) ;
2236 $blockOut .= $this->recentChangesBlockGroup ( $block ) ;
2240 return '<div>'.$blockOut.'</div>' ;
2243 # Called in a loop over all displayed RC entries
2244 # Either returns the line, or caches it for later use
2245 function recentChangesLine( &$rc, $watched = false )
2248 $usenew = $wgUser->getOption( 'usenewrc' );
2250 $line = $this->recentChangesLineNew ( $rc, $watched ) ;
2252 $line = $this->recentChangesLineOld ( $rc, $watched ) ;
2256 function recentChangesLineOld( &$rc, $watched = false )
2258 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds;
2260 # Extract DB fields into local scope
2261 extract( $rc->mAttribs
);
2262 $curIdEq = 'curid=' . $rc_cur_id;
2264 # Make date header if necessary
2265 $date = $wgLang->date( $rc_timestamp, true);
2267 if ( $date != $this->lastdate
) {
2268 if ( '' != $this->lastdate
) { $s .= "</ul>\n"; }
2269 $s .= "<h4>{$date}</h4>\n<ul class='special'>";
2270 $this->lastdate
= $date;
2271 $this->rclistOpen
= true;
2275 if ( $rc_type == RC_MOVE
) {
2277 $s .= '(' . wfMsg( 'diff' ) . ') (';
2279 $s .= $this->makeKnownLinkObj( $rc->getMovedToTitle(), wfMsg( 'hist' ), 'action=history' ) .
2282 # "[[x]] moved to [[y]]"
2284 $s .= wfMsg( '1movedto2', $this->makeKnownLinkObj( $rc->getTitle(), '', 'redirect=no' ),
2285 $this->makeKnownLinkObj( $rc->getMovedToTitle(), '' ) );
2289 if ( $rc_type == RC_NEW ||
$rc_type == RC_LOG
) {
2290 $diffLink = wfMsg( 'diff' );
2292 $diffLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'diff' ),
2293 $curIdEq.'&diff='.$rc_this_oldid.'&oldid='.$rc_last_oldid ,'' ,'' , ' tabindex="'.$rc->counter
.'"');
2295 $s .= '('.$diffLink.') (';
2298 $s .= $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'hist' ), $curIdEq.'&action=history' );
2301 # M and N (minor and new)
2302 $M = wfMsg( 'minoreditletter' );
2303 $N = wfMsg( 'newpageletter' );
2304 if ( $rc_minor ) { $s .= ' <strong>'.$M.'</strong>'; }
2305 if ( $rc_type == RC_NEW
) { $s .= '<strong>'.$N.'</strong>'; }
2308 $articleLink = $this->makeKnownLinkObj( $rc->getTitle(), '' );
2311 $articleLink = '<strong>'.$articleLink.'</strong>';
2313 $s .= ' '.$articleLink;
2318 $s .= '; ' . $wgLang->time( $rc_timestamp, true, $wgRCSeconds ) . ' . . ';
2320 # User link (or contributions for unregistered users)
2321 if ( 0 == $rc_user ) {
2322 $userLink = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
2323 $rc_user_text, 'target=' . $rc_user_text );
2325 $userLink = $this->makeLink( $wgLang->getNsText( NS_USER
) . ':'.$rc_user_text, $rc_user_text );
2330 $talkname=$wgLang->getNsText(NS_TALK
); # use the shorter name
2331 global $wgDisableAnonTalk;
2332 if( 0 == $rc_user && $wgDisableAnonTalk ) {
2335 $utns=$wgLang->getNsText(NS_USER_TALK
);
2336 $userTalkLink= $this->makeLink($utns . ':'.$rc_user_text, $talkname );
2340 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2341 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2342 'Blockip' ), wfMsg( 'blocklink' ), 'ip='.$rc_user_text );
2346 if($userTalkLink) $userTalkLink .= ' | ';
2347 $userTalkLink .= $blockLink;
2349 if($userTalkLink) $s.=' ('.$userTalkLink.')';
2352 if ( '' != $rc_comment && '*' != $rc_comment && $rc_type != RC_MOVE
) {
2353 $rc_comment=$this->formatComment($rc_comment);
2354 $s .= $wgLang->emphasize(' (' . $rc_comment . ')');
2361 # function recentChangesLineNew( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched = false, $oldid = 0 , $diffid = 0 )
2362 function recentChangesLineNew( &$baseRC, $watched = false )
2364 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds;
2366 # Create a specialised object
2367 $rc = RCCacheEntry
::newFromParent( $baseRC ) ;
2369 # Extract fields from DB into the function scope (rc_xxxx variables)
2370 extract( $rc->mAttribs
);
2371 $curIdEq = 'curid=' . $rc_cur_id;
2373 # If it's a new day, add the headline and flush the cache
2374 $date = $wgLang->date( $rc_timestamp, true);
2376 if ( $date != $this->lastdate
) {
2377 # Process current cache
2378 $ret = $this->recentChangesBlock () ;
2379 $this->rc_cache
= array() ;
2380 $ret .= "<h4>{$date}</h4>\n";
2381 $this->lastdate
= $date;
2385 if ( $rc_type == RC_MOVE
) {
2386 $clink = $this->makeKnownLinkObj( $rc->getTitle(), '', 'redirect=no' );
2387 $clink .= ' ' . wfMsg('movedto') . ' ';
2388 $clink .= $this->makeKnownLinkObj( $rc->getMovedToTitle(), '' );
2390 $clink = $this->makeKnownLinkObj( $rc->getTitle(), '' ) ;
2393 $time = $wgLang->time( $rc_timestamp, true, $wgRCSeconds );
2394 $rc->watched
= $watched ;
2395 $rc->link
= $clink ;
2396 $rc->timestamp
= $time;
2399 if ( ( $rc_type == RC_NEW
&& $rc_this_oldid == 0 ) ||
$rc_type == RC_LOG ||
$rc_type == RC_MOVE
) {
2400 $curLink = wfMsg( 'cur' );
2402 $curLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'cur' ),
2403 $curIdEq.'&diff=0&oldid='.$rc_this_oldid ,'' ,'' , ' tabindex="'.$baseRC->counter
.'"' );
2407 $titleObj = $rc->getTitle();
2408 if ( $rc_last_oldid == 0 ||
$rc_type == RC_LOG ||
$rc_type == RC_MOVE
) {
2409 $lastLink = wfMsg( 'last' );
2411 $lastLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'last' ),
2412 $curIdEq.'&diff='.$rc_this_oldid.'&oldid='.$rc_last_oldid );
2415 # Make user link (or user contributions for unregistered users)
2416 if ( 0 == $rc_user ) {
2417 $userLink = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
2418 $rc_user_text, 'target=' . $rc_user_text );
2420 $userLink = $this->makeLink( $wgLang->getNsText(
2421 Namespace::getUser() ) . ':'.$rc_user_text, $rc_user_text );
2424 $rc->userlink
= $userLink ;
2425 $rc->lastlink
= $lastLink ;
2426 $rc->curlink
= $curLink ;
2428 # Make user talk link
2429 $utns=$wgLang->getNsText(NS_USER_TALK
);
2430 $talkname=$wgLang->getNsText(NS_TALK
); # use the shorter name
2431 $userTalkLink= $this->makeLink($utns . ':'.$rc_user_text, $talkname );
2433 global $wgDisableAnonTalk;
2434 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2435 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2436 'Blockip' ), wfMsg( 'blocklink' ), 'ip='.$rc_user_text );
2437 if( $wgDisableAnonTalk )
2438 $rc->usertalklink
= ' ('.$blockLink.')';
2440 $rc->usertalklink
= ' ('.$userTalkLink.' | '.$blockLink.')';
2442 if( $wgDisableAnonTalk && ($rc_user == 0) )
2443 $rc->usertalklink
= '';
2445 $rc->usertalklink
= ' ('.$userTalkLink.')';
2448 # Put accumulated information into the cache, for later display
2449 # Page moves go on their own line
2450 $title = $rc->getTitle();
2451 $secureName = $title->getPrefixedDBkey();
2452 if ( $rc_type == RC_MOVE
) {
2453 # Use an @ character to prevent collision with page names
2454 $this->rc_cache
['@@' . ($this->rcMoveIndex++
)] = array($rc);
2456 if ( !isset ( $this->rc_cache
[$secureName] ) ) $this->rc_cache
[$secureName] = array() ;
2457 array_push ( $this->rc_cache
[$secureName] , $rc ) ;
2462 function endImageHistoryList()
2468 /* This function is called by all recent changes variants, by the page history,
2469 and by the user contributions list. It is responsible for formatting edit
2470 comments. It escapes any HTML in the comment, but adds some CSS to format
2471 auto-generated comments (from section editing) and formats [[wikilinks]].
2472 Main author: Erik Möller (moeller@scireview.de)
2474 function formatComment($comment)
2477 $comment=wfEscapeHTML($comment);
2479 # The pattern for autogen comments is / * foo * /, which makes for
2481 # We look for all comments, match any text before and after the comment,
2482 # add a separator where needed and format the comment itself with CSS
2483 while (preg_match('/(.*)\/\*\s*(.*?)\s*\*\/(.*)/', $comment,$match)) {
2488 if($pre) { $auto = $sep.' '.$auto; }
2489 if($post) { $auto .= ' '.$sep; }
2490 $auto='<span class="autocomment">'.$auto.'</span>';
2491 $comment=$pre.$auto.$post;
2494 # format regular and media links - all other wiki formatting
2496 while(preg_match('/\[\[(.*?)(\|(.*?))*\]\]/',$comment,$match)) {
2498 $medians = $wgLang->getNsText(Namespace::getMedia()).':';
2500 if(preg_match('/^'.$medians.'/i',$match[1])) {
2501 $func='makeMediaLink';
2503 # Handle link renaming [[foo|text]] will show link as "text"
2504 if(isset($match[3]) ) {
2506 preg_replace('/\[\[(.*?)\]\]/',
2507 $this->$func($match[1],$match[3]),$comment,1);
2510 preg_replace('/\[\[(.*?)\]\]/',
2511 $this->$func($match[1],$match[1]),$comment,1);
2519 function imageHistoryLine( $iscur, $timestamp, $img, $user, $usertext, $size, $description )
2521 global $wgUser, $wgLang, $wgTitle;
2523 $datetime = $wgLang->timeanddate( $timestamp, true );
2524 $del = wfMsg( 'deleteimg' );
2525 $cur = wfMsg( 'cur' );
2528 $url = Image
::wfImageUrl( $img );
2530 if ( $wgUser->isSysop() ) {
2531 $link = $wgTitle->escapeLocalURL( 'image=' . $wgTitle->getPartialURL() .
2533 $style = $this->getInternalLinkAttributes( $link, $del );
2535 $dlink = '<a href="'.$link.'"'.$style.'>'.$del.'</a>';
2540 $url = wfEscapeHTML( wfImageArchiveUrl( $img ) );
2541 if( $wgUser->getID() != 0 ) {
2542 $rlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2543 wfMsg( 'revertimg' ), 'action=revert&oldimage=' .
2544 urlencode( $img ) );
2545 $dlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2546 $del, 'action=delete&oldimage=' . urlencode( $img ) );
2548 # Having live active links for non-logged in users
2549 # means that bots and spiders crawling our site can
2550 # inadvertently change content. Baaaad idea.
2551 $rlink = wfMsg( 'revertimg' );
2556 $userlink = $usertext;
2558 $userlink = $this->makeLink( $wgLang->getNsText( Namespace::getUser() ) .
2559 ':'.$usertext, $usertext );
2561 $nbytes = wfMsg( 'nbytes', $size );
2562 $style = $this->getInternalLinkAttributes( $url, $datetime );
2564 $s = "<li> ({$dlink}) ({$rlink}) <a href=\"{$url}\"{$style}>{$datetime}</a>"
2565 . " . . {$userlink} ({$nbytes})";
2567 if ( '' != $description && '*' != $description ) {
2568 $sk=$wgUser->getSkin();
2569 $s .= $wgLang->emphasize(' (' . $sk->formatComment($description) . ')');
2575 function tocIndent($level) {
2576 return str_repeat( '<div class="tocindent">'."\n", $level>0 ?
$level : 0 );
2579 function tocUnindent($level) {
2580 return str_repeat( "</div>\n", $level>0 ?
$level : 0 );
2583 # parameter level defines if we are on an indentation level
2584 function tocLine( $anchor, $tocline, $level ) {
2585 $link = '<a href="#'.$anchor.'">'.$tocline.'</a><br />';
2589 return '<div class="tocline">'.$link."</div>\n";
2594 function tocTable($toc) {
2595 # note to CSS fanatics: putting this in a div does not work -- div won't auto-expand
2596 # try min-width & co when somebody gets a chance
2597 $hideline = ' <script type="text/javascript">showTocToggle("' . addslashes( wfMsg('showtoc') ) . '","' . addslashes( wfMsg('hidetoc') ) . '")</script>';
2599 '<table border="0" id="toc"><tr id="toctitle"><td align="center">'."\n".
2600 '<b>'.wfMsg('toc').'</b>' .
2602 '</td></tr><tr id="tocinside"><td>'."\n".
2603 $toc."</td></tr></table>\n";
2606 # These two do not check for permissions: check $wgTitle->userCanEdit before calling them
2607 function editSectionScript( $section, $head ) {
2608 global $wgTitle, $wgRequest;
2609 if( $wgRequest->getInt( 'oldid' ) && ( $wgRequest->getVal( 'diff' ) != '0' ) ) {
2612 $url = $wgTitle->escapeLocalURL( 'action=edit§ion='.$section );
2613 return '<span oncontextmenu=\'document.location="'.$url.'";return false;\'>'.$head.'</span>';
2616 function editSectionLink( $section ) {
2618 global $wgTitle, $wgUser, $wgLang;
2620 if( $wgRequest->getInt( 'oldid' ) && ( $wgRequest->getVal( 'diff' ) != '0' ) ) {
2621 # Section edit links would be out of sync on an old page.
2622 # But, if we're diffing to the current page, they'll be
2627 $editurl = '§ion='.$section;
2628 $url = $this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg('editsection'),'action=edit'.$editurl);
2630 if( $wgLang->isRTL() ) {
2632 $nearside = 'right';
2637 return "<div class=\"editsection\" style=\"float:$farside;margin-$nearside:5px;\">[".$url."]</div>";
2641 // This function is called by EditPage.php and shows a bulletin board style
2642 // toolbar for common editing functions. It can be disabled in the user preferences.
2643 // The necsesary JavaScript code can be found in style/wikibits.js.
2644 function getEditToolbar() {
2645 global $wgStylePath, $wgLang, $wgMimeType;
2647 // toolarray an array of arrays which each include the filename of
2648 // the button image (without path), the opening tag, the closing tag,
2649 // and optionally a sample text that is inserted between the two when no
2650 // selection is highlighted.
2651 // The tip text is shown when the user moves the mouse over the button.
2653 // Already here are accesskeys (key), which are not used yet until someone
2654 // can figure out a way to make them work in IE. However, we should make
2655 // sure these keys are not defined on the edit page.
2657 array( 'image'=>'button_bold.png',
2660 'sample'=>wfMsg('bold_sample'),
2661 'tip'=>wfMsg('bold_tip'),
2664 array( "image"=>"button_italic.png",
2667 "sample"=>wfMsg("italic_sample"),
2668 "tip"=>wfMsg("italic_tip"),
2671 array( "image"=>"button_link.png",
2674 "sample"=>wfMsg("link_sample"),
2675 "tip"=>wfMsg("link_tip"),
2678 array( "image"=>"button_extlink.png",
2681 "sample"=>wfMsg("extlink_sample"),
2682 "tip"=>wfMsg("extlink_tip"),
2685 array( "image"=>"button_headline.png",
2688 "sample"=>wfMsg("headline_sample"),
2689 "tip"=>wfMsg("headline_tip"),
2692 array( "image"=>"button_image.png",
2693 "open"=>"[[".$wgLang->getNsText(NS_IMAGE
).":",
2695 "sample"=>wfMsg("image_sample"),
2696 "tip"=>wfMsg("image_tip"),
2699 array( "image"=>"button_media.png",
2700 "open"=>"[[".$wgLang->getNsText(NS_MEDIA
).":",
2702 "sample"=>wfMsg("media_sample"),
2703 "tip"=>wfMsg("media_tip"),
2706 array( "image"=>"button_math.png",
2707 "open"=>"\\<math\\>",
2708 "close"=>"\\</math\\>",
2709 "sample"=>wfMsg("math_sample"),
2710 "tip"=>wfMsg("math_tip"),
2713 array( "image"=>"button_nowiki.png",
2714 "open"=>"\\<nowiki\\>",
2715 "close"=>"\\</nowiki\\>",
2716 "sample"=>wfMsg("nowiki_sample"),
2717 "tip"=>wfMsg("nowiki_tip"),
2720 array( "image"=>"button_sig.png",
2724 "tip"=>wfMsg("sig_tip"),
2727 array( "image"=>"button_hr.png",
2728 "open"=>"\\n----\\n",
2731 "tip"=>wfMsg("hr_tip"),
2735 $toolbar ="<script type='text/javascript'>\n/*<![CDATA[*/\n";
2737 $toolbar.="document.writeln(\"<div id='toolbar'>\");\n";
2738 foreach($toolarray as $tool) {
2740 $image=$wgStylePath.'/images/'.$tool['image'];
2741 $open=$tool['open'];
2742 $close=$tool['close'];
2743 $sample = addslashes( $tool['sample'] );
2745 // Note that we use the tip both for the ALT tag and the TITLE tag of the image.
2746 // Older browsers show a "speedtip" type message only for ALT.
2747 // Ideally these should be different, realistically they
2748 // probably don't need to be.
2749 $tip = addslashes( $tool['tip'] );
2751 #$key = $tool["key"];
2753 $toolbar.="addButton('$image','$tip','$open','$close','$sample');\n";
2756 $toolbar.="addInfobox('" . addslashes( wfMsg( "infobox" ) ) . "','" . addslashes(wfMsg("infobox_alert")) . "');\n";
2757 $toolbar.="document.writeln(\"</div>\");\n";
2759 $toolbar.="/*]]>*/\n</script>";