3 # This is not a valid entry point, perform no further processing unless MEDIAWIKI is defined
4 if( defined( "MEDIAWIKI" ) ) {
8 require_once( 'Feed.php' ); // should not be called if the actual page isn't feed enabled
9 require_once( 'Image.php' );
11 # These are the INTERNAL names, which get mapped
12 # directly to class names. For display purposes, the
13 # Language class has internationalized names
15 /* private */ $wgValidSkinNames = array(
16 'standard' => 'Standard',
17 'nostalgia' => 'Nostalgia',
18 'cologneblue' => 'CologneBlue'
21 #$wgValidSkinNames[] = 'PHPTal';
22 #$wgValidSkinNames['davinci'] = 'DaVinci';
23 #$wgValidSkinNames['mono'] = 'Mono';
24 $wgValidSkinNames['monobook'] = 'MonoBook';
25 $wgValidSkinNames['myskin'] = 'MySkin';
26 #$wgValidSkinNames['monobookminimal'] = 'MonoBookMinimal';
29 require_once( 'RecentChange.php' );
31 class RCCacheEntry
extends RecentChange
33 var $secureName, $link;
34 var $curlink , $difflink, $lastlink , $usertalklink , $versionlink ;
35 var $userlink, $timestamp, $watched;
37 function newFromParent( $rc )
39 $rc2 = new RCCacheEntry
;
40 $rc2->mAttribs
= $rc->mAttribs
;
41 $rc2->mExtra
= $rc->mExtra
;
48 /* private */ var $lastdate, $lastline;
49 var $linktrail ; # linktrail regexp
50 var $rc_cache ; # Cache for Enhanced Recent Changes
51 var $rcCacheIndex ; # Recent Changes Cache Counter for visibility toggle
53 var $postParseLinkColour = true;
57 $this->linktrail
= wfMsg('linktrail');
60 function getSkinNames()
62 global $wgValidSkinNames;
63 return $wgValidSkinNames;
66 function getStylesheet()
68 return 'wikistandard.css';
70 function getSkinName() {
74 # Get/set accessor for delayed link colouring
75 function postParseLinkColour( $setting = NULL ) {
76 return wfSetVar( $this->postParseLinkColour
, $setting );
81 global $wgOut, $wgUser;
83 if ( $wgOut->isQuickbarSuppressed() ) { return 0; }
84 $q = $wgUser->getOption( 'quickbar' );
85 if ( '' == $q ) { $q = 0; }
89 function initPage( &$out )
91 $fname = 'Skin::initPage';
92 wfProfileIn( $fname );
94 $out->addLink( array( 'rel' => 'shortcut icon', 'href' => '/favicon.ico' ) );
96 $this->addMetadataLinks($out);
98 wfProfileOut( $fname );
101 function addMetadataLinks( &$out ) {
102 global $wgTitle, $wgEnableDublinCoreRdf, $wgEnableCreativeCommonsRdf, $wgRdfMimeType, $action;
103 global $wgRightsPage, $wgRightsUrl;
105 if( $out->isArticleRelated() ) {
106 # note: buggy CC software only reads first "meta" link
107 if( $wgEnableCreativeCommonsRdf ) {
108 $out->addMetadataLink( array(
109 'title' => 'Creative Commons',
110 'type' => 'application/rdf+xml',
111 'href' => $wgTitle->getLocalURL( 'action=creativecommons') ) );
113 if( $wgEnableDublinCoreRdf ) {
114 $out->addMetadataLink( array(
115 'title' => 'Dublin Core',
116 'type' => 'application/rdf+xml',
117 'href' => $wgTitle->getLocalURL( 'action=dublincore' ) ) );
121 if( $wgRightsPage ) {
122 $copy = Title
::newFromText( $wgRightsPage );
124 $copyright = $copy->getLocalURL();
127 if( !$copyright && $wgRightsUrl ) {
128 $copyright = $wgRightsUrl;
131 $out->addLink( array(
132 'rel' => 'copyright',
133 'href' => $copyright ) );
137 function outputPage( &$out ) {
138 global $wgDebugComments;
140 wfProfileIn( 'Skin::outputPage' );
141 $this->initPage( $out );
142 $out->out( $out->headElement() );
144 $out->out( "\n<body" );
145 $ops = $this->getBodyOptions();
146 foreach ( $ops as $name => $val ) {
147 $out->out( " $name='$val'" );
150 if ( $wgDebugComments ) {
151 $out->out( "<!-- Wiki debugging output:\n" .
152 $out->mDebugtext
. "-->\n" );
154 $out->out( $this->beforeContent() );
156 $out->out( $out->mBodytext
. "\n" );
158 $out->out( $this->afterContent() );
161 $out->out( $out->reportTime() );
163 $out->out( "\n</body></html>" );
166 function getHeadScripts() {
167 global $wgStylePath, $wgUser, $wgLang, $wgAllowUserJs;
168 $r = "<script type=\"text/javascript\" src=\"{$wgStylePath}/wikibits.js\"></script>\n";
169 if( $wgAllowUserJs && $wgUser->getID() != 0 ) { # logged in
170 $userpage = $wgLang->getNsText( Namespace::getUser() ) . ":" . $wgUser->getName();
171 $userjs = htmlspecialchars($this->makeUrl($userpage.'/'.$this->getSkinName().'.js', 'action=raw&ctype=text/javascript'));
172 $r .= '<script type="text/javascript" src="'.$userjs."\"></script>\n";
177 # get the user/site-specific stylesheet, SkinPHPTal called from RawPage.php (settings are cached that way)
178 function getUserStylesheet() {
179 global $wgOut, $wgStylePath, $wgLang, $wgUser, $wgRequest, $wgTitle, $wgAllowUserCss;
180 $sheet = $this->getStylesheet();
181 $action = $wgRequest->getText('action');
182 $s = "@import \"$wgStylePath/$sheet\";\n";
183 if($wgLang->isRTL()) $s .= "@import \"$wgStylePath/common_rtl.css\";\n";
184 if( $wgAllowUserCss && $wgUser->getID() != 0 ) { # logged in
185 if($wgTitle->isCssSubpage() and $action == 'submit' and $wgTitle->userCanEditCssJsSubpage()) {
186 $s .= $wgRequest->getText('wpTextbox1');
188 $userpage = $wgLang->getNsText( Namespace::getUser() ) . ":" . $wgUser->getName();
189 $s.= '@import "'.$this->makeUrl($userpage.'/'.$this->getSkinName().'.css', 'action=raw&ctype=text/css').'";'."\n";
192 $s .= $this->doGetUserStyles();
195 # placeholder, returns generated js in monobook
196 function getUserJs() {
200 function getUserStyles()
202 global $wgOut, $wgStylePath, $wgLang;
203 $s = "<style type='text/css'>\n";
204 $s .= "/*/*/ /*<![CDATA[*/\n"; # <-- Hide the styles from Netscape 4 without hiding them from IE/Mac
205 $s .= $this->getUserStylesheet();
206 $s .= "/*]]>*/ /* */\n";
211 function doGetUserStyles()
213 global $wgUser, $wgLang;
215 $csspage = $wgLang->getNsText( NS_MEDIAWIKI
) . ":" . $this->getSkinName() . ".css";
216 $s = '@import "'.$this->makeUrl($csspage, 'action=raw&ctype=text/css')."\";\n";
218 if ( 1 == $wgUser->getOption( 'underline' ) ) {
219 # Don't override browser settings
223 $s .= "a { text-decoration: none; }\n";
225 if ( 1 == $wgUser->getOption( 'highlightbroken' ) ) {
226 $s .= "a.new, #quickbar a.new { color: #CC2200; }\n";
228 if ( 1 == $wgUser->getOption( 'justify' ) ) {
229 $s .= "#article { text-align: justify; }\n";
234 function getBodyOptions()
236 global $wgUser, $wgTitle, $wgNamespaceBackgrounds, $wgOut, $wgRequest;
238 extract( $wgRequest->getValues( 'oldid', 'redirect', 'diff' ) );
240 if ( 0 != $wgTitle->getNamespace() ) {
241 $a = array( 'bgcolor' => '#ffffec' );
243 else $a = array( 'bgcolor' => '#FFFFFF' );
244 if($wgOut->isArticle() && $wgUser->getOption('editondblclick') &&
245 (!$wgTitle->isProtected() ||
$wgUser->isSysop()) ) {
246 $t = wfMsg( 'editthispage' );
248 if ( !empty($redirect) ) {
249 $red = "&redirect={$redirect}";
251 if ( !empty($oldid) && ! isset( $diff ) ) {
252 $oid = "&oldid={$oldid}";
254 $s = $wgTitle->getFullURL( "action=edit{$oid}{$red}" );
255 $s = 'document.location = "' .$s .'";';
256 $a +
= array ('ondblclick' => $s);
259 $a['onload'] = $wgOut->getOnloadHandler();
263 function getExternalLinkAttributes( $link, $text, $class='' )
265 global $wgUser, $wgOut, $wgLang;
267 $link = urldecode( $link );
268 $link = $wgLang->checkTitleEncoding( $link );
269 $link = str_replace( '_', ' ', $link );
270 $link = htmlspecialchars( $link );
272 $r = ($class != '') ?
" class='$class'" : " class='external'";
274 if ( 1 == $wgUser->getOption( 'hover' ) ) {
275 $r .= " title=\"{$link}\"";
280 function getInternalLinkAttributes( $link, $text, $broken = false )
282 global $wgUser, $wgOut;
284 $link = urldecode( $link );
285 $link = str_replace( '_', ' ', $link );
286 $link = htmlspecialchars( $link );
288 if ( $broken == 'stub' ) {
289 $r = ' class="stub"';
290 } else if ( $broken == 'yes' ) {
296 if ( 1 == $wgUser->getOption( 'hover' ) ) {
297 $r .= " title=\"{$link}\"";
302 function getInternalLinkAttributesObj( &$nt, $text, $broken = false )
304 global $wgUser, $wgOut;
306 if ( $broken == 'stub' ) {
307 $r = ' class="stub"';
308 } else if ( $broken == 'yes' ) {
314 if ( 1 == $wgUser->getOption( 'hover' ) ) {
315 $r .= ' title ="' . $nt->getEscapedText() . '"';
326 # This will be called immediately after the <body> tag. Split into
327 # two functions to make it easier to subclass.
329 function beforeContent()
331 global $wgUser, $wgOut;
333 return $this->doBeforeContent();
336 function doBeforeContent()
338 global $wgUser, $wgOut, $wgTitle, $wgLang, $wgSiteNotice;
339 $fname = 'Skin::doBeforeContent';
340 wfProfileIn( $fname );
343 $qb = $this->qbSetting();
345 if( $langlinks = $this->otherLanguages() ) {
351 $borderhack = 'class="top"';
354 $s .= "\n<div id='content'>\n<div id='topbar'>\n" .
355 "<table border='0' cellspacing='0' width='98%'>\n<tr>\n";
358 $left = ($qb == 1 ||
$qb == 3);
359 if($wgLang->isRTL()) $left = !$left;
362 $s .= "<td class='top' align='left' valign='top' rowspan='{$rows}'>\n" .
363 $this->logoText() . '</td>';
365 $s .= $this->getQuickbarCompensator( $rows );
367 $l = $wgLang->isRTL() ?
'right' : 'left';
368 $s .= "<td {$borderhack} align='$l' valign='top'>\n";
370 $s .= $this->topLinks() ;
371 $s .= "<p class='subtitle'>" . $this->pageTitleLinks() . "</p>\n";
373 $r = $wgLang->isRTL() ?
"left" : "right";
374 $s .= "</td>\n<td {$borderhack} valign='top' align='$r' nowrap='nowrap'>";
375 $s .= $this->nameAndLogin();
376 $s .= "\n<br />" . $this->searchForm() . "</td>";
379 $s .= "</tr>\n<tr>\n<td class='top' colspan=\"2\">$langlinks</td>\n";
382 if ( $shove && !$left ) { # Right
383 $s .= $this->getQuickbarCompensator( $rows );
385 $s .= "</tr>\n</table>\n</div>\n";
386 $s .= "\n<div id='article'>\n";
388 if( $wgSiteNotice ) {
389 $s .= "\n<div id='siteNotice'>$wgSiteNotice</div>\n";
391 $s .= $this->pageTitle();
392 $s .= $this->pageSubtitle() ;
393 $s .= $this->getCategories();
394 wfProfileOut( $fname );
398 function getCategoryLinks () {
399 global $wgOut, $wgTitle, $wgUser, $wgParser;
400 global $wgUseCategoryMagic, $wgUseCategoryBrowser, $wgLang;
402 if( !$wgUseCategoryMagic ) return '' ;
403 if( count( $wgOut->mCategoryLinks
) == 0 ) return '';
405 # Taken out so that they will be displayed in previews -- TS
406 #if( !$wgOut->isArticle() ) return '';
408 $t = implode ( ' | ' , $wgOut->mCategoryLinks
) ;
409 $s = $this->makeKnownLink( 'Special:Categories',
410 wfMsg( 'categories' ), 'article=' . urlencode( $wgTitle->getPrefixedDBkey() ) )
413 if($wgUseCategoryBrowser) {
416 $s.= $wgTitle->getAllParentCategories($catstack);
422 function getCategories() {
423 $catlinks=$this->getCategoryLinks();
424 if(!empty($catlinks)) {
425 return "<p class='catlinks'>{$catlinks}</p>";
429 function getQuickbarCompensator( $rows = 1 )
431 return "<td width='152' rowspan='{$rows}'> </td>";
434 # This gets called immediately before the </body> tag.
436 function afterContent()
438 global $wgUser, $wgOut, $wgServer;
439 global $wgTitle, $wgLang;
441 $printfooter = "<div class=\"printfooter\">\n" . $this->printFooter() . "</div>\n";
442 return $printfooter . $this->doAfterContent();
445 function printSource() {
447 $url = htmlspecialchars( $wgTitle->getFullURL() );
448 return wfMsg( "retrievedfrom", "<a href=\"$url\">$url</a>" );
451 function printFooter() {
452 return "<p>" . $this->printSource() .
453 "</p>\n\n<p>" . $this->pageStats() . "</p>\n";
456 function doAfterContent()
458 global $wgUser, $wgOut, $wgLang;
459 $fname = 'Skin::doAfterContent';
460 wfProfileIn( $fname );
461 wfProfileIn( $fname.'-1' );
463 $s = "\n</div><br style=\"clear:both\" />\n";
464 $s .= "\n<div id='footer'>";
465 $s .= '<table border="0" cellspacing="0"><tr>';
467 wfProfileOut( $fname.'-1' );
468 wfProfileIn( $fname.'-2' );
470 $qb = $this->qbSetting();
472 $left = ($qb == 1 ||
$qb == 3);
473 if($wgLang->isRTL()) $left = !$left;
475 if ( $shove && $left ) { # Left
476 $s .= $this->getQuickbarCompensator();
478 wfProfileOut( $fname.'-2' );
479 wfProfileIn( $fname.'-3' );
480 $l = $wgLang->isRTL() ?
'right' : 'left';
481 $s .= "<td class='bottom' align='$l' valign='top'>";
483 $s .= $this->bottomLinks();
484 $s .= "\n<br />" . $this->mainPageLink()
485 . ' | ' . $this->aboutLink()
486 . ' | ' . $this->specialLink( 'recentchanges' )
487 . ' | ' . $this->searchForm()
488 . '<br /><span id="pagestats">' . $this->pageStats() . '</span>';
491 if ( $shove && !$left ) { # Right
492 $s .= $this->getQuickbarCompensator();
494 $s .= "</tr></table>\n</div>\n</div>\n";
496 wfProfileOut( $fname.'-3' );
497 wfProfileIn( $fname.'-4' );
498 if ( 0 != $qb ) { $s .= $this->quickBar(); }
499 wfProfileOut( $fname.'-4' );
500 wfProfileOut( $fname );
504 function pageTitleLinks()
506 global $wgOut, $wgTitle, $wgUser, $wgLang, $wgUseApproval, $wgRequest;
508 extract( $wgRequest->getValues( 'oldid', 'diff' ) );
509 $action = $wgRequest->getText( 'action' );
511 $s = $this->printableLink();
512 if ( wfMsg ( 'disclaimers' ) != '-' ) $s .= ' | ' . $this->makeKnownLink( wfMsg( 'disclaimerpage' ), wfMsg( 'disclaimers' ) ) ;
514 if ( $wgOut->isArticleRelated() ) {
515 if ( $wgTitle->getNamespace() == Namespace::getImage() ) {
516 $name = $wgTitle->getDBkey();
517 $link = htmlspecialchars( Image
::wfImageUrl( $name ) );
518 $style = $this->getInternalLinkAttributes( $link, $name );
519 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>";
521 # This will show the "Approve" link if $wgUseApproval=true;
522 if ( isset ( $wgUseApproval ) && $wgUseApproval )
524 $t = $wgTitle->getDBkey();
525 $name = 'Approve this article' ;
526 $link = "http://test.wikipedia.org/w/magnus/wiki.phtml?title={$t}&action=submit&doit=1" ;
527 #htmlspecialchars( wfImageUrl( $name ) );
528 $style = $this->getExternalLinkAttributes( $link, $name );
529 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>" ;
532 if ( 'history' == $action ||
isset( $diff ) ||
isset( $oldid ) ) {
533 $s .= ' | ' . $this->makeKnownLink( $wgTitle->getPrefixedText(),
534 wfMsg( 'currentrev' ) );
537 if ( $wgUser->getNewtalk() ) {
538 # do not show "You have new messages" text when we are viewing our
541 if(!(strcmp($wgTitle->getText(),$wgUser->getName()) == 0 &&
542 $wgTitle->getNamespace()==Namespace::getTalk(Namespace::getUser()))) {
543 $n =$wgUser->getName();
544 $tl = $this->makeKnownLink( $wgLang->getNsText(
545 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
546 wfMsg('newmessageslink') );
547 $s.= ' | <strong>'. wfMsg( 'newmessages', $tl ) . '</strong>';
551 $undelete = $this->getUndeleteLink();
552 if( !empty( $undelete ) ) {
553 $s .= ' | '.$undelete;
558 function getUndeleteLink() {
559 global $wgUser, $wgTitle, $wgLang, $action;
560 if( $wgUser->isSysop() &&
561 (($wgTitle->getArticleId() == 0) ||
($action == "history")) &&
562 ($n = $wgTitle->isDeleted() ) ) {
563 return wfMsg( 'thisisdeleted',
564 $this->makeKnownLink(
565 $wgLang->SpecialPage( 'Undelete/' . $wgTitle->getPrefixedDBkey() ),
566 wfMsg( 'restorelink', $n ) ) );
571 function printableLink()
573 global $wgOut, $wgFeedClasses, $wgRequest;
575 $baseurl = $_SERVER['REQUEST_URI'];
576 if( strpos( '?', $baseurl ) == false ) {
581 $baseurl = htmlspecialchars( $baseurl );
582 $printurl = $wgRequest->escapeAppendQuery( 'printable=yes' );
584 $s = "<a href=\"$printurl\">" . wfMsg( 'printableversion' ) . '</a>';
585 if( $wgOut->isSyndicated() ) {
586 foreach( $wgFeedClasses as $format => $class ) {
587 $feedurl = $wgRequest->escapeAppendQuery( "feed=$format" );
588 $s .= " | <a href=\"$feedurl\">{$format}</a>";
596 global $wgOut, $wgTitle, $wgUser;
598 $s = '<h1 class="pagetitle">' . htmlspecialchars( $wgOut->getPageTitle() ) . '</h1>';
599 if($wgUser->getOption( 'editsectiononrightclick' ) && $wgTitle->userCanEdit()) { $s=$this->editSectionScript(0,$s);}
603 function pageSubtitle()
607 $sub = $wgOut->getSubtitle();
609 global $wgExtraSubtitle;
610 $sub = wfMsg( 'fromwikipedia' ) . $wgExtraSubtitle;
612 $subpages = $this->subPageSubtitle();
613 $sub .= !empty($subpages)?
"</p><p class='subpages'>$subpages":'';
614 $s = "<p class='subtitle'>{$sub}</p>\n";
618 function subPageSubtitle()
620 global $wgOut,$wgTitle,$wgNamespacesWithSubpages;
622 if($wgOut->isArticle() && !empty($wgNamespacesWithSubpages[$wgTitle->getNamespace()])) {
623 $ptext=$wgTitle->getPrefixedText();
624 if(preg_match('/\//',$ptext)) {
625 $links = explode('/',$ptext);
628 foreach($links as $link) {
630 if ($c<count($links)) {
631 $growinglink .= $link;
632 $getlink = $this->makeLink( $growinglink, $link );
633 if(preg_match('/class="new"/i',$getlink)) { break; } # this is a hack, but it saves time
637 $subpages .= '< ';
639 $subpages .= $getlink;
648 function nameAndLogin()
650 global $wgUser, $wgTitle, $wgLang, $wgShowIPinHeader, $wgIP;
652 $li = $wgLang->specialPage( 'Userlogin' );
653 $lo = $wgLang->specialPage( 'Userlogout' );
656 if ( 0 == $wgUser->getID() ) {
657 if( $wgShowIPinHeader && isset( $_COOKIE[ini_get('session.name')] ) ) {
660 $tl = $this->makeKnownLink( $wgLang->getNsText(
661 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
662 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
664 $s .= $n . ' ('.$tl.')';
666 $s .= wfMsg('notloggedin');
669 $rt = $wgTitle->getPrefixedURL();
670 if ( 0 == strcasecmp( urlencode( $lo ), $rt ) ) {
672 } else { $q = "returnto={$rt}"; }
674 $s .= "\n<br />" . $this->makeKnownLink( $li,
675 wfMsg( 'login' ), $q );
677 $n = $wgUser->getName();
678 $rt = $wgTitle->getPrefixedURL();
679 $tl = $this->makeKnownLink( $wgLang->getNsText(
680 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
681 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
685 $s .= $this->makeKnownLink( $wgLang->getNsText(
686 Namespace::getUser() ) . ":{$n}", $n ) . "{$tl}<br />" .
687 $this->makeKnownLink( $lo, wfMsg( 'logout' ),
688 "returnto={$rt}" ) . ' | ' .
689 $this->specialLink( 'preferences' );
691 $s .= ' | ' . $this->makeKnownLink( wfMsg( 'helppage' ),
697 function getSearchLink() {
698 $searchPage =& Title
::makeTitle( NS_SPECIAL
, 'Search' );
699 return $searchPage->getLocalURL();
702 function escapeSearchLink() {
703 return htmlspecialchars( $this->getSearchLink() );
706 function searchForm()
709 $search = $wgRequest->getText( 'search' );
711 $s = '<form name="search" class="inline" method="post" action="'
712 . $this->escapeSearchLink() . "\">\n"
713 . '<input type="text" name="search" size="19" value="'
714 . htmlspecialchars(substr($search,0,256)) . "\" />\n"
715 . '<input type="submit" name="go" value="' . wfMsg ('go') . '" /> '
716 . '<input type="submit" name="fulltext" value="' . wfMsg ('search') . "\" />\n</form>";
726 $s = $this->mainPageLink() . $sep
727 . $this->specialLink( 'recentchanges' );
729 if ( $wgOut->isArticleRelated() ) {
730 $s .= $sep . $this->editThisPage()
731 . $sep . $this->historyLink();
733 # Many people don't like this dropdown box
734 #$s .= $sep . $this->specialPagesList();
739 function bottomLinks()
741 global $wgOut, $wgUser, $wgTitle;
745 if ( $wgOut->isArticleRelated() ) {
746 $s .= '<strong>' . $this->editThisPage() . '</strong>';
747 if ( 0 != $wgUser->getID() ) {
748 $s .= $sep . $this->watchThisPage();
750 $s .= $sep . $this->talkLink()
751 . $sep . $this->historyLink()
752 . $sep . $this->whatLinksHere()
753 . $sep . $this->watchPageLinksLink();
755 if ( $wgTitle->getNamespace() == Namespace::getUser()
756 ||
$wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser()) )
759 $id=User
::idFromName($wgTitle->getText());
760 $ip=User
::isIP($wgTitle->getText());
762 if($id ||
$ip) { # both anons and non-anons have contri list
763 $s .= $sep . $this->userContribsLink();
765 if ( 0 != $wgUser->getID() ) { # show only to signed in users
766 if($id) { # can only email non-anons
767 $s .= $sep . $this->emailUserLink();
771 if ( $wgUser->isSysop() && $wgTitle->getArticleId() ) {
772 $s .= "\n<br />" . $this->deleteThisPage() .
773 $sep . $this->protectThisPage() .
774 $sep . $this->moveThisPage();
776 $s .= "<br />\n" . $this->otherLanguages();
783 global $wgOut, $wgLang, $wgArticle, $wgRequest;
784 global $wgDisableCounters, $wgMaxCredits, $wgShowCreditsIfMax;
786 extract( $wgRequest->getValues( 'oldid', 'diff' ) );
787 if ( ! $wgOut->isArticle() ) { return ''; }
788 if ( isset( $oldid ) ||
isset( $diff ) ) { return ''; }
789 if ( 0 == $wgArticle->getID() ) { return ''; }
792 if ( !$wgDisableCounters ) {
793 $count = $wgLang->formatNum( $wgArticle->getCount() );
795 $s = wfMsg( 'viewcount', $count );
799 if (isset($wgMaxCredits) && $wgMaxCredits != 0) {
800 require_once("Credits.php");
801 $s .= ' ' . getCredits($wgArticle, $wgMaxCredits, $wgShowCreditsIfMax);
803 $s .= $this->lastModified();
806 return $s . ' ' . $this->getCopyright();
809 function getCopyright() {
810 global $wgRightsPage, $wgRightsUrl, $wgRightsText, $wgRequest;
813 $oldid = $wgRequest->getVal( 'oldid' );
814 $diff = $wgRequest->getVal( 'diff' );
816 if ( !is_null( $oldid ) && is_null( $diff ) && wfMsg( 'history_copyright' ) !== '-' ) {
817 $msg = 'history_copyright';
823 if( $wgRightsPage ) {
824 $link = $this->makeKnownLink( $wgRightsPage, $wgRightsText );
825 } elseif( $wgRightsUrl ) {
826 $link = $this->makeExternalLink( $wgRightsUrl, $wgRightsText );
831 $out .= wfMsg( $msg, $link );
835 function getCopyrightIcon() {
836 global $wgRightsPage, $wgRightsUrl, $wgRightsText, $wgRightsIcon;
838 if( $wgRightsIcon ) {
839 $icon = htmlspecialchars( $wgRightsIcon );
841 $url = htmlspecialchars( $wgRightsUrl );
842 $out .= '<a href="'.$url.'">';
844 $text = htmlspecialchars( $wgRightsText );
845 $out .= "<img src=\"$icon\" alt='$text' />";
853 function getPoweredBy() {
855 $url = htmlspecialchars( "$wgStylePath/images/poweredby_mediawiki_88x31.png" );
856 $img = '<a href="http://www.mediawiki.org/"><img src="'.$url.'" alt="MediaWiki" /></a>';
860 function lastModified()
862 global $wgLang, $wgArticle;
864 $timestamp = $wgArticle->getTimestamp();
866 $d = $wgLang->timeanddate( $wgArticle->getTimestamp(), true );
867 $s = ' ' . wfMsg( 'lastmodified', $d );
874 function logoText( $align = '' )
876 if ( '' != $align ) { $a = ' align="'.$align.'"'; }
879 $mp = wfMsg( 'mainpage' );
880 $titleObj = Title
::newFromText( $mp );
881 $s = '<a href="' . $titleObj->escapeLocalURL()
882 . '"><img'.$a.' src="'
883 . $this->getLogo() . '" alt="' . "[{$mp}]\" /></a>";
889 global $wgOut, $wgTitle, $wgUser, $wgRequest, $wgLang;
890 global $wgDisableUploads, $wgRemoteUploads;
892 $fname = 'Skin::quickBar';
893 wfProfileIn( $fname );
895 $action = $wgRequest->getText( 'action' );
896 $wpPreview = $wgRequest->getBool( 'wpPreview' );
897 $tns=$wgTitle->getNamespace();
899 $s = "\n<div id='quickbar'>";
900 $s .= "\n" . $this->logoText() . "\n<hr class='sep' />";
903 $s .= $this->mainPageLink()
904 . $sep . $this->specialLink( 'recentchanges' )
905 . $sep . $this->specialLink( 'randompage' );
906 if ($wgUser->getID()) {
907 $s.= $sep . $this->specialLink( 'watchlist' ) ;
908 $s .= $sep .$this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
909 wfMsg( 'mycontris' ), 'target=' . wfUrlencode($wgUser->getName() ) );
912 // only show watchlist link if logged in
913 if ( wfMsg ( 'currentevents' ) != '-' ) $s .= $sep . $this->makeKnownLink( wfMsg( 'currentevents' ), '' ) ;
914 $s .= "\n<br /><hr class='sep' />";
915 $articleExists = $wgTitle->getArticleId();
916 if ( $wgOut->isArticle() ||
$action =='edit' ||
$action =='history' ||
$wpPreview) {
917 if($wgOut->isArticle()) {
918 $s .= '<strong>' . $this->editThisPage() . '</strong>';
919 } else { # backlink to the article in edit or history mode
920 if($articleExists){ # no backlink if no article
923 $text = wfMsg('articlepage');
926 $text = wfMsg('viewtalkpage');
929 $text = wfMsg('userpage');
932 $text = wfMsg('viewtalkpage');
935 $text = wfMsg('wikipediapage');
938 $text = wfMsg('viewtalkpage');
941 $text = wfMsg('imagepage');
944 $text = wfMsg('viewtalkpage');
947 $text= wfMsg('articlepage');
950 $link = $wgTitle->getText();
951 if ($nstext = $wgLang->getNsText($tns) ) { # add namespace if necessary
952 $link = $nstext . ':' . $link ;
955 $s .= $this->makeLink( $link, $text );
956 } elseif( $wgTitle->getNamespace() != Namespace::getSpecial() ) {
957 # we just throw in a "New page" text to tell the user that he's in edit mode,
958 # and to avoid messing with the separator that is prepended to the next item
959 $s .= '<strong>' . wfMsg('newpage') . '</strong>';
965 if( $tns%2
&& $action!='edit' && !$wpPreview) {
966 $s.= '<br />'.$this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg('postcomment'),'action=edit§ion=new');
970 watching could cause problems in edit mode:
971 if user edits article, then loads "watch this article" in background and then saves
972 article with "Watch this article" checkbox disabled, the article is transparently
973 unwatched. Therefore we do not show the "Watch this page" link in edit mode
975 if ( 0 != $wgUser->getID() && $articleExists) {
976 if($action!='edit' && $action != 'submit' )
978 $s .= $sep . $this->watchThisPage();
980 if ( $wgTitle->userCanEdit() )
981 $s .= $sep . $this->moveThisPage();
983 if ( $wgUser->isSysop() and $articleExists ) {
984 $s .= $sep . $this->deleteThisPage() .
985 $sep . $this->protectThisPage();
987 $s .= $sep . $this->talkLink();
988 if ($articleExists && $action !='history') {
989 $s .= $sep . $this->historyLink();
991 $s.=$sep . $this->whatLinksHere();
993 if($wgOut->isArticleRelated()) {
994 $s .= $sep . $this->watchPageLinksLink();
997 if ( Namespace::getUser() == $wgTitle->getNamespace()
998 ||
$wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser())
1001 $id=User
::idFromName($wgTitle->getText());
1002 $ip=User
::isIP($wgTitle->getText());
1005 $s .= $sep . $this->userContribsLink();
1007 if ( 0 != $wgUser->getID() ) {
1008 if($id) { # can only email real users
1009 $s .= $sep . $this->emailUserLink();
1013 $s .= "\n<br /><hr class='sep' />";
1016 if ( 0 != $wgUser->getID() && ( !$wgDisableUploads ||
$wgRemoteUploads ) ) {
1017 $s .= $this->specialLink( 'upload' ) . $sep;
1019 $s .= $this->specialLink( 'specialpages' )
1020 . $sep . $this->bugReportsLink();
1022 global $wgSiteSupportPage;
1023 if( $wgSiteSupportPage ) {
1024 $s .= "\n<br /><a href=\"" . htmlspecialchars( $wgSiteSupportPage ) .
1025 '" class="internal">' . wfMsg( 'sitesupport' ) . '</a>';
1028 $s .= "\n<br /></div>\n";
1029 wfProfileOut( $fname );
1033 function specialPagesList()
1035 global $wgUser, $wgOut, $wgLang, $wgServer, $wgRedirectScript;
1036 require_once('SpecialPage.php');
1038 $pages = SpecialPage
::getPages();
1040 foreach ( $pages[''] as $name => $page ) {
1041 $a[$name] = $page->getDescription();
1043 if ( $wgUser->isSysop() )
1045 foreach ( $pages['sysop'] as $name => $page ) {
1046 $a[$name] = $page->getDescription();
1049 if ( $wgUser->isDeveloper() )
1051 foreach ( $pages['developer'] as $name => $page ) {
1052 $a[$name] = $page->getDescription() ;
1055 $go = wfMsg( 'go' );
1056 $sp = wfMsg( 'specialpages' );
1057 $spp = $wgLang->specialPage( 'Specialpages' );
1059 $s = '<form id="specialpages" method="get" class="inline" ' .
1060 'action="' . htmlspecialchars( "{$wgServer}{$wgRedirectScript}" ) . "\">\n";
1061 $s .= "<select name=\"wpDropdown\">\n";
1062 $s .= "<option value=\"{$spp}\">{$sp}</option>\n";
1064 foreach ( $a as $name => $desc ) {
1065 $p = $wgLang->specialPage( $name );
1066 $s .= "<option value=\"{$p}\">{$desc}</option>\n";
1068 $s .= "</select>\n";
1069 $s .= "<input type='submit' value=\"{$go}\" name='redirect' />\n";
1074 function mainPageLink()
1076 $mp = wfMsg( 'mainpage' );
1077 $s = $this->makeKnownLink( $mp, $mp );
1081 function copyrightLink()
1083 $s = $this->makeKnownLink( wfMsg( 'copyrightpage' ),
1084 wfMsg( 'copyrightpagename' ) );
1088 function aboutLink()
1090 $s = $this->makeKnownLink( wfMsg( 'aboutpage' ),
1091 wfMsg( 'aboutwikipedia' ) );
1096 function disclaimerLink()
1098 $s = $this->makeKnownLink( wfMsg( 'disclaimerpage' ),
1099 wfMsg( 'disclaimers' ) );
1103 function editThisPage()
1105 global $wgOut, $wgTitle, $wgRequest;
1107 $oldid = $wgRequest->getVal( 'oldid' );
1108 $diff = $wgRequest->getVal( 'diff' );
1109 $redirect = $wgRequest->getVal( 'redirect' );
1111 if ( ! $wgOut->isArticleRelated() ) {
1112 $s = wfMsg( 'protectedpage' );
1114 $n = $wgTitle->getPrefixedText();
1115 if ( $wgTitle->userCanEdit() ) {
1116 $t = wfMsg( 'editthispage' );
1118 #$t = wfMsg( "protectedpage" );
1119 $t = wfMsg( 'viewsource' );
1123 if ( !is_null( $redirect ) ) { $red = "&redirect={$redirect}"; }
1124 if ( $oldid && ! isset( $diff ) ) {
1125 $oid = "&oldid={$oldid}";
1127 $s = $this->makeKnownLink( $n, $t, "action=edit{$oid}{$red}" );
1132 function deleteThisPage()
1134 global $wgUser, $wgOut, $wgTitle, $wgRequest;
1136 $diff = $wgRequest->getVal( 'diff' );
1137 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
1138 $n = $wgTitle->getPrefixedText();
1139 $t = wfMsg( 'deletethispage' );
1141 $s = $this->makeKnownLink( $n, $t, 'action=delete' );
1148 function protectThisPage()
1150 global $wgUser, $wgOut, $wgTitle, $wgRequest;
1152 $diff = $wgRequest->getVal( 'diff' );
1153 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
1154 $n = $wgTitle->getPrefixedText();
1156 if ( $wgTitle->isProtected() ) {
1157 $t = wfMsg( 'unprotectthispage' );
1158 $q = 'action=unprotect';
1160 $t = wfMsg( 'protectthispage' );
1161 $q = 'action=protect';
1163 $s = $this->makeKnownLink( $n, $t, $q );
1170 function watchThisPage()
1172 global $wgUser, $wgOut, $wgTitle;
1174 if ( $wgOut->isArticleRelated() ) {
1175 $n = $wgTitle->getPrefixedText();
1177 if ( $wgTitle->userIsWatching() ) {
1178 $t = wfMsg( 'unwatchthispage' );
1179 $q = 'action=unwatch';
1181 $t = wfMsg( 'watchthispage' );
1182 $q = 'action=watch';
1184 $s = $this->makeKnownLink( $n, $t, $q );
1186 $s = wfMsg( 'notanarticle' );
1191 function moveThisPage()
1193 global $wgTitle, $wgLang;
1195 if ( $wgTitle->userCanEdit() ) {
1196 $s = $this->makeKnownLink( $wgLang->specialPage( 'Movepage' ),
1197 wfMsg( 'movethispage' ), 'target=' . $wgTitle->getPrefixedURL() );
1198 } // no message if page is protected - would be redundant
1202 function historyLink()
1206 $s = $this->makeKnownLink( $wgTitle->getPrefixedText(),
1207 wfMsg( 'history' ), 'action=history' );
1211 function whatLinksHere()
1213 global $wgTitle, $wgLang;
1215 $s = $this->makeKnownLink( $wgLang->specialPage( 'Whatlinkshere' ),
1216 wfMsg( 'whatlinkshere' ), 'target=' . $wgTitle->getPrefixedURL() );
1220 function userContribsLink()
1222 global $wgTitle, $wgLang;
1224 $s = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
1225 wfMsg( 'contributions' ), 'target=' . $wgTitle->getPartialURL() );
1229 function emailUserLink()
1231 global $wgTitle, $wgLang;
1233 $s = $this->makeKnownLink( $wgLang->specialPage( 'Emailuser' ),
1234 wfMsg( 'emailuser' ), 'target=' . $wgTitle->getPartialURL() );
1238 function watchPageLinksLink()
1240 global $wgOut, $wgTitle, $wgLang;
1242 if ( ! $wgOut->isArticleRelated() ) {
1243 $s = '(' . wfMsg( 'notanarticle' ) . ')';
1245 $s = $this->makeKnownLink( $wgLang->specialPage(
1246 'Recentchangeslinked' ), wfMsg( 'recentchangeslinked' ),
1247 'target=' . $wgTitle->getPrefixedURL() );
1252 function otherLanguages()
1254 global $wgOut, $wgLang, $wgTitle, $wgUseNewInterlanguage;
1256 $a = $wgOut->getLanguageLinks();
1257 if ( 0 == count( $a ) ) {
1258 if ( !$wgUseNewInterlanguage ) return '';
1259 $ns = $wgLang->getNsIndex ( $wgTitle->getNamespace () ) ;
1260 if ( $ns != 0 AND $ns != 1 ) return '' ;
1262 $x = 'mode=addlink&xt='.$wgTitle->getDBkey() ;
1263 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1264 wfMsg( 'intl' ) , $x );
1267 if ( !$wgUseNewInterlanguage ) {
1268 $s = wfMsg( 'otherlanguages' ) . ': ';
1270 global $wgLanguageCode ;
1271 $x = 'mode=zoom&xt='.$wgTitle->getDBkey() ;
1272 $x .= '&xl='.$wgLanguageCode ;
1273 $s = $this->makeKnownLink( $wgLang->specialPage( 'Intl' ),
1274 wfMsg( 'otherlanguages' ) , $x ) . ': ' ;
1277 $s = wfMsg( 'otherlanguages' ) . ': ';
1279 if($wgLang->isRTL()) $s .= '<span dir="LTR">';
1280 foreach( $a as $l ) {
1281 if ( ! $first ) { $s .= ' | '; }
1284 $nt = Title
::newFromText( $l );
1285 $url = $nt->getFullURL();
1286 $text = $wgLang->getLanguageName( $nt->getInterwiki() );
1288 if ( '' == $text ) { $text = $l; }
1289 $style = $this->getExternalLinkAttributes( $l, $text );
1290 $s .= "<a href=\"{$url}\"{$style}>{$text}</a>";
1292 if($wgLang->isRTL()) $s .= '</span>';
1296 function bugReportsLink()
1298 $s = $this->makeKnownLink( wfMsg( 'bugreportspage' ),
1299 wfMsg( 'bugreports' ) );
1305 global $wgLinkCache;
1306 $t1 = Title
::newFromText( gmdate( 'F j' ) );
1307 $t2 = Title
::newFromText( gmdate( 'Y' ) );
1309 $wgLinkCache->suspend();
1310 $id = $t1->getArticleID();
1311 $wgLinkCache->resume();
1314 $s = $this->makeBrokenLink( $t1->getText() );
1316 $s = $this->makeKnownLink( $t1->getText() );
1320 $wgLinkCache->suspend();
1321 $id = $t2->getArticleID();
1322 $wgLinkCache->resume();
1325 $s .= $this->makeBrokenLink( $t2->getText() );
1327 $s .= $this->makeKnownLink( $t2->getText() );
1334 global $wgLang, $wgTitle, $wgLinkCache;
1336 $tns = $wgTitle->getNamespace();
1337 if ( -1 == $tns ) { return ''; }
1339 $pn = $wgTitle->getText();
1340 $tp = wfMsg( 'talkpage' );
1341 if ( Namespace::isTalk( $tns ) ) {
1342 $lns = Namespace::getSubject( $tns );
1345 $text = wfMsg('articlepage');
1348 $text = wfMsg('userpage');
1351 $text = wfMsg('wikipediapage');
1354 $text = wfMsg('imagepage');
1357 $text= wfMsg('articlepage');
1361 $lns = Namespace::getTalk( $tns );
1364 $n = $wgLang->getNsText( $lns );
1365 if ( '' == $n ) { $link = $pn; }
1366 else { $link = $n.':'.$pn; }
1368 $wgLinkCache->suspend();
1369 $s = $this->makeLink( $link, $text );
1370 $wgLinkCache->resume();
1375 function commentLink()
1377 global $wgLang, $wgTitle, $wgLinkCache;
1379 $tns = $wgTitle->getNamespace();
1380 if ( -1 == $tns ) { return ''; }
1382 $lns = ( Namespace::isTalk( $tns ) ) ?
$tns : Namespace::getTalk( $tns );
1384 # assert Namespace::isTalk( $lns )
1386 $n = $wgLang->getNsText( $lns );
1387 $pn = $wgTitle->getText();
1391 $wgLinkCache->suspend();
1392 $s = $this->makeKnownLink($link, wfMsg('postcomment'), 'action=edit§ion=new');
1393 $wgLinkCache->resume();
1398 # After all the page content is transformed into HTML, it makes
1399 # a final pass through here for things like table backgrounds.
1401 function transformContent( $text )
1406 # Note: This function MUST call getArticleID() on the link,
1407 # otherwise the cache won't get updated properly. See LINKCACHE.DOC.
1409 function makeLink( $title, $text = '', $query = '', $trail = '' ) {
1410 wfProfileIn( 'Skin::makeLink' );
1411 $nt = Title
::newFromText( $title );
1413 $result = $this->makeLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1415 wfDebug( 'Invalid title passed to Skin::makeLink(): "'.$title."\"\n" );
1416 $result = $text == "" ?
$title : $text;
1419 wfProfileOut( 'Skin::makeLink' );
1423 function makeKnownLink( $title, $text = '', $query = '', $trail = '', $prefix = '',$aprops = '') {
1424 $nt = Title
::newFromText( $title );
1426 return $this->makeKnownLinkObj( Title
::newFromText( $title ), $text, $query, $trail, $prefix , $aprops );
1428 wfDebug( 'Invalid title passed to Skin::makeKnownLink(): "'.$title."\"\n" );
1429 return $text == '' ?
$title : $text;
1433 function makeBrokenLink( $title, $text = '', $query = '', $trail = '' ) {
1434 $nt = Title
::newFromText( $title );
1436 return $this->makeBrokenLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1438 wfDebug( 'Invalid title passed to Skin::makeBrokenLink(): "'.$title."\"\n" );
1439 return $text == '' ?
$title : $text;
1443 function makeStubLink( $title, $text = '', $query = '', $trail = '' ) {
1444 $nt = Title
::newFromText( $title );
1446 return $this->makeStubLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1448 wfDebug( 'Invalid title passed to Skin::makeStubLink(): "'.$title."\"\n" );
1449 return $text == '' ?
$title : $text;
1453 # Pass a title object, not a title string
1454 function makeLinkObj( &$nt, $text= '', $query = '', $trail = '', $prefix = '' )
1456 global $wgOut, $wgUser;
1457 $fname = 'Skin::makeLinkObj';
1461 return "<!-- ERROR -->{$prefix}{$text}{$trail}";
1463 if ( $nt->isExternal() ) {
1464 $u = $nt->getFullURL();
1465 $link = $nt->getPrefixedURL();
1466 if ( '' == $text ) { $text = $nt->getPrefixedText(); }
1467 $style = $this->getExternalLinkAttributes( $link, $text, 'extiw' );
1470 if ( '' != $trail ) {
1471 if ( preg_match( '/^([a-z]+)(.*)$$/sD', $trail, $m ) ) {
1476 $retVal = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1477 } elseif ( 0 == $nt->getNamespace() && "" == $nt->getText() ) {
1478 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1479 } elseif ( ( -1 == $nt->getNamespace() ) ||
1480 ( Namespace::getImage() == $nt->getNamespace() ) ) {
1481 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1483 if ( $this->postParseLinkColour() ) {
1485 if ( '' != $trail ) {
1486 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1492 # Allows wiki to bypass using linkcache, see OutputPage::parseLinkHolders()
1493 $retVal = '<!--LINK ' . implode( ' ', array( $nt->getNamespace(), $nt->getDBkey(),
1494 $query, $prefix . $text . $inside ) ) . "-->{$trail}";
1496 # Work out link colour immediately
1497 $aid = $nt->getArticleID() ;
1499 $retVal = $this->makeBrokenLinkObj( $nt, $text, $query, $trail, $prefix );
1501 $threshold = $wgUser->getOption('stubthreshold') ;
1502 if ( $threshold > 0 ) {
1503 $dbr =& wfGetDB( DB_SLAVE
);
1504 $s = $dbr->selectRow( 'cur', array( 'LENGTH(cur_text) AS x', 'cur_namespace',
1505 'cur_is_redirect' ), array( 'cur_id' => $aid ), $fname ) ;
1506 if ( $s !== false ) {
1508 if ( $s->cur_is_redirect
OR $s->cur_namespace
!= 0 ) {
1509 $size = $threshold*2 ; # Really big
1511 $dbr->freeResult( $res );
1513 $size = $threshold*2 ; # Really big
1518 if ( $size < $threshold ) {
1519 $retVal = $this->makeStubLinkObj( $nt, $text, $query, $trail, $prefix );
1521 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1529 # Pass a title object, not a title string
1530 function makeKnownLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' , $aprops = '')
1532 global $wgOut, $wgTitle, $wgInputEncoding;
1534 $fname = 'Skin::makeKnownLinkObj';
1535 wfProfileIn( $fname );
1537 if ( !is_object( $nt ) ) {
1540 $link = $nt->getPrefixedURL();
1542 if ( '' == $link ) {
1544 if ( '' == $text ) {
1545 $text = htmlspecialchars( $nt->getFragment() );
1548 $u = $nt->escapeLocalURL( $query );
1550 if ( '' != $nt->getFragment() ) {
1551 $anchor = urlencode( do_html_entity_decode( str_replace(' ', '_', $nt->getFragment()), ENT_COMPAT
, $wgInputEncoding ) );
1552 $replacearray = array(
1556 $u .= '#' . str_replace(array_keys($replacearray),array_values($replacearray),$anchor);
1558 if ( '' == $text ) {
1559 $text = htmlspecialchars( $nt->getPrefixedText() );
1561 $style = $this->getInternalLinkAttributesObj( $nt, $text );
1564 if ( '' != $trail ) {
1565 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1570 $r = "<a href=\"{$u}\"{$style}{$aprops}>{$prefix}{$text}{$inside}</a>{$trail}";
1571 wfProfileOut( $fname );
1575 # Pass a title object, not a title string
1576 function makeBrokenLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
1578 global $wgOut, $wgUser;
1580 $fname = 'Skin::makeBrokenLinkObj';
1581 wfProfileIn( $fname );
1583 if ( '' == $query ) {
1586 $q = 'action=edit&'.$query;
1588 $u = $nt->escapeLocalURL( $q );
1590 if ( '' == $text ) {
1591 $text = htmlspecialchars( $nt->getPrefixedText() );
1593 $style = $this->getInternalLinkAttributesObj( $nt, $text, "yes" );
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}";
1608 wfProfileOut( $fname );
1612 # Pass a title object, not a title string
1613 function makeStubLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
1615 global $wgOut, $wgUser;
1617 $link = $nt->getPrefixedURL();
1619 $u = $nt->escapeLocalURL( $query );
1621 if ( '' == $text ) {
1622 $text = htmlspecialchars( $nt->getPrefixedText() );
1624 $style = $this->getInternalLinkAttributesObj( $nt, $text, 'stub' );
1627 if ( '' != $trail ) {
1628 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1633 if ( $wgUser->getOption( 'highlightbroken' ) ) {
1634 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1636 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>!</a>{$trail}";
1641 function makeSelfLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
1643 $u = $nt->escapeLocalURL( $query );
1644 if ( '' == $text ) {
1645 $text = htmlspecialchars( $nt->getPrefixedText() );
1648 if ( '' != $trail ) {
1649 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1654 return "<strong>{$prefix}{$text}{$inside}</strong>{$trail}";
1657 /* these are used extensively in SkinPHPTal, but also some other places */
1658 /*static*/ function makeSpecialUrl( $name, $urlaction='' ) {
1659 $title = Title
::makeTitle( NS_SPECIAL
, $name );
1660 $this->checkTitle($title, $name);
1661 return $title->getLocalURL( $urlaction );
1663 /*static*/ function makeTalkUrl ( $name, $urlaction='' ) {
1664 $title = Title
::newFromText( $name );
1665 $title = $title->getTalkPage();
1666 $this->checkTitle($title, $name);
1667 return $title->getLocalURL( $urlaction );
1669 /*static*/ function makeArticleUrl ( $name, $urlaction='' ) {
1670 $title = Title
::newFromText( $name );
1671 $title= $title->getSubjectPage();
1672 $this->checkTitle($title, $name);
1673 return $title->getLocalURL( $urlaction );
1675 /*static*/ function makeI18nUrl ( $name, $urlaction='' ) {
1676 $title = Title
::newFromText( wfMsg($name) );
1677 $this->checkTitle($title, $name);
1678 return $title->getLocalURL( $urlaction );
1680 /*static*/ function makeUrl ( $name, $urlaction='' ) {
1681 $title = Title
::newFromText( $name );
1682 $this->checkTitle($title, $name);
1683 return $title->getLocalURL( $urlaction );
1685 # this can be passed the NS number as defined in Language.php
1686 /*static*/ function makeNSUrl( $name, $urlaction='', $namespace=0 ) {
1687 $title = Title
::makeTitle( $namespace, $name );
1688 $this->checkTitle($title, $name);
1689 return $title->getLocalURL( $urlaction );
1692 /* these return an array with the 'href' and boolean 'exists' */
1693 /*static*/ function makeUrlDetails ( $name, $urlaction='' ) {
1694 $title = Title
::newFromText( $name );
1695 $this->checkTitle($title, $name);
1697 'href' => $title->getLocalURL( $urlaction ),
1698 'exists' => $title->getArticleID() != 0?
true:false
1701 /*static*/ function makeTalkUrlDetails ( $name, $urlaction='' ) {
1702 $title = Title
::newFromText( $name );
1703 $title = $title->getTalkPage();
1704 $this->checkTitle($title, $name);
1706 'href' => $title->getLocalURL( $urlaction ),
1707 'exists' => $title->getArticleID() != 0?
true:false
1710 /*static*/ function makeArticleUrlDetails ( $name, $urlaction='' ) {
1711 $title = Title
::newFromText( $name );
1712 $title= $title->getSubjectPage();
1713 $this->checkTitle($title, $name);
1715 'href' => $title->getLocalURL( $urlaction ),
1716 'exists' => $title->getArticleID() != 0?
true:false
1719 /*static*/ function makeI18nUrlDetails ( $name, $urlaction='' ) {
1720 $title = Title
::newFromText( wfMsg($name) );
1721 $this->checkTitle($title, $name);
1723 'href' => $title->getLocalURL( $urlaction ),
1724 'exists' => $title->getArticleID() != 0?
true:false
1728 # make sure we have some title to operate on
1729 /*static*/ function checkTitle ( &$title, &$name ) {
1730 if(!is_object($title)) {
1731 $title = Title
::newFromText( $name );
1732 if(!is_object($title)) {
1733 $title = Title
::newFromText( '--error: link target missing--' );
1738 function fnamePart( $url )
1740 $basename = strrchr( $url, '/' );
1741 if ( false === $basename ) {
1744 $basename = substr( $basename, 1 );
1746 return htmlspecialchars( $basename );
1749 function makeImage( $url, $alt = '' )
1754 $alt = $this->fnamePart( $url );
1756 $s = '<img src="'.$url.'" alt="'.$alt.'" />';
1760 function makeImageLink( $name, $url, $alt = '' ) {
1761 $nt = Title
::makeTitle( Namespace::getImage(), $name );
1762 return $this->makeImageLinkObj( $nt, $alt );
1765 function makeImageLinkObj( $nt, $alt = '' ) {
1766 global $wgLang, $wgUseImageResize;
1767 $img = Image
::newFromTitle( $nt );
1768 $url = $img->getURL();
1771 $prefix = $postfix = '';
1773 if ( $wgUseImageResize ) {
1774 # Check if the alt text is of the form "options|alt text"
1776 # * thumbnail make a thumbnail with enlarge-icon and caption, alignment depends on lang
1777 # * left no resizing, just left align. label is used for alt= only
1778 # * right same, but right aligned
1779 # * none same, but not aligned
1780 # * ___px scale to ___ pixels width, no aligning. e.g. use in taxobox
1781 # * center center the image
1782 # * framed Keep original image size, no magnify-button.
1784 $part = explode( '|', $alt);
1786 $mwThumb =& MagicWord
::get( MAG_IMG_THUMBNAIL
);
1787 $mwLeft =& MagicWord
::get( MAG_IMG_LEFT
);
1788 $mwRight =& MagicWord
::get( MAG_IMG_RIGHT
);
1789 $mwNone =& MagicWord
::get( MAG_IMG_NONE
);
1790 $mwWidth =& MagicWord
::get( MAG_IMG_WIDTH
);
1791 $mwCenter =& MagicWord
::get( MAG_IMG_CENTER
);
1792 $mwFramed =& MagicWord
::get( MAG_IMG_FRAMED
);
1793 $alt = $part[count($part)-1];
1795 $height = $framed = $thumb = false;
1796 $manual_thumb = "" ;
1798 foreach( $part as $key => $val ) {
1799 $val_parts = explode ( "=" , $val , 2 ) ;
1800 $left_part = array_shift ( $val_parts ) ;
1801 if ( ! is_null( $mwThumb->matchVariableStartToEnd($val) ) ) {
1803 } elseif ( count ( $val_parts ) == 1 && ! is_null( $mwThumb->matchVariableStartToEnd($left_part) ) ) {
1804 # use manually specified thumbnail
1806 $manual_thumb = array_shift ( $val_parts ) ;
1807 } elseif ( ! is_null( $mwRight->matchVariableStartToEnd($val) ) ) {
1808 # remember to set an alignment, don't render immediately
1810 } elseif ( ! is_null( $mwLeft->matchVariableStartToEnd($val) ) ) {
1811 # remember to set an alignment, don't render immediately
1813 } elseif ( ! is_null( $mwCenter->matchVariableStartToEnd($val) ) ) {
1814 # remember to set an alignment, don't render immediately
1816 } elseif ( ! is_null( $mwNone->matchVariableStartToEnd($val) ) ) {
1817 # remember to set an alignment, don't render immediately
1819 } elseif ( ! is_null( $match = $mwWidth->matchVariableStartToEnd($val) ) ) {
1820 # $match is the image width in pixels
1821 if ( preg_match( '/^([0-9]*)x([0-9]*)$/', $match, $m ) ) {
1822 $width = intval( $m[1] );
1823 $height = intval( $m[2] );
1825 $width = intval($match);
1827 } elseif ( ! is_null( $mwFramed->matchVariableStartToEnd($val) ) ) {
1831 if ( 'center' == $align )
1833 $prefix = '<span style="text-align: center">';
1834 $postfix = '</span>';
1838 if ( $thumb ||
$framed ) {
1840 # Create a thumbnail. Alignment depends on language
1841 # writing direction, # right aligned for left-to-right-
1842 # languages ("Western languages"), left-aligned
1843 # for right-to-left-languages ("Semitic languages")
1845 # If thumbnail width has not been provided, it is set
1846 # here to 180 pixels
1847 if ( $align == '' ) {
1848 $align = $wgLang->isRTL() ?
'left' : 'right';
1850 if ( ! isset($width) ) {
1853 return $prefix.$this->makeThumbLinkObj( $img, $alt, $align, $width, $height, $framed, $manual_thumb ).$postfix;
1855 } elseif ( isset($width) ) {
1857 # Create a resized image, without the additional thumbnail
1860 if ( ( ! $height === false )
1861 && ( $img->getHeight() * $width / $img->getWidth() > $height ) ) {
1862 print "height=$height<br>\nimg->getHeight() = ".$img->getHeight()."<br>\n";
1863 print 'rescaling by factor '. $height / $img->getHeight() . "<br>\n";
1864 $width = $img->getWidth() * $height / $img->getHeight();
1866 if ( '' == $manual_thumb ) $url = $img->createThumb( $width );
1868 } # endif $wgUseImageResize
1870 if ( empty( $alt ) ) {
1871 $alt = preg_replace( '/\.(.+?)^/', '', $img->getName() );
1873 $alt = htmlspecialchars( $alt );
1875 $u = $nt->escapeLocalURL();
1878 $s = wfMsg( 'missingimage', $img->getName() );
1879 $s .= "<br>{$alt}<br>{$url}<br>\n";
1881 $s = '<a href="'.$u.'" class="image" title="'.$alt.'">' .
1882 '<img src="'.$url.'" alt="'.$alt.'" /></a>';
1884 if ( '' != $align ) {
1885 $s = "<div class=\"float{$align}\"><span>{$s}</span></div>";
1887 return str_replace("\n", ' ',$prefix.$s.$postfix);
1890 # Make HTML for a thumbnail including image, border and caption
1891 # $img is an Image object
1892 function makeThumbLinkObj( $img, $label = '', $align = 'right', $boxwidth = 180, $boxheight=false, $framed=false , $manual_thumb = "" ) {
1893 global $wgStylePath, $wgLang;
1894 # $image = Title::makeTitle( Namespace::getImage(), $name );
1895 $url = $img->getURL();
1897 #$label = htmlspecialchars( $label );
1898 $alt = preg_replace( '/<[^>]*>/', '', $label);
1899 $alt = htmlspecialchars( $alt );
1901 $width = $height = 0;
1902 if ( $img->exists() )
1904 $width = $img->getWidth();
1905 $height = $img->getHeight();
1907 if ( 0 == $width ||
0 == $height )
1909 $width = $height = 200;
1911 if ( $boxwidth == 0 )
1917 // Use image dimensions, don't scale
1919 $oboxwidth = $boxwidth +
2;
1920 $boxheight = $height;
1923 $h = intval( $height/($width/$boxwidth) );
1924 $oboxwidth = $boxwidth +
2;
1925 if ( ( ! $boxheight === false ) && ( $h > $boxheight ) )
1927 $boxwidth *= $boxheight/$h;
1931 if ( '' == $manual_thumb ) $thumbUrl = $img->createThumb( $boxwidth );
1934 if ( $manual_thumb != '' ) # Use manually specified thumbnail
1936 $manual_title = Title
::makeTitle( Namespace::getImage(), $manual_thumb ); #new Title ( $manual_thumb ) ;
1937 $manual_img = Image
::newFromTitle( $manual_title );
1938 $thumbUrl = $manual_img->getURL();
1939 if ( $manual_img->exists() )
1941 $width = $manual_img->getWidth();
1942 $height = $manual_img->getHeight();
1943 $boxwidth = $width ;
1944 $boxheight = $height ;
1945 $oboxwidth = $boxwidth +
2 ;
1949 $u = $img->getEscapeLocalURL();
1951 $more = htmlspecialchars( wfMsg( 'thumbnail-more' ) );
1952 $magnifyalign = $wgLang->isRTL() ?
'left' : 'right';
1953 $textalign = $wgLang->isRTL() ?
' style="text-align:right"' : '';
1955 $s = "<div class=\"thumb t{$align}\"><div style=\"width:{$oboxwidth}px;\">";
1956 if ( $thumbUrl == '' ) {
1957 $s .= wfMsg( 'missingimage', $img->getName() );
1960 $s .= '<a href="'.$u.'" class="internal" title="'.$alt.'">'.
1961 '<img src="'.$thumbUrl.'" alt="'.$alt.'" ' .
1962 'width="'.$boxwidth.'" height="'.$boxheight.'" /></a>';
1966 $zoomicon = '<div class="magnify" style="float:'.$magnifyalign.'">'.
1967 '<a href="'.$u.'" class="internal" title="'.$more.'">'.
1968 '<img src="'.$wgStylePath.'/images/magnify-clip.png" ' .
1969 'width="15" height="11" alt="'.$more.'" /></a></div>';
1972 $s .= ' <div class="thumbcaption" '.$textalign.'>'.$zoomicon.$label."</div></div></div>";
1973 return str_replace("\n", ' ', $s);
1976 function makeMediaLink( $name, $url, $alt = "" ) {
1977 $nt = Title
::makeTitle( Namespace::getMedia(), $name );
1978 return $this->makeMediaLinkObj( $nt, $alt );
1981 function makeMediaLinkObj( $nt, $alt = "" )
1983 if ( ! isset( $nt ) )
1985 ### HOTFIX. Instead of breaking, return empty string.
1988 $name = $nt->getDBKey();
1989 $url = Image
::wfImageUrl( $name );
1990 if ( empty( $alt ) ) {
1991 $alt = preg_replace( '/\.(.+?)^/', '', $name );
1994 $u = htmlspecialchars( $url );
1995 $s = "<a href=\"{$u}\" class='internal' title=\"{$alt}\">{$alt}</a>";
2000 function specialLink( $name, $key = "" )
2004 if ( '' == $key ) { $key = strtolower( $name ); }
2005 $pn = $wgLang->ucfirst( $name );
2006 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
2010 function makeExternalLink( $url, $text, $escape = true ) {
2011 $style = $this->getExternalLinkAttributes( $url, $text );
2012 $url = htmlspecialchars( $url );
2014 $text = htmlspecialchars( $text );
2016 return '<a href="'.$url.'"'.$style.'>'.$text.'</a>';
2019 # Called by history lists and recent changes
2022 # Returns text for the start of the tabular part of RC
2023 function beginRecentChangesList()
2025 $this->rc_cache
= array() ;
2026 $this->rcMoveIndex
= 0;
2027 $this->rcCacheIndex
= 0 ;
2028 $this->lastdate
= '';
2029 $this->rclistOpen
= false;
2033 function beginImageHistoryList()
2035 $s = "\n<h2>" . wfMsg( 'imghistory' ) . "</h2>\n" .
2036 "<p>" . wfMsg( 'imghistlegend' ) . "</p>\n".'<ul class="special">';
2040 # Returns text for the end of RC
2041 # If enhanced RC is in use, returns pretty much all the text
2042 function endRecentChangesList()
2044 $s = $this->recentChangesBlock() ;
2045 if( $this->rclistOpen
) {
2051 # Enhanced RC ungrouped line
2052 function recentChangesBlockLine ( $rcObj )
2054 global $wgStylePath, $wgLang ;
2056 # Get rc_xxxx variables
2057 extract( $rcObj->mAttribs
) ;
2058 $curIdEq = 'curid='.$rc_cur_id;
2063 $r .= '<img src="'.$wgStylePath.'/images/Arr_.png" width="12" height="12" border="0" />' ;
2066 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2067 $r .= ' ';
2069 # M & N (minor & new)
2070 $M = wfMsg( 'minoreditletter' );
2071 $N = wfMsg( 'newpageletter' );
2073 if ( $rc_type == RC_NEW
) {
2086 $r .= ' '.$rcObj->timestamp
.' ' ;
2090 $link = $rcObj->link
;
2091 if ( $rcObj->watched
) $link = '<strong>'.$link.'</strong>' ;
2096 $r .= $rcObj->difflink
;
2100 $r .= $this->makeKnownLinkObj( $rcObj->getTitle(), wfMsg( 'hist' ), $curIdEq.'&action=history' );
2103 $r .= ') . . '.$rcObj->userlink
;
2104 $r .= $rcObj->usertalklink
;
2107 if ( $rc_comment != '' && $rc_type != RC_MOVE
&& $rc_type != RC_MOVE_OVER_REDIRECT
) {
2108 $rc_comment=$this->formatComment($rc_comment);
2109 $r .= $wgLang->emphasize( ' ('.$rc_comment.')' );
2117 function recentChangesBlockGroup ( $block )
2119 global $wgStylePath, $wgLang ;
2122 $M = wfMsg( 'minoreditletter' );
2123 $N = wfMsg( 'newpageletter' );
2125 # Collate list of users
2127 $userlinks = array () ;
2128 foreach ( $block AS $rcObj ) {
2129 $oldid = $rcObj->mAttribs
['rc_last_oldid'];
2130 if ( $rcObj->mAttribs
['rc_new'] ) $isnew = true ;
2131 $u = $rcObj->userlink
;
2132 if ( !isset ( $userlinks[$u] ) ) $userlinks[$u] = 0 ;
2136 # Sort the list and convert to text
2137 krsort ( $userlinks ) ;
2138 asort ( $userlinks ) ;
2140 foreach ( $userlinks as $userlink => $count) {
2142 if ( $count > 1 ) $text .= " ({$count}×)" ;
2143 array_push ( $users , $text ) ;
2145 $users = ' <font size="-1">['.implode('; ',$users).']</font>' ;
2148 $rci = 'RCI'.$this->rcCacheIndex
;
2149 $rcl = 'RCL'.$this->rcCacheIndex
;
2150 $rcm = 'RCM'.$this->rcCacheIndex
;
2151 $toggleLink = "javascript:toggleVisibility('$rci','$rcm','$rcl')" ;
2152 $arrowdir = $wgLang->isRTL() ?
'l' : 'r';
2153 $tl = '<span id="'.$rcm.'"><a href="'.$toggleLink.'"><img src="'.$wgStylePath.'/images/Arr_'.$arrowdir.'.png" width="12" height="12" /></a></span>' ;
2154 $tl .= '<span id="'.$rcl.'" style="display:none"><a href="'.$toggleLink.'"><img src="'.$wgStylePath.'/images/Arr_d.png" width="12" height="12" /></a></span>' ;
2160 if ( $isnew ) $r .= $N ;
2161 else $r .= ' ' ;
2162 $r .= ' ' ; # Minor
2165 $r .= ' '.$block[0]->timestamp
.' ' ;
2169 $link = $block[0]->link
;
2170 if ( $block[0]->watched
) $link = '<strong>'.$link.'</strong>' ;
2173 $curIdEq = 'curid=' . $block[0]->mAttribs
['rc_cur_id'];
2174 if ( $block[0]->mAttribs
['rc_type'] != RC_LOG
) {
2176 $r .= ' ('.count($block).' ' ;
2177 if ( $isnew ) $r .= wfMsg('changes');
2178 else $r .= $this->makeKnownLinkObj( $block[0]->getTitle() , wfMsg('changes') ,
2179 $curIdEq.'&diff=0&oldid='.$oldid ) ;
2183 $r .= $this->makeKnownLinkObj( $block[0]->getTitle(), wfMsg( 'history' ), $curIdEq.'&action=history' );
2191 $r .= '<div id="'.$rci.'" style="display:none">' ;
2192 foreach ( $block AS $rcObj ) {
2193 # Get rc_xxxx variables
2194 extract( $rcObj->mAttribs
);
2196 $r .= '<img src="'.$wgStylePath.'/images/Arr_.png" width="12" height="12" />';
2197 $r .= '<tt> ' ;
2198 if ( $rc_new ) $r .= $N ;
2199 else $r .= ' ' ;
2200 if ( $rc_minor ) $r .= $M ;
2201 else $r .= ' ' ;
2205 if ( $rc_last_oldid != 0 ) {
2206 $o = 'oldid='.$rc_last_oldid ;
2208 if ( $rc_type == RC_LOG
) {
2209 $link = $rcObj->timestamp
;
2211 $link = $this->makeKnownLinkObj( $rcObj->getTitle(), $rcObj->timestamp
, "{$curIdEq}&$o" ) ;
2213 $link = '<tt>'.$link.'</tt>' ;
2217 $r .= $rcObj->curlink
;
2219 $r .= $rcObj->lastlink
;
2220 $r .= ') . . '.$rcObj->userlink
;
2221 $r .= $rcObj->usertalklink
;
2222 if ( $rc_comment != '' ) {
2223 $rc_comment=$this->formatComment($rc_comment);
2224 $r .= $wgLang->emphasize( ' ('.$rc_comment.')' ) ;
2230 $this->rcCacheIndex++
;
2234 # If enhanced RC is in use, this function takes the previously cached
2235 # RC lines, arranges them, and outputs the HTML
2236 function recentChangesBlock ()
2238 global $wgStylePath ;
2239 if ( count ( $this->rc_cache
) == 0 ) return '' ;
2241 foreach ( $this->rc_cache
AS $secureName => $block ) {
2242 if ( count ( $block ) < 2 ) {
2243 $blockOut .= $this->recentChangesBlockLine ( array_shift ( $block ) ) ;
2245 $blockOut .= $this->recentChangesBlockGroup ( $block ) ;
2249 return '<div>'.$blockOut.'</div>' ;
2252 # Called in a loop over all displayed RC entries
2253 # Either returns the line, or caches it for later use
2254 function recentChangesLine( &$rc, $watched = false )
2257 $usenew = $wgUser->getOption( 'usenewrc' );
2259 $line = $this->recentChangesLineNew ( $rc, $watched ) ;
2261 $line = $this->recentChangesLineOld ( $rc, $watched ) ;
2265 function recentChangesLineOld( &$rc, $watched = false )
2267 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds, $wgUseRCPatrol, $wgOnlySysopsCanPatrol;
2269 # Extract DB fields into local scope
2270 extract( $rc->mAttribs
);
2271 $curIdEq = 'curid=' . $rc_cur_id;
2273 # Make date header if necessary
2274 $date = $wgLang->date( $rc_timestamp, true);
2276 if ( $date != $this->lastdate
) {
2277 if ( '' != $this->lastdate
) { $s .= "</ul>\n"; }
2278 $s .= "<h4>{$date}</h4>\n<ul class='special'>";
2279 $this->lastdate
= $date;
2280 $this->rclistOpen
= true;
2283 # If this edit has not yet been patrolled, make it stick out
2284 $s .= ( ! $wgUseRCPatrol ||
$rc_patrolled ) ?
'<li> ' : '<li class="not_patrolled"> ';
2286 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2288 $s .= '(' . wfMsg( 'diff' ) . ') (';
2290 $s .= $this->makeKnownLinkObj( $rc->getMovedToTitle(), wfMsg( 'hist' ), 'action=history' ) .
2293 # "[[x]] moved to [[y]]"
2294 $msg = ( $rc_type == RC_MOVE
) ?
'1movedto2' : '1movedto2_redir';
2295 $s .= wfMsg( $msg, $this->makeKnownLinkObj( $rc->getTitle(), '', 'redirect=no' ),
2296 $this->makeKnownLinkObj( $rc->getMovedToTitle(), '' ) );
2299 if ( $rc_type == RC_NEW ||
$rc_type == RC_LOG
) {
2300 $diffLink = wfMsg( 'diff' );
2302 if ( $wgUseRCPatrol && $rc_patrolled == 0 && $wgUser->getID() != 0 &&
2303 ( $wgUser->isSysop() ||
!$wgOnlySysopsCanPatrol ) )
2304 $rcidparam = "&rcid={$rc_id}";
2307 $diffLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'diff' ),
2308 "{$curIdEq}&diff={$rc_this_oldid}&oldid={$rc_last_oldid}{$rcidparam}",
2309 '', '', ' tabindex="'.$rc->counter
.'"');
2311 $s .= '('.$diffLink.') (';
2314 $s .= $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'hist' ), $curIdEq.'&action=history' );
2317 # M and N (minor and new)
2318 if ( $rc_minor ) { $s .= ' <span class="minor">'.wfMsg( "minoreditletter" ).'</span>'; }
2319 if ( $rc_type == RC_NEW
) { $s .= '<span class="newpage">'.wfMsg( "newpageletter" ).'</span>'; }
2322 # If it's a new article, there is no diff link, but if it hasn't been
2323 # patrolled yet, we need to give users a way to do so
2324 if ( $wgUseRCPatrol && $rc_type == RC_NEW
&& $rc_patrolled == 0 &&
2325 $wgUser->getID() != 0 && ( $wgUser->isSysop() ||
!$wgOnlySysopsCanPatrol ) )
2326 $articleLink = $this->makeKnownLinkObj( $rc->getTitle(), '', "rcid={$rc_id}" );
2328 $articleLink = $this->makeKnownLinkObj( $rc->getTitle(), '' );
2331 $articleLink = '<strong>'.$articleLink.'</strong>';
2333 $s .= ' '.$articleLink;
2338 $s .= '; ' . $wgLang->time( $rc_timestamp, true, $wgRCSeconds ) . ' . . ';
2340 # User link (or contributions for unregistered users)
2341 if ( 0 == $rc_user ) {
2342 $userLink = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
2343 $rc_user_text, 'target=' . $rc_user_text );
2345 $userLink = $this->makeLink( $wgLang->getNsText( NS_USER
) . ':'.$rc_user_text, $rc_user_text );
2350 $talkname=$wgLang->getNsText(NS_TALK
); # use the shorter name
2351 global $wgDisableAnonTalk;
2352 if( 0 == $rc_user && $wgDisableAnonTalk ) {
2355 $utns=$wgLang->getNsText(NS_USER_TALK
);
2356 $userTalkLink= $this->makeLink($utns . ':'.$rc_user_text, $talkname );
2360 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2361 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2362 'Blockip' ), wfMsg( 'blocklink' ), 'ip='.$rc_user_text );
2366 if($userTalkLink) $userTalkLink .= ' | ';
2367 $userTalkLink .= $blockLink;
2369 if($userTalkLink) $s.=' ('.$userTalkLink.')';
2372 if ( '' != $rc_comment && '*' != $rc_comment && $rc_type != RC_MOVE
&& $rc_type != RC_MOVE_OVER_REDIRECT
) {
2373 $rc_comment=$this->formatComment($rc_comment);
2374 $s .= $wgLang->emphasize(' (' . $rc_comment . ')');
2381 function recentChangesLineNew( &$baseRC, $watched = false )
2383 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds;
2385 # Create a specialised object
2386 $rc = RCCacheEntry
::newFromParent( $baseRC ) ;
2388 # Extract fields from DB into the function scope (rc_xxxx variables)
2389 extract( $rc->mAttribs
);
2390 $curIdEq = 'curid=' . $rc_cur_id;
2392 # If it's a new day, add the headline and flush the cache
2393 $date = $wgLang->date( $rc_timestamp, true);
2395 if ( $date != $this->lastdate
) {
2396 # Process current cache
2397 $ret = $this->recentChangesBlock () ;
2398 $this->rc_cache
= array() ;
2399 $ret .= "<h4>{$date}</h4>\n";
2400 $this->lastdate
= $date;
2404 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2405 $msg = ( $rc_type == RC_MOVE
) ?
"1movedto2" : "1movedto2_redir";
2406 $clink = wfMsg( $msg, $this->makeKnownLinkObj( $rc->getTitle(), '', 'redirect=no' ),
2407 $this->makeKnownLinkObj( $rc->getMovedToTitle(), '' ) );
2409 $clink = $this->makeKnownLinkObj( $rc->getTitle(), '' ) ;
2412 $time = $wgLang->time( $rc_timestamp, true, $wgRCSeconds );
2413 $rc->watched
= $watched ;
2414 $rc->link
= $clink ;
2415 $rc->timestamp
= $time;
2417 # Make "cur" and "diff" links
2418 if ( ( $rc_type == RC_NEW
&& $rc_this_oldid == 0 ) ||
$rc_type == RC_LOG ||
$rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2419 $curLink = wfMsg( 'cur' );
2420 $diffLink = wfMsg( 'diff' );
2422 $query = $curIdEq.'&diff=0&oldid='.$rc_this_oldid;
2423 $aprops = ' tabindex="'.$baseRC->counter
.'"';
2424 $curLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'cur' ), $query, '' ,'' , $aprops );
2425 $diffLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'diff'), $query, '' ,'' , $aprops );
2429 $titleObj = $rc->getTitle();
2430 if ( $rc_last_oldid == 0 ||
$rc_type == RC_LOG ||
$rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2431 $lastLink = wfMsg( 'last' );
2433 $lastLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'last' ),
2434 $curIdEq.'&diff='.$rc_this_oldid.'&oldid='.$rc_last_oldid );
2437 # Make user link (or user contributions for unregistered users)
2438 if ( $rc_user == 0 ) {
2439 $userLink = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
2440 $rc_user_text, 'target=' . $rc_user_text );
2442 $userLink = $this->makeLink( $wgLang->getNsText(
2443 Namespace::getUser() ) . ':'.$rc_user_text, $rc_user_text );
2446 $rc->userlink
= $userLink;
2447 $rc->lastlink
= $lastLink;
2448 $rc->curlink
= $curLink;
2449 $rc->difflink
= $diffLink;
2451 # Make user talk link
2452 $utns=$wgLang->getNsText(NS_USER_TALK
);
2453 $talkname=$wgLang->getNsText(NS_TALK
); # use the shorter name
2454 $userTalkLink= $this->makeLink($utns . ':'.$rc_user_text, $talkname );
2456 global $wgDisableAnonTalk;
2457 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2458 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2459 'Blockip' ), wfMsg( 'blocklink' ), 'ip='.$rc_user_text );
2460 if( $wgDisableAnonTalk )
2461 $rc->usertalklink
= ' ('.$blockLink.')';
2463 $rc->usertalklink
= ' ('.$userTalkLink.' | '.$blockLink.')';
2465 if( $wgDisableAnonTalk && ($rc_user == 0) )
2466 $rc->usertalklink
= '';
2468 $rc->usertalklink
= ' ('.$userTalkLink.')';
2471 # Put accumulated information into the cache, for later display
2472 # Page moves go on their own line
2473 $title = $rc->getTitle();
2474 $secureName = $title->getPrefixedDBkey();
2475 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2476 # Use an @ character to prevent collision with page names
2477 $this->rc_cache
['@@' . ($this->rcMoveIndex++
)] = array($rc);
2479 if ( !isset ( $this->rc_cache
[$secureName] ) ) $this->rc_cache
[$secureName] = array() ;
2480 array_push ( $this->rc_cache
[$secureName] , $rc ) ;
2485 function endImageHistoryList()
2491 /* This function is called by all recent changes variants, by the page history,
2492 and by the user contributions list. It is responsible for formatting edit
2493 comments. It escapes any HTML in the comment, but adds some CSS to format
2494 auto-generated comments (from section editing) and formats [[wikilinks]].
2495 Main author: Erik Möller (moeller@scireview.de)
2497 function formatComment($comment)
2500 $comment = htmlspecialchars( $comment );
2502 # The pattern for autogen comments is / * foo * /, which makes for
2504 # We look for all comments, match any text before and after the comment,
2505 # add a separator where needed and format the comment itself with CSS
2506 while (preg_match('/(.*)\/\*\s*(.*?)\s*\*\/(.*)/', $comment,$match)) {
2511 if($pre) { $auto = $sep.' '.$auto; }
2512 if($post) { $auto .= ' '.$sep; }
2513 $auto='<span class="autocomment">'.$auto.'</span>';
2514 $comment=$pre.$auto.$post;
2517 # format regular and media links - all other wiki formatting
2519 $medians = $wgLang->getNsText(Namespace::getMedia()).':';
2520 while(preg_match('/\[\[(.*?)(\|(.*?))*\]\](.*)$/',$comment,$match)) {
2521 # Handle link renaming [[foo|text]] will show link as "text"
2522 if( "" != $match[3] ) {
2527 if( preg_match( '/^' . $medians . '(.*)$/i', $match[1], $submatch ) ) {
2528 # Media link; trail not supported.
2529 $linkRegexp = '/\[\[(.*?)\]\]/';
2530 $thelink = $this->makeMediaLink( $submatch[1], "", $text );
2532 # Other kind of link
2533 if( preg_match( wfMsg( "linktrail" ), $match[4], $submatch ) ) {
2534 $trail = $submatch[1];
2538 $linkRegexp = '/\[\[(.*?)\]\]' . preg_quote( $trail, '/' ) . '/';
2539 $thelink = $this->makeLink( $match[1], $text, "", $trail );
2541 $comment = preg_replace( $linkRegexp, $thelink, $comment, 1 );
2546 function imageHistoryLine( $iscur, $timestamp, $img, $user, $usertext, $size, $description )
2548 global $wgUser, $wgLang, $wgTitle;
2550 $datetime = $wgLang->timeanddate( $timestamp, true );
2551 $del = wfMsg( 'deleteimg' );
2552 $delall = wfMsg( 'deleteimgcompletely' );
2553 $cur = wfMsg( 'cur' );
2556 $url = Image
::wfImageUrl( $img );
2558 if ( $wgUser->isSysop() ) {
2559 $link = $wgTitle->escapeLocalURL( 'image=' . $wgTitle->getPartialURL() .
2561 $style = $this->getInternalLinkAttributes( $link, $delall );
2563 $dlink = '<a href="'.$link.'"'.$style.'>'.$delall.'</a>';
2568 $url = htmlspecialchars( wfImageArchiveUrl( $img ) );
2569 if( $wgUser->getID() != 0 && $wgTitle->userCanEdit() ) {
2570 $rlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2571 wfMsg( 'revertimg' ), 'action=revert&oldimage=' .
2572 urlencode( $img ) );
2573 $dlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2574 $del, 'action=delete&oldimage=' . urlencode( $img ) );
2576 # Having live active links for non-logged in users
2577 # means that bots and spiders crawling our site can
2578 # inadvertently change content. Baaaad idea.
2579 $rlink = wfMsg( 'revertimg' );
2584 $userlink = $usertext;
2586 $userlink = $this->makeLink( $wgLang->getNsText( Namespace::getUser() ) .
2587 ':'.$usertext, $usertext );
2589 $nbytes = wfMsg( 'nbytes', $size );
2590 $style = $this->getInternalLinkAttributes( $url, $datetime );
2592 $s = "<li> ({$dlink}) ({$rlink}) <a href=\"{$url}\"{$style}>{$datetime}</a>"
2593 . " . . {$userlink} ({$nbytes})";
2595 if ( '' != $description && '*' != $description ) {
2596 $sk=$wgUser->getSkin();
2597 $s .= $wgLang->emphasize(' (' . $sk->formatComment($description) . ')');
2603 function tocIndent($level) {
2604 return str_repeat( '<div class="tocindent">'."\n", $level>0 ?
$level : 0 );
2607 function tocUnindent($level) {
2608 return str_repeat( "</div>\n", $level>0 ?
$level : 0 );
2611 # parameter level defines if we are on an indentation level
2612 function tocLine( $anchor, $tocline, $level ) {
2613 $link = '<a href="#'.$anchor.'">'.$tocline.'</a><br />';
2617 return '<div class="tocline">'.$link."</div>\n";
2622 function tocTable($toc) {
2623 # note to CSS fanatics: putting this in a div does not work -- div won't auto-expand
2624 # try min-width & co when somebody gets a chance
2625 $hideline = ' <script type="text/javascript">showTocToggle("' . addslashes( wfMsg('showtoc') ) . '","' . addslashes( wfMsg('hidetoc') ) . '")</script>';
2627 '<table border="0" id="toc"><tr id="toctitle"><td align="center">'."\n".
2628 '<b>'.wfMsg('toc').'</b>' .
2630 '</td></tr><tr id="tocinside"><td>'."\n".
2631 $toc."</td></tr></table>\n";
2634 # These two do not check for permissions: check $wgTitle->userCanEdit before calling them
2635 function editSectionScript( $section, $head ) {
2636 global $wgTitle, $wgRequest;
2637 if( $wgRequest->getInt( 'oldid' ) && ( $wgRequest->getVal( 'diff' ) != '0' ) ) {
2640 $url = $wgTitle->escapeLocalURL( 'action=edit§ion='.$section );
2641 return '<span oncontextmenu=\'document.location="'.$url.'";return false;\'>'.$head.'</span>';
2644 function editSectionLink( $section ) {
2646 global $wgTitle, $wgUser, $wgLang;
2648 if( $wgRequest->getInt( 'oldid' ) && ( $wgRequest->getVal( 'diff' ) != '0' ) ) {
2649 # Section edit links would be out of sync on an old page.
2650 # But, if we're diffing to the current page, they'll be
2655 $editurl = '§ion='.$section;
2656 $url = $this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg('editsection'),'action=edit'.$editurl);
2658 if( $wgLang->isRTL() ) {
2660 $nearside = 'right';
2665 return "<div class=\"editsection\" style=\"float:$farside;margin-$nearside:5px;\">[".$url."]</div>";
2669 // This function is called by EditPage.php and shows a bulletin board style
2670 // toolbar for common editing functions. It can be disabled in the user preferences.
2671 // The necsesary JavaScript code can be found in style/wikibits.js.
2672 function getEditToolbar() {
2673 global $wgStylePath, $wgLang, $wgMimeType;
2675 // toolarray an array of arrays which each include the filename of
2676 // the button image (without path), the opening tag, the closing tag,
2677 // and optionally a sample text that is inserted between the two when no
2678 // selection is highlighted.
2679 // The tip text is shown when the user moves the mouse over the button.
2681 // Already here are accesskeys (key), which are not used yet until someone
2682 // can figure out a way to make them work in IE. However, we should make
2683 // sure these keys are not defined on the edit page.
2685 array( 'image'=>'button_bold.png',
2688 'sample'=>wfMsg('bold_sample'),
2689 'tip'=>wfMsg('bold_tip'),
2692 array( "image"=>"button_italic.png",
2695 "sample"=>wfMsg("italic_sample"),
2696 "tip"=>wfMsg("italic_tip"),
2699 array( "image"=>"button_link.png",
2702 "sample"=>wfMsg("link_sample"),
2703 "tip"=>wfMsg("link_tip"),
2706 array( "image"=>"button_extlink.png",
2709 "sample"=>wfMsg("extlink_sample"),
2710 "tip"=>wfMsg("extlink_tip"),
2713 array( "image"=>"button_headline.png",
2716 "sample"=>wfMsg("headline_sample"),
2717 "tip"=>wfMsg("headline_tip"),
2720 array( "image"=>"button_image.png",
2721 "open"=>"[[".$wgLang->getNsText(NS_IMAGE
).":",
2723 "sample"=>wfMsg("image_sample"),
2724 "tip"=>wfMsg("image_tip"),
2727 array( "image"=>"button_media.png",
2728 "open"=>"[[".$wgLang->getNsText(NS_MEDIA
).":",
2730 "sample"=>wfMsg("media_sample"),
2731 "tip"=>wfMsg("media_tip"),
2734 array( "image"=>"button_math.png",
2735 "open"=>"\\<math\\>",
2736 "close"=>"\\</math\\>",
2737 "sample"=>wfMsg("math_sample"),
2738 "tip"=>wfMsg("math_tip"),
2741 array( "image"=>"button_nowiki.png",
2742 "open"=>"\\<nowiki\\>",
2743 "close"=>"\\</nowiki\\>",
2744 "sample"=>wfMsg("nowiki_sample"),
2745 "tip"=>wfMsg("nowiki_tip"),
2748 array( "image"=>"button_sig.png",
2752 "tip"=>wfMsg("sig_tip"),
2755 array( "image"=>"button_hr.png",
2756 "open"=>"\\n----\\n",
2759 "tip"=>wfMsg("hr_tip"),
2763 $toolbar ="<script type='text/javascript'>\n/*<![CDATA[*/\n";
2765 $toolbar.="document.writeln(\"<div id='toolbar'>\");\n";
2766 foreach($toolarray as $tool) {
2768 $image=$wgStylePath.'/images/'.$tool['image'];
2769 $open=$tool['open'];
2770 $close=$tool['close'];
2771 $sample = addslashes( $tool['sample'] );
2773 // Note that we use the tip both for the ALT tag and the TITLE tag of the image.
2774 // Older browsers show a "speedtip" type message only for ALT.
2775 // Ideally these should be different, realistically they
2776 // probably don't need to be.
2777 $tip = addslashes( $tool['tip'] );
2779 #$key = $tool["key"];
2781 $toolbar.="addButton('$image','$tip','$open','$close','$sample');\n";
2784 $toolbar.="addInfobox('" . addslashes( wfMsg( "infobox" ) ) . "','" . addslashes(wfMsg("infobox_alert")) . "');\n";
2785 $toolbar.="document.writeln(\"</div>\");\n";
2787 $toolbar.="/*]]>*/\n</script>";