4 require_once( 'Feed.php' ); // should not be called if the actual page isn't feed enabled
5 require_once( 'Image.php' );
7 # These are the INTERNAL names, which get mapped
8 # directly to class names. For display purposes, the
9 # Language class has internationalized names
11 /* private */ $wgValidSkinNames = array(
12 'standard' => 'Standard',
13 'nostalgia' => 'Nostalgia',
14 'cologneblue' => 'CologneBlue'
17 #$wgValidSkinNames[] = 'PHPTal';
18 #$wgValidSkinNames['davinci'] = 'DaVinci';
19 #$wgValidSkinNames['mono'] = 'Mono';
20 $wgValidSkinNames['monobook'] = 'MonoBook';
21 $wgValidSkinNames['myskin'] = 'MySkin';
22 #$wgValidSkinNames['monobookminimal'] = 'MonoBookMinimal';
25 require_once( 'RecentChange.php' );
27 class RCCacheEntry
extends RecentChange
29 var $secureName, $link;
30 var $curlink , $difflink, $lastlink , $usertalklink , $versionlink ;
31 var $userlink, $timestamp, $watched;
33 function newFromParent( $rc )
35 $rc2 = new RCCacheEntry
;
36 $rc2->mAttribs
= $rc->mAttribs
;
37 $rc2->mExtra
= $rc->mExtra
;
44 /* private */ var $lastdate, $lastline;
45 var $linktrail ; # linktrail regexp
46 var $rc_cache ; # Cache for Enhanced Recent Changes
47 var $rcCacheIndex ; # Recent Changes Cache Counter for visibility toggle
52 $this->linktrail
= wfMsg('linktrail');
55 function getSkinNames()
57 global $wgValidSkinNames;
58 return $wgValidSkinNames;
61 function getStylesheet()
63 return 'wikistandard.css';
65 function getSkinName() {
71 global $wgOut, $wgUser;
73 if ( $wgOut->isQuickbarSuppressed() ) { return 0; }
74 $q = $wgUser->getOption( 'quickbar' );
75 if ( '' == $q ) { $q = 0; }
79 function initPage( &$out )
81 $fname = 'Skin::initPage';
82 wfProfileIn( $fname );
84 $out->addLink( array( 'rel' => 'shortcut icon', 'href' => '/favicon.ico' ) );
86 $this->addMetadataLinks($out);
88 wfProfileOut( $fname );
91 function addMetadataLinks( &$out ) {
92 global $wgTitle, $wgEnableDublinCoreRdf, $wgEnableCreativeCommonsRdf, $wgRdfMimeType, $action;
93 global $wgRightsPage, $wgRightsUrl;
95 if( $out->isArticleRelated() ) {
96 # note: buggy CC software only reads first "meta" link
97 if( $wgEnableCreativeCommonsRdf ) {
98 $out->addMetadataLink( array(
99 'title' => 'Creative Commons',
100 'type' => 'application/rdf+xml',
101 'href' => $wgTitle->getLocalURL( 'action=creativecommons') ) );
103 if( $wgEnableDublinCoreRdf ) {
104 $out->addMetadataLink( array(
105 'title' => 'Dublin Core',
106 'type' => 'application/rdf+xml',
107 'href' => $wgTitle->getLocalURL( 'action=dublincore' ) ) );
111 if( $wgRightsPage ) {
112 $copy = Title
::newFromText( $wgRightsPage );
114 $copyright = $copy->getLocalURL();
117 if( !$copyright && $wgRightsUrl ) {
118 $copyright = $wgRightsUrl;
121 $out->addLink( array(
122 'rel' => 'copyright',
123 'href' => $copyright ) );
127 function outputPage( &$out ) {
128 global $wgDebugComments;
130 wfProfileIn( 'Skin::outputPage' );
131 $this->initPage( $out );
132 $out->out( $out->headElement() );
134 $out->out( "\n<body" );
135 $ops = $this->getBodyOptions();
136 foreach ( $ops as $name => $val ) {
137 $out->out( " $name='$val'" );
140 if ( $wgDebugComments ) {
141 $out->out( "<!-- Wiki debugging output:\n" .
142 $out->mDebugtext
. "-->\n" );
144 $out->out( $this->beforeContent() );
146 $out->out( $out->mBodytext
. "\n" );
148 $out->out( $this->afterContent() );
151 $out->out( $out->reportTime() );
153 $out->out( "\n</body></html>" );
156 function getHeadScripts() {
157 global $wgStylePath, $wgUser, $wgLang, $wgAllowUserJs;
158 $r = "<script type=\"text/javascript\" src=\"{$wgStylePath}/wikibits.js\"></script>\n";
159 if( $wgAllowUserJs && $wgUser->getID() != 0 ) { # logged in
160 $userpage = $wgLang->getNsText( Namespace::getUser() ) . ":" . $wgUser->getName();
161 $userjs = htmlspecialchars($this->makeUrl($userpage.'/'.$this->getSkinName().'.js', 'action=raw&ctype=text/javascript'));
162 $r .= '<script type="text/javascript" src="'.$userjs."\"></script>\n";
167 # get the user/site-specific stylesheet, SkinPHPTal called from RawPage.php (settings are cached that way)
168 function getUserStylesheet() {
169 global $wgOut, $wgStylePath, $wgLang, $wgUser, $wgRequest, $wgTitle, $wgAllowUserCss;
170 $sheet = $this->getStylesheet();
171 $action = $wgRequest->getText('action');
172 $s = "@import \"$wgStylePath/$sheet\";\n";
173 if($wgLang->isRTL()) $s .= "@import \"$wgStylePath/common_rtl.css\";\n";
174 if( $wgAllowUserCss && $wgUser->getID() != 0 ) { # logged in
175 if($wgTitle->isCssSubpage() and $action == 'submit' and $wgTitle->userCanEditCssJsSubpage()) {
176 $s .= $wgRequest->getText('wpTextbox1');
178 $userpage = $wgLang->getNsText( Namespace::getUser() ) . ":" . $wgUser->getName();
179 $s.= '@import "'.$this->makeUrl($userpage.'/'.$this->getSkinName().'.css', 'action=raw&ctype=text/css').'";'."\n";
182 $s .= $this->doGetUserStyles();
185 # placeholder, returns generated js in monobook
186 function getUserJs() {
190 function getUserStyles()
192 global $wgOut, $wgStylePath, $wgLang;
193 $s = "<style type='text/css'>\n";
194 $s .= "/*/*/\n"; # <-- Hide the styles from Netscape 4 without hiding them from IE/Mac
195 $s .= $this->getUserStylesheet();
201 function doGetUserStyles()
203 global $wgUser, $wgLang;
205 $csspage = $wgLang->getNsText( NS_MEDIAWIKI
) . ":" . $this->getSkinName() . ".css";
206 $s = '@import "'.$this->makeUrl($csspage, 'action=raw&ctype=text/css')."\";\n";
208 if ( 1 == $wgUser->getOption( 'underline' ) ) {
209 # Don't override browser settings
213 $s .= "a { text-decoration: none; }\n";
215 if ( 1 == $wgUser->getOption( 'highlightbroken' ) ) {
216 $s .= "a.new, #quickbar a.new { color: #CC2200; }\n";
218 if ( 1 == $wgUser->getOption( 'justify' ) ) {
219 $s .= "#article { text-align: justify; }\n";
224 function getBodyOptions()
226 global $wgUser, $wgTitle, $wgNamespaceBackgrounds, $wgOut, $wgRequest;
228 extract( $wgRequest->getValues( 'oldid', 'redirect', 'diff' ) );
230 if ( 0 != $wgTitle->getNamespace() ) {
231 $a = array( 'bgcolor' => '#ffffec' );
233 else $a = array( 'bgcolor' => '#FFFFFF' );
234 if($wgOut->isArticle() && $wgUser->getOption('editondblclick') &&
235 (!$wgTitle->isProtected() ||
$wgUser->isSysop()) ) {
236 $t = wfMsg( 'editthispage' );
238 if ( !empty($redirect) ) {
239 $red = "&redirect={$redirect}";
241 if ( !empty($oldid) && ! isset( $diff ) ) {
242 $oid = "&oldid={$oldid}";
244 $s = $wgTitle->getFullURL( "action=edit{$oid}{$red}" );
245 $s = 'document.location = "' .$s .'";';
246 $a +
= array ('ondblclick' => $s);
249 $a['onload'] = $wgOut->getOnloadHandler();
253 function getExternalLinkAttributes( $link, $text, $class='' )
255 global $wgUser, $wgOut, $wgLang;
257 $link = urldecode( $link );
258 $link = $wgLang->checkTitleEncoding( $link );
259 $link = str_replace( '_', ' ', $link );
260 $link = wfEscapeHTML( $link );
262 $r = ($class != '') ?
" class='$class'" : " class='external'";
264 if ( 1 == $wgUser->getOption( 'hover' ) ) {
265 $r .= " title=\"{$link}\"";
270 function getInternalLinkAttributes( $link, $text, $broken = false )
272 global $wgUser, $wgOut;
274 $link = urldecode( $link );
275 $link = str_replace( '_', ' ', $link );
276 $link = wfEscapeHTML( $link );
278 if ( $broken == 'stub' ) {
279 $r = ' class="stub"';
280 } else if ( $broken == 'yes' ) {
286 if ( 1 == $wgUser->getOption( 'hover' ) ) {
287 $r .= " title=\"{$link}\"";
292 function getInternalLinkAttributesObj( &$nt, $text, $broken = false )
294 global $wgUser, $wgOut;
296 if ( $broken == 'stub' ) {
297 $r = ' class="stub"';
298 } else if ( $broken == 'yes' ) {
304 if ( 1 == $wgUser->getOption( 'hover' ) ) {
305 $r .= ' title ="' . $nt->getEscapedText() . '"';
316 # This will be called immediately after the <body> tag. Split into
317 # two functions to make it easier to subclass.
319 function beforeContent()
321 global $wgUser, $wgOut;
323 return $this->doBeforeContent();
326 function doBeforeContent()
328 global $wgUser, $wgOut, $wgTitle, $wgLang, $wgSiteNotice;
329 $fname = 'Skin::doBeforeContent';
330 wfProfileIn( $fname );
333 $qb = $this->qbSetting();
335 if( $langlinks = $this->otherLanguages() ) {
341 $borderhack = 'class="top"';
344 $s .= "\n<div id='content'>\n<div id='topbar'>\n" .
345 "<table border='0' cellspacing='0' width='98%'>\n<tr>\n";
348 $left = ($qb == 1 ||
$qb == 3);
349 if($wgLang->isRTL()) $left = !$left;
352 $s .= "<td class='top' align='left' valign='top' rowspan='{$rows}'>\n" .
353 $this->logoText() . '</td>';
355 $s .= $this->getQuickbarCompensator( $rows );
357 $l = $wgLang->isRTL() ?
'right' : 'left';
358 $s .= "<td {$borderhack} align='$l' valign='top'>\n";
360 $s .= $this->topLinks() ;
361 $s .= "<p class='subtitle'>" . $this->pageTitleLinks() . "</p>\n";
363 $r = $wgLang->isRTL() ?
"left" : "right";
364 $s .= "</td>\n<td {$borderhack} valign='top' align='$r' nowrap='nowrap'>";
365 $s .= $this->nameAndLogin();
366 $s .= "\n<br />" . $this->searchForm() . "</td>";
369 $s .= "</tr>\n<tr>\n<td class='top' colspan=\"2\">$langlinks</td>\n";
372 if ( $shove && !$left ) { # Right
373 $s .= $this->getQuickbarCompensator( $rows );
375 $s .= "</tr>\n</table>\n</div>\n";
376 $s .= "\n<div id='article'>\n";
378 if( $wgSiteNotice ) {
379 $s .= "\n<div id='siteNotice'>$wgSiteNotice</div>\n";
381 $s .= $this->pageTitle();
382 $s .= $this->pageSubtitle() ;
383 $s .= $this->getCategories();
384 wfProfileOut( $fname );
388 function getCategoryLinks () {
389 global $wgOut, $wgTitle, $wgUser, $wgParser;
390 global $wgUseCategoryMagic, $wgUseCategoryBrowser, $wgLang;
392 if( !$wgUseCategoryMagic ) return '' ;
393 if( count( $wgOut->mCategoryLinks
) == 0 ) return '';
395 # Taken out so that they will be displayed in previews -- TS
396 #if( !$wgOut->isArticle() ) return '';
398 $t = implode ( ' | ' , $wgOut->mCategoryLinks
) ;
399 $s = $this->makeKnownLink( 'Special:Categories',
400 wfMsg( 'categories' ), 'article=' . urlencode( $wgTitle->getPrefixedDBkey() ) )
403 if($wgUseCategoryBrowser) {
406 $s.= $wgTitle->getAllParentCategories($catstack);
412 function getCategories() {
413 $catlinks=$this->getCategoryLinks();
414 if(!empty($catlinks)) {
415 return "<p class='catlinks'>{$catlinks}</p>";
419 function getQuickbarCompensator( $rows = 1 )
421 return "<td width='152' rowspan='{$rows}'> </td>";
424 # This gets called immediately before the </body> tag.
426 function afterContent()
428 global $wgUser, $wgOut, $wgServer;
429 global $wgTitle, $wgLang;
431 $printfooter = "<div class=\"printfooter\">\n" . $this->printFooter() . "</div>\n";
432 return $printfooter . $this->doAfterContent();
435 function printFooter() {
437 $url = htmlspecialchars( $wgTitle->getFullURL() );
438 return "<p>" . wfMsg( "retrievedfrom", "<a href=\"$url\">$url</a>" ) .
439 "</p>\n\n<p>" . $this->pageStats() . "</p>\n";
442 function doAfterContent()
444 global $wgUser, $wgOut, $wgLang;
445 $fname = 'Skin::doAfterContent';
446 wfProfileIn( $fname );
447 wfProfileIn( $fname.'-1' );
449 $s = "\n</div><br style=\"clear:both\" />\n";
450 $s .= "\n<div id='footer'>";
451 $s .= '<table border="0" cellspacing="0"><tr>';
453 wfProfileOut( $fname.'-1' );
454 wfProfileIn( $fname.'-2' );
456 $qb = $this->qbSetting();
458 $left = ($qb == 1 ||
$qb == 3);
459 if($wgLang->isRTL()) $left = !$left;
461 if ( $shove && $left ) { # Left
462 $s .= $this->getQuickbarCompensator();
464 wfProfileOut( $fname.'-2' );
465 wfProfileIn( $fname.'-3' );
466 $l = $wgLang->isRTL() ?
'right' : 'left';
467 $s .= "<td class='bottom' align='$l' valign='top'>";
469 $s .= $this->bottomLinks();
470 $s .= "\n<br />" . $this->mainPageLink()
471 . ' | ' . $this->aboutLink()
472 . ' | ' . $this->specialLink( 'recentchanges' )
473 . ' | ' . $this->searchForm()
474 . '<br /><span id="pagestats">' . $this->pageStats() . '</span>';
477 if ( $shove && !$left ) { # Right
478 $s .= $this->getQuickbarCompensator();
480 $s .= "</tr></table>\n</div>\n</div>\n";
482 wfProfileOut( $fname.'-3' );
483 wfProfileIn( $fname.'-4' );
484 if ( 0 != $qb ) { $s .= $this->quickBar(); }
485 wfProfileOut( $fname.'-4' );
486 wfProfileOut( $fname );
490 function pageTitleLinks()
492 global $wgOut, $wgTitle, $wgUser, $wgLang, $wgUseApproval, $wgRequest;
494 extract( $wgRequest->getValues( 'oldid', 'diff' ) );
495 $action = $wgRequest->getText( 'action' );
497 $s = $this->printableLink();
498 if ( wfMsg ( 'disclaimers' ) != '-' ) $s .= ' | ' . $this->makeKnownLink( wfMsg( 'disclaimerpage' ), wfMsg( 'disclaimers' ) ) ;
500 if ( $wgOut->isArticleRelated() ) {
501 if ( $wgTitle->getNamespace() == Namespace::getImage() ) {
502 $name = $wgTitle->getDBkey();
503 $link = wfEscapeHTML( Image
::wfImageUrl( $name ) );
504 $style = $this->getInternalLinkAttributes( $link, $name );
505 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>";
507 # This will show the "Approve" link if $wgUseApproval=true;
508 if ( isset ( $wgUseApproval ) && $wgUseApproval )
510 $t = $wgTitle->getDBkey();
511 $name = 'Approve this article' ;
512 $link = "http://test.wikipedia.org/w/magnus/wiki.phtml?title={$t}&action=submit&doit=1" ;
513 #wfEscapeHTML( wfImageUrl( $name ) );
514 $style = $this->getExternalLinkAttributes( $link, $name );
515 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>" ;
518 if ( 'history' == $action ||
isset( $diff ) ||
isset( $oldid ) ) {
519 $s .= ' | ' . $this->makeKnownLink( $wgTitle->getPrefixedText(),
520 wfMsg( 'currentrev' ) );
523 if ( $wgUser->getNewtalk() ) {
524 # do not show "You have new messages" text when we are viewing our
527 if(!(strcmp($wgTitle->getText(),$wgUser->getName()) == 0 &&
528 $wgTitle->getNamespace()==Namespace::getTalk(Namespace::getUser()))) {
529 $n =$wgUser->getName();
530 $tl = $this->makeKnownLink( $wgLang->getNsText(
531 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
532 wfMsg('newmessageslink') );
533 $s.= ' | <strong>'. wfMsg( 'newmessages', $tl ) . '</strong>';
537 $undelete = $this->getUndeleteLink();
538 if( !empty( $undelete ) ) {
539 $s .= ' | '.$undelete;
544 function getUndeleteLink() {
545 global $wgUser, $wgTitle, $wgLang, $action;
546 if( $wgUser->isSysop() &&
547 (($wgTitle->getArticleId() == 0) ||
($action == "history")) &&
548 ($n = $wgTitle->isDeleted() ) ) {
549 return wfMsg( 'thisisdeleted',
550 $this->makeKnownLink(
551 $wgLang->SpecialPage( 'Undelete/' . $wgTitle->getPrefixedDBkey() ),
552 wfMsg( 'restorelink', $n ) ) );
557 function printableLink()
559 global $wgOut, $wgFeedClasses, $wgRequest;
561 $baseurl = $_SERVER['REQUEST_URI'];
562 if( strpos( '?', $baseurl ) == false ) {
567 $baseurl = htmlspecialchars( $baseurl );
568 $printurl = $wgRequest->escapeAppendQuery( 'printable=yes' );
570 $s = "<a href=\"$printurl\">" . wfMsg( 'printableversion' ) . '</a>';
571 if( $wgOut->isSyndicated() ) {
572 foreach( $wgFeedClasses as $format => $class ) {
573 $feedurl = $wgRequest->escapeAppendQuery( "feed=$format" );
574 $s .= " | <a href=\"$feedurl\">{$format}</a>";
582 global $wgOut, $wgTitle, $wgUser;
584 $s = '<h1 class="pagetitle">' . htmlspecialchars( $wgOut->getPageTitle() ) . '</h1>';
585 if($wgUser->getOption( 'editsectiononrightclick' ) && $wgTitle->userCanEdit()) { $s=$this->editSectionScript(0,$s);}
589 function pageSubtitle()
593 $sub = $wgOut->getSubtitle();
595 global $wgExtraSubtitle;
596 $sub = wfMsg( 'fromwikipedia' ) . $wgExtraSubtitle;
598 $subpages = $this->subPageSubtitle();
599 $sub .= !empty($subpages)?
"</p><p class='subpages'>$subpages":'';
600 $s = "<p class='subtitle'>{$sub}</p>\n";
604 function subPageSubtitle()
606 global $wgOut,$wgTitle,$wgNamespacesWithSubpages;
608 if($wgOut->isArticle() && !empty($wgNamespacesWithSubpages[$wgTitle->getNamespace()])) {
609 $ptext=$wgTitle->getPrefixedText();
610 if(preg_match('/\//',$ptext)) {
611 $links = explode('/',$ptext);
614 foreach($links as $link) {
616 if ($c<count($links)) {
617 $growinglink .= $link;
618 $getlink = $this->makeLink( $growinglink, $link );
619 if(preg_match('/class="new"/i',$getlink)) { break; } # this is a hack, but it saves time
623 $subpages .= '< ';
625 $subpages .= $getlink;
634 function nameAndLogin()
636 global $wgUser, $wgTitle, $wgLang, $wgShowIPinHeader, $wgIP;
638 $li = $wgLang->specialPage( 'Userlogin' );
639 $lo = $wgLang->specialPage( 'Userlogout' );
642 if ( 0 == $wgUser->getID() ) {
643 if( $wgShowIPinHeader && isset( $_COOKIE[ini_get('session.name')] ) ) {
646 $tl = $this->makeKnownLink( $wgLang->getNsText(
647 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
648 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
650 $s .= $n . ' ('.$tl.')';
652 $s .= wfMsg('notloggedin');
655 $rt = $wgTitle->getPrefixedURL();
656 if ( 0 == strcasecmp( urlencode( $lo ), $rt ) ) {
658 } else { $q = "returnto={$rt}"; }
660 $s .= "\n<br />" . $this->makeKnownLink( $li,
661 wfMsg( 'login' ), $q );
663 $n = $wgUser->getName();
664 $rt = $wgTitle->getPrefixedURL();
665 $tl = $this->makeKnownLink( $wgLang->getNsText(
666 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
667 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
671 $s .= $this->makeKnownLink( $wgLang->getNsText(
672 Namespace::getUser() ) . ":{$n}", $n ) . "{$tl}<br />" .
673 $this->makeKnownLink( $lo, wfMsg( 'logout' ),
674 "returnto={$rt}" ) . ' | ' .
675 $this->specialLink( 'preferences' );
677 $s .= ' | ' . $this->makeKnownLink( wfMsg( 'helppage' ),
683 function getSearchLink() {
684 $searchPage =& Title
::makeTitle( NS_SPECIAL
, 'Search' );
685 return $searchPage->getLocalURL();
688 function escapeSearchLink() {
689 return htmlspecialchars( $this->getSearchLink() );
692 function searchForm()
695 $search = $wgRequest->getText( 'search' );
697 $s = '<form name="search" class="inline" method="post" action="'
698 . $this->escapeSearchLink() . "\">\n"
699 . '<input type="text" name="search" size="19" value="'
700 . htmlspecialchars(substr($search,0,256)) . "\" />\n"
701 . '<input type="submit" name="go" value="' . wfMsg ('go') . '" /> '
702 . '<input type="submit" name="fulltext" value="' . wfMsg ('search') . "\" />\n</form>";
712 $s = $this->mainPageLink() . $sep
713 . $this->specialLink( 'recentchanges' );
715 if ( $wgOut->isArticleRelated() ) {
716 $s .= $sep . $this->editThisPage()
717 . $sep . $this->historyLink();
719 # Many people don't like this dropdown box
720 #$s .= $sep . $this->specialPagesList();
725 function bottomLinks()
727 global $wgOut, $wgUser, $wgTitle;
731 if ( $wgOut->isArticleRelated() ) {
732 $s .= '<strong>' . $this->editThisPage() . '</strong>';
733 if ( 0 != $wgUser->getID() ) {
734 $s .= $sep . $this->watchThisPage();
736 $s .= $sep . $this->talkLink()
737 . $sep . $this->historyLink()
738 . $sep . $this->whatLinksHere()
739 . $sep . $this->watchPageLinksLink();
741 if ( $wgTitle->getNamespace() == Namespace::getUser()
742 ||
$wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser()) )
745 $id=User
::idFromName($wgTitle->getText());
746 $ip=User
::isIP($wgTitle->getText());
748 if($id ||
$ip) { # both anons and non-anons have contri list
749 $s .= $sep . $this->userContribsLink();
751 if ( 0 != $wgUser->getID() ) { # show only to signed in users
752 if($id) { # can only email non-anons
753 $s .= $sep . $this->emailUserLink();
757 if ( $wgUser->isSysop() && $wgTitle->getArticleId() ) {
758 $s .= "\n<br />" . $this->deleteThisPage() .
759 $sep . $this->protectThisPage() .
760 $sep . $this->moveThisPage();
762 $s .= "<br />\n" . $this->otherLanguages();
769 global $wgOut, $wgLang, $wgArticle, $wgRequest;
770 global $wgDisableCounters, $wgMaxCredits, $wgShowCreditsIfMax;
772 extract( $wgRequest->getValues( 'oldid', 'diff' ) );
773 if ( ! $wgOut->isArticle() ) { return ''; }
774 if ( isset( $oldid ) ||
isset( $diff ) ) { return ''; }
775 if ( 0 == $wgArticle->getID() ) { return ''; }
778 if ( !$wgDisableCounters ) {
779 $count = $wgLang->formatNum( $wgArticle->getCount() );
781 $s = wfMsg( 'viewcount', $count );
785 if (isset($wgMaxCredits) && $wgMaxCredits != 0) {
786 require_once("Credits.php");
787 $s .= ' ' . getCredits($wgArticle, $wgMaxCredits, $wgShowCreditsIfMax);
789 $s .= $this->lastModified();
792 return $s . ' ' . $this->getCopyright();
795 function getCopyright() {
796 global $wgRightsPage, $wgRightsUrl, $wgRightsText, $wgRequest;
799 $oldid = $wgRequest->getVal( 'oldid' );
800 $diff = $wgRequest->getVal( 'diff' );
802 if ( !is_null( $oldid ) && is_null( $diff ) && wfMsg( 'history_copyright' ) !== '-' ) {
803 $msg = 'history_copyright';
809 if( $wgRightsPage ) {
810 $link = $this->makeKnownLink( $wgRightsPage, $wgRightsText );
811 } elseif( $wgRightsUrl ) {
812 $link = $this->makeExternalLink( $wgRightsUrl, $wgRightsText );
817 $out .= wfMsg( $msg, $link );
821 function getCopyrightIcon() {
822 global $wgRightsPage, $wgRightsUrl, $wgRightsText, $wgRightsIcon;
824 if( $wgRightsIcon ) {
825 $icon = htmlspecialchars( $wgRightsIcon );
827 $url = htmlspecialchars( $wgRightsUrl );
828 $out .= '<a href="'.$url.'">';
830 $text = htmlspecialchars( $wgRightsText );
831 $out .= "<img src=\"$icon\" alt='$text' />";
839 function getPoweredBy() {
841 $url = htmlspecialchars( "$wgStylePath/images/poweredby_mediawiki_88x31.png" );
842 $img = '<a href="http://www.mediawiki.org/"><img src="'.$url.'" alt="MediaWiki" /></a>';
846 function lastModified()
848 global $wgLang, $wgArticle;
850 $timestamp = $wgArticle->getTimestamp();
852 $d = $wgLang->timeanddate( $wgArticle->getTimestamp(), true );
853 $s = ' ' . wfMsg( 'lastmodified', $d );
860 function logoText( $align = '' )
862 if ( '' != $align ) { $a = ' align="'.$align.'"'; }
865 $mp = wfMsg( 'mainpage' );
866 $titleObj = Title
::newFromText( $mp );
867 $s = '<a href="' . $titleObj->escapeLocalURL()
868 . '"><img'.$a.' src="'
869 . $this->getLogo() . '" alt="' . "[{$mp}]\" /></a>";
875 global $wgOut, $wgTitle, $wgUser, $wgRequest, $wgLang;
876 global $wgDisableUploads, $wgRemoteUploads;
878 $fname = 'Skin::quickBar';
879 wfProfileIn( $fname );
881 $action = $wgRequest->getText( 'action' );
882 $wpPreview = $wgRequest->getBool( 'wpPreview' );
883 $tns=$wgTitle->getNamespace();
885 $s = "\n<div id='quickbar'>";
886 $s .= "\n" . $this->logoText() . "\n<hr class='sep' />";
889 $s .= $this->mainPageLink()
890 . $sep . $this->specialLink( 'recentchanges' )
891 . $sep . $this->specialLink( 'randompage' );
892 if ($wgUser->getID()) {
893 $s.= $sep . $this->specialLink( 'watchlist' ) ;
894 $s .= $sep .$this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
895 wfMsg( 'mycontris' ), 'target=' . wfUrlencode($wgUser->getName() ) );
898 // only show watchlist link if logged in
899 if ( wfMsg ( 'currentevents' ) != '-' ) $s .= $sep . $this->makeKnownLink( wfMsg( 'currentevents' ), '' ) ;
900 $s .= "\n<br /><hr class='sep' />";
901 $articleExists = $wgTitle->getArticleId();
902 if ( $wgOut->isArticle() ||
$action =='edit' ||
$action =='history' ||
$wpPreview) {
903 if($wgOut->isArticle()) {
904 $s .= '<strong>' . $this->editThisPage() . '</strong>';
905 } else { # backlink to the article in edit or history mode
906 if($articleExists){ # no backlink if no article
909 $text = wfMsg('articlepage');
912 $text = wfMsg('viewtalkpage');
915 $text = wfMsg('userpage');
918 $text = wfMsg('viewtalkpage');
921 $text = wfMsg('wikipediapage');
924 $text = wfMsg('viewtalkpage');
927 $text = wfMsg('imagepage');
930 $text = wfMsg('viewtalkpage');
933 $text= wfMsg('articlepage');
936 $link = $wgTitle->getText();
937 if ($nstext = $wgLang->getNsText($tns) ) { # add namespace if necessary
938 $link = $nstext . ':' . $link ;
941 $s .= $this->makeLink( $link, $text );
942 } elseif( $wgTitle->getNamespace() != Namespace::getSpecial() ) {
943 # we just throw in a "New page" text to tell the user that he's in edit mode,
944 # and to avoid messing with the separator that is prepended to the next item
945 $s .= '<strong>' . wfMsg('newpage') . '</strong>';
951 if( $tns%2
&& $action!='edit' && !$wpPreview) {
952 $s.= '<br />'.$this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg('postcomment'),'action=edit§ion=new');
956 watching could cause problems in edit mode:
957 if user edits article, then loads "watch this article" in background and then saves
958 article with "Watch this article" checkbox disabled, the article is transparently
959 unwatched. Therefore we do not show the "Watch this page" link in edit mode
961 if ( 0 != $wgUser->getID() && $articleExists) {
962 if($action!='edit' && $action != 'submit' )
964 $s .= $sep . $this->watchThisPage();
966 if ( $wgTitle->userCanEdit() )
967 $s .= $sep . $this->moveThisPage();
969 if ( $wgUser->isSysop() and $articleExists ) {
970 $s .= $sep . $this->deleteThisPage() .
971 $sep . $this->protectThisPage();
973 $s .= $sep . $this->talkLink();
974 if ($articleExists && $action !='history') {
975 $s .= $sep . $this->historyLink();
977 $s.=$sep . $this->whatLinksHere();
979 if($wgOut->isArticleRelated()) {
980 $s .= $sep . $this->watchPageLinksLink();
983 if ( Namespace::getUser() == $wgTitle->getNamespace()
984 ||
$wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser())
987 $id=User
::idFromName($wgTitle->getText());
988 $ip=User
::isIP($wgTitle->getText());
991 $s .= $sep . $this->userContribsLink();
993 if ( 0 != $wgUser->getID() ) {
994 if($id) { # can only email real users
995 $s .= $sep . $this->emailUserLink();
999 $s .= "\n<br /><hr class='sep' />";
1002 if ( 0 != $wgUser->getID() && ( !$wgDisableUploads ||
$wgRemoteUploads ) ) {
1003 $s .= $this->specialLink( 'upload' ) . $sep;
1005 $s .= $this->specialLink( 'specialpages' )
1006 . $sep . $this->bugReportsLink();
1008 global $wgSiteSupportPage;
1009 if( $wgSiteSupportPage ) {
1010 $s .= "\n<br /><a href=\"" . htmlspecialchars( $wgSiteSupportPage ) .
1011 '" class="internal">' . wfMsg( 'sitesupport' ) . '</a>';
1014 $s .= "\n<br /></div>\n";
1015 wfProfileOut( $fname );
1019 function specialPagesList()
1021 global $wgUser, $wgOut, $wgLang, $wgServer, $wgRedirectScript;
1022 require_once('SpecialPage.php');
1024 $pages = SpecialPage
::getPages();
1026 foreach ( $pages[''] as $name => $page ) {
1027 $a[$name] = $page->getDescription();
1029 if ( $wgUser->isSysop() )
1031 foreach ( $pages['sysop'] as $name => $page ) {
1032 $a[$name] = $page->getDescription();
1035 if ( $wgUser->isDeveloper() )
1037 foreach ( $pages['developer'] as $name => $page ) {
1038 $a[$name] = $page->getDescription() ;
1041 $go = wfMsg( 'go' );
1042 $sp = wfMsg( 'specialpages' );
1043 $spp = $wgLang->specialPage( 'Specialpages' );
1045 $s = '<form id="specialpages" method="get" class="inline" ' .
1046 'action="' . htmlspecialchars( "{$wgServer}{$wgRedirectScript}" ) . "\">\n";
1047 $s .= "<select name=\"wpDropdown\">\n";
1048 $s .= "<option value=\"{$spp}\">{$sp}</option>\n";
1050 foreach ( $a as $name => $desc ) {
1051 $p = $wgLang->specialPage( $name );
1052 $s .= "<option value=\"{$p}\">{$desc}</option>\n";
1054 $s .= "</select>\n";
1055 $s .= "<input type='submit' value=\"{$go}\" name='redirect' />\n";
1060 function mainPageLink()
1062 $mp = wfMsg( 'mainpage' );
1063 $s = $this->makeKnownLink( $mp, $mp );
1067 function copyrightLink()
1069 $s = $this->makeKnownLink( wfMsg( 'copyrightpage' ),
1070 wfMsg( 'copyrightpagename' ) );
1074 function aboutLink()
1076 $s = $this->makeKnownLink( wfMsg( 'aboutpage' ),
1077 wfMsg( 'aboutwikipedia' ) );
1082 function disclaimerLink()
1084 $s = $this->makeKnownLink( wfMsg( 'disclaimerpage' ),
1085 wfMsg( 'disclaimers' ) );
1089 function editThisPage()
1091 global $wgOut, $wgTitle, $wgRequest;
1093 $oldid = $wgRequest->getVal( 'oldid' );
1094 $diff = $wgRequest->getVal( 'diff' );
1095 $redirect = $wgRequest->getVal( 'redirect' );
1097 if ( ! $wgOut->isArticleRelated() ) {
1098 $s = wfMsg( 'protectedpage' );
1100 $n = $wgTitle->getPrefixedText();
1101 if ( $wgTitle->userCanEdit() ) {
1102 $t = wfMsg( 'editthispage' );
1104 #$t = wfMsg( "protectedpage" );
1105 $t = wfMsg( 'viewsource' );
1109 if ( !is_null( $redirect ) ) { $red = "&redirect={$redirect}"; }
1110 if ( $oldid && ! isset( $diff ) ) {
1111 $oid = "&oldid={$oldid}";
1113 $s = $this->makeKnownLink( $n, $t, "action=edit{$oid}{$red}" );
1118 function deleteThisPage()
1120 global $wgUser, $wgOut, $wgTitle, $wgRequest;
1122 $diff = $wgRequest->getVal( 'diff' );
1123 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
1124 $n = $wgTitle->getPrefixedText();
1125 $t = wfMsg( 'deletethispage' );
1127 $s = $this->makeKnownLink( $n, $t, 'action=delete' );
1134 function protectThisPage()
1136 global $wgUser, $wgOut, $wgTitle, $wgRequest;
1138 $diff = $wgRequest->getVal( 'diff' );
1139 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
1140 $n = $wgTitle->getPrefixedText();
1142 if ( $wgTitle->isProtected() ) {
1143 $t = wfMsg( 'unprotectthispage' );
1144 $q = 'action=unprotect';
1146 $t = wfMsg( 'protectthispage' );
1147 $q = 'action=protect';
1149 $s = $this->makeKnownLink( $n, $t, $q );
1156 function watchThisPage()
1158 global $wgUser, $wgOut, $wgTitle;
1160 if ( $wgOut->isArticleRelated() ) {
1161 $n = $wgTitle->getPrefixedText();
1163 if ( $wgTitle->userIsWatching() ) {
1164 $t = wfMsg( 'unwatchthispage' );
1165 $q = 'action=unwatch';
1167 $t = wfMsg( 'watchthispage' );
1168 $q = 'action=watch';
1170 $s = $this->makeKnownLink( $n, $t, $q );
1172 $s = wfMsg( 'notanarticle' );
1177 function moveThisPage()
1179 global $wgTitle, $wgLang;
1181 if ( $wgTitle->userCanEdit() ) {
1182 $s = $this->makeKnownLink( $wgLang->specialPage( 'Movepage' ),
1183 wfMsg( 'movethispage' ), 'target=' . $wgTitle->getPrefixedURL() );
1184 } // no message if page is protected - would be redundant
1188 function historyLink()
1192 $s = $this->makeKnownLink( $wgTitle->getPrefixedText(),
1193 wfMsg( 'history' ), 'action=history' );
1197 function whatLinksHere()
1199 global $wgTitle, $wgLang;
1201 $s = $this->makeKnownLink( $wgLang->specialPage( 'Whatlinkshere' ),
1202 wfMsg( 'whatlinkshere' ), 'target=' . $wgTitle->getPrefixedURL() );
1206 function userContribsLink()
1208 global $wgTitle, $wgLang;
1210 $s = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
1211 wfMsg( 'contributions' ), 'target=' . $wgTitle->getPartialURL() );
1215 function emailUserLink()
1217 global $wgTitle, $wgLang;
1219 $s = $this->makeKnownLink( $wgLang->specialPage( 'Emailuser' ),
1220 wfMsg( 'emailuser' ), 'target=' . $wgTitle->getPartialURL() );
1224 function watchPageLinksLink()
1226 global $wgOut, $wgTitle, $wgLang;
1228 if ( ! $wgOut->isArticleRelated() ) {
1229 $s = '(' . wfMsg( 'notanarticle' ) . ')';
1231 $s = $this->makeKnownLink( $wgLang->specialPage(
1232 'Recentchangeslinked' ), wfMsg( 'recentchangeslinked' ),
1233 'target=' . $wgTitle->getPrefixedURL() );
1238 function otherLanguages()
1240 global $wgOut, $wgLang, $wgTitle, $wgUseNewInterlanguage;
1242 $a = $wgOut->getLanguageLinks();
1243 if ( 0 == count( $a ) ) {
1244 if ( !$wgUseNewInterlanguage ) return '';
1245 $ns = $wgLang->getNsIndex ( $wgTitle->getNamespace () ) ;
1246 if ( $ns != 0 AND $ns != 1 ) return '' ;
1248 $x = 'mode=addlink&xt='.$wgTitle->getDBkey() ;
1249 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1250 wfMsg( 'intl' ) , $x );
1253 if ( !$wgUseNewInterlanguage ) {
1254 $s = wfMsg( 'otherlanguages' ) . ': ';
1256 global $wgLanguageCode ;
1257 $x = 'mode=zoom&xt='.$wgTitle->getDBkey() ;
1258 $x .= '&xl='.$wgLanguageCode ;
1259 $s = $this->makeKnownLink( $wgLang->specialPage( 'Intl' ),
1260 wfMsg( 'otherlanguages' ) , $x ) . ': ' ;
1263 $s = wfMsg( 'otherlanguages' ) . ': ';
1265 if($wgLang->isRTL()) $s .= '<span dir="LTR">';
1266 foreach( $a as $l ) {
1267 if ( ! $first ) { $s .= ' | '; }
1270 $nt = Title
::newFromText( $l );
1271 $url = $nt->getFullURL();
1272 $text = $wgLang->getLanguageName( $nt->getInterwiki() );
1274 if ( '' == $text ) { $text = $l; }
1275 $style = $this->getExternalLinkAttributes( $l, $text );
1276 $s .= "<a href=\"{$url}\"{$style}>{$text}</a>";
1278 if($wgLang->isRTL()) $s .= '</span>';
1282 function bugReportsLink()
1284 $s = $this->makeKnownLink( wfMsg( 'bugreportspage' ),
1285 wfMsg( 'bugreports' ) );
1291 global $wgLinkCache;
1292 $t1 = Title
::newFromText( gmdate( 'F j' ) );
1293 $t2 = Title
::newFromText( gmdate( 'Y' ) );
1295 $wgLinkCache->suspend();
1296 $id = $t1->getArticleID();
1297 $wgLinkCache->resume();
1300 $s = $this->makeBrokenLink( $t1->getText() );
1302 $s = $this->makeKnownLink( $t1->getText() );
1306 $wgLinkCache->suspend();
1307 $id = $t2->getArticleID();
1308 $wgLinkCache->resume();
1311 $s .= $this->makeBrokenLink( $t2->getText() );
1313 $s .= $this->makeKnownLink( $t2->getText() );
1320 global $wgLang, $wgTitle, $wgLinkCache;
1322 $tns = $wgTitle->getNamespace();
1323 if ( -1 == $tns ) { return ''; }
1325 $pn = $wgTitle->getText();
1326 $tp = wfMsg( 'talkpage' );
1327 if ( Namespace::isTalk( $tns ) ) {
1328 $lns = Namespace::getSubject( $tns );
1331 $text = wfMsg('articlepage');
1334 $text = wfMsg('userpage');
1337 $text = wfMsg('wikipediapage');
1340 $text = wfMsg('imagepage');
1343 $text= wfMsg('articlepage');
1347 $lns = Namespace::getTalk( $tns );
1350 $n = $wgLang->getNsText( $lns );
1351 if ( '' == $n ) { $link = $pn; }
1352 else { $link = $n.':'.$pn; }
1354 $wgLinkCache->suspend();
1355 $s = $this->makeLink( $link, $text );
1356 $wgLinkCache->resume();
1361 function commentLink()
1363 global $wgLang, $wgTitle, $wgLinkCache;
1365 $tns = $wgTitle->getNamespace();
1366 if ( -1 == $tns ) { return ''; }
1368 $lns = ( Namespace::isTalk( $tns ) ) ?
$tns : Namespace::getTalk( $tns );
1370 # assert Namespace::isTalk( $lns )
1372 $n = $wgLang->getNsText( $lns );
1373 $pn = $wgTitle->getText();
1377 $wgLinkCache->suspend();
1378 $s = $this->makeKnownLink($link, wfMsg('postcomment'), 'action=edit§ion=new');
1379 $wgLinkCache->resume();
1384 # After all the page content is transformed into HTML, it makes
1385 # a final pass through here for things like table backgrounds.
1387 function transformContent( $text )
1392 # Note: This function MUST call getArticleID() on the link,
1393 # otherwise the cache won't get updated properly. See LINKCACHE.DOC.
1395 function makeLink( $title, $text = '', $query = '', $trail = '' ) {
1396 wfProfileIn( 'Skin::makeLink' );
1397 $nt = Title
::newFromText( $title );
1399 $result = $this->makeLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1401 wfDebug( 'Invalid title passed to Skin::makeLink(): "'.$title."\"\n" );
1402 $result = $text == "" ?
$title : $text;
1405 wfProfileOut( 'Skin::makeLink' );
1409 function makeKnownLink( $title, $text = '', $query = '', $trail = '', $prefix = '',$aprops = '') {
1410 $nt = Title
::newFromText( $title );
1412 return $this->makeKnownLinkObj( Title
::newFromText( $title ), $text, $query, $trail, $prefix , $aprops );
1414 wfDebug( 'Invalid title passed to Skin::makeKnownLink(): "'.$title."\"\n" );
1415 return $text == '' ?
$title : $text;
1419 function makeBrokenLink( $title, $text = '', $query = '', $trail = '' ) {
1420 $nt = Title
::newFromText( $title );
1422 return $this->makeBrokenLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1424 wfDebug( 'Invalid title passed to Skin::makeBrokenLink(): "'.$title."\"\n" );
1425 return $text == '' ?
$title : $text;
1429 function makeStubLink( $title, $text = '', $query = '', $trail = '' ) {
1430 $nt = Title
::newFromText( $title );
1432 return $this->makeStubLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1434 wfDebug( 'Invalid title passed to Skin::makeStubLink(): "'.$title."\"\n" );
1435 return $text == '' ?
$title : $text;
1439 # Pass a title object, not a title string
1440 function makeLinkObj( &$nt, $text= '', $query = '', $trail = '', $prefix = '' )
1442 global $wgOut, $wgUser;
1443 global $wgInternalLinks;
1444 $fname = 'Skin::makeLinkObj';
1446 if ( $nt->isExternal() ) {
1447 $u = $nt->getFullURL();
1448 $link = $nt->getPrefixedURL();
1449 if ( '' == $text ) { $text = $nt->getPrefixedText(); }
1450 $style = $this->getExternalLinkAttributes( $link, $text, 'extiw' );
1453 if ( '' != $trail ) {
1454 if ( preg_match( '/^([a-z]+)(.*)$$/sD', $trail, $m ) ) {
1459 $retVal = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1460 } elseif ( 0 == $nt->getNamespace() && "" == $nt->getText() ) {
1461 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1462 } elseif ( ( -1 == $nt->getNamespace() ) ||
1463 ( Namespace::getImage() == $nt->getNamespace() ) ) {
1464 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1467 if ( '' != $trail ) {
1468 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1474 # Allows wiki to bypass using linkcache, see OutputPage::parseLinkHolders()
1475 $wgInternalLinks['obj'][] = $nt;
1476 $wgInternalLinks['text'][] = $text . $inside;
1477 $wgInternalLinks['query'][] = $query;
1478 $wgInternalLinks['prefix'][] = $prefix;
1479 $wgInternalLinks['ns'][] = $nt->getNamespace();
1480 $retVal = "<tmp=" . $nt->getDBkey() . ">{$trail}";
1485 # Pass a title object, not a title string
1486 function makeKnownLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' , $aprops = '')
1488 global $wgOut, $wgTitle, $wgInputEncoding;
1490 $fname = 'Skin::makeKnownLinkObj';
1491 wfProfileIn( $fname );
1493 if ( !is_object( $nt ) ) {
1496 $link = $nt->getPrefixedURL();
1498 if ( '' == $link ) {
1500 if ( '' == $text ) {
1501 $text = htmlspecialchars( $nt->getFragment() );
1504 $u = $nt->escapeLocalURL( $query );
1506 if ( '' != $nt->getFragment() ) {
1507 $anchor = urlencode( do_html_entity_decode( str_replace(' ', '_', $nt->getFragment()), ENT_COMPAT
, $wgInputEncoding ) );
1508 $replacearray = array(
1512 $u .= '#' . str_replace(array_keys($replacearray),array_values($replacearray),$anchor);
1514 if ( '' == $text ) {
1515 $text = htmlspecialchars( $nt->getPrefixedText() );
1517 $style = $this->getInternalLinkAttributesObj( $nt, $text );
1520 if ( '' != $trail ) {
1521 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1526 $r = "<a href=\"{$u}\"{$style}{$aprops}>{$prefix}{$text}{$inside}</a>{$trail}";
1527 wfProfileOut( $fname );
1531 # Pass a title object, not a title string
1532 function makeBrokenLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
1534 global $wgOut, $wgUser;
1536 $fname = 'Skin::makeBrokenLinkObj';
1537 wfProfileIn( $fname );
1539 if ( '' == $query ) {
1542 $q = 'action=edit&'.$query;
1544 $u = $nt->escapeLocalURL( $q );
1546 if ( '' == $text ) {
1547 $text = htmlspecialchars( $nt->getPrefixedText() );
1549 $style = $this->getInternalLinkAttributesObj( $nt, $text, "yes" );
1552 if ( '' != $trail ) {
1553 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1558 if ( $wgUser->getOption( 'highlightbroken' ) ) {
1559 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1561 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>?</a>{$trail}";
1564 wfProfileOut( $fname );
1568 # Pass a title object, not a title string
1569 function makeStubLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
1571 global $wgOut, $wgUser;
1573 $link = $nt->getPrefixedURL();
1575 $u = $nt->escapeLocalURL( $query );
1577 if ( '' == $text ) {
1578 $text = htmlspecialchars( $nt->getPrefixedText() );
1580 $style = $this->getInternalLinkAttributesObj( $nt, $text, 'stub' );
1583 if ( '' != $trail ) {
1584 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1589 if ( $wgUser->getOption( 'highlightbroken' ) ) {
1590 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1592 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>!</a>{$trail}";
1597 function makeSelfLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
1599 $u = $nt->escapeLocalURL( $query );
1600 if ( '' == $text ) {
1601 $text = htmlspecialchars( $nt->getPrefixedText() );
1604 if ( '' != $trail ) {
1605 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1610 return "<strong>{$prefix}{$text}{$inside}</strong>{$trail}";
1613 /* these are used extensively in SkinPHPTal, but also some other places */
1614 /*static*/ function makeSpecialUrl( $name, $urlaction='' ) {
1615 $title = Title
::makeTitle( NS_SPECIAL
, $name );
1616 $this->checkTitle($title, $name);
1617 return $title->getLocalURL( $urlaction );
1619 /*static*/ function makeTalkUrl ( $name, $urlaction='' ) {
1620 $title = Title
::newFromText( $name );
1621 $title = $title->getTalkPage();
1622 $this->checkTitle($title, $name);
1623 return $title->getLocalURL( $urlaction );
1625 /*static*/ function makeArticleUrl ( $name, $urlaction='' ) {
1626 $title = Title
::newFromText( $name );
1627 $title= $title->getSubjectPage();
1628 $this->checkTitle($title, $name);
1629 return $title->getLocalURL( $urlaction );
1631 /*static*/ function makeI18nUrl ( $name, $urlaction='' ) {
1632 $title = Title
::newFromText( wfMsg($name) );
1633 $this->checkTitle($title, $name);
1634 return $title->getLocalURL( $urlaction );
1636 /*static*/ function makeUrl ( $name, $urlaction='' ) {
1637 $title = Title
::newFromText( $name );
1638 $this->checkTitle($title, $name);
1639 return $title->getLocalURL( $urlaction );
1641 # this can be passed the NS number as defined in Language.php
1642 /*static*/ function makeNSUrl( $name, $urlaction='', $namespace=0 ) {
1643 $title = Title
::makeTitle( $namespace, $name );
1644 $this->checkTitle($title, $name);
1645 return $title->getLocalURL( $urlaction );
1648 /* these return an array with the 'href' and boolean 'exists' */
1649 /*static*/ function makeUrlDetails ( $name, $urlaction='' ) {
1650 $title = Title
::newFromText( $name );
1651 $this->checkTitle($title, $name);
1653 'href' => $title->getLocalURL( $urlaction ),
1654 'exists' => $title->getArticleID() != 0?
true:false
1657 /*static*/ function makeTalkUrlDetails ( $name, $urlaction='' ) {
1658 $title = Title
::newFromText( $name );
1659 $title = $title->getTalkPage();
1660 $this->checkTitle($title, $name);
1662 'href' => $title->getLocalURL( $urlaction ),
1663 'exists' => $title->getArticleID() != 0?
true:false
1666 /*static*/ function makeArticleUrlDetails ( $name, $urlaction='' ) {
1667 $title = Title
::newFromText( $name );
1668 $title= $title->getSubjectPage();
1669 $this->checkTitle($title, $name);
1671 'href' => $title->getLocalURL( $urlaction ),
1672 'exists' => $title->getArticleID() != 0?
true:false
1675 /*static*/ function makeI18nUrlDetails ( $name, $urlaction='' ) {
1676 $title = Title
::newFromText( wfMsg($name) );
1677 $this->checkTitle($title, $name);
1679 'href' => $title->getLocalURL( $urlaction ),
1680 'exists' => $title->getArticleID() != 0?
true:false
1684 # make sure we have some title to operate on
1685 /*static*/ function checkTitle ( &$title, &$name ) {
1686 if(!is_object($title)) {
1687 $title = Title
::newFromText( $name );
1688 if(!is_object($title)) {
1689 $title = Title
::newFromText( '--error: link target missing--' );
1694 function fnamePart( $url )
1696 $basename = strrchr( $url, '/' );
1697 if ( false === $basename ) { $basename = $url; }
1698 else { $basename = substr( $basename, 1 ); }
1699 return wfEscapeHTML( $basename );
1702 function makeImage( $url, $alt = '' )
1706 if ( '' == $alt ) { $alt = $this->fnamePart( $url ); }
1707 $s = '<img src="'.$url.'" alt="'.$alt.'" />';
1711 function makeImageLink( $name, $url, $alt = '' ) {
1712 $nt = Title
::makeTitle( Namespace::getImage(), $name );
1713 return $this->makeImageLinkObj( $nt, $alt );
1716 function makeImageLinkObj( $nt, $alt = '' ) {
1717 global $wgLang, $wgUseImageResize;
1718 $img = Image
::newFromTitle( $nt );
1719 $url = $img->getURL();
1722 $prefix = $postfix = '';
1724 if ( $wgUseImageResize ) {
1725 # Check if the alt text is of the form "options|alt text"
1727 # * thumbnail make a thumbnail with enlarge-icon and caption, alignment depends on lang
1728 # * left no resizing, just left align. label is used for alt= only
1729 # * right same, but right aligned
1730 # * none same, but not aligned
1731 # * ___px scale to ___ pixels width, no aligning. e.g. use in taxobox
1732 # * center center the image
1733 # * framed Keep original image size, no magnify-button.
1735 $part = explode( '|', $alt);
1737 $mwThumb =& MagicWord
::get( MAG_IMG_THUMBNAIL
);
1738 $mwLeft =& MagicWord
::get( MAG_IMG_LEFT
);
1739 $mwRight =& MagicWord
::get( MAG_IMG_RIGHT
);
1740 $mwNone =& MagicWord
::get( MAG_IMG_NONE
);
1741 $mwWidth =& MagicWord
::get( MAG_IMG_WIDTH
);
1742 $mwCenter =& MagicWord
::get( MAG_IMG_CENTER
);
1743 $mwFramed =& MagicWord
::get( MAG_IMG_FRAMED
);
1744 $alt = $part[count($part)-1];
1746 $height = $framed = $thumb = false;
1747 $manual_thumb = "" ;
1749 foreach( $part as $key => $val ) {
1750 $val_parts = explode ( "=" , $val , 2 ) ;
1751 $left_part = array_shift ( $val_parts ) ;
1752 if ( ! is_null( $mwThumb->matchVariableStartToEnd($val) ) ) {
1754 } elseif ( count ( $val_parts ) == 1 && ! is_null( $mwThumb->matchVariableStartToEnd($left_part) ) ) {
1755 # use manually specified thumbnail
1757 $manual_thumb = array_shift ( $val_parts ) ;
1758 } elseif ( ! is_null( $mwRight->matchVariableStartToEnd($val) ) ) {
1759 # remember to set an alignment, don't render immediately
1761 } elseif ( ! is_null( $mwLeft->matchVariableStartToEnd($val) ) ) {
1762 # remember to set an alignment, don't render immediately
1764 } elseif ( ! is_null( $mwCenter->matchVariableStartToEnd($val) ) ) {
1765 # remember to set an alignment, don't render immediately
1767 } elseif ( ! is_null( $mwNone->matchVariableStartToEnd($val) ) ) {
1768 # remember to set an alignment, don't render immediately
1770 } elseif ( ! is_null( $match = $mwWidth->matchVariableStartToEnd($val) ) ) {
1771 # $match is the image width in pixels
1772 if ( preg_match( '/^([0-9]*)x([0-9]*)$/', $match, $m ) ) {
1773 $width = intval( $m[1] );
1774 $height = intval( $m[2] );
1776 $width = intval($match);
1778 } elseif ( ! is_null( $mwFramed->matchVariableStartToEnd($val) ) ) {
1782 if ( 'center' == $align )
1784 $prefix = '<span style="text-align: center">';
1785 $postfix = '</span>';
1789 if ( $thumb ||
$framed ) {
1791 # Create a thumbnail. Alignment depends on language
1792 # writing direction, # right aligned for left-to-right-
1793 # languages ("Western languages"), left-aligned
1794 # for right-to-left-languages ("Semitic languages")
1796 # If thumbnail width has not been provided, it is set
1797 # here to 180 pixels
1798 if ( $align == '' ) {
1799 $align = $wgLang->isRTL() ?
'left' : 'right';
1801 if ( ! isset($width) ) {
1804 return $prefix.$this->makeThumbLinkObj( $img, $alt, $align, $width, $height, $framed, $manual_thumb ).$postfix;
1806 } elseif ( isset($width) ) {
1808 # Create a resized image, without the additional thumbnail
1811 if ( ( ! $height === false )
1812 && ( $img->getHeight() * $width / $img->getWidth() > $height ) ) {
1813 print "height=$height<br>\nimg->getHeight() = ".$img->getHeight()."<br>\n";
1814 print 'rescaling by factor '. $height / $img->getHeight() . "<br>\n";
1815 $width = $img->getWidth() * $height / $img->getHeight();
1817 if ( '' == $manual_thumb ) $url = $img->createThumb( $width );
1819 } # endif $wgUseImageResize
1821 if ( empty( $alt ) ) {
1822 $alt = preg_replace( '/\.(.+?)^/', '', $img->getName() );
1824 $alt = htmlspecialchars( $alt );
1826 $u = $nt->escapeLocalURL();
1829 $s = str_replace( "$1", $img->getName(), wfMsg('missingimage') );
1830 $s .= "<br>{$alt}<br>{$url}<br>\n";
1832 $s = '<a href="'.$u.'" class="image" title="'.$alt.'">' .
1833 '<img src="'.$url.'" alt="'.$alt.'" /></a>';
1835 if ( '' != $align ) {
1836 $s = "<div class=\"float{$align}\"><span>{$s}</span></div>";
1838 return str_replace("\n", ' ',$prefix.$s.$postfix);
1842 function makeThumbLinkObj( $img, $label = '', $align = 'right', $boxwidth = 180, $boxheight=false, $framed=false , $manual_thumb = "" ) {
1843 global $wgStylePath, $wgLang;
1844 # $image = Title::makeTitle( Namespace::getImage(), $name );
1845 $url = $img->getURL();
1847 #$label = htmlspecialchars( $label );
1848 $alt = preg_replace( '/<[^>]*>/', '', $label);
1849 $alt = htmlspecialchars( $alt );
1851 if ( $img->exists() )
1853 $width = $img->getWidth();
1854 $height = $img->getHeight();
1856 $width = $height = 200;
1860 // Use image dimensions, don't scale
1862 $oboxwidth = $boxwidth +
2;
1863 $boxheight = $height;
1866 $h = intval( $height/($width/$boxwidth) );
1867 $oboxwidth = $boxwidth +
2;
1868 if ( ( ! $boxheight === false ) && ( $h > $boxheight ) )
1870 $boxwidth *= $boxheight/$h;
1874 if ( '' == $manual_thumb ) $thumbUrl = $img->createThumb( $boxwidth );
1877 if ( $manual_thumb != '' ) # Use manually specified thumbnail
1879 $manual_title = Title
::makeTitle( Namespace::getImage(), $manual_thumb ); #new Title ( $manual_thumb ) ;
1880 $manual_img = Image
::newFromTitle( $manual_title );
1881 $thumbUrl = $manual_img->getURL();
1882 if ( $manual_img->exists() )
1884 $width = $manual_img->getWidth();
1885 $height = $manual_img->getHeight();
1886 $boxwidth = $width ;
1887 $boxheight = $height ;
1888 $oboxwidth = $boxwidth +
2 ;
1892 $u = $img->getEscapeLocalURL();
1894 $more = htmlspecialchars( wfMsg( 'thumbnail-more' ) );
1895 $magnifyalign = $wgLang->isRTL() ?
'left' : 'right';
1896 $textalign = $wgLang->isRTL() ?
' style="text-align:right"' : '';
1898 $s = "<div class=\"thumb t{$align}\"><div style=\"width:{$oboxwidth}px;\">";
1899 if ( $thumbUrl == '' ) {
1900 $s .= str_replace( "$1", $img->getName(), wfMsg('missingimage') );
1903 $s .= '<a href="'.$u.'" class="internal" title="'.$alt.'">'.
1904 '<img src="'.$thumbUrl.'" alt="'.$alt.'" ' .
1905 'width="'.$boxwidth.'" height="'.$boxheight.'" /></a>';
1909 $zoomicon = '<div class="magnify" style="float:'.$magnifyalign.'">'.
1910 '<a href="'.$u.'" class="internal" title="'.$more.'">'.
1911 '<img src="'.$wgStylePath.'/images/magnify-clip.png" ' .
1912 'width="15" height="11" alt="'.$more.'" /></a></div>';
1915 $s .= ' <div class="thumbcaption" '.$textalign.'>'.$zoomicon.$label."</div></div></div>";
1916 return str_replace("\n", ' ', $s);
1919 function makeMediaLink( $name, $url, $alt = "" ) {
1920 $nt = Title
::makeTitle( Namespace::getMedia(), $name );
1921 return $this->makeMediaLinkObj( $nt, $alt );
1924 function makeMediaLinkObj( $nt, $alt = "" )
1926 if ( ! isset( $nt ) )
1928 ### HOTFIX. Instead of breaking, return empry string.
1931 $name = $nt->getDBKey();
1932 $url = Image
::wfImageUrl( $name );
1933 if ( empty( $alt ) ) {
1934 $alt = preg_replace( '/\.(.+?)^/', '', $name );
1937 $u = htmlspecialchars( $url );
1938 $s = "<a href=\"{$u}\" class='internal' title=\"{$alt}\">{$alt}</a>";
1943 function specialLink( $name, $key = "" )
1947 if ( '' == $key ) { $key = strtolower( $name ); }
1948 $pn = $wgLang->ucfirst( $name );
1949 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1953 function makeExternalLink( $url, $text, $escape = true ) {
1954 $style = $this->getExternalLinkAttributes( $url, $text );
1955 $url = htmlspecialchars( $url );
1957 $text = htmlspecialchars( $text );
1959 return '<a href="'.$url.'"'.$style.'>'.$text.'</a>';
1962 # Called by history lists and recent changes
1965 # Returns text for the start of the tabular part of RC
1966 function beginRecentChangesList()
1968 $this->rc_cache
= array() ;
1969 $this->rcMoveIndex
= 0;
1970 $this->rcCacheIndex
= 0 ;
1971 $this->lastdate
= '';
1972 $this->rclistOpen
= false;
1976 function beginImageHistoryList()
1978 $s = "\n<h2>" . wfMsg( 'imghistory' ) . "</h2>\n" .
1979 "<p>" . wfMsg( 'imghistlegend' ) . "</p>\n".'<ul class="special">';
1983 # Returns text for the end of RC
1984 # If enhanced RC is in use, returns pretty much all the text
1985 function endRecentChangesList()
1987 $s = $this->recentChangesBlock() ;
1988 if( $this->rclistOpen
) {
1994 # Enhanced RC ungrouped line
1995 function recentChangesBlockLine ( $rcObj )
1997 global $wgStylePath, $wgLang ;
1999 # Get rc_xxxx variables
2000 extract( $rcObj->mAttribs
) ;
2001 $curIdEq = 'curid='.$rc_cur_id;
2006 $r .= '<img src="'.$wgStylePath.'/images/Arr_.png" width="12" height="12" border="0" />' ;
2009 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2010 $r .= ' ';
2012 # M & N (minor & new)
2013 $M = wfMsg( 'minoreditletter' );
2014 $N = wfMsg( 'newpageletter' );
2016 if ( $rc_type == RC_NEW
) {
2029 $r .= ' '.$rcObj->timestamp
.' ' ;
2033 $link = $rcObj->link
;
2034 if ( $rcObj->watched
) $link = '<strong>'.$link.'</strong>' ;
2039 $r .= $rcObj->difflink
;
2043 $r .= $this->makeKnownLinkObj( $rcObj->getTitle(), wfMsg( 'hist' ), $curIdEq.'&action=history' );
2046 $r .= ') . . '.$rcObj->userlink
;
2047 $r .= $rcObj->usertalklink
;
2050 if ( $rc_comment != '' && $rc_type != RC_MOVE
&& $rc_type != RC_MOVE_OVER_REDIRECT
) {
2051 $rc_comment=$this->formatComment($rc_comment);
2052 $r .= $wgLang->emphasize( ' ('.$rc_comment.')' );
2060 function recentChangesBlockGroup ( $block )
2062 global $wgStylePath, $wgLang ;
2065 $M = wfMsg( 'minoreditletter' );
2066 $N = wfMsg( 'newpageletter' );
2068 # Collate list of users
2070 $userlinks = array () ;
2071 foreach ( $block AS $rcObj ) {
2072 $oldid = $rcObj->mAttribs
['rc_last_oldid'];
2073 if ( $rcObj->mAttribs
['rc_new'] ) $isnew = true ;
2074 $u = $rcObj->userlink
;
2075 if ( !isset ( $userlinks[$u] ) ) $userlinks[$u] = 0 ;
2079 # Sort the list and convert to text
2080 krsort ( $userlinks ) ;
2081 asort ( $userlinks ) ;
2083 foreach ( $userlinks as $userlink => $count) {
2085 if ( $count > 1 ) $text .= " ({$count}×)" ;
2086 array_push ( $users , $text ) ;
2088 $users = ' <font size="-1">['.implode('; ',$users).']</font>' ;
2091 $rci = 'RCI'.$this->rcCacheIndex
;
2092 $rcl = 'RCL'.$this->rcCacheIndex
;
2093 $rcm = 'RCM'.$this->rcCacheIndex
;
2094 $toggleLink = "javascript:toggleVisibility('$rci','$rcm','$rcl')" ;
2095 $arrowdir = $wgLang->isRTL() ?
'l' : 'r';
2096 $tl = '<span id="'.$rcm.'"><a href="'.$toggleLink.'"><img src="'.$wgStylePath.'/images/Arr_'.$arrowdir.'.png" width="12" height="12" /></a></span>' ;
2097 $tl .= '<span id="'.$rcl.'" style="display:none"><a href="'.$toggleLink.'"><img src="'.$wgStylePath.'/images/Arr_d.png" width="12" height="12" /></a></span>' ;
2103 if ( $isnew ) $r .= $N ;
2104 else $r .= ' ' ;
2105 $r .= ' ' ; # Minor
2108 $r .= ' '.$block[0]->timestamp
.' ' ;
2112 $link = $block[0]->link
;
2113 if ( $block[0]->watched
) $link = '<strong>'.$link.'</strong>' ;
2116 $curIdEq = 'curid=' . $block[0]->mAttribs
['rc_cur_id'];
2117 if ( $block[0]->mAttribs
['rc_type'] != RC_LOG
) {
2119 $r .= ' ('.count($block).' ' ;
2120 if ( $isnew ) $r .= wfMsg('changes');
2121 else $r .= $this->makeKnownLinkObj( $block[0]->getTitle() , wfMsg('changes') ,
2122 $curIdEq.'&diff=0&oldid='.$oldid ) ;
2126 $r .= $this->makeKnownLinkObj( $block[0]->getTitle(), wfMsg( 'history' ), $curIdEq.'&action=history' );
2134 $r .= '<div id="'.$rci.'" style="display:none">' ;
2135 foreach ( $block AS $rcObj ) {
2136 # Get rc_xxxx variables
2137 extract( $rcObj->mAttribs
);
2139 $r .= '<img src="'.$wgStylePath.'/images/Arr_.png" width="12" height="12" />';
2140 $r .= '<tt> ' ;
2141 if ( $rc_new ) $r .= $N ;
2142 else $r .= ' ' ;
2143 if ( $rc_minor ) $r .= $M ;
2144 else $r .= ' ' ;
2148 if ( $rc_last_oldid != 0 ) {
2149 $o = 'oldid='.$rc_last_oldid ;
2151 if ( $rc_type == RC_LOG
) {
2152 $link = $rcObj->timestamp
;
2154 $link = $this->makeKnownLinkObj( $rcObj->getTitle(), $rcObj->timestamp
, "{$curIdEq}&$o" ) ;
2156 $link = '<tt>'.$link.'</tt>' ;
2160 $r .= $rcObj->curlink
;
2162 $r .= $rcObj->lastlink
;
2163 $r .= ') . . '.$rcObj->userlink
;
2164 $r .= $rcObj->usertalklink
;
2165 if ( $rc_comment != '' ) {
2166 $rc_comment=$this->formatComment($rc_comment);
2167 $r .= $wgLang->emphasize( ' ('.$rc_comment.')' ) ;
2173 $this->rcCacheIndex++
;
2177 # If enhanced RC is in use, this function takes the previously cached
2178 # RC lines, arranges them, and outputs the HTML
2179 function recentChangesBlock ()
2181 global $wgStylePath ;
2182 if ( count ( $this->rc_cache
) == 0 ) return '' ;
2184 foreach ( $this->rc_cache
AS $secureName => $block ) {
2185 if ( count ( $block ) < 2 ) {
2186 $blockOut .= $this->recentChangesBlockLine ( array_shift ( $block ) ) ;
2188 $blockOut .= $this->recentChangesBlockGroup ( $block ) ;
2192 return '<div>'.$blockOut.'</div>' ;
2195 # Called in a loop over all displayed RC entries
2196 # Either returns the line, or caches it for later use
2197 function recentChangesLine( &$rc, $watched = false )
2200 $usenew = $wgUser->getOption( 'usenewrc' );
2202 $line = $this->recentChangesLineNew ( $rc, $watched ) ;
2204 $line = $this->recentChangesLineOld ( $rc, $watched ) ;
2208 function recentChangesLineOld( &$rc, $watched = false )
2210 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds;
2212 # Extract DB fields into local scope
2213 extract( $rc->mAttribs
);
2214 $curIdEq = 'curid=' . $rc_cur_id;
2216 # Make date header if necessary
2217 $date = $wgLang->date( $rc_timestamp, true);
2219 if ( $date != $this->lastdate
) {
2220 if ( '' != $this->lastdate
) { $s .= "</ul>\n"; }
2221 $s .= "<h4>{$date}</h4>\n<ul class='special'>";
2222 $this->lastdate
= $date;
2223 $this->rclistOpen
= true;
2227 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2229 $s .= '(' . wfMsg( 'diff' ) . ') (';
2231 $s .= $this->makeKnownLinkObj( $rc->getMovedToTitle(), wfMsg( 'hist' ), 'action=history' ) .
2234 # "[[x]] moved to [[y]]"
2235 if ( $rc_type == RC_MOVE
) {
2238 $msg = '1movedto2_redir';
2240 $s .= wfMsg( $msg, $this->makeKnownLinkObj( $rc->getTitle(), '', 'redirect=no' ),
2241 $this->makeKnownLinkObj( $rc->getMovedToTitle(), '' ) );
2244 if ( $rc_type == RC_NEW ||
$rc_type == RC_LOG
) {
2245 $diffLink = wfMsg( 'diff' );
2247 $diffLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'diff' ),
2248 $curIdEq.'&diff='.$rc_this_oldid.'&oldid='.$rc_last_oldid ,'' ,'' , ' tabindex="'.$rc->counter
.'"');
2250 $s .= '('.$diffLink.') (';
2253 $s .= $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'hist' ), $curIdEq.'&action=history' );
2256 # M and N (minor and new)
2257 $M = wfMsg( 'minoreditletter' );
2258 $N = wfMsg( 'newpageletter' );
2259 if ( $rc_minor ) { $s .= ' <strong>'.$M.'</strong>'; }
2260 if ( $rc_type == RC_NEW
) { $s .= '<strong>'.$N.'</strong>'; }
2263 $articleLink = $this->makeKnownLinkObj( $rc->getTitle(), '' );
2266 $articleLink = '<strong>'.$articleLink.'</strong>';
2268 $s .= ' '.$articleLink;
2273 $s .= '; ' . $wgLang->time( $rc_timestamp, true, $wgRCSeconds ) . ' . . ';
2275 # User link (or contributions for unregistered users)
2276 if ( 0 == $rc_user ) {
2277 $userLink = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
2278 $rc_user_text, 'target=' . $rc_user_text );
2280 $userLink = $this->makeLink( $wgLang->getNsText( NS_USER
) . ':'.$rc_user_text, $rc_user_text );
2285 $talkname=$wgLang->getNsText(NS_TALK
); # use the shorter name
2286 global $wgDisableAnonTalk;
2287 if( 0 == $rc_user && $wgDisableAnonTalk ) {
2290 $utns=$wgLang->getNsText(NS_USER_TALK
);
2291 $userTalkLink= $this->makeLink($utns . ':'.$rc_user_text, $talkname );
2295 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2296 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2297 'Blockip' ), wfMsg( 'blocklink' ), 'ip='.$rc_user_text );
2301 if($userTalkLink) $userTalkLink .= ' | ';
2302 $userTalkLink .= $blockLink;
2304 if($userTalkLink) $s.=' ('.$userTalkLink.')';
2307 if ( '' != $rc_comment && '*' != $rc_comment && $rc_type != RC_MOVE
&& $rc_type != RC_MOVE_OVER_REDIRECT
) {
2308 $rc_comment=$this->formatComment($rc_comment);
2309 $s .= $wgLang->emphasize(' (' . $rc_comment . ')');
2316 # function recentChangesLineNew( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched = false, $oldid = 0 , $diffid = 0 )
2317 function recentChangesLineNew( &$baseRC, $watched = false )
2319 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds;
2321 # Create a specialised object
2322 $rc = RCCacheEntry
::newFromParent( $baseRC ) ;
2324 # Extract fields from DB into the function scope (rc_xxxx variables)
2325 extract( $rc->mAttribs
);
2326 $curIdEq = 'curid=' . $rc_cur_id;
2328 # If it's a new day, add the headline and flush the cache
2329 $date = $wgLang->date( $rc_timestamp, true);
2331 if ( $date != $this->lastdate
) {
2332 # Process current cache
2333 $ret = $this->recentChangesBlock () ;
2334 $this->rc_cache
= array() ;
2335 $ret .= "<h4>{$date}</h4>\n";
2336 $this->lastdate
= $date;
2340 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2341 if ( $rc_type == RC_MOVE
) {
2344 $msg = "1movedto2_redir";
2346 $clink = wfMsg( $msg, $this->makeKnownLinkObj( $rc->getTitle(), '', 'redirect=no' ),
2347 $this->makeKnownLinkObj( $rc->getMovedToTitle(), '' ) );
2349 $clink = $this->makeKnownLinkObj( $rc->getTitle(), '' ) ;
2352 $time = $wgLang->time( $rc_timestamp, true, $wgRCSeconds );
2353 $rc->watched
= $watched ;
2354 $rc->link
= $clink ;
2355 $rc->timestamp
= $time;
2357 # Make "cur" and "diff" links
2358 if ( ( $rc_type == RC_NEW
&& $rc_this_oldid == 0 ) ||
$rc_type == RC_LOG ||
$rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2359 $curLink = wfMsg( 'cur' );
2360 $diffLink = wfMsg( 'diff' );
2362 $query = $curIdEq.'&diff=0&oldid='.$rc_this_oldid;
2363 $aprops = ' tabindex="'.$baseRC->counter
.'"';
2364 $curLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'cur' ), $query, '' ,'' , $aprops );
2365 $diffLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'diff'), $query, '' ,'' , $aprops );
2369 $titleObj = $rc->getTitle();
2370 if ( $rc_last_oldid == 0 ||
$rc_type == RC_LOG ||
$rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2371 $lastLink = wfMsg( 'last' );
2373 $lastLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'last' ),
2374 $curIdEq.'&diff='.$rc_this_oldid.'&oldid='.$rc_last_oldid );
2377 # Make user link (or user contributions for unregistered users)
2378 if ( 0 == $rc_user ) {
2379 $userLink = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
2380 $rc_user_text, 'target=' . $rc_user_text );
2382 $userLink = $this->makeLink( $wgLang->getNsText(
2383 Namespace::getUser() ) . ':'.$rc_user_text, $rc_user_text );
2386 $rc->userlink
= $userLink ;
2387 $rc->lastlink
= $lastLink ;
2388 $rc->curlink
= $curLink ;
2389 $rc->difflink
= $diffLink;
2392 # Make user talk link
2393 $utns=$wgLang->getNsText(NS_USER_TALK
);
2394 $talkname=$wgLang->getNsText(NS_TALK
); # use the shorter name
2395 $userTalkLink= $this->makeLink($utns . ':'.$rc_user_text, $talkname );
2397 global $wgDisableAnonTalk;
2398 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2399 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2400 'Blockip' ), wfMsg( 'blocklink' ), 'ip='.$rc_user_text );
2401 if( $wgDisableAnonTalk )
2402 $rc->usertalklink
= ' ('.$blockLink.')';
2404 $rc->usertalklink
= ' ('.$userTalkLink.' | '.$blockLink.')';
2406 if( $wgDisableAnonTalk && ($rc_user == 0) )
2407 $rc->usertalklink
= '';
2409 $rc->usertalklink
= ' ('.$userTalkLink.')';
2412 # Put accumulated information into the cache, for later display
2413 # Page moves go on their own line
2414 $title = $rc->getTitle();
2415 $secureName = $title->getPrefixedDBkey();
2416 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2417 # Use an @ character to prevent collision with page names
2418 $this->rc_cache
['@@' . ($this->rcMoveIndex++
)] = array($rc);
2420 if ( !isset ( $this->rc_cache
[$secureName] ) ) $this->rc_cache
[$secureName] = array() ;
2421 array_push ( $this->rc_cache
[$secureName] , $rc ) ;
2426 function endImageHistoryList()
2432 /* This function is called by all recent changes variants, by the page history,
2433 and by the user contributions list. It is responsible for formatting edit
2434 comments. It escapes any HTML in the comment, but adds some CSS to format
2435 auto-generated comments (from section editing) and formats [[wikilinks]].
2436 Main author: Erik Möller (moeller@scireview.de)
2438 function formatComment($comment)
2441 $comment=wfEscapeHTML($comment);
2443 # The pattern for autogen comments is / * foo * /, which makes for
2445 # We look for all comments, match any text before and after the comment,
2446 # add a separator where needed and format the comment itself with CSS
2447 while (preg_match('/(.*)\/\*\s*(.*?)\s*\*\/(.*)/', $comment,$match)) {
2452 if($pre) { $auto = $sep.' '.$auto; }
2453 if($post) { $auto .= ' '.$sep; }
2454 $auto='<span class="autocomment">'.$auto.'</span>';
2455 $comment=$pre.$auto.$post;
2458 # format regular and media links - all other wiki formatting
2460 while(preg_match('/\[\[(.*?)(\|(.*?))*\]\]/',$comment,$match)) {
2462 $medians = $wgLang->getNsText(Namespace::getMedia()).':';
2464 if(preg_match('/^'.$medians.'/i',$match[1])) {
2465 $func='makeMediaLink';
2467 # Handle link renaming [[foo|text]] will show link as "text"
2468 if(isset($match[3]) ) {
2470 preg_replace('/\[\[(.*?)\]\]/',
2471 $this->$func($match[1],$match[3]),$comment,1);
2474 preg_replace('/\[\[(.*?)\]\]/',
2475 $this->$func($match[1],$match[1]),$comment,1);
2483 function imageHistoryLine( $iscur, $timestamp, $img, $user, $usertext, $size, $description )
2485 global $wgUser, $wgLang, $wgTitle;
2487 $datetime = $wgLang->timeanddate( $timestamp, true );
2488 $del = wfMsg( 'deleteimg' );
2489 $cur = wfMsg( 'cur' );
2492 $url = Image
::wfImageUrl( $img );
2494 if ( $wgUser->isSysop() ) {
2495 $link = $wgTitle->escapeLocalURL( 'image=' . $wgTitle->getPartialURL() .
2497 $style = $this->getInternalLinkAttributes( $link, $del );
2499 $dlink = '<a href="'.$link.'"'.$style.'>'.$del.'</a>';
2504 $url = wfEscapeHTML( wfImageArchiveUrl( $img ) );
2505 if( $wgUser->getID() != 0 ) {
2506 $rlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2507 wfMsg( 'revertimg' ), 'action=revert&oldimage=' .
2508 urlencode( $img ) );
2509 $dlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2510 $del, 'action=delete&oldimage=' . urlencode( $img ) );
2512 # Having live active links for non-logged in users
2513 # means that bots and spiders crawling our site can
2514 # inadvertently change content. Baaaad idea.
2515 $rlink = wfMsg( 'revertimg' );
2520 $userlink = $usertext;
2522 $userlink = $this->makeLink( $wgLang->getNsText( Namespace::getUser() ) .
2523 ':'.$usertext, $usertext );
2525 $nbytes = wfMsg( 'nbytes', $size );
2526 $style = $this->getInternalLinkAttributes( $url, $datetime );
2528 $s = "<li> ({$dlink}) ({$rlink}) <a href=\"{$url}\"{$style}>{$datetime}</a>"
2529 . " . . {$userlink} ({$nbytes})";
2531 if ( '' != $description && '*' != $description ) {
2532 $sk=$wgUser->getSkin();
2533 $s .= $wgLang->emphasize(' (' . $sk->formatComment($description) . ')');
2539 function tocIndent($level) {
2540 return str_repeat( '<div class="tocindent">'."\n", $level>0 ?
$level : 0 );
2543 function tocUnindent($level) {
2544 return str_repeat( "</div>\n", $level>0 ?
$level : 0 );
2547 # parameter level defines if we are on an indentation level
2548 function tocLine( $anchor, $tocline, $level ) {
2549 $link = '<a href="#'.$anchor.'">'.$tocline.'</a><br />';
2553 return '<div class="tocline">'.$link."</div>\n";
2558 function tocTable($toc) {
2559 # note to CSS fanatics: putting this in a div does not work -- div won't auto-expand
2560 # try min-width & co when somebody gets a chance
2561 $hideline = ' <script type="text/javascript">showTocToggle("' . addslashes( wfMsg('showtoc') ) . '","' . addslashes( wfMsg('hidetoc') ) . '")</script>';
2563 '<table border="0" id="toc"><tr id="toctitle"><td align="center">'."\n".
2564 '<b>'.wfMsg('toc').'</b>' .
2566 '</td></tr><tr id="tocinside"><td>'."\n".
2567 $toc."</td></tr></table>\n";
2570 # These two do not check for permissions: check $wgTitle->userCanEdit before calling them
2571 function editSectionScript( $section, $head ) {
2572 global $wgTitle, $wgRequest;
2573 if( $wgRequest->getInt( 'oldid' ) && ( $wgRequest->getVal( 'diff' ) != '0' ) ) {
2576 $url = $wgTitle->escapeLocalURL( 'action=edit§ion='.$section );
2577 return '<span oncontextmenu=\'document.location="'.$url.'";return false;\'>'.$head.'</span>';
2580 function editSectionLink( $section ) {
2582 global $wgTitle, $wgUser, $wgLang;
2584 if( $wgRequest->getInt( 'oldid' ) && ( $wgRequest->getVal( 'diff' ) != '0' ) ) {
2585 # Section edit links would be out of sync on an old page.
2586 # But, if we're diffing to the current page, they'll be
2591 $editurl = '§ion='.$section;
2592 $url = $this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg('editsection'),'action=edit'.$editurl);
2594 if( $wgLang->isRTL() ) {
2596 $nearside = 'right';
2601 return "<div class=\"editsection\" style=\"float:$farside;margin-$nearside:5px;\">[".$url."]</div>";
2605 // This function is called by EditPage.php and shows a bulletin board style
2606 // toolbar for common editing functions. It can be disabled in the user preferences.
2607 // The necsesary JavaScript code can be found in style/wikibits.js.
2608 function getEditToolbar() {
2609 global $wgStylePath, $wgLang, $wgMimeType;
2611 // toolarray an array of arrays which each include the filename of
2612 // the button image (without path), the opening tag, the closing tag,
2613 // and optionally a sample text that is inserted between the two when no
2614 // selection is highlighted.
2615 // The tip text is shown when the user moves the mouse over the button.
2617 // Already here are accesskeys (key), which are not used yet until someone
2618 // can figure out a way to make them work in IE. However, we should make
2619 // sure these keys are not defined on the edit page.
2621 array( 'image'=>'button_bold.png',
2624 'sample'=>wfMsg('bold_sample'),
2625 'tip'=>wfMsg('bold_tip'),
2628 array( "image"=>"button_italic.png",
2631 "sample"=>wfMsg("italic_sample"),
2632 "tip"=>wfMsg("italic_tip"),
2635 array( "image"=>"button_link.png",
2638 "sample"=>wfMsg("link_sample"),
2639 "tip"=>wfMsg("link_tip"),
2642 array( "image"=>"button_extlink.png",
2645 "sample"=>wfMsg("extlink_sample"),
2646 "tip"=>wfMsg("extlink_tip"),
2649 array( "image"=>"button_headline.png",
2652 "sample"=>wfMsg("headline_sample"),
2653 "tip"=>wfMsg("headline_tip"),
2656 array( "image"=>"button_image.png",
2657 "open"=>"[[".$wgLang->getNsText(NS_IMAGE
).":",
2659 "sample"=>wfMsg("image_sample"),
2660 "tip"=>wfMsg("image_tip"),
2663 array( "image"=>"button_media.png",
2664 "open"=>"[[".$wgLang->getNsText(NS_MEDIA
).":",
2666 "sample"=>wfMsg("media_sample"),
2667 "tip"=>wfMsg("media_tip"),
2670 array( "image"=>"button_math.png",
2671 "open"=>"\\<math\\>",
2672 "close"=>"\\</math\\>",
2673 "sample"=>wfMsg("math_sample"),
2674 "tip"=>wfMsg("math_tip"),
2677 array( "image"=>"button_nowiki.png",
2678 "open"=>"\\<nowiki\\>",
2679 "close"=>"\\</nowiki\\>",
2680 "sample"=>wfMsg("nowiki_sample"),
2681 "tip"=>wfMsg("nowiki_tip"),
2684 array( "image"=>"button_sig.png",
2688 "tip"=>wfMsg("sig_tip"),
2691 array( "image"=>"button_hr.png",
2692 "open"=>"\\n----\\n",
2695 "tip"=>wfMsg("hr_tip"),
2699 $toolbar ="<script type='text/javascript'>\n/*<![CDATA[*/\n";
2701 $toolbar.="document.writeln(\"<div id='toolbar'>\");\n";
2702 foreach($toolarray as $tool) {
2704 $image=$wgStylePath.'/images/'.$tool['image'];
2705 $open=$tool['open'];
2706 $close=$tool['close'];
2707 $sample = addslashes( $tool['sample'] );
2709 // Note that we use the tip both for the ALT tag and the TITLE tag of the image.
2710 // Older browsers show a "speedtip" type message only for ALT.
2711 // Ideally these should be different, realistically they
2712 // probably don't need to be.
2713 $tip = addslashes( $tool['tip'] );
2715 #$key = $tool["key"];
2717 $toolbar.="addButton('$image','$tip','$open','$close','$sample');\n";
2720 $toolbar.="addInfobox('" . addslashes( wfMsg( "infobox" ) ) . "','" . addslashes(wfMsg("infobox_alert")) . "');\n";
2721 $toolbar.="document.writeln(\"</div>\");\n";
2723 $toolbar.="/*]]>*/\n</script>";