Make Math rendering options user settable strings in MediaWiki namespace. First batch.
[mediawiki.git] / includes / Skin.php
blobab40ff88e04507d451e34d6ccc3965221e507fab
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, $wgSiteNotice;
322 if( $wgSiteNotice ) {
323 $note = "\n<div id='siteNotice'>$wgSiteNotice</div>\n";
324 } else {
325 $note = '';
327 return $this->doBeforeContent() . $note;
330 function doBeforeContent()
332 global $wgUser, $wgOut, $wgTitle, $wgLang;
333 $fname = 'Skin::doBeforeContent';
334 wfProfileIn( $fname );
336 $s = '';
337 $qb = $this->qbSetting();
339 if( $langlinks = $this->otherLanguages() ) {
340 $rows = 2;
341 $borderhack = '';
342 } else {
343 $rows = 1;
344 $langlinks = false;
345 $borderhack = 'class="top"';
348 $s .= "\n<div id='content'>\n<div id='topbar'>\n" .
349 "<table border='0' cellspacing='0' width='98%'>\n<tr>\n";
351 $shove = ($qb != 0);
352 $left = ($qb == 1 || $qb == 3);
353 if($wgLang->isRTL()) $left = !$left;
355 if ( !$shove ) {
356 $s .= "<td class='top' align='left' valign='top' rowspan='{$rows}'>\n" .
357 $this->logoText() . '</td>';
358 } elseif( $left ) {
359 $s .= $this->getQuickbarCompensator( $rows );
361 $l = $wgLang->isRTL() ? 'right' : 'left';
362 $s .= "<td {$borderhack} align='$l' valign='top'>\n";
364 $s .= $this->topLinks() ;
365 $s .= "<p class='subtitle'>" . $this->pageTitleLinks() . "</p>\n";
367 $r = $wgLang->isRTL() ? "left" : "right";
368 $s .= "</td>\n<td {$borderhack} valign='top' align='$r' nowrap='nowrap'>";
369 $s .= $this->nameAndLogin();
370 $s .= "\n<br />" . $this->searchForm() . "</td>";
372 if ( $langlinks ) {
373 $s .= "</tr>\n<tr>\n<td class='top' colspan=\"2\">$langlinks</td>\n";
376 if ( $shove && !$left ) { # Right
377 $s .= $this->getQuickbarCompensator( $rows );
379 $s .= "</tr>\n</table>\n</div>\n";
380 $s .= "\n<div id='article'>\n";
382 $s .= $this->pageTitle();
383 $s .= $this->pageSubtitle() ;
384 $s .= $this->getCategories();
385 wfProfileOut( $fname );
386 return $s;
389 function getCategoryLinks () {
390 global $wgOut, $wgTitle, $wgUser, $wgParser;
391 global $wgUseCategoryMagic, $wgUseCategoryBrowser, $wgLang;
393 if( !$wgUseCategoryMagic ) return '' ;
394 if( count( $wgOut->mCategoryLinks ) == 0 ) return '';
396 # Taken out so that they will be displayed in previews -- TS
397 #if( !$wgOut->isArticle() ) return '';
399 $t = implode ( ' | ' , $wgOut->mCategoryLinks ) ;
400 $s = $this->makeKnownLink( 'Special:Categories',
401 wfMsg( 'categories' ), 'article=' . urlencode( $wgTitle->getPrefixedDBkey() ) )
402 . ': ' . $t;
404 if($wgUseCategoryBrowser) {
405 $s .= '<br/><hr/>';
406 $catstack = array();
407 $s.= $wgTitle->getAllParentCategories($catstack);
410 return $s;
413 function getCategories() {
414 $catlinks=$this->getCategoryLinks();
415 if(!empty($catlinks)) {
416 return "<p class='catlinks'>{$catlinks}</p>";
420 function getQuickbarCompensator( $rows = 1 )
422 return "<td width='152' rowspan='{$rows}'>&nbsp;</td>";
425 # This gets called immediately before the </body> tag.
427 function afterContent()
429 global $wgUser, $wgOut, $wgServer;
430 global $wgTitle, $wgLang;
432 $printfooter = "<div class=\"printfooter\">\n" . $this->printFooter() . "</div>\n";
433 return $printfooter . $this->doAfterContent();
436 function printFooter() {
437 global $wgTitle;
438 $url = htmlspecialchars( $wgTitle->getFullURL() );
439 return "<p>" . wfMsg( "retrievedfrom", "<a href=\"$url\">$url</a>" ) .
440 "</p>\n\n<p>" . $this->pageStats() . "</p>\n";
443 function doAfterContent()
445 global $wgUser, $wgOut, $wgLang;
446 $fname = 'Skin::doAfterContent';
447 wfProfileIn( $fname );
448 wfProfileIn( $fname.'-1' );
450 $s = "\n</div><br style=\"clear:both\" />\n";
451 $s .= "\n<div id='footer'>";
452 $s .= '<table border="0" cellspacing="0"><tr>';
454 wfProfileOut( $fname.'-1' );
455 wfProfileIn( $fname.'-2' );
457 $qb = $this->qbSetting();
458 $shove = ($qb != 0);
459 $left = ($qb == 1 || $qb == 3);
460 if($wgLang->isRTL()) $left = !$left;
462 if ( $shove && $left ) { # Left
463 $s .= $this->getQuickbarCompensator();
465 wfProfileOut( $fname.'-2' );
466 wfProfileIn( $fname.'-3' );
467 $l = $wgLang->isRTL() ? 'right' : 'left';
468 $s .= "<td class='bottom' align='$l' valign='top'>";
470 $s .= $this->bottomLinks();
471 $s .= "\n<br />" . $this->mainPageLink()
472 . ' | ' . $this->aboutLink()
473 . ' | ' . $this->specialLink( 'recentchanges' )
474 . ' | ' . $this->searchForm()
475 . '<br /><span id="pagestats">' . $this->pageStats() . '</span>';
477 $s .= "</td>";
478 if ( $shove && !$left ) { # Right
479 $s .= $this->getQuickbarCompensator();
481 $s .= "</tr></table>\n</div>\n</div>\n";
483 wfProfileOut( $fname.'-3' );
484 wfProfileIn( $fname.'-4' );
485 if ( 0 != $qb ) { $s .= $this->quickBar(); }
486 wfProfileOut( $fname.'-4' );
487 wfProfileOut( $fname );
488 return $s;
491 function pageTitleLinks()
493 global $wgOut, $wgTitle, $wgUser, $wgLang, $wgUseApproval, $wgRequest;
495 extract( $wgRequest->getValues( 'oldid', 'diff' ) );
496 $action = $wgRequest->getText( 'action' );
498 $s = $this->printableLink();
499 if ( wfMsg ( 'disclaimers' ) != '-' ) $s .= ' | ' . $this->makeKnownLink( wfMsg( 'disclaimerpage' ), wfMsg( 'disclaimers' ) ) ;
501 if ( $wgOut->isArticleRelated() ) {
502 if ( $wgTitle->getNamespace() == Namespace::getImage() ) {
503 $name = $wgTitle->getDBkey();
504 $link = wfEscapeHTML( Image::wfImageUrl( $name ) );
505 $style = $this->getInternalLinkAttributes( $link, $name );
506 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>";
508 # This will show the "Approve" link if $wgUseApproval=true;
509 if ( isset ( $wgUseApproval ) && $wgUseApproval )
511 $t = $wgTitle->getDBkey();
512 $name = 'Approve this article' ;
513 $link = "http://test.wikipedia.org/w/magnus/wiki.phtml?title={$t}&action=submit&doit=1" ;
514 #wfEscapeHTML( wfImageUrl( $name ) );
515 $style = $this->getExternalLinkAttributes( $link, $name );
516 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>" ;
519 if ( 'history' == $action || isset( $diff ) || isset( $oldid ) ) {
520 $s .= ' | ' . $this->makeKnownLink( $wgTitle->getPrefixedText(),
521 wfMsg( 'currentrev' ) );
524 if ( $wgUser->getNewtalk() ) {
525 # do not show "You have new messages" text when we are viewing our
526 # own talk page
528 if(!(strcmp($wgTitle->getText(),$wgUser->getName()) == 0 &&
529 $wgTitle->getNamespace()==Namespace::getTalk(Namespace::getUser()))) {
530 $n =$wgUser->getName();
531 $tl = $this->makeKnownLink( $wgLang->getNsText(
532 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
533 wfMsg('newmessageslink') );
534 $s.= ' | <strong>'. wfMsg( 'newmessages', $tl ) . '</strong>';
538 $undelete = $this->getUndeleteLink();
539 if( !empty( $undelete ) ) {
540 $s .= ' | '.$undelete;
542 return $s;
545 function getUndeleteLink() {
546 global $wgUser, $wgTitle, $wgLang, $action;
547 if( $wgUser->isSysop() &&
548 (($wgTitle->getArticleId() == 0) || ($action == "history")) &&
549 ($n = $wgTitle->isDeleted() ) ) {
550 return wfMsg( 'thisisdeleted',
551 $this->makeKnownLink(
552 $wgLang->SpecialPage( 'Undelete/' . $wgTitle->getPrefixedDBkey() ),
553 wfMsg( 'restorelink', $n ) ) );
555 return '';
558 function printableLink()
560 global $wgOut, $wgFeedClasses, $wgRequest;
562 $baseurl = $_SERVER['REQUEST_URI'];
563 if( strpos( '?', $baseurl ) == false ) {
564 $baseurl .= '?';
565 } else {
566 $baseurl .= '&';
568 $baseurl = htmlspecialchars( $baseurl );
569 $printurl = $wgRequest->escapeAppendQuery( 'printable=yes' );
571 $s = "<a href=\"$printurl\">" . wfMsg( 'printableversion' ) . '</a>';
572 if( $wgOut->isSyndicated() ) {
573 foreach( $wgFeedClasses as $format => $class ) {
574 $feedurl = $wgRequest->escapeAppendQuery( "feed=$format" );
575 $s .= " | <a href=\"$feedurl\">{$format}</a>";
578 return $s;
581 function pageTitle()
583 global $wgOut, $wgTitle, $wgUser;
585 $s = '<h1 class="pagetitle">' . htmlspecialchars( $wgOut->getPageTitle() ) . '</h1>';
586 if($wgUser->getOption( 'editsectiononrightclick' ) && $wgTitle->userCanEdit()) { $s=$this->editSectionScript(0,$s);}
587 return $s;
590 function pageSubtitle()
592 global $wgOut;
594 $sub = $wgOut->getSubtitle();
595 if ( '' == $sub ) {
596 global $wgExtraSubtitle;
597 $sub = wfMsg( 'fromwikipedia' ) . $wgExtraSubtitle;
599 $subpages = $this->subPageSubtitle();
600 $sub .= !empty($subpages)?"</p><p class='subpages'>$subpages":'';
601 $s = "<p class='subtitle'>{$sub}</p>\n";
602 return $s;
605 function subPageSubtitle()
607 global $wgOut,$wgTitle,$wgNamespacesWithSubpages;
608 $subpages = '';
609 if($wgOut->isArticle() && !empty($wgNamespacesWithSubpages[$wgTitle->getNamespace()])) {
610 $ptext=$wgTitle->getPrefixedText();
611 if(preg_match('/\//',$ptext)) {
612 $links = explode('/',$ptext);
613 $c = 0;
614 $growinglink = '';
615 foreach($links as $link) {
616 $c++;
617 if ($c<count($links)) {
618 $growinglink .= $link;
619 $getlink = $this->makeLink( $growinglink, $link );
620 if(preg_match('/class="new"/i',$getlink)) { break; } # this is a hack, but it saves time
621 if ($c>1) {
622 $subpages .= ' | ';
623 } else {
624 $subpages .= '&lt; ';
626 $subpages .= $getlink;
627 $growinglink .= '/';
632 return $subpages;
635 function nameAndLogin()
637 global $wgUser, $wgTitle, $wgLang, $wgShowIPinHeader, $wgIP;
639 $li = $wgLang->specialPage( 'Userlogin' );
640 $lo = $wgLang->specialPage( 'Userlogout' );
642 $s = '';
643 if ( 0 == $wgUser->getID() ) {
644 if( $wgShowIPinHeader && isset( $_COOKIE[ini_get('session.name')] ) ) {
645 $n = $wgIP;
647 $tl = $this->makeKnownLink( $wgLang->getNsText(
648 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
649 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
651 $s .= $n . ' ('.$tl.')';
652 } else {
653 $s .= wfMsg('notloggedin');
656 $rt = $wgTitle->getPrefixedURL();
657 if ( 0 == strcasecmp( urlencode( $lo ), $rt ) ) {
658 $q = '';
659 } else { $q = "returnto={$rt}"; }
661 $s .= "\n<br />" . $this->makeKnownLink( $li,
662 wfMsg( 'login' ), $q );
663 } else {
664 $n = $wgUser->getName();
665 $rt = $wgTitle->getPrefixedURL();
666 $tl = $this->makeKnownLink( $wgLang->getNsText(
667 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
668 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
670 $tl = " ({$tl})";
672 $s .= $this->makeKnownLink( $wgLang->getNsText(
673 Namespace::getUser() ) . ":{$n}", $n ) . "{$tl}<br />" .
674 $this->makeKnownLink( $lo, wfMsg( 'logout' ),
675 "returnto={$rt}" ) . ' | ' .
676 $this->specialLink( 'preferences' );
678 $s .= ' | ' . $this->makeKnownLink( wfMsg( 'helppage' ),
679 wfMsg( 'help' ) );
681 return $s;
684 function getSearchLink() {
685 $searchPage =& Title::makeTitle( NS_SPECIAL, 'Search' );
686 return $searchPage->getLocalURL();
689 function escapeSearchLink() {
690 return htmlspecialchars( $this->getSearchLink() );
693 function searchForm()
695 global $wgRequest;
696 $search = $wgRequest->getText( 'search' );
698 $s = '<form name="search" class="inline" method="post" action="'
699 . $this->escapeSearchLink() . "\">\n"
700 . '<input type="text" name="search" size="19" value="'
701 . htmlspecialchars(substr($search,0,256)) . "\" />\n"
702 . '<input type="submit" name="go" value="' . wfMsg ('go') . '" />&nbsp;'
703 . '<input type="submit" name="fulltext" value="' . wfMsg ('search') . "\" />\n</form>";
705 return $s;
708 function topLinks()
710 global $wgOut;
711 $sep = " |\n";
713 $s = $this->mainPageLink() . $sep
714 . $this->specialLink( 'recentchanges' );
716 if ( $wgOut->isArticleRelated() ) {
717 $s .= $sep . $this->editThisPage()
718 . $sep . $this->historyLink();
720 # Many people don't like this dropdown box
721 #$s .= $sep . $this->specialPagesList();
723 return $s;
726 function bottomLinks()
728 global $wgOut, $wgUser, $wgTitle;
729 $sep = " |\n";
731 $s = '';
732 if ( $wgOut->isArticleRelated() ) {
733 $s .= '<strong>' . $this->editThisPage() . '</strong>';
734 if ( 0 != $wgUser->getID() ) {
735 $s .= $sep . $this->watchThisPage();
737 $s .= $sep . $this->talkLink()
738 . $sep . $this->historyLink()
739 . $sep . $this->whatLinksHere()
740 . $sep . $this->watchPageLinksLink();
742 if ( $wgTitle->getNamespace() == Namespace::getUser()
743 || $wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser()) )
746 $id=User::idFromName($wgTitle->getText());
747 $ip=User::isIP($wgTitle->getText());
749 if($id || $ip) { # both anons and non-anons have contri list
750 $s .= $sep . $this->userContribsLink();
752 if ( 0 != $wgUser->getID() ) { # show only to signed in users
753 if($id) { # can only email non-anons
754 $s .= $sep . $this->emailUserLink();
758 if ( $wgUser->isSysop() && $wgTitle->getArticleId() ) {
759 $s .= "\n<br />" . $this->deleteThisPage() .
760 $sep . $this->protectThisPage() .
761 $sep . $this->moveThisPage();
763 $s .= "<br />\n" . $this->otherLanguages();
765 return $s;
768 function pageStats()
770 global $wgOut, $wgLang, $wgArticle, $wgRequest;
771 global $wgDisableCounters, $wgMaxCredits, $wgShowCreditsIfMax;
773 extract( $wgRequest->getValues( 'oldid', 'diff' ) );
774 if ( ! $wgOut->isArticle() ) { return ''; }
775 if ( isset( $oldid ) || isset( $diff ) ) { return ''; }
776 if ( 0 == $wgArticle->getID() ) { return ''; }
778 $s = '';
779 if ( !$wgDisableCounters ) {
780 $count = $wgLang->formatNum( $wgArticle->getCount() );
781 if ( $count ) {
782 $s = wfMsg( 'viewcount', $count );
786 if (isset($wgMaxCredits) && $wgMaxCredits != 0) {
787 require_once("Credits.php");
788 $s .= ' ' . getCredits($wgArticle, $wgMaxCredits, $wgShowCreditsIfMax);
789 } else {
790 $s .= $this->lastModified();
793 return $s . ' ' . $this->getCopyright();
796 function getCopyright() {
797 global $wgRightsPage, $wgRightsUrl, $wgRightsText, $wgRequest;
800 $oldid = $wgRequest->getVal( 'oldid' );
801 $diff = $wgRequest->getVal( 'diff' );
803 if ( !is_null( $oldid ) && is_null( $diff ) && wfMsg( 'history_copyright' ) !== '-' ) {
804 $msg = 'history_copyright';
805 } else {
806 $msg = 'copyright';
809 $out = '';
810 if( $wgRightsPage ) {
811 $link = $this->makeKnownLink( $wgRightsPage, $wgRightsText );
812 } elseif( $wgRightsUrl ) {
813 $link = $this->makeExternalLink( $wgRightsUrl, $wgRightsText );
814 } else {
815 # Give up now
816 return $out;
818 $out .= wfMsg( $msg, $link );
819 return $out;
822 function getCopyrightIcon() {
823 global $wgRightsPage, $wgRightsUrl, $wgRightsText, $wgRightsIcon;
824 $out = '';
825 if( $wgRightsIcon ) {
826 $icon = htmlspecialchars( $wgRightsIcon );
827 if( $wgRightsUrl ) {
828 $url = htmlspecialchars( $wgRightsUrl );
829 $out .= '<a href="'.$url.'">';
831 $text = htmlspecialchars( $wgRightsText );
832 $out .= "<img src=\"$icon\" alt='$text' />";
833 if( $wgRightsUrl ) {
834 $out .= '</a>';
837 return $out;
840 function getPoweredBy() {
841 global $wgStylePath;
842 $url = htmlspecialchars( "$wgStylePath/images/poweredby_mediawiki_88x31.png" );
843 $img = '<a href="http://www.mediawiki.org/"><img src="'.$url.'" alt="MediaWiki" /></a>';
844 return $img;
847 function lastModified()
849 global $wgLang, $wgArticle;
851 $timestamp = $wgArticle->getTimestamp();
852 if ( $timestamp ) {
853 $d = $wgLang->timeanddate( $wgArticle->getTimestamp(), true );
854 $s = ' ' . wfMsg( 'lastmodified', $d );
855 } else {
856 $s = '';
858 return $s;
861 function logoText( $align = '' )
863 if ( '' != $align ) { $a = ' align="'.$align.'"'; }
864 else { $a = ''; }
866 $mp = wfMsg( 'mainpage' );
867 $titleObj = Title::newFromText( $mp );
868 $s = '<a href="' . $titleObj->escapeLocalURL()
869 . '"><img'.$a.' src="'
870 . $this->getLogo() . '" alt="' . "[{$mp}]\" /></a>";
871 return $s;
874 function quickBar()
876 global $wgOut, $wgTitle, $wgUser, $wgRequest, $wgLang;
877 global $wgDisableUploads, $wgRemoteUploads;
879 $fname = 'Skin::quickBar';
880 wfProfileIn( $fname );
882 $action = $wgRequest->getText( 'action' );
883 $wpPreview = $wgRequest->getBool( 'wpPreview' );
884 $tns=$wgTitle->getNamespace();
886 $s = "\n<div id='quickbar'>";
887 $s .= "\n" . $this->logoText() . "\n<hr class='sep' />";
889 $sep = "\n<br />";
890 $s .= $this->mainPageLink()
891 . $sep . $this->specialLink( 'recentchanges' )
892 . $sep . $this->specialLink( 'randompage' );
893 if ($wgUser->getID()) {
894 $s.= $sep . $this->specialLink( 'watchlist' ) ;
895 $s .= $sep .$this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
896 wfMsg( 'mycontris' ), 'target=' . wfUrlencode($wgUser->getName() ) );
899 // only show watchlist link if logged in
900 if ( wfMsg ( 'currentevents' ) != '-' ) $s .= $sep . $this->makeKnownLink( wfMsg( 'currentevents' ), '' ) ;
901 $s .= "\n<br /><hr class='sep' />";
902 $articleExists = $wgTitle->getArticleId();
903 if ( $wgOut->isArticle() || $action =='edit' || $action =='history' || $wpPreview) {
904 if($wgOut->isArticle()) {
905 $s .= '<strong>' . $this->editThisPage() . '</strong>';
906 } else { # backlink to the article in edit or history mode
907 if($articleExists){ # no backlink if no article
908 switch($tns) {
909 case 0:
910 $text = wfMsg('articlepage');
911 break;
912 case 1:
913 $text = wfMsg('viewtalkpage');
914 break;
915 case 2:
916 $text = wfMsg('userpage');
917 break;
918 case 3:
919 $text = wfMsg('viewtalkpage');
920 break;
921 case 4:
922 $text = wfMsg('wikipediapage');
923 break;
924 case 5:
925 $text = wfMsg('viewtalkpage');
926 break;
927 case 6:
928 $text = wfMsg('imagepage');
929 break;
930 case 7:
931 $text = wfMsg('viewtalkpage');
932 break;
933 default:
934 $text= wfMsg('articlepage');
937 $link = $wgTitle->getText();
938 if ($nstext = $wgLang->getNsText($tns) ) { # add namespace if necessary
939 $link = $nstext . ':' . $link ;
942 $s .= $this->makeLink( $link, $text );
943 } elseif( $wgTitle->getNamespace() != Namespace::getSpecial() ) {
944 # we just throw in a "New page" text to tell the user that he's in edit mode,
945 # and to avoid messing with the separator that is prepended to the next item
946 $s .= '<strong>' . wfMsg('newpage') . '</strong>';
952 if( $tns%2 && $action!='edit' && !$wpPreview) {
953 $s.= '<br />'.$this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg('postcomment'),'action=edit&section=new');
957 watching could cause problems in edit mode:
958 if user edits article, then loads "watch this article" in background and then saves
959 article with "Watch this article" checkbox disabled, the article is transparently
960 unwatched. Therefore we do not show the "Watch this page" link in edit mode
962 if ( 0 != $wgUser->getID() && $articleExists) {
963 if($action!='edit' && $action != 'submit' )
965 $s .= $sep . $this->watchThisPage();
967 if ( $wgTitle->userCanEdit() )
968 $s .= $sep . $this->moveThisPage();
970 if ( $wgUser->isSysop() and $articleExists ) {
971 $s .= $sep . $this->deleteThisPage() .
972 $sep . $this->protectThisPage();
974 $s .= $sep . $this->talkLink();
975 if ($articleExists && $action !='history') {
976 $s .= $sep . $this->historyLink();
978 $s.=$sep . $this->whatLinksHere();
980 if($wgOut->isArticleRelated()) {
981 $s .= $sep . $this->watchPageLinksLink();
984 if ( Namespace::getUser() == $wgTitle->getNamespace()
985 || $wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser())
988 $id=User::idFromName($wgTitle->getText());
989 $ip=User::isIP($wgTitle->getText());
991 if($id||$ip) {
992 $s .= $sep . $this->userContribsLink();
994 if ( 0 != $wgUser->getID() ) {
995 if($id) { # can only email real users
996 $s .= $sep . $this->emailUserLink();
1000 $s .= "\n<br /><hr class='sep' />";
1003 if ( 0 != $wgUser->getID() && ( !$wgDisableUploads || $wgRemoteUploads ) ) {
1004 $s .= $this->specialLink( 'upload' ) . $sep;
1006 $s .= $this->specialLink( 'specialpages' )
1007 . $sep . $this->bugReportsLink();
1009 global $wgSiteSupportPage;
1010 if( $wgSiteSupportPage ) {
1011 $s .= "\n<br /><a href=\"" . htmlspecialchars( $wgSiteSupportPage ) .
1012 '" class="internal">' . wfMsg( 'sitesupport' ) . '</a>';
1015 $s .= "\n<br /></div>\n";
1016 wfProfileOut( $fname );
1017 return $s;
1020 function specialPagesList()
1022 global $wgUser, $wgOut, $wgLang, $wgServer, $wgRedirectScript;
1023 require_once('SpecialPage.php');
1024 $a = array();
1025 $pages = SpecialPage::getPages();
1027 foreach ( $pages[''] as $name => $page ) {
1028 $a[$name] = $page->getDescription();
1030 if ( $wgUser->isSysop() )
1032 foreach ( $pages['sysop'] as $name => $page ) {
1033 $a[$name] = $page->getDescription();
1036 if ( $wgUser->isDeveloper() )
1038 foreach ( $pages['developer'] as $name => $page ) {
1039 $a[$name] = $page->getDescription() ;
1042 $go = wfMsg( 'go' );
1043 $sp = wfMsg( 'specialpages' );
1044 $spp = $wgLang->specialPage( 'Specialpages' );
1046 $s = '<form id="specialpages" method="get" class="inline" ' .
1047 'action="' . htmlspecialchars( "{$wgServer}{$wgRedirectScript}" ) . "\">\n";
1048 $s .= "<select name=\"wpDropdown\">\n";
1049 $s .= "<option value=\"{$spp}\">{$sp}</option>\n";
1051 foreach ( $a as $name => $desc ) {
1052 $p = $wgLang->specialPage( $name );
1053 $s .= "<option value=\"{$p}\">{$desc}</option>\n";
1055 $s .= "</select>\n";
1056 $s .= "<input type='submit' value=\"{$go}\" name='redirect' />\n";
1057 $s .= "</form>\n";
1058 return $s;
1061 function mainPageLink()
1063 $mp = wfMsg( 'mainpage' );
1064 $s = $this->makeKnownLink( $mp, $mp );
1065 return $s;
1068 function copyrightLink()
1070 $s = $this->makeKnownLink( wfMsg( 'copyrightpage' ),
1071 wfMsg( 'copyrightpagename' ) );
1072 return $s;
1075 function aboutLink()
1077 $s = $this->makeKnownLink( wfMsg( 'aboutpage' ),
1078 wfMsg( 'aboutwikipedia' ) );
1079 return $s;
1083 function disclaimerLink()
1085 $s = $this->makeKnownLink( wfMsg( 'disclaimerpage' ),
1086 wfMsg( 'disclaimers' ) );
1087 return $s;
1090 function editThisPage()
1092 global $wgOut, $wgTitle, $wgRequest;
1094 $oldid = $wgRequest->getVal( 'oldid' );
1095 $diff = $wgRequest->getVal( 'diff' );
1096 $redirect = $wgRequest->getVal( 'redirect' );
1098 if ( ! $wgOut->isArticleRelated() ) {
1099 $s = wfMsg( 'protectedpage' );
1100 } else {
1101 $n = $wgTitle->getPrefixedText();
1102 if ( $wgTitle->userCanEdit() ) {
1103 $t = wfMsg( 'editthispage' );
1104 } else {
1105 #$t = wfMsg( "protectedpage" );
1106 $t = wfMsg( 'viewsource' );
1108 $oid = $red = '';
1110 if ( !is_null( $redirect ) ) { $red = "&redirect={$redirect}"; }
1111 if ( $oldid && ! isset( $diff ) ) {
1112 $oid = "&oldid={$oldid}";
1114 $s = $this->makeKnownLink( $n, $t, "action=edit{$oid}{$red}" );
1116 return $s;
1119 function deleteThisPage()
1121 global $wgUser, $wgOut, $wgTitle, $wgRequest;
1123 $diff = $wgRequest->getVal( 'diff' );
1124 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
1125 $n = $wgTitle->getPrefixedText();
1126 $t = wfMsg( 'deletethispage' );
1128 $s = $this->makeKnownLink( $n, $t, 'action=delete' );
1129 } else {
1130 $s = '';
1132 return $s;
1135 function protectThisPage()
1137 global $wgUser, $wgOut, $wgTitle, $wgRequest;
1139 $diff = $wgRequest->getVal( 'diff' );
1140 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
1141 $n = $wgTitle->getPrefixedText();
1143 if ( $wgTitle->isProtected() ) {
1144 $t = wfMsg( 'unprotectthispage' );
1145 $q = 'action=unprotect';
1146 } else {
1147 $t = wfMsg( 'protectthispage' );
1148 $q = 'action=protect';
1150 $s = $this->makeKnownLink( $n, $t, $q );
1151 } else {
1152 $s = '';
1154 return $s;
1157 function watchThisPage()
1159 global $wgUser, $wgOut, $wgTitle;
1161 if ( $wgOut->isArticleRelated() ) {
1162 $n = $wgTitle->getPrefixedText();
1164 if ( $wgTitle->userIsWatching() ) {
1165 $t = wfMsg( 'unwatchthispage' );
1166 $q = 'action=unwatch';
1167 } else {
1168 $t = wfMsg( 'watchthispage' );
1169 $q = 'action=watch';
1171 $s = $this->makeKnownLink( $n, $t, $q );
1172 } else {
1173 $s = wfMsg( 'notanarticle' );
1175 return $s;
1178 function moveThisPage()
1180 global $wgTitle, $wgLang;
1182 if ( $wgTitle->userCanEdit() ) {
1183 $s = $this->makeKnownLink( $wgLang->specialPage( 'Movepage' ),
1184 wfMsg( 'movethispage' ), 'target=' . $wgTitle->getPrefixedURL() );
1185 } // no message if page is protected - would be redundant
1186 return $s;
1189 function historyLink()
1191 global $wgTitle;
1193 $s = $this->makeKnownLink( $wgTitle->getPrefixedText(),
1194 wfMsg( 'history' ), 'action=history' );
1195 return $s;
1198 function whatLinksHere()
1200 global $wgTitle, $wgLang;
1202 $s = $this->makeKnownLink( $wgLang->specialPage( 'Whatlinkshere' ),
1203 wfMsg( 'whatlinkshere' ), 'target=' . $wgTitle->getPrefixedURL() );
1204 return $s;
1207 function userContribsLink()
1209 global $wgTitle, $wgLang;
1211 $s = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
1212 wfMsg( 'contributions' ), 'target=' . $wgTitle->getPartialURL() );
1213 return $s;
1216 function emailUserLink()
1218 global $wgTitle, $wgLang;
1220 $s = $this->makeKnownLink( $wgLang->specialPage( 'Emailuser' ),
1221 wfMsg( 'emailuser' ), 'target=' . $wgTitle->getPartialURL() );
1222 return $s;
1225 function watchPageLinksLink()
1227 global $wgOut, $wgTitle, $wgLang;
1229 if ( ! $wgOut->isArticleRelated() ) {
1230 $s = '(' . wfMsg( 'notanarticle' ) . ')';
1231 } else {
1232 $s = $this->makeKnownLink( $wgLang->specialPage(
1233 'Recentchangeslinked' ), wfMsg( 'recentchangeslinked' ),
1234 'target=' . $wgTitle->getPrefixedURL() );
1236 return $s;
1239 function otherLanguages()
1241 global $wgOut, $wgLang, $wgTitle, $wgUseNewInterlanguage;
1243 $a = $wgOut->getLanguageLinks();
1244 if ( 0 == count( $a ) ) {
1245 if ( !$wgUseNewInterlanguage ) return '';
1246 $ns = $wgLang->getNsIndex ( $wgTitle->getNamespace () ) ;
1247 if ( $ns != 0 AND $ns != 1 ) return '' ;
1248 $pn = 'Intl' ;
1249 $x = 'mode=addlink&xt='.$wgTitle->getDBkey() ;
1250 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1251 wfMsg( 'intl' ) , $x );
1254 if ( !$wgUseNewInterlanguage ) {
1255 $s = wfMsg( 'otherlanguages' ) . ': ';
1256 } else {
1257 global $wgLanguageCode ;
1258 $x = 'mode=zoom&xt='.$wgTitle->getDBkey() ;
1259 $x .= '&xl='.$wgLanguageCode ;
1260 $s = $this->makeKnownLink( $wgLang->specialPage( 'Intl' ),
1261 wfMsg( 'otherlanguages' ) , $x ) . ': ' ;
1264 $s = wfMsg( 'otherlanguages' ) . ': ';
1265 $first = true;
1266 if($wgLang->isRTL()) $s .= '<span dir="LTR">';
1267 foreach( $a as $l ) {
1268 if ( ! $first ) { $s .= ' | '; }
1269 $first = false;
1271 $nt = Title::newFromText( $l );
1272 $url = $nt->getFullURL();
1273 $text = $wgLang->getLanguageName( $nt->getInterwiki() );
1275 if ( '' == $text ) { $text = $l; }
1276 $style = $this->getExternalLinkAttributes( $l, $text );
1277 $s .= "<a href=\"{$url}\"{$style}>{$text}</a>";
1279 if($wgLang->isRTL()) $s .= '</span>';
1280 return $s;
1283 function bugReportsLink()
1285 $s = $this->makeKnownLink( wfMsg( 'bugreportspage' ),
1286 wfMsg( 'bugreports' ) );
1287 return $s;
1290 function dateLink()
1292 global $wgLinkCache;
1293 $t1 = Title::newFromText( gmdate( 'F j' ) );
1294 $t2 = Title::newFromText( gmdate( 'Y' ) );
1296 $wgLinkCache->suspend();
1297 $id = $t1->getArticleID();
1298 $wgLinkCache->resume();
1300 if ( 0 == $id ) {
1301 $s = $this->makeBrokenLink( $t1->getText() );
1302 } else {
1303 $s = $this->makeKnownLink( $t1->getText() );
1305 $s .= ', ';
1307 $wgLinkCache->suspend();
1308 $id = $t2->getArticleID();
1309 $wgLinkCache->resume();
1311 if ( 0 == $id ) {
1312 $s .= $this->makeBrokenLink( $t2->getText() );
1313 } else {
1314 $s .= $this->makeKnownLink( $t2->getText() );
1316 return $s;
1319 function talkLink()
1321 global $wgLang, $wgTitle, $wgLinkCache;
1323 $tns = $wgTitle->getNamespace();
1324 if ( -1 == $tns ) { return ''; }
1326 $pn = $wgTitle->getText();
1327 $tp = wfMsg( 'talkpage' );
1328 if ( Namespace::isTalk( $tns ) ) {
1329 $lns = Namespace::getSubject( $tns );
1330 switch($tns) {
1331 case 1:
1332 $text = wfMsg('articlepage');
1333 break;
1334 case 3:
1335 $text = wfMsg('userpage');
1336 break;
1337 case 5:
1338 $text = wfMsg('wikipediapage');
1339 break;
1340 case 7:
1341 $text = wfMsg('imagepage');
1342 break;
1343 default:
1344 $text= wfMsg('articlepage');
1346 } else {
1348 $lns = Namespace::getTalk( $tns );
1349 $text=$tp;
1351 $n = $wgLang->getNsText( $lns );
1352 if ( '' == $n ) { $link = $pn; }
1353 else { $link = $n.':'.$pn; }
1355 $wgLinkCache->suspend();
1356 $s = $this->makeLink( $link, $text );
1357 $wgLinkCache->resume();
1359 return $s;
1362 function commentLink()
1364 global $wgLang, $wgTitle, $wgLinkCache;
1366 $tns = $wgTitle->getNamespace();
1367 if ( -1 == $tns ) { return ''; }
1369 $lns = ( Namespace::isTalk( $tns ) ) ? $tns : Namespace::getTalk( $tns );
1371 # assert Namespace::isTalk( $lns )
1373 $n = $wgLang->getNsText( $lns );
1374 $pn = $wgTitle->getText();
1376 $link = $n.':'.$pn;
1378 $wgLinkCache->suspend();
1379 $s = $this->makeKnownLink($link, wfMsg('postcomment'), 'action=edit&section=new');
1380 $wgLinkCache->resume();
1382 return $s;
1385 # After all the page content is transformed into HTML, it makes
1386 # a final pass through here for things like table backgrounds.
1388 function transformContent( $text )
1390 return $text;
1393 # Note: This function MUST call getArticleID() on the link,
1394 # otherwise the cache won't get updated properly. See LINKCACHE.DOC.
1396 function makeLink( $title, $text = '', $query = '', $trail = '' ) {
1397 wfProfileIn( 'Skin::makeLink' );
1398 $nt = Title::newFromText( $title );
1399 if ($nt) {
1400 $result = $this->makeLinkObj( Title::newFromText( $title ), $text, $query, $trail );
1401 } else {
1402 wfDebug( 'Invalid title passed to Skin::makeLink(): "'.$title."\"\n" );
1403 $result = $text == "" ? $title : $text;
1406 wfProfileOut( 'Skin::makeLink' );
1407 return $result;
1410 function makeKnownLink( $title, $text = '', $query = '', $trail = '', $prefix = '',$aprops = '') {
1411 $nt = Title::newFromText( $title );
1412 if ($nt) {
1413 return $this->makeKnownLinkObj( Title::newFromText( $title ), $text, $query, $trail, $prefix , $aprops );
1414 } else {
1415 wfDebug( 'Invalid title passed to Skin::makeKnownLink(): "'.$title."\"\n" );
1416 return $text == '' ? $title : $text;
1420 function makeBrokenLink( $title, $text = '', $query = '', $trail = '' ) {
1421 $nt = Title::newFromText( $title );
1422 if ($nt) {
1423 return $this->makeBrokenLinkObj( Title::newFromText( $title ), $text, $query, $trail );
1424 } else {
1425 wfDebug( 'Invalid title passed to Skin::makeBrokenLink(): "'.$title."\"\n" );
1426 return $text == '' ? $title : $text;
1430 function makeStubLink( $title, $text = '', $query = '', $trail = '' ) {
1431 $nt = Title::newFromText( $title );
1432 if ($nt) {
1433 return $this->makeStubLinkObj( Title::newFromText( $title ), $text, $query, $trail );
1434 } else {
1435 wfDebug( 'Invalid title passed to Skin::makeStubLink(): "'.$title."\"\n" );
1436 return $text == '' ? $title : $text;
1440 # Pass a title object, not a title string
1441 function makeLinkObj( &$nt, $text= '', $query = '', $trail = '', $prefix = '' )
1443 global $wgOut, $wgUser;
1444 $fname = 'Skin::makeLinkObj';
1446 if ( $nt->isExternal() ) {
1447 $u = $nt->getFullURL();
1448 $link = $nt->getPrefixedURL();
1449 if ( '' == $text ) { $text = $nt->getPrefixedText(); }
1450 $style = $this->getExternalLinkAttributes( $link, $text, 'extiw' );
1452 $inside = '';
1453 if ( '' != $trail ) {
1454 if ( preg_match( '/^([a-z]+)(.*)$$/sD', $trail, $m ) ) {
1455 $inside = $m[1];
1456 $trail = $m[2];
1459 $retVal = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1460 } elseif ( 0 == $nt->getNamespace() && "" == $nt->getText() ) {
1461 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1462 } elseif ( ( -1 == $nt->getNamespace() ) ||
1463 ( Namespace::getImage() == $nt->getNamespace() ) ) {
1464 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1465 } else {
1466 $aid = $nt->getArticleID() ;
1467 if ( 0 == $aid ) {
1468 $retVal = $this->makeBrokenLinkObj( $nt, $text, $query, $trail, $prefix );
1469 } else {
1470 $threshold = $wgUser->getOption('stubthreshold') ;
1471 if ( $threshold > 0 ) {
1472 $s = $dbr->getArray( 'cur',
1473 array( 'LENGTH(cur_text) AS x', 'cur_namespace', 'cur_is_redirect' ),
1474 array( 'cur_id' => $aid ),
1475 $fname
1478 if ( $s !== false ) {
1479 $size = $s->x;
1480 if ( $s->cur_is_redirect OR $s->cur_namespace != 0 ) {
1481 $size = $threshold*2 ; # Really big
1483 } else {
1484 $size = $threshold*2 ; # Really big
1486 } else {
1487 $size = 1 ;
1489 if ( $size < $threshold ) {
1490 $retVal = $this->makeStubLinkObj( $nt, $text, $query, $trail, $prefix );
1491 } else {
1492 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1496 return $retVal;
1499 # Pass a title object, not a title string
1500 function makeKnownLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' , $aprops = '')
1502 global $wgOut, $wgTitle, $wgInputEncoding;
1504 $fname = 'Skin::makeKnownLinkObj';
1505 wfProfileIn( $fname );
1507 if ( !is_object( $nt ) ) {
1508 return $text;
1510 $link = $nt->getPrefixedURL();
1512 if ( '' == $link ) {
1513 $u = '';
1514 if ( '' == $text ) {
1515 $text = htmlspecialchars( $nt->getFragment() );
1517 } else {
1518 $u = $nt->escapeLocalURL( $query );
1520 if ( '' != $nt->getFragment() ) {
1521 $anchor = urlencode( do_html_entity_decode( str_replace(' ', '_', $nt->getFragment()), ENT_COMPAT, $wgInputEncoding ) );
1522 $replacearray = array(
1523 '%3A' => ':',
1524 '%' => '.'
1526 $u .= '#' . str_replace(array_keys($replacearray),array_values($replacearray),$anchor);
1528 if ( '' == $text ) {
1529 $text = htmlspecialchars( $nt->getPrefixedText() );
1531 $style = $this->getInternalLinkAttributesObj( $nt, $text );
1533 $inside = '';
1534 if ( '' != $trail ) {
1535 if ( preg_match( $this->linktrail, $trail, $m ) ) {
1536 $inside = $m[1];
1537 $trail = $m[2];
1540 $r = "<a href=\"{$u}\"{$style}{$aprops}>{$prefix}{$text}{$inside}</a>{$trail}";
1541 wfProfileOut( $fname );
1542 return $r;
1545 # Pass a title object, not a title string
1546 function makeBrokenLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
1548 global $wgOut, $wgUser;
1550 $fname = 'Skin::makeBrokenLinkObj';
1551 wfProfileIn( $fname );
1553 if ( '' == $query ) {
1554 $q = 'action=edit';
1555 } else {
1556 $q = 'action=edit&'.$query;
1558 $u = $nt->escapeLocalURL( $q );
1560 if ( '' == $text ) {
1561 $text = htmlspecialchars( $nt->getPrefixedText() );
1563 $style = $this->getInternalLinkAttributesObj( $nt, $text, "yes" );
1565 $inside = '';
1566 if ( '' != $trail ) {
1567 if ( preg_match( $this->linktrail, $trail, $m ) ) {
1568 $inside = $m[1];
1569 $trail = $m[2];
1572 if ( $wgUser->getOption( 'highlightbroken' ) ) {
1573 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1574 } else {
1575 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>?</a>{$trail}";
1578 wfProfileOut( $fname );
1579 return $s;
1582 # Pass a title object, not a title string
1583 function makeStubLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
1585 global $wgOut, $wgUser;
1587 $link = $nt->getPrefixedURL();
1589 $u = $nt->escapeLocalURL( $query );
1591 if ( '' == $text ) {
1592 $text = htmlspecialchars( $nt->getPrefixedText() );
1594 $style = $this->getInternalLinkAttributesObj( $nt, $text, 'stub' );
1596 $inside = '';
1597 if ( '' != $trail ) {
1598 if ( preg_match( $this->linktrail, $trail, $m ) ) {
1599 $inside = $m[1];
1600 $trail = $m[2];
1603 if ( $wgUser->getOption( 'highlightbroken' ) ) {
1604 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1605 } else {
1606 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>!</a>{$trail}";
1608 return $s;
1611 function makeSelfLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
1613 $u = $nt->escapeLocalURL( $query );
1614 if ( '' == $text ) {
1615 $text = htmlspecialchars( $nt->getPrefixedText() );
1617 $inside = '';
1618 if ( '' != $trail ) {
1619 if ( preg_match( $this->linktrail, $trail, $m ) ) {
1620 $inside = $m[1];
1621 $trail = $m[2];
1624 return "<strong>{$prefix}{$text}{$inside}</strong>{$trail}";
1627 /* these are used extensively in SkinPHPTal, but also some other places */
1628 /*static*/ function makeSpecialUrl( $name, $urlaction='' ) {
1629 $title = Title::makeTitle( NS_SPECIAL, $name );
1630 $this->checkTitle($title, $name);
1631 return $title->getLocalURL( $urlaction );
1633 /*static*/ function makeTalkUrl ( $name, $urlaction='' ) {
1634 $title = Title::newFromText( $name );
1635 $title = $title->getTalkPage();
1636 $this->checkTitle($title, $name);
1637 return $title->getLocalURL( $urlaction );
1639 /*static*/ function makeArticleUrl ( $name, $urlaction='' ) {
1640 $title = Title::newFromText( $name );
1641 $title= $title->getSubjectPage();
1642 $this->checkTitle($title, $name);
1643 return $title->getLocalURL( $urlaction );
1645 /*static*/ function makeI18nUrl ( $name, $urlaction='' ) {
1646 $title = Title::newFromText( wfMsg($name) );
1647 $this->checkTitle($title, $name);
1648 return $title->getLocalURL( $urlaction );
1650 /*static*/ function makeUrl ( $name, $urlaction='' ) {
1651 $title = Title::newFromText( $name );
1652 $this->checkTitle($title, $name);
1653 return $title->getLocalURL( $urlaction );
1655 # this can be passed the NS number as defined in Language.php
1656 /*static*/ function makeNSUrl( $name, $urlaction='', $namespace=0 ) {
1657 $title = Title::makeTitle( $namespace, $name );
1658 $this->checkTitle($title, $name);
1659 return $title->getLocalURL( $urlaction );
1662 /* these return an array with the 'href' and boolean 'exists' */
1663 /*static*/ function makeUrlDetails ( $name, $urlaction='' ) {
1664 $title = Title::newFromText( $name );
1665 $this->checkTitle($title, $name);
1666 return array(
1667 'href' => $title->getLocalURL( $urlaction ),
1668 'exists' => $title->getArticleID() != 0?true:false
1671 /*static*/ function makeTalkUrlDetails ( $name, $urlaction='' ) {
1672 $title = Title::newFromText( $name );
1673 $title = $title->getTalkPage();
1674 $this->checkTitle($title, $name);
1675 return array(
1676 'href' => $title->getLocalURL( $urlaction ),
1677 'exists' => $title->getArticleID() != 0?true:false
1680 /*static*/ function makeArticleUrlDetails ( $name, $urlaction='' ) {
1681 $title = Title::newFromText( $name );
1682 $title= $title->getSubjectPage();
1683 $this->checkTitle($title, $name);
1684 return array(
1685 'href' => $title->getLocalURL( $urlaction ),
1686 'exists' => $title->getArticleID() != 0?true:false
1689 /*static*/ function makeI18nUrlDetails ( $name, $urlaction='' ) {
1690 $title = Title::newFromText( wfMsg($name) );
1691 $this->checkTitle($title, $name);
1692 return array(
1693 'href' => $title->getLocalURL( $urlaction ),
1694 'exists' => $title->getArticleID() != 0?true:false
1698 # make sure we have some title to operate on
1699 /*static*/ function checkTitle ( &$title, &$name ) {
1700 if(!is_object($title)) {
1701 $title = Title::newFromText( $name );
1702 if(!is_object($title)) {
1703 $title = Title::newFromText( '--error: link target missing--' );
1708 function fnamePart( $url )
1710 $basename = strrchr( $url, '/' );
1711 if ( false === $basename ) { $basename = $url; }
1712 else { $basename = substr( $basename, 1 ); }
1713 return wfEscapeHTML( $basename );
1716 function makeImage( $url, $alt = '' )
1718 global $wgOut;
1720 if ( '' == $alt ) { $alt = $this->fnamePart( $url ); }
1721 $s = '<img src="'.$url.'" alt="'.$alt.'" />';
1722 return $s;
1725 function makeImageLink( $name, $url, $alt = '' ) {
1726 $nt = Title::makeTitle( Namespace::getImage(), $name );
1727 return $this->makeImageLinkObj( $nt, $alt );
1730 function makeImageLinkObj( $nt, $alt = '' ) {
1731 global $wgLang, $wgUseImageResize;
1732 $img = Image::newFromTitle( $nt );
1733 $url = $img->getURL();
1735 $align = '';
1736 $prefix = $postfix = '';
1738 if ( $wgUseImageResize ) {
1739 # Check if the alt text is of the form "options|alt text"
1740 # Options are:
1741 # * thumbnail make a thumbnail with enlarge-icon and caption, alignment depends on lang
1742 # * left no resizing, just left align. label is used for alt= only
1743 # * right same, but right aligned
1744 # * none same, but not aligned
1745 # * ___px scale to ___ pixels width, no aligning. e.g. use in taxobox
1746 # * center center the image
1747 # * framed Keep original image size, no magnify-button.
1749 $part = explode( '|', $alt);
1751 $mwThumb =& MagicWord::get( MAG_IMG_THUMBNAIL );
1752 $mwLeft =& MagicWord::get( MAG_IMG_LEFT );
1753 $mwRight =& MagicWord::get( MAG_IMG_RIGHT );
1754 $mwNone =& MagicWord::get( MAG_IMG_NONE );
1755 $mwWidth =& MagicWord::get( MAG_IMG_WIDTH );
1756 $mwCenter =& MagicWord::get( MAG_IMG_CENTER );
1757 $mwFramed =& MagicWord::get( MAG_IMG_FRAMED );
1758 $alt = $part[count($part)-1];
1760 $height = $framed = $thumb = false;
1761 $manual_thumb = "" ;
1763 foreach( $part as $key => $val ) {
1764 $val_parts = explode ( "=" , $val , 2 ) ;
1765 $left_part = array_shift ( $val_parts ) ;
1766 if ( ! is_null( $mwThumb->matchVariableStartToEnd($val) ) ) {
1767 $thumb=true;
1768 } elseif ( count ( $val_parts ) == 1 && ! is_null( $mwThumb->matchVariableStartToEnd($left_part) ) ) {
1769 # use manually specified thumbnail
1770 $thumb=true;
1771 $manual_thumb = array_shift ( $val_parts ) ;
1772 } elseif ( ! is_null( $mwRight->matchVariableStartToEnd($val) ) ) {
1773 # remember to set an alignment, don't render immediately
1774 $align = 'right';
1775 } elseif ( ! is_null( $mwLeft->matchVariableStartToEnd($val) ) ) {
1776 # remember to set an alignment, don't render immediately
1777 $align = 'left';
1778 } elseif ( ! is_null( $mwCenter->matchVariableStartToEnd($val) ) ) {
1779 # remember to set an alignment, don't render immediately
1780 $align = 'center';
1781 } elseif ( ! is_null( $mwNone->matchVariableStartToEnd($val) ) ) {
1782 # remember to set an alignment, don't render immediately
1783 $align = 'none';
1784 } elseif ( ! is_null( $match = $mwWidth->matchVariableStartToEnd($val) ) ) {
1785 # $match is the image width in pixels
1786 if ( preg_match( '/^([0-9]*)x([0-9]*)$/', $match, $m ) ) {
1787 $width = intval( $m[1] );
1788 $height = intval( $m[2] );
1789 } else {
1790 $width = intval($match);
1792 } elseif ( ! is_null( $mwFramed->matchVariableStartToEnd($val) ) ) {
1793 $framed=true;
1796 if ( 'center' == $align )
1798 $prefix = '<span style="text-align: center">';
1799 $postfix = '</span>';
1800 $align = 'none';
1803 if ( $thumb || $framed ) {
1805 # Create a thumbnail. Alignment depends on language
1806 # writing direction, # right aligned for left-to-right-
1807 # languages ("Western languages"), left-aligned
1808 # for right-to-left-languages ("Semitic languages")
1810 # If thumbnail width has not been provided, it is set
1811 # here to 180 pixels
1812 if ( $align == '' ) {
1813 $align = $wgLang->isRTL() ? 'left' : 'right';
1815 if ( ! isset($width) ) {
1816 $width = 180;
1818 return $prefix.$this->makeThumbLinkObj( $img, $alt, $align, $width, $height, $framed, $manual_thumb ).$postfix;
1820 } elseif ( isset($width) ) {
1822 # Create a resized image, without the additional thumbnail
1823 # features
1825 if ( ( ! $height === false )
1826 && ( $img->getHeight() * $width / $img->getWidth() > $height ) ) {
1827 print "height=$height<br>\nimg->getHeight() = ".$img->getHeight()."<br>\n";
1828 print 'rescaling by factor '. $height / $img->getHeight() . "<br>\n";
1829 $width = $img->getWidth() * $height / $img->getHeight();
1831 if ( '' == $manual_thumb ) $url = $img->createThumb( $width );
1833 } # endif $wgUseImageResize
1835 if ( empty( $alt ) ) {
1836 $alt = preg_replace( '/\.(.+?)^/', '', $img->getName() );
1838 $alt = htmlspecialchars( $alt );
1840 $u = $nt->escapeLocalURL();
1841 if ( $url == '' )
1843 $s = str_replace( "$1", $img->getName(), wfMsg('missingimage') );
1844 $s .= "<br>{$alt}<br>{$url}<br>\n";
1845 } else {
1846 $s = '<a href="'.$u.'" class="image" title="'.$alt.'">' .
1847 '<img src="'.$url.'" alt="'.$alt.'" /></a>';
1849 if ( '' != $align ) {
1850 $s = "<div class=\"float{$align}\"><span>{$s}</span></div>";
1852 return str_replace("\n", ' ',$prefix.$s.$postfix);
1856 function makeThumbLinkObj( $img, $label = '', $align = 'right', $boxwidth = 180, $boxheight=false, $framed=false , $manual_thumb = "" ) {
1857 global $wgStylePath, $wgLang;
1858 # $image = Title::makeTitle( Namespace::getImage(), $name );
1859 $url = $img->getURL();
1861 #$label = htmlspecialchars( $label );
1862 $alt = preg_replace( '/<[^>]*>/', '', $label);
1863 $alt = htmlspecialchars( $alt );
1865 if ( $img->exists() )
1867 $width = $img->getWidth();
1868 $height = $img->getHeight();
1869 } else {
1870 $width = $height = 200;
1872 if ( $framed )
1874 // Use image dimensions, don't scale
1875 $boxwidth = $width;
1876 $oboxwidth = $boxwidth + 2;
1877 $boxheight = $height;
1878 $thumbUrl = $url;
1879 } else {
1880 $h = intval( $height/($width/$boxwidth) );
1881 $oboxwidth = $boxwidth + 2;
1882 if ( ( ! $boxheight === false ) && ( $h > $boxheight ) )
1884 $boxwidth *= $boxheight/$h;
1885 } else {
1886 $boxheight = $h;
1888 if ( '' == $manual_thumb ) $thumbUrl = $img->createThumb( $boxwidth );
1891 if ( $manual_thumb != '' ) # Use manually specified thumbnail
1893 $manual_title = Title::makeTitle( Namespace::getImage(), $manual_thumb ); #new Title ( $manual_thumb ) ;
1894 $manual_img = Image::newFromTitle( $manual_title );
1895 $thumbUrl = $manual_img->getURL();
1896 if ( $manual_img->exists() )
1898 $width = $manual_img->getWidth();
1899 $height = $manual_img->getHeight();
1900 $boxwidth = $width ;
1901 $boxheight = $height ;
1902 $oboxwidth = $boxwidth + 2 ;
1906 $u = $img->getEscapeLocalURL();
1908 $more = htmlspecialchars( wfMsg( 'thumbnail-more' ) );
1909 $magnifyalign = $wgLang->isRTL() ? 'left' : 'right';
1910 $textalign = $wgLang->isRTL() ? ' style="text-align:right"' : '';
1912 $s = "<div class=\"thumb t{$align}\"><div style=\"width:{$oboxwidth}px;\">";
1913 if ( $thumbUrl == '' ) {
1914 $s .= str_replace( "$1", $img->getName(), wfMsg('missingimage') );
1915 $zoomicon = '';
1916 } else {
1917 $s .= '<a href="'.$u.'" class="internal" title="'.$alt.'">'.
1918 '<img src="'.$thumbUrl.'" alt="'.$alt.'" ' .
1919 'width="'.$boxwidth.'" height="'.$boxheight.'" /></a>';
1920 if ( $framed ) {
1921 $zoomicon="";
1922 } else {
1923 $zoomicon = '<div class="magnify" style="float:'.$magnifyalign.'">'.
1924 '<a href="'.$u.'" class="internal" title="'.$more.'">'.
1925 '<img src="'.$wgStylePath.'/images/magnify-clip.png" ' .
1926 'width="15" height="11" alt="'.$more.'" /></a></div>';
1929 $s .= ' <div class="thumbcaption" '.$textalign.'>'.$zoomicon.$label."</div></div></div>";
1930 return str_replace("\n", ' ', $s);
1933 function makeMediaLink( $name, $url, $alt = "" ) {
1934 $nt = Title::makeTitle( Namespace::getMedia(), $name );
1935 return $this->makeMediaLinkObj( $nt, $alt );
1938 function makeMediaLinkObj( $nt, $alt = "" )
1940 if ( ! isset( $nt ) )
1942 ### HOTFIX. Instead of breaking, return empry string.
1943 $s = $alt;
1944 } else {
1945 $name = $nt->getDBKey();
1946 $url = Image::wfImageUrl( $name );
1947 if ( empty( $alt ) ) {
1948 $alt = preg_replace( '/\.(.+?)^/', '', $name );
1951 $u = htmlspecialchars( $url );
1952 $s = "<a href=\"{$u}\" class='internal' title=\"{$alt}\">{$alt}</a>";
1954 return $s;
1957 function specialLink( $name, $key = "" )
1959 global $wgLang;
1961 if ( '' == $key ) { $key = strtolower( $name ); }
1962 $pn = $wgLang->ucfirst( $name );
1963 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1964 wfMsg( $key ) );
1967 function makeExternalLink( $url, $text, $escape = true ) {
1968 $style = $this->getExternalLinkAttributes( $url, $text );
1969 $url = htmlspecialchars( $url );
1970 if( $escape ) {
1971 $text = htmlspecialchars( $text );
1973 return '<a href="'.$url.'"'.$style.'>'.$text.'</a>';
1976 # Called by history lists and recent changes
1979 # Returns text for the start of the tabular part of RC
1980 function beginRecentChangesList()
1982 $this->rc_cache = array() ;
1983 $this->rcMoveIndex = 0;
1984 $this->rcCacheIndex = 0 ;
1985 $this->lastdate = '';
1986 $this->rclistOpen = false;
1987 return '';
1990 function beginImageHistoryList()
1992 $s = "\n<h2>" . wfMsg( 'imghistory' ) . "</h2>\n" .
1993 "<p>" . wfMsg( 'imghistlegend' ) . "</p>\n".'<ul class="special">';
1994 return $s;
1997 # Returns text for the end of RC
1998 # If enhanced RC is in use, returns pretty much all the text
1999 function endRecentChangesList()
2001 $s = $this->recentChangesBlock() ;
2002 if( $this->rclistOpen ) {
2003 $s .= "</ul>\n";
2005 return $s;
2008 # Enhanced RC ungrouped line
2009 function recentChangesBlockLine ( $rcObj )
2011 global $wgStylePath, $wgLang ;
2013 # Get rc_xxxx variables
2014 extract( $rcObj->mAttribs ) ;
2015 $curIdEq = 'curid='.$rc_cur_id;
2017 # Spacer image
2018 $r = '' ;
2020 $r .= '<img src="'.$wgStylePath.'/images/Arr_.png" width="12" height="12" border="0" />' ;
2021 $r .= '<tt>' ;
2023 if ( $rc_type == RC_MOVE || $rc_type == RC_MOVE_OVER_REDIRECT ) {
2024 $r .= '&nbsp;&nbsp;';
2025 } else {
2026 # M & N (minor & new)
2027 $M = wfMsg( 'minoreditletter' );
2028 $N = wfMsg( 'newpageletter' );
2030 if ( $rc_type == RC_NEW ) {
2031 $r .= $N ;
2032 } else {
2033 $r .= '&nbsp;' ;
2035 if ( $rc_minor ) {
2036 $r .= $M ;
2037 } else {
2038 $r .= '&nbsp;' ;
2042 # Timestamp
2043 $r .= ' '.$rcObj->timestamp.' ' ;
2044 $r .= '</tt>' ;
2046 # Article link
2047 $link = $rcObj->link ;
2048 if ( $rcObj->watched ) $link = '<strong>'.$link.'</strong>' ;
2049 $r .= $link ;
2051 # Diff
2052 $r .= ' (' ;
2053 $r .= $rcObj->difflink ;
2054 $r .= '; ' ;
2056 # Hist
2057 $r .= $this->makeKnownLinkObj( $rcObj->getTitle(), wfMsg( 'hist' ), $curIdEq.'&action=history' );
2059 # User/talk
2060 $r .= ') . . '.$rcObj->userlink ;
2061 $r .= $rcObj->usertalklink ;
2063 # Comment
2064 if ( $rc_comment != '' && $rc_type != RC_MOVE && $rc_type != RC_MOVE_OVER_REDIRECT ) {
2065 $rc_comment=$this->formatComment($rc_comment);
2066 $r .= $wgLang->emphasize( ' ('.$rc_comment.')' );
2069 $r .= "<br />\n" ;
2070 return $r ;
2073 # Enhanced RC group
2074 function recentChangesBlockGroup ( $block )
2076 global $wgStylePath, $wgLang ;
2078 $r = '' ;
2079 $M = wfMsg( 'minoreditletter' );
2080 $N = wfMsg( 'newpageletter' );
2082 # Collate list of users
2083 $isnew = false ;
2084 $userlinks = array () ;
2085 foreach ( $block AS $rcObj ) {
2086 $oldid = $rcObj->mAttribs['rc_last_oldid'];
2087 if ( $rcObj->mAttribs['rc_new'] ) $isnew = true ;
2088 $u = $rcObj->userlink ;
2089 if ( !isset ( $userlinks[$u] ) ) $userlinks[$u] = 0 ;
2090 $userlinks[$u]++ ;
2093 # Sort the list and convert to text
2094 krsort ( $userlinks ) ;
2095 asort ( $userlinks ) ;
2096 $users = array () ;
2097 foreach ( $userlinks as $userlink => $count) {
2098 $text = $userlink ;
2099 if ( $count > 1 ) $text .= " ({$count}&times;)" ;
2100 array_push ( $users , $text ) ;
2102 $users = ' <font size="-1">['.implode('; ',$users).']</font>' ;
2104 # Arrow
2105 $rci = 'RCI'.$this->rcCacheIndex ;
2106 $rcl = 'RCL'.$this->rcCacheIndex ;
2107 $rcm = 'RCM'.$this->rcCacheIndex ;
2108 $toggleLink = "javascript:toggleVisibility('$rci','$rcm','$rcl')" ;
2109 $arrowdir = $wgLang->isRTL() ? 'l' : 'r';
2110 $tl = '<span id="'.$rcm.'"><a href="'.$toggleLink.'"><img src="'.$wgStylePath.'/images/Arr_'.$arrowdir.'.png" width="12" height="12" /></a></span>' ;
2111 $tl .= '<span id="'.$rcl.'" style="display:none"><a href="'.$toggleLink.'"><img src="'.$wgStylePath.'/images/Arr_d.png" width="12" height="12" /></a></span>' ;
2112 $r .= $tl ;
2114 # Main line
2115 # M/N
2116 $r .= '<tt>' ;
2117 if ( $isnew ) $r .= $N ;
2118 else $r .= '&nbsp;' ;
2119 $r .= '&nbsp;' ; # Minor
2121 # Timestamp
2122 $r .= ' '.$block[0]->timestamp.' ' ;
2123 $r .= '</tt>' ;
2125 # Article link
2126 $link = $block[0]->link ;
2127 if ( $block[0]->watched ) $link = '<strong>'.$link.'</strong>' ;
2128 $r .= $link ;
2130 $curIdEq = 'curid=' . $block[0]->mAttribs['rc_cur_id'];
2131 if ( $block[0]->mAttribs['rc_type'] != RC_LOG ) {
2132 # Changes
2133 $r .= ' ('.count($block).' ' ;
2134 if ( $isnew ) $r .= wfMsg('changes');
2135 else $r .= $this->makeKnownLinkObj( $block[0]->getTitle() , wfMsg('changes') ,
2136 $curIdEq.'&diff=0&oldid='.$oldid ) ;
2137 $r .= '; ' ;
2139 # History
2140 $r .= $this->makeKnownLinkObj( $block[0]->getTitle(), wfMsg( 'history' ), $curIdEq.'&action=history' );
2141 $r .= ')' ;
2144 $r .= $users ;
2145 $r .= "<br />\n" ;
2147 # Sub-entries
2148 $r .= '<div id="'.$rci.'" style="display:none">' ;
2149 foreach ( $block AS $rcObj ) {
2150 # Get rc_xxxx variables
2151 extract( $rcObj->mAttribs );
2153 $r .= '<img src="'.$wgStylePath.'/images/Arr_.png" width="12" height="12" />';
2154 $r .= '<tt>&nbsp; &nbsp; &nbsp; &nbsp;' ;
2155 if ( $rc_new ) $r .= $N ;
2156 else $r .= '&nbsp;' ;
2157 if ( $rc_minor ) $r .= $M ;
2158 else $r .= '&nbsp;' ;
2159 $r .= '</tt>' ;
2161 $o = '' ;
2162 if ( $rc_last_oldid != 0 ) {
2163 $o = 'oldid='.$rc_last_oldid ;
2165 if ( $rc_type == RC_LOG ) {
2166 $link = $rcObj->timestamp ;
2167 } else {
2168 $link = $this->makeKnownLinkObj( $rcObj->getTitle(), $rcObj->timestamp , "{$curIdEq}&$o" ) ;
2170 $link = '<tt>'.$link.'</tt>' ;
2172 $r .= $link ;
2173 $r .= ' (' ;
2174 $r .= $rcObj->curlink ;
2175 $r .= '; ' ;
2176 $r .= $rcObj->lastlink ;
2177 $r .= ') . . '.$rcObj->userlink ;
2178 $r .= $rcObj->usertalklink ;
2179 if ( $rc_comment != '' ) {
2180 $rc_comment=$this->formatComment($rc_comment);
2181 $r .= $wgLang->emphasize( ' ('.$rc_comment.')' ) ;
2183 $r .= "<br />\n" ;
2185 $r .= "</div>\n" ;
2187 $this->rcCacheIndex++ ;
2188 return $r ;
2191 # If enhanced RC is in use, this function takes the previously cached
2192 # RC lines, arranges them, and outputs the HTML
2193 function recentChangesBlock ()
2195 global $wgStylePath ;
2196 if ( count ( $this->rc_cache ) == 0 ) return '' ;
2197 $blockOut = '';
2198 foreach ( $this->rc_cache AS $secureName => $block ) {
2199 if ( count ( $block ) < 2 ) {
2200 $blockOut .= $this->recentChangesBlockLine ( array_shift ( $block ) ) ;
2201 } else {
2202 $blockOut .= $this->recentChangesBlockGroup ( $block ) ;
2206 return '<div>'.$blockOut.'</div>' ;
2209 # Called in a loop over all displayed RC entries
2210 # Either returns the line, or caches it for later use
2211 function recentChangesLine( &$rc, $watched = false )
2213 global $wgUser ;
2214 $usenew = $wgUser->getOption( 'usenewrc' );
2215 if ( $usenew )
2216 $line = $this->recentChangesLineNew ( $rc, $watched ) ;
2217 else
2218 $line = $this->recentChangesLineOld ( $rc, $watched ) ;
2219 return $line ;
2222 function recentChangesLineOld( &$rc, $watched = false )
2224 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds;
2226 # Extract DB fields into local scope
2227 extract( $rc->mAttribs );
2228 $curIdEq = 'curid=' . $rc_cur_id;
2230 # Make date header if necessary
2231 $date = $wgLang->date( $rc_timestamp, true);
2232 $s = '';
2233 if ( $date != $this->lastdate ) {
2234 if ( '' != $this->lastdate ) { $s .= "</ul>\n"; }
2235 $s .= "<h4>{$date}</h4>\n<ul class='special'>";
2236 $this->lastdate = $date;
2237 $this->rclistOpen = true;
2239 $s .= '<li> ';
2241 if ( $rc_type == RC_MOVE || $rc_type == RC_MOVE_OVER_REDIRECT ) {
2242 # Diff
2243 $s .= '(' . wfMsg( 'diff' ) . ') (';
2244 # Hist
2245 $s .= $this->makeKnownLinkObj( $rc->getMovedToTitle(), wfMsg( 'hist' ), 'action=history' ) .
2246 ') . . ';
2248 # "[[x]] moved to [[y]]"
2249 if ( $rc_type == RC_MOVE ) {
2250 $msg = '1movedto2';
2251 } else {
2252 $msg = '1movedto2_redir';
2254 $s .= wfMsg( $msg, $this->makeKnownLinkObj( $rc->getTitle(), '', 'redirect=no' ),
2255 $this->makeKnownLinkObj( $rc->getMovedToTitle(), '' ) );
2256 } else {
2257 # Diff link
2258 if ( $rc_type == RC_NEW || $rc_type == RC_LOG ) {
2259 $diffLink = wfMsg( 'diff' );
2260 } else {
2261 $diffLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'diff' ),
2262 $curIdEq.'&diff='.$rc_this_oldid.'&oldid='.$rc_last_oldid ,'' ,'' , ' tabindex="'.$rc->counter.'"');
2264 $s .= '('.$diffLink.') (';
2266 # History link
2267 $s .= $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'hist' ), $curIdEq.'&action=history' );
2268 $s .= ') . . ';
2270 # M and N (minor and new)
2271 $M = wfMsg( 'minoreditletter' );
2272 $N = wfMsg( 'newpageletter' );
2273 if ( $rc_minor ) { $s .= ' <strong>'.$M.'</strong>'; }
2274 if ( $rc_type == RC_NEW ) { $s .= '<strong>'.$N.'</strong>'; }
2276 # Article link
2277 $articleLink = $this->makeKnownLinkObj( $rc->getTitle(), '' );
2279 if ( $watched ) {
2280 $articleLink = '<strong>'.$articleLink.'</strong>';
2282 $s .= ' '.$articleLink;
2286 # Timestamp
2287 $s .= '; ' . $wgLang->time( $rc_timestamp, true, $wgRCSeconds ) . ' . . ';
2289 # User link (or contributions for unregistered users)
2290 if ( 0 == $rc_user ) {
2291 $userLink = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
2292 $rc_user_text, 'target=' . $rc_user_text );
2293 } else {
2294 $userLink = $this->makeLink( $wgLang->getNsText( NS_USER ) . ':'.$rc_user_text, $rc_user_text );
2296 $s .= $userLink;
2298 # User talk link
2299 $talkname=$wgLang->getNsText(NS_TALK); # use the shorter name
2300 global $wgDisableAnonTalk;
2301 if( 0 == $rc_user && $wgDisableAnonTalk ) {
2302 $userTalkLink = '';
2303 } else {
2304 $utns=$wgLang->getNsText(NS_USER_TALK);
2305 $userTalkLink= $this->makeLink($utns . ':'.$rc_user_text, $talkname );
2307 # Block link
2308 $blockLink='';
2309 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2310 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2311 'Blockip' ), wfMsg( 'blocklink' ), 'ip='.$rc_user_text );
2314 if($blockLink) {
2315 if($userTalkLink) $userTalkLink .= ' | ';
2316 $userTalkLink .= $blockLink;
2318 if($userTalkLink) $s.=' ('.$userTalkLink.')';
2320 # Add comment
2321 if ( '' != $rc_comment && '*' != $rc_comment && $rc_type != RC_MOVE && $rc_type != RC_MOVE_OVER_REDIRECT ) {
2322 $rc_comment=$this->formatComment($rc_comment);
2323 $s .= $wgLang->emphasize(' (' . $rc_comment . ')');
2325 $s .= "</li>\n";
2327 return $s;
2330 # function recentChangesLineNew( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched = false, $oldid = 0 , $diffid = 0 )
2331 function recentChangesLineNew( &$baseRC, $watched = false )
2333 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds;
2335 # Create a specialised object
2336 $rc = RCCacheEntry::newFromParent( $baseRC ) ;
2338 # Extract fields from DB into the function scope (rc_xxxx variables)
2339 extract( $rc->mAttribs );
2340 $curIdEq = 'curid=' . $rc_cur_id;
2342 # If it's a new day, add the headline and flush the cache
2343 $date = $wgLang->date( $rc_timestamp, true);
2344 $ret = '' ;
2345 if ( $date != $this->lastdate ) {
2346 # Process current cache
2347 $ret = $this->recentChangesBlock () ;
2348 $this->rc_cache = array() ;
2349 $ret .= "<h4>{$date}</h4>\n";
2350 $this->lastdate = $date;
2353 # Make article link
2354 if ( $rc_type == RC_MOVE || $rc_type == RC_MOVE_OVER_REDIRECT ) {
2355 if ( $rc_type == RC_MOVE ) {
2356 $msg = "1movedto2";
2357 } else {
2358 $msg = "1movedto2_redir";
2360 $clink = wfMsg( $msg, $this->makeKnownLinkObj( $rc->getTitle(), '', 'redirect=no' ),
2361 $this->makeKnownLinkObj( $rc->getMovedToTitle(), '' ) );
2362 } else {
2363 $clink = $this->makeKnownLinkObj( $rc->getTitle(), '' ) ;
2366 $time = $wgLang->time( $rc_timestamp, true, $wgRCSeconds );
2367 $rc->watched = $watched ;
2368 $rc->link = $clink ;
2369 $rc->timestamp = $time;
2371 # Make "cur" and "diff" links
2372 if ( ( $rc_type == RC_NEW && $rc_this_oldid == 0 ) || $rc_type == RC_LOG || $rc_type == RC_MOVE || $rc_type == RC_MOVE_OVER_REDIRECT ) {
2373 $curLink = wfMsg( 'cur' );
2374 $diffLink = wfMsg( 'diff' );
2375 } else {
2376 $query = $curIdEq.'&diff=0&oldid='.$rc_this_oldid;
2377 $aprops = ' tabindex="'.$baseRC->counter.'"';
2378 $curLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'cur' ), $query, '' ,'' , $aprops );
2379 $diffLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'diff'), $query, '' ,'' , $aprops );
2382 # Make "last" link
2383 $titleObj = $rc->getTitle();
2384 if ( $rc_last_oldid == 0 || $rc_type == RC_LOG || $rc_type == RC_MOVE || $rc_type == RC_MOVE_OVER_REDIRECT ) {
2385 $lastLink = wfMsg( 'last' );
2386 } else {
2387 $lastLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'last' ),
2388 $curIdEq.'&diff='.$rc_this_oldid.'&oldid='.$rc_last_oldid );
2391 # Make user link (or user contributions for unregistered users)
2392 if ( 0 == $rc_user ) {
2393 $userLink = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
2394 $rc_user_text, 'target=' . $rc_user_text );
2395 } else {
2396 $userLink = $this->makeLink( $wgLang->getNsText(
2397 Namespace::getUser() ) . ':'.$rc_user_text, $rc_user_text );
2400 $rc->userlink = $userLink ;
2401 $rc->lastlink = $lastLink ;
2402 $rc->curlink = $curLink ;
2403 $rc->difflink = $diffLink;
2406 # Make user talk link
2407 $utns=$wgLang->getNsText(NS_USER_TALK);
2408 $talkname=$wgLang->getNsText(NS_TALK); # use the shorter name
2409 $userTalkLink= $this->makeLink($utns . ':'.$rc_user_text, $talkname );
2411 global $wgDisableAnonTalk;
2412 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2413 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2414 'Blockip' ), wfMsg( 'blocklink' ), 'ip='.$rc_user_text );
2415 if( $wgDisableAnonTalk )
2416 $rc->usertalklink = ' ('.$blockLink.')';
2417 else
2418 $rc->usertalklink = ' ('.$userTalkLink.' | '.$blockLink.')';
2419 } else {
2420 if( $wgDisableAnonTalk && ($rc_user == 0) )
2421 $rc->usertalklink = '';
2422 else
2423 $rc->usertalklink = ' ('.$userTalkLink.')';
2426 # Put accumulated information into the cache, for later display
2427 # Page moves go on their own line
2428 $title = $rc->getTitle();
2429 $secureName = $title->getPrefixedDBkey();
2430 if ( $rc_type == RC_MOVE || $rc_type == RC_MOVE_OVER_REDIRECT ) {
2431 # Use an @ character to prevent collision with page names
2432 $this->rc_cache['@@' . ($this->rcMoveIndex++)] = array($rc);
2433 } else {
2434 if ( !isset ( $this->rc_cache[$secureName] ) ) $this->rc_cache[$secureName] = array() ;
2435 array_push ( $this->rc_cache[$secureName] , $rc ) ;
2437 return $ret;
2440 function endImageHistoryList()
2442 $s = "</ul>\n";
2443 return $s;
2446 /* This function is called by all recent changes variants, by the page history,
2447 and by the user contributions list. It is responsible for formatting edit
2448 comments. It escapes any HTML in the comment, but adds some CSS to format
2449 auto-generated comments (from section editing) and formats [[wikilinks]].
2450 Main author: Erik Möller (moeller@scireview.de)
2452 function formatComment($comment)
2454 global $wgLang;
2455 $comment=wfEscapeHTML($comment);
2457 # The pattern for autogen comments is / * foo * /, which makes for
2458 # some nasty regex.
2459 # We look for all comments, match any text before and after the comment,
2460 # add a separator where needed and format the comment itself with CSS
2461 while (preg_match('/(.*)\/\*\s*(.*?)\s*\*\/(.*)/', $comment,$match)) {
2462 $pre=$match[1];
2463 $auto=$match[2];
2464 $post=$match[3];
2465 $sep='-';
2466 if($pre) { $auto = $sep.' '.$auto; }
2467 if($post) { $auto .= ' '.$sep; }
2468 $auto='<span class="autocomment">'.$auto.'</span>';
2469 $comment=$pre.$auto.$post;
2472 # format regular and media links - all other wiki formatting
2473 # is ignored
2474 while(preg_match('/\[\[(.*?)(\|(.*?))*\]\]/',$comment,$match)) {
2476 $medians = $wgLang->getNsText(Namespace::getMedia()).':';
2477 $func='makeLink';
2478 if(preg_match('/^'.$medians.'/i',$match[1])) {
2479 $func='makeMediaLink';
2481 # Handle link renaming [[foo|text]] will show link as "text"
2482 if(isset($match[3]) ) {
2483 $comment=
2484 preg_replace('/\[\[(.*?)\]\]/',
2485 $this->$func($match[1],$match[3]),$comment,1);
2486 } else {
2487 $comment=
2488 preg_replace('/\[\[(.*?)\]\]/',
2489 $this->$func($match[1],$match[1]),$comment,1);
2493 return $comment;
2497 function imageHistoryLine( $iscur, $timestamp, $img, $user, $usertext, $size, $description )
2499 global $wgUser, $wgLang, $wgTitle;
2501 $datetime = $wgLang->timeanddate( $timestamp, true );
2502 $del = wfMsg( 'deleteimg' );
2503 $cur = wfMsg( 'cur' );
2505 if ( $iscur ) {
2506 $url = Image::wfImageUrl( $img );
2507 $rlink = $cur;
2508 if ( $wgUser->isSysop() ) {
2509 $link = $wgTitle->escapeLocalURL( 'image=' . $wgTitle->getPartialURL() .
2510 '&action=delete' );
2511 $style = $this->getInternalLinkAttributes( $link, $del );
2513 $dlink = '<a href="'.$link.'"'.$style.'>'.$del.'</a>';
2514 } else {
2515 $dlink = $del;
2517 } else {
2518 $url = wfEscapeHTML( wfImageArchiveUrl( $img ) );
2519 if( $wgUser->getID() != 0 ) {
2520 $rlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2521 wfMsg( 'revertimg' ), 'action=revert&oldimage=' .
2522 urlencode( $img ) );
2523 $dlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2524 $del, 'action=delete&oldimage=' . urlencode( $img ) );
2525 } else {
2526 # Having live active links for non-logged in users
2527 # means that bots and spiders crawling our site can
2528 # inadvertently change content. Baaaad idea.
2529 $rlink = wfMsg( 'revertimg' );
2530 $dlink = $del;
2533 if ( 0 == $user ) {
2534 $userlink = $usertext;
2535 } else {
2536 $userlink = $this->makeLink( $wgLang->getNsText( Namespace::getUser() ) .
2537 ':'.$usertext, $usertext );
2539 $nbytes = wfMsg( 'nbytes', $size );
2540 $style = $this->getInternalLinkAttributes( $url, $datetime );
2542 $s = "<li> ({$dlink}) ({$rlink}) <a href=\"{$url}\"{$style}>{$datetime}</a>"
2543 . " . . {$userlink} ({$nbytes})";
2545 if ( '' != $description && '*' != $description ) {
2546 $sk=$wgUser->getSkin();
2547 $s .= $wgLang->emphasize(' (' . $sk->formatComment($description) . ')');
2549 $s .= "</li>\n";
2550 return $s;
2553 function tocIndent($level) {
2554 return str_repeat( '<div class="tocindent">'."\n", $level>0 ? $level : 0 );
2557 function tocUnindent($level) {
2558 return str_repeat( "</div>\n", $level>0 ? $level : 0 );
2561 # parameter level defines if we are on an indentation level
2562 function tocLine( $anchor, $tocline, $level ) {
2563 $link = '<a href="#'.$anchor.'">'.$tocline.'</a><br />';
2564 if($level) {
2565 return $link."\n";
2566 } else {
2567 return '<div class="tocline">'.$link."</div>\n";
2572 function tocTable($toc) {
2573 # note to CSS fanatics: putting this in a div does not work -- div won't auto-expand
2574 # try min-width & co when somebody gets a chance
2575 $hideline = ' <script type="text/javascript">showTocToggle("' . addslashes( wfMsg('showtoc') ) . '","' . addslashes( wfMsg('hidetoc') ) . '")</script>';
2576 return
2577 '<table border="0" id="toc"><tr id="toctitle"><td align="center">'."\n".
2578 '<b>'.wfMsg('toc').'</b>' .
2579 $hideline .
2580 '</td></tr><tr id="tocinside"><td>'."\n".
2581 $toc."</td></tr></table>\n";
2584 # These two do not check for permissions: check $wgTitle->userCanEdit before calling them
2585 function editSectionScript( $section, $head ) {
2586 global $wgTitle, $wgRequest;
2587 if( $wgRequest->getInt( 'oldid' ) && ( $wgRequest->getVal( 'diff' ) != '0' ) ) {
2588 return $head;
2590 $url = $wgTitle->escapeLocalURL( 'action=edit&section='.$section );
2591 return '<span oncontextmenu=\'document.location="'.$url.'";return false;\'>'.$head.'</span>';
2594 function editSectionLink( $section ) {
2595 global $wgRequest;
2596 global $wgTitle, $wgUser, $wgLang;
2598 if( $wgRequest->getInt( 'oldid' ) && ( $wgRequest->getVal( 'diff' ) != '0' ) ) {
2599 # Section edit links would be out of sync on an old page.
2600 # But, if we're diffing to the current page, they'll be
2601 # correct.
2602 return '';
2605 $editurl = '&section='.$section;
2606 $url = $this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg('editsection'),'action=edit'.$editurl);
2608 if( $wgLang->isRTL() ) {
2609 $farside = 'left';
2610 $nearside = 'right';
2611 } else {
2612 $farside = 'right';
2613 $nearside = 'left';
2615 return "<div class=\"editsection\" style=\"float:$farside;margin-$nearside:5px;\">[".$url."]</div>";
2619 // This function is called by EditPage.php and shows a bulletin board style
2620 // toolbar for common editing functions. It can be disabled in the user preferences.
2621 // The necsesary JavaScript code can be found in style/wikibits.js.
2622 function getEditToolbar() {
2623 global $wgStylePath, $wgLang, $wgMimeType;
2625 // toolarray an array of arrays which each include the filename of
2626 // the button image (without path), the opening tag, the closing tag,
2627 // and optionally a sample text that is inserted between the two when no
2628 // selection is highlighted.
2629 // The tip text is shown when the user moves the mouse over the button.
2631 // Already here are accesskeys (key), which are not used yet until someone
2632 // can figure out a way to make them work in IE. However, we should make
2633 // sure these keys are not defined on the edit page.
2634 $toolarray=array(
2635 array( 'image'=>'button_bold.png',
2636 'open'=>"\'\'\'",
2637 'close'=>"\'\'\'",
2638 'sample'=>wfMsg('bold_sample'),
2639 'tip'=>wfMsg('bold_tip'),
2640 'key'=>'B'
2642 array( "image"=>"button_italic.png",
2643 "open"=>"\'\'",
2644 "close"=>"\'\'",
2645 "sample"=>wfMsg("italic_sample"),
2646 "tip"=>wfMsg("italic_tip"),
2647 "key"=>"I"
2649 array( "image"=>"button_link.png",
2650 "open"=>"[[",
2651 "close"=>"]]",
2652 "sample"=>wfMsg("link_sample"),
2653 "tip"=>wfMsg("link_tip"),
2654 "key"=>"L"
2656 array( "image"=>"button_extlink.png",
2657 "open"=>"[",
2658 "close"=>"]",
2659 "sample"=>wfMsg("extlink_sample"),
2660 "tip"=>wfMsg("extlink_tip"),
2661 "key"=>"X"
2663 array( "image"=>"button_headline.png",
2664 "open"=>"\\n== ",
2665 "close"=>" ==\\n",
2666 "sample"=>wfMsg("headline_sample"),
2667 "tip"=>wfMsg("headline_tip"),
2668 "key"=>"H"
2670 array( "image"=>"button_image.png",
2671 "open"=>"[[".$wgLang->getNsText(NS_IMAGE).":",
2672 "close"=>"]]",
2673 "sample"=>wfMsg("image_sample"),
2674 "tip"=>wfMsg("image_tip"),
2675 "key"=>"D"
2677 array( "image"=>"button_media.png",
2678 "open"=>"[[".$wgLang->getNsText(NS_MEDIA).":",
2679 "close"=>"]]",
2680 "sample"=>wfMsg("media_sample"),
2681 "tip"=>wfMsg("media_tip"),
2682 "key"=>"M"
2684 array( "image"=>"button_math.png",
2685 "open"=>"\\<math\\>",
2686 "close"=>"\\</math\\>",
2687 "sample"=>wfMsg("math_sample"),
2688 "tip"=>wfMsg("math_tip"),
2689 "key"=>"C"
2691 array( "image"=>"button_nowiki.png",
2692 "open"=>"\\<nowiki\\>",
2693 "close"=>"\\</nowiki\\>",
2694 "sample"=>wfMsg("nowiki_sample"),
2695 "tip"=>wfMsg("nowiki_tip"),
2696 "key"=>"N"
2698 array( "image"=>"button_sig.png",
2699 "open"=>"--~~~~",
2700 "close"=>"",
2701 "sample"=>"",
2702 "tip"=>wfMsg("sig_tip"),
2703 "key"=>"Y"
2705 array( "image"=>"button_hr.png",
2706 "open"=>"\\n----\\n",
2707 "close"=>"",
2708 "sample"=>"",
2709 "tip"=>wfMsg("hr_tip"),
2710 "key"=>"R"
2713 $toolbar ="<script type='text/javascript'>\n/*<![CDATA[*/\n";
2715 $toolbar.="document.writeln(\"<div id='toolbar'>\");\n";
2716 foreach($toolarray as $tool) {
2718 $image=$wgStylePath.'/images/'.$tool['image'];
2719 $open=$tool['open'];
2720 $close=$tool['close'];
2721 $sample = addslashes( $tool['sample'] );
2723 // Note that we use the tip both for the ALT tag and the TITLE tag of the image.
2724 // Older browsers show a "speedtip" type message only for ALT.
2725 // Ideally these should be different, realistically they
2726 // probably don't need to be.
2727 $tip = addslashes( $tool['tip'] );
2729 #$key = $tool["key"];
2731 $toolbar.="addButton('$image','$tip','$open','$close','$sample');\n";
2734 $toolbar.="addInfobox('" . addslashes( wfMsg( "infobox" ) ) . "','" . addslashes(wfMsg("infobox_alert")) . "');\n";
2735 $toolbar.="document.writeln(\"</div>\");\n";
2737 $toolbar.="/*]]>*/\n</script>";
2738 return $toolbar;