5c16a87fb12e1952750b09eb3528c4b84b7d294f
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 $fname = 'Skin::makeLinkObj';
1445 if ( $nt->isExternal() ) {
1446 $u = $nt->getFullURL();
1447 $link = $nt->getPrefixedURL();
1448 if ( '' == $text ) { $text = $nt->getPrefixedText(); }
1449 $style = $this->getExternalLinkAttributes( $link, $text, 'extiw' );
1452 if ( '' != $trail ) {
1453 if ( preg_match( '/^([a-z]+)(.*)$$/sD', $trail, $m ) ) {
1458 $retVal = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1459 } elseif ( 0 == $nt->getNamespace() && "" == $nt->getText() ) {
1460 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1461 } elseif ( ( -1 == $nt->getNamespace() ) ||
1462 ( Namespace::getImage() == $nt->getNamespace() ) ) {
1463 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1465 $aid = $nt->getArticleID() ;
1467 $retVal = $this->makeBrokenLinkObj( $nt, $text, $query, $trail, $prefix );
1469 $threshold = $wgUser->getOption('stubthreshold') ;
1470 if ( $threshold > 0 ) {
1471 $s = $dbr->getArray( 'cur',
1472 array( 'LENGTH(cur_text) AS x', 'cur_namespace', 'cur_is_redirect' ),
1473 array( 'cur_id' => $aid ),
1477 if ( $s !== false ) {
1479 if ( $s->cur_is_redirect
OR $s->cur_namespace
!= 0 ) {
1480 $size = $threshold*2 ; # Really big
1483 $size = $threshold*2 ; # Really big
1488 if ( $size < $threshold ) {
1489 $retVal = $this->makeStubLinkObj( $nt, $text, $query, $trail, $prefix );
1491 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1498 # Pass a title object, not a title string
1499 function makeKnownLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' , $aprops = '')
1501 global $wgOut, $wgTitle, $wgInputEncoding;
1503 $fname = 'Skin::makeKnownLinkObj';
1504 wfProfileIn( $fname );
1506 if ( !is_object( $nt ) ) {
1509 $link = $nt->getPrefixedURL();
1511 if ( '' == $link ) {
1513 if ( '' == $text ) {
1514 $text = htmlspecialchars( $nt->getFragment() );
1517 $u = $nt->escapeLocalURL( $query );
1519 if ( '' != $nt->getFragment() ) {
1520 $anchor = urlencode( do_html_entity_decode( str_replace(' ', '_', $nt->getFragment()), ENT_COMPAT
, $wgInputEncoding ) );
1521 $replacearray = array(
1525 $u .= '#' . str_replace(array_keys($replacearray),array_values($replacearray),$anchor);
1527 if ( '' == $text ) {
1528 $text = htmlspecialchars( $nt->getPrefixedText() );
1530 $style = $this->getInternalLinkAttributesObj( $nt, $text );
1533 if ( '' != $trail ) {
1534 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1539 $r = "<a href=\"{$u}\"{$style}{$aprops}>{$prefix}{$text}{$inside}</a>{$trail}";
1540 wfProfileOut( $fname );
1544 # Pass a title object, not a title string
1545 function makeBrokenLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
1547 global $wgOut, $wgUser;
1549 $fname = 'Skin::makeBrokenLinkObj';
1550 wfProfileIn( $fname );
1552 if ( '' == $query ) {
1555 $q = 'action=edit&'.$query;
1557 $u = $nt->escapeLocalURL( $q );
1559 if ( '' == $text ) {
1560 $text = htmlspecialchars( $nt->getPrefixedText() );
1562 $style = $this->getInternalLinkAttributesObj( $nt, $text, "yes" );
1565 if ( '' != $trail ) {
1566 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1571 if ( $wgUser->getOption( 'highlightbroken' ) ) {
1572 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1574 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>?</a>{$trail}";
1577 wfProfileOut( $fname );
1581 # Pass a title object, not a title string
1582 function makeStubLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
1584 global $wgOut, $wgUser;
1586 $link = $nt->getPrefixedURL();
1588 $u = $nt->escapeLocalURL( $query );
1590 if ( '' == $text ) {
1591 $text = htmlspecialchars( $nt->getPrefixedText() );
1593 $style = $this->getInternalLinkAttributesObj( $nt, $text, 'stub' );
1596 if ( '' != $trail ) {
1597 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1602 if ( $wgUser->getOption( 'highlightbroken' ) ) {
1603 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1605 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>!</a>{$trail}";
1610 function makeSelfLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
1612 $u = $nt->escapeLocalURL( $query );
1613 if ( '' == $text ) {
1614 $text = htmlspecialchars( $nt->getPrefixedText() );
1617 if ( '' != $trail ) {
1618 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1623 return "<strong>{$prefix}{$text}{$inside}</strong>{$trail}";
1626 /* these are used extensively in SkinPHPTal, but also some other places */
1627 /*static*/ function makeSpecialUrl( $name, $urlaction='' ) {
1628 $title = Title
::makeTitle( NS_SPECIAL
, $name );
1629 $this->checkTitle($title, $name);
1630 return $title->getLocalURL( $urlaction );
1632 /*static*/ function makeTalkUrl ( $name, $urlaction='' ) {
1633 $title = Title
::newFromText( $name );
1634 $title = $title->getTalkPage();
1635 $this->checkTitle($title, $name);
1636 return $title->getLocalURL( $urlaction );
1638 /*static*/ function makeArticleUrl ( $name, $urlaction='' ) {
1639 $title = Title
::newFromText( $name );
1640 $title= $title->getSubjectPage();
1641 $this->checkTitle($title, $name);
1642 return $title->getLocalURL( $urlaction );
1644 /*static*/ function makeI18nUrl ( $name, $urlaction='' ) {
1645 $title = Title
::newFromText( wfMsg($name) );
1646 $this->checkTitle($title, $name);
1647 return $title->getLocalURL( $urlaction );
1649 /*static*/ function makeUrl ( $name, $urlaction='' ) {
1650 $title = Title
::newFromText( $name );
1651 $this->checkTitle($title, $name);
1652 return $title->getLocalURL( $urlaction );
1654 # this can be passed the NS number as defined in Language.php
1655 /*static*/ function makeNSUrl( $name, $urlaction='', $namespace=0 ) {
1656 $title = Title
::makeTitle( $namespace, $name );
1657 $this->checkTitle($title, $name);
1658 return $title->getLocalURL( $urlaction );
1661 /* these return an array with the 'href' and boolean 'exists' */
1662 /*static*/ function makeUrlDetails ( $name, $urlaction='' ) {
1663 $title = Title
::newFromText( $name );
1664 $this->checkTitle($title, $name);
1666 'href' => $title->getLocalURL( $urlaction ),
1667 'exists' => $title->getArticleID() != 0?
true:false
1670 /*static*/ function makeTalkUrlDetails ( $name, $urlaction='' ) {
1671 $title = Title
::newFromText( $name );
1672 $title = $title->getTalkPage();
1673 $this->checkTitle($title, $name);
1675 'href' => $title->getLocalURL( $urlaction ),
1676 'exists' => $title->getArticleID() != 0?
true:false
1679 /*static*/ function makeArticleUrlDetails ( $name, $urlaction='' ) {
1680 $title = Title
::newFromText( $name );
1681 $title= $title->getSubjectPage();
1682 $this->checkTitle($title, $name);
1684 'href' => $title->getLocalURL( $urlaction ),
1685 'exists' => $title->getArticleID() != 0?
true:false
1688 /*static*/ function makeI18nUrlDetails ( $name, $urlaction='' ) {
1689 $title = Title
::newFromText( wfMsg($name) );
1690 $this->checkTitle($title, $name);
1692 'href' => $title->getLocalURL( $urlaction ),
1693 'exists' => $title->getArticleID() != 0?
true:false
1697 # make sure we have some title to operate on
1698 /*static*/ function checkTitle ( &$title, &$name ) {
1699 if(!is_object($title)) {
1700 $title = Title
::newFromText( $name );
1701 if(!is_object($title)) {
1702 $title = Title
::newFromText( '--error: link target missing--' );
1707 function fnamePart( $url )
1709 $basename = strrchr( $url, '/' );
1710 if ( false === $basename ) { $basename = $url; }
1711 else { $basename = substr( $basename, 1 ); }
1712 return wfEscapeHTML( $basename );
1715 function makeImage( $url, $alt = '' )
1719 if ( '' == $alt ) { $alt = $this->fnamePart( $url ); }
1720 $s = '<img src="'.$url.'" alt="'.$alt.'" />';
1724 function makeImageLink( $name, $url, $alt = '' ) {
1725 $nt = Title
::makeTitle( Namespace::getImage(), $name );
1726 return $this->makeImageLinkObj( $nt, $alt );
1729 function makeImageLinkObj( $nt, $alt = '' ) {
1730 global $wgLang, $wgUseImageResize;
1731 $img = Image
::newFromTitle( $nt );
1732 $url = $img->getURL();
1735 $prefix = $postfix = '';
1737 if ( $wgUseImageResize ) {
1738 # Check if the alt text is of the form "options|alt text"
1740 # * thumbnail make a thumbnail with enlarge-icon and caption, alignment depends on lang
1741 # * left no resizing, just left align. label is used for alt= only
1742 # * right same, but right aligned
1743 # * none same, but not aligned
1744 # * ___px scale to ___ pixels width, no aligning. e.g. use in taxobox
1745 # * center center the image
1746 # * framed Keep original image size, no magnify-button.
1748 $part = explode( '|', $alt);
1750 $mwThumb =& MagicWord
::get( MAG_IMG_THUMBNAIL
);
1751 $mwLeft =& MagicWord
::get( MAG_IMG_LEFT
);
1752 $mwRight =& MagicWord
::get( MAG_IMG_RIGHT
);
1753 $mwNone =& MagicWord
::get( MAG_IMG_NONE
);
1754 $mwWidth =& MagicWord
::get( MAG_IMG_WIDTH
);
1755 $mwCenter =& MagicWord
::get( MAG_IMG_CENTER
);
1756 $mwFramed =& MagicWord
::get( MAG_IMG_FRAMED
);
1757 $alt = $part[count($part)-1];
1759 $height = $framed = $thumb = false;
1760 $manual_thumb = "" ;
1762 foreach( $part as $key => $val ) {
1763 $val_parts = explode ( "=" , $val , 2 ) ;
1764 $left_part = array_shift ( $val_parts ) ;
1765 if ( ! is_null( $mwThumb->matchVariableStartToEnd($val) ) ) {
1767 } elseif ( count ( $val_parts ) == 1 && ! is_null( $mwThumb->matchVariableStartToEnd($left_part) ) ) {
1768 # use manually specified thumbnail
1770 $manual_thumb = array_shift ( $val_parts ) ;
1771 } elseif ( ! is_null( $mwRight->matchVariableStartToEnd($val) ) ) {
1772 # remember to set an alignment, don't render immediately
1774 } elseif ( ! is_null( $mwLeft->matchVariableStartToEnd($val) ) ) {
1775 # remember to set an alignment, don't render immediately
1777 } elseif ( ! is_null( $mwCenter->matchVariableStartToEnd($val) ) ) {
1778 # remember to set an alignment, don't render immediately
1780 } elseif ( ! is_null( $mwNone->matchVariableStartToEnd($val) ) ) {
1781 # remember to set an alignment, don't render immediately
1783 } elseif ( ! is_null( $match = $mwWidth->matchVariableStartToEnd($val) ) ) {
1784 # $match is the image width in pixels
1785 if ( preg_match( '/^([0-9]*)x([0-9]*)$/', $match, $m ) ) {
1786 $width = intval( $m[1] );
1787 $height = intval( $m[2] );
1789 $width = intval($match);
1791 } elseif ( ! is_null( $mwFramed->matchVariableStartToEnd($val) ) ) {
1795 if ( 'center' == $align )
1797 $prefix = '<span style="text-align: center">';
1798 $postfix = '</span>';
1802 if ( $thumb ||
$framed ) {
1804 # Create a thumbnail. Alignment depends on language
1805 # writing direction, # right aligned for left-to-right-
1806 # languages ("Western languages"), left-aligned
1807 # for right-to-left-languages ("Semitic languages")
1809 # If thumbnail width has not been provided, it is set
1810 # here to 180 pixels
1811 if ( $align == '' ) {
1812 $align = $wgLang->isRTL() ?
'left' : 'right';
1814 if ( ! isset($width) ) {
1817 return $prefix.$this->makeThumbLinkObj( $img, $alt, $align, $width, $height, $framed, $manual_thumb ).$postfix;
1819 } elseif ( isset($width) ) {
1821 # Create a resized image, without the additional thumbnail
1824 if ( ( ! $height === false )
1825 && ( $img->getHeight() * $width / $img->getWidth() > $height ) ) {
1826 print "height=$height<br>\nimg->getHeight() = ".$img->getHeight()."<br>\n";
1827 print 'rescaling by factor '. $height / $img->getHeight() . "<br>\n";
1828 $width = $img->getWidth() * $height / $img->getHeight();
1830 if ( '' == $manual_thumb ) $url = $img->createThumb( $width );
1832 } # endif $wgUseImageResize
1834 if ( empty( $alt ) ) {
1835 $alt = preg_replace( '/\.(.+?)^/', '', $img->getName() );
1837 $alt = htmlspecialchars( $alt );
1839 $u = $nt->escapeLocalURL();
1842 $s = str_replace( "$1", $img->getName(), wfMsg('missingimage') );
1843 $s .= "<br>{$alt}<br>{$url}<br>\n";
1845 $s = '<a href="'.$u.'" class="image" title="'.$alt.'">' .
1846 '<img src="'.$url.'" alt="'.$alt.'" /></a>';
1848 if ( '' != $align ) {
1849 $s = "<div class=\"float{$align}\"><span>{$s}</span></div>";
1851 return str_replace("\n", ' ',$prefix.$s.$postfix);
1855 function makeThumbLinkObj( $img, $label = '', $align = 'right', $boxwidth = 180, $boxheight=false, $framed=false , $manual_thumb = "" ) {
1856 global $wgStylePath, $wgLang;
1857 # $image = Title::makeTitle( Namespace::getImage(), $name );
1858 $url = $img->getURL();
1860 #$label = htmlspecialchars( $label );
1861 $alt = preg_replace( '/<[^>]*>/', '', $label);
1862 $alt = htmlspecialchars( $alt );
1864 if ( $img->exists() )
1866 $width = $img->getWidth();
1867 $height = $img->getHeight();
1869 $width = $height = 200;
1873 // Use image dimensions, don't scale
1875 $oboxwidth = $boxwidth +
2;
1876 $boxheight = $height;
1879 $h = intval( $height/($width/$boxwidth) );
1880 $oboxwidth = $boxwidth +
2;
1881 if ( ( ! $boxheight === false ) && ( $h > $boxheight ) )
1883 $boxwidth *= $boxheight/$h;
1887 if ( '' == $manual_thumb ) $thumbUrl = $img->createThumb( $boxwidth );
1890 if ( $manual_thumb != '' ) # Use manually specified thumbnail
1892 $manual_title = Title
::makeTitle( Namespace::getImage(), $manual_thumb ); #new Title ( $manual_thumb ) ;
1893 $manual_img = Image
::newFromTitle( $manual_title );
1894 $thumbUrl = $manual_img->getURL();
1895 if ( $manual_img->exists() )
1897 $width = $manual_img->getWidth();
1898 $height = $manual_img->getHeight();
1899 $boxwidth = $width ;
1900 $boxheight = $height ;
1901 $oboxwidth = $boxwidth +
2 ;
1905 $u = $img->getEscapeLocalURL();
1907 $more = htmlspecialchars( wfMsg( 'thumbnail-more' ) );
1908 $magnifyalign = $wgLang->isRTL() ?
'left' : 'right';
1909 $textalign = $wgLang->isRTL() ?
' style="text-align:right"' : '';
1911 $s = "<div class=\"thumb t{$align}\"><div style=\"width:{$oboxwidth}px;\">";
1912 if ( $thumbUrl == '' ) {
1913 $s .= str_replace( "$1", $img->getName(), wfMsg('missingimage') );
1916 $s .= '<a href="'.$u.'" class="internal" title="'.$alt.'">'.
1917 '<img src="'.$thumbUrl.'" alt="'.$alt.'" ' .
1918 'width="'.$boxwidth.'" height="'.$boxheight.'" /></a>';
1922 $zoomicon = '<div class="magnify" style="float:'.$magnifyalign.'">'.
1923 '<a href="'.$u.'" class="internal" title="'.$more.'">'.
1924 '<img src="'.$wgStylePath.'/images/magnify-clip.png" ' .
1925 'width="15" height="11" alt="'.$more.'" /></a></div>';
1928 $s .= ' <div class="thumbcaption" '.$textalign.'>'.$zoomicon.$label."</div></div></div>";
1929 return str_replace("\n", ' ', $s);
1932 function makeMediaLink( $name, $url, $alt = "" ) {
1933 $nt = Title
::makeTitle( Namespace::getMedia(), $name );
1934 return $this->makeMediaLinkObj( $nt, $alt );
1937 function makeMediaLinkObj( $nt, $alt = "" )
1939 if ( ! isset( $nt ) )
1941 ### HOTFIX. Instead of breaking, return empry string.
1944 $name = $nt->getDBKey();
1945 $url = Image
::wfImageUrl( $name );
1946 if ( empty( $alt ) ) {
1947 $alt = preg_replace( '/\.(.+?)^/', '', $name );
1950 $u = htmlspecialchars( $url );
1951 $s = "<a href=\"{$u}\" class='internal' title=\"{$alt}\">{$alt}</a>";
1956 function specialLink( $name, $key = "" )
1960 if ( '' == $key ) { $key = strtolower( $name ); }
1961 $pn = $wgLang->ucfirst( $name );
1962 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1966 function makeExternalLink( $url, $text, $escape = true ) {
1967 $style = $this->getExternalLinkAttributes( $url, $text );
1968 $url = htmlspecialchars( $url );
1970 $text = htmlspecialchars( $text );
1972 return '<a href="'.$url.'"'.$style.'>'.$text.'</a>';
1975 # Called by history lists and recent changes
1978 # Returns text for the start of the tabular part of RC
1979 function beginRecentChangesList()
1981 $this->rc_cache
= array() ;
1982 $this->rcMoveIndex
= 0;
1983 $this->rcCacheIndex
= 0 ;
1984 $this->lastdate
= '';
1985 $this->rclistOpen
= false;
1989 function beginImageHistoryList()
1991 $s = "\n<h2>" . wfMsg( 'imghistory' ) . "</h2>\n" .
1992 "<p>" . wfMsg( 'imghistlegend' ) . "</p>\n".'<ul class="special">';
1996 # Returns text for the end of RC
1997 # If enhanced RC is in use, returns pretty much all the text
1998 function endRecentChangesList()
2000 $s = $this->recentChangesBlock() ;
2001 if( $this->rclistOpen
) {
2007 # Enhanced RC ungrouped line
2008 function recentChangesBlockLine ( $rcObj )
2010 global $wgStylePath, $wgLang ;
2012 # Get rc_xxxx variables
2013 extract( $rcObj->mAttribs
) ;
2014 $curIdEq = 'curid='.$rc_cur_id;
2019 $r .= '<img src="'.$wgStylePath.'/images/Arr_.png" width="12" height="12" border="0" />' ;
2022 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2023 $r .= ' ';
2025 # M & N (minor & new)
2026 $M = wfMsg( 'minoreditletter' );
2027 $N = wfMsg( 'newpageletter' );
2029 if ( $rc_type == RC_NEW
) {
2042 $r .= ' '.$rcObj->timestamp
.' ' ;
2046 $link = $rcObj->link
;
2047 if ( $rcObj->watched
) $link = '<strong>'.$link.'</strong>' ;
2052 $r .= $rcObj->difflink
;
2056 $r .= $this->makeKnownLinkObj( $rcObj->getTitle(), wfMsg( 'hist' ), $curIdEq.'&action=history' );
2059 $r .= ') . . '.$rcObj->userlink
;
2060 $r .= $rcObj->usertalklink
;
2063 if ( $rc_comment != '' && $rc_type != RC_MOVE
&& $rc_type != RC_MOVE_OVER_REDIRECT
) {
2064 $rc_comment=$this->formatComment($rc_comment);
2065 $r .= $wgLang->emphasize( ' ('.$rc_comment.')' );
2073 function recentChangesBlockGroup ( $block )
2075 global $wgStylePath, $wgLang ;
2078 $M = wfMsg( 'minoreditletter' );
2079 $N = wfMsg( 'newpageletter' );
2081 # Collate list of users
2083 $userlinks = array () ;
2084 foreach ( $block AS $rcObj ) {
2085 $oldid = $rcObj->mAttribs
['rc_last_oldid'];
2086 if ( $rcObj->mAttribs
['rc_new'] ) $isnew = true ;
2087 $u = $rcObj->userlink
;
2088 if ( !isset ( $userlinks[$u] ) ) $userlinks[$u] = 0 ;
2092 # Sort the list and convert to text
2093 krsort ( $userlinks ) ;
2094 asort ( $userlinks ) ;
2096 foreach ( $userlinks as $userlink => $count) {
2098 if ( $count > 1 ) $text .= " ({$count}×)" ;
2099 array_push ( $users , $text ) ;
2101 $users = ' <font size="-1">['.implode('; ',$users).']</font>' ;
2104 $rci = 'RCI'.$this->rcCacheIndex
;
2105 $rcl = 'RCL'.$this->rcCacheIndex
;
2106 $rcm = 'RCM'.$this->rcCacheIndex
;
2107 $toggleLink = "javascript:toggleVisibility('$rci','$rcm','$rcl')" ;
2108 $arrowdir = $wgLang->isRTL() ?
'l' : 'r';
2109 $tl = '<span id="'.$rcm.'"><a href="'.$toggleLink.'"><img src="'.$wgStylePath.'/images/Arr_'.$arrowdir.'.png" width="12" height="12" /></a></span>' ;
2110 $tl .= '<span id="'.$rcl.'" style="display:none"><a href="'.$toggleLink.'"><img src="'.$wgStylePath.'/images/Arr_d.png" width="12" height="12" /></a></span>' ;
2116 if ( $isnew ) $r .= $N ;
2117 else $r .= ' ' ;
2118 $r .= ' ' ; # Minor
2121 $r .= ' '.$block[0]->timestamp
.' ' ;
2125 $link = $block[0]->link
;
2126 if ( $block[0]->watched
) $link = '<strong>'.$link.'</strong>' ;
2129 $curIdEq = 'curid=' . $block[0]->mAttribs
['rc_cur_id'];
2130 if ( $block[0]->mAttribs
['rc_type'] != RC_LOG
) {
2132 $r .= ' ('.count($block).' ' ;
2133 if ( $isnew ) $r .= wfMsg('changes');
2134 else $r .= $this->makeKnownLinkObj( $block[0]->getTitle() , wfMsg('changes') ,
2135 $curIdEq.'&diff=0&oldid='.$oldid ) ;
2139 $r .= $this->makeKnownLinkObj( $block[0]->getTitle(), wfMsg( 'history' ), $curIdEq.'&action=history' );
2147 $r .= '<div id="'.$rci.'" style="display:none">' ;
2148 foreach ( $block AS $rcObj ) {
2149 # Get rc_xxxx variables
2150 extract( $rcObj->mAttribs
);
2152 $r .= '<img src="'.$wgStylePath.'/images/Arr_.png" width="12" height="12" />';
2153 $r .= '<tt> ' ;
2154 if ( $rc_new ) $r .= $N ;
2155 else $r .= ' ' ;
2156 if ( $rc_minor ) $r .= $M ;
2157 else $r .= ' ' ;
2161 if ( $rc_last_oldid != 0 ) {
2162 $o = 'oldid='.$rc_last_oldid ;
2164 if ( $rc_type == RC_LOG
) {
2165 $link = $rcObj->timestamp
;
2167 $link = $this->makeKnownLinkObj( $rcObj->getTitle(), $rcObj->timestamp
, "{$curIdEq}&$o" ) ;
2169 $link = '<tt>'.$link.'</tt>' ;
2173 $r .= $rcObj->curlink
;
2175 $r .= $rcObj->lastlink
;
2176 $r .= ') . . '.$rcObj->userlink
;
2177 $r .= $rcObj->usertalklink
;
2178 if ( $rc_comment != '' ) {
2179 $rc_comment=$this->formatComment($rc_comment);
2180 $r .= $wgLang->emphasize( ' ('.$rc_comment.')' ) ;
2186 $this->rcCacheIndex++
;
2190 # If enhanced RC is in use, this function takes the previously cached
2191 # RC lines, arranges them, and outputs the HTML
2192 function recentChangesBlock ()
2194 global $wgStylePath ;
2195 if ( count ( $this->rc_cache
) == 0 ) return '' ;
2197 foreach ( $this->rc_cache
AS $secureName => $block ) {
2198 if ( count ( $block ) < 2 ) {
2199 $blockOut .= $this->recentChangesBlockLine ( array_shift ( $block ) ) ;
2201 $blockOut .= $this->recentChangesBlockGroup ( $block ) ;
2205 return '<div>'.$blockOut.'</div>' ;
2208 # Called in a loop over all displayed RC entries
2209 # Either returns the line, or caches it for later use
2210 function recentChangesLine( &$rc, $watched = false )
2213 $usenew = $wgUser->getOption( 'usenewrc' );
2215 $line = $this->recentChangesLineNew ( $rc, $watched ) ;
2217 $line = $this->recentChangesLineOld ( $rc, $watched ) ;
2221 function recentChangesLineOld( &$rc, $watched = false )
2223 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds;
2225 # Extract DB fields into local scope
2226 extract( $rc->mAttribs
);
2227 $curIdEq = 'curid=' . $rc_cur_id;
2229 # Make date header if necessary
2230 $date = $wgLang->date( $rc_timestamp, true);
2232 if ( $date != $this->lastdate
) {
2233 if ( '' != $this->lastdate
) { $s .= "</ul>\n"; }
2234 $s .= "<h4>{$date}</h4>\n<ul class='special'>";
2235 $this->lastdate
= $date;
2236 $this->rclistOpen
= true;
2240 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2242 $s .= '(' . wfMsg( 'diff' ) . ') (';
2244 $s .= $this->makeKnownLinkObj( $rc->getMovedToTitle(), wfMsg( 'hist' ), 'action=history' ) .
2247 # "[[x]] moved to [[y]]"
2248 if ( $rc_type == RC_MOVE
) {
2251 $msg = '1movedto2_redir';
2253 $s .= wfMsg( $msg, $this->makeKnownLinkObj( $rc->getTitle(), '', 'redirect=no' ),
2254 $this->makeKnownLinkObj( $rc->getMovedToTitle(), '' ) );
2257 if ( $rc_type == RC_NEW ||
$rc_type == RC_LOG
) {
2258 $diffLink = wfMsg( 'diff' );
2260 $diffLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'diff' ),
2261 $curIdEq.'&diff='.$rc_this_oldid.'&oldid='.$rc_last_oldid ,'' ,'' , ' tabindex="'.$rc->counter
.'"');
2263 $s .= '('.$diffLink.') (';
2266 $s .= $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'hist' ), $curIdEq.'&action=history' );
2269 # M and N (minor and new)
2270 $M = wfMsg( 'minoreditletter' );
2271 $N = wfMsg( 'newpageletter' );
2272 if ( $rc_minor ) { $s .= ' <strong>'.$M.'</strong>'; }
2273 if ( $rc_type == RC_NEW
) { $s .= '<strong>'.$N.'</strong>'; }
2276 $articleLink = $this->makeKnownLinkObj( $rc->getTitle(), '' );
2279 $articleLink = '<strong>'.$articleLink.'</strong>';
2281 $s .= ' '.$articleLink;
2286 $s .= '; ' . $wgLang->time( $rc_timestamp, true, $wgRCSeconds ) . ' . . ';
2288 # User link (or contributions for unregistered users)
2289 if ( 0 == $rc_user ) {
2290 $userLink = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
2291 $rc_user_text, 'target=' . $rc_user_text );
2293 $userLink = $this->makeLink( $wgLang->getNsText( NS_USER
) . ':'.$rc_user_text, $rc_user_text );
2298 $talkname=$wgLang->getNsText(NS_TALK
); # use the shorter name
2299 global $wgDisableAnonTalk;
2300 if( 0 == $rc_user && $wgDisableAnonTalk ) {
2303 $utns=$wgLang->getNsText(NS_USER_TALK
);
2304 $userTalkLink= $this->makeLink($utns . ':'.$rc_user_text, $talkname );
2308 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2309 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2310 'Blockip' ), wfMsg( 'blocklink' ), 'ip='.$rc_user_text );
2314 if($userTalkLink) $userTalkLink .= ' | ';
2315 $userTalkLink .= $blockLink;
2317 if($userTalkLink) $s.=' ('.$userTalkLink.')';
2320 if ( '' != $rc_comment && '*' != $rc_comment && $rc_type != RC_MOVE
&& $rc_type != RC_MOVE_OVER_REDIRECT
) {
2321 $rc_comment=$this->formatComment($rc_comment);
2322 $s .= $wgLang->emphasize(' (' . $rc_comment . ')');
2329 # function recentChangesLineNew( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched = false, $oldid = 0 , $diffid = 0 )
2330 function recentChangesLineNew( &$baseRC, $watched = false )
2332 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds;
2334 # Create a specialised object
2335 $rc = RCCacheEntry
::newFromParent( $baseRC ) ;
2337 # Extract fields from DB into the function scope (rc_xxxx variables)
2338 extract( $rc->mAttribs
);
2339 $curIdEq = 'curid=' . $rc_cur_id;
2341 # If it's a new day, add the headline and flush the cache
2342 $date = $wgLang->date( $rc_timestamp, true);
2344 if ( $date != $this->lastdate
) {
2345 # Process current cache
2346 $ret = $this->recentChangesBlock () ;
2347 $this->rc_cache
= array() ;
2348 $ret .= "<h4>{$date}</h4>\n";
2349 $this->lastdate
= $date;
2353 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2354 if ( $rc_type == RC_MOVE
) {
2357 $msg = "1movedto2_redir";
2359 $clink = wfMsg( $msg, $this->makeKnownLinkObj( $rc->getTitle(), '', 'redirect=no' ),
2360 $this->makeKnownLinkObj( $rc->getMovedToTitle(), '' ) );
2362 $clink = $this->makeKnownLinkObj( $rc->getTitle(), '' ) ;
2365 $time = $wgLang->time( $rc_timestamp, true, $wgRCSeconds );
2366 $rc->watched
= $watched ;
2367 $rc->link
= $clink ;
2368 $rc->timestamp
= $time;
2370 # Make "cur" and "diff" links
2371 if ( ( $rc_type == RC_NEW
&& $rc_this_oldid == 0 ) ||
$rc_type == RC_LOG ||
$rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2372 $curLink = wfMsg( 'cur' );
2373 $diffLink = wfMsg( 'diff' );
2375 $query = $curIdEq.'&diff=0&oldid='.$rc_this_oldid;
2376 $aprops = ' tabindex="'.$baseRC->counter
.'"';
2377 $curLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'cur' ), $query, '' ,'' , $aprops );
2378 $diffLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'diff'), $query, '' ,'' , $aprops );
2382 $titleObj = $rc->getTitle();
2383 if ( $rc_last_oldid == 0 ||
$rc_type == RC_LOG ||
$rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2384 $lastLink = wfMsg( 'last' );
2386 $lastLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'last' ),
2387 $curIdEq.'&diff='.$rc_this_oldid.'&oldid='.$rc_last_oldid );
2390 # Make user link (or user contributions for unregistered users)
2391 if ( 0 == $rc_user ) {
2392 $userLink = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
2393 $rc_user_text, 'target=' . $rc_user_text );
2395 $userLink = $this->makeLink( $wgLang->getNsText(
2396 Namespace::getUser() ) . ':'.$rc_user_text, $rc_user_text );
2399 $rc->userlink
= $userLink ;
2400 $rc->lastlink
= $lastLink ;
2401 $rc->curlink
= $curLink ;
2402 $rc->difflink
= $diffLink;
2405 # Make user talk link
2406 $utns=$wgLang->getNsText(NS_USER_TALK
);
2407 $talkname=$wgLang->getNsText(NS_TALK
); # use the shorter name
2408 $userTalkLink= $this->makeLink($utns . ':'.$rc_user_text, $talkname );
2410 global $wgDisableAnonTalk;
2411 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2412 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2413 'Blockip' ), wfMsg( 'blocklink' ), 'ip='.$rc_user_text );
2414 if( $wgDisableAnonTalk )
2415 $rc->usertalklink
= ' ('.$blockLink.')';
2417 $rc->usertalklink
= ' ('.$userTalkLink.' | '.$blockLink.')';
2419 if( $wgDisableAnonTalk && ($rc_user == 0) )
2420 $rc->usertalklink
= '';
2422 $rc->usertalklink
= ' ('.$userTalkLink.')';
2425 # Put accumulated information into the cache, for later display
2426 # Page moves go on their own line
2427 $title = $rc->getTitle();
2428 $secureName = $title->getPrefixedDBkey();
2429 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2430 # Use an @ character to prevent collision with page names
2431 $this->rc_cache
['@@' . ($this->rcMoveIndex++
)] = array($rc);
2433 if ( !isset ( $this->rc_cache
[$secureName] ) ) $this->rc_cache
[$secureName] = array() ;
2434 array_push ( $this->rc_cache
[$secureName] , $rc ) ;
2439 function endImageHistoryList()
2445 /* This function is called by all recent changes variants, by the page history,
2446 and by the user contributions list. It is responsible for formatting edit
2447 comments. It escapes any HTML in the comment, but adds some CSS to format
2448 auto-generated comments (from section editing) and formats [[wikilinks]].
2449 Main author: Erik Möller (moeller@scireview.de)
2451 function formatComment($comment)
2454 $comment=wfEscapeHTML($comment);
2456 # The pattern for autogen comments is / * foo * /, which makes for
2458 # We look for all comments, match any text before and after the comment,
2459 # add a separator where needed and format the comment itself with CSS
2460 while (preg_match('/(.*)\/\*\s*(.*?)\s*\*\/(.*)/', $comment,$match)) {
2465 if($pre) { $auto = $sep.' '.$auto; }
2466 if($post) { $auto .= ' '.$sep; }
2467 $auto='<span class="autocomment">'.$auto.'</span>';
2468 $comment=$pre.$auto.$post;
2471 # format regular and media links - all other wiki formatting
2473 while(preg_match('/\[\[(.*?)(\|(.*?))*\]\]/',$comment,$match)) {
2475 $medians = $wgLang->getNsText(Namespace::getMedia()).':';
2477 if(preg_match('/^'.$medians.'/i',$match[1])) {
2478 $func='makeMediaLink';
2480 # Handle link renaming [[foo|text]] will show link as "text"
2481 if(isset($match[3]) ) {
2483 preg_replace('/\[\[(.*?)\]\]/',
2484 $this->$func($match[1],$match[3]),$comment,1);
2487 preg_replace('/\[\[(.*?)\]\]/',
2488 $this->$func($match[1],$match[1]),$comment,1);
2496 function imageHistoryLine( $iscur, $timestamp, $img, $user, $usertext, $size, $description )
2498 global $wgUser, $wgLang, $wgTitle;
2500 $datetime = $wgLang->timeanddate( $timestamp, true );
2501 $del = wfMsg( 'deleteimg' );
2502 $cur = wfMsg( 'cur' );
2505 $url = Image
::wfImageUrl( $img );
2507 if ( $wgUser->isSysop() ) {
2508 $link = $wgTitle->escapeLocalURL( 'image=' . $wgTitle->getPartialURL() .
2510 $style = $this->getInternalLinkAttributes( $link, $del );
2512 $dlink = '<a href="'.$link.'"'.$style.'>'.$del.'</a>';
2517 $url = wfEscapeHTML( wfImageArchiveUrl( $img ) );
2518 if( $wgUser->getID() != 0 ) {
2519 $rlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2520 wfMsg( 'revertimg' ), 'action=revert&oldimage=' .
2521 urlencode( $img ) );
2522 $dlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2523 $del, 'action=delete&oldimage=' . urlencode( $img ) );
2525 # Having live active links for non-logged in users
2526 # means that bots and spiders crawling our site can
2527 # inadvertently change content. Baaaad idea.
2528 $rlink = wfMsg( 'revertimg' );
2533 $userlink = $usertext;
2535 $userlink = $this->makeLink( $wgLang->getNsText( Namespace::getUser() ) .
2536 ':'.$usertext, $usertext );
2538 $nbytes = wfMsg( 'nbytes', $size );
2539 $style = $this->getInternalLinkAttributes( $url, $datetime );
2541 $s = "<li> ({$dlink}) ({$rlink}) <a href=\"{$url}\"{$style}>{$datetime}</a>"
2542 . " . . {$userlink} ({$nbytes})";
2544 if ( '' != $description && '*' != $description ) {
2545 $sk=$wgUser->getSkin();
2546 $s .= $wgLang->emphasize(' (' . $sk->formatComment($description) . ')');
2552 function tocIndent($level) {
2553 return str_repeat( '<div class="tocindent">'."\n", $level>0 ?
$level : 0 );
2556 function tocUnindent($level) {
2557 return str_repeat( "</div>\n", $level>0 ?
$level : 0 );
2560 # parameter level defines if we are on an indentation level
2561 function tocLine( $anchor, $tocline, $level ) {
2562 $link = '<a href="#'.$anchor.'">'.$tocline.'</a><br />';
2566 return '<div class="tocline">'.$link."</div>\n";
2571 function tocTable($toc) {
2572 # note to CSS fanatics: putting this in a div does not work -- div won't auto-expand
2573 # try min-width & co when somebody gets a chance
2574 $hideline = ' <script type="text/javascript">showTocToggle("' . addslashes( wfMsg('showtoc') ) . '","' . addslashes( wfMsg('hidetoc') ) . '")</script>';
2576 '<table border="0" id="toc"><tr id="toctitle"><td align="center">'."\n".
2577 '<b>'.wfMsg('toc').'</b>' .
2579 '</td></tr><tr id="tocinside"><td>'."\n".
2580 $toc."</td></tr></table>\n";
2583 # These two do not check for permissions: check $wgTitle->userCanEdit before calling them
2584 function editSectionScript( $section, $head ) {
2585 global $wgTitle, $wgRequest;
2586 if( $wgRequest->getInt( 'oldid' ) && ( $wgRequest->getVal( 'diff' ) != '0' ) ) {
2589 $url = $wgTitle->escapeLocalURL( 'action=edit§ion='.$section );
2590 return '<span oncontextmenu=\'document.location="'.$url.'";return false;\'>'.$head.'</span>';
2593 function editSectionLink( $section ) {
2595 global $wgTitle, $wgUser, $wgLang;
2597 if( $wgRequest->getInt( 'oldid' ) && ( $wgRequest->getVal( 'diff' ) != '0' ) ) {
2598 # Section edit links would be out of sync on an old page.
2599 # But, if we're diffing to the current page, they'll be
2604 $editurl = '§ion='.$section;
2605 $url = $this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg('editsection'),'action=edit'.$editurl);
2607 if( $wgLang->isRTL() ) {
2609 $nearside = 'right';
2614 return "<div class=\"editsection\" style=\"float:$farside;margin-$nearside:5px;\">[".$url."]</div>";
2618 // This function is called by EditPage.php and shows a bulletin board style
2619 // toolbar for common editing functions. It can be disabled in the user preferences.
2620 // The necsesary JavaScript code can be found in style/wikibits.js.
2621 function getEditToolbar() {
2622 global $wgStylePath, $wgLang, $wgMimeType;
2624 // toolarray an array of arrays which each include the filename of
2625 // the button image (without path), the opening tag, the closing tag,
2626 // and optionally a sample text that is inserted between the two when no
2627 // selection is highlighted.
2628 // The tip text is shown when the user moves the mouse over the button.
2630 // Already here are accesskeys (key), which are not used yet until someone
2631 // can figure out a way to make them work in IE. However, we should make
2632 // sure these keys are not defined on the edit page.
2634 array( 'image'=>'button_bold.png',
2637 'sample'=>wfMsg('bold_sample'),
2638 'tip'=>wfMsg('bold_tip'),
2641 array( "image"=>"button_italic.png",
2644 "sample"=>wfMsg("italic_sample"),
2645 "tip"=>wfMsg("italic_tip"),
2648 array( "image"=>"button_link.png",
2651 "sample"=>wfMsg("link_sample"),
2652 "tip"=>wfMsg("link_tip"),
2655 array( "image"=>"button_extlink.png",
2658 "sample"=>wfMsg("extlink_sample"),
2659 "tip"=>wfMsg("extlink_tip"),
2662 array( "image"=>"button_headline.png",
2665 "sample"=>wfMsg("headline_sample"),
2666 "tip"=>wfMsg("headline_tip"),
2669 array( "image"=>"button_image.png",
2670 "open"=>"[[".$wgLang->getNsText(NS_IMAGE
).":",
2672 "sample"=>wfMsg("image_sample"),
2673 "tip"=>wfMsg("image_tip"),
2676 array( "image"=>"button_media.png",
2677 "open"=>"[[".$wgLang->getNsText(NS_MEDIA
).":",
2679 "sample"=>wfMsg("media_sample"),
2680 "tip"=>wfMsg("media_tip"),
2683 array( "image"=>"button_math.png",
2684 "open"=>"\\<math\\>",
2685 "close"=>"\\</math\\>",
2686 "sample"=>wfMsg("math_sample"),
2687 "tip"=>wfMsg("math_tip"),
2690 array( "image"=>"button_nowiki.png",
2691 "open"=>"\\<nowiki\\>",
2692 "close"=>"\\</nowiki\\>",
2693 "sample"=>wfMsg("nowiki_sample"),
2694 "tip"=>wfMsg("nowiki_tip"),
2697 array( "image"=>"button_sig.png",
2701 "tip"=>wfMsg("sig_tip"),
2704 array( "image"=>"button_hr.png",
2705 "open"=>"\\n----\\n",
2708 "tip"=>wfMsg("hr_tip"),
2712 $toolbar ="<script type='text/javascript'>\n/*<![CDATA[*/\n";
2714 $toolbar.="document.writeln(\"<div id='toolbar'>\");\n";
2715 foreach($toolarray as $tool) {
2717 $image=$wgStylePath.'/images/'.$tool['image'];
2718 $open=$tool['open'];
2719 $close=$tool['close'];
2720 $sample = addslashes( $tool['sample'] );
2722 // Note that we use the tip both for the ALT tag and the TITLE tag of the image.
2723 // Older browsers show a "speedtip" type message only for ALT.
2724 // Ideally these should be different, realistically they
2725 // probably don't need to be.
2726 $tip = addslashes( $tool['tip'] );
2728 #$key = $tool["key"];
2730 $toolbar.="addButton('$image','$tip','$open','$close','$sample');\n";
2733 $toolbar.="addInfobox('" . addslashes( wfMsg( "infobox" ) ) . "','" . addslashes(wfMsg("infobox_alert")) . "');\n";
2734 $toolbar.="document.writeln(\"</div>\");\n";
2736 $toolbar.="/*]]>*/\n</script>";