This commit only removes trailing whitespace in each line. This is to make the following
[mediawiki.git] / includes / Skin.php
blobdb44468c1b179dd6d56ed6b5aa617eecd226b702
1 <?php
2 # See skin.doc
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'
16 if( $wgUsePHPTal ) {
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;
38 return $rc2;
40 } ;
42 class Skin {
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
48 var $rcMoveIndex;
50 function Skin()
52 $this->linktrail = wfMsg('linktrail');
55 function getSkinNames()
57 global $wgValidSkinNames;
58 return $wgValidSkinNames;
61 function getStylesheet()
63 return 'wikistandard.css';
65 function getSkinName() {
66 return "standard";
69 function qbSetting()
71 global $wgOut, $wgUser;
73 if ( $wgOut->isQuickbarSuppressed() ) { return 0; }
74 $q = $wgUser->getOption( 'quickbar' );
75 if ( '' == $q ) { $q = 0; }
76 return $q;
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' ) ) );
110 $copyright = '';
111 if( $wgRightsPage ) {
112 $copy = Title::newFromText( $wgRightsPage );
113 if( $copy ) {
114 $copyright = $copy->getLocalURL();
117 if( !$copyright && $wgRightsUrl ) {
118 $copyright = $wgRightsUrl;
120 if( $copyright ) {
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'" );
139 $out->out( ">\n" );
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() );
150 wfProfileClose();
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";
164 return $r;
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');
177 } else {
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();
183 return $s."\n";
185 # placeholder, returns generated js in monobook
186 function getUserJs() {
187 return;
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();
196 $s .= "/* */\n";
197 $s .= "</style>\n";
198 return $s;
201 function doGetUserStyles()
203 global $wgUser;
205 $s = '';
206 if ( 1 == $wgUser->getOption( 'underline' ) ) {
207 # Don't override browser settings
208 } else {
209 # CHECK MERGE @@@
210 # Force no underline
211 $s .= 'a { ' .
212 "text-decoration: none; }\n";
214 if ( 1 == $wgUser->getOption( 'highlightbroken' ) ) {
215 $s .= "a.new, #quickbar a.new { color: #CC2200; }\n";
217 if ( 1 == $wgUser->getOption( 'justify' ) ) {
218 $s .= "#article { text-align: justify; }\n";
220 return $s;
223 function getBodyOptions()
225 global $wgUser, $wgTitle, $wgNamespaceBackgrounds, $wgOut, $wgRequest;
227 extract( $wgRequest->getValues( 'oldid', 'redirect', 'diff' ) );
229 if ( 0 != $wgTitle->getNamespace() ) {
230 $a = array( 'bgcolor' => '#ffffec' );
232 else $a = array( 'bgcolor' => '#FFFFFF' );
233 if($wgOut->isArticle() && $wgUser->getOption('editondblclick') &&
234 (!$wgTitle->isProtected() || $wgUser->isSysop()) ) {
235 $t = wfMsg( 'editthispage' );
236 $oid = $red = '';
237 if ( !empty($redirect) ) {
238 $red = "&redirect={$redirect}";
240 if ( !empty($oldid) && ! isset( $diff ) ) {
241 $oid = "&oldid={$oldid}";
243 $s = $wgTitle->getFullURL( "action=edit{$oid}{$red}" );
244 $s = 'document.location = "' .$s .'";';
245 $a += array ('ondblclick' => $s);
248 $a['onload'] = $wgOut->getOnloadHandler();
249 return $a;
252 function getExternalLinkAttributes( $link, $text, $class='' )
254 global $wgUser, $wgOut, $wgLang;
256 $link = urldecode( $link );
257 $link = $wgLang->checkTitleEncoding( $link );
258 $link = str_replace( '_', ' ', $link );
259 $link = wfEscapeHTML( $link );
261 $r = ($class != '') ? " class='$class'" : " class='external'";
263 if ( 1 == $wgUser->getOption( 'hover' ) ) {
264 $r .= " title=\"{$link}\"";
266 return $r;
269 function getInternalLinkAttributes( $link, $text, $broken = false )
271 global $wgUser, $wgOut;
273 $link = urldecode( $link );
274 $link = str_replace( '_', ' ', $link );
275 $link = wfEscapeHTML( $link );
277 if ( $broken == 'stub' ) {
278 $r = ' class="stub"';
279 } else if ( $broken == 'yes' ) {
280 $r = ' class="new"';
281 } else {
282 $r = '';
285 if ( 1 == $wgUser->getOption( 'hover' ) ) {
286 $r .= " title=\"{$link}\"";
288 return $r;
291 function getInternalLinkAttributesObj( &$nt, $text, $broken = false )
293 global $wgUser, $wgOut;
295 if ( $broken == 'stub' ) {
296 $r = ' class="stub"';
297 } else if ( $broken == 'yes' ) {
298 $r = ' class="new"';
299 } else {
300 $r = '';
303 if ( 1 == $wgUser->getOption( 'hover' ) ) {
304 $r .= ' title ="' . $nt->getEscapedText() . '"';
306 return $r;
309 function getLogo()
311 global $wgLogo;
312 return $wgLogo;
315 # This will be called immediately after the <body> tag. Split into
316 # two functions to make it easier to subclass.
318 function beforeContent()
320 global $wgUser, $wgOut;
322 return $this->doBeforeContent();
325 function doBeforeContent()
327 global $wgUser, $wgOut, $wgTitle, $wgLang, $wgSiteNotice;
328 $fname = 'Skin::doBeforeContent';
329 wfProfileIn( $fname );
331 $s = '';
332 $qb = $this->qbSetting();
334 if( $langlinks = $this->otherLanguages() ) {
335 $rows = 2;
336 $borderhack = '';
337 } else {
338 $rows = 1;
339 $langlinks = false;
340 $borderhack = 'class="top"';
343 $s .= "\n<div id='content'>\n<div id='topbar'>\n" .
344 "<table border='0' cellspacing='0' width='98%'>\n<tr>\n";
346 $shove = ($qb != 0);
347 $left = ($qb == 1 || $qb == 3);
348 if($wgLang->isRTL()) $left = !$left;
350 if ( !$shove ) {
351 $s .= "<td class='top' align='left' valign='top' rowspan='{$rows}'>\n" .
352 $this->logoText() . '</td>';
353 } elseif( $left ) {
354 $s .= $this->getQuickbarCompensator( $rows );
356 $l = $wgLang->isRTL() ? 'right' : 'left';
357 $s .= "<td {$borderhack} align='$l' valign='top'>\n";
359 $s .= $this->topLinks() ;
360 $s .= "<p class='subtitle'>" . $this->pageTitleLinks() . "</p>\n";
362 $r = $wgLang->isRTL() ? "left" : "right";
363 $s .= "</td>\n<td {$borderhack} valign='top' align='$r' nowrap='nowrap'>";
364 $s .= $this->nameAndLogin();
365 $s .= "\n<br />" . $this->searchForm() . "</td>";
367 if ( $langlinks ) {
368 $s .= "</tr>\n<tr>\n<td class='top' colspan=\"2\">$langlinks</td>\n";
371 if ( $shove && !$left ) { # Right
372 $s .= $this->getQuickbarCompensator( $rows );
374 $s .= "</tr>\n</table>\n</div>\n";
375 $s .= "\n<div id='article'>\n";
377 if( $wgSiteNotice ) {
378 $s .= "\n<div id='siteNotice'>$wgSiteNotice</div>\n";
380 $s .= $this->pageTitle();
381 $s .= $this->pageSubtitle() ;
382 $s .= $this->getCategories();
383 wfProfileOut( $fname );
384 return $s;
387 function getCategoryLinks () {
388 global $wgOut, $wgTitle, $wgUser, $wgParser;
389 global $wgUseCategoryMagic, $wgUseCategoryBrowser, $wgLang;
391 if( !$wgUseCategoryMagic ) return '' ;
392 if( count( $wgOut->mCategoryLinks ) == 0 ) return '';
394 # Taken out so that they will be displayed in previews -- TS
395 #if( !$wgOut->isArticle() ) return '';
397 $t = implode ( ' | ' , $wgOut->mCategoryLinks ) ;
398 $s = $this->makeKnownLink( 'Special:Categories',
399 wfMsg( 'categories' ), 'article=' . urlencode( $wgTitle->getPrefixedDBkey() ) )
400 . ': ' . $t;
402 if($wgUseCategoryBrowser) {
403 $s .= '<br/><hr/>';
404 $catstack = array();
405 $s.= $wgTitle->getAllParentCategories($catstack);
408 return $s;
411 function getCategories() {
412 $catlinks=$this->getCategoryLinks();
413 if(!empty($catlinks)) {
414 return "<p class='catlinks'>{$catlinks}</p>";
418 function getQuickbarCompensator( $rows = 1 )
420 return "<td width='152' rowspan='{$rows}'>&nbsp;</td>";
423 # This gets called immediately before the </body> tag.
425 function afterContent()
427 global $wgUser, $wgOut, $wgServer;
428 global $wgTitle, $wgLang;
430 $printfooter = "<div class=\"printfooter\">\n" . $this->printFooter() . "</div>\n";
431 return $printfooter . $this->doAfterContent();
434 function printFooter() {
435 global $wgTitle;
436 $url = htmlspecialchars( $wgTitle->getFullURL() );
437 return "<p>" . wfMsg( "retrievedfrom", "<a href=\"$url\">$url</a>" ) .
438 "</p>\n\n<p>" . $this->pageStats() . "</p>\n";
441 function doAfterContent()
443 global $wgUser, $wgOut, $wgLang;
444 $fname = 'Skin::doAfterContent';
445 wfProfileIn( $fname );
446 wfProfileIn( $fname.'-1' );
448 $s = "\n</div><br style=\"clear:both\" />\n";
449 $s .= "\n<div id='footer'>";
450 $s .= '<table border="0" cellspacing="0"><tr>';
452 wfProfileOut( $fname.'-1' );
453 wfProfileIn( $fname.'-2' );
455 $qb = $this->qbSetting();
456 $shove = ($qb != 0);
457 $left = ($qb == 1 || $qb == 3);
458 if($wgLang->isRTL()) $left = !$left;
460 if ( $shove && $left ) { # Left
461 $s .= $this->getQuickbarCompensator();
463 wfProfileOut( $fname.'-2' );
464 wfProfileIn( $fname.'-3' );
465 $l = $wgLang->isRTL() ? 'right' : 'left';
466 $s .= "<td class='bottom' align='$l' valign='top'>";
468 $s .= $this->bottomLinks();
469 $s .= "\n<br />" . $this->mainPageLink()
470 . ' | ' . $this->aboutLink()
471 . ' | ' . $this->specialLink( 'recentchanges' )
472 . ' | ' . $this->searchForm()
473 . '<br /><span id="pagestats">' . $this->pageStats() . '</span>';
475 $s .= "</td>";
476 if ( $shove && !$left ) { # Right
477 $s .= $this->getQuickbarCompensator();
479 $s .= "</tr></table>\n</div>\n</div>\n";
481 wfProfileOut( $fname.'-3' );
482 wfProfileIn( $fname.'-4' );
483 if ( 0 != $qb ) { $s .= $this->quickBar(); }
484 wfProfileOut( $fname.'-4' );
485 wfProfileOut( $fname );
486 return $s;
489 function pageTitleLinks()
491 global $wgOut, $wgTitle, $wgUser, $wgLang, $wgUseApproval, $wgRequest;
493 extract( $wgRequest->getValues( 'oldid', 'diff' ) );
494 $action = $wgRequest->getText( 'action' );
496 $s = $this->printableLink();
497 if ( wfMsg ( 'disclaimers' ) != '-' ) $s .= ' | ' . $this->makeKnownLink( wfMsg( 'disclaimerpage' ), wfMsg( 'disclaimers' ) ) ;
499 if ( $wgOut->isArticleRelated() ) {
500 if ( $wgTitle->getNamespace() == Namespace::getImage() ) {
501 $name = $wgTitle->getDBkey();
502 $link = wfEscapeHTML( Image::wfImageUrl( $name ) );
503 $style = $this->getInternalLinkAttributes( $link, $name );
504 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>";
506 # This will show the "Approve" link if $wgUseApproval=true;
507 if ( isset ( $wgUseApproval ) && $wgUseApproval )
509 $t = $wgTitle->getDBkey();
510 $name = 'Approve this article' ;
511 $link = "http://test.wikipedia.org/w/magnus/wiki.phtml?title={$t}&action=submit&doit=1" ;
512 #wfEscapeHTML( wfImageUrl( $name ) );
513 $style = $this->getExternalLinkAttributes( $link, $name );
514 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>" ;
517 if ( 'history' == $action || isset( $diff ) || isset( $oldid ) ) {
518 $s .= ' | ' . $this->makeKnownLink( $wgTitle->getPrefixedText(),
519 wfMsg( 'currentrev' ) );
522 if ( $wgUser->getNewtalk() ) {
523 # do not show "You have new messages" text when we are viewing our
524 # own talk page
526 if(!(strcmp($wgTitle->getText(),$wgUser->getName()) == 0 &&
527 $wgTitle->getNamespace()==Namespace::getTalk(Namespace::getUser()))) {
528 $n =$wgUser->getName();
529 $tl = $this->makeKnownLink( $wgLang->getNsText(
530 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
531 wfMsg('newmessageslink') );
532 $s.= ' | <strong>'. wfMsg( 'newmessages', $tl ) . '</strong>';
536 $undelete = $this->getUndeleteLink();
537 if( !empty( $undelete ) ) {
538 $s .= ' | '.$undelete;
540 return $s;
543 function getUndeleteLink() {
544 global $wgUser, $wgTitle, $wgLang, $action;
545 if( $wgUser->isSysop() &&
546 (($wgTitle->getArticleId() == 0) || ($action == "history")) &&
547 ($n = $wgTitle->isDeleted() ) ) {
548 return wfMsg( 'thisisdeleted',
549 $this->makeKnownLink(
550 $wgLang->SpecialPage( 'Undelete/' . $wgTitle->getPrefixedDBkey() ),
551 wfMsg( 'restorelink', $n ) ) );
553 return '';
556 function printableLink()
558 global $wgOut, $wgFeedClasses, $wgRequest;
560 $baseurl = $_SERVER['REQUEST_URI'];
561 if( strpos( '?', $baseurl ) == false ) {
562 $baseurl .= '?';
563 } else {
564 $baseurl .= '&';
566 $baseurl = htmlspecialchars( $baseurl );
567 $printurl = $wgRequest->escapeAppendQuery( 'printable=yes' );
569 $s = "<a href=\"$printurl\">" . wfMsg( 'printableversion' ) . '</a>';
570 if( $wgOut->isSyndicated() ) {
571 foreach( $wgFeedClasses as $format => $class ) {
572 $feedurl = $wgRequest->escapeAppendQuery( "feed=$format" );
573 $s .= " | <a href=\"$feedurl\">{$format}</a>";
576 return $s;
579 function pageTitle()
581 global $wgOut, $wgTitle, $wgUser;
583 $s = '<h1 class="pagetitle">' . htmlspecialchars( $wgOut->getPageTitle() ) . '</h1>';
584 if($wgUser->getOption( 'editsectiononrightclick' ) && $wgTitle->userCanEdit()) { $s=$this->editSectionScript(0,$s);}
585 return $s;
588 function pageSubtitle()
590 global $wgOut;
592 $sub = $wgOut->getSubtitle();
593 if ( '' == $sub ) {
594 global $wgExtraSubtitle;
595 $sub = wfMsg( 'fromwikipedia' ) . $wgExtraSubtitle;
597 $subpages = $this->subPageSubtitle();
598 $sub .= !empty($subpages)?"</p><p class='subpages'>$subpages":'';
599 $s = "<p class='subtitle'>{$sub}</p>\n";
600 return $s;
603 function subPageSubtitle()
605 global $wgOut,$wgTitle,$wgNamespacesWithSubpages;
606 $subpages = '';
607 if($wgOut->isArticle() && !empty($wgNamespacesWithSubpages[$wgTitle->getNamespace()])) {
608 $ptext=$wgTitle->getPrefixedText();
609 if(preg_match('/\//',$ptext)) {
610 $links = explode('/',$ptext);
611 $c = 0;
612 $growinglink = '';
613 foreach($links as $link) {
614 $c++;
615 if ($c<count($links)) {
616 $growinglink .= $link;
617 $getlink = $this->makeLink( $growinglink, $link );
618 if(preg_match('/class="new"/i',$getlink)) { break; } # this is a hack, but it saves time
619 if ($c>1) {
620 $subpages .= ' | ';
621 } else {
622 $subpages .= '&lt; ';
624 $subpages .= $getlink;
625 $growinglink .= '/';
630 return $subpages;
633 function nameAndLogin()
635 global $wgUser, $wgTitle, $wgLang, $wgShowIPinHeader, $wgIP;
637 $li = $wgLang->specialPage( 'Userlogin' );
638 $lo = $wgLang->specialPage( 'Userlogout' );
640 $s = '';
641 if ( 0 == $wgUser->getID() ) {
642 if( $wgShowIPinHeader && isset( $_COOKIE[ini_get('session.name')] ) ) {
643 $n = $wgIP;
645 $tl = $this->makeKnownLink( $wgLang->getNsText(
646 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
647 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
649 $s .= $n . ' ('.$tl.')';
650 } else {
651 $s .= wfMsg('notloggedin');
654 $rt = $wgTitle->getPrefixedURL();
655 if ( 0 == strcasecmp( urlencode( $lo ), $rt ) ) {
656 $q = '';
657 } else { $q = "returnto={$rt}"; }
659 $s .= "\n<br />" . $this->makeKnownLink( $li,
660 wfMsg( 'login' ), $q );
661 } else {
662 $n = $wgUser->getName();
663 $rt = $wgTitle->getPrefixedURL();
664 $tl = $this->makeKnownLink( $wgLang->getNsText(
665 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
666 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
668 $tl = " ({$tl})";
670 $s .= $this->makeKnownLink( $wgLang->getNsText(
671 Namespace::getUser() ) . ":{$n}", $n ) . "{$tl}<br />" .
672 $this->makeKnownLink( $lo, wfMsg( 'logout' ),
673 "returnto={$rt}" ) . ' | ' .
674 $this->specialLink( 'preferences' );
676 $s .= ' | ' . $this->makeKnownLink( wfMsg( 'helppage' ),
677 wfMsg( 'help' ) );
679 return $s;
682 function getSearchLink() {
683 $searchPage =& Title::makeTitle( NS_SPECIAL, 'Search' );
684 return $searchPage->getLocalURL();
687 function escapeSearchLink() {
688 return htmlspecialchars( $this->getSearchLink() );
691 function searchForm()
693 global $wgRequest;
694 $search = $wgRequest->getText( 'search' );
696 $s = '<form name="search" class="inline" method="post" action="'
697 . $this->escapeSearchLink() . "\">\n"
698 . '<input type="text" name="search" size="19" value="'
699 . htmlspecialchars(substr($search,0,256)) . "\" />\n"
700 . '<input type="submit" name="go" value="' . wfMsg ('go') . '" />&nbsp;'
701 . '<input type="submit" name="fulltext" value="' . wfMsg ('search') . "\" />\n</form>";
703 return $s;
706 function topLinks()
708 global $wgOut;
709 $sep = " |\n";
711 $s = $this->mainPageLink() . $sep
712 . $this->specialLink( 'recentchanges' );
714 if ( $wgOut->isArticleRelated() ) {
715 $s .= $sep . $this->editThisPage()
716 . $sep . $this->historyLink();
718 # Many people don't like this dropdown box
719 #$s .= $sep . $this->specialPagesList();
721 return $s;
724 function bottomLinks()
726 global $wgOut, $wgUser, $wgTitle;
727 $sep = " |\n";
729 $s = '';
730 if ( $wgOut->isArticleRelated() ) {
731 $s .= '<strong>' . $this->editThisPage() . '</strong>';
732 if ( 0 != $wgUser->getID() ) {
733 $s .= $sep . $this->watchThisPage();
735 $s .= $sep . $this->talkLink()
736 . $sep . $this->historyLink()
737 . $sep . $this->whatLinksHere()
738 . $sep . $this->watchPageLinksLink();
740 if ( $wgTitle->getNamespace() == Namespace::getUser()
741 || $wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser()) )
744 $id=User::idFromName($wgTitle->getText());
745 $ip=User::isIP($wgTitle->getText());
747 if($id || $ip) { # both anons and non-anons have contri list
748 $s .= $sep . $this->userContribsLink();
750 if ( 0 != $wgUser->getID() ) { # show only to signed in users
751 if($id) { # can only email non-anons
752 $s .= $sep . $this->emailUserLink();
756 if ( $wgUser->isSysop() && $wgTitle->getArticleId() ) {
757 $s .= "\n<br />" . $this->deleteThisPage() .
758 $sep . $this->protectThisPage() .
759 $sep . $this->moveThisPage();
761 $s .= "<br />\n" . $this->otherLanguages();
763 return $s;
766 function pageStats()
768 global $wgOut, $wgLang, $wgArticle, $wgRequest;
769 global $wgDisableCounters, $wgMaxCredits, $wgShowCreditsIfMax;
771 extract( $wgRequest->getValues( 'oldid', 'diff' ) );
772 if ( ! $wgOut->isArticle() ) { return ''; }
773 if ( isset( $oldid ) || isset( $diff ) ) { return ''; }
774 if ( 0 == $wgArticle->getID() ) { return ''; }
776 $s = '';
777 if ( !$wgDisableCounters ) {
778 $count = $wgLang->formatNum( $wgArticle->getCount() );
779 if ( $count ) {
780 $s = wfMsg( 'viewcount', $count );
784 if (isset($wgMaxCredits) && $wgMaxCredits != 0) {
785 require_once("Credits.php");
786 $s .= ' ' . getCredits($wgArticle, $wgMaxCredits, $wgShowCreditsIfMax);
787 } else {
788 $s .= $this->lastModified();
791 return $s . ' ' . $this->getCopyright();
794 function getCopyright() {
795 global $wgRightsPage, $wgRightsUrl, $wgRightsText, $wgRequest;
798 $oldid = $wgRequest->getVal( 'oldid' );
799 $diff = $wgRequest->getVal( 'diff' );
801 if ( !is_null( $oldid ) && is_null( $diff ) && wfMsg( 'history_copyright' ) !== '-' ) {
802 $msg = 'history_copyright';
803 } else {
804 $msg = 'copyright';
807 $out = '';
808 if( $wgRightsPage ) {
809 $link = $this->makeKnownLink( $wgRightsPage, $wgRightsText );
810 } elseif( $wgRightsUrl ) {
811 $link = $this->makeExternalLink( $wgRightsUrl, $wgRightsText );
812 } else {
813 # Give up now
814 return $out;
816 $out .= wfMsg( $msg, $link );
817 return $out;
820 function getCopyrightIcon() {
821 global $wgRightsPage, $wgRightsUrl, $wgRightsText, $wgRightsIcon;
822 $out = '';
823 if( $wgRightsIcon ) {
824 $icon = htmlspecialchars( $wgRightsIcon );
825 if( $wgRightsUrl ) {
826 $url = htmlspecialchars( $wgRightsUrl );
827 $out .= '<a href="'.$url.'">';
829 $text = htmlspecialchars( $wgRightsText );
830 $out .= "<img src=\"$icon\" alt='$text' />";
831 if( $wgRightsUrl ) {
832 $out .= '</a>';
835 return $out;
838 function getPoweredBy() {
839 global $wgStylePath;
840 $url = htmlspecialchars( "$wgStylePath/images/poweredby_mediawiki_88x31.png" );
841 $img = '<a href="http://www.mediawiki.org/"><img src="'.$url.'" alt="MediaWiki" /></a>';
842 return $img;
845 function lastModified()
847 global $wgLang, $wgArticle;
849 $timestamp = $wgArticle->getTimestamp();
850 if ( $timestamp ) {
851 $d = $wgLang->timeanddate( $wgArticle->getTimestamp(), true );
852 $s = ' ' . wfMsg( 'lastmodified', $d );
853 } else {
854 $s = '';
856 return $s;
859 function logoText( $align = '' )
861 if ( '' != $align ) { $a = ' align="'.$align.'"'; }
862 else { $a = ''; }
864 $mp = wfMsg( 'mainpage' );
865 $titleObj = Title::newFromText( $mp );
866 $s = '<a href="' . $titleObj->escapeLocalURL()
867 . '"><img'.$a.' src="'
868 . $this->getLogo() . '" alt="' . "[{$mp}]\" /></a>";
869 return $s;
872 function quickBar()
874 global $wgOut, $wgTitle, $wgUser, $wgRequest, $wgLang;
875 global $wgDisableUploads, $wgRemoteUploads;
877 $fname = 'Skin::quickBar';
878 wfProfileIn( $fname );
880 $action = $wgRequest->getText( 'action' );
881 $wpPreview = $wgRequest->getBool( 'wpPreview' );
882 $tns=$wgTitle->getNamespace();
884 $s = "\n<div id='quickbar'>";
885 $s .= "\n" . $this->logoText() . "\n<hr class='sep' />";
887 $sep = "\n<br />";
888 $s .= $this->mainPageLink()
889 . $sep . $this->specialLink( 'recentchanges' )
890 . $sep . $this->specialLink( 'randompage' );
891 if ($wgUser->getID()) {
892 $s.= $sep . $this->specialLink( 'watchlist' ) ;
893 $s .= $sep .$this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
894 wfMsg( 'mycontris' ), 'target=' . wfUrlencode($wgUser->getName() ) );
897 // only show watchlist link if logged in
898 if ( wfMsg ( 'currentevents' ) != '-' ) $s .= $sep . $this->makeKnownLink( wfMsg( 'currentevents' ), '' ) ;
899 $s .= "\n<br /><hr class='sep' />";
900 $articleExists = $wgTitle->getArticleId();
901 if ( $wgOut->isArticle() || $action =='edit' || $action =='history' || $wpPreview) {
902 if($wgOut->isArticle()) {
903 $s .= '<strong>' . $this->editThisPage() . '</strong>';
904 } else { # backlink to the article in edit or history mode
905 if($articleExists){ # no backlink if no article
906 switch($tns) {
907 case 0:
908 $text = wfMsg('articlepage');
909 break;
910 case 1:
911 $text = wfMsg('viewtalkpage');
912 break;
913 case 2:
914 $text = wfMsg('userpage');
915 break;
916 case 3:
917 $text = wfMsg('viewtalkpage');
918 break;
919 case 4:
920 $text = wfMsg('wikipediapage');
921 break;
922 case 5:
923 $text = wfMsg('viewtalkpage');
924 break;
925 case 6:
926 $text = wfMsg('imagepage');
927 break;
928 case 7:
929 $text = wfMsg('viewtalkpage');
930 break;
931 default:
932 $text= wfMsg('articlepage');
935 $link = $wgTitle->getText();
936 if ($nstext = $wgLang->getNsText($tns) ) { # add namespace if necessary
937 $link = $nstext . ':' . $link ;
940 $s .= $this->makeLink( $link, $text );
941 } elseif( $wgTitle->getNamespace() != Namespace::getSpecial() ) {
942 # we just throw in a "New page" text to tell the user that he's in edit mode,
943 # and to avoid messing with the separator that is prepended to the next item
944 $s .= '<strong>' . wfMsg('newpage') . '</strong>';
950 if( $tns%2 && $action!='edit' && !$wpPreview) {
951 $s.= '<br />'.$this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg('postcomment'),'action=edit&section=new');
955 watching could cause problems in edit mode:
956 if user edits article, then loads "watch this article" in background and then saves
957 article with "Watch this article" checkbox disabled, the article is transparently
958 unwatched. Therefore we do not show the "Watch this page" link in edit mode
960 if ( 0 != $wgUser->getID() && $articleExists) {
961 if($action!='edit' && $action != 'submit' )
963 $s .= $sep . $this->watchThisPage();
965 if ( $wgTitle->userCanEdit() )
966 $s .= $sep . $this->moveThisPage();
968 if ( $wgUser->isSysop() and $articleExists ) {
969 $s .= $sep . $this->deleteThisPage() .
970 $sep . $this->protectThisPage();
972 $s .= $sep . $this->talkLink();
973 if ($articleExists && $action !='history') {
974 $s .= $sep . $this->historyLink();
976 $s.=$sep . $this->whatLinksHere();
978 if($wgOut->isArticleRelated()) {
979 $s .= $sep . $this->watchPageLinksLink();
982 if ( Namespace::getUser() == $wgTitle->getNamespace()
983 || $wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser())
986 $id=User::idFromName($wgTitle->getText());
987 $ip=User::isIP($wgTitle->getText());
989 if($id||$ip) {
990 $s .= $sep . $this->userContribsLink();
992 if ( 0 != $wgUser->getID() ) {
993 if($id) { # can only email real users
994 $s .= $sep . $this->emailUserLink();
998 $s .= "\n<br /><hr class='sep' />";
1001 if ( 0 != $wgUser->getID() && ( !$wgDisableUploads || $wgRemoteUploads ) ) {
1002 $s .= $this->specialLink( 'upload' ) . $sep;
1004 $s .= $this->specialLink( 'specialpages' )
1005 . $sep . $this->bugReportsLink();
1007 global $wgSiteSupportPage;
1008 if( $wgSiteSupportPage ) {
1009 $s .= "\n<br /><a href=\"" . htmlspecialchars( $wgSiteSupportPage ) .
1010 '" class="internal">' . wfMsg( 'sitesupport' ) . '</a>';
1013 $s .= "\n<br /></div>\n";
1014 wfProfileOut( $fname );
1015 return $s;
1018 function specialPagesList()
1020 global $wgUser, $wgOut, $wgLang, $wgServer, $wgRedirectScript;
1021 require_once('SpecialPage.php');
1022 $a = array();
1023 $pages = SpecialPage::getPages();
1025 foreach ( $pages[''] as $name => $page ) {
1026 $a[$name] = $page->getDescription();
1028 if ( $wgUser->isSysop() )
1030 foreach ( $pages['sysop'] as $name => $page ) {
1031 $a[$name] = $page->getDescription();
1034 if ( $wgUser->isDeveloper() )
1036 foreach ( $pages['developer'] as $name => $page ) {
1037 $a[$name] = $page->getDescription() ;
1040 $go = wfMsg( 'go' );
1041 $sp = wfMsg( 'specialpages' );
1042 $spp = $wgLang->specialPage( 'Specialpages' );
1044 $s = '<form id="specialpages" method="get" class="inline" ' .
1045 'action="' . htmlspecialchars( "{$wgServer}{$wgRedirectScript}" ) . "\">\n";
1046 $s .= "<select name=\"wpDropdown\">\n";
1047 $s .= "<option value=\"{$spp}\">{$sp}</option>\n";
1049 foreach ( $a as $name => $desc ) {
1050 $p = $wgLang->specialPage( $name );
1051 $s .= "<option value=\"{$p}\">{$desc}</option>\n";
1053 $s .= "</select>\n";
1054 $s .= "<input type='submit' value=\"{$go}\" name='redirect' />\n";
1055 $s .= "</form>\n";
1056 return $s;
1059 function mainPageLink()
1061 $mp = wfMsg( 'mainpage' );
1062 $s = $this->makeKnownLink( $mp, $mp );
1063 return $s;
1066 function copyrightLink()
1068 $s = $this->makeKnownLink( wfMsg( 'copyrightpage' ),
1069 wfMsg( 'copyrightpagename' ) );
1070 return $s;
1073 function aboutLink()
1075 $s = $this->makeKnownLink( wfMsg( 'aboutpage' ),
1076 wfMsg( 'aboutwikipedia' ) );
1077 return $s;
1081 function disclaimerLink()
1083 $s = $this->makeKnownLink( wfMsg( 'disclaimerpage' ),
1084 wfMsg( 'disclaimers' ) );
1085 return $s;
1088 function editThisPage()
1090 global $wgOut, $wgTitle, $wgRequest;
1092 $oldid = $wgRequest->getVal( 'oldid' );
1093 $diff = $wgRequest->getVal( 'diff' );
1094 $redirect = $wgRequest->getVal( 'redirect' );
1096 if ( ! $wgOut->isArticleRelated() ) {
1097 $s = wfMsg( 'protectedpage' );
1098 } else {
1099 $n = $wgTitle->getPrefixedText();
1100 if ( $wgTitle->userCanEdit() ) {
1101 $t = wfMsg( 'editthispage' );
1102 } else {
1103 #$t = wfMsg( "protectedpage" );
1104 $t = wfMsg( 'viewsource' );
1106 $oid = $red = '';
1108 if ( !is_null( $redirect ) ) { $red = "&redirect={$redirect}"; }
1109 if ( $oldid && ! isset( $diff ) ) {
1110 $oid = "&oldid={$oldid}";
1112 $s = $this->makeKnownLink( $n, $t, "action=edit{$oid}{$red}" );
1114 return $s;
1117 function deleteThisPage()
1119 global $wgUser, $wgOut, $wgTitle, $wgRequest;
1121 $diff = $wgRequest->getVal( 'diff' );
1122 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
1123 $n = $wgTitle->getPrefixedText();
1124 $t = wfMsg( 'deletethispage' );
1126 $s = $this->makeKnownLink( $n, $t, 'action=delete' );
1127 } else {
1128 $s = '';
1130 return $s;
1133 function protectThisPage()
1135 global $wgUser, $wgOut, $wgTitle, $wgRequest;
1137 $diff = $wgRequest->getVal( 'diff' );
1138 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
1139 $n = $wgTitle->getPrefixedText();
1141 if ( $wgTitle->isProtected() ) {
1142 $t = wfMsg( 'unprotectthispage' );
1143 $q = 'action=unprotect';
1144 } else {
1145 $t = wfMsg( 'protectthispage' );
1146 $q = 'action=protect';
1148 $s = $this->makeKnownLink( $n, $t, $q );
1149 } else {
1150 $s = '';
1152 return $s;
1155 function watchThisPage()
1157 global $wgUser, $wgOut, $wgTitle;
1159 if ( $wgOut->isArticleRelated() ) {
1160 $n = $wgTitle->getPrefixedText();
1162 if ( $wgTitle->userIsWatching() ) {
1163 $t = wfMsg( 'unwatchthispage' );
1164 $q = 'action=unwatch';
1165 } else {
1166 $t = wfMsg( 'watchthispage' );
1167 $q = 'action=watch';
1169 $s = $this->makeKnownLink( $n, $t, $q );
1170 } else {
1171 $s = wfMsg( 'notanarticle' );
1173 return $s;
1176 function moveThisPage()
1178 global $wgTitle, $wgLang;
1180 if ( $wgTitle->userCanEdit() ) {
1181 $s = $this->makeKnownLink( $wgLang->specialPage( 'Movepage' ),
1182 wfMsg( 'movethispage' ), 'target=' . $wgTitle->getPrefixedURL() );
1183 } // no message if page is protected - would be redundant
1184 return $s;
1187 function historyLink()
1189 global $wgTitle;
1191 $s = $this->makeKnownLink( $wgTitle->getPrefixedText(),
1192 wfMsg( 'history' ), 'action=history' );
1193 return $s;
1196 function whatLinksHere()
1198 global $wgTitle, $wgLang;
1200 $s = $this->makeKnownLink( $wgLang->specialPage( 'Whatlinkshere' ),
1201 wfMsg( 'whatlinkshere' ), 'target=' . $wgTitle->getPrefixedURL() );
1202 return $s;
1205 function userContribsLink()
1207 global $wgTitle, $wgLang;
1209 $s = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
1210 wfMsg( 'contributions' ), 'target=' . $wgTitle->getPartialURL() );
1211 return $s;
1214 function emailUserLink()
1216 global $wgTitle, $wgLang;
1218 $s = $this->makeKnownLink( $wgLang->specialPage( 'Emailuser' ),
1219 wfMsg( 'emailuser' ), 'target=' . $wgTitle->getPartialURL() );
1220 return $s;
1223 function watchPageLinksLink()
1225 global $wgOut, $wgTitle, $wgLang;
1227 if ( ! $wgOut->isArticleRelated() ) {
1228 $s = '(' . wfMsg( 'notanarticle' ) . ')';
1229 } else {
1230 $s = $this->makeKnownLink( $wgLang->specialPage(
1231 'Recentchangeslinked' ), wfMsg( 'recentchangeslinked' ),
1232 'target=' . $wgTitle->getPrefixedURL() );
1234 return $s;
1237 function otherLanguages()
1239 global $wgOut, $wgLang, $wgTitle, $wgUseNewInterlanguage;
1241 $a = $wgOut->getLanguageLinks();
1242 if ( 0 == count( $a ) ) {
1243 if ( !$wgUseNewInterlanguage ) return '';
1244 $ns = $wgLang->getNsIndex ( $wgTitle->getNamespace () ) ;
1245 if ( $ns != 0 AND $ns != 1 ) return '' ;
1246 $pn = 'Intl' ;
1247 $x = 'mode=addlink&xt='.$wgTitle->getDBkey() ;
1248 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1249 wfMsg( 'intl' ) , $x );
1252 if ( !$wgUseNewInterlanguage ) {
1253 $s = wfMsg( 'otherlanguages' ) . ': ';
1254 } else {
1255 global $wgLanguageCode ;
1256 $x = 'mode=zoom&xt='.$wgTitle->getDBkey() ;
1257 $x .= '&xl='.$wgLanguageCode ;
1258 $s = $this->makeKnownLink( $wgLang->specialPage( 'Intl' ),
1259 wfMsg( 'otherlanguages' ) , $x ) . ': ' ;
1262 $s = wfMsg( 'otherlanguages' ) . ': ';
1263 $first = true;
1264 if($wgLang->isRTL()) $s .= '<span dir="LTR">';
1265 foreach( $a as $l ) {
1266 if ( ! $first ) { $s .= ' | '; }
1267 $first = false;
1269 $nt = Title::newFromText( $l );
1270 $url = $nt->getFullURL();
1271 $text = $wgLang->getLanguageName( $nt->getInterwiki() );
1273 if ( '' == $text ) { $text = $l; }
1274 $style = $this->getExternalLinkAttributes( $l, $text );
1275 $s .= "<a href=\"{$url}\"{$style}>{$text}</a>";
1277 if($wgLang->isRTL()) $s .= '</span>';
1278 return $s;
1281 function bugReportsLink()
1283 $s = $this->makeKnownLink( wfMsg( 'bugreportspage' ),
1284 wfMsg( 'bugreports' ) );
1285 return $s;
1288 function dateLink()
1290 global $wgLinkCache;
1291 $t1 = Title::newFromText( gmdate( 'F j' ) );
1292 $t2 = Title::newFromText( gmdate( 'Y' ) );
1294 $wgLinkCache->suspend();
1295 $id = $t1->getArticleID();
1296 $wgLinkCache->resume();
1298 if ( 0 == $id ) {
1299 $s = $this->makeBrokenLink( $t1->getText() );
1300 } else {
1301 $s = $this->makeKnownLink( $t1->getText() );
1303 $s .= ', ';
1305 $wgLinkCache->suspend();
1306 $id = $t2->getArticleID();
1307 $wgLinkCache->resume();
1309 if ( 0 == $id ) {
1310 $s .= $this->makeBrokenLink( $t2->getText() );
1311 } else {
1312 $s .= $this->makeKnownLink( $t2->getText() );
1314 return $s;
1317 function talkLink()
1319 global $wgLang, $wgTitle, $wgLinkCache;
1321 $tns = $wgTitle->getNamespace();
1322 if ( -1 == $tns ) { return ''; }
1324 $pn = $wgTitle->getText();
1325 $tp = wfMsg( 'talkpage' );
1326 if ( Namespace::isTalk( $tns ) ) {
1327 $lns = Namespace::getSubject( $tns );
1328 switch($tns) {
1329 case 1:
1330 $text = wfMsg('articlepage');
1331 break;
1332 case 3:
1333 $text = wfMsg('userpage');
1334 break;
1335 case 5:
1336 $text = wfMsg('wikipediapage');
1337 break;
1338 case 7:
1339 $text = wfMsg('imagepage');
1340 break;
1341 default:
1342 $text= wfMsg('articlepage');
1344 } else {
1346 $lns = Namespace::getTalk( $tns );
1347 $text=$tp;
1349 $n = $wgLang->getNsText( $lns );
1350 if ( '' == $n ) { $link = $pn; }
1351 else { $link = $n.':'.$pn; }
1353 $wgLinkCache->suspend();
1354 $s = $this->makeLink( $link, $text );
1355 $wgLinkCache->resume();
1357 return $s;
1360 function commentLink()
1362 global $wgLang, $wgTitle, $wgLinkCache;
1364 $tns = $wgTitle->getNamespace();
1365 if ( -1 == $tns ) { return ''; }
1367 $lns = ( Namespace::isTalk( $tns ) ) ? $tns : Namespace::getTalk( $tns );
1369 # assert Namespace::isTalk( $lns )
1371 $n = $wgLang->getNsText( $lns );
1372 $pn = $wgTitle->getText();
1374 $link = $n.':'.$pn;
1376 $wgLinkCache->suspend();
1377 $s = $this->makeKnownLink($link, wfMsg('postcomment'), 'action=edit&section=new');
1378 $wgLinkCache->resume();
1380 return $s;
1383 # After all the page content is transformed into HTML, it makes
1384 # a final pass through here for things like table backgrounds.
1386 function transformContent( $text )
1388 return $text;
1391 # Note: This function MUST call getArticleID() on the link,
1392 # otherwise the cache won't get updated properly. See LINKCACHE.DOC.
1394 function makeLink( $title, $text = '', $query = '', $trail = '' ) {
1395 wfProfileIn( 'Skin::makeLink' );
1396 $nt = Title::newFromText( $title );
1397 if ($nt) {
1398 $result = $this->makeLinkObj( Title::newFromText( $title ), $text, $query, $trail );
1399 } else {
1400 wfDebug( 'Invalid title passed to Skin::makeLink(): "'.$title."\"\n" );
1401 $result = $text == "" ? $title : $text;
1404 wfProfileOut( 'Skin::makeLink' );
1405 return $result;
1408 function makeKnownLink( $title, $text = '', $query = '', $trail = '', $prefix = '',$aprops = '') {
1409 $nt = Title::newFromText( $title );
1410 if ($nt) {
1411 return $this->makeKnownLinkObj( Title::newFromText( $title ), $text, $query, $trail, $prefix , $aprops );
1412 } else {
1413 wfDebug( 'Invalid title passed to Skin::makeKnownLink(): "'.$title."\"\n" );
1414 return $text == '' ? $title : $text;
1418 function makeBrokenLink( $title, $text = '', $query = '', $trail = '' ) {
1419 $nt = Title::newFromText( $title );
1420 if ($nt) {
1421 return $this->makeBrokenLinkObj( Title::newFromText( $title ), $text, $query, $trail );
1422 } else {
1423 wfDebug( 'Invalid title passed to Skin::makeBrokenLink(): "'.$title."\"\n" );
1424 return $text == '' ? $title : $text;
1428 function makeStubLink( $title, $text = '', $query = '', $trail = '' ) {
1429 $nt = Title::newFromText( $title );
1430 if ($nt) {
1431 return $this->makeStubLinkObj( Title::newFromText( $title ), $text, $query, $trail );
1432 } else {
1433 wfDebug( 'Invalid title passed to Skin::makeStubLink(): "'.$title."\"\n" );
1434 return $text == '' ? $title : $text;
1438 # Pass a title object, not a title string
1439 function makeLinkObj( &$nt, $text= '', $query = '', $trail = '', $prefix = '' )
1441 global $wgOut, $wgUser;
1442 $fname = 'Skin::makeLinkObj';
1444 if ( $nt->isExternal() ) {
1445 $u = $nt->getFullURL();
1446 $link = $nt->getPrefixedURL();
1447 if ( '' == $text ) { $text = $nt->getPrefixedText(); }
1448 $style = $this->getExternalLinkAttributes( $link, $text, 'extiw' );
1450 $inside = '';
1451 if ( '' != $trail ) {
1452 if ( preg_match( '/^([a-z]+)(.*)$$/sD', $trail, $m ) ) {
1453 $inside = $m[1];
1454 $trail = $m[2];
1457 $retVal = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1458 } elseif ( 0 == $nt->getNamespace() && "" == $nt->getText() ) {
1459 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1460 } elseif ( ( -1 == $nt->getNamespace() ) ||
1461 ( Namespace::getImage() == $nt->getNamespace() ) ) {
1462 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1463 } else {
1464 $aid = $nt->getArticleID() ;
1465 if ( 0 == $aid ) {
1466 $retVal = $this->makeBrokenLinkObj( $nt, $text, $query, $trail, $prefix );
1467 } else {
1468 $threshold = $wgUser->getOption('stubthreshold') ;
1469 if ( $threshold > 0 ) {
1470 $s = $dbr->getArray( 'cur',
1471 array( 'LENGTH(cur_text) AS x', 'cur_namespace', 'cur_is_redirect' ),
1472 array( 'cur_id' => $aid ),
1473 $fname
1476 if ( $s !== false ) {
1477 $size = $s->x;
1478 if ( $s->cur_is_redirect OR $s->cur_namespace != 0 ) {
1479 $size = $threshold*2 ; # Really big
1481 } else {
1482 $size = $threshold*2 ; # Really big
1484 } else {
1485 $size = 1 ;
1487 if ( $size < $threshold ) {
1488 $retVal = $this->makeStubLinkObj( $nt, $text, $query, $trail, $prefix );
1489 } else {
1490 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1494 return $retVal;
1497 # Pass a title object, not a title string
1498 function makeKnownLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' , $aprops = '')
1500 global $wgOut, $wgTitle, $wgInputEncoding;
1502 $fname = 'Skin::makeKnownLinkObj';
1503 wfProfileIn( $fname );
1505 if ( !is_object( $nt ) ) {
1506 return $text;
1508 $link = $nt->getPrefixedURL();
1510 if ( '' == $link ) {
1511 $u = '';
1512 if ( '' == $text ) {
1513 $text = htmlspecialchars( $nt->getFragment() );
1515 } else {
1516 $u = $nt->escapeLocalURL( $query );
1518 if ( '' != $nt->getFragment() ) {
1519 $anchor = urlencode( do_html_entity_decode( str_replace(' ', '_', $nt->getFragment()), ENT_COMPAT, $wgInputEncoding ) );
1520 $replacearray = array(
1521 '%3A' => ':',
1522 '%' => '.'
1524 $u .= '#' . str_replace(array_keys($replacearray),array_values($replacearray),$anchor);
1526 if ( '' == $text ) {
1527 $text = htmlspecialchars( $nt->getPrefixedText() );
1529 $style = $this->getInternalLinkAttributesObj( $nt, $text );
1531 $inside = '';
1532 if ( '' != $trail ) {
1533 if ( preg_match( $this->linktrail, $trail, $m ) ) {
1534 $inside = $m[1];
1535 $trail = $m[2];
1538 $r = "<a href=\"{$u}\"{$style}{$aprops}>{$prefix}{$text}{$inside}</a>{$trail}";
1539 wfProfileOut( $fname );
1540 return $r;
1543 # Pass a title object, not a title string
1544 function makeBrokenLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
1546 global $wgOut, $wgUser;
1548 $fname = 'Skin::makeBrokenLinkObj';
1549 wfProfileIn( $fname );
1551 if ( '' == $query ) {
1552 $q = 'action=edit';
1553 } else {
1554 $q = 'action=edit&'.$query;
1556 $u = $nt->escapeLocalURL( $q );
1558 if ( '' == $text ) {
1559 $text = htmlspecialchars( $nt->getPrefixedText() );
1561 $style = $this->getInternalLinkAttributesObj( $nt, $text, "yes" );
1563 $inside = '';
1564 if ( '' != $trail ) {
1565 if ( preg_match( $this->linktrail, $trail, $m ) ) {
1566 $inside = $m[1];
1567 $trail = $m[2];
1570 if ( $wgUser->getOption( 'highlightbroken' ) ) {
1571 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1572 } else {
1573 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>?</a>{$trail}";
1576 wfProfileOut( $fname );
1577 return $s;
1580 # Pass a title object, not a title string
1581 function makeStubLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
1583 global $wgOut, $wgUser;
1585 $link = $nt->getPrefixedURL();
1587 $u = $nt->escapeLocalURL( $query );
1589 if ( '' == $text ) {
1590 $text = htmlspecialchars( $nt->getPrefixedText() );
1592 $style = $this->getInternalLinkAttributesObj( $nt, $text, 'stub' );
1594 $inside = '';
1595 if ( '' != $trail ) {
1596 if ( preg_match( $this->linktrail, $trail, $m ) ) {
1597 $inside = $m[1];
1598 $trail = $m[2];
1601 if ( $wgUser->getOption( 'highlightbroken' ) ) {
1602 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1603 } else {
1604 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>!</a>{$trail}";
1606 return $s;
1609 function makeSelfLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
1611 $u = $nt->escapeLocalURL( $query );
1612 if ( '' == $text ) {
1613 $text = htmlspecialchars( $nt->getPrefixedText() );
1615 $inside = '';
1616 if ( '' != $trail ) {
1617 if ( preg_match( $this->linktrail, $trail, $m ) ) {
1618 $inside = $m[1];
1619 $trail = $m[2];
1622 return "<strong>{$prefix}{$text}{$inside}</strong>{$trail}";
1625 /* these are used extensively in SkinPHPTal, but also some other places */
1626 /*static*/ function makeSpecialUrl( $name, $urlaction='' ) {
1627 $title = Title::makeTitle( NS_SPECIAL, $name );
1628 $this->checkTitle($title, $name);
1629 return $title->getLocalURL( $urlaction );
1631 /*static*/ function makeTalkUrl ( $name, $urlaction='' ) {
1632 $title = Title::newFromText( $name );
1633 $title = $title->getTalkPage();
1634 $this->checkTitle($title, $name);
1635 return $title->getLocalURL( $urlaction );
1637 /*static*/ function makeArticleUrl ( $name, $urlaction='' ) {
1638 $title = Title::newFromText( $name );
1639 $title= $title->getSubjectPage();
1640 $this->checkTitle($title, $name);
1641 return $title->getLocalURL( $urlaction );
1643 /*static*/ function makeI18nUrl ( $name, $urlaction='' ) {
1644 $title = Title::newFromText( wfMsg($name) );
1645 $this->checkTitle($title, $name);
1646 return $title->getLocalURL( $urlaction );
1648 /*static*/ function makeUrl ( $name, $urlaction='' ) {
1649 $title = Title::newFromText( $name );
1650 $this->checkTitle($title, $name);
1651 return $title->getLocalURL( $urlaction );
1653 # this can be passed the NS number as defined in Language.php
1654 /*static*/ function makeNSUrl( $name, $urlaction='', $namespace=0 ) {
1655 $title = Title::makeTitle( $namespace, $name );
1656 $this->checkTitle($title, $name);
1657 return $title->getLocalURL( $urlaction );
1660 /* these return an array with the 'href' and boolean 'exists' */
1661 /*static*/ function makeUrlDetails ( $name, $urlaction='' ) {
1662 $title = Title::newFromText( $name );
1663 $this->checkTitle($title, $name);
1664 return array(
1665 'href' => $title->getLocalURL( $urlaction ),
1666 'exists' => $title->getArticleID() != 0?true:false
1669 /*static*/ function makeTalkUrlDetails ( $name, $urlaction='' ) {
1670 $title = Title::newFromText( $name );
1671 $title = $title->getTalkPage();
1672 $this->checkTitle($title, $name);
1673 return array(
1674 'href' => $title->getLocalURL( $urlaction ),
1675 'exists' => $title->getArticleID() != 0?true:false
1678 /*static*/ function makeArticleUrlDetails ( $name, $urlaction='' ) {
1679 $title = Title::newFromText( $name );
1680 $title= $title->getSubjectPage();
1681 $this->checkTitle($title, $name);
1682 return array(
1683 'href' => $title->getLocalURL( $urlaction ),
1684 'exists' => $title->getArticleID() != 0?true:false
1687 /*static*/ function makeI18nUrlDetails ( $name, $urlaction='' ) {
1688 $title = Title::newFromText( wfMsg($name) );
1689 $this->checkTitle($title, $name);
1690 return array(
1691 'href' => $title->getLocalURL( $urlaction ),
1692 'exists' => $title->getArticleID() != 0?true:false
1696 # make sure we have some title to operate on
1697 /*static*/ function checkTitle ( &$title, &$name ) {
1698 if(!is_object($title)) {
1699 $title = Title::newFromText( $name );
1700 if(!is_object($title)) {
1701 $title = Title::newFromText( '--error: link target missing--' );
1706 function fnamePart( $url )
1708 $basename = strrchr( $url, '/' );
1709 if ( false === $basename ) { $basename = $url; }
1710 else { $basename = substr( $basename, 1 ); }
1711 return wfEscapeHTML( $basename );
1714 function makeImage( $url, $alt = '' )
1716 global $wgOut;
1718 if ( '' == $alt ) { $alt = $this->fnamePart( $url ); }
1719 $s = '<img src="'.$url.'" alt="'.$alt.'" />';
1720 return $s;
1723 function makeImageLink( $name, $url, $alt = '' ) {
1724 $nt = Title::makeTitle( Namespace::getImage(), $name );
1725 return $this->makeImageLinkObj( $nt, $alt );
1728 function makeImageLinkObj( $nt, $alt = '' ) {
1729 global $wgLang, $wgUseImageResize;
1730 $img = Image::newFromTitle( $nt );
1731 $url = $img->getURL();
1733 $align = '';
1734 $prefix = $postfix = '';
1736 if ( $wgUseImageResize ) {
1737 # Check if the alt text is of the form "options|alt text"
1738 # Options are:
1739 # * thumbnail make a thumbnail with enlarge-icon and caption, alignment depends on lang
1740 # * left no resizing, just left align. label is used for alt= only
1741 # * right same, but right aligned
1742 # * none same, but not aligned
1743 # * ___px scale to ___ pixels width, no aligning. e.g. use in taxobox
1744 # * center center the image
1745 # * framed Keep original image size, no magnify-button.
1747 $part = explode( '|', $alt);
1749 $mwThumb =& MagicWord::get( MAG_IMG_THUMBNAIL );
1750 $mwLeft =& MagicWord::get( MAG_IMG_LEFT );
1751 $mwRight =& MagicWord::get( MAG_IMG_RIGHT );
1752 $mwNone =& MagicWord::get( MAG_IMG_NONE );
1753 $mwWidth =& MagicWord::get( MAG_IMG_WIDTH );
1754 $mwCenter =& MagicWord::get( MAG_IMG_CENTER );
1755 $mwFramed =& MagicWord::get( MAG_IMG_FRAMED );
1756 $alt = $part[count($part)-1];
1758 $height = $framed = $thumb = false;
1759 $manual_thumb = "" ;
1761 foreach( $part as $key => $val ) {
1762 $val_parts = explode ( "=" , $val , 2 ) ;
1763 $left_part = array_shift ( $val_parts ) ;
1764 if ( ! is_null( $mwThumb->matchVariableStartToEnd($val) ) ) {
1765 $thumb=true;
1766 } elseif ( count ( $val_parts ) == 1 && ! is_null( $mwThumb->matchVariableStartToEnd($left_part) ) ) {
1767 # use manually specified thumbnail
1768 $thumb=true;
1769 $manual_thumb = array_shift ( $val_parts ) ;
1770 } elseif ( ! is_null( $mwRight->matchVariableStartToEnd($val) ) ) {
1771 # remember to set an alignment, don't render immediately
1772 $align = 'right';
1773 } elseif ( ! is_null( $mwLeft->matchVariableStartToEnd($val) ) ) {
1774 # remember to set an alignment, don't render immediately
1775 $align = 'left';
1776 } elseif ( ! is_null( $mwCenter->matchVariableStartToEnd($val) ) ) {
1777 # remember to set an alignment, don't render immediately
1778 $align = 'center';
1779 } elseif ( ! is_null( $mwNone->matchVariableStartToEnd($val) ) ) {
1780 # remember to set an alignment, don't render immediately
1781 $align = 'none';
1782 } elseif ( ! is_null( $match = $mwWidth->matchVariableStartToEnd($val) ) ) {
1783 # $match is the image width in pixels
1784 if ( preg_match( '/^([0-9]*)x([0-9]*)$/', $match, $m ) ) {
1785 $width = intval( $m[1] );
1786 $height = intval( $m[2] );
1787 } else {
1788 $width = intval($match);
1790 } elseif ( ! is_null( $mwFramed->matchVariableStartToEnd($val) ) ) {
1791 $framed=true;
1794 if ( 'center' == $align )
1796 $prefix = '<span style="text-align: center">';
1797 $postfix = '</span>';
1798 $align = 'none';
1801 if ( $thumb || $framed ) {
1803 # Create a thumbnail. Alignment depends on language
1804 # writing direction, # right aligned for left-to-right-
1805 # languages ("Western languages"), left-aligned
1806 # for right-to-left-languages ("Semitic languages")
1808 # If thumbnail width has not been provided, it is set
1809 # here to 180 pixels
1810 if ( $align == '' ) {
1811 $align = $wgLang->isRTL() ? 'left' : 'right';
1813 if ( ! isset($width) ) {
1814 $width = 180;
1816 return $prefix.$this->makeThumbLinkObj( $img, $alt, $align, $width, $height, $framed, $manual_thumb ).$postfix;
1818 } elseif ( isset($width) ) {
1820 # Create a resized image, without the additional thumbnail
1821 # features
1823 if ( ( ! $height === false )
1824 && ( $img->getHeight() * $width / $img->getWidth() > $height ) ) {
1825 print "height=$height<br>\nimg->getHeight() = ".$img->getHeight()."<br>\n";
1826 print 'rescaling by factor '. $height / $img->getHeight() . "<br>\n";
1827 $width = $img->getWidth() * $height / $img->getHeight();
1829 if ( '' == $manual_thumb ) $url = $img->createThumb( $width );
1831 } # endif $wgUseImageResize
1833 if ( empty( $alt ) ) {
1834 $alt = preg_replace( '/\.(.+?)^/', '', $img->getName() );
1836 $alt = htmlspecialchars( $alt );
1838 $u = $nt->escapeLocalURL();
1839 if ( $url == '' )
1841 $s = str_replace( "$1", $img->getName(), wfMsg('missingimage') );
1842 $s .= "<br>{$alt}<br>{$url}<br>\n";
1843 } else {
1844 $s = '<a href="'.$u.'" class="image" title="'.$alt.'">' .
1845 '<img src="'.$url.'" alt="'.$alt.'" /></a>';
1847 if ( '' != $align ) {
1848 $s = "<div class=\"float{$align}\"><span>{$s}</span></div>";
1850 return str_replace("\n", ' ',$prefix.$s.$postfix);
1854 function makeThumbLinkObj( $img, $label = '', $align = 'right', $boxwidth = 180, $boxheight=false, $framed=false , $manual_thumb = "" ) {
1855 global $wgStylePath, $wgLang;
1856 # $image = Title::makeTitle( Namespace::getImage(), $name );
1857 $url = $img->getURL();
1859 #$label = htmlspecialchars( $label );
1860 $alt = preg_replace( '/<[^>]*>/', '', $label);
1861 $alt = htmlspecialchars( $alt );
1863 if ( $img->exists() )
1865 $width = $img->getWidth();
1866 $height = $img->getHeight();
1867 } else {
1868 $width = $height = 200;
1870 if ( $framed )
1872 // Use image dimensions, don't scale
1873 $boxwidth = $width;
1874 $oboxwidth = $boxwidth + 2;
1875 $boxheight = $height;
1876 $thumbUrl = $url;
1877 } else {
1878 $h = intval( $height/($width/$boxwidth) );
1879 $oboxwidth = $boxwidth + 2;
1880 if ( ( ! $boxheight === false ) && ( $h > $boxheight ) )
1882 $boxwidth *= $boxheight/$h;
1883 } else {
1884 $boxheight = $h;
1886 if ( '' == $manual_thumb ) $thumbUrl = $img->createThumb( $boxwidth );
1889 if ( $manual_thumb != '' ) # Use manually specified thumbnail
1891 $manual_title = Title::makeTitle( Namespace::getImage(), $manual_thumb ); #new Title ( $manual_thumb ) ;
1892 $manual_img = Image::newFromTitle( $manual_title );
1893 $thumbUrl = $manual_img->getURL();
1894 if ( $manual_img->exists() )
1896 $width = $manual_img->getWidth();
1897 $height = $manual_img->getHeight();
1898 $boxwidth = $width ;
1899 $boxheight = $height ;
1900 $oboxwidth = $boxwidth + 2 ;
1904 $u = $img->getEscapeLocalURL();
1906 $more = htmlspecialchars( wfMsg( 'thumbnail-more' ) );
1907 $magnifyalign = $wgLang->isRTL() ? 'left' : 'right';
1908 $textalign = $wgLang->isRTL() ? ' style="text-align:right"' : '';
1910 $s = "<div class=\"thumb t{$align}\"><div style=\"width:{$oboxwidth}px;\">";
1911 if ( $thumbUrl == '' ) {
1912 $s .= str_replace( "$1", $img->getName(), wfMsg('missingimage') );
1913 $zoomicon = '';
1914 } else {
1915 $s .= '<a href="'.$u.'" class="internal" title="'.$alt.'">'.
1916 '<img src="'.$thumbUrl.'" alt="'.$alt.'" ' .
1917 'width="'.$boxwidth.'" height="'.$boxheight.'" /></a>';
1918 if ( $framed ) {
1919 $zoomicon="";
1920 } else {
1921 $zoomicon = '<div class="magnify" style="float:'.$magnifyalign.'">'.
1922 '<a href="'.$u.'" class="internal" title="'.$more.'">'.
1923 '<img src="'.$wgStylePath.'/images/magnify-clip.png" ' .
1924 'width="15" height="11" alt="'.$more.'" /></a></div>';
1927 $s .= ' <div class="thumbcaption" '.$textalign.'>'.$zoomicon.$label."</div></div></div>";
1928 return str_replace("\n", ' ', $s);
1931 function makeMediaLink( $name, $url, $alt = "" ) {
1932 $nt = Title::makeTitle( Namespace::getMedia(), $name );
1933 return $this->makeMediaLinkObj( $nt, $alt );
1936 function makeMediaLinkObj( $nt, $alt = "" )
1938 if ( ! isset( $nt ) )
1940 ### HOTFIX. Instead of breaking, return empry string.
1941 $s = $alt;
1942 } else {
1943 $name = $nt->getDBKey();
1944 $url = Image::wfImageUrl( $name );
1945 if ( empty( $alt ) ) {
1946 $alt = preg_replace( '/\.(.+?)^/', '', $name );
1949 $u = htmlspecialchars( $url );
1950 $s = "<a href=\"{$u}\" class='internal' title=\"{$alt}\">{$alt}</a>";
1952 return $s;
1955 function specialLink( $name, $key = "" )
1957 global $wgLang;
1959 if ( '' == $key ) { $key = strtolower( $name ); }
1960 $pn = $wgLang->ucfirst( $name );
1961 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1962 wfMsg( $key ) );
1965 function makeExternalLink( $url, $text, $escape = true ) {
1966 $style = $this->getExternalLinkAttributes( $url, $text );
1967 $url = htmlspecialchars( $url );
1968 if( $escape ) {
1969 $text = htmlspecialchars( $text );
1971 return '<a href="'.$url.'"'.$style.'>'.$text.'</a>';
1974 # Called by history lists and recent changes
1977 # Returns text for the start of the tabular part of RC
1978 function beginRecentChangesList()
1980 $this->rc_cache = array() ;
1981 $this->rcMoveIndex = 0;
1982 $this->rcCacheIndex = 0 ;
1983 $this->lastdate = '';
1984 $this->rclistOpen = false;
1985 return '';
1988 function beginImageHistoryList()
1990 $s = "\n<h2>" . wfMsg( 'imghistory' ) . "</h2>\n" .
1991 "<p>" . wfMsg( 'imghistlegend' ) . "</p>\n".'<ul class="special">';
1992 return $s;
1995 # Returns text for the end of RC
1996 # If enhanced RC is in use, returns pretty much all the text
1997 function endRecentChangesList()
1999 $s = $this->recentChangesBlock() ;
2000 if( $this->rclistOpen ) {
2001 $s .= "</ul>\n";
2003 return $s;
2006 # Enhanced RC ungrouped line
2007 function recentChangesBlockLine ( $rcObj )
2009 global $wgStylePath, $wgLang ;
2011 # Get rc_xxxx variables
2012 extract( $rcObj->mAttribs ) ;
2013 $curIdEq = 'curid='.$rc_cur_id;
2015 # Spacer image
2016 $r = '' ;
2018 $r .= '<img src="'.$wgStylePath.'/images/Arr_.png" width="12" height="12" border="0" />' ;
2019 $r .= '<tt>' ;
2021 if ( $rc_type == RC_MOVE || $rc_type == RC_MOVE_OVER_REDIRECT ) {
2022 $r .= '&nbsp;&nbsp;';
2023 } else {
2024 # M & N (minor & new)
2025 $M = wfMsg( 'minoreditletter' );
2026 $N = wfMsg( 'newpageletter' );
2028 if ( $rc_type == RC_NEW ) {
2029 $r .= $N ;
2030 } else {
2031 $r .= '&nbsp;' ;
2033 if ( $rc_minor ) {
2034 $r .= $M ;
2035 } else {
2036 $r .= '&nbsp;' ;
2040 # Timestamp
2041 $r .= ' '.$rcObj->timestamp.' ' ;
2042 $r .= '</tt>' ;
2044 # Article link
2045 $link = $rcObj->link ;
2046 if ( $rcObj->watched ) $link = '<strong>'.$link.'</strong>' ;
2047 $r .= $link ;
2049 # Diff
2050 $r .= ' (' ;
2051 $r .= $rcObj->difflink ;
2052 $r .= '; ' ;
2054 # Hist
2055 $r .= $this->makeKnownLinkObj( $rcObj->getTitle(), wfMsg( 'hist' ), $curIdEq.'&action=history' );
2057 # User/talk
2058 $r .= ') . . '.$rcObj->userlink ;
2059 $r .= $rcObj->usertalklink ;
2061 # Comment
2062 if ( $rc_comment != '' && $rc_type != RC_MOVE && $rc_type != RC_MOVE_OVER_REDIRECT ) {
2063 $rc_comment=$this->formatComment($rc_comment);
2064 $r .= $wgLang->emphasize( ' ('.$rc_comment.')' );
2067 $r .= "<br />\n" ;
2068 return $r ;
2071 # Enhanced RC group
2072 function recentChangesBlockGroup ( $block )
2074 global $wgStylePath, $wgLang ;
2076 $r = '' ;
2077 $M = wfMsg( 'minoreditletter' );
2078 $N = wfMsg( 'newpageletter' );
2080 # Collate list of users
2081 $isnew = false ;
2082 $userlinks = array () ;
2083 foreach ( $block AS $rcObj ) {
2084 $oldid = $rcObj->mAttribs['rc_last_oldid'];
2085 if ( $rcObj->mAttribs['rc_new'] ) $isnew = true ;
2086 $u = $rcObj->userlink ;
2087 if ( !isset ( $userlinks[$u] ) ) $userlinks[$u] = 0 ;
2088 $userlinks[$u]++ ;
2091 # Sort the list and convert to text
2092 krsort ( $userlinks ) ;
2093 asort ( $userlinks ) ;
2094 $users = array () ;
2095 foreach ( $userlinks as $userlink => $count) {
2096 $text = $userlink ;
2097 if ( $count > 1 ) $text .= " ({$count}&times;)" ;
2098 array_push ( $users , $text ) ;
2100 $users = ' <font size="-1">['.implode('; ',$users).']</font>' ;
2102 # Arrow
2103 $rci = 'RCI'.$this->rcCacheIndex ;
2104 $rcl = 'RCL'.$this->rcCacheIndex ;
2105 $rcm = 'RCM'.$this->rcCacheIndex ;
2106 $toggleLink = "javascript:toggleVisibility('$rci','$rcm','$rcl')" ;
2107 $arrowdir = $wgLang->isRTL() ? 'l' : 'r';
2108 $tl = '<span id="'.$rcm.'"><a href="'.$toggleLink.'"><img src="'.$wgStylePath.'/images/Arr_'.$arrowdir.'.png" width="12" height="12" /></a></span>' ;
2109 $tl .= '<span id="'.$rcl.'" style="display:none"><a href="'.$toggleLink.'"><img src="'.$wgStylePath.'/images/Arr_d.png" width="12" height="12" /></a></span>' ;
2110 $r .= $tl ;
2112 # Main line
2113 # M/N
2114 $r .= '<tt>' ;
2115 if ( $isnew ) $r .= $N ;
2116 else $r .= '&nbsp;' ;
2117 $r .= '&nbsp;' ; # Minor
2119 # Timestamp
2120 $r .= ' '.$block[0]->timestamp.' ' ;
2121 $r .= '</tt>' ;
2123 # Article link
2124 $link = $block[0]->link ;
2125 if ( $block[0]->watched ) $link = '<strong>'.$link.'</strong>' ;
2126 $r .= $link ;
2128 $curIdEq = 'curid=' . $block[0]->mAttribs['rc_cur_id'];
2129 if ( $block[0]->mAttribs['rc_type'] != RC_LOG ) {
2130 # Changes
2131 $r .= ' ('.count($block).' ' ;
2132 if ( $isnew ) $r .= wfMsg('changes');
2133 else $r .= $this->makeKnownLinkObj( $block[0]->getTitle() , wfMsg('changes') ,
2134 $curIdEq.'&diff=0&oldid='.$oldid ) ;
2135 $r .= '; ' ;
2137 # History
2138 $r .= $this->makeKnownLinkObj( $block[0]->getTitle(), wfMsg( 'history' ), $curIdEq.'&action=history' );
2139 $r .= ')' ;
2142 $r .= $users ;
2143 $r .= "<br />\n" ;
2145 # Sub-entries
2146 $r .= '<div id="'.$rci.'" style="display:none">' ;
2147 foreach ( $block AS $rcObj ) {
2148 # Get rc_xxxx variables
2149 extract( $rcObj->mAttribs );
2151 $r .= '<img src="'.$wgStylePath.'/images/Arr_.png" width="12" height="12" />';
2152 $r .= '<tt>&nbsp; &nbsp; &nbsp; &nbsp;' ;
2153 if ( $rc_new ) $r .= $N ;
2154 else $r .= '&nbsp;' ;
2155 if ( $rc_minor ) $r .= $M ;
2156 else $r .= '&nbsp;' ;
2157 $r .= '</tt>' ;
2159 $o = '' ;
2160 if ( $rc_last_oldid != 0 ) {
2161 $o = 'oldid='.$rc_last_oldid ;
2163 if ( $rc_type == RC_LOG ) {
2164 $link = $rcObj->timestamp ;
2165 } else {
2166 $link = $this->makeKnownLinkObj( $rcObj->getTitle(), $rcObj->timestamp , "{$curIdEq}&$o" ) ;
2168 $link = '<tt>'.$link.'</tt>' ;
2170 $r .= $link ;
2171 $r .= ' (' ;
2172 $r .= $rcObj->curlink ;
2173 $r .= '; ' ;
2174 $r .= $rcObj->lastlink ;
2175 $r .= ') . . '.$rcObj->userlink ;
2176 $r .= $rcObj->usertalklink ;
2177 if ( $rc_comment != '' ) {
2178 $rc_comment=$this->formatComment($rc_comment);
2179 $r .= $wgLang->emphasize( ' ('.$rc_comment.')' ) ;
2181 $r .= "<br />\n" ;
2183 $r .= "</div>\n" ;
2185 $this->rcCacheIndex++ ;
2186 return $r ;
2189 # If enhanced RC is in use, this function takes the previously cached
2190 # RC lines, arranges them, and outputs the HTML
2191 function recentChangesBlock ()
2193 global $wgStylePath ;
2194 if ( count ( $this->rc_cache ) == 0 ) return '' ;
2195 $blockOut = '';
2196 foreach ( $this->rc_cache AS $secureName => $block ) {
2197 if ( count ( $block ) < 2 ) {
2198 $blockOut .= $this->recentChangesBlockLine ( array_shift ( $block ) ) ;
2199 } else {
2200 $blockOut .= $this->recentChangesBlockGroup ( $block ) ;
2204 return '<div>'.$blockOut.'</div>' ;
2207 # Called in a loop over all displayed RC entries
2208 # Either returns the line, or caches it for later use
2209 function recentChangesLine( &$rc, $watched = false )
2211 global $wgUser ;
2212 $usenew = $wgUser->getOption( 'usenewrc' );
2213 if ( $usenew )
2214 $line = $this->recentChangesLineNew ( $rc, $watched ) ;
2215 else
2216 $line = $this->recentChangesLineOld ( $rc, $watched ) ;
2217 return $line ;
2220 function recentChangesLineOld( &$rc, $watched = false )
2222 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds;
2224 # Extract DB fields into local scope
2225 extract( $rc->mAttribs );
2226 $curIdEq = 'curid=' . $rc_cur_id;
2228 # Make date header if necessary
2229 $date = $wgLang->date( $rc_timestamp, true);
2230 $s = '';
2231 if ( $date != $this->lastdate ) {
2232 if ( '' != $this->lastdate ) { $s .= "</ul>\n"; }
2233 $s .= "<h4>{$date}</h4>\n<ul class='special'>";
2234 $this->lastdate = $date;
2235 $this->rclistOpen = true;
2237 $s .= '<li> ';
2239 if ( $rc_type == RC_MOVE || $rc_type == RC_MOVE_OVER_REDIRECT ) {
2240 # Diff
2241 $s .= '(' . wfMsg( 'diff' ) . ') (';
2242 # Hist
2243 $s .= $this->makeKnownLinkObj( $rc->getMovedToTitle(), wfMsg( 'hist' ), 'action=history' ) .
2244 ') . . ';
2246 # "[[x]] moved to [[y]]"
2247 if ( $rc_type == RC_MOVE ) {
2248 $msg = '1movedto2';
2249 } else {
2250 $msg = '1movedto2_redir';
2252 $s .= wfMsg( $msg, $this->makeKnownLinkObj( $rc->getTitle(), '', 'redirect=no' ),
2253 $this->makeKnownLinkObj( $rc->getMovedToTitle(), '' ) );
2254 } else {
2255 # Diff link
2256 if ( $rc_type == RC_NEW || $rc_type == RC_LOG ) {
2257 $diffLink = wfMsg( 'diff' );
2258 } else {
2259 $diffLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'diff' ),
2260 $curIdEq.'&diff='.$rc_this_oldid.'&oldid='.$rc_last_oldid ,'' ,'' , ' tabindex="'.$rc->counter.'"');
2262 $s .= '('.$diffLink.') (';
2264 # History link
2265 $s .= $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'hist' ), $curIdEq.'&action=history' );
2266 $s .= ') . . ';
2268 # M and N (minor and new)
2269 $M = wfMsg( 'minoreditletter' );
2270 $N = wfMsg( 'newpageletter' );
2271 if ( $rc_minor ) { $s .= ' <strong>'.$M.'</strong>'; }
2272 if ( $rc_type == RC_NEW ) { $s .= '<strong>'.$N.'</strong>'; }
2274 # Article link
2275 $articleLink = $this->makeKnownLinkObj( $rc->getTitle(), '' );
2277 if ( $watched ) {
2278 $articleLink = '<strong>'.$articleLink.'</strong>';
2280 $s .= ' '.$articleLink;
2284 # Timestamp
2285 $s .= '; ' . $wgLang->time( $rc_timestamp, true, $wgRCSeconds ) . ' . . ';
2287 # User link (or contributions for unregistered users)
2288 if ( 0 == $rc_user ) {
2289 $userLink = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
2290 $rc_user_text, 'target=' . $rc_user_text );
2291 } else {
2292 $userLink = $this->makeLink( $wgLang->getNsText( NS_USER ) . ':'.$rc_user_text, $rc_user_text );
2294 $s .= $userLink;
2296 # User talk link
2297 $talkname=$wgLang->getNsText(NS_TALK); # use the shorter name
2298 global $wgDisableAnonTalk;
2299 if( 0 == $rc_user && $wgDisableAnonTalk ) {
2300 $userTalkLink = '';
2301 } else {
2302 $utns=$wgLang->getNsText(NS_USER_TALK);
2303 $userTalkLink= $this->makeLink($utns . ':'.$rc_user_text, $talkname );
2305 # Block link
2306 $blockLink='';
2307 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2308 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2309 'Blockip' ), wfMsg( 'blocklink' ), 'ip='.$rc_user_text );
2312 if($blockLink) {
2313 if($userTalkLink) $userTalkLink .= ' | ';
2314 $userTalkLink .= $blockLink;
2316 if($userTalkLink) $s.=' ('.$userTalkLink.')';
2318 # Add comment
2319 if ( '' != $rc_comment && '*' != $rc_comment && $rc_type != RC_MOVE && $rc_type != RC_MOVE_OVER_REDIRECT ) {
2320 $rc_comment=$this->formatComment($rc_comment);
2321 $s .= $wgLang->emphasize(' (' . $rc_comment . ')');
2323 $s .= "</li>\n";
2325 return $s;
2328 # function recentChangesLineNew( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched = false, $oldid = 0 , $diffid = 0 )
2329 function recentChangesLineNew( &$baseRC, $watched = false )
2331 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds;
2333 # Create a specialised object
2334 $rc = RCCacheEntry::newFromParent( $baseRC ) ;
2336 # Extract fields from DB into the function scope (rc_xxxx variables)
2337 extract( $rc->mAttribs );
2338 $curIdEq = 'curid=' . $rc_cur_id;
2340 # If it's a new day, add the headline and flush the cache
2341 $date = $wgLang->date( $rc_timestamp, true);
2342 $ret = '' ;
2343 if ( $date != $this->lastdate ) {
2344 # Process current cache
2345 $ret = $this->recentChangesBlock () ;
2346 $this->rc_cache = array() ;
2347 $ret .= "<h4>{$date}</h4>\n";
2348 $this->lastdate = $date;
2351 # Make article link
2352 if ( $rc_type == RC_MOVE || $rc_type == RC_MOVE_OVER_REDIRECT ) {
2353 if ( $rc_type == RC_MOVE ) {
2354 $msg = "1movedto2";
2355 } else {
2356 $msg = "1movedto2_redir";
2358 $clink = wfMsg( $msg, $this->makeKnownLinkObj( $rc->getTitle(), '', 'redirect=no' ),
2359 $this->makeKnownLinkObj( $rc->getMovedToTitle(), '' ) );
2360 } else {
2361 $clink = $this->makeKnownLinkObj( $rc->getTitle(), '' ) ;
2364 $time = $wgLang->time( $rc_timestamp, true, $wgRCSeconds );
2365 $rc->watched = $watched ;
2366 $rc->link = $clink ;
2367 $rc->timestamp = $time;
2369 # Make "cur" and "diff" links
2370 if ( ( $rc_type == RC_NEW && $rc_this_oldid == 0 ) || $rc_type == RC_LOG || $rc_type == RC_MOVE || $rc_type == RC_MOVE_OVER_REDIRECT ) {
2371 $curLink = wfMsg( 'cur' );
2372 $diffLink = wfMsg( 'diff' );
2373 } else {
2374 $query = $curIdEq.'&diff=0&oldid='.$rc_this_oldid;
2375 $aprops = ' tabindex="'.$baseRC->counter.'"';
2376 $curLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'cur' ), $query, '' ,'' , $aprops );
2377 $diffLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'diff'), $query, '' ,'' , $aprops );
2380 # Make "last" link
2381 $titleObj = $rc->getTitle();
2382 if ( $rc_last_oldid == 0 || $rc_type == RC_LOG || $rc_type == RC_MOVE || $rc_type == RC_MOVE_OVER_REDIRECT ) {
2383 $lastLink = wfMsg( 'last' );
2384 } else {
2385 $lastLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'last' ),
2386 $curIdEq.'&diff='.$rc_this_oldid.'&oldid='.$rc_last_oldid );
2389 # Make user link (or user contributions for unregistered users)
2390 if ( 0 == $rc_user ) {
2391 $userLink = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
2392 $rc_user_text, 'target=' . $rc_user_text );
2393 } else {
2394 $userLink = $this->makeLink( $wgLang->getNsText(
2395 Namespace::getUser() ) . ':'.$rc_user_text, $rc_user_text );
2398 $rc->userlink = $userLink ;
2399 $rc->lastlink = $lastLink ;
2400 $rc->curlink = $curLink ;
2401 $rc->difflink = $diffLink;
2404 # Make user talk link
2405 $utns=$wgLang->getNsText(NS_USER_TALK);
2406 $talkname=$wgLang->getNsText(NS_TALK); # use the shorter name
2407 $userTalkLink= $this->makeLink($utns . ':'.$rc_user_text, $talkname );
2409 global $wgDisableAnonTalk;
2410 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2411 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2412 'Blockip' ), wfMsg( 'blocklink' ), 'ip='.$rc_user_text );
2413 if( $wgDisableAnonTalk )
2414 $rc->usertalklink = ' ('.$blockLink.')';
2415 else
2416 $rc->usertalklink = ' ('.$userTalkLink.' | '.$blockLink.')';
2417 } else {
2418 if( $wgDisableAnonTalk && ($rc_user == 0) )
2419 $rc->usertalklink = '';
2420 else
2421 $rc->usertalklink = ' ('.$userTalkLink.')';
2424 # Put accumulated information into the cache, for later display
2425 # Page moves go on their own line
2426 $title = $rc->getTitle();
2427 $secureName = $title->getPrefixedDBkey();
2428 if ( $rc_type == RC_MOVE || $rc_type == RC_MOVE_OVER_REDIRECT ) {
2429 # Use an @ character to prevent collision with page names
2430 $this->rc_cache['@@' . ($this->rcMoveIndex++)] = array($rc);
2431 } else {
2432 if ( !isset ( $this->rc_cache[$secureName] ) ) $this->rc_cache[$secureName] = array() ;
2433 array_push ( $this->rc_cache[$secureName] , $rc ) ;
2435 return $ret;
2438 function endImageHistoryList()
2440 $s = "</ul>\n";
2441 return $s;
2444 /* This function is called by all recent changes variants, by the page history,
2445 and by the user contributions list. It is responsible for formatting edit
2446 comments. It escapes any HTML in the comment, but adds some CSS to format
2447 auto-generated comments (from section editing) and formats [[wikilinks]].
2448 Main author: Erik Möller (moeller@scireview.de)
2450 function formatComment($comment)
2452 global $wgLang;
2453 $comment=wfEscapeHTML($comment);
2455 # The pattern for autogen comments is / * foo * /, which makes for
2456 # some nasty regex.
2457 # We look for all comments, match any text before and after the comment,
2458 # add a separator where needed and format the comment itself with CSS
2459 while (preg_match('/(.*)\/\*\s*(.*?)\s*\*\/(.*)/', $comment,$match)) {
2460 $pre=$match[1];
2461 $auto=$match[2];
2462 $post=$match[3];
2463 $sep='-';
2464 if($pre) { $auto = $sep.' '.$auto; }
2465 if($post) { $auto .= ' '.$sep; }
2466 $auto='<span class="autocomment">'.$auto.'</span>';
2467 $comment=$pre.$auto.$post;
2470 # format regular and media links - all other wiki formatting
2471 # is ignored
2472 while(preg_match('/\[\[(.*?)(\|(.*?))*\]\]/',$comment,$match)) {
2474 $medians = $wgLang->getNsText(Namespace::getMedia()).':';
2475 $func='makeLink';
2476 if(preg_match('/^'.$medians.'/i',$match[1])) {
2477 $func='makeMediaLink';
2479 # Handle link renaming [[foo|text]] will show link as "text"
2480 if(isset($match[3]) ) {
2481 $comment=
2482 preg_replace('/\[\[(.*?)\]\]/',
2483 $this->$func($match[1],$match[3]),$comment,1);
2484 } else {
2485 $comment=
2486 preg_replace('/\[\[(.*?)\]\]/',
2487 $this->$func($match[1],$match[1]),$comment,1);
2491 return $comment;
2495 function imageHistoryLine( $iscur, $timestamp, $img, $user, $usertext, $size, $description )
2497 global $wgUser, $wgLang, $wgTitle;
2499 $datetime = $wgLang->timeanddate( $timestamp, true );
2500 $del = wfMsg( 'deleteimg' );
2501 $cur = wfMsg( 'cur' );
2503 if ( $iscur ) {
2504 $url = Image::wfImageUrl( $img );
2505 $rlink = $cur;
2506 if ( $wgUser->isSysop() ) {
2507 $link = $wgTitle->escapeLocalURL( 'image=' . $wgTitle->getPartialURL() .
2508 '&action=delete' );
2509 $style = $this->getInternalLinkAttributes( $link, $del );
2511 $dlink = '<a href="'.$link.'"'.$style.'>'.$del.'</a>';
2512 } else {
2513 $dlink = $del;
2515 } else {
2516 $url = wfEscapeHTML( wfImageArchiveUrl( $img ) );
2517 if( $wgUser->getID() != 0 ) {
2518 $rlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2519 wfMsg( 'revertimg' ), 'action=revert&oldimage=' .
2520 urlencode( $img ) );
2521 $dlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2522 $del, 'action=delete&oldimage=' . urlencode( $img ) );
2523 } else {
2524 # Having live active links for non-logged in users
2525 # means that bots and spiders crawling our site can
2526 # inadvertently change content. Baaaad idea.
2527 $rlink = wfMsg( 'revertimg' );
2528 $dlink = $del;
2531 if ( 0 == $user ) {
2532 $userlink = $usertext;
2533 } else {
2534 $userlink = $this->makeLink( $wgLang->getNsText( Namespace::getUser() ) .
2535 ':'.$usertext, $usertext );
2537 $nbytes = wfMsg( 'nbytes', $size );
2538 $style = $this->getInternalLinkAttributes( $url, $datetime );
2540 $s = "<li> ({$dlink}) ({$rlink}) <a href=\"{$url}\"{$style}>{$datetime}</a>"
2541 . " . . {$userlink} ({$nbytes})";
2543 if ( '' != $description && '*' != $description ) {
2544 $sk=$wgUser->getSkin();
2545 $s .= $wgLang->emphasize(' (' . $sk->formatComment($description) . ')');
2547 $s .= "</li>\n";
2548 return $s;
2551 function tocIndent($level) {
2552 return str_repeat( '<div class="tocindent">'."\n", $level>0 ? $level : 0 );
2555 function tocUnindent($level) {
2556 return str_repeat( "</div>\n", $level>0 ? $level : 0 );
2559 # parameter level defines if we are on an indentation level
2560 function tocLine( $anchor, $tocline, $level ) {
2561 $link = '<a href="#'.$anchor.'">'.$tocline.'</a><br />';
2562 if($level) {
2563 return $link."\n";
2564 } else {
2565 return '<div class="tocline">'.$link."</div>\n";
2570 function tocTable($toc) {
2571 # note to CSS fanatics: putting this in a div does not work -- div won't auto-expand
2572 # try min-width & co when somebody gets a chance
2573 $hideline = ' <script type="text/javascript">showTocToggle("' . addslashes( wfMsg('showtoc') ) . '","' . addslashes( wfMsg('hidetoc') ) . '")</script>';
2574 return
2575 '<table border="0" id="toc"><tr id="toctitle"><td align="center">'."\n".
2576 '<b>'.wfMsg('toc').'</b>' .
2577 $hideline .
2578 '</td></tr><tr id="tocinside"><td>'."\n".
2579 $toc."</td></tr></table>\n";
2582 # These two do not check for permissions: check $wgTitle->userCanEdit before calling them
2583 function editSectionScript( $section, $head ) {
2584 global $wgTitle, $wgRequest;
2585 if( $wgRequest->getInt( 'oldid' ) && ( $wgRequest->getVal( 'diff' ) != '0' ) ) {
2586 return $head;
2588 $url = $wgTitle->escapeLocalURL( 'action=edit&section='.$section );
2589 return '<span oncontextmenu=\'document.location="'.$url.'";return false;\'>'.$head.'</span>';
2592 function editSectionLink( $section ) {
2593 global $wgRequest;
2594 global $wgTitle, $wgUser, $wgLang;
2596 if( $wgRequest->getInt( 'oldid' ) && ( $wgRequest->getVal( 'diff' ) != '0' ) ) {
2597 # Section edit links would be out of sync on an old page.
2598 # But, if we're diffing to the current page, they'll be
2599 # correct.
2600 return '';
2603 $editurl = '&section='.$section;
2604 $url = $this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg('editsection'),'action=edit'.$editurl);
2606 if( $wgLang->isRTL() ) {
2607 $farside = 'left';
2608 $nearside = 'right';
2609 } else {
2610 $farside = 'right';
2611 $nearside = 'left';
2613 return "<div class=\"editsection\" style=\"float:$farside;margin-$nearside:5px;\">[".$url."]</div>";
2617 // This function is called by EditPage.php and shows a bulletin board style
2618 // toolbar for common editing functions. It can be disabled in the user preferences.
2619 // The necsesary JavaScript code can be found in style/wikibits.js.
2620 function getEditToolbar() {
2621 global $wgStylePath, $wgLang, $wgMimeType;
2623 // toolarray an array of arrays which each include the filename of
2624 // the button image (without path), the opening tag, the closing tag,
2625 // and optionally a sample text that is inserted between the two when no
2626 // selection is highlighted.
2627 // The tip text is shown when the user moves the mouse over the button.
2629 // Already here are accesskeys (key), which are not used yet until someone
2630 // can figure out a way to make them work in IE. However, we should make
2631 // sure these keys are not defined on the edit page.
2632 $toolarray=array(
2633 array( 'image'=>'button_bold.png',
2634 'open'=>"\'\'\'",
2635 'close'=>"\'\'\'",
2636 'sample'=>wfMsg('bold_sample'),
2637 'tip'=>wfMsg('bold_tip'),
2638 'key'=>'B'
2640 array( "image"=>"button_italic.png",
2641 "open"=>"\'\'",
2642 "close"=>"\'\'",
2643 "sample"=>wfMsg("italic_sample"),
2644 "tip"=>wfMsg("italic_tip"),
2645 "key"=>"I"
2647 array( "image"=>"button_link.png",
2648 "open"=>"[[",
2649 "close"=>"]]",
2650 "sample"=>wfMsg("link_sample"),
2651 "tip"=>wfMsg("link_tip"),
2652 "key"=>"L"
2654 array( "image"=>"button_extlink.png",
2655 "open"=>"[",
2656 "close"=>"]",
2657 "sample"=>wfMsg("extlink_sample"),
2658 "tip"=>wfMsg("extlink_tip"),
2659 "key"=>"X"
2661 array( "image"=>"button_headline.png",
2662 "open"=>"\\n== ",
2663 "close"=>" ==\\n",
2664 "sample"=>wfMsg("headline_sample"),
2665 "tip"=>wfMsg("headline_tip"),
2666 "key"=>"H"
2668 array( "image"=>"button_image.png",
2669 "open"=>"[[".$wgLang->getNsText(NS_IMAGE).":",
2670 "close"=>"]]",
2671 "sample"=>wfMsg("image_sample"),
2672 "tip"=>wfMsg("image_tip"),
2673 "key"=>"D"
2675 array( "image"=>"button_media.png",
2676 "open"=>"[[".$wgLang->getNsText(NS_MEDIA).":",
2677 "close"=>"]]",
2678 "sample"=>wfMsg("media_sample"),
2679 "tip"=>wfMsg("media_tip"),
2680 "key"=>"M"
2682 array( "image"=>"button_math.png",
2683 "open"=>"\\<math\\>",
2684 "close"=>"\\</math\\>",
2685 "sample"=>wfMsg("math_sample"),
2686 "tip"=>wfMsg("math_tip"),
2687 "key"=>"C"
2689 array( "image"=>"button_nowiki.png",
2690 "open"=>"\\<nowiki\\>",
2691 "close"=>"\\</nowiki\\>",
2692 "sample"=>wfMsg("nowiki_sample"),
2693 "tip"=>wfMsg("nowiki_tip"),
2694 "key"=>"N"
2696 array( "image"=>"button_sig.png",
2697 "open"=>"--~~~~",
2698 "close"=>"",
2699 "sample"=>"",
2700 "tip"=>wfMsg("sig_tip"),
2701 "key"=>"Y"
2703 array( "image"=>"button_hr.png",
2704 "open"=>"\\n----\\n",
2705 "close"=>"",
2706 "sample"=>"",
2707 "tip"=>wfMsg("hr_tip"),
2708 "key"=>"R"
2711 $toolbar ="<script type='text/javascript'>\n/*<![CDATA[*/\n";
2713 $toolbar.="document.writeln(\"<div id='toolbar'>\");\n";
2714 foreach($toolarray as $tool) {
2716 $image=$wgStylePath.'/images/'.$tool['image'];
2717 $open=$tool['open'];
2718 $close=$tool['close'];
2719 $sample = addslashes( $tool['sample'] );
2721 // Note that we use the tip both for the ALT tag and the TITLE tag of the image.
2722 // Older browsers show a "speedtip" type message only for ALT.
2723 // Ideally these should be different, realistically they
2724 // probably don't need to be.
2725 $tip = addslashes( $tool['tip'] );
2727 #$key = $tool["key"];
2729 $toolbar.="addButton('$image','$tip','$open','$close','$sample');\n";
2732 $toolbar.="addInfobox('" . addslashes( wfMsg( "infobox" ) ) . "','" . addslashes(wfMsg("infobox_alert")) . "');\n";
2733 $toolbar.="document.writeln(\"</div>\");\n";
2735 $toolbar.="/*]]>*/\n</script>";
2736 return $toolbar;