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;
1087 require_once('SpecialPage.php');
1089 $pages = SpecialPage
::getPages();
1091 foreach ( $pages[''] as $name => $page ) {
1092 $a[$name] = $page->getDescription();
1094 if ( $wgUser->isSysop() )
1096 foreach ( $pages['sysop'] as $name => $page ) {
1097 $a[$name] = $page->getDescription();
1100 if ( $wgUser->isDeveloper() )
1102 foreach ( $pages['developer'] as $name => $page ) {
1103 $a[$name] = $page->getDescription() ;
1106 $go = wfMsg( 'go' );
1107 $sp = wfMsg( 'specialpages' );
1108 $spp = $wgLang->specialPage( 'Specialpages' );
1110 $s = '<form id="specialpages" method="get" class="inline" ' .
1111 'action="' . htmlspecialchars( "{$wgServer}{$wgRedirectScript}" ) . "\">\n";
1112 $s .= "<select name=\"wpDropdown\">\n";
1113 $s .= "<option value=\"{$spp}\">{$sp}</option>\n";
1115 foreach ( $a as $name => $desc ) {
1116 $p = $wgLang->specialPage( $name );
1117 $s .= "<option value=\"{$p}\">{$desc}</option>\n";
1119 $s .= "</select>\n";
1120 $s .= "<input type='submit' value=\"{$go}\" name='redirect' />\n";
1125 function mainPageLink()
1127 $mp = wfMsg( 'mainpage' );
1128 $s = $this->makeKnownLink( $mp, $mp );
1132 function copyrightLink()
1134 $s = $this->makeKnownLink( wfMsg( 'copyrightpage' ),
1135 wfMsg( 'copyrightpagename' ) );
1139 function aboutLink()
1141 $s = $this->makeKnownLink( wfMsg( 'aboutpage' ),
1142 wfMsg( 'aboutwikipedia' ) );
1147 function disclaimerLink()
1149 $s = $this->makeKnownLink( wfMsg( 'disclaimerpage' ),
1150 wfMsg( 'disclaimers' ) );
1154 function editThisPage()
1156 global $wgOut, $wgTitle, $wgRequest;
1158 $oldid = $wgRequest->getVal( 'oldid' );
1159 $diff = $wgRequest->getVal( 'diff' );
1160 $redirect = $wgRequest->getVal( 'redirect' );
1162 if ( ! $wgOut->isArticleRelated() ) {
1163 $s = wfMsg( 'protectedpage' );
1165 $n = $wgTitle->getPrefixedText();
1166 if ( $wgTitle->userCanEdit() ) {
1167 $t = wfMsg( 'editthispage' );
1169 #$t = wfMsg( "protectedpage" );
1170 $t = wfMsg( 'viewsource' );
1174 if ( !is_null( $redirect ) ) { $red = "&redirect={$redirect}"; }
1175 if ( $oldid && ! isset( $diff ) ) {
1176 $oid = "&oldid={$oldid}";
1178 $s = $this->makeKnownLink( $n, $t, "action=edit{$oid}{$red}" );
1183 function deleteThisPage()
1185 global $wgUser, $wgOut, $wgTitle, $wgRequest;
1187 $diff = $wgRequest->getVal( 'diff' );
1188 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
1189 $n = $wgTitle->getPrefixedText();
1190 $t = wfMsg( 'deletethispage' );
1192 $s = $this->makeKnownLink( $n, $t, 'action=delete' );
1199 function protectThisPage()
1201 global $wgUser, $wgOut, $wgTitle, $wgRequest;
1203 $diff = $wgRequest->getVal( 'diff' );
1204 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
1205 $n = $wgTitle->getPrefixedText();
1207 if ( $wgTitle->isProtected() ) {
1208 $t = wfMsg( 'unprotectthispage' );
1209 $q = 'action=unprotect';
1211 $t = wfMsg( 'protectthispage' );
1212 $q = 'action=protect';
1214 $s = $this->makeKnownLink( $n, $t, $q );
1221 function watchThisPage()
1223 global $wgUser, $wgOut, $wgTitle;
1225 if ( $wgOut->isArticleRelated() ) {
1226 $n = $wgTitle->getPrefixedText();
1228 if ( $wgTitle->userIsWatching() ) {
1229 $t = wfMsg( 'unwatchthispage' );
1230 $q = 'action=unwatch';
1232 $t = wfMsg( 'watchthispage' );
1233 $q = 'action=watch';
1235 $s = $this->makeKnownLink( $n, $t, $q );
1237 $s = wfMsg( 'notanarticle' );
1242 function moveThisPage()
1244 global $wgTitle, $wgLang;
1246 if ( $wgTitle->userCanEdit() ) {
1247 $s = $this->makeKnownLink( $wgLang->specialPage( 'Movepage' ),
1248 wfMsg( 'movethispage' ), 'target=' . $wgTitle->getPrefixedURL() );
1249 } // no message if page is protected - would be redundant
1253 function historyLink()
1257 $s = $this->makeKnownLink( $wgTitle->getPrefixedText(),
1258 wfMsg( 'history' ), 'action=history' );
1262 function whatLinksHere()
1264 global $wgTitle, $wgLang;
1266 $s = $this->makeKnownLink( $wgLang->specialPage( 'Whatlinkshere' ),
1267 wfMsg( 'whatlinkshere' ), 'target=' . $wgTitle->getPrefixedURL() );
1271 function userContribsLink()
1273 global $wgTitle, $wgLang;
1275 $s = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
1276 wfMsg( 'contributions' ), 'target=' . $wgTitle->getPartialURL() );
1280 function emailUserLink()
1282 global $wgTitle, $wgLang;
1284 $s = $this->makeKnownLink( $wgLang->specialPage( 'Emailuser' ),
1285 wfMsg( 'emailuser' ), 'target=' . $wgTitle->getPartialURL() );
1289 function watchPageLinksLink()
1291 global $wgOut, $wgTitle, $wgLang;
1293 if ( ! $wgOut->isArticleRelated() ) {
1294 $s = '(' . wfMsg( 'notanarticle' ) . ')';
1296 $s = $this->makeKnownLink( $wgLang->specialPage(
1297 'Recentchangeslinked' ), wfMsg( 'recentchangeslinked' ),
1298 'target=' . $wgTitle->getPrefixedURL() );
1303 function otherLanguages()
1305 global $wgOut, $wgLang, $wgTitle, $wgUseNewInterlanguage;
1307 $a = $wgOut->getLanguageLinks();
1308 if ( 0 == count( $a ) ) {
1309 if ( !$wgUseNewInterlanguage ) return '';
1310 $ns = $wgLang->getNsIndex ( $wgTitle->getNamespace () ) ;
1311 if ( $ns != 0 AND $ns != 1 ) return '' ;
1313 $x = 'mode=addlink&xt='.$wgTitle->getDBkey() ;
1314 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1315 wfMsg( 'intl' ) , $x );
1318 if ( !$wgUseNewInterlanguage ) {
1319 $s = wfMsg( 'otherlanguages' ) . ': ';
1321 global $wgLanguageCode ;
1322 $x = 'mode=zoom&xt='.$wgTitle->getDBkey() ;
1323 $x .= '&xl='.$wgLanguageCode ;
1324 $s = $this->makeKnownLink( $wgLang->specialPage( 'Intl' ),
1325 wfMsg( 'otherlanguages' ) , $x ) . ': ' ;
1328 $s = wfMsg( 'otherlanguages' ) . ': ';
1330 if($wgLang->isRTL()) $s .= '<span dir="LTR">';
1331 foreach( $a as $l ) {
1332 if ( ! $first ) { $s .= ' | '; }
1335 $nt = Title
::newFromText( $l );
1336 $url = $nt->getFullURL();
1337 $text = $wgLang->getLanguageName( $nt->getInterwiki() );
1339 if ( '' == $text ) { $text = $l; }
1340 $style = $this->getExternalLinkAttributes( $l, $text );
1341 $s .= "<a href=\"{$url}\"{$style}>{$text}</a>";
1343 if($wgLang->isRTL()) $s .= '</span>';
1347 function bugReportsLink()
1349 $s = $this->makeKnownLink( wfMsg( 'bugreportspage' ),
1350 wfMsg( 'bugreports' ) );
1356 global $wgLinkCache;
1357 $t1 = Title
::newFromText( gmdate( 'F j' ) );
1358 $t2 = Title
::newFromText( gmdate( 'Y' ) );
1360 $wgLinkCache->suspend();
1361 $id = $t1->getArticleID();
1362 $wgLinkCache->resume();
1365 $s = $this->makeBrokenLink( $t1->getText() );
1367 $s = $this->makeKnownLink( $t1->getText() );
1371 $wgLinkCache->suspend();
1372 $id = $t2->getArticleID();
1373 $wgLinkCache->resume();
1376 $s .= $this->makeBrokenLink( $t2->getText() );
1378 $s .= $this->makeKnownLink( $t2->getText() );
1385 global $wgLang, $wgTitle, $wgLinkCache;
1387 $tns = $wgTitle->getNamespace();
1388 if ( -1 == $tns ) { return ''; }
1390 $pn = $wgTitle->getText();
1391 $tp = wfMsg( 'talkpage' );
1392 if ( Namespace::isTalk( $tns ) ) {
1393 $lns = Namespace::getSubject( $tns );
1396 $text = wfMsg('articlepage');
1399 $text = wfMsg('userpage');
1402 $text = wfMsg('wikipediapage');
1405 $text = wfMsg('imagepage');
1408 $text= wfMsg('articlepage');
1412 $lns = Namespace::getTalk( $tns );
1415 $n = $wgLang->getNsText( $lns );
1416 if ( '' == $n ) { $link = $pn; }
1417 else { $link = $n.':'.$pn; }
1419 $wgLinkCache->suspend();
1420 $s = $this->makeLink( $link, $text );
1421 $wgLinkCache->resume();
1426 function commentLink()
1428 global $wgLang, $wgTitle, $wgLinkCache;
1430 $tns = $wgTitle->getNamespace();
1431 if ( -1 == $tns ) { return ''; }
1433 $lns = ( Namespace::isTalk( $tns ) ) ?
$tns : Namespace::getTalk( $tns );
1435 # assert Namespace::isTalk( $lns )
1437 $n = $wgLang->getNsText( $lns );
1438 $pn = $wgTitle->getText();
1442 $wgLinkCache->suspend();
1443 $s = $this->makeKnownLink($link, wfMsg('postcomment'), 'action=edit§ion=new');
1444 $wgLinkCache->resume();
1449 # After all the page content is transformed into HTML, it makes
1450 # a final pass through here for things like table backgrounds.
1452 function transformContent( $text )
1457 # Note: This function MUST call getArticleID() on the link,
1458 # otherwise the cache won't get updated properly. See LINKCACHE.DOC.
1460 function makeLink( $title, $text = '', $query = '', $trail = '' ) {
1461 wfProfileIn( 'Skin::makeLink' );
1462 $nt = Title
::newFromText( $title );
1464 $result = $this->makeLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1466 wfDebug( 'Invalid title passed to Skin::makeLink(): "'.$title."\"\n" );
1467 $result = $text == "" ?
$title : $text;
1470 wfProfileOut( 'Skin::makeLink' );
1474 function makeKnownLink( $title, $text = '', $query = '', $trail = '', $prefix = '',$aprops = '') {
1475 $nt = Title
::newFromText( $title );
1477 return $this->makeKnownLinkObj( Title
::newFromText( $title ), $text, $query, $trail, $prefix , $aprops );
1479 wfDebug( 'Invalid title passed to Skin::makeKnownLink(): "'.$title."\"\n" );
1480 return $text == '' ?
$title : $text;
1484 function makeBrokenLink( $title, $text = '', $query = '', $trail = '' ) {
1485 $nt = Title
::newFromText( $title );
1487 return $this->makeBrokenLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1489 wfDebug( 'Invalid title passed to Skin::makeBrokenLink(): "'.$title."\"\n" );
1490 return $text == '' ?
$title : $text;
1494 function makeStubLink( $title, $text = '', $query = '', $trail = '' ) {
1495 $nt = Title
::newFromText( $title );
1497 return $this->makeStubLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1499 wfDebug( 'Invalid title passed to Skin::makeStubLink(): "'.$title."\"\n" );
1500 return $text == '' ?
$title : $text;
1504 # Pass a title object, not a title string
1505 function makeLinkObj( &$nt, $text= '', $query = '', $trail = '', $prefix = '' )
1507 global $wgOut, $wgUser;
1508 if ( $nt->isExternal() ) {
1509 $u = $nt->getFullURL();
1510 $link = $nt->getPrefixedURL();
1511 if ( '' == $text ) { $text = $nt->getPrefixedText(); }
1512 $style = $this->getExternalLinkAttributes( $link, $text, 'extiw' );
1515 if ( '' != $trail ) {
1516 if ( preg_match( '/^([a-z]+)(.*)$$/sD', $trail, $m ) ) {
1521 $retVal = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1522 } elseif ( 0 == $nt->getNamespace() && "" == $nt->getText() ) {
1523 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1524 } elseif ( ( -1 == $nt->getNamespace() ) ||
1525 ( Namespace::getImage() == $nt->getNamespace() ) ) {
1526 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1528 $aid = $nt->getArticleID() ;
1530 $retVal = $this->makeBrokenLinkObj( $nt, $text, $query, $trail, $prefix );
1532 $threshold = $wgUser->getOption('stubthreshold') ;
1533 if ( $threshold > 0 ) {
1534 $res = wfQuery ( "SELECT LENGTH(cur_text) AS x, cur_namespace, cur_is_redirect FROM cur WHERE cur_id='{$aid}'", DB_READ
) ;
1536 if ( wfNumRows( $res ) > 0 ) {
1537 $s = wfFetchObject( $res );
1539 if ( $s->cur_is_redirect
OR $s->cur_namespace
!= 0 ) {
1540 $size = $threshold*2 ; # Really big
1542 wfFreeResult( $res );
1544 $size = $threshold*2 ; # Really big
1549 if ( $size < $threshold ) {
1550 $retVal = $this->makeStubLinkObj( $nt, $text, $query, $trail, $prefix );
1552 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1559 # Pass a title object, not a title string
1560 function makeKnownLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' , $aprops = '')
1562 global $wgOut, $wgTitle, $wgInputEncoding;
1564 $fname = 'Skin::makeKnownLinkObj';
1565 wfProfileIn( $fname );
1567 $link = $nt->getPrefixedURL();
1569 if ( '' == $link ) {
1571 if ( '' == $text ) {
1572 $text = htmlspecialchars( $nt->getFragment() );
1575 $u = $nt->escapeLocalURL( $query );
1577 if ( '' != $nt->getFragment() ) {
1578 $anchor = urlencode( do_html_entity_decode( str_replace(' ', '_', $nt->getFragment()), ENT_COMPAT
, $wgInputEncoding ) );
1579 $replacearray = array(
1583 $u .= '#' . str_replace(array_keys($replacearray),array_values($replacearray),$anchor);
1585 if ( '' == $text ) {
1586 $text = htmlspecialchars( $nt->getPrefixedText() );
1588 $style = $this->getInternalLinkAttributesObj( $nt, $text );
1591 if ( '' != $trail ) {
1592 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1597 $r = "<a href=\"{$u}\"{$style}{$aprops}>{$prefix}{$text}{$inside}</a>{$trail}";
1598 wfProfileOut( $fname );
1602 # Pass a title object, not a title string
1603 function makeBrokenLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
1605 global $wgOut, $wgUser;
1607 $fname = 'Skin::makeBrokenLinkObj';
1608 wfProfileIn( $fname );
1610 if ( '' == $query ) {
1613 $q = 'action=edit&'.$query;
1615 $u = $nt->escapeLocalURL( $q );
1617 if ( '' == $text ) {
1618 $text = htmlspecialchars( $nt->getPrefixedText() );
1620 $style = $this->getInternalLinkAttributesObj( $nt, $text, "yes" );
1623 if ( '' != $trail ) {
1624 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1629 if ( $wgUser->getOption( 'highlightbroken' ) ) {
1630 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1632 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>?</a>{$trail}";
1635 wfProfileOut( $fname );
1639 # Pass a title object, not a title string
1640 function makeStubLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
1642 global $wgOut, $wgUser;
1644 $link = $nt->getPrefixedURL();
1646 $u = $nt->escapeLocalURL( $query );
1648 if ( '' == $text ) {
1649 $text = htmlspecialchars( $nt->getPrefixedText() );
1651 $style = $this->getInternalLinkAttributesObj( $nt, $text, 'stub' );
1654 if ( '' != $trail ) {
1655 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1660 if ( $wgUser->getOption( 'highlightbroken' ) ) {
1661 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1663 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>!</a>{$trail}";
1668 function makeSelfLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
1670 $u = $nt->escapeLocalURL( $query );
1671 if ( '' == $text ) {
1672 $text = htmlspecialchars( $nt->getPrefixedText() );
1675 if ( '' != $trail ) {
1676 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1681 return "<strong>{$prefix}{$text}{$inside}</strong>{$trail}";
1684 /* these are used extensively in SkinPHPTal, but also some other places */
1685 /*static*/ function makeSpecialUrl( $name, $urlaction='' ) {
1686 $title = Title
::makeTitle( NS_SPECIAL
, $name );
1687 $this->checkTitle($title, $name);
1688 return $title->getLocalURL( $urlaction );
1690 /*static*/ function makeTalkUrl ( $name, $urlaction='' ) {
1691 $title = Title
::newFromText( $name );
1692 $title = $title->getTalkPage();
1693 $this->checkTitle($title, $name);
1694 return $title->getLocalURL( $urlaction );
1696 /*static*/ function makeArticleUrl ( $name, $urlaction='' ) {
1697 $title = Title
::newFromText( $name );
1698 $title= $title->getSubjectPage();
1699 $this->checkTitle($title, $name);
1700 return $title->getLocalURL( $urlaction );
1702 /*static*/ function makeI18nUrl ( $name, $urlaction='' ) {
1703 $title = Title
::newFromText( wfMsg($name) );
1704 $this->checkTitle($title, $name);
1705 return $title->getLocalURL( $urlaction );
1707 /*static*/ function makeUrl ( $name, $urlaction='' ) {
1708 $title = Title
::newFromText( $name );
1709 $this->checkTitle($title, $name);
1710 return $title->getLocalURL( $urlaction );
1712 # this can be passed the NS number as defined in Language.php
1713 /*static*/ function makeNSUrl( $name, $urlaction='', $namespace=0 ) {
1714 $title = Title
::makeTitle( $namespace, $name );
1715 $this->checkTitle($title, $name);
1716 return $title->getLocalURL( $urlaction );
1719 /* these return an array with the 'href' and boolean 'exists' */
1720 /*static*/ function makeUrlDetails ( $name, $urlaction='' ) {
1721 $title = Title
::newFromText( $name );
1722 $this->checkTitle($title, $name);
1724 'href' => $title->getLocalURL( $urlaction ),
1725 'exists' => $title->getArticleID() != 0?
true:false
1728 /*static*/ function makeTalkUrlDetails ( $name, $urlaction='' ) {
1729 $title = Title
::newFromText( $name );
1730 $title = $title->getTalkPage();
1731 $this->checkTitle($title, $name);
1733 'href' => $title->getLocalURL( $urlaction ),
1734 'exists' => $title->getArticleID() != 0?
true:false
1737 /*static*/ function makeArticleUrlDetails ( $name, $urlaction='' ) {
1738 $title = Title
::newFromText( $name );
1739 $title= $title->getSubjectPage();
1740 $this->checkTitle($title, $name);
1742 'href' => $title->getLocalURL( $urlaction ),
1743 'exists' => $title->getArticleID() != 0?
true:false
1746 /*static*/ function makeI18nUrlDetails ( $name, $urlaction='' ) {
1747 $title = Title
::newFromText( wfMsg($name) );
1748 $this->checkTitle($title, $name);
1750 'href' => $title->getLocalURL( $urlaction ),
1751 'exists' => $title->getArticleID() != 0?
true:false
1755 # make sure we have some title to operate on
1756 /*static*/ function checkTitle ( &$title, &$name ) {
1757 if(!is_object($title)) {
1758 $title = Title
::newFromText( $name );
1759 if(!is_object($title)) {
1760 $title = Title
::newFromText( '<error: link target missing>' );
1765 function fnamePart( $url )
1767 $basename = strrchr( $url, '/' );
1768 if ( false === $basename ) { $basename = $url; }
1769 else { $basename = substr( $basename, 1 ); }
1770 return wfEscapeHTML( $basename );
1773 function makeImage( $url, $alt = '' )
1777 if ( '' == $alt ) { $alt = $this->fnamePart( $url ); }
1778 $s = '<img src="'.$url.'" alt="'.$alt.'" />';
1782 function makeImageLink( $name, $url, $alt = '' ) {
1783 $nt = Title
::makeTitle( Namespace::getImage(), $name );
1784 return $this->makeImageLinkObj( $nt, $alt );
1787 function makeImageLinkObj( $nt, $alt = '' ) {
1788 global $wgLang, $wgUseImageResize;
1789 $img = Image
::newFromTitle( $nt );
1790 $url = $img->getURL();
1793 $prefix = $postfix = '';
1795 if ( $wgUseImageResize ) {
1796 # Check if the alt text is of the form "options|alt text"
1798 # * thumbnail make a thumbnail with enlarge-icon and caption, alignment depends on lang
1799 # * left no resizing, just left align. label is used for alt= only
1800 # * right same, but right aligned
1801 # * none same, but not aligned
1802 # * ___px scale to ___ pixels width, no aligning. e.g. use in taxobox
1803 # * center center the image
1804 # * framed Keep original image size, no magnify-button.
1806 $part = explode( '|', $alt);
1808 $mwThumb =& MagicWord
::get( MAG_IMG_THUMBNAIL
);
1809 $mwLeft =& MagicWord
::get( MAG_IMG_LEFT
);
1810 $mwRight =& MagicWord
::get( MAG_IMG_RIGHT
);
1811 $mwNone =& MagicWord
::get( MAG_IMG_NONE
);
1812 $mwWidth =& MagicWord
::get( MAG_IMG_WIDTH
);
1813 $mwCenter =& MagicWord
::get( MAG_IMG_CENTER
);
1814 $mwFramed =& MagicWord
::get( MAG_IMG_FRAMED
);
1815 $alt = $part[count($part)-1];
1817 $height = $framed = $thumb = false;
1819 foreach( $part as $key => $val ) {
1820 if ( ! is_null( $mwThumb->matchVariableStartToEnd($val) ) ) {
1822 } elseif ( ! is_null( $mwRight->matchVariableStartToEnd($val) ) ) {
1823 # remember to set an alignment, don't render immediately
1825 } elseif ( ! is_null( $mwLeft->matchVariableStartToEnd($val) ) ) {
1826 # remember to set an alignment, don't render immediately
1828 } elseif ( ! is_null( $mwCenter->matchVariableStartToEnd($val) ) ) {
1829 # remember to set an alignment, don't render immediately
1831 } elseif ( ! is_null( $mwNone->matchVariableStartToEnd($val) ) ) {
1832 # remember to set an alignment, don't render immediately
1834 } elseif ( ! is_null( $match = $mwWidth->matchVariableStartToEnd($val) ) ) {
1835 # $match is the image width in pixels
1836 if ( preg_match( '/^([0-9]*)x([0-9]*)$/', $match, $m ) ) {
1837 $width = intval( $m[1] );
1838 $height = intval( $m[2] );
1840 $width = intval($match);
1842 } elseif ( ! is_null( $mwFramed->matchVariableStartToEnd($val) ) ) {
1846 if ( 'center' == $align )
1848 $prefix = '<span style="text-align: center">';
1849 $postfix = '</span>';
1853 if ( $thumb ||
$framed ) {
1855 # Create a thumbnail. Alignment depends on language
1856 # writing direction, # right aligned for left-to-right-
1857 # languages ("Western languages"), left-aligned
1858 # for right-to-left-languages ("Semitic languages")
1860 # If thumbnail width has not been provided, it is set
1861 # here to 180 pixels
1862 if ( $align == '' ) {
1863 $align = $wgLang->isRTL() ?
'left' : 'right';
1865 if ( ! isset($width) ) {
1868 return $prefix.$this->makeThumbLinkObj( $img, $alt, $align, $width, $height, $framed ).$postfix;
1870 } elseif ( isset($width) ) {
1872 # Create a resized image, without the additional thumbnail
1875 if ( ( ! $height === false )
1876 && ( $img->getHeight() * $width / $img->getWidth() > $height ) ) {
1877 print "height=$height<br>\nimg->getHeight() = ".$img->getHeight()."<br>\n";
1878 print 'rescaling by factor '. $height / $img->getHeight() . "<br>\n";
1879 $width = $img->getWidth() * $height / $img->getHeight();
1881 $url = $img->createThumb( $width );
1883 } # endif $wgUseImageResize
1885 if ( empty( $alt ) ) {
1886 $alt = preg_replace( '/\.(.+?)^/', '', $img->getName() );
1888 $alt = htmlspecialchars( $alt );
1890 $u = $nt->escapeLocalURL();
1893 $s = str_replace( "$1", $img->getName(), wfMsg('missingimage') );
1894 $s .= "<br>{$alt}<br>{$url}<br>\n";
1896 $s = '<a href="'.$u.'" class="image" title="'.$alt.'">' .
1897 '<img src="'.$url.'" alt="'.$alt.'" /></a>';
1899 if ( '' != $align ) {
1900 $s = "<div class=\"float{$align}\"><span>{$s}</span></div>";
1902 return str_replace("\n", ' ',$prefix.$s.$postfix);
1906 function makeThumbLinkObj( $img, $label = '', $align = 'right', $boxwidth = 180, $boxheight=false, $framed=false ) {
1907 global $wgStylePath, $wgLang;
1908 # $image = Title::makeTitle( Namespace::getImage(), $name );
1909 $url = $img->getURL();
1911 #$label = htmlspecialchars( $label );
1912 $alt = preg_replace( '/<[^>]*>/', '', $label);
1913 $alt = htmlspecialchars( $alt );
1915 if ( $img->exists() )
1917 $width = $img->getWidth();
1918 $height = $img->getHeight();
1920 $width = $height = 200;
1924 // Use image dimensions, don't scale
1926 $oboxwidth = $boxwidth +
2;
1927 $boxheight = $height;
1930 $h = intval( $height/($width/$boxwidth) );
1931 $oboxwidth = $boxwidth +
2;
1932 if ( ( ! $boxheight === false ) && ( $h > $boxheight ) )
1934 $boxwidth *= $boxheight/$h;
1938 $thumbUrl = $img->createThumb( $boxwidth );
1941 $u = $img->getEscapeLocalURL();
1943 $more = htmlspecialchars( wfMsg( 'thumbnail-more' ) );
1944 $magnifyalign = $wgLang->isRTL() ?
'left' : 'right';
1945 $textalign = $wgLang->isRTL() ?
' style="text-align:right"' : '';
1947 $s = "<div class=\"thumb t{$align}\"><div style=\"width:{$oboxwidth}px;\">";
1948 if ( $thumbUrl == '' ) {
1949 $s .= str_replace( "$1", $img->getName(), wfMsg('missingimage') );
1952 $s .= '<a href="'.$u.'" class="internal" title="'.$alt.'">'.
1953 '<img src="'.$thumbUrl.'" alt="'.$alt.'" ' .
1954 'width="'.$boxwidth.'" height="'.$boxheight.'" /></a>';
1958 $zoomicon = '<div class="magnify" style="float:'.$magnifyalign.'">'.
1959 '<a href="'.$u.'" class="internal" title="'.$more.'">'.
1960 '<img src="'.$wgStylePath.'/images/magnify-clip.png" ' .
1961 'width="15" height="11" alt="'.$more.'" /></a></div>';
1964 $s .= ' <div class="thumbcaption" '.$textalign.'>'.$zoomicon.$label."</div></div></div>";
1965 return str_replace("\n", ' ', $s);
1968 function makeMediaLink( $name, $url, $alt = "" ) {
1969 $nt = Title
::makeTitle( Namespace::getMedia(), $name );
1970 return $this->makeMediaLinkObj( $nt, $alt );
1973 function makeMediaLinkObj( $nt, $alt = "" )
1975 if ( ! isset( $nt ) )
1977 ### HOTFIX. Instead of breaking, return empry string.
1980 $name = $nt->getDBKey();
1981 $url = Image
::wfImageUrl( $name );
1982 if ( empty( $alt ) ) {
1983 $alt = preg_replace( '/\.(.+?)^/', '', $name );
1986 $u = htmlspecialchars( $url );
1987 $s = "<a href=\"{$u}\" class='internal' title=\"{$alt}\">{$alt}</a>";
1992 function specialLink( $name, $key = "" )
1996 if ( '' == $key ) { $key = strtolower( $name ); }
1997 $pn = $wgLang->ucfirst( $name );
1998 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
2002 function makeExternalLink( $url, $text, $escape = true ) {
2003 $style = $this->getExternalLinkAttributes( $url, $text );
2004 $url = htmlspecialchars( $url );
2006 $text = htmlspecialchars( $text );
2008 return '<a href="'.$url.'"'.$style.'>'.$text.'</a>';
2011 # Called by history lists and recent changes
2014 # Returns text for the start of the tabular part of RC
2015 function beginRecentChangesList()
2017 $this->rc_cache
= array() ;
2018 $this->rcMoveIndex
= 0;
2019 $this->rcCacheIndex
= 0 ;
2020 $this->lastdate
= '';
2021 $this->rclistOpen
= false;
2025 function beginImageHistoryList()
2027 $s = "\n<h2>" . wfMsg( 'imghistory' ) . "</h2>\n" .
2028 "<p>" . wfMsg( 'imghistlegend' ) . "</p>\n".'<ul class="special">';
2032 # Returns text for the end of RC
2033 # If enhanced RC is in use, returns pretty much all the text
2034 function endRecentChangesList()
2036 $s = $this->recentChangesBlock() ;
2037 if( $this->rclistOpen
) {
2043 # Enhanced RC ungrouped line
2044 function recentChangesBlockLine ( $rcObj )
2046 global $wgStylePath, $wgLang ;
2048 # Get rc_xxxx variables
2049 extract( $rcObj->mAttribs
) ;
2050 $curIdEq = 'curid='.$rc_cur_id;
2055 $r .= '<img src="'.$wgStylePath.'/images/Arr_.png" width="12" height="12" border="0" />' ;
2058 if ( $rc_type == RC_MOVE
) {
2059 $r .= ' ';
2061 # M & N (minor & new)
2062 $M = wfMsg( 'minoreditletter' );
2063 $N = wfMsg( 'newpageletter' );
2065 if ( $rc_type == RC_NEW
) {
2078 $r .= ' '.$rcObj->timestamp
.' ' ;
2082 $link = $rcObj->link
;
2083 if ( $rcObj->watched
) $link = '<strong>'.$link.'</strong>' ;
2088 $r .= $rcObj->curlink
;
2092 $r .= $this->makeKnownLinkObj( $rcObj->getTitle(), wfMsg( 'hist' ), $curIdEq.'&action=history' );
2095 $r .= ') . . '.$rcObj->userlink
;
2096 $r .= $rcObj->usertalklink
;
2099 if ( $rc_comment != '' && $rc_type != RC_MOVE
) {
2100 $rc_comment=$this->formatComment($rc_comment);
2101 $r .= $wgLang->emphasize( ' ('.$rc_comment.')' );
2109 function recentChangesBlockGroup ( $block )
2111 global $wgStylePath, $wgLang ;
2114 $M = wfMsg( 'minoreditletter' );
2115 $N = wfMsg( 'newpageletter' );
2117 # Collate list of users
2119 $userlinks = array () ;
2120 foreach ( $block AS $rcObj ) {
2121 $oldid = $rcObj->mAttribs
['rc_last_oldid'];
2122 if ( $rcObj->mAttribs
['rc_new'] ) $isnew = true ;
2123 $u = $rcObj->userlink
;
2124 if ( !isset ( $userlinks[$u] ) ) $userlinks[$u] = 0 ;
2128 # Sort the list and convert to text
2129 krsort ( $userlinks ) ;
2130 asort ( $userlinks ) ;
2132 foreach ( $userlinks as $userlink => $count) {
2134 if ( $count > 1 ) $text .= " ({$count}×)" ;
2135 array_push ( $users , $text ) ;
2137 $users = ' <font size="-1">['.implode('; ',$users).']</font>' ;
2140 $rci = 'RCI'.$this->rcCacheIndex
;
2141 $rcl = 'RCL'.$this->rcCacheIndex
;
2142 $rcm = 'RCM'.$this->rcCacheIndex
;
2143 $toggleLink = "javascript:toggleVisibility('$rci','$rcm','$rcl')" ;
2144 $arrowdir = $wgLang->isRTL() ?
'l' : 'r';
2145 $tl = '<span id="'.$rcm.'"><a href="'.$toggleLink.'"><img src="'.$wgStylePath.'/images/Arr_'.$arrowdir.'.png" width="12" height="12" /></a></span>' ;
2146 $tl .= '<span id="'.$rcl.'" style="display:none"><a href="'.$toggleLink.'"><img src="'.$wgStylePath.'/images/Arr_d.png" width="12" height="12" /></a></span>' ;
2152 if ( $isnew ) $r .= $N ;
2153 else $r .= ' ' ;
2154 $r .= ' ' ; # Minor
2157 $r .= ' '.$block[0]->timestamp
.' ' ;
2161 $link = $block[0]->link
;
2162 if ( $block[0]->watched
) $link = '<strong>'.$link.'</strong>' ;
2165 $curIdEq = 'curid=' . $block[0]->mAttribs
['rc_cur_id'];
2166 if ( $block[0]->mAttribs
['rc_type'] != RC_LOG
) {
2168 $r .= ' ('.count($block).' ' ;
2169 if ( $isnew ) $r .= wfMsg('changes');
2170 else $r .= $this->makeKnownLinkObj( $block[0]->getTitle() , wfMsg('changes') ,
2171 $curIdEq.'&diff=0&oldid='.$oldid ) ;
2175 $r .= $this->makeKnownLinkObj( $block[0]->getTitle(), wfMsg( 'history' ), $curIdEq.'&action=history' );
2183 $r .= '<div id="'.$rci.'" style="display:none">' ;
2184 foreach ( $block AS $rcObj ) {
2185 # Get rc_xxxx variables
2186 extract( $rcObj->mAttribs
);
2188 $r .= '<img src="'.$wgStylePath.'/images/Arr_.png" width="12" height="12" />';
2189 $r .= '<tt> ' ;
2190 if ( $rc_new ) $r .= $N ;
2191 else $r .= ' ' ;
2192 if ( $rc_minor ) $r .= $M ;
2193 else $r .= ' ' ;
2197 if ( $rc_last_oldid != 0 ) {
2198 $o = 'oldid='.$rc_last_oldid ;
2200 if ( $rc_type == RC_LOG
) {
2201 $link = $rcObj->timestamp
;
2203 $link = $this->makeKnownLinkObj( $rcObj->getTitle(), $rcObj->timestamp
, "{$curIdEq}&$o" ) ;
2205 $link = '<tt>'.$link.'</tt>' ;
2209 $r .= $rcObj->curlink
;
2211 $r .= $rcObj->lastlink
;
2212 $r .= ') . . '.$rcObj->userlink
;
2213 $r .= $rcObj->usertalklink
;
2214 if ( $rc_comment != '' ) {
2215 $rc_comment=$this->formatComment($rc_comment);
2216 $r .= $wgLang->emphasize( ' ('.$rc_comment.')' ) ;
2222 $this->rcCacheIndex++
;
2226 # If enhanced RC is in use, this function takes the previously cached
2227 # RC lines, arranges them, and outputs the HTML
2228 function recentChangesBlock ()
2230 global $wgStylePath ;
2231 if ( count ( $this->rc_cache
) == 0 ) return '' ;
2233 foreach ( $this->rc_cache
AS $secureName => $block ) {
2234 if ( count ( $block ) < 2 ) {
2235 $blockOut .= $this->recentChangesBlockLine ( array_shift ( $block ) ) ;
2237 $blockOut .= $this->recentChangesBlockGroup ( $block ) ;
2241 return '<div>'.$blockOut.'</div>' ;
2244 # Called in a loop over all displayed RC entries
2245 # Either returns the line, or caches it for later use
2246 function recentChangesLine( &$rc, $watched = false )
2249 $usenew = $wgUser->getOption( 'usenewrc' );
2251 $line = $this->recentChangesLineNew ( $rc, $watched ) ;
2253 $line = $this->recentChangesLineOld ( $rc, $watched ) ;
2257 function recentChangesLineOld( &$rc, $watched = false )
2259 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds;
2261 # Extract DB fields into local scope
2262 extract( $rc->mAttribs
);
2263 $curIdEq = 'curid=' . $rc_cur_id;
2265 # Make date header if necessary
2266 $date = $wgLang->date( $rc_timestamp, true);
2268 if ( $date != $this->lastdate
) {
2269 if ( '' != $this->lastdate
) { $s .= "</ul>\n"; }
2270 $s .= "<h4>{$date}</h4>\n<ul class='special'>";
2271 $this->lastdate
= $date;
2272 $this->rclistOpen
= true;
2276 if ( $rc_type == RC_MOVE
) {
2278 $s .= '(' . wfMsg( 'diff' ) . ') (';
2280 $s .= $this->makeKnownLinkObj( $rc->getMovedToTitle(), wfMsg( 'hist' ), 'action=history' ) .
2283 # "[[x]] moved to [[y]]"
2285 $s .= wfMsg( '1movedto2', $this->makeKnownLinkObj( $rc->getTitle(), '', 'redirect=no' ),
2286 $this->makeKnownLinkObj( $rc->getMovedToTitle(), '' ) );
2290 if ( $rc_type == RC_NEW ||
$rc_type == RC_LOG
) {
2291 $diffLink = wfMsg( 'diff' );
2293 $diffLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'diff' ),
2294 $curIdEq.'&diff='.$rc_this_oldid.'&oldid='.$rc_last_oldid ,'' ,'' , ' tabindex="'.$rc->counter
.'"');
2296 $s .= '('.$diffLink.') (';
2299 $s .= $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'hist' ), $curIdEq.'&action=history' );
2302 # M and N (minor and new)
2303 $M = wfMsg( 'minoreditletter' );
2304 $N = wfMsg( 'newpageletter' );
2305 if ( $rc_minor ) { $s .= ' <strong>'.$M.'</strong>'; }
2306 if ( $rc_type == RC_NEW
) { $s .= '<strong>'.$N.'</strong>'; }
2309 $articleLink = $this->makeKnownLinkObj( $rc->getTitle(), '' );
2312 $articleLink = '<strong>'.$articleLink.'</strong>';
2314 $s .= ' '.$articleLink;
2319 $s .= '; ' . $wgLang->time( $rc_timestamp, true, $wgRCSeconds ) . ' . . ';
2321 # User link (or contributions for unregistered users)
2322 if ( 0 == $rc_user ) {
2323 $userLink = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
2324 $rc_user_text, 'target=' . $rc_user_text );
2326 $userLink = $this->makeLink( $wgLang->getNsText( NS_USER
) . ':'.$rc_user_text, $rc_user_text );
2331 $talkname=$wgLang->getNsText(NS_TALK
); # use the shorter name
2332 global $wgDisableAnonTalk;
2333 if( 0 == $rc_user && $wgDisableAnonTalk ) {
2336 $utns=$wgLang->getNsText(NS_USER_TALK
);
2337 $userTalkLink= $this->makeLink($utns . ':'.$rc_user_text, $talkname );
2341 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2342 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2343 'Blockip' ), wfMsg( 'blocklink' ), 'ip='.$rc_user_text );
2347 if($userTalkLink) $userTalkLink .= ' | ';
2348 $userTalkLink .= $blockLink;
2350 if($userTalkLink) $s.=' ('.$userTalkLink.')';
2353 if ( '' != $rc_comment && '*' != $rc_comment && $rc_type != RC_MOVE
) {
2354 $rc_comment=$this->formatComment($rc_comment);
2355 $s .= $wgLang->emphasize(' (' . $rc_comment . ')');
2362 # function recentChangesLineNew( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched = false, $oldid = 0 , $diffid = 0 )
2363 function recentChangesLineNew( &$baseRC, $watched = false )
2365 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds;
2367 # Create a specialised object
2368 $rc = RCCacheEntry
::newFromParent( $baseRC ) ;
2370 # Extract fields from DB into the function scope (rc_xxxx variables)
2371 extract( $rc->mAttribs
);
2372 $curIdEq = 'curid=' . $rc_cur_id;
2374 # If it's a new day, add the headline and flush the cache
2375 $date = $wgLang->date( $rc_timestamp, true);
2377 if ( $date != $this->lastdate
) {
2378 # Process current cache
2379 $ret = $this->recentChangesBlock () ;
2380 $this->rc_cache
= array() ;
2381 $ret .= "<h4>{$date}</h4>\n";
2382 $this->lastdate
= $date;
2386 if ( $rc_type == RC_MOVE
) {
2387 $clink = $this->makeKnownLinkObj( $rc->getTitle(), '', 'redirect=no' );
2388 $clink .= ' ' . wfMsg('movedto') . ' ';
2389 $clink .= $this->makeKnownLinkObj( $rc->getMovedToTitle(), '' );
2391 $clink = $this->makeKnownLinkObj( $rc->getTitle(), '' ) ;
2394 $time = $wgLang->time( $rc_timestamp, true, $wgRCSeconds );
2395 $rc->watched
= $watched ;
2396 $rc->link
= $clink ;
2397 $rc->timestamp
= $time;
2400 if ( ( $rc_type == RC_NEW
&& $rc_this_oldid == 0 ) ||
$rc_type == RC_LOG ||
$rc_type == RC_MOVE
) {
2401 $curLink = wfMsg( 'cur' );
2403 $curLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'cur' ),
2404 $curIdEq.'&diff=0&oldid='.$rc_this_oldid ,'' ,'' , ' tabindex="'.$baseRC->counter
.'"' );
2408 $titleObj = $rc->getTitle();
2409 if ( $rc_last_oldid == 0 ||
$rc_type == RC_LOG ||
$rc_type == RC_MOVE
) {
2410 $lastLink = wfMsg( 'last' );
2412 $lastLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'last' ),
2413 $curIdEq.'&diff='.$rc_this_oldid.'&oldid='.$rc_last_oldid );
2416 # Make user link (or user contributions for unregistered users)
2417 if ( 0 == $rc_user ) {
2418 $userLink = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
2419 $rc_user_text, 'target=' . $rc_user_text );
2421 $userLink = $this->makeLink( $wgLang->getNsText(
2422 Namespace::getUser() ) . ':'.$rc_user_text, $rc_user_text );
2425 $rc->userlink
= $userLink ;
2426 $rc->lastlink
= $lastLink ;
2427 $rc->curlink
= $curLink ;
2429 # Make user talk link
2430 $utns=$wgLang->getNsText(NS_USER_TALK
);
2431 $talkname=$wgLang->getNsText(NS_TALK
); # use the shorter name
2432 $userTalkLink= $this->makeLink($utns . ':'.$rc_user_text, $talkname );
2434 global $wgDisableAnonTalk;
2435 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2436 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2437 'Blockip' ), wfMsg( 'blocklink' ), 'ip='.$rc_user_text );
2438 if( $wgDisableAnonTalk )
2439 $rc->usertalklink
= ' ('.$blockLink.')';
2441 $rc->usertalklink
= ' ('.$userTalkLink.' | '.$blockLink.')';
2443 if( $wgDisableAnonTalk && ($rc_user == 0) )
2444 $rc->usertalklink
= '';
2446 $rc->usertalklink
= ' ('.$userTalkLink.')';
2449 # Put accumulated information into the cache, for later display
2450 # Page moves go on their own line
2451 $title = $rc->getTitle();
2452 $secureName = $title->getPrefixedDBkey();
2453 if ( $rc_type == RC_MOVE
) {
2454 # Use an @ character to prevent collision with page names
2455 $this->rc_cache
['@@' . ($this->rcMoveIndex++
)] = array($rc);
2457 if ( !isset ( $this->rc_cache
[$secureName] ) ) $this->rc_cache
[$secureName] = array() ;
2458 array_push ( $this->rc_cache
[$secureName] , $rc ) ;
2463 function endImageHistoryList()
2469 /* This function is called by all recent changes variants, by the page history,
2470 and by the user contributions list. It is responsible for formatting edit
2471 comments. It escapes any HTML in the comment, but adds some CSS to format
2472 auto-generated comments (from section editing) and formats [[wikilinks]].
2473 Main author: Erik Möller (moeller@scireview.de)
2475 function formatComment($comment)
2478 $comment=wfEscapeHTML($comment);
2480 # The pattern for autogen comments is / * foo * /, which makes for
2482 # We look for all comments, match any text before and after the comment,
2483 # add a separator where needed and format the comment itself with CSS
2484 while (preg_match('/(.*)\/\*\s*(.*?)\s*\*\/(.*)/', $comment,$match)) {
2489 if($pre) { $auto = $sep.' '.$auto; }
2490 if($post) { $auto .= ' '.$sep; }
2491 $auto='<span class="autocomment">'.$auto.'</span>';
2492 $comment=$pre.$auto.$post;
2495 # format regular and media links - all other wiki formatting
2497 while(preg_match('/\[\[(.*?)(\|(.*?))*\]\]/',$comment,$match)) {
2499 $medians = $wgLang->getNsText(Namespace::getMedia()).':';
2501 if(preg_match('/^'.$medians.'/i',$match[1])) {
2502 $func='makeMediaLink';
2504 # Handle link renaming [[foo|text]] will show link as "text"
2505 if(isset($match[3]) ) {
2507 preg_replace('/\[\[(.*?)\]\]/',
2508 $this->$func($match[1],$match[3]),$comment,1);
2511 preg_replace('/\[\[(.*?)\]\]/',
2512 $this->$func($match[1],$match[1]),$comment,1);
2520 function imageHistoryLine( $iscur, $timestamp, $img, $user, $usertext, $size, $description )
2522 global $wgUser, $wgLang, $wgTitle;
2524 $datetime = $wgLang->timeanddate( $timestamp, true );
2525 $del = wfMsg( 'deleteimg' );
2526 $cur = wfMsg( 'cur' );
2529 $url = Image
::wfImageUrl( $img );
2531 if ( $wgUser->isSysop() ) {
2532 $link = $wgTitle->escapeLocalURL( 'image=' . $wgTitle->getPartialURL() .
2534 $style = $this->getInternalLinkAttributes( $link, $del );
2536 $dlink = '<a href="'.$link.'"'.$style.'>'.$del.'</a>';
2541 $url = wfEscapeHTML( wfImageArchiveUrl( $img ) );
2542 if( $wgUser->getID() != 0 ) {
2543 $rlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2544 wfMsg( 'revertimg' ), 'action=revert&oldimage=' .
2545 urlencode( $img ) );
2546 $dlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2547 $del, 'action=delete&oldimage=' . urlencode( $img ) );
2549 # Having live active links for non-logged in users
2550 # means that bots and spiders crawling our site can
2551 # inadvertently change content. Baaaad idea.
2552 $rlink = wfMsg( 'revertimg' );
2557 $userlink = $usertext;
2559 $userlink = $this->makeLink( $wgLang->getNsText( Namespace::getUser() ) .
2560 ':'.$usertext, $usertext );
2562 $nbytes = wfMsg( 'nbytes', $size );
2563 $style = $this->getInternalLinkAttributes( $url, $datetime );
2565 $s = "<li> ({$dlink}) ({$rlink}) <a href=\"{$url}\"{$style}>{$datetime}</a>"
2566 . " . . {$userlink} ({$nbytes})";
2568 if ( '' != $description && '*' != $description ) {
2569 $sk=$wgUser->getSkin();
2570 $s .= $wgLang->emphasize(' (' . $sk->formatComment($description) . ')');
2576 function tocIndent($level) {
2577 return str_repeat( '<div class="tocindent">'."\n", $level>0 ?
$level : 0 );
2580 function tocUnindent($level) {
2581 return str_repeat( "</div>\n", $level>0 ?
$level : 0 );
2584 # parameter level defines if we are on an indentation level
2585 function tocLine( $anchor, $tocline, $level ) {
2586 $link = '<a href="#'.$anchor.'">'.$tocline.'</a><br />';
2590 return '<div class="tocline">'.$link."</div>\n";
2595 function tocTable($toc) {
2596 # note to CSS fanatics: putting this in a div does not work -- div won't auto-expand
2597 # try min-width & co when somebody gets a chance
2598 $hideline = ' <script type="text/javascript">showTocToggle("' . addslashes( wfMsg('showtoc') ) . '","' . addslashes( wfMsg('hidetoc') ) . '")</script>';
2600 '<table border="0" id="toc"><tr id="toctitle"><td align="center">'."\n".
2601 '<b>'.wfMsg('toc').'</b>' .
2603 '</td></tr><tr id="tocinside"><td>'."\n".
2604 $toc."</td></tr></table>\n";
2607 # These two do not check for permissions: check $wgTitle->userCanEdit before calling them
2608 function editSectionScript( $section, $head ) {
2609 global $wgTitle, $wgRequest;
2610 if( $wgRequest->getInt( 'oldid' ) && ( $wgRequest->getVal( 'diff' ) != '0' ) ) {
2613 $url = $wgTitle->escapeLocalURL( 'action=edit§ion='.$section );
2614 return '<span oncontextmenu=\'document.location="'.$url.'";return false;\'>'.$head.'</span>';
2617 function editSectionLink( $section ) {
2619 global $wgTitle, $wgUser, $wgLang;
2621 if( $wgRequest->getInt( 'oldid' ) && ( $wgRequest->getVal( 'diff' ) != '0' ) ) {
2622 # Section edit links would be out of sync on an old page.
2623 # But, if we're diffing to the current page, they'll be
2628 $editurl = '§ion='.$section;
2629 $url = $this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg('editsection'),'action=edit'.$editurl);
2631 if( $wgLang->isRTL() ) {
2633 $nearside = 'right';
2638 return "<div class=\"editsection\" style=\"float:$farside;margin-$nearside:5px;\">[".$url."]</div>";
2642 // This function is called by EditPage.php and shows a bulletin board style
2643 // toolbar for common editing functions. It can be disabled in the user preferences.
2644 // The necsesary JavaScript code can be found in style/wikibits.js.
2645 function getEditToolbar() {
2646 global $wgStylePath, $wgLang, $wgMimeType;
2648 // toolarray an array of arrays which each include the filename of
2649 // the button image (without path), the opening tag, the closing tag,
2650 // and optionally a sample text that is inserted between the two when no
2651 // selection is highlighted.
2652 // The tip text is shown when the user moves the mouse over the button.
2654 // Already here are accesskeys (key), which are not used yet until someone
2655 // can figure out a way to make them work in IE. However, we should make
2656 // sure these keys are not defined on the edit page.
2658 array( 'image'=>'button_bold.png',
2661 'sample'=>wfMsg('bold_sample'),
2662 'tip'=>wfMsg('bold_tip'),
2665 array( "image"=>"button_italic.png",
2668 "sample"=>wfMsg("italic_sample"),
2669 "tip"=>wfMsg("italic_tip"),
2672 array( "image"=>"button_link.png",
2675 "sample"=>wfMsg("link_sample"),
2676 "tip"=>wfMsg("link_tip"),
2679 array( "image"=>"button_extlink.png",
2682 "sample"=>wfMsg("extlink_sample"),
2683 "tip"=>wfMsg("extlink_tip"),
2686 array( "image"=>"button_headline.png",
2689 "sample"=>wfMsg("headline_sample"),
2690 "tip"=>wfMsg("headline_tip"),
2693 array( "image"=>"button_image.png",
2694 "open"=>"[[".$wgLang->getNsText(NS_IMAGE
).":",
2696 "sample"=>wfMsg("image_sample"),
2697 "tip"=>wfMsg("image_tip"),
2700 array( "image"=>"button_media.png",
2701 "open"=>"[[".$wgLang->getNsText(NS_MEDIA
).":",
2703 "sample"=>wfMsg("media_sample"),
2704 "tip"=>wfMsg("media_tip"),
2707 array( "image"=>"button_math.png",
2708 "open"=>"\\<math\\>",
2709 "close"=>"\\</math\\>",
2710 "sample"=>wfMsg("math_sample"),
2711 "tip"=>wfMsg("math_tip"),
2714 array( "image"=>"button_nowiki.png",
2715 "open"=>"\\<nowiki\\>",
2716 "close"=>"\\</nowiki\\>",
2717 "sample"=>wfMsg("nowiki_sample"),
2718 "tip"=>wfMsg("nowiki_tip"),
2721 array( "image"=>"button_sig.png",
2725 "tip"=>wfMsg("sig_tip"),
2728 array( "image"=>"button_hr.png",
2729 "open"=>"\\n----\\n",
2732 "tip"=>wfMsg("hr_tip"),
2736 $toolbar ="<script type='text/javascript'>\n/*<![CDATA[*/\n";
2738 $toolbar.="document.writeln(\"<div id='toolbar'>\");\n";
2739 foreach($toolarray as $tool) {
2741 $image=$wgStylePath.'/images/'.$tool['image'];
2742 $open=$tool['open'];
2743 $close=$tool['close'];
2744 $sample = addslashes( $tool['sample'] );
2746 // Note that we use the tip both for the ALT tag and the TITLE tag of the image.
2747 // Older browsers show a "speedtip" type message only for ALT.
2748 // Ideally these should be different, realistically they
2749 // probably don't need to be.
2750 $tip = addslashes( $tool['tip'] );
2752 #$key = $tool["key"];
2754 $toolbar.="addButton('$image','$tip','$open','$close','$sample');\n";
2757 $toolbar.="addInfobox('" . addslashes( wfMsg( "infobox" ) ) . "','" . addslashes(wfMsg("infobox_alert")) . "');\n";
2758 $toolbar.="document.writeln(\"</div>\");\n";
2760 $toolbar.="/*]]>*/\n</script>";