Changed include path in response to report on #mediawiki. Problem was an aborted...
[mediawiki.git] / includes / Skin.php
blobbc460590f5d28a5eeccc92fd0820d192941bf3b0
1 <?php
3 require_once( 'Feed.php' );
4 require_once( 'Image.php' );
6 # See skin.doc
8 # These are the INTERNAL names, which get mapped
9 # directly to class names. For display purposes, the
10 # Language class has internationalized names
12 /* private */ $wgValidSkinNames = array(
13 'standard' => 'Standard',
14 'nostalgia' => 'Nostalgia',
15 'cologneblue' => 'CologneBlue'
17 if( $wgUsePHPTal ) {
18 #$wgValidSkinNames[] = 'PHPTal';
19 #$wgValidSkinNames['davinci'] = 'DaVinci';
20 #$wgValidSkinNames['mono'] = 'Mono';
21 $wgValidSkinNames['monobook'] = 'MonoBook';
22 $wgValidSkinNames['myskin'] = 'MySkin';
23 #$wgValidSkinNames['monobookminimal'] = 'MonoBookMinimal';
26 require_once( 'RecentChange.php' );
28 class RCCacheEntry extends RecentChange
30 var $secureName, $link;
31 var $curlink , $lastlink , $usertalklink , $versionlink ;
32 var $userlink, $timestamp, $watched;
34 function newFromParent( $rc )
36 $rc2 = new RCCacheEntry;
37 $rc2->mAttribs = $rc->mAttribs;
38 $rc2->mExtra = $rc->mExtra;
39 return $rc2;
41 } ;
43 class Skin {
45 /* private */ var $lastdate, $lastline;
46 var $linktrail ; # linktrail regexp
47 var $rc_cache ; # Cache for Enhanced Recent Changes
48 var $rcCacheIndex ; # Recent Changes Cache Counter for visibility toggle
49 var $rcMoveIndex;
51 function Skin()
53 $this->linktrail = wfMsg('linktrail');
56 function getSkinNames()
58 global $wgValidSkinNames;
59 return $wgValidSkinNames;
62 function getStylesheet()
64 return 'wikistandard.css';
66 function getSkinName() {
67 return "standard";
70 function qbSetting()
72 global $wgOut, $wgUser;
74 if ( $wgOut->isQuickbarSuppressed() ) { return 0; }
75 $q = $wgUser->getOption( 'quickbar' );
76 if ( '' == $q ) { $q = 0; }
77 return $q;
80 function initPage( &$out )
82 $fname = 'Skin::initPage';
83 wfProfileIn( $fname );
85 $out->addLink( array( 'rel' => 'shortcut icon', 'href' => '/favicon.ico' ) );
87 $this->addMetadataLinks($out);
89 wfProfileOut( $fname );
92 function addMetadataLinks( &$out ) {
93 global $wgTitle, $wgEnableDublinCoreRdf, $wgEnableCreativeCommonsRdf, $wgRdfMimeType, $action;
94 global $wgRightsPage, $wgRightsUrl;
96 if( $out->isArticleRelated() ) {
97 # note: buggy CC software only reads first "meta" link
98 if( $wgEnableCreativeCommonsRdf ) {
99 $out->addMetadataLink( array(
100 'title' => 'Creative Commons',
101 'type' => 'application/rdf+xml',
102 'href' => $wgTitle->getLocalURL( 'action=creativecommons') ) );
104 if( $wgEnableDublinCoreRdf ) {
105 $out->addMetadataLink( array(
106 'title' => 'Dublin Core',
107 'type' => 'application/rdf+xml',
108 'href' => $wgTitle->getLocalURL( 'action=dublincore' ) ) );
111 $copyright = '';
112 if( $wgRightsPage ) {
113 $copy = Title::newFromText( $wgRightsPage );
114 if( $copy ) {
115 $copyright = $copy->getLocalURL();
118 if( !$copyright && $wgRightsUrl ) {
119 $copyright = $wgRightsUrl;
121 if( $copyright ) {
122 $out->addLink( array(
123 'rel' => 'copyright',
124 'href' => $copyright ) );
128 function outputPage( &$out ) {
129 global $wgDebugComments;
131 wfProfileIn( 'Skin::outputPage' );
132 $this->initPage( $out );
133 $out->out( $out->headElement() );
135 $out->out( "\n<body" );
136 $ops = $this->getBodyOptions();
137 foreach ( $ops as $name => $val ) {
138 $out->out( " $name='$val'" );
140 $out->out( ">\n" );
141 if ( $wgDebugComments ) {
142 $out->out( "<!-- Wiki debugging output:\n" .
143 $out->mDebugtext . "-->\n" );
145 $out->out( $this->beforeContent() );
147 $out->out( $out->mBodytext . "\n" );
149 $out->out( $this->afterContent() );
151 wfProfileClose();
152 $out->out( $out->reportTime() );
154 $out->out( "\n</body></html>" );
157 function getHeadScripts() {
158 global $wgStylePath, $wgUser, $wgLang;
159 $r = "<script type=\"text/javascript\" src=\"{$wgStylePath}/wikibits.js\"></script>\n";
160 if( $wgUser->getID() != 0 ) { # logged in
161 $userpage = $wgLang->getNsText( Namespace::getUser() ) . ":" . $wgUser->getName();
162 $userjs = htmlspecialchars($this->makeUrl($userpage.'/'.$this->getSkinName().'.js', 'action=raw&ctype=text/javascript'));
163 $r .= '<script type="text/javascript" src="'.$userjs."\"></script>\n";
165 return $r;
168 # get the user/site-specific stylesheet, SkinPHPTal called from RawPage.php (settings are cached that way)
169 function getUserStylesheet() {
170 global $wgOut, $wgStylePath, $wgLang, $wgUser, $wgRequest, $wgTitle;
171 $sheet = $this->getStylesheet();
172 $action = $wgRequest->getText('action');
173 $s = "@import \"$wgStylePath/$sheet\";\n";
174 if($wgLang->isRTL()) $s .= "@import \"$wgStylePath/common_rtl.css\";\n";
175 if( $wgUser->getID() != 0 ) { # logged in
176 if($wgTitle->isCssSubpage() and $action == 'submit' and $wgTitle->userCanEditCssJsSubpage()) {
177 $s .= $wgRequest->getText('wpTextbox1');
178 } else {
179 $userpage = $wgLang->getNsText( Namespace::getUser() ) . ":" . $wgUser->getName();
180 $s.= '@import "'.$this->makeUrl($userpage.'/'.$this->getSkinName(), 'action=raw&ctype=text/css').'";'."\n";
183 $s .= $this->doGetUserStyles();
184 return $s."\n";
186 # placeholder, returns generated js in monobook
187 function getUserJs() {
188 return;
191 function getUserStyles()
193 global $wgOut, $wgStylePath, $wgLang;
194 $s = "<style type='text/css'>\n";
195 $s .= "/*/*/\n"; # <-- Hide the styles from Netscape 4 without hiding them from IE/Mac
196 $s .= $this->getUserStylesheet();
197 $s .= "/* */\n";
198 $s .= "</style>\n";
199 return $s;
202 function doGetUserStyles()
204 global $wgUser;
206 $s = '';
207 if ( 1 == $wgUser->getOption( 'underline' ) ) {
208 # Don't override browser settings
209 } else {
210 # CHECK MERGE @@@
211 # Force no underline
212 $s .= 'a { ' .
213 "text-decoration: none; }\n";
215 if ( 1 == $wgUser->getOption( 'highlightbroken' ) ) {
216 $s .= "a.new, #quickbar a.new { color: #CC2200; }\n";
218 if ( 1 == $wgUser->getOption( 'justify' ) ) {
219 $s .= "#article { text-align: justify; }\n";
221 return $s;
224 function getBodyOptions()
226 global $wgUser, $wgTitle, $wgNamespaceBackgrounds, $wgOut, $wgRequest;
228 extract( $wgRequest->getValues( 'oldid', 'redirect', 'diff' ) );
230 if ( 0 != $wgTitle->getNamespace() ) {
231 $a = array( 'bgcolor' => '#ffffec' );
233 else $a = array( 'bgcolor' => '#FFFFFF' );
234 if($wgOut->isArticle() && $wgUser->getOption('editondblclick') &&
235 (!$wgTitle->isProtected() || $wgUser->isSysop()) ) {
236 $t = wfMsg( 'editthispage' );
237 $oid = $red = '';
238 if ( !empty($redirect) ) {
239 $red = "&redirect={$redirect}";
241 if ( !empty($oldid) && ! isset( $diff ) ) {
242 $oid = "&oldid={$oldid}";
244 $s = $wgTitle->getFullURL( "action=edit{$oid}{$red}" );
245 $s = 'document.location = "' .$s .'";';
246 $a += array ('ondblclick' => $s);
249 $a['onload'] = $wgOut->getOnloadHandler();
250 return $a;
253 function getExternalLinkAttributes( $link, $text, $class='' )
255 global $wgUser, $wgOut, $wgLang;
257 $link = urldecode( $link );
258 $link = $wgLang->checkTitleEncoding( $link );
259 $link = str_replace( '_', ' ', $link );
260 $link = wfEscapeHTML( $link );
262 $r = ($class != '') ? " class='$class'" : " class='external'";
264 if ( 1 == $wgUser->getOption( 'hover' ) ) {
265 $r .= " title=\"{$link}\"";
267 return $r;
270 function getInternalLinkAttributes( $link, $text, $broken = false )
272 global $wgUser, $wgOut;
274 $link = urldecode( $link );
275 $link = str_replace( '_', ' ', $link );
276 $link = wfEscapeHTML( $link );
278 if ( $broken == 'stub' ) {
279 $r = ' class="stub"';
280 } else if ( $broken == 'yes' ) {
281 $r = ' class="new"';
282 } else {
283 $r = '';
286 if ( 1 == $wgUser->getOption( 'hover' ) ) {
287 $r .= " title=\"{$link}\"";
289 return $r;
292 function getInternalLinkAttributesObj( &$nt, $text, $broken = false )
294 global $wgUser, $wgOut;
296 if ( $broken == 'stub' ) {
297 $r = ' class="stub"';
298 } else if ( $broken == 'yes' ) {
299 $r = ' class="new"';
300 } else {
301 $r = '';
304 if ( 1 == $wgUser->getOption( 'hover' ) ) {
305 $r .= ' title ="' . $nt->getEscapedText() . '"';
307 return $r;
310 function getLogo()
312 global $wgLogo;
313 return $wgLogo;
316 # This will be called immediately after the <body> tag. Split into
317 # two functions to make it easier to subclass.
319 function beforeContent()
321 global $wgUser, $wgOut, $wgSiteNotice;
323 if( $wgSiteNotice ) {
324 $note = "\n<div id='siteNotice'>$wgSiteNotice</div>\n";
325 } else {
326 $note = '';
328 return $this->doBeforeContent() . $note;
331 function doBeforeContent()
333 global $wgUser, $wgOut, $wgTitle, $wgLang;
334 $fname = 'Skin::doBeforeContent';
335 wfProfileIn( $fname );
337 $s = '';
338 $qb = $this->qbSetting();
340 if( $langlinks = $this->otherLanguages() ) {
341 $rows = 2;
342 $borderhack = '';
343 } else {
344 $rows = 1;
345 $langlinks = false;
346 $borderhack = 'class="top"';
349 $s .= "\n<div id='content'>\n<div id='topbar'>\n" .
350 "<table border='0' cellspacing='0' width='98%'>\n<tr>\n";
352 $shove = ($qb != 0);
353 $left = ($qb == 1 || $qb == 3);
354 if($wgLang->isRTL()) $left = !$left;
356 if ( !$shove ) {
357 $s .= "<td class='top' align='left' valign='top' rowspan='{$rows}'>\n" .
358 $this->logoText() . '</td>';
359 } elseif( $left ) {
360 $s .= $this->getQuickbarCompensator( $rows );
362 $l = $wgLang->isRTL() ? 'right' : 'left';
363 $s .= "<td {$borderhack} align='$l' valign='top'>\n";
365 $s .= $this->topLinks() ;
366 $s .= "<p class='subtitle'>" . $this->pageTitleLinks() . "</p>\n";
368 $r = $wgLang->isRTL() ? "left" : "right";
369 $s .= "</td>\n<td {$borderhack} valign='top' align='$r' nowrap='nowrap'>";
370 $s .= $this->nameAndLogin();
371 $s .= "\n<br />" . $this->searchForm() . "</td>";
373 if ( $langlinks ) {
374 $s .= "</tr>\n<tr>\n<td class='top' colspan=\"2\">$langlinks</td>\n";
377 if ( $shove && !$left ) { # Right
378 $s .= $this->getQuickbarCompensator( $rows );
380 $s .= "</tr>\n</table>\n</div>\n";
381 $s .= "\n<div id='article'>\n";
383 $s .= $this->pageTitle();
384 $s .= $this->pageSubtitle() ;
385 $s .= $this->getCategories();
386 wfProfileOut( $fname );
387 return $s;
390 function getCategoryLinks () {
391 global $wgOut, $wgTitle, $wgUser, $wgParser;
392 global $wgUseCategoryMagic, $wgUseCategoryBrowser, $wgLang;
393 if( !$wgUseCategoryMagic ) return '' ;
394 if( count( $wgOut->mCategoryLinks ) == 0 ) return '';
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;
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 $s .= ' ' . $this->getCredits();
786 return $s . ' ' . $this->getCopyright();
789 function getCredits() {
790 global $wgMaxCredits;
792 $s = '';
794 if (!isset($wgMaxCredits) || $wgMaxCredits == 0) {
795 $s = $this->lastModified();
796 } else {
797 $s = $this->getAuthorCredits();
798 if ($wgMaxCredits > 1) {
799 $s .= ' ' . $this->getContributorCredits();
803 return $s;
806 function getAuthorCredits() {
807 global $wgLang, $wgArticle;
809 $last_author = $wgArticle->getUser();
811 if ($last_author == 0) {
812 $author_credit = wfMsg('anonymous');
813 } else {
814 $real_name = User::whoIsReal($last_author);
815 if (!empty($real_name)) {
816 $author_credit = $real_name;
817 } else {
818 $author_credit = wfMsg('siteuser', User::whoIs($last_author));
822 $timestamp = $wgArticle->getTimestamp();
823 if ( $timestamp ) {
824 $d = $wgLang->timeanddate( $wgArticle->getTimestamp(), true );
825 } else {
826 $d = '';
828 return wfMsg('lastmodifiedby', $d, $author_credit);
831 function getContributorCredits() {
833 global $wgArticle, $wgMaxCredits, $wgLang;
835 # don't count last editor
837 $contributors = $wgArticle->getContributors($wgMaxCredits - 1);
839 $real_names = array();
840 $user_names = array();
842 # Sift for real versus user names
844 foreach ($contributors as $user_id => $user_parts) {
845 if ($user_id != 0) {
846 if (!empty($user_parts[1])) {
847 $real_names[$user_id] = $user_parts[1];
848 } else {
849 $user_names[$user_id] = $user_parts[0];
854 $real = $wgLang->listToText(array_values($real_names));
855 $user = $wgLang->listToText(array_values($user_names));
857 if (!empty($user)) {
858 $user = wfMsg('siteusers', $user);
861 if ($contributors[0] && $contributors[0][0] > 0) {
862 $anon = wfMsg('anonymous');
863 } else {
864 $anon = '';
867 $creds = $wgLang->listToText(array($real, $user, $anon));
869 return wfMsg('othercontribs', $creds);
872 function getCopyright() {
873 global $wgRightsPage, $wgRightsUrl, $wgRightsText;
874 $out = '';
875 if( $wgRightsPage ) {
876 $link = $this->makeKnownLink( $wgRightsPage, $wgRightsText );
877 } elseif( $wgRightsUrl ) {
878 $link = $this->makeExternalLink( $wgRightsUrl, $wgRightsText );
879 } else {
880 # Give up now
881 return $out;
883 $out .= wfMsg( 'copyright', $link );
884 return $out;
887 function getCopyrightIcon() {
888 global $wgRightsPage, $wgRightsUrl, $wgRightsText, $wgRightsIcon;
889 $out = '';
890 if( $wgRightsIcon ) {
891 $icon = htmlspecialchars( $wgRightsIcon );
892 if( $wgRightsUrl ) {
893 $url = htmlspecialchars( $wgRightsUrl );
894 $out .= '<a href="'.$url.'">';
896 $text = htmlspecialchars( $wgRightsText );
897 $out .= "<img src=\"$icon\" alt='$text' />";
898 if( $wgRightsUrl ) {
899 $out .= '</a>';
902 return $out;
905 function getPoweredBy() {
906 global $wgStylePath;
907 $url = htmlspecialchars( "$wgStylePath/images/poweredby_mediawiki_88x31.png" );
908 $img = '<a href="http://www.mediawiki.org/"><img src="'.$url.'" alt="MediaWiki" /></a>';
909 return $img;
912 function lastModified()
914 global $wgLang, $wgArticle;
916 $timestamp = $wgArticle->getTimestamp();
917 if ( $timestamp ) {
918 $d = $wgLang->timeanddate( $wgArticle->getTimestamp(), true );
919 $s = ' ' . wfMsg( 'lastmodified', $d );
920 } else {
921 $s = '';
923 return $s;
926 function logoText( $align = '' )
928 if ( '' != $align ) { $a = ' align="'.$align.'"'; }
929 else { $a = ''; }
931 $mp = wfMsg( 'mainpage' );
932 $titleObj = Title::newFromText( $mp );
933 $s = '<a href="' . $titleObj->escapeLocalURL()
934 . '"><img'.$a.' src="'
935 . $this->getLogo() . '" alt="' . "[{$mp}]\" /></a>";
936 return $s;
939 function quickBar()
941 global $wgOut, $wgTitle, $wgUser, $wgRequest, $wgLang;
942 global $wgDisableUploads, $wgRemoteUploads;
944 $fname = 'Skin::quickBar';
945 wfProfileIn( $fname );
947 $action = $wgRequest->getText( 'action' );
948 $wpPreview = $wgRequest->getBool( 'wpPreview' );
949 $tns=$wgTitle->getNamespace();
951 $s = "\n<div id='quickbar'>";
952 $s .= "\n" . $this->logoText() . "\n<hr class='sep' />";
954 $sep = "\n<br />";
955 $s .= $this->mainPageLink()
956 . $sep . $this->specialLink( 'recentchanges' )
957 . $sep . $this->specialLink( 'randompage' );
958 if ($wgUser->getID()) {
959 $s.= $sep . $this->specialLink( 'watchlist' ) ;
960 $s .= $sep .$this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
961 wfMsg( 'mycontris' ), 'target=' . wfUrlencode($wgUser->getName() ) );
964 // only show watchlist link if logged in
965 if ( wfMsg ( 'currentevents' ) != '-' ) $s .= $sep . $this->makeKnownLink( wfMsg( 'currentevents' ), '' ) ;
966 $s .= "\n<br /><hr class='sep' />";
967 $articleExists = $wgTitle->getArticleId();
968 if ( $wgOut->isArticle() || $action =='edit' || $action =='history' || $wpPreview) {
969 if($wgOut->isArticle()) {
970 $s .= '<strong>' . $this->editThisPage() . '</strong>';
971 } else { # backlink to the article in edit or history mode
972 if($articleExists){ # no backlink if no article
973 switch($tns) {
974 case 0:
975 $text = wfMsg('articlepage');
976 break;
977 case 1:
978 $text = wfMsg('viewtalkpage');
979 break;
980 case 2:
981 $text = wfMsg('userpage');
982 break;
983 case 3:
984 $text = wfMsg('viewtalkpage');
985 break;
986 case 4:
987 $text = wfMsg('wikipediapage');
988 break;
989 case 5:
990 $text = wfMsg('viewtalkpage');
991 break;
992 case 6:
993 $text = wfMsg('imagepage');
994 break;
995 case 7:
996 $text = wfMsg('viewtalkpage');
997 break;
998 default:
999 $text= wfMsg('articlepage');
1002 $link = $wgTitle->getText();
1003 if ($nstext = $wgLang->getNsText($tns) ) { # add namespace if necessary
1004 $link = $nstext . ':' . $link ;
1007 $s .= $this->makeLink( $link, $text );
1008 } elseif( $wgTitle->getNamespace() != Namespace::getSpecial() ) {
1009 # we just throw in a "New page" text to tell the user that he's in edit mode,
1010 # and to avoid messing with the separator that is prepended to the next item
1011 $s .= '<strong>' . wfMsg('newpage') . '</strong>';
1017 if( $tns%2 && $action!='edit' && !$wpPreview) {
1018 $s.= '<br />'.$this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg('postcomment'),'action=edit&section=new');
1022 watching could cause problems in edit mode:
1023 if user edits article, then loads "watch this article" in background and then saves
1024 article with "Watch this article" checkbox disabled, the article is transparently
1025 unwatched. Therefore we do not show the "Watch this page" link in edit mode
1027 if ( 0 != $wgUser->getID() && $articleExists) {
1028 if($action!='edit' && $action != 'submit' )
1030 $s .= $sep . $this->watchThisPage();
1032 if ( $wgTitle->userCanEdit() )
1033 $s .= $sep . $this->moveThisPage();
1035 if ( $wgUser->isSysop() and $articleExists ) {
1036 $s .= $sep . $this->deleteThisPage() .
1037 $sep . $this->protectThisPage();
1039 $s .= $sep . $this->talkLink();
1040 if ($articleExists && $action !='history') {
1041 $s .= $sep . $this->historyLink();
1043 $s.=$sep . $this->whatLinksHere();
1045 if($wgOut->isArticleRelated()) {
1046 $s .= $sep . $this->watchPageLinksLink();
1049 if ( Namespace::getUser() == $wgTitle->getNamespace()
1050 || $wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser())
1053 $id=User::idFromName($wgTitle->getText());
1054 $ip=User::isIP($wgTitle->getText());
1056 if($id||$ip) {
1057 $s .= $sep . $this->userContribsLink();
1059 if ( 0 != $wgUser->getID() ) {
1060 if($id) { # can only email real users
1061 $s .= $sep . $this->emailUserLink();
1065 $s .= "\n<br /><hr class='sep' />";
1068 if ( 0 != $wgUser->getID() && ( !$wgDisableUploads || $wgRemoteUploads ) ) {
1069 $s .= $this->specialLink( 'upload' ) . $sep;
1071 $s .= $this->specialLink( 'specialpages' )
1072 . $sep . $this->bugReportsLink();
1074 global $wgSiteSupportPage;
1075 if( $wgSiteSupportPage ) {
1076 $s .= "\n<br /><a href=\"" . htmlspecialchars( $wgSiteSupportPage ) .
1077 '" class="internal">' . wfMsg( 'sitesupport' ) . '</a>';
1080 $s .= "\n<br /></div>\n";
1081 wfProfileOut( $fname );
1082 return $s;
1085 function specialPagesList()
1087 global $wgUser, $wgOut, $wgLang, $wgServer, $wgRedirectScript;
1088 $a = array();
1089 $pages = SpecialPage::getPages();
1091 foreach ( $pages[''] as $name => $page ) {
1092 $a[$name] = $page->getDescription();
1094 if ( $wgUser->isSysop() )
1096 foreach ( $pages['sysop'] as $name => $page ) {
1097 $a[$name] = $page->getDescription();
1100 if ( $wgUser->isDeveloper() )
1102 foreach ( $pages['developer'] as $name => $page ) {
1103 $a[$name] = $page->getDescription() ;
1106 $go = wfMsg( 'go' );
1107 $sp = wfMsg( 'specialpages' );
1108 $spp = $wgLang->specialPage( 'Specialpages' );
1110 $s = '<form id="specialpages" method="get" class="inline" ' .
1111 'action="' . htmlspecialchars( "{$wgServer}{$wgRedirectScript}" ) . "\">\n";
1112 $s .= "<select name=\"wpDropdown\">\n";
1113 $s .= "<option value=\"{$spp}\">{$sp}</option>\n";
1115 foreach ( $a as $name => $desc ) {
1116 $p = $wgLang->specialPage( $name );
1117 $s .= "<option value=\"{$p}\">{$desc}</option>\n";
1119 $s .= "</select>\n";
1120 $s .= "<input type='submit' value=\"{$go}\" name='redirect' />\n";
1121 $s .= "</form>\n";
1122 return $s;
1125 function mainPageLink()
1127 $mp = wfMsg( 'mainpage' );
1128 $s = $this->makeKnownLink( $mp, $mp );
1129 return $s;
1132 function copyrightLink()
1134 $s = $this->makeKnownLink( wfMsg( 'copyrightpage' ),
1135 wfMsg( 'copyrightpagename' ) );
1136 return $s;
1139 function aboutLink()
1141 $s = $this->makeKnownLink( wfMsg( 'aboutpage' ),
1142 wfMsg( 'aboutwikipedia' ) );
1143 return $s;
1147 function disclaimerLink()
1149 $s = $this->makeKnownLink( wfMsg( 'disclaimerpage' ),
1150 wfMsg( 'disclaimers' ) );
1151 return $s;
1154 function editThisPage()
1156 global $wgOut, $wgTitle, $wgRequest;
1158 $oldid = $wgRequest->getVal( 'oldid' );
1159 $diff = $wgRequest->getVal( 'diff' );
1160 $redirect = $wgRequest->getVal( 'redirect' );
1162 if ( ! $wgOut->isArticleRelated() ) {
1163 $s = wfMsg( 'protectedpage' );
1164 } else {
1165 $n = $wgTitle->getPrefixedText();
1166 if ( $wgTitle->userCanEdit() ) {
1167 $t = wfMsg( 'editthispage' );
1168 } else {
1169 #$t = wfMsg( "protectedpage" );
1170 $t = wfMsg( 'viewsource' );
1172 $oid = $red = '';
1174 if ( !is_null( $redirect ) ) { $red = "&redirect={$redirect}"; }
1175 if ( $oldid && ! isset( $diff ) ) {
1176 $oid = "&oldid={$oldid}";
1178 $s = $this->makeKnownLink( $n, $t, "action=edit{$oid}{$red}" );
1180 return $s;
1183 function deleteThisPage()
1185 global $wgUser, $wgOut, $wgTitle, $wgRequest;
1187 $diff = $wgRequest->getVal( 'diff' );
1188 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
1189 $n = $wgTitle->getPrefixedText();
1190 $t = wfMsg( 'deletethispage' );
1192 $s = $this->makeKnownLink( $n, $t, 'action=delete' );
1193 } else {
1194 $s = '';
1196 return $s;
1199 function protectThisPage()
1201 global $wgUser, $wgOut, $wgTitle, $wgRequest;
1203 $diff = $wgRequest->getVal( 'diff' );
1204 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
1205 $n = $wgTitle->getPrefixedText();
1207 if ( $wgTitle->isProtected() ) {
1208 $t = wfMsg( 'unprotectthispage' );
1209 $q = 'action=unprotect';
1210 } else {
1211 $t = wfMsg( 'protectthispage' );
1212 $q = 'action=protect';
1214 $s = $this->makeKnownLink( $n, $t, $q );
1215 } else {
1216 $s = '';
1218 return $s;
1221 function watchThisPage()
1223 global $wgUser, $wgOut, $wgTitle;
1225 if ( $wgOut->isArticleRelated() ) {
1226 $n = $wgTitle->getPrefixedText();
1228 if ( $wgTitle->userIsWatching() ) {
1229 $t = wfMsg( 'unwatchthispage' );
1230 $q = 'action=unwatch';
1231 } else {
1232 $t = wfMsg( 'watchthispage' );
1233 $q = 'action=watch';
1235 $s = $this->makeKnownLink( $n, $t, $q );
1236 } else {
1237 $s = wfMsg( 'notanarticle' );
1239 return $s;
1242 function moveThisPage()
1244 global $wgTitle, $wgLang;
1246 if ( $wgTitle->userCanEdit() ) {
1247 $s = $this->makeKnownLink( $wgLang->specialPage( 'Movepage' ),
1248 wfMsg( 'movethispage' ), 'target=' . $wgTitle->getPrefixedURL() );
1249 } // no message if page is protected - would be redundant
1250 return $s;
1253 function historyLink()
1255 global $wgTitle;
1257 $s = $this->makeKnownLink( $wgTitle->getPrefixedText(),
1258 wfMsg( 'history' ), 'action=history' );
1259 return $s;
1262 function whatLinksHere()
1264 global $wgTitle, $wgLang;
1266 $s = $this->makeKnownLink( $wgLang->specialPage( 'Whatlinkshere' ),
1267 wfMsg( 'whatlinkshere' ), 'target=' . $wgTitle->getPrefixedURL() );
1268 return $s;
1271 function userContribsLink()
1273 global $wgTitle, $wgLang;
1275 $s = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
1276 wfMsg( 'contributions' ), 'target=' . $wgTitle->getPartialURL() );
1277 return $s;
1280 function emailUserLink()
1282 global $wgTitle, $wgLang;
1284 $s = $this->makeKnownLink( $wgLang->specialPage( 'Emailuser' ),
1285 wfMsg( 'emailuser' ), 'target=' . $wgTitle->getPartialURL() );
1286 return $s;
1289 function watchPageLinksLink()
1291 global $wgOut, $wgTitle, $wgLang;
1293 if ( ! $wgOut->isArticleRelated() ) {
1294 $s = '(' . wfMsg( 'notanarticle' ) . ')';
1295 } else {
1296 $s = $this->makeKnownLink( $wgLang->specialPage(
1297 'Recentchangeslinked' ), wfMsg( 'recentchangeslinked' ),
1298 'target=' . $wgTitle->getPrefixedURL() );
1300 return $s;
1303 function otherLanguages()
1305 global $wgOut, $wgLang, $wgTitle, $wgUseNewInterlanguage;
1307 $a = $wgOut->getLanguageLinks();
1308 if ( 0 == count( $a ) ) {
1309 if ( !$wgUseNewInterlanguage ) return '';
1310 $ns = $wgLang->getNsIndex ( $wgTitle->getNamespace () ) ;
1311 if ( $ns != 0 AND $ns != 1 ) return '' ;
1312 $pn = 'Intl' ;
1313 $x = 'mode=addlink&xt='.$wgTitle->getDBkey() ;
1314 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1315 wfMsg( 'intl' ) , $x );
1318 if ( !$wgUseNewInterlanguage ) {
1319 $s = wfMsg( 'otherlanguages' ) . ': ';
1320 } else {
1321 global $wgLanguageCode ;
1322 $x = 'mode=zoom&xt='.$wgTitle->getDBkey() ;
1323 $x .= '&xl='.$wgLanguageCode ;
1324 $s = $this->makeKnownLink( $wgLang->specialPage( 'Intl' ),
1325 wfMsg( 'otherlanguages' ) , $x ) . ': ' ;
1328 $s = wfMsg( 'otherlanguages' ) . ': ';
1329 $first = true;
1330 if($wgLang->isRTL()) $s .= '<span dir="LTR">';
1331 foreach( $a as $l ) {
1332 if ( ! $first ) { $s .= ' | '; }
1333 $first = false;
1335 $nt = Title::newFromText( $l );
1336 $url = $nt->getFullURL();
1337 $text = $wgLang->getLanguageName( $nt->getInterwiki() );
1339 if ( '' == $text ) { $text = $l; }
1340 $style = $this->getExternalLinkAttributes( $l, $text );
1341 $s .= "<a href=\"{$url}\"{$style}>{$text}</a>";
1343 if($wgLang->isRTL()) $s .= '</span>';
1344 return $s;
1347 function bugReportsLink()
1349 $s = $this->makeKnownLink( wfMsg( 'bugreportspage' ),
1350 wfMsg( 'bugreports' ) );
1351 return $s;
1354 function dateLink()
1356 global $wgLinkCache;
1357 $t1 = Title::newFromText( gmdate( 'F j' ) );
1358 $t2 = Title::newFromText( gmdate( 'Y' ) );
1360 $wgLinkCache->suspend();
1361 $id = $t1->getArticleID();
1362 $wgLinkCache->resume();
1364 if ( 0 == $id ) {
1365 $s = $this->makeBrokenLink( $t1->getText() );
1366 } else {
1367 $s = $this->makeKnownLink( $t1->getText() );
1369 $s .= ', ';
1371 $wgLinkCache->suspend();
1372 $id = $t2->getArticleID();
1373 $wgLinkCache->resume();
1375 if ( 0 == $id ) {
1376 $s .= $this->makeBrokenLink( $t2->getText() );
1377 } else {
1378 $s .= $this->makeKnownLink( $t2->getText() );
1380 return $s;
1383 function talkLink()
1385 global $wgLang, $wgTitle, $wgLinkCache;
1387 $tns = $wgTitle->getNamespace();
1388 if ( -1 == $tns ) { return ''; }
1390 $pn = $wgTitle->getText();
1391 $tp = wfMsg( 'talkpage' );
1392 if ( Namespace::isTalk( $tns ) ) {
1393 $lns = Namespace::getSubject( $tns );
1394 switch($tns) {
1395 case 1:
1396 $text = wfMsg('articlepage');
1397 break;
1398 case 3:
1399 $text = wfMsg('userpage');
1400 break;
1401 case 5:
1402 $text = wfMsg('wikipediapage');
1403 break;
1404 case 7:
1405 $text = wfMsg('imagepage');
1406 break;
1407 default:
1408 $text= wfMsg('articlepage');
1410 } else {
1412 $lns = Namespace::getTalk( $tns );
1413 $text=$tp;
1415 $n = $wgLang->getNsText( $lns );
1416 if ( '' == $n ) { $link = $pn; }
1417 else { $link = $n.':'.$pn; }
1419 $wgLinkCache->suspend();
1420 $s = $this->makeLink( $link, $text );
1421 $wgLinkCache->resume();
1423 return $s;
1426 function commentLink()
1428 global $wgLang, $wgTitle, $wgLinkCache;
1430 $tns = $wgTitle->getNamespace();
1431 if ( -1 == $tns ) { return ''; }
1433 $lns = ( Namespace::isTalk( $tns ) ) ? $tns : Namespace::getTalk( $tns );
1435 # assert Namespace::isTalk( $lns )
1437 $n = $wgLang->getNsText( $lns );
1438 $pn = $wgTitle->getText();
1440 $link = $n.':'.$pn;
1442 $wgLinkCache->suspend();
1443 $s = $this->makeKnownLink($link, wfMsg('postcomment'), 'action=edit&section=new');
1444 $wgLinkCache->resume();
1446 return $s;
1449 # After all the page content is transformed into HTML, it makes
1450 # a final pass through here for things like table backgrounds.
1452 function transformContent( $text )
1454 return $text;
1457 # Note: This function MUST call getArticleID() on the link,
1458 # otherwise the cache won't get updated properly. See LINKCACHE.DOC.
1460 function makeLink( $title, $text = '', $query = '', $trail = '' ) {
1461 wfProfileIn( 'Skin::makeLink' );
1462 $nt = Title::newFromText( $title );
1463 if ($nt) {
1464 $result = $this->makeLinkObj( Title::newFromText( $title ), $text, $query, $trail );
1465 } else {
1466 wfDebug( 'Invalid title passed to Skin::makeLink(): "'.$title."\"\n" );
1467 $result = $text == "" ? $title : $text;
1470 wfProfileOut( 'Skin::makeLink' );
1471 return $result;
1474 function makeKnownLink( $title, $text = '', $query = '', $trail = '', $prefix = '',$aprops = '') {
1475 $nt = Title::newFromText( $title );
1476 if ($nt) {
1477 return $this->makeKnownLinkObj( Title::newFromText( $title ), $text, $query, $trail, $prefix , $aprops );
1478 } else {
1479 wfDebug( 'Invalid title passed to Skin::makeKnownLink(): "'.$title."\"\n" );
1480 return $text == '' ? $title : $text;
1484 function makeBrokenLink( $title, $text = '', $query = '', $trail = '' ) {
1485 $nt = Title::newFromText( $title );
1486 if ($nt) {
1487 return $this->makeBrokenLinkObj( Title::newFromText( $title ), $text, $query, $trail );
1488 } else {
1489 wfDebug( 'Invalid title passed to Skin::makeBrokenLink(): "'.$title."\"\n" );
1490 return $text == '' ? $title : $text;
1494 function makeStubLink( $title, $text = '', $query = '', $trail = '' ) {
1495 $nt = Title::newFromText( $title );
1496 if ($nt) {
1497 return $this->makeStubLinkObj( Title::newFromText( $title ), $text, $query, $trail );
1498 } else {
1499 wfDebug( 'Invalid title passed to Skin::makeStubLink(): "'.$title."\"\n" );
1500 return $text == '' ? $title : $text;
1504 # Pass a title object, not a title string
1505 function makeLinkObj( &$nt, $text= '', $query = '', $trail = '', $prefix = '' )
1507 global $wgOut, $wgUser;
1508 if ( $nt->isExternal() ) {
1509 $u = $nt->getFullURL();
1510 $link = $nt->getPrefixedURL();
1511 if ( '' == $text ) { $text = $nt->getPrefixedText(); }
1512 $style = $this->getExternalLinkAttributes( $link, $text, 'extiw' );
1514 $inside = '';
1515 if ( '' != $trail ) {
1516 if ( preg_match( '/^([a-z]+)(.*)$$/sD', $trail, $m ) ) {
1517 $inside = $m[1];
1518 $trail = $m[2];
1521 $retVal = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1522 } elseif ( 0 == $nt->getNamespace() && "" == $nt->getText() ) {
1523 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1524 } elseif ( ( -1 == $nt->getNamespace() ) ||
1525 ( Namespace::getImage() == $nt->getNamespace() ) ) {
1526 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1527 } else {
1528 $aid = $nt->getArticleID() ;
1529 if ( 0 == $aid ) {
1530 $retVal = $this->makeBrokenLinkObj( $nt, $text, $query, $trail, $prefix );
1531 } else {
1532 $threshold = $wgUser->getOption('stubthreshold') ;
1533 if ( $threshold > 0 ) {
1534 $res = wfQuery ( "SELECT LENGTH(cur_text) AS x, cur_namespace, cur_is_redirect FROM cur WHERE cur_id='{$aid}'", DB_READ ) ;
1536 if ( wfNumRows( $res ) > 0 ) {
1537 $s = wfFetchObject( $res );
1538 $size = $s->x;
1539 if ( $s->cur_is_redirect OR $s->cur_namespace != 0 ) {
1540 $size = $threshold*2 ; # Really big
1542 wfFreeResult( $res );
1543 } else {
1544 $size = $threshold*2 ; # Really big
1546 } else {
1547 $size = 1 ;
1549 if ( $size < $threshold ) {
1550 $retVal = $this->makeStubLinkObj( $nt, $text, $query, $trail, $prefix );
1551 } else {
1552 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1556 return $retVal;
1559 # Pass a title object, not a title string
1560 function makeKnownLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' , $aprops = '')
1562 global $wgOut, $wgTitle;
1564 $fname = 'Skin::makeKnownLinkObj';
1565 wfProfileIn( $fname );
1567 $link = $nt->getPrefixedURL();
1569 if ( '' == $link ) {
1570 $u = '';
1571 if ( '' == $text ) {
1572 $text = htmlspecialchars( $nt->getFragment() );
1574 } else {
1575 $u = $nt->escapeLocalURL( $query );
1577 if ( '' != $nt->getFragment() ) {
1578 $u .= '#' . htmlspecialchars( $nt->getFragment() );
1580 if ( '' == $text ) {
1581 $text = htmlspecialchars( $nt->getPrefixedText() );
1583 $style = $this->getInternalLinkAttributesObj( $nt, $text );
1585 $inside = '';
1586 if ( '' != $trail ) {
1587 if ( preg_match( $this->linktrail, $trail, $m ) ) {
1588 $inside = $m[1];
1589 $trail = $m[2];
1592 $r = "<a href=\"{$u}\"{$style}{$aprops}>{$prefix}{$text}{$inside}</a>{$trail}";
1593 wfProfileOut( $fname );
1594 return $r;
1597 # Pass a title object, not a title string
1598 function makeBrokenLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
1600 global $wgOut, $wgUser;
1602 $fname = 'Skin::makeBrokenLinkObj';
1603 wfProfileIn( $fname );
1605 if ( '' == $query ) {
1606 $q = 'action=edit';
1607 } else {
1608 $q = 'action=edit&'.$query;
1610 $u = $nt->escapeLocalURL( $q );
1612 if ( '' == $text ) {
1613 $text = htmlspecialchars( $nt->getPrefixedText() );
1615 $style = $this->getInternalLinkAttributesObj( $nt, $text, "yes" );
1617 $inside = '';
1618 if ( '' != $trail ) {
1619 if ( preg_match( $this->linktrail, $trail, $m ) ) {
1620 $inside = $m[1];
1621 $trail = $m[2];
1624 if ( $wgUser->getOption( 'highlightbroken' ) ) {
1625 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1626 } else {
1627 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>?</a>{$trail}";
1630 wfProfileOut( $fname );
1631 return $s;
1634 # Pass a title object, not a title string
1635 function makeStubLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
1637 global $wgOut, $wgUser;
1639 $link = $nt->getPrefixedURL();
1641 $u = $nt->escapeLocalURL( $query );
1643 if ( '' == $text ) {
1644 $text = htmlspecialchars( $nt->getPrefixedText() );
1646 $style = $this->getInternalLinkAttributesObj( $nt, $text, 'stub' );
1648 $inside = '';
1649 if ( '' != $trail ) {
1650 if ( preg_match( $this->linktrail, $trail, $m ) ) {
1651 $inside = $m[1];
1652 $trail = $m[2];
1655 if ( $wgUser->getOption( 'highlightbroken' ) ) {
1656 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1657 } else {
1658 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>!</a>{$trail}";
1660 return $s;
1663 function makeSelfLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
1665 $u = $nt->escapeLocalURL( $query );
1666 if ( '' == $text ) {
1667 $text = htmlspecialchars( $nt->getPrefixedText() );
1669 $inside = '';
1670 if ( '' != $trail ) {
1671 if ( preg_match( $this->linktrail, $trail, $m ) ) {
1672 $inside = $m[1];
1673 $trail = $m[2];
1676 return "<strong>{$prefix}{$text}{$inside}</strong>{$trail}";
1679 /* these are used extensively in SkinPHPTal, but also some other places */
1680 /*static*/ function makeSpecialUrl( $name, $urlaction='' ) {
1681 $title = Title::makeTitle( NS_SPECIAL, $name );
1682 $this->checkTitle($title, $name);
1683 return $title->getLocalURL( $urlaction );
1685 /*static*/ function makeTalkUrl ( $name, $urlaction='' ) {
1686 $title = Title::newFromText( $name );
1687 $title = $title->getTalkPage();
1688 $this->checkTitle($title, $name);
1689 return $title->getLocalURL( $urlaction );
1691 /*static*/ function makeArticleUrl ( $name, $urlaction='' ) {
1692 $title = Title::newFromText( $name );
1693 $title= $title->getSubjectPage();
1694 $this->checkTitle($title, $name);
1695 return $title->getLocalURL( $urlaction );
1697 /*static*/ function makeI18nUrl ( $name, $urlaction='' ) {
1698 $title = Title::newFromText( wfMsg($name) );
1699 $this->checkTitle($title, $name);
1700 return $title->getLocalURL( $urlaction );
1702 /*static*/ function makeUrl ( $name, $urlaction='' ) {
1703 $title = Title::newFromText( $name );
1704 $this->checkTitle($title, $name);
1705 return $title->getLocalURL( $urlaction );
1707 # this can be passed the NS number as defined in Language.php
1708 /*static*/ function makeNSUrl( $name, $urlaction='', $namespace=0 ) {
1709 $title = Title::makeTitle( $namespace, $name );
1710 $this->checkTitle($title, $name);
1711 return $title->getLocalURL( $urlaction );
1714 /* these return an array with the 'href' and boolean 'exists' */
1715 /*static*/ function makeUrlDetails ( $name, $urlaction='' ) {
1716 $title = Title::newFromText( $name );
1717 $this->checkTitle($title, $name);
1718 return array(
1719 'href' => $title->getLocalURL( $urlaction ),
1720 'exists' => $title->getArticleID() != 0?true:false
1723 /*static*/ function makeTalkUrlDetails ( $name, $urlaction='' ) {
1724 $title = Title::newFromText( $name );
1725 $title = $title->getTalkPage();
1726 $this->checkTitle($title, $name);
1727 return array(
1728 'href' => $title->getLocalURL( $urlaction ),
1729 'exists' => $title->getArticleID() != 0?true:false
1732 /*static*/ function makeArticleUrlDetails ( $name, $urlaction='' ) {
1733 $title = Title::newFromText( $name );
1734 $title= $title->getSubjectPage();
1735 $this->checkTitle($title, $name);
1736 return array(
1737 'href' => $title->getLocalURL( $urlaction ),
1738 'exists' => $title->getArticleID() != 0?true:false
1741 /*static*/ function makeI18nUrlDetails ( $name, $urlaction='' ) {
1742 $title = Title::newFromText( wfMsg($name) );
1743 $this->checkTitle($title, $name);
1744 return array(
1745 'href' => $title->getLocalURL( $urlaction ),
1746 'exists' => $title->getArticleID() != 0?true:false
1750 # make sure we have some title to operate on
1751 /*static*/ function checkTitle ( &$title, &$name ) {
1752 if(!is_object($title)) {
1753 $title = Title::newFromText( $name );
1754 if(!is_object($title)) {
1755 $title = Title::newFromText( '<error: link target missing>' );
1760 function fnamePart( $url )
1762 $basename = strrchr( $url, '/' );
1763 if ( false === $basename ) { $basename = $url; }
1764 else { $basename = substr( $basename, 1 ); }
1765 return wfEscapeHTML( $basename );
1768 function makeImage( $url, $alt = '' )
1770 global $wgOut;
1772 if ( '' == $alt ) { $alt = $this->fnamePart( $url ); }
1773 $s = '<img src="'.$url.'" alt="'.$alt.'" />';
1774 return $s;
1777 function makeImageLink( $name, $url, $alt = '' ) {
1778 $nt = Title::makeTitle( Namespace::getImage(), $name );
1779 return $this->makeImageLinkObj( $nt, $alt );
1782 function makeImageLinkObj( $nt, $alt = '' ) {
1783 global $wgLang, $wgUseImageResize;
1784 $img = Image::newFromTitle( $nt );
1785 $url = $img->getURL();
1787 $align = '';
1788 $prefix = $postfix = '';
1790 if ( $wgUseImageResize ) {
1791 # Check if the alt text is of the form "options|alt text"
1792 # Options are:
1793 # * thumbnail make a thumbnail with enlarge-icon and caption, alignment depends on lang
1794 # * left no resizing, just left align. label is used for alt= only
1795 # * right same, but right aligned
1796 # * none same, but not aligned
1797 # * ___px scale to ___ pixels width, no aligning. e.g. use in taxobox
1798 # * center center the image
1799 # * framed Keep original image size, no magnify-button.
1801 $part = explode( '|', $alt);
1803 $mwThumb =& MagicWord::get( MAG_IMG_THUMBNAIL );
1804 $mwLeft =& MagicWord::get( MAG_IMG_LEFT );
1805 $mwRight =& MagicWord::get( MAG_IMG_RIGHT );
1806 $mwNone =& MagicWord::get( MAG_IMG_NONE );
1807 $mwWidth =& MagicWord::get( MAG_IMG_WIDTH );
1808 $mwCenter =& MagicWord::get( MAG_IMG_CENTER );
1809 $mwFramed =& MagicWord::get( MAG_IMG_FRAMED );
1810 $alt = $part[count($part)-1];
1812 $height = $framed = $thumb = false;
1814 foreach( $part as $key => $val ) {
1815 if ( ! is_null( $mwThumb->matchVariableStartToEnd($val) ) ) {
1816 $thumb=true;
1817 } elseif ( ! is_null( $mwRight->matchVariableStartToEnd($val) ) ) {
1818 # remember to set an alignment, don't render immediately
1819 $align = 'right';
1820 } elseif ( ! is_null( $mwLeft->matchVariableStartToEnd($val) ) ) {
1821 # remember to set an alignment, don't render immediately
1822 $align = 'left';
1823 } elseif ( ! is_null( $mwCenter->matchVariableStartToEnd($val) ) ) {
1824 # remember to set an alignment, don't render immediately
1825 $align = 'center';
1826 } elseif ( ! is_null( $mwNone->matchVariableStartToEnd($val) ) ) {
1827 # remember to set an alignment, don't render immediately
1828 $align = 'none';
1829 } elseif ( ! is_null( $match = $mwWidth->matchVariableStartToEnd($val) ) ) {
1830 # $match is the image width in pixels
1831 if ( preg_match( '/^([0-9]*)x([0-9]*)$/', $match, $m ) ) {
1832 $width = intval( $m[1] );
1833 $height = intval( $m[2] );
1834 } else {
1835 $width = intval($match);
1837 } elseif ( ! is_null( $mwFramed->matchVariableStartToEnd($val) ) ) {
1838 $framed=true;
1841 if ( 'center' == $align )
1843 $prefix = '<span style="text-align: center">';
1844 $postfix = '</span>';
1845 $align = 'none';
1848 if ( $thumb || $framed ) {
1850 # Create a thumbnail. Alignment depends on language
1851 # writing direction, # right aligned for left-to-right-
1852 # languages ("Western languages"), left-aligned
1853 # for right-to-left-languages ("Semitic languages")
1855 # If thumbnail width has not been provided, it is set
1856 # here to 180 pixels
1857 if ( $align == '' ) {
1858 $align = $wgLang->isRTL() ? 'left' : 'right';
1860 if ( ! isset($width) ) {
1861 $width = 180;
1863 return $prefix.$this->makeThumbLinkObj( $img, $alt, $align, $width, $height, $framed ).$postfix;
1865 } elseif ( isset($width) ) {
1867 # Create a resized image, without the additional thumbnail
1868 # features
1870 if ( ( ! $height === false )
1871 && ( $img->getHeight() * $width / $img->getWidth() > $height ) ) {
1872 print "height=$height<br>\nimg->getHeight() = ".$img->getHeight()."<br>\n";
1873 print 'rescaling by factor '. $height / $img->getHeight() . "<br>\n";
1874 $width = $img->getWidth() * $height / $img->getHeight();
1876 $url = $img->createThumb( $width );
1878 } # endif $wgUseImageResize
1880 if ( empty( $alt ) ) {
1881 $alt = preg_replace( '/\.(.+?)^/', '', $img->getName() );
1883 $alt = htmlspecialchars( $alt );
1885 $u = $nt->escapeLocalURL();
1886 if ( $url == '' )
1888 $s = str_replace( "$1", $img->getName(), wfMsg('missingimage') );
1889 $s .= "<br>{$alt}<br>{$url}<br>\n";
1890 } else {
1891 $s = '<a href="'.$u.'" class="image" title="'.$alt.'">' .
1892 '<img src="'.$url.'" alt="'.$alt.'" /></a>';
1894 if ( '' != $align ) {
1895 $s = "<div class=\"float{$align}\"><span>{$s}</span></div>";
1897 return str_replace("\n", ' ',$prefix.$s.$postfix);
1901 function makeThumbLinkObj( $img, $label = '', $align = 'right', $boxwidth = 180, $boxheight=false, $framed=false ) {
1902 global $wgStylePath, $wgLang;
1903 # $image = Title::makeTitle( Namespace::getImage(), $name );
1904 $url = $img->getURL();
1906 #$label = htmlspecialchars( $label );
1907 $alt = preg_replace( '/<[^>]*>/', '', $label);
1908 $alt = htmlspecialchars( $alt );
1910 if ( $img->exists() )
1912 $width = $img->getWidth();
1913 $height = $img->getHeight();
1914 } else {
1915 $width = $height = 200;
1917 if ( $framed )
1919 // Use image dimensions, don't scale
1920 $boxwidth = $width;
1921 $oboxwidth = $boxwidth + 2;
1922 $boxheight = $height;
1923 $thumbUrl = $url;
1924 } else {
1925 $h = intval( $height/($width/$boxwidth) );
1926 $oboxwidth = $boxwidth + 2;
1927 if ( ( ! $boxheight === false ) && ( $h > $boxheight ) )
1929 $boxwidth *= $boxheight/$h;
1930 } else {
1931 $boxheight = $h;
1933 $thumbUrl = $img->createThumb( $boxwidth );
1936 $u = $img->getEscapeLocalURL();
1938 $more = htmlspecialchars( wfMsg( 'thumbnail-more' ) );
1939 $magnifyalign = $wgLang->isRTL() ? 'left' : 'right';
1940 $textalign = $wgLang->isRTL() ? ' style="text-align:right"' : '';
1942 $s = "<div class=\"thumb t{$align}\"><div style=\"width:{$oboxwidth}px;\">";
1943 if ( $thumbUrl == '' ) {
1944 $s .= str_replace( "$1", $img->getName(), wfMsg('missingimage') );
1945 $zoomicon = '';
1946 } else {
1947 $s .= '<a href="'.$u.'" class="internal" title="'.$alt.'">'.
1948 '<img src="'.$thumbUrl.'" alt="'.$alt.'" ' .
1949 'width="'.$boxwidth.'" height="'.$boxheight.'" /></a>';
1950 if ( $framed ) {
1951 $zoomicon="";
1952 } else {
1953 $zoomicon = '<div class="magnify" style="float:'.$magnifyalign.'">'.
1954 '<a href="'.$u.'" class="internal" title="'.$more.'">'.
1955 '<img src="'.$wgStylePath.'/images/magnify-clip.png" ' .
1956 'width="15" height="11" alt="'.$more.'" /></a></div>';
1959 $s .= ' <div class="thumbcaption" '.$textalign.'>'.$zoomicon.$label."</div></div></div>";
1960 return str_replace("\n", ' ', $s);
1963 function makeMediaLink( $name, $url, $alt = "" ) {
1964 $nt = Title::makeTitle( Namespace::getMedia(), $name );
1965 return $this->makeMediaLinkObj( $nt, $alt );
1968 function makeMediaLinkObj( $nt, $alt = "" )
1970 if ( ! isset( $nt ) )
1972 ### HOTFIX. Instead of breaking, return empry string.
1973 $s = $alt;
1974 } else {
1975 $name = $nt->getDBKey();
1976 $url = Image::wfImageUrl( $name );
1977 if ( empty( $alt ) ) {
1978 $alt = preg_replace( '/\.(.+?)^/', '', $name );
1981 $u = htmlspecialchars( $url );
1982 $s = "<a href=\"{$u}\" class='internal' title=\"{$alt}\">{$alt}</a>";
1984 return $s;
1987 function specialLink( $name, $key = "" )
1989 global $wgLang;
1991 if ( '' == $key ) { $key = strtolower( $name ); }
1992 $pn = $wgLang->ucfirst( $name );
1993 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1994 wfMsg( $key ) );
1997 function makeExternalLink( $url, $text, $escape = true ) {
1998 $style = $this->getExternalLinkAttributes( $url, $text );
1999 $url = htmlspecialchars( $url );
2000 if( $escape ) {
2001 $text = htmlspecialchars( $text );
2003 return '<a href="'.$url.'"'.$style.'>'.$text.'</a>';
2006 # Called by history lists and recent changes
2009 # Returns text for the start of the tabular part of RC
2010 function beginRecentChangesList()
2012 $this->rc_cache = array() ;
2013 $this->rcMoveIndex = 0;
2014 $this->rcCacheIndex = 0 ;
2015 $this->lastdate = '';
2016 $this->rclistOpen = false;
2017 return '';
2020 function beginImageHistoryList()
2022 $s = "\n<h2>" . wfMsg( 'imghistory' ) . "</h2>\n" .
2023 "<p>" . wfMsg( 'imghistlegend' ) . "</p>\n".'<ul class="special">';
2024 return $s;
2027 # Returns text for the end of RC
2028 # If enhanced RC is in use, returns pretty much all the text
2029 function endRecentChangesList()
2031 $s = $this->recentChangesBlock() ;
2032 if( $this->rclistOpen ) {
2033 $s .= "</ul>\n";
2035 return $s;
2038 # Enhanced RC ungrouped line
2039 function recentChangesBlockLine ( $rcObj )
2041 global $wgStylePath, $wgLang ;
2043 # Get rc_xxxx variables
2044 extract( $rcObj->mAttribs ) ;
2045 $curIdEq = 'curid='.$rc_cur_id;
2047 # Spacer image
2048 $r = '' ;
2050 $r .= '<img src="'.$wgStylePath.'/images/Arr_.png" width="12" height="12" border="0" />' ;
2051 $r .= '<tt>' ;
2053 if ( $rc_type == RC_MOVE ) {
2054 $r .= '&nbsp;&nbsp;';
2055 } else {
2056 # M & N (minor & new)
2057 $M = wfMsg( 'minoreditletter' );
2058 $N = wfMsg( 'newpageletter' );
2060 if ( $rc_type == RC_NEW ) {
2061 $r .= $N ;
2062 } else {
2063 $r .= '&nbsp;' ;
2065 if ( $rc_minor ) {
2066 $r .= $M ;
2067 } else {
2068 $r .= '&nbsp;' ;
2072 # Timestamp
2073 $r .= ' '.$rcObj->timestamp.' ' ;
2074 $r .= '</tt>' ;
2076 # Article link
2077 $link = $rcObj->link ;
2078 if ( $rcObj->watched ) $link = '<strong>'.$link.'</strong>' ;
2079 $r .= $link ;
2081 # Cur
2082 $r .= ' (' ;
2083 $r .= $rcObj->curlink ;
2084 $r .= '; ' ;
2086 # Hist
2087 $r .= $this->makeKnownLinkObj( $rcObj->getTitle(), wfMsg( 'hist' ), $curIdEq.'&action=history' );
2089 # User/talk
2090 $r .= ') . . '.$rcObj->userlink ;
2091 $r .= $rcObj->usertalklink ;
2093 # Comment
2094 if ( $rc_comment != '' && $rc_type != RC_MOVE ) {
2095 $rc_comment=$this->formatComment($rc_comment);
2096 $r .= $wgLang->emphasize( ' ('.$rc_comment.')' );
2099 $r .= "<br />\n" ;
2100 return $r ;
2103 # Enhanced RC group
2104 function recentChangesBlockGroup ( $block )
2106 global $wgStylePath, $wgLang ;
2108 $r = '' ;
2109 $M = wfMsg( 'minoreditletter' );
2110 $N = wfMsg( 'newpageletter' );
2112 # Collate list of users
2113 $isnew = false ;
2114 $userlinks = array () ;
2115 foreach ( $block AS $rcObj ) {
2116 $oldid = $rcObj->mAttribs['rc_last_oldid'];
2117 if ( $rcObj->mAttribs['rc_new'] ) $isnew = true ;
2118 $u = $rcObj->userlink ;
2119 if ( !isset ( $userlinks[$u] ) ) $userlinks[$u] = 0 ;
2120 $userlinks[$u]++ ;
2123 # Sort the list and convert to text
2124 krsort ( $userlinks ) ;
2125 asort ( $userlinks ) ;
2126 $users = array () ;
2127 foreach ( $userlinks as $userlink => $count) {
2128 $text = $userlink ;
2129 if ( $count > 1 ) $text .= " ({$count}&times;)" ;
2130 array_push ( $users , $text ) ;
2132 $users = ' <font size="-1">['.implode('; ',$users).']</font>' ;
2134 # Arrow
2135 $rci = 'RCI'.$this->rcCacheIndex ;
2136 $rcl = 'RCL'.$this->rcCacheIndex ;
2137 $rcm = 'RCM'.$this->rcCacheIndex ;
2138 $toggleLink = "javascript:toggleVisibility('$rci','$rcm','$rcl')" ;
2139 $arrowdir = $wgLang->isRTL() ? 'l' : 'r';
2140 $tl = '<span id="'.$rcm.'"><a href="'.$toggleLink.'"><img src="'.$wgStylePath.'/images/Arr_'.$arrowdir.'.png" width="12" height="12" /></a></span>' ;
2141 $tl .= '<span id="'.$rcl.'" style="display:none"><a href="'.$toggleLink.'"><img src="'.$wgStylePath.'/images/Arr_d.png" width="12" height="12" /></a></span>' ;
2142 $r .= $tl ;
2144 # Main line
2145 # M/N
2146 $r .= '<tt>' ;
2147 if ( $isnew ) $r .= $N ;
2148 else $r .= '&nbsp;' ;
2149 $r .= '&nbsp;' ; # Minor
2151 # Timestamp
2152 $r .= ' '.$block[0]->timestamp.' ' ;
2153 $r .= '</tt>' ;
2155 # Article link
2156 $link = $block[0]->link ;
2157 if ( $block[0]->watched ) $link = '<strong>'.$link.'</strong>' ;
2158 $r .= $link ;
2160 $curIdEq = 'curid=' . $block[0]->mAttribs['rc_cur_id'];
2161 if ( $block[0]->mAttribs['rc_type'] != RC_LOG ) {
2162 # Changes
2163 $r .= ' ('.count($block).' ' ;
2164 if ( $isnew ) $r .= wfMsg('changes');
2165 else $r .= $this->makeKnownLinkObj( $block[0]->getTitle() , wfMsg('changes') ,
2166 $curIdEq.'&diff=0&oldid='.$oldid ) ;
2167 $r .= '; ' ;
2169 # History
2170 $r .= $this->makeKnownLinkObj( $block[0]->getTitle(), wfMsg( 'history' ), $curIdEq.'&action=history' );
2171 $r .= ')' ;
2174 $r .= $users ;
2175 $r .= "<br />\n" ;
2177 # Sub-entries
2178 $r .= '<div id="'.$rci.'" style="display:none">' ;
2179 foreach ( $block AS $rcObj ) {
2180 # Get rc_xxxx variables
2181 extract( $rcObj->mAttribs );
2183 $r .= '<img src="'.$wgStylePath.'/images/Arr_.png" width="12" height="12" />';
2184 $r .= '<tt>&nbsp; &nbsp; &nbsp; &nbsp;' ;
2185 if ( $rc_new ) $r .= $N ;
2186 else $r .= '&nbsp;' ;
2187 if ( $rc_minor ) $r .= $M ;
2188 else $r .= '&nbsp;' ;
2189 $r .= '</tt>' ;
2191 $o = '' ;
2192 if ( $rc_last_oldid != 0 ) {
2193 $o = 'oldid='.$rc_last_oldid ;
2195 if ( $rc_type == RC_LOG ) {
2196 $link = $rcObj->timestamp ;
2197 } else {
2198 $link = $this->makeKnownLinkObj( $rcObj->getTitle(), $rcObj->timestamp , "{$curIdEq}&$o" ) ;
2200 $link = '<tt>'.$link.'</tt>' ;
2202 $r .= $link ;
2203 $r .= ' (' ;
2204 $r .= $rcObj->curlink ;
2205 $r .= '; ' ;
2206 $r .= $rcObj->lastlink ;
2207 $r .= ') . . '.$rcObj->userlink ;
2208 $r .= $rcObj->usertalklink ;
2209 if ( $rc_comment != '' ) {
2210 $rc_comment=$this->formatComment($rc_comment);
2211 $r .= $wgLang->emphasize( ' ('.$rc_comment.')' ) ;
2213 $r .= "<br />\n" ;
2215 $r .= "</div>\n" ;
2217 $this->rcCacheIndex++ ;
2218 return $r ;
2221 # If enhanced RC is in use, this function takes the previously cached
2222 # RC lines, arranges them, and outputs the HTML
2223 function recentChangesBlock ()
2225 global $wgStylePath ;
2226 if ( count ( $this->rc_cache ) == 0 ) return '' ;
2227 $blockOut = '';
2228 foreach ( $this->rc_cache AS $secureName => $block ) {
2229 if ( count ( $block ) < 2 ) {
2230 $blockOut .= $this->recentChangesBlockLine ( array_shift ( $block ) ) ;
2231 } else {
2232 $blockOut .= $this->recentChangesBlockGroup ( $block ) ;
2236 return '<div>'.$blockOut.'</div>' ;
2239 # Called in a loop over all displayed RC entries
2240 # Either returns the line, or caches it for later use
2241 function recentChangesLine( &$rc, $watched = false )
2243 global $wgUser ;
2244 $usenew = $wgUser->getOption( 'usenewrc' );
2245 if ( $usenew )
2246 $line = $this->recentChangesLineNew ( $rc, $watched ) ;
2247 else
2248 $line = $this->recentChangesLineOld ( $rc, $watched ) ;
2249 return $line ;
2252 function recentChangesLineOld( &$rc, $watched = false )
2254 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds;
2256 # Extract DB fields into local scope
2257 extract( $rc->mAttribs );
2258 $curIdEq = 'curid=' . $rc_cur_id;
2260 # Make date header if necessary
2261 $date = $wgLang->date( $rc_timestamp, true);
2262 $s = '';
2263 if ( $date != $this->lastdate ) {
2264 if ( '' != $this->lastdate ) { $s .= "</ul>\n"; }
2265 $s .= "<h4>{$date}</h4>\n<ul class='special'>";
2266 $this->lastdate = $date;
2267 $this->rclistOpen = true;
2269 $s .= '<li> ';
2271 if ( $rc_type == RC_MOVE ) {
2272 # Diff
2273 $s .= '(' . wfMsg( 'diff' ) . ') (';
2274 # Hist
2275 $s .= $this->makeKnownLinkObj( $rc->getMovedToTitle(), wfMsg( 'hist' ), 'action=history' ) .
2276 ') . . ';
2278 # "[[x]] moved to [[y]]"
2280 $s .= wfMsg( '1movedto2', $this->makeKnownLinkObj( $rc->getTitle(), '', 'redirect=no' ),
2281 $this->makeKnownLinkObj( $rc->getMovedToTitle(), '' ) );
2283 } else {
2284 # Diff link
2285 if ( $rc_type == RC_NEW || $rc_type == RC_LOG ) {
2286 $diffLink = wfMsg( 'diff' );
2287 } else {
2288 $diffLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'diff' ),
2289 $curIdEq.'&diff='.$rc_this_oldid.'&oldid='.$rc_last_oldid ,'' ,'' , ' tabindex="'.$rc->counter.'"');
2291 $s .= '('.$diffLink.') (';
2293 # History link
2294 $s .= $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'hist' ), $curIdEq.'&action=history' );
2295 $s .= ') . . ';
2297 # M and N (minor and new)
2298 $M = wfMsg( 'minoreditletter' );
2299 $N = wfMsg( 'newpageletter' );
2300 if ( $rc_minor ) { $s .= ' <strong>'.$M.'</strong>'; }
2301 if ( $rc_type == RC_NEW ) { $s .= '<strong>'.$N.'</strong>'; }
2303 # Article link
2304 $articleLink = $this->makeKnownLinkObj( $rc->getTitle(), '' );
2306 if ( $watched ) {
2307 $articleLink = '<strong>'.$articleLink.'</strong>';
2309 $s .= ' '.$articleLink;
2313 # Timestamp
2314 $s .= '; ' . $wgLang->time( $rc_timestamp, true, $wgRCSeconds ) . ' . . ';
2316 # User link (or contributions for unregistered users)
2317 if ( 0 == $rc_user ) {
2318 $userLink = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
2319 $rc_user_text, 'target=' . $rc_user_text );
2320 } else {
2321 $userLink = $this->makeLink( $wgLang->getNsText( NS_USER ) . ':'.$rc_user_text, $rc_user_text );
2323 $s .= $userLink;
2325 # User talk link
2326 $talkname=$wgLang->getNsText(NS_TALK); # use the shorter name
2327 global $wgDisableAnonTalk;
2328 if( 0 == $rc_user && $wgDisableAnonTalk ) {
2329 $userTalkLink = '';
2330 } else {
2331 $utns=$wgLang->getNsText(NS_USER_TALK);
2332 $userTalkLink= $this->makeLink($utns . ':'.$rc_user_text, $talkname );
2334 # Block link
2335 $blockLink='';
2336 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2337 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2338 'Blockip' ), wfMsg( 'blocklink' ), 'ip='.$rc_user_text );
2341 if($blockLink) {
2342 if($userTalkLink) $userTalkLink .= ' | ';
2343 $userTalkLink .= $blockLink;
2345 if($userTalkLink) $s.=' ('.$userTalkLink.')';
2347 # Add comment
2348 if ( '' != $rc_comment && '*' != $rc_comment && $rc_type != RC_MOVE ) {
2349 $rc_comment=$this->formatComment($rc_comment);
2350 $s .= $wgLang->emphasize(' (' . $rc_comment . ')');
2352 $s .= "</li>\n";
2354 return $s;
2357 # function recentChangesLineNew( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched = false, $oldid = 0 , $diffid = 0 )
2358 function recentChangesLineNew( &$baseRC, $watched = false )
2360 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds;
2362 # Create a specialised object
2363 $rc = RCCacheEntry::newFromParent( $baseRC ) ;
2365 # Extract fields from DB into the function scope (rc_xxxx variables)
2366 extract( $rc->mAttribs );
2367 $curIdEq = 'curid=' . $rc_cur_id;
2369 # If it's a new day, add the headline and flush the cache
2370 $date = $wgLang->date( $rc_timestamp, true);
2371 $ret = '' ;
2372 if ( $date != $this->lastdate ) {
2373 # Process current cache
2374 $ret = $this->recentChangesBlock () ;
2375 $this->rc_cache = array() ;
2376 $ret .= "<h4>{$date}</h4>\n";
2377 $this->lastdate = $date;
2380 # Make article link
2381 if ( $rc_type == RC_MOVE ) {
2382 $clink = $this->makeKnownLinkObj( $rc->getTitle(), '', 'redirect=no' );
2383 $clink .= ' ' . wfMsg('movedto') . ' ';
2384 $clink .= $this->makeKnownLinkObj( $rc->getMovedToTitle(), '' );
2385 } else {
2386 $clink = $this->makeKnownLinkObj( $rc->getTitle(), '' ) ;
2389 $time = $wgLang->time( $rc_timestamp, true, $wgRCSeconds );
2390 $rc->watched = $watched ;
2391 $rc->link = $clink ;
2392 $rc->timestamp = $time;
2394 # Make "cur" link
2395 if ( ( $rc_type == RC_NEW && $rc_this_oldid == 0 ) || $rc_type == RC_LOG || $rc_type == RC_MOVE) {
2396 $curLink = wfMsg( 'cur' );
2397 } else {
2398 $curLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'cur' ),
2399 $curIdEq.'&diff=0&oldid='.$rc_this_oldid ,'' ,'' , ' tabindex="'.$baseRC->counter.'"' );
2402 # Make "last" link
2403 $titleObj = $rc->getTitle();
2404 if ( $rc_last_oldid == 0 || $rc_type == RC_LOG || $rc_type == RC_MOVE ) {
2405 $lastLink = wfMsg( 'last' );
2406 } else {
2407 $lastLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'last' ),
2408 $curIdEq.'&diff='.$rc_this_oldid.'&oldid='.$rc_last_oldid );
2411 # Make user link (or user contributions for unregistered users)
2412 if ( 0 == $rc_user ) {
2413 $userLink = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
2414 $rc_user_text, 'target=' . $rc_user_text );
2415 } else {
2416 $userLink = $this->makeLink( $wgLang->getNsText(
2417 Namespace::getUser() ) . ':'.$rc_user_text, $rc_user_text );
2420 $rc->userlink = $userLink ;
2421 $rc->lastlink = $lastLink ;
2422 $rc->curlink = $curLink ;
2424 # Make user talk link
2425 $utns=$wgLang->getNsText(NS_USER_TALK);
2426 $talkname=$wgLang->getNsText(NS_TALK); # use the shorter name
2427 $userTalkLink= $this->makeLink($utns . ':'.$rc_user_text, $talkname );
2429 global $wgDisableAnonTalk;
2430 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2431 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2432 'Blockip' ), wfMsg( 'blocklink' ), 'ip='.$rc_user_text );
2433 if( $wgDisableAnonTalk )
2434 $rc->usertalklink = ' ('.$blockLink.')';
2435 else
2436 $rc->usertalklink = ' ('.$userTalkLink.' | '.$blockLink.')';
2437 } else {
2438 if( $wgDisableAnonTalk && ($rc_user == 0) )
2439 $rc->usertalklink = '';
2440 else
2441 $rc->usertalklink = ' ('.$userTalkLink.')';
2444 # Put accumulated information into the cache, for later display
2445 # Page moves go on their own line
2446 $title = $rc->getTitle();
2447 $secureName = $title->getPrefixedDBkey();
2448 if ( $rc_type == RC_MOVE ) {
2449 # Use an @ character to prevent collision with page names
2450 $this->rc_cache['@@' . ($this->rcMoveIndex++)] = array($rc);
2451 } else {
2452 if ( !isset ( $this->rc_cache[$secureName] ) ) $this->rc_cache[$secureName] = array() ;
2453 array_push ( $this->rc_cache[$secureName] , $rc ) ;
2455 return $ret;
2458 function endImageHistoryList()
2460 $s = "</ul>\n";
2461 return $s;
2464 /* This function is called by all recent changes variants, by the page history,
2465 and by the user contributions list. It is responsible for formatting edit
2466 comments. It escapes any HTML in the comment, but adds some CSS to format
2467 auto-generated comments (from section editing) and formats [[wikilinks]].
2468 Main author: Erik Möller (moeller@scireview.de)
2470 function formatComment($comment)
2472 global $wgLang;
2473 $comment=wfEscapeHTML($comment);
2475 # The pattern for autogen comments is / * foo * /, which makes for
2476 # some nasty regex.
2477 # We look for all comments, match any text before and after the comment,
2478 # add a separator where needed and format the comment itself with CSS
2479 while (preg_match('/(.*)\/\*\s*(.*?)\s*\*\/(.*)/', $comment,$match)) {
2480 $pre=$match[1];
2481 $auto=$match[2];
2482 $post=$match[3];
2483 $sep='-';
2484 if($pre) { $auto = $sep.' '.$auto; }
2485 if($post) { $auto .= ' '.$sep; }
2486 $auto='<span class="autocomment">'.$auto.'</span>';
2487 $comment=$pre.$auto.$post;
2490 # format regular and media links - all other wiki formatting
2491 # is ignored
2492 while(preg_match('/\[\[(.*?)(\|(.*?))*\]\]/',$comment,$match)) {
2494 $medians = $wgLang->getNsText(Namespace::getMedia());
2495 $func='makeLink';
2496 if(preg_match('/^'.$medians.'/i',$match[1])) {
2497 $func='makeMediaLink';
2499 if(isset($match[3]) ) {
2500 $comment=
2501 preg_replace('/\[\[(.*?)\]\]/',
2502 $this->$func($match[1],$match[3]),$comment,1);
2503 } else {
2504 $comment=
2505 preg_replace('/\[\[(.*?)\]\]/',
2506 $this->$func($match[1],$match[1]),$comment,1);
2510 return $comment;
2514 function imageHistoryLine( $iscur, $timestamp, $img, $user, $usertext, $size, $description )
2516 global $wgUser, $wgLang, $wgTitle;
2518 $datetime = $wgLang->timeanddate( $timestamp, true );
2519 $del = wfMsg( 'deleteimg' );
2520 $cur = wfMsg( 'cur' );
2522 if ( $iscur ) {
2523 $url = Image::wfImageUrl( $img );
2524 $rlink = $cur;
2525 if ( $wgUser->isSysop() ) {
2526 $link = $wgTitle->escapeLocalURL( 'image=' . $wgTitle->getPartialURL() .
2527 '&action=delete' );
2528 $style = $this->getInternalLinkAttributes( $link, $del );
2530 $dlink = '<a href="'.$link.'"'.$style.'>'.$del.'</a>';
2531 } else {
2532 $dlink = $del;
2534 } else {
2535 $url = wfEscapeHTML( wfImageArchiveUrl( $img ) );
2536 if( $wgUser->getID() != 0 ) {
2537 $rlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2538 wfMsg( 'revertimg' ), 'action=revert&oldimage=' .
2539 urlencode( $img ) );
2540 $dlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2541 $del, 'action=delete&oldimage=' . urlencode( $img ) );
2542 } else {
2543 # Having live active links for non-logged in users
2544 # means that bots and spiders crawling our site can
2545 # inadvertently change content. Baaaad idea.
2546 $rlink = wfMsg( 'revertimg' );
2547 $dlink = $del;
2550 if ( 0 == $user ) {
2551 $userlink = $usertext;
2552 } else {
2553 $userlink = $this->makeLink( $wgLang->getNsText( Namespace::getUser() ) .
2554 ':'.$usertext, $usertext );
2556 $nbytes = wfMsg( 'nbytes', $size );
2557 $style = $this->getInternalLinkAttributes( $url, $datetime );
2559 $s = "<li> ({$dlink}) ({$rlink}) <a href=\"{$url}\"{$style}>{$datetime}</a>"
2560 . " . . {$userlink} ({$nbytes})";
2562 if ( '' != $description && '*' != $description ) {
2563 $sk=$wgUser->getSkin();
2564 $s .= $wgLang->emphasize(' (' . $sk->formatComment($description) . ')');
2566 $s .= "</li>\n";
2567 return $s;
2570 function tocIndent($level) {
2571 return str_repeat( '<div class="tocindent">'."\n", $level>0 ? $level : 0 );
2574 function tocUnindent($level) {
2575 return str_repeat( "</div>\n", $level>0 ? $level : 0 );
2578 # parameter level defines if we are on an indentation level
2579 function tocLine( $anchor, $tocline, $level ) {
2580 $link = '<a href="#'.$anchor.'">'.$tocline.'</a><br />';
2581 if($level) {
2582 return $link."\n";
2583 } else {
2584 return '<div class="tocline">'.$link."</div>\n";
2589 function tocTable($toc) {
2590 # note to CSS fanatics: putting this in a div does not work -- div won't auto-expand
2591 # try min-width & co when somebody gets a chance
2592 $hideline = ' <script type="text/javascript">showTocToggle("' . addslashes( wfMsg('showtoc') ) . '","' . addslashes( wfMsg('hidetoc') ) . '")</script>';
2593 return
2594 '<table border="0" id="toc"><tr id="toctitle"><td align="center">'."\n".
2595 '<b>'.wfMsg('toc').'</b>' .
2596 $hideline .
2597 '</td></tr><tr id="tocinside"><td>'."\n".
2598 $toc."</td></tr></table>\n";
2601 # These two do not check for permissions: check $wgTitle->userCanEdit before calling them
2602 function editSectionScript( $section, $head ) {
2603 global $wgTitle, $wgRequest;
2604 if( $wgRequest->getInt( 'oldid' ) && ( $wgRequest->getVal( 'diff' ) != '0' ) ) {
2605 return $head;
2607 $url = $wgTitle->escapeLocalURL( 'action=edit&section='.$section );
2608 return '<span oncontextmenu=\'document.location="'.$url.'";return false;\'>'.$head.'</span>';
2611 function editSectionLink( $section ) {
2612 global $wgRequest;
2613 global $wgTitle, $wgUser, $wgLang;
2615 if( $wgRequest->getInt( 'oldid' ) && ( $wgRequest->getVal( 'diff' ) != '0' ) ) {
2616 # Section edit links would be out of sync on an old page.
2617 # But, if we're diffing to the current page, they'll be
2618 # correct.
2619 return '';
2622 $editurl = '&section='.$section;
2623 $url = $this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg('editsection'),'action=edit'.$editurl);
2625 if( $wgLang->isRTL() ) {
2626 $farside = 'left';
2627 $nearside = 'right';
2628 } else {
2629 $farside = 'right';
2630 $nearside = 'left';
2632 return "<div class=\"editsection\" style=\"float:$farside;margin-$nearside:5px;\">[".$url."]</div>";
2636 // This function is called by EditPage.php and shows a bulletin board style
2637 // toolbar for common editing functions. It can be disabled in the user preferences.
2638 // The necsesary JavaScript code can be found in style/wikibits.js.
2639 function getEditToolbar() {
2640 global $wgStylePath, $wgLang, $wgMimeType;
2642 // toolarray an array of arrays which each include the filename of
2643 // the button image (without path), the opening tag, the closing tag,
2644 // and optionally a sample text that is inserted between the two when no
2645 // selection is highlighted.
2646 // The tip text is shown when the user moves the mouse over the button.
2648 // Already here are accesskeys (key), which are not used yet until someone
2649 // can figure out a way to make them work in IE. However, we should make
2650 // sure these keys are not defined on the edit page.
2651 $toolarray=array(
2652 array( 'image'=>'button_bold.png',
2653 'open'=>"\'\'\'",
2654 'close'=>"\'\'\'",
2655 'sample'=>wfMsg('bold_sample'),
2656 'tip'=>wfMsg('bold_tip'),
2657 'key'=>'B'
2659 array( "image"=>"button_italic.png",
2660 "open"=>"\'\'",
2661 "close"=>"\'\'",
2662 "sample"=>wfMsg("italic_sample"),
2663 "tip"=>wfMsg("italic_tip"),
2664 "key"=>"I"
2666 array( "image"=>"button_link.png",
2667 "open"=>"[[",
2668 "close"=>"]]",
2669 "sample"=>wfMsg("link_sample"),
2670 "tip"=>wfMsg("link_tip"),
2671 "key"=>"L"
2673 array( "image"=>"button_extlink.png",
2674 "open"=>"[",
2675 "close"=>"]",
2676 "sample"=>wfMsg("extlink_sample"),
2677 "tip"=>wfMsg("extlink_tip"),
2678 "key"=>"X"
2680 array( "image"=>"button_headline.png",
2681 "open"=>"\\n== ",
2682 "close"=>" ==\\n",
2683 "sample"=>wfMsg("headline_sample"),
2684 "tip"=>wfMsg("headline_tip"),
2685 "key"=>"H"
2687 array( "image"=>"button_image.png",
2688 "open"=>"[[".$wgLang->getNsText(NS_IMAGE).":",
2689 "close"=>"]]",
2690 "sample"=>wfMsg("image_sample"),
2691 "tip"=>wfMsg("image_tip"),
2692 "key"=>"D"
2694 array( "image"=>"button_media.png",
2695 "open"=>"[[".$wgLang->getNsText(NS_MEDIA).":",
2696 "close"=>"]]",
2697 "sample"=>wfMsg("media_sample"),
2698 "tip"=>wfMsg("media_tip"),
2699 "key"=>"M"
2701 array( "image"=>"button_math.png",
2702 "open"=>"\\<math\\>",
2703 "close"=>"\\</math\\>",
2704 "sample"=>wfMsg("math_sample"),
2705 "tip"=>wfMsg("math_tip"),
2706 "key"=>"C"
2708 array( "image"=>"button_nowiki.png",
2709 "open"=>"\\<nowiki\\>",
2710 "close"=>"\\</nowiki\\>",
2711 "sample"=>wfMsg("nowiki_sample"),
2712 "tip"=>wfMsg("nowiki_tip"),
2713 "key"=>"N"
2715 array( "image"=>"button_sig.png",
2716 "open"=>"--~~~~",
2717 "close"=>"",
2718 "sample"=>"",
2719 "tip"=>wfMsg("sig_tip"),
2720 "key"=>"Y"
2722 array( "image"=>"button_hr.png",
2723 "open"=>"\\n----\\n",
2724 "close"=>"",
2725 "sample"=>"",
2726 "tip"=>wfMsg("hr_tip"),
2727 "key"=>"R"
2730 $toolbar ="<script type='text/javascript'>\n/*<![CDATA[*/\n";
2732 $toolbar.="document.writeln(\"<div id='toolbar'>\");\n";
2733 foreach($toolarray as $tool) {
2735 $image=$wgStylePath.'/images/'.$tool['image'];
2736 $open=$tool['open'];
2737 $close=$tool['close'];
2738 $sample = addslashes( $tool['sample'] );
2740 // Note that we use the tip both for the ALT tag and the TITLE tag of the image.
2741 // Older browsers show a "speedtip" type message only for ALT.
2742 // Ideally these should be different, realistically they
2743 // probably don't need to be.
2744 $tip = addslashes( $tool['tip'] );
2746 #$key = $tool["key"];
2748 $toolbar.="addButton('$image','$tip','$open','$close','$sample');\n";
2751 $toolbar.="addInfobox('" . addslashes( wfMsg( "infobox" ) ) . "','" . addslashes(wfMsg("infobox_alert")) . "');\n";
2752 $toolbar.="document.writeln(\"</div>\");\n";
2754 $toolbar.="/*]]>*/\n</script>";
2755 return $toolbar;
2760 require_once( 'SkinStandard.php' );
2761 require_once( 'SkinNostalgia.php' );
2762 require_once( 'SkinCologneBlue.php' );
2764 if( $wgUsePHPTal ) {
2765 require_once( 'SkinPHPTal.php' );