9 * This is not a valid entry point, perform no further processing unless MEDIAWIKI is defined
11 if( defined( "MEDIAWIKI" ) ) {
14 require_once( 'Image.php' );
16 # These are the INTERNAL names, which get mapped directly to class names and
17 # file names in ./skins/. For display purposes, the Language class has
18 # internationalized names
21 $wgValidSkinNames = array(
22 'standard' => 'Standard',
23 'nostalgia' => 'Nostalgia',
24 'cologneblue' => 'CologneBlue'
27 #$wgValidSkinNames[] = 'PHPTal';
28 #$wgValidSkinNames['davinci'] = 'DaVinci';
29 #$wgValidSkinNames['mono'] = 'Mono';
30 #$wgValidSkinNames['monobookminimal'] = 'MonoBookMinimal';
31 $wgValidSkinNames['monobook'] = 'MonoBook';
32 $wgValidSkinNames['myskin'] = 'MySkin';
33 $wgValidSkinNames['chick'] = 'Chick';
37 # Get a list of all skins available in /skins/
38 # Build using the regular expression '^(.*).php$'
39 # Array keys are all lower case, array value keep the case used by filename
42 $skinDir = dir($IP.'/skins');
44 # while code from www.php.net
45 while (false !== ($file = $skinDir->read())) {
46 if(preg_match('/^(.*).php$/',$file, $matches)) {
48 $wgValidSkinNames[strtolower($aSkin)] = $aSkin;
54 require_once( 'RecentChange.php' );
56 global $wgLinkHolders;
57 $wgLinkHolders = array(
58 'namespaces' => array(),
69 class RCCacheEntry
extends RecentChange
71 var $secureName, $link;
72 var $curlink , $difflink, $lastlink , $usertalklink , $versionlink ;
73 var $userlink, $timestamp, $watched;
75 function newFromParent( $rc )
77 $rc2 = new RCCacheEntry
;
78 $rc2->mAttribs
= $rc->mAttribs
;
79 $rc2->mExtra
= $rc->mExtra
;
86 * The main skin class that provide methods and properties for all other skins
87 * including PHPTal skins.
88 * This base class is also the "Standard" skin.
95 var $lastdate, $lastline;
96 var $linktrail ; # linktrail regexp
97 var $rc_cache ; # Cache for Enhanced Recent Changes
98 var $rcCacheIndex ; # Recent Changes Cache Counter for visibility toggle
100 var $postParseLinkColour = true;
104 global $wgUseOldExistenceCheck;
105 $postParseLinkColour = !$wgUseOldExistenceCheck;
106 $this->linktrail
= wfMsg('linktrail');
109 function getSkinNames() {
110 global $wgValidSkinNames;
111 return $wgValidSkinNames;
114 function getStylesheet() {
115 return 'common/wikistandard.css';
118 function getSkinName() {
123 * Get/set accessor for delayed link colouring
125 function postParseLinkColour( $setting = NULL ) {
126 return wfSetVar( $this->postParseLinkColour
, $setting );
129 function qbSetting() {
130 global $wgOut, $wgUser;
132 if ( $wgOut->isQuickbarSuppressed() ) { return 0; }
133 $q = $wgUser->getOption( 'quickbar' );
134 if ( '' == $q ) { $q = 0; }
138 function initPage( &$out ) {
139 $fname = 'Skin::initPage';
140 wfProfileIn( $fname );
142 $out->addLink( array( 'rel' => 'shortcut icon', 'href' => '/favicon.ico' ) );
144 $this->addMetadataLinks($out);
146 wfProfileOut( $fname );
149 function addMetadataLinks( &$out ) {
150 global $wgTitle, $wgEnableDublinCoreRdf, $wgEnableCreativeCommonsRdf, $wgRdfMimeType, $action;
151 global $wgRightsPage, $wgRightsUrl;
153 if( $out->isArticleRelated() ) {
154 # note: buggy CC software only reads first "meta" link
155 if( $wgEnableCreativeCommonsRdf ) {
156 $out->addMetadataLink( array(
157 'title' => 'Creative Commons',
158 'type' => 'application/rdf+xml',
159 'href' => $wgTitle->getLocalURL( 'action=creativecommons') ) );
161 if( $wgEnableDublinCoreRdf ) {
162 $out->addMetadataLink( array(
163 'title' => 'Dublin Core',
164 'type' => 'application/rdf+xml',
165 'href' => $wgTitle->getLocalURL( 'action=dublincore' ) ) );
169 if( $wgRightsPage ) {
170 $copy = Title
::newFromText( $wgRightsPage );
172 $copyright = $copy->getLocalURL();
175 if( !$copyright && $wgRightsUrl ) {
176 $copyright = $wgRightsUrl;
179 $out->addLink( array(
180 'rel' => 'copyright',
181 'href' => $copyright ) );
185 function outputPage( &$out ) {
186 global $wgDebugComments;
188 wfProfileIn( 'Skin::outputPage' );
189 $this->initPage( $out );
190 $out->out( $out->headElement() );
192 $out->out( "\n<body" );
193 $ops = $this->getBodyOptions();
194 foreach ( $ops as $name => $val ) {
195 $out->out( " $name='$val'" );
198 if ( $wgDebugComments ) {
199 $out->out( "<!-- Wiki debugging output:\n" .
200 $out->mDebugtext
. "-->\n" );
202 $out->out( $this->beforeContent() );
204 $out->out( $out->mBodytext
. "\n" );
206 $out->out( $this->afterContent() );
209 $out->out( $out->reportTime() );
211 $out->out( "\n</body></html>" );
214 function getHeadScripts() {
215 global $wgStylePath, $wgUser, $wgLang, $wgAllowUserJs;
216 $r = "<script type=\"text/javascript\" src=\"{$wgStylePath}/common/wikibits.js\"></script>\n";
217 if( $wgAllowUserJs && $wgUser->getID() != 0 ) { # logged in
218 $userpage = $wgLang->getNsText( Namespace::getUser() ) . ":" . $wgUser->getName();
219 $userjs = htmlspecialchars($this->makeUrl($userpage.'/'.$this->getSkinName().'.js', 'action=raw&ctype=text/javascript'));
220 $r .= '<script type="text/javascript" src="'.$userjs."\"></script>\n";
225 # get the user/site-specific stylesheet, SkinPHPTal called from RawPage.php (settings are cached that way)
226 function getUserStylesheet() {
227 global $wgOut, $wgStylePath, $wgLang, $wgUser, $wgRequest, $wgTitle, $wgAllowUserCss;
228 $sheet = $this->getStylesheet();
229 $action = $wgRequest->getText('action');
230 $s = "@import \"$wgStylePath/$sheet\";\n";
231 if($wgLang->isRTL()) $s .= "@import \"$wgStylePath/common/common_rtl.css\";\n";
232 if( $wgAllowUserCss && $wgUser->getID() != 0 ) { # logged in
233 if($wgTitle->isCssSubpage() and $action == 'submit' and $wgTitle->userCanEditCssJsSubpage()) {
234 $s .= $wgRequest->getText('wpTextbox1');
236 $userpage = $wgLang->getNsText( Namespace::getUser() ) . ":" . $wgUser->getName();
237 $s.= '@import "'.$this->makeUrl($userpage.'/'.$this->getSkinName().'.css', 'action=raw&ctype=text/css').'";'."\n";
240 $s .= $this->doGetUserStyles();
245 * placeholder, returns generated js in monobook
247 function getUserJs() { return; }
250 * Return html code that include User stylesheets
252 function getUserStyles() {
253 global $wgOut, $wgStylePath, $wgLang;
254 $s = "<style type='text/css'>\n";
255 $s .= "/*/*/ /*<![CDATA[*/\n"; # <-- Hide the styles from Netscape 4 without hiding them from IE/Mac
256 $s .= $this->getUserStylesheet();
257 $s .= "/*]]>*/ /* */\n";
263 * Some styles that are set by user through the user settings interface.
265 function doGetUserStyles() {
266 global $wgUser, $wgLang;
268 $csspage = $wgLang->getNsText( NS_MEDIAWIKI
) . ':' . $this->getSkinName() . '.css';
269 $s = '@import "'.$this->makeUrl($csspage, 'action=raw&ctype=text/css')."\";\n";
271 if ( 1 == $wgUser->getOption( 'underline' ) ) {
272 # Don't override browser settings
276 $s .= "a { text-decoration: none; }\n";
278 if ( 1 == $wgUser->getOption( 'highlightbroken' ) ) {
279 $s .= "a.new, #quickbar a.new { color: #CC2200; }\n";
281 if ( 1 == $wgUser->getOption( 'justify' ) ) {
282 $s .= "#article { text-align: justify; }\n";
287 function getBodyOptions() {
288 global $wgUser, $wgTitle, $wgNamespaceBackgrounds, $wgOut, $wgRequest;
290 extract( $wgRequest->getValues( 'oldid', 'redirect', 'diff' ) );
292 if ( 0 != $wgTitle->getNamespace() ) {
293 $a = array( 'bgcolor' => '#ffffec' );
295 else $a = array( 'bgcolor' => '#FFFFFF' );
296 if($wgOut->isArticle() && $wgUser->getOption('editondblclick') &&
297 (!$wgTitle->isProtected() ||
$wgUser->isSysop()) ) {
298 $t = wfMsg( 'editthispage' );
300 if ( !empty($redirect) ) {
301 $red = "&redirect={$redirect}";
303 if ( !empty($oldid) && ! isset( $diff ) ) {
304 $oid = "&oldid={$oldid}";
306 $s = $wgTitle->getFullURL( "action=edit{$oid}{$red}" );
307 $s = 'document.location = "' .$s .'";';
308 $a +
= array ('ondblclick' => $s);
311 $a['onload'] = $wgOut->getOnloadHandler();
315 function getExternalLinkAttributes( $link, $text, $class='' ) {
316 global $wgUser, $wgOut, $wgLang;
318 $same = ($link == $text);
319 $link = urldecode( $link );
320 $link = $wgLang->checkTitleEncoding( $link );
321 $link = str_replace( '_', ' ', $link );
322 $link = htmlspecialchars( $link );
324 $r = ($class != '') ?
" class='$class'" : " class='external'";
326 if ( !$same && $wgUser->getOption( 'hover' ) ) {
327 $r .= " title=\"{$link}\"";
332 function getInternalLinkAttributes( $link, $text, $broken = false ) {
333 global $wgUser, $wgOut;
335 $link = urldecode( $link );
336 $link = str_replace( '_', ' ', $link );
337 $link = htmlspecialchars( $link );
339 if ( $broken == 'stub' ) {
340 $r = ' class="stub"';
341 } else if ( $broken == 'yes' ) {
347 if ( 1 == $wgUser->getOption( 'hover' ) ) {
348 $r .= " title=\"{$link}\"";
354 * @param bool $broken
356 function getInternalLinkAttributesObj( &$nt, $text, $broken = false ) {
357 global $wgUser, $wgOut;
359 if ( $broken == 'stub' ) {
360 $r = ' class="stub"';
361 } else if ( $broken == 'yes' ) {
367 if ( 1 == $wgUser->getOption( 'hover' ) ) {
368 $r .= ' title="' . $nt->getEscapedText() . '"';
382 * This will be called immediately after the <body> tag. Split into
383 * two functions to make it easier to subclass.
385 function beforeContent() {
386 global $wgUser, $wgOut;
388 return $this->doBeforeContent();
391 function doBeforeContent() {
392 global $wgUser, $wgOut, $wgTitle, $wgLang, $wgSiteNotice;
393 $fname = 'Skin::doBeforeContent';
394 wfProfileIn( $fname );
397 $qb = $this->qbSetting();
399 if( $langlinks = $this->otherLanguages() ) {
405 $borderhack = 'class="top"';
408 $s .= "\n<div id='content'>\n<div id='topbar'>\n" .
409 "<table border='0' cellspacing='0' width='98%'>\n<tr>\n";
412 $left = ($qb == 1 ||
$qb == 3);
413 if($wgLang->isRTL()) $left = !$left;
416 $s .= "<td class='top' align='left' valign='top' rowspan='{$rows}'>\n" .
417 $this->logoText() . '</td>';
419 $s .= $this->getQuickbarCompensator( $rows );
421 $l = $wgLang->isRTL() ?
'right' : 'left';
422 $s .= "<td {$borderhack} align='$l' valign='top'>\n";
424 $s .= $this->topLinks() ;
425 $s .= "<p class='subtitle'>" . $this->pageTitleLinks() . "</p>\n";
427 $r = $wgLang->isRTL() ?
"left" : "right";
428 $s .= "</td>\n<td {$borderhack} valign='top' align='$r' nowrap='nowrap'>";
429 $s .= $this->nameAndLogin();
430 $s .= "\n<br />" . $this->searchForm() . "</td>";
433 $s .= "</tr>\n<tr>\n<td class='top' colspan=\"2\">$langlinks</td>\n";
436 if ( $shove && !$left ) { # Right
437 $s .= $this->getQuickbarCompensator( $rows );
439 $s .= "</tr>\n</table>\n</div>\n";
440 $s .= "\n<div id='article'>\n";
442 if( $wgSiteNotice ) {
443 $s .= "\n<div id='siteNotice'>$wgSiteNotice</div>\n";
445 $s .= $this->pageTitle();
446 $s .= $this->pageSubtitle() ;
447 $s .= $this->getCategories();
448 wfProfileOut( $fname );
452 function getCategoryLinks () {
453 global $wgOut, $wgTitle, $wgUser, $wgParser;
454 global $wgUseCategoryMagic, $wgUseCategoryBrowser, $wgLang;
456 if( !$wgUseCategoryMagic ) return '' ;
457 if( count( $wgOut->mCategoryLinks
) == 0 ) return '';
459 # Taken out so that they will be displayed in previews -- TS
460 #if( !$wgOut->isArticle() ) return '';
462 $t = implode ( ' | ' , $wgOut->mCategoryLinks
) ;
463 $s = $this->makeKnownLink( 'Special:Categories',
464 wfMsg( 'categories' ), 'article=' . urlencode( $wgTitle->getPrefixedDBkey() ) )
467 # optional 'dmoz-like' category browser. Will be shown under the list
468 # of categories an article belong to
469 if($wgUseCategoryBrowser) {
472 # get a big array of the parents tree
473 $parenttree = $wgTitle->getCategorieBrowser();
475 # Render the array as a serie of links
476 function walkThrough ($tree) {
478 $sk = $wgUser->getSkin();
480 foreach($tree as $element => $parent) {
482 # element start a new list
485 # grab the others elements
486 $return .= walkThrough($parent);
488 # add our current element to the list
489 $eltitle = Title
::NewFromText($element);
490 # FIXME : should be makeLink() [AV]
491 $return .= $sk->makeKnownLink($element, $eltitle->getText()).' > ';
496 $s .= walkThrough($parenttree);
502 function getCategories() {
503 $catlinks=$this->getCategoryLinks();
504 if(!empty($catlinks)) {
505 return "<p class='catlinks'>{$catlinks}</p>";
509 function getQuickbarCompensator( $rows = 1 ) {
510 return "<td width='152' rowspan='{$rows}'> </td>";
513 # This gets called immediately before the </body> tag.
515 function afterContent() {
516 global $wgUser, $wgOut, $wgServer;
517 global $wgTitle, $wgLang;
519 $printfooter = "<div class=\"printfooter\">\n" . $this->printFooter() . "</div>\n";
520 return $printfooter . $this->doAfterContent();
523 function printSource() {
525 $url = htmlspecialchars( $wgTitle->getFullURL() );
526 return wfMsg( "retrievedfrom", "<a href=\"$url\">$url</a>" );
529 function printFooter() {
530 return "<p>" . $this->printSource() .
531 "</p>\n\n<p>" . $this->pageStats() . "</p>\n";
534 function doAfterContent() {
535 global $wgUser, $wgOut, $wgLang;
536 $fname = 'Skin::doAfterContent';
537 wfProfileIn( $fname );
538 wfProfileIn( $fname.'-1' );
540 $s = "\n</div><br style=\"clear:both\" />\n";
541 $s .= "\n<div id='footer'>";
542 $s .= '<table border="0" cellspacing="0"><tr>';
544 wfProfileOut( $fname.'-1' );
545 wfProfileIn( $fname.'-2' );
547 $qb = $this->qbSetting();
549 $left = ($qb == 1 ||
$qb == 3);
550 if($wgLang->isRTL()) $left = !$left;
552 if ( $shove && $left ) { # Left
553 $s .= $this->getQuickbarCompensator();
555 wfProfileOut( $fname.'-2' );
556 wfProfileIn( $fname.'-3' );
557 $l = $wgLang->isRTL() ?
'right' : 'left';
558 $s .= "<td class='bottom' align='$l' valign='top'>";
560 $s .= $this->bottomLinks();
561 $s .= "\n<br />" . $this->mainPageLink()
562 . ' | ' . $this->aboutLink()
563 . ' | ' . $this->specialLink( 'recentchanges' )
564 . ' | ' . $this->searchForm()
565 . '<br /><span id="pagestats">' . $this->pageStats() . '</span>';
568 if ( $shove && !$left ) { # Right
569 $s .= $this->getQuickbarCompensator();
571 $s .= "</tr></table>\n</div>\n</div>\n";
573 wfProfileOut( $fname.'-3' );
574 wfProfileIn( $fname.'-4' );
575 if ( 0 != $qb ) { $s .= $this->quickBar(); }
576 wfProfileOut( $fname.'-4' );
577 wfProfileOut( $fname );
581 function pageTitleLinks() {
582 global $wgOut, $wgTitle, $wgUser, $wgLang, $wgUseApproval, $wgRequest;
584 extract( $wgRequest->getValues( 'oldid', 'diff' ) );
585 $action = $wgRequest->getText( 'action' );
587 $s = $this->printableLink();
588 if ( wfMsg ( 'disclaimers' ) != '-' ) $s .= ' | ' . $this->makeKnownLink( wfMsg( 'disclaimerpage' ), wfMsg( 'disclaimers' ) ) ;
590 if ( $wgOut->isArticleRelated() ) {
591 if ( $wgTitle->getNamespace() == Namespace::getImage() ) {
592 $name = $wgTitle->getDBkey();
593 $link = htmlspecialchars( Image
::wfImageUrl( $name ) );
594 $style = $this->getInternalLinkAttributes( $link, $name );
595 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>";
597 # This will show the "Approve" link if $wgUseApproval=true;
598 if ( isset ( $wgUseApproval ) && $wgUseApproval )
600 $t = $wgTitle->getDBkey();
601 $name = 'Approve this article' ;
602 $link = "http://test.wikipedia.org/w/magnus/wiki.phtml?title={$t}&action=submit&doit=1" ;
603 #htmlspecialchars( wfImageUrl( $name ) );
604 $style = $this->getExternalLinkAttributes( $link, $name );
605 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>" ;
608 if ( 'history' == $action ||
isset( $diff ) ||
isset( $oldid ) ) {
609 $s .= ' | ' . $this->makeKnownLink( $wgTitle->getPrefixedText(),
610 wfMsg( 'currentrev' ) );
613 if ( $wgUser->getNewtalk() ) {
614 # do not show "You have new messages" text when we are viewing our
617 if(!(strcmp($wgTitle->getText(),$wgUser->getName()) == 0 &&
618 $wgTitle->getNamespace()==Namespace::getTalk(Namespace::getUser()))) {
619 $n =$wgUser->getName();
620 $tl = $this->makeKnownLink( $wgLang->getNsText(
621 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
622 wfMsg('newmessageslink') );
623 $s.= ' | <strong>'. wfMsg( 'newmessages', $tl ) . '</strong>';
625 $wgOut->setSquidMaxage(0);
629 $undelete = $this->getUndeleteLink();
630 if( !empty( $undelete ) ) {
631 $s .= ' | '.$undelete;
636 function getUndeleteLink() {
637 global $wgUser, $wgTitle, $wgLang, $action;
638 if( $wgUser->isSysop() &&
639 (($wgTitle->getArticleId() == 0) ||
($action == "history")) &&
640 ($n = $wgTitle->isDeleted() ) ) {
641 return wfMsg( 'thisisdeleted',
642 $this->makeKnownLink(
643 $wgLang->SpecialPage( 'Undelete/' . $wgTitle->getPrefixedDBkey() ),
644 wfMsg( 'restorelink', $n ) ) );
649 function printableLink() {
650 global $wgOut, $wgFeedClasses, $wgRequest;
652 $baseurl = $_SERVER['REQUEST_URI'];
653 if( strpos( '?', $baseurl ) == false ) {
658 $baseurl = htmlspecialchars( $baseurl );
659 $printurl = $wgRequest->escapeAppendQuery( 'printable=yes' );
661 $s = "<a href=\"$printurl\">" . wfMsg( 'printableversion' ) . '</a>';
662 if( $wgOut->isSyndicated() ) {
663 foreach( $wgFeedClasses as $format => $class ) {
664 $feedurl = $wgRequest->escapeAppendQuery( "feed=$format" );
665 $s .= " | <a href=\"$feedurl\">{$format}</a>";
671 function pageTitle() {
672 global $wgOut, $wgTitle, $wgUser;
674 $s = '<h1 class="pagetitle">' . htmlspecialchars( $wgOut->getPageTitle() ) . '</h1>';
675 if($wgUser->getOption( 'editsectiononrightclick' ) && $wgTitle->userCanEdit()) { $s=$this->editSectionScript(0,$s);}
679 function pageSubtitle() {
682 $sub = $wgOut->getSubtitle();
684 global $wgExtraSubtitle;
685 $sub = wfMsg( 'tagline' ) . $wgExtraSubtitle;
687 $subpages = $this->subPageSubtitle();
688 $sub .= !empty($subpages)?
"</p><p class='subpages'>$subpages":'';
689 $s = "<p class='subtitle'>{$sub}</p>\n";
693 function subPageSubtitle() {
694 global $wgOut,$wgTitle,$wgNamespacesWithSubpages;
696 if($wgOut->isArticle() && !empty($wgNamespacesWithSubpages[$wgTitle->getNamespace()])) {
697 $ptext=$wgTitle->getPrefixedText();
698 if(preg_match('/\//',$ptext)) {
699 $links = explode('/',$ptext);
702 foreach($links as $link) {
704 if ($c<count($links)) {
705 $growinglink .= $link;
706 $getlink = $this->makeLink( $growinglink, $link );
707 if(preg_match('/class="new"/i',$getlink)) { break; } # this is a hack, but it saves time
711 $subpages .= '< ';
713 $subpages .= $getlink;
722 function nameAndLogin() {
723 global $wgUser, $wgTitle, $wgLang, $wgShowIPinHeader, $wgIP;
725 $li = $wgLang->specialPage( 'Userlogin' );
726 $lo = $wgLang->specialPage( 'Userlogout' );
729 if ( 0 == $wgUser->getID() ) {
730 if( $wgShowIPinHeader && isset( $_COOKIE[ini_get('session.name')] ) ) {
733 $tl = $this->makeKnownLink( $wgLang->getNsText(
734 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
735 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
737 $s .= $n . ' ('.$tl.')';
739 $s .= wfMsg('notloggedin');
742 $rt = $wgTitle->getPrefixedURL();
743 if ( 0 == strcasecmp( urlencode( $lo ), $rt ) ) {
745 } else { $q = "returnto={$rt}"; }
747 $s .= "\n<br />" . $this->makeKnownLink( $li,
748 wfMsg( 'login' ), $q );
750 $n = $wgUser->getName();
751 $rt = $wgTitle->getPrefixedURL();
752 $tl = $this->makeKnownLink( $wgLang->getNsText(
753 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
754 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
758 $s .= $this->makeKnownLink( $wgLang->getNsText(
759 Namespace::getUser() ) . ":{$n}", $n ) . "{$tl}<br />" .
760 $this->makeKnownLink( $lo, wfMsg( 'logout' ),
761 "returnto={$rt}" ) . ' | ' .
762 $this->specialLink( 'preferences' );
764 $s .= ' | ' . $this->makeKnownLink( wfMsg( 'helppage' ),
770 function getSearchLink() {
771 $searchPage =& Title
::makeTitle( NS_SPECIAL
, 'Search' );
772 return $searchPage->getLocalURL();
775 function escapeSearchLink() {
776 return htmlspecialchars( $this->getSearchLink() );
779 function searchForm() {
781 $search = $wgRequest->getText( 'search' );
783 $s = '<form name="search" class="inline" method="post" action="'
784 . $this->escapeSearchLink() . "\">\n"
785 . '<input type="text" name="search" size="19" value="'
786 . htmlspecialchars(substr($search,0,256)) . "\" />\n"
787 . '<input type="submit" name="go" value="' . wfMsg ('go') . '" /> '
788 . '<input type="submit" name="fulltext" value="' . wfMsg ('search') . "\" />\n</form>";
793 function topLinks() {
797 $s = $this->mainPageLink() . $sep
798 . $this->specialLink( 'recentchanges' );
800 if ( $wgOut->isArticleRelated() ) {
801 $s .= $sep . $this->editThisPage()
802 . $sep . $this->historyLink();
804 # Many people don't like this dropdown box
805 #$s .= $sep . $this->specialPagesList();
810 function bottomLinks() {
811 global $wgOut, $wgUser, $wgTitle;
815 if ( $wgOut->isArticleRelated() ) {
816 $s .= '<strong>' . $this->editThisPage() . '</strong>';
817 if ( 0 != $wgUser->getID() ) {
818 $s .= $sep . $this->watchThisPage();
820 $s .= $sep . $this->talkLink()
821 . $sep . $this->historyLink()
822 . $sep . $this->whatLinksHere()
823 . $sep . $this->watchPageLinksLink();
825 if ( $wgTitle->getNamespace() == Namespace::getUser()
826 ||
$wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser()) )
829 $id=User
::idFromName($wgTitle->getText());
830 $ip=User
::isIP($wgTitle->getText());
832 if($id ||
$ip) { # both anons and non-anons have contri list
833 $s .= $sep . $this->userContribsLink();
835 if ( 0 != $wgUser->getID() ) { # show only to signed in users
836 if($id) { # can only email non-anons
837 $s .= $sep . $this->emailUserLink();
841 if ( $wgUser->isSysop() && $wgTitle->getArticleId() ) {
842 $s .= "\n<br />" . $this->deleteThisPage() .
843 $sep . $this->protectThisPage() .
844 $sep . $this->moveThisPage();
846 $s .= "<br />\n" . $this->otherLanguages();
851 function pageStats() {
852 global $wgOut, $wgLang, $wgArticle, $wgRequest;
853 global $wgDisableCounters, $wgMaxCredits, $wgShowCreditsIfMax;
855 extract( $wgRequest->getValues( 'oldid', 'diff' ) );
856 if ( ! $wgOut->isArticle() ) { return ''; }
857 if ( isset( $oldid ) ||
isset( $diff ) ) { return ''; }
858 if ( 0 == $wgArticle->getID() ) { return ''; }
861 if ( !$wgDisableCounters ) {
862 $count = $wgLang->formatNum( $wgArticle->getCount() );
864 $s = wfMsg( 'viewcount', $count );
868 if (isset($wgMaxCredits) && $wgMaxCredits != 0) {
869 require_once("Credits.php");
870 $s .= ' ' . getCredits($wgArticle, $wgMaxCredits, $wgShowCreditsIfMax);
872 $s .= $this->lastModified();
875 return $s . ' ' . $this->getCopyright();
878 function getCopyright() {
879 global $wgRightsPage, $wgRightsUrl, $wgRightsText, $wgRequest;
882 $oldid = $wgRequest->getVal( 'oldid' );
883 $diff = $wgRequest->getVal( 'diff' );
885 if ( !is_null( $oldid ) && is_null( $diff ) && wfMsg( 'history_copyright' ) !== '-' ) {
886 $msg = 'history_copyright';
892 if( $wgRightsPage ) {
893 $link = $this->makeKnownLink( $wgRightsPage, $wgRightsText );
894 } elseif( $wgRightsUrl ) {
895 $link = $this->makeExternalLink( $wgRightsUrl, $wgRightsText );
900 $out .= wfMsg( $msg, $link );
904 function getCopyrightIcon() {
905 global $wgRightsPage, $wgRightsUrl, $wgRightsText, $wgRightsIcon;
907 if( $wgRightsIcon ) {
908 $icon = htmlspecialchars( $wgRightsIcon );
910 $url = htmlspecialchars( $wgRightsUrl );
911 $out .= '<a href="'.$url.'">';
913 $text = htmlspecialchars( $wgRightsText );
914 $out .= "<img src=\"$icon\" alt='$text' />";
922 function getPoweredBy() {
924 $url = htmlspecialchars( "$wgStylePath/common/images/poweredby_mediawiki_88x31.png" );
925 $img = '<a href="http://www.mediawiki.org/"><img src="'.$url.'" alt="MediaWiki" /></a>';
929 function lastModified() {
930 global $wgLang, $wgArticle;
932 $timestamp = $wgArticle->getTimestamp();
934 $d = $wgLang->timeanddate( $wgArticle->getTimestamp(), true );
935 $s = ' ' . wfMsg( 'lastmodified', $d );
942 function logoText( $align = '' ) {
943 if ( '' != $align ) { $a = " align='{$align}'"; }
946 $mp = wfMsg( 'mainpage' );
947 $titleObj = Title
::newFromText( $mp );
948 if ( is_object( $titleObj ) ) {
949 $url = $titleObj->escapeLocalURL();
954 $logourl = $this->getLogo();
955 $s = "<a href='{$url}'><img{$a} src='{$logourl}' alt='[{$mp}]' /></a>";
959 function quickBar() {
960 global $wgOut, $wgTitle, $wgUser, $wgRequest, $wgLang;
961 global $wgDisableUploads, $wgRemoteUploads;
963 $fname = 'Skin::quickBar';
964 wfProfileIn( $fname );
966 $action = $wgRequest->getText( 'action' );
967 $wpPreview = $wgRequest->getBool( 'wpPreview' );
968 $tns=$wgTitle->getNamespace();
970 $s = "\n<div id='quickbar'>";
971 $s .= "\n" . $this->logoText() . "\n<hr class='sep' />";
974 $s .= $this->mainPageLink()
975 . $sep . $this->specialLink( 'recentchanges' )
976 . $sep . $this->specialLink( 'randompage' );
977 if ($wgUser->getID()) {
978 $s.= $sep . $this->specialLink( 'watchlist' ) ;
979 $s .= $sep .$this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
980 wfMsg( 'mycontris' ), 'target=' . wfUrlencode($wgUser->getName() ) );
983 // only show watchlist link if logged in
984 if ( wfMsg ( 'currentevents' ) != '-' ) $s .= $sep . $this->makeKnownLink( wfMsg( 'currentevents' ), '' ) ;
985 $s .= "\n<br /><hr class='sep' />";
986 $articleExists = $wgTitle->getArticleId();
987 if ( $wgOut->isArticle() ||
$action =='edit' ||
$action =='history' ||
$wpPreview) {
988 if($wgOut->isArticle()) {
989 $s .= '<strong>' . $this->editThisPage() . '</strong>';
990 } else { # backlink to the article in edit or history mode
991 if($articleExists){ # no backlink if no article
994 $text = wfMsg('articlepage');
997 $text = wfMsg('viewtalkpage');
1000 $text = wfMsg('userpage');
1003 $text = wfMsg('viewtalkpage');
1006 $text = wfMsg('wikipediapage');
1009 $text = wfMsg('viewtalkpage');
1012 $text = wfMsg('imagepage');
1015 $text = wfMsg('viewtalkpage');
1018 $text= wfMsg('articlepage');
1021 $link = $wgTitle->getText();
1022 if ($nstext = $wgLang->getNsText($tns) ) { # add namespace if necessary
1023 $link = $nstext . ':' . $link ;
1026 $s .= $this->makeLink( $link, $text );
1027 } elseif( $wgTitle->getNamespace() != Namespace::getSpecial() ) {
1028 # we just throw in a "New page" text to tell the user that he's in edit mode,
1029 # and to avoid messing with the separator that is prepended to the next item
1030 $s .= '<strong>' . wfMsg('newpage') . '</strong>';
1036 if( $tns%2
&& $action!='edit' && !$wpPreview) {
1037 $s.= '<br />'.$this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg('postcomment'),'action=edit§ion=new');
1041 watching could cause problems in edit mode:
1042 if user edits article, then loads "watch this article" in background and then saves
1043 article with "Watch this article" checkbox disabled, the article is transparently
1044 unwatched. Therefore we do not show the "Watch this page" link in edit mode
1046 if ( 0 != $wgUser->getID() && $articleExists) {
1047 if($action!='edit' && $action != 'submit' )
1049 $s .= $sep . $this->watchThisPage();
1051 if ( $wgTitle->userCanEdit() )
1052 $s .= $sep . $this->moveThisPage();
1054 if ( $wgUser->isSysop() and $articleExists ) {
1055 $s .= $sep . $this->deleteThisPage() .
1056 $sep . $this->protectThisPage();
1058 $s .= $sep . $this->talkLink();
1059 if ($articleExists && $action !='history') {
1060 $s .= $sep . $this->historyLink();
1062 $s.=$sep . $this->whatLinksHere();
1064 if($wgOut->isArticleRelated()) {
1065 $s .= $sep . $this->watchPageLinksLink();
1068 if ( Namespace::getUser() == $wgTitle->getNamespace()
1069 ||
$wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser())
1072 $id=User
::idFromName($wgTitle->getText());
1073 $ip=User
::isIP($wgTitle->getText());
1076 $s .= $sep . $this->userContribsLink();
1078 if ( 0 != $wgUser->getID() ) {
1079 if($id) { # can only email real users
1080 $s .= $sep . $this->emailUserLink();
1084 $s .= "\n<br /><hr class='sep' />";
1087 if ( 0 != $wgUser->getID() && ( !$wgDisableUploads ||
$wgRemoteUploads ) ) {
1088 $s .= $this->specialLink( 'upload' ) . $sep;
1090 $s .= $this->specialLink( 'specialpages' )
1091 . $sep . $this->bugReportsLink();
1093 global $wgSiteSupportPage;
1094 if( $wgSiteSupportPage ) {
1095 $s .= "\n<br /><a href=\"" . htmlspecialchars( $wgSiteSupportPage ) .
1096 '" class="internal">' . wfMsg( 'sitesupport' ) . '</a>';
1099 $s .= "\n<br /></div>\n";
1100 wfProfileOut( $fname );
1104 function specialPagesList() {
1105 global $wgUser, $wgOut, $wgLang, $wgServer, $wgRedirectScript;
1106 require_once('SpecialPage.php');
1108 $pages = SpecialPage
::getPages();
1110 foreach ( $pages[''] as $name => $page ) {
1111 $a[$name] = $page->getDescription();
1113 if ( $wgUser->isSysop() )
1115 foreach ( $pages['sysop'] as $name => $page ) {
1116 $a[$name] = $page->getDescription();
1119 if ( $wgUser->isDeveloper() )
1121 foreach ( $pages['developer'] as $name => $page ) {
1122 $a[$name] = $page->getDescription() ;
1125 $go = wfMsg( 'go' );
1126 $sp = wfMsg( 'specialpages' );
1127 $spp = $wgLang->specialPage( 'Specialpages' );
1129 $s = '<form id="specialpages" method="get" class="inline" ' .
1130 'action="' . htmlspecialchars( "{$wgServer}{$wgRedirectScript}" ) . "\">\n";
1131 $s .= "<select name=\"wpDropdown\">\n";
1132 $s .= "<option value=\"{$spp}\">{$sp}</option>\n";
1134 foreach ( $a as $name => $desc ) {
1135 $p = $wgLang->specialPage( $name );
1136 $s .= "<option value=\"{$p}\">{$desc}</option>\n";
1138 $s .= "</select>\n";
1139 $s .= "<input type='submit' value=\"{$go}\" name='redirect' />\n";
1144 function mainPageLink() {
1145 $mp = wfMsg( 'mainpage' );
1146 $s = $this->makeKnownLink( $mp, $mp );
1150 function copyrightLink() {
1151 $s = $this->makeKnownLink( wfMsg( 'copyrightpage' ),
1152 wfMsg( 'copyrightpagename' ) );
1156 function aboutLink() {
1157 $s = $this->makeKnownLink( wfMsg( 'aboutpage' ),
1158 wfMsg( 'aboutsite' ) );
1163 function disclaimerLink() {
1164 $s = $this->makeKnownLink( wfMsg( 'disclaimerpage' ),
1165 wfMsg( 'disclaimers' ) );
1169 function editThisPage() {
1170 global $wgOut, $wgTitle, $wgRequest;
1172 $oldid = $wgRequest->getVal( 'oldid' );
1173 $diff = $wgRequest->getVal( 'diff' );
1174 $redirect = $wgRequest->getVal( 'redirect' );
1176 if ( ! $wgOut->isArticleRelated() ) {
1177 $s = wfMsg( 'protectedpage' );
1179 $n = $wgTitle->getPrefixedText();
1180 if ( $wgTitle->userCanEdit() ) {
1181 $t = wfMsg( 'editthispage' );
1183 #$t = wfMsg( "protectedpage" );
1184 $t = wfMsg( 'viewsource' );
1188 if ( !is_null( $redirect ) ) { $red = "&redirect={$redirect}"; }
1189 if ( $oldid && ! isset( $diff ) ) {
1190 $oid = '&oldid='.$oldid;
1192 $s = $this->makeKnownLink( $n, $t, "action=edit{$oid}{$red}" );
1197 function deleteThisPage() {
1198 global $wgUser, $wgOut, $wgTitle, $wgRequest;
1200 $diff = $wgRequest->getVal( 'diff' );
1201 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
1202 $n = $wgTitle->getPrefixedText();
1203 $t = wfMsg( 'deletethispage' );
1205 $s = $this->makeKnownLink( $n, $t, 'action=delete' );
1212 function protectThisPage() {
1213 global $wgUser, $wgOut, $wgTitle, $wgRequest;
1215 $diff = $wgRequest->getVal( 'diff' );
1216 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
1217 $n = $wgTitle->getPrefixedText();
1219 if ( $wgTitle->isProtected() ) {
1220 $t = wfMsg( 'unprotectthispage' );
1221 $q = 'action=unprotect';
1223 $t = wfMsg( 'protectthispage' );
1224 $q = 'action=protect';
1226 $s = $this->makeKnownLink( $n, $t, $q );
1233 function watchThisPage() {
1234 global $wgUser, $wgOut, $wgTitle;
1236 if ( $wgOut->isArticleRelated() ) {
1237 $n = $wgTitle->getPrefixedText();
1239 if ( $wgTitle->userIsWatching() ) {
1240 $t = wfMsg( 'unwatchthispage' );
1241 $q = 'action=unwatch';
1243 $t = wfMsg( 'watchthispage' );
1244 $q = 'action=watch';
1246 $s = $this->makeKnownLink( $n, $t, $q );
1248 $s = wfMsg( 'notanarticle' );
1253 function moveThisPage() {
1254 global $wgTitle, $wgLang;
1256 if ( $wgTitle->userCanEdit() ) {
1257 $s = $this->makeKnownLink( $wgLang->specialPage( 'Movepage' ),
1258 wfMsg( 'movethispage' ), 'target=' . $wgTitle->getPrefixedURL() );
1259 } // no message if page is protected - would be redundant
1263 function historyLink() {
1266 $s = $this->makeKnownLink( $wgTitle->getPrefixedText(),
1267 wfMsg( 'history' ), 'action=history' );
1271 function whatLinksHere() {
1272 global $wgTitle, $wgLang;
1274 $s = $this->makeKnownLink( $wgLang->specialPage( 'Whatlinkshere' ),
1275 wfMsg( 'whatlinkshere' ), 'target=' . $wgTitle->getPrefixedURL() );
1279 function userContribsLink() {
1280 global $wgTitle, $wgLang;
1282 $s = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
1283 wfMsg( 'contributions' ), 'target=' . $wgTitle->getPartialURL() );
1287 function emailUserLink() {
1288 global $wgTitle, $wgLang;
1290 $s = $this->makeKnownLink( $wgLang->specialPage( 'Emailuser' ),
1291 wfMsg( 'emailuser' ), 'target=' . $wgTitle->getPartialURL() );
1295 function watchPageLinksLink() {
1296 global $wgOut, $wgTitle, $wgLang;
1298 if ( ! $wgOut->isArticleRelated() ) {
1299 $s = '(' . wfMsg( 'notanarticle' ) . ')';
1301 $s = $this->makeKnownLink( $wgLang->specialPage(
1302 'Recentchangeslinked' ), wfMsg( 'recentchangeslinked' ),
1303 'target=' . $wgTitle->getPrefixedURL() );
1308 function otherLanguages() {
1309 global $wgOut, $wgLang, $wgTitle, $wgUseNewInterlanguage;
1311 $a = $wgOut->getLanguageLinks();
1312 if ( 0 == count( $a ) ) {
1313 if ( !$wgUseNewInterlanguage ) return '';
1314 $ns = $wgLang->getNsIndex ( $wgTitle->getNamespace () ) ;
1315 if ( $ns != 0 AND $ns != 1 ) return '' ;
1317 $x = 'mode=addlink&xt='.$wgTitle->getDBkey() ;
1318 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1319 wfMsg( 'intl' ) , $x );
1322 if ( !$wgUseNewInterlanguage ) {
1323 $s = wfMsg( 'otherlanguages' ) . ': ';
1325 global $wgLanguageCode ;
1326 $x = 'mode=zoom&xt='.$wgTitle->getDBkey() ;
1327 $x .= '&xl='.$wgLanguageCode ;
1328 $s = $this->makeKnownLink( $wgLang->specialPage( 'Intl' ),
1329 wfMsg( 'otherlanguages' ) , $x ) . ': ' ;
1332 $s = wfMsg( 'otherlanguages' ) . ': ';
1334 if($wgLang->isRTL()) $s .= '<span dir="LTR">';
1335 foreach( $a as $l ) {
1336 if ( ! $first ) { $s .= ' | '; }
1339 $nt = Title
::newFromText( $l );
1340 $url = $nt->getFullURL();
1341 $text = $wgLang->getLanguageName( $nt->getInterwiki() );
1343 if ( '' == $text ) { $text = $l; }
1344 $style = $this->getExternalLinkAttributes( $l, $text );
1345 $s .= "<a href=\"{$url}\"{$style}>{$text}</a>";
1347 if($wgLang->isRTL()) $s .= '</span>';
1351 function bugReportsLink() {
1352 $s = $this->makeKnownLink( wfMsg( 'bugreportspage' ),
1353 wfMsg( 'bugreports' ) );
1357 function dateLink() {
1358 global $wgLinkCache;
1359 $t1 = Title
::newFromText( gmdate( 'F j' ) );
1360 $t2 = Title
::newFromText( gmdate( 'Y' ) );
1362 $wgLinkCache->suspend();
1363 $id = $t1->getArticleID();
1364 $wgLinkCache->resume();
1367 $s = $this->makeBrokenLink( $t1->getText() );
1369 $s = $this->makeKnownLink( $t1->getText() );
1373 $wgLinkCache->suspend();
1374 $id = $t2->getArticleID();
1375 $wgLinkCache->resume();
1378 $s .= $this->makeBrokenLink( $t2->getText() );
1380 $s .= $this->makeKnownLink( $t2->getText() );
1385 function talkLink() {
1386 global $wgLang, $wgTitle, $wgLinkCache;
1388 $tns = $wgTitle->getNamespace();
1389 if ( -1 == $tns ) { return ''; }
1391 $pn = $wgTitle->getText();
1392 $tp = wfMsg( 'talkpage' );
1393 if ( Namespace::isTalk( $tns ) ) {
1394 $lns = Namespace::getSubject( $tns );
1397 $text = wfMsg('articlepage');
1400 $text = wfMsg('userpage');
1403 $text = wfMsg('wikipediapage');
1406 $text = wfMsg('imagepage');
1409 $text= wfMsg('articlepage');
1413 $lns = Namespace::getTalk( $tns );
1416 $n = $wgLang->getNsText( $lns );
1417 if ( '' == $n ) { $link = $pn; }
1418 else { $link = $n.':'.$pn; }
1420 $wgLinkCache->suspend();
1421 $s = $this->makeLink( $link, $text );
1422 $wgLinkCache->resume();
1427 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();
1442 $wgLinkCache->suspend();
1443 $s = $this->makeKnownLink($link, wfMsg('postcomment'), 'action=edit§ion=new');
1444 $wgLinkCache->resume();
1450 * After all the page content is transformed into HTML, it makes
1451 * a final pass through here for things like table backgrounds.
1452 * @todo probably deprecated [AV]
1454 function transformContent( $text ) {
1459 * Note: This function MUST call getArticleID() on the link,
1460 * otherwise the cache won't get updated properly. See LINKCACHE.DOC.
1462 function makeLink( $title, $text = '', $query = '', $trail = '' ) {
1463 wfProfileIn( 'Skin::makeLink' );
1464 $nt = Title
::newFromText( $title );
1466 $result = $this->makeLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1468 wfDebug( 'Invalid title passed to Skin::makeLink(): "'.$title."\"\n" );
1469 $result = $text == "" ?
$title : $text;
1472 wfProfileOut( 'Skin::makeLink' );
1476 function makeKnownLink( $title, $text = '', $query = '', $trail = '', $prefix = '',$aprops = '') {
1477 $nt = Title
::newFromText( $title );
1479 return $this->makeKnownLinkObj( Title
::newFromText( $title ), $text, $query, $trail, $prefix , $aprops );
1481 wfDebug( 'Invalid title passed to Skin::makeKnownLink(): "'.$title."\"\n" );
1482 return $text == '' ?
$title : $text;
1486 function makeBrokenLink( $title, $text = '', $query = '', $trail = '' ) {
1487 $nt = Title
::newFromText( $title );
1489 return $this->makeBrokenLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1491 wfDebug( 'Invalid title passed to Skin::makeBrokenLink(): "'.$title."\"\n" );
1492 return $text == '' ?
$title : $text;
1496 function makeStubLink( $title, $text = '', $query = '', $trail = '' ) {
1497 $nt = Title
::newFromText( $title );
1499 return $this->makeStubLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1501 wfDebug( 'Invalid title passed to Skin::makeStubLink(): "'.$title."\"\n" );
1502 return $text == '' ?
$title : $text;
1507 * Pass a title object, not a title string
1509 function makeLinkObj( &$nt, $text= '', $query = '', $trail = '', $prefix = '' ) {
1510 global $wgOut, $wgUser, $wgLinkHolders;
1511 $fname = 'Skin::makeLinkObj';
1514 if ( ! isset($nt) ) {
1515 # wfDebugDieBacktrace();
1516 return "<!-- ERROR -->{$prefix}{$text}{$trail}";
1519 if ( $nt->isExternal() ) {
1520 $u = $nt->getFullURL();
1521 $link = $nt->getPrefixedURL();
1522 if ( '' == $text ) { $text = $nt->getPrefixedText(); }
1523 $style = $this->getExternalLinkAttributes( $link, $text, 'extiw' );
1526 if ( '' != $trail ) {
1527 if ( preg_match( '/^([a-z]+)(.*)$$/sD', $trail, $m ) ) {
1532 $retVal = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1533 } elseif ( 0 == $nt->getNamespace() && "" == $nt->getText() ) {
1534 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1535 } elseif ( ( -1 == $nt->getNamespace() ) ||
1536 ( Namespace::getImage() == $nt->getNamespace() ) ) {
1537 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1539 if ( $this->postParseLinkColour() ) {
1541 if ( '' != $trail ) {
1542 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1548 # Allows wiki to bypass using linkcache, see OutputPage::parseLinkHolders()
1549 $nr = array_push( $wgLinkHolders['namespaces'], $nt->getNamespace() );
1550 $wgLinkHolders['dbkeys'][] = $nt->getDBkey();
1551 $wgLinkHolders['queries'][] = $query;
1552 $wgLinkHolders['texts'][] = $prefix.$text.$inside;
1553 $wgLinkHolders['titles'][] = $nt;
1555 $retVal = '<!--LINK '. ($nr-1) ."-->{$trail}";
1557 # Work out link colour immediately
1558 $aid = $nt->getArticleID() ;
1560 $retVal = $this->makeBrokenLinkObj( $nt, $text, $query, $trail, $prefix );
1562 $threshold = $wgUser->getOption('stubthreshold') ;
1563 if ( $threshold > 0 ) {
1564 $dbr =& wfGetDB( DB_SLAVE
);
1565 $s = $dbr->selectRow( 'cur', array( 'LENGTH(cur_text) AS x', 'cur_namespace',
1566 'cur_is_redirect' ), array( 'cur_id' => $aid ), $fname ) ;
1567 if ( $s !== false ) {
1569 if ( $s->cur_is_redirect
OR $s->cur_namespace
!= 0 ) {
1570 $size = $threshold*2 ; # Really big
1572 $dbr->freeResult( $res );
1574 $size = $threshold*2 ; # Really big
1579 if ( $size < $threshold ) {
1580 $retVal = $this->makeStubLinkObj( $nt, $text, $query, $trail, $prefix );
1582 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1591 * Pass a title object, not a title string
1593 function makeKnownLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' , $aprops = '' ) {
1594 global $wgOut, $wgTitle, $wgInputEncoding;
1596 $fname = 'Skin::makeKnownLinkObj';
1597 wfProfileIn( $fname );
1599 if ( !is_object( $nt ) ) {
1602 $link = $nt->getPrefixedURL();
1603 # if ( '' != $section && substr($section,0,1) != "#" ) {
1606 if ( '' == $link ) {
1608 if ( '' == $text ) {
1609 $text = htmlspecialchars( $nt->getFragment() );
1612 $u = $nt->escapeLocalURL( $query );
1614 if ( '' != $nt->getFragment() ) {
1615 $anchor = urlencode( do_html_entity_decode( str_replace(' ', '_', $nt->getFragment()), ENT_COMPAT
, $wgInputEncoding ) );
1616 $replacearray = array(
1620 $u .= '#' . str_replace(array_keys($replacearray),array_values($replacearray),$anchor);
1622 if ( '' == $text ) {
1623 $text = htmlspecialchars( $nt->getPrefixedText() );
1625 $style = $this->getInternalLinkAttributesObj( $nt, $text );
1628 if ( '' != $trail ) {
1629 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1634 $r = "<a href=\"{$u}\"{$style}{$aprops}>{$prefix}{$text}{$inside}</a>{$trail}";
1635 wfProfileOut( $fname );
1640 * Pass a title object, not a title string
1642 function makeBrokenLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' ) {
1643 global $wgOut, $wgUser;
1646 if ( ! isset($nt) ) {
1647 # wfDebugDieBacktrace();
1648 return "<!-- ERROR -->{$prefix}{$text}{$trail}";
1651 $fname = 'Skin::makeBrokenLinkObj';
1652 wfProfileIn( $fname );
1654 if ( '' == $query ) {
1657 $q = 'action=edit&'.$query;
1659 $u = $nt->escapeLocalURL( $q );
1661 if ( '' == $text ) {
1662 $text = htmlspecialchars( $nt->getPrefixedText() );
1664 $style = $this->getInternalLinkAttributesObj( $nt, $text, "yes" );
1667 if ( '' != $trail ) {
1668 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1673 if ( $wgUser->getOption( 'highlightbroken' ) ) {
1674 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1676 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>?</a>{$trail}";
1679 wfProfileOut( $fname );
1684 * Pass a title object, not a title string
1686 function makeStubLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' ) {
1687 global $wgOut, $wgUser;
1689 $link = $nt->getPrefixedURL();
1691 $u = $nt->escapeLocalURL( $query );
1693 if ( '' == $text ) {
1694 $text = htmlspecialchars( $nt->getPrefixedText() );
1696 $style = $this->getInternalLinkAttributesObj( $nt, $text, 'stub' );
1699 if ( '' != $trail ) {
1700 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1705 if ( $wgUser->getOption( 'highlightbroken' ) ) {
1706 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1708 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>!</a>{$trail}";
1713 function makeSelfLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' ) {
1714 $u = $nt->escapeLocalURL( $query );
1715 if ( '' == $text ) {
1716 $text = htmlspecialchars( $nt->getPrefixedText() );
1719 if ( '' != $trail ) {
1720 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1725 return "<strong>{$prefix}{$text}{$inside}</strong>{$trail}";
1728 /* these are used extensively in SkinPHPTal, but also some other places */
1729 /*static*/ function makeSpecialUrl( $name, $urlaction='' ) {
1730 $title = Title
::makeTitle( NS_SPECIAL
, $name );
1731 $this->checkTitle($title, $name);
1732 return $title->getLocalURL( $urlaction );
1734 /*static*/ function makeTalkUrl ( $name, $urlaction='' ) {
1735 $title = Title
::newFromText( $name );
1736 $title = $title->getTalkPage();
1737 $this->checkTitle($title, $name);
1738 return $title->getLocalURL( $urlaction );
1740 /*static*/ function makeArticleUrl ( $name, $urlaction='' ) {
1741 $title = Title
::newFromText( $name );
1742 $title= $title->getSubjectPage();
1743 $this->checkTitle($title, $name);
1744 return $title->getLocalURL( $urlaction );
1746 /*static*/ function makeI18nUrl ( $name, $urlaction='' ) {
1747 $title = Title
::newFromText( wfMsgForContent($name) );
1748 $this->checkTitle($title, $name);
1749 return $title->getLocalURL( $urlaction );
1751 /*static*/ function makeUrl ( $name, $urlaction='' ) {
1752 $title = Title
::newFromText( $name );
1753 $this->checkTitle($title, $name);
1754 return $title->getLocalURL( $urlaction );
1756 # this can be passed the NS number as defined in Language.php
1757 /*static*/ function makeNSUrl( $name, $urlaction='', $namespace=0 ) {
1758 $title = Title
::makeTitleSafe( $namespace, $name );
1759 $this->checkTitle($title, $name);
1760 return $title->getLocalURL( $urlaction );
1763 /* these return an array with the 'href' and boolean 'exists' */
1764 /*static*/ function makeUrlDetails ( $name, $urlaction='' ) {
1765 $title = Title
::newFromText( $name );
1766 $this->checkTitle($title, $name);
1768 'href' => $title->getLocalURL( $urlaction ),
1769 'exists' => $title->getArticleID() != 0?
true:false
1772 /*static*/ function makeTalkUrlDetails ( $name, $urlaction='' ) {
1773 $title = Title
::newFromText( $name );
1774 $title = $title->getTalkPage();
1775 $this->checkTitle($title, $name);
1777 'href' => $title->getLocalURL( $urlaction ),
1778 'exists' => $title->getArticleID() != 0?
true:false
1781 /*static*/ function makeArticleUrlDetails ( $name, $urlaction='' ) {
1782 $title = Title
::newFromText( $name );
1783 $title= $title->getSubjectPage();
1784 $this->checkTitle($title, $name);
1786 'href' => $title->getLocalURL( $urlaction ),
1787 'exists' => $title->getArticleID() != 0?
true:false
1790 /*static*/ function makeI18nUrlDetails ( $name, $urlaction='' ) {
1791 $title = Title
::newFromText( wfMsgForContent($name) );
1792 $this->checkTitle($title, $name);
1794 'href' => $title->getLocalURL( $urlaction ),
1795 'exists' => $title->getArticleID() != 0?
true:false
1799 # make sure we have some title to operate on
1800 /*static*/ function checkTitle ( &$title, &$name ) {
1801 if(!is_object($title)) {
1802 $title = Title
::newFromText( $name );
1803 if(!is_object($title)) {
1804 $title = Title
::newFromText( '--error: link target missing--' );
1809 function fnamePart( $url ) {
1810 $basename = strrchr( $url, '/' );
1811 if ( false === $basename ) {
1814 $basename = substr( $basename, 1 );
1816 return htmlspecialchars( $basename );
1819 function makeImage( $url, $alt = '' ) {
1823 $alt = $this->fnamePart( $url );
1825 $s = '<img src="'.$url.'" alt="'.$alt.'" />';
1829 function makeImageLink( $name, $url, $alt = '' ) {
1830 $nt = Title
::makeTitleSafe( NS_IMAGE
, $name );
1831 return $this->makeImageLinkObj( $nt, $alt );
1834 function makeImageLinkObj( $nt, $alt = '' ) {
1835 global $wgLang, $wgUseImageResize;
1836 $img = Image
::newFromTitle( $nt );
1837 $url = $img->getURL();
1840 $prefix = $postfix = '';
1842 if ( $wgUseImageResize ) {
1843 # Check if the alt text is of the form "options|alt text"
1845 # * thumbnail make a thumbnail with enlarge-icon and caption, alignment depends on lang
1846 # * left no resizing, just left align. label is used for alt= only
1847 # * right same, but right aligned
1848 # * none same, but not aligned
1849 # * ___px scale to ___ pixels width, no aligning. e.g. use in taxobox
1850 # * center center the image
1851 # * framed Keep original image size, no magnify-button.
1853 $part = explode( '|', $alt);
1855 $mwThumb =& MagicWord
::get( MAG_IMG_THUMBNAIL
);
1856 $mwLeft =& MagicWord
::get( MAG_IMG_LEFT
);
1857 $mwRight =& MagicWord
::get( MAG_IMG_RIGHT
);
1858 $mwNone =& MagicWord
::get( MAG_IMG_NONE
);
1859 $mwWidth =& MagicWord
::get( MAG_IMG_WIDTH
);
1860 $mwCenter =& MagicWord
::get( MAG_IMG_CENTER
);
1861 $mwFramed =& MagicWord
::get( MAG_IMG_FRAMED
);
1862 $alt = $part[count($part)-1];
1864 $height = $framed = $thumb = false;
1865 $manual_thumb = "" ;
1867 foreach( $part as $key => $val ) {
1868 $val_parts = explode ( "=" , $val , 2 ) ;
1869 $left_part = array_shift ( $val_parts ) ;
1870 if ( ! is_null( $mwThumb->matchVariableStartToEnd($val) ) ) {
1872 } elseif ( count ( $val_parts ) == 1 && ! is_null( $mwThumb->matchVariableStartToEnd($left_part) ) ) {
1873 # use manually specified thumbnail
1875 $manual_thumb = array_shift ( $val_parts ) ;
1876 } elseif ( ! is_null( $mwRight->matchVariableStartToEnd($val) ) ) {
1877 # remember to set an alignment, don't render immediately
1879 } elseif ( ! is_null( $mwLeft->matchVariableStartToEnd($val) ) ) {
1880 # remember to set an alignment, don't render immediately
1882 } elseif ( ! is_null( $mwCenter->matchVariableStartToEnd($val) ) ) {
1883 # remember to set an alignment, don't render immediately
1885 } elseif ( ! is_null( $mwNone->matchVariableStartToEnd($val) ) ) {
1886 # remember to set an alignment, don't render immediately
1888 } elseif ( ! is_null( $match = $mwWidth->matchVariableStartToEnd($val) ) ) {
1889 # $match is the image width in pixels
1890 if ( preg_match( '/^([0-9]*)x([0-9]*)$/', $match, $m ) ) {
1891 $width = intval( $m[1] );
1892 $height = intval( $m[2] );
1894 $width = intval($match);
1896 } elseif ( ! is_null( $mwFramed->matchVariableStartToEnd($val) ) ) {
1900 if ( 'center' == $align )
1902 $prefix = '<span style="text-align: center">';
1903 $postfix = '</span>';
1907 if ( $thumb ||
$framed ) {
1909 # Create a thumbnail. Alignment depends on language
1910 # writing direction, # right aligned for left-to-right-
1911 # languages ("Western languages"), left-aligned
1912 # for right-to-left-languages ("Semitic languages")
1914 # If thumbnail width has not been provided, it is set
1915 # here to 180 pixels
1916 if ( $align == '' ) {
1917 $align = $wgLang->isRTL() ?
'left' : 'right';
1919 if ( ! isset($width) ) {
1922 return $prefix.$this->makeThumbLinkObj( $img, $alt, $align, $width, $height, $framed, $manual_thumb ).$postfix;
1924 } elseif ( isset($width) ) {
1926 # Create a resized image, without the additional thumbnail
1929 if ( ( ! $height === false )
1930 && ( $img->getHeight() * $width / $img->getWidth() > $height ) ) {
1931 print "height=$height<br>\nimg->getHeight() = ".$img->getHeight()."<br>\n";
1932 print 'rescaling by factor '. $height / $img->getHeight() . "<br>\n";
1933 $width = $img->getWidth() * $height / $img->getHeight();
1935 if ( '' == $manual_thumb ) $url = $img->createThumb( $width );
1937 } # endif $wgUseImageResize
1939 if ( empty( $alt ) ) {
1940 $alt = preg_replace( '/\.(.+?)^/', '', $img->getName() );
1942 $alt = htmlspecialchars( $alt );
1944 $u = $nt->escapeLocalURL();
1947 $s = wfMsg( 'missingimage', $img->getName() );
1948 $s .= "<br>{$alt}<br>{$url}<br>\n";
1950 $s = '<a href="'.$u.'" class="image" title="'.$alt.'">' .
1951 '<img src="'.$url.'" alt="'.$alt.'" /></a>';
1953 if ( '' != $align ) {
1954 $s = "<div class=\"float{$align}\"><span>{$s}</span></div>";
1956 return str_replace("\n", ' ',$prefix.$s.$postfix);
1960 * Make HTML for a thumbnail including image, border and caption
1961 * $img is an Image object
1963 function makeThumbLinkObj( $img, $label = '', $align = 'right', $boxwidth = 180, $boxheight=false, $framed=false , $manual_thumb = "" ) {
1964 global $wgStylePath, $wgLang;
1965 # $image = Title::makeTitleSafe( NS_IMAGE, $name );
1966 $url = $img->getURL();
1968 #$label = htmlspecialchars( $label );
1969 $alt = preg_replace( '/<[^>]*>/', '', $label);
1970 $alt = htmlspecialchars( $alt );
1972 $width = $height = 0;
1973 if ( $img->exists() )
1975 $width = $img->getWidth();
1976 $height = $img->getHeight();
1978 if ( 0 == $width ||
0 == $height )
1980 $width = $height = 200;
1982 if ( $boxwidth == 0 )
1988 // Use image dimensions, don't scale
1990 $oboxwidth = $boxwidth +
2;
1991 $boxheight = $height;
1994 $h = intval( $height/($width/$boxwidth) );
1995 $oboxwidth = $boxwidth +
2;
1996 if ( ( ! $boxheight === false ) && ( $h > $boxheight ) )
1998 $boxwidth *= $boxheight/$h;
2002 if ( '' == $manual_thumb ) $thumbUrl = $img->createThumb( $boxwidth );
2005 if ( $manual_thumb != '' ) # Use manually specified thumbnail
2007 $manual_title = Title
::makeTitleSafe( NS_IMAGE
, $manual_thumb ); #new Title ( $manual_thumb ) ;
2008 $manual_img = Image
::newFromTitle( $manual_title );
2009 $thumbUrl = $manual_img->getURL();
2010 if ( $manual_img->exists() )
2012 $width = $manual_img->getWidth();
2013 $height = $manual_img->getHeight();
2014 $boxwidth = $width ;
2015 $boxheight = $height ;
2016 $oboxwidth = $boxwidth +
2 ;
2020 $u = $img->getEscapeLocalURL();
2022 $more = htmlspecialchars( wfMsg( 'thumbnail-more' ) );
2023 $magnifyalign = $wgLang->isRTL() ?
'left' : 'right';
2024 $textalign = $wgLang->isRTL() ?
' style="text-align:right"' : '';
2026 $s = "<div class=\"thumb t{$align}\"><div style=\"width:{$oboxwidth}px;\">";
2027 if ( $thumbUrl == '' ) {
2028 $s .= wfMsg( 'missingimage', $img->getName() );
2031 $s .= '<a href="'.$u.'" class="internal" title="'.$alt.'">'.
2032 '<img src="'.$thumbUrl.'" alt="'.$alt.'" ' .
2033 'width="'.$boxwidth.'" height="'.$boxheight.'" /></a>';
2037 $zoomicon = '<div class="magnify" style="float:'.$magnifyalign.'">'.
2038 '<a href="'.$u.'" class="internal" title="'.$more.'">'.
2039 '<img src="'.$wgStylePath.'/common/images/magnify-clip.png" ' .
2040 'width="15" height="11" alt="'.$more.'" /></a></div>';
2043 $s .= ' <div class="thumbcaption" '.$textalign.'>'.$zoomicon.$label."</div></div></div>";
2044 return str_replace("\n", ' ', $s);
2047 function makeMediaLink( $name, $url, $alt = '' ) {
2048 $nt = Title
::makeTitleSafe( Namespace::getMedia(), $name );
2049 return $this->makeMediaLinkObj( $nt, $alt );
2052 function makeMediaLinkObj( $nt, $alt = '' ) {
2053 if ( ! isset( $nt ) )
2055 ### HOTFIX. Instead of breaking, return empty string.
2058 $name = $nt->getDBKey();
2059 $url = Image
::wfImageUrl( $name );
2060 if ( empty( $alt ) ) {
2061 $alt = preg_replace( '/\.(.+?)^/', '', $name );
2064 $u = htmlspecialchars( $url );
2065 $s = "<a href=\"{$u}\" class='internal' title=\"{$alt}\">{$alt}</a>";
2070 function specialLink( $name, $key = '' ) {
2073 if ( '' == $key ) { $key = strtolower( $name ); }
2074 $pn = $wgLang->ucfirst( $name );
2075 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
2079 function makeExternalLink( $url, $text, $escape = true ) {
2080 $style = $this->getExternalLinkAttributes( $url, $text );
2081 $url = htmlspecialchars( $url );
2083 $text = htmlspecialchars( $text );
2085 return '<a href="'.$url.'"'.$style.'>'.$text.'</a>';
2088 # Called by history lists and recent changes
2091 # Returns text for the start of the tabular part of RC
2092 function beginRecentChangesList() {
2093 $this->rc_cache
= array() ;
2094 $this->rcMoveIndex
= 0;
2095 $this->rcCacheIndex
= 0 ;
2096 $this->lastdate
= '';
2097 $this->rclistOpen
= false;
2101 function beginImageHistoryList() {
2102 $s = "\n<h2>" . wfMsg( 'imghistory' ) . "</h2>\n" .
2103 "<p>" . wfMsg( 'imghistlegend' ) . "</p>\n".'<ul class="special">';
2108 * Returns text for the end of RC
2109 * If enhanced RC is in use, returns pretty much all the text
2111 function endRecentChangesList() {
2112 $s = $this->recentChangesBlock() ;
2113 if( $this->rclistOpen
) {
2120 * Enhanced RC ungrouped line
2122 function recentChangesBlockLine ( $rcObj ) {
2123 global $wgStylePath, $wgLang ;
2125 # Get rc_xxxx variables
2126 extract( $rcObj->mAttribs
) ;
2127 $curIdEq = 'curid='.$rc_cur_id;
2132 $r .= '<img src="'.$wgStylePath.'/common/images/Arr_.png" width="12" height="12" border="0" />' ;
2135 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2136 $r .= ' ';
2138 # M & N (minor & new)
2139 $M = wfMsg( 'minoreditletter' );
2140 $N = wfMsg( 'newpageletter' );
2142 if ( $rc_type == RC_NEW
) {
2155 $r .= ' '.$rcObj->timestamp
.' ' ;
2159 $link = $rcObj->link
;
2160 if ( $rcObj->watched
) $link = '<strong>'.$link.'</strong>' ;
2165 $r .= $rcObj->difflink
;
2169 $r .= $this->makeKnownLinkObj( $rcObj->getTitle(), wfMsg( 'hist' ), $curIdEq.'&action=history' );
2172 $r .= ') . . '.$rcObj->userlink
;
2173 $r .= $rcObj->usertalklink
;
2176 if ( $rc_comment != '' && $rc_type != RC_MOVE
&& $rc_type != RC_MOVE_OVER_REDIRECT
) {
2177 $rc_comment=$this->formatComment($rc_comment, $rcObj->getTitle());
2178 $r .= $wgLang->emphasize( ' ('.$rc_comment.')' );
2188 function recentChangesBlockGroup ( $block ) {
2189 global $wgStylePath, $wgLang ;
2192 $M = wfMsg( 'minoreditletter' );
2193 $N = wfMsg( 'newpageletter' );
2195 # Collate list of users
2197 $userlinks = array () ;
2198 foreach ( $block AS $rcObj ) {
2199 $oldid = $rcObj->mAttribs
['rc_last_oldid'];
2200 if ( $rcObj->mAttribs
['rc_new'] ) $isnew = true ;
2201 $u = $rcObj->userlink
;
2202 if ( !isset ( $userlinks[$u] ) ) $userlinks[$u] = 0 ;
2206 # Sort the list and convert to text
2207 krsort ( $userlinks ) ;
2208 asort ( $userlinks ) ;
2210 foreach ( $userlinks as $userlink => $count) {
2212 if ( $count > 1 ) $text .= " ({$count}×)" ;
2213 array_push ( $users , $text ) ;
2215 $users = ' <font size="-1">['.implode('; ',$users).']</font>' ;
2218 $rci = 'RCI'.$this->rcCacheIndex
;
2219 $rcl = 'RCL'.$this->rcCacheIndex
;
2220 $rcm = 'RCM'.$this->rcCacheIndex
;
2221 $toggleLink = "javascript:toggleVisibility('$rci','$rcm','$rcl')" ;
2222 $arrowdir = $wgLang->isRTL() ?
'l' : 'r';
2223 $tl = '<span id="'.$rcm.'"><a href="'.$toggleLink.'"><img src="'.$wgStylePath.'/common/images/Arr_'.$arrowdir.'.png" width="12" height="12" /></a></span>' ;
2224 $tl .= '<span id="'.$rcl.'" style="display:none"><a href="'.$toggleLink.'"><img src="'.$wgStylePath.'/common/images/Arr_d.png" width="12" height="12" /></a></span>' ;
2230 if ( $isnew ) $r .= $N ;
2231 else $r .= ' ' ;
2232 $r .= ' ' ; # Minor
2235 $r .= ' '.$block[0]->timestamp
.' ' ;
2239 $link = $block[0]->link
;
2240 if ( $block[0]->watched
) $link = '<strong>'.$link.'</strong>' ;
2243 $curIdEq = 'curid=' . $block[0]->mAttribs
['rc_cur_id'];
2244 if ( $block[0]->mAttribs
['rc_type'] != RC_LOG
) {
2246 $r .= ' ('.count($block).' ' ;
2247 if ( $isnew ) $r .= wfMsg('changes');
2248 else $r .= $this->makeKnownLinkObj( $block[0]->getTitle() , wfMsg('changes') ,
2249 $curIdEq.'&diff=0&oldid='.$oldid ) ;
2253 $r .= $this->makeKnownLinkObj( $block[0]->getTitle(), wfMsg( 'history' ), $curIdEq.'&action=history' );
2261 $r .= '<div id="'.$rci.'" style="display:none">' ;
2262 foreach ( $block AS $rcObj ) {
2263 # Get rc_xxxx variables
2264 extract( $rcObj->mAttribs
);
2266 $r .= '<img src="'.$wgStylePath.'/common/images/Arr_.png" width="12" height="12" />';
2267 $r .= '<tt> ' ;
2268 if ( $rc_new ) $r .= $N ;
2269 else $r .= ' ' ;
2270 if ( $rc_minor ) $r .= $M ;
2271 else $r .= ' ' ;
2275 if ( $rc_last_oldid != 0 ) {
2276 $o = 'oldid='.$rc_last_oldid ;
2278 if ( $rc_type == RC_LOG
) {
2279 $link = $rcObj->timestamp
;
2281 $link = $this->makeKnownLinkObj( $rcObj->getTitle(), $rcObj->timestamp
, "{$curIdEq}&$o" ) ;
2283 $link = '<tt>'.$link.'</tt>' ;
2287 $r .= $rcObj->curlink
;
2289 $r .= $rcObj->lastlink
;
2290 $r .= ') . . '.$rcObj->userlink
;
2291 $r .= $rcObj->usertalklink
;
2292 if ( $rc_comment != '' ) {
2293 $rc_comment=$this->formatComment($rc_comment, $rcObj->getTitle());
2294 $r .= $wgLang->emphasize( ' ('.$rc_comment.')' ) ;
2300 $this->rcCacheIndex++
;
2305 * If enhanced RC is in use, this function takes the previously cached
2306 * RC lines, arranges them, and outputs the HTML
2308 function recentChangesBlock () {
2309 global $wgStylePath ;
2310 if ( count ( $this->rc_cache
) == 0 ) return '' ;
2312 foreach ( $this->rc_cache
AS $secureName => $block ) {
2313 if ( count ( $block ) < 2 ) {
2314 $blockOut .= $this->recentChangesBlockLine ( array_shift ( $block ) ) ;
2316 $blockOut .= $this->recentChangesBlockGroup ( $block ) ;
2320 return '<div>'.$blockOut.'</div>' ;
2324 * Called in a loop over all displayed RC entries
2325 * Either returns the line, or caches it for later use
2327 function recentChangesLine( &$rc, $watched = false ) {
2329 $usenew = $wgUser->getOption( 'usenewrc' );
2331 $line = $this->recentChangesLineNew ( $rc, $watched ) ;
2333 $line = $this->recentChangesLineOld ( $rc, $watched ) ;
2337 function recentChangesLineOld( &$rc, $watched = false ) {
2338 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds, $wgUseRCPatrol, $wgOnlySysopsCanPatrol;
2340 # Extract DB fields into local scope
2341 extract( $rc->mAttribs
);
2342 $curIdEq = 'curid=' . $rc_cur_id;
2344 # Make date header if necessary
2345 $date = $wgLang->date( $rc_timestamp, true);
2347 if ( $date != $this->lastdate
) {
2348 if ( '' != $this->lastdate
) { $s .= "</ul>\n"; }
2349 $s .= "<h4>{$date}</h4>\n<ul class='special'>";
2350 $this->lastdate
= $date;
2351 $this->rclistOpen
= true;
2354 # If this edit has not yet been patrolled, make it stick out
2355 $s .= ( ! $wgUseRCPatrol ||
$rc_patrolled ) ?
'<li> ' : '<li class="not_patrolled"> ';
2357 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2359 $s .= '(' . wfMsg( 'diff' ) . ') (';
2361 $s .= $this->makeKnownLinkObj( $rc->getMovedToTitle(), wfMsg( 'hist' ), 'action=history' ) .
2364 # "[[x]] moved to [[y]]"
2365 $msg = ( $rc_type == RC_MOVE
) ?
'1movedto2' : '1movedto2_redir';
2366 $s .= wfMsg( $msg, $this->makeKnownLinkObj( $rc->getTitle(), '', 'redirect=no' ),
2367 $this->makeKnownLinkObj( $rc->getMovedToTitle(), '' ) );
2368 } elseif( $rc_namespace == NS_SPECIAL
&& preg_match( '!^Log/(.*)$!', $rc_title, $matches ) ) {
2370 $logtype = $matches[1];
2371 $logname = LogPage
::logName( $logtype );
2372 $s .= '(' . $this->makeKnownLinkObj( $rc->getTitle(), $logname ) . ')';
2375 if ( $rc_type == RC_NEW ||
$rc_type == RC_LOG
) {
2376 $diffLink = wfMsg( 'diff' );
2378 if ( $wgUseRCPatrol && $rc_patrolled == 0 && $wgUser->getID() != 0 &&
2379 ( $wgUser->isSysop() ||
!$wgOnlySysopsCanPatrol ) )
2380 $rcidparam = "&rcid={$rc_id}";
2383 $diffLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'diff' ),
2384 "{$curIdEq}&diff={$rc_this_oldid}&oldid={$rc_last_oldid}{$rcidparam}",
2385 '', '', ' tabindex="'.$rc->counter
.'"');
2387 $s .= '('.$diffLink.') (';
2390 $s .= $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'hist' ), $curIdEq.'&action=history' );
2393 # M and N (minor and new)
2394 if ( $rc_minor ) { $s .= ' <span class="minor">'.wfMsg( "minoreditletter" ).'</span>'; }
2395 if ( $rc_type == RC_NEW
) { $s .= '<span class="newpage">'.wfMsg( "newpageletter" ).'</span>'; }
2398 # If it's a new article, there is no diff link, but if it hasn't been
2399 # patrolled yet, we need to give users a way to do so
2400 if ( $wgUseRCPatrol && $rc_type == RC_NEW
&& $rc_patrolled == 0 &&
2401 $wgUser->getID() != 0 && ( $wgUser->isSysop() ||
!$wgOnlySysopsCanPatrol ) )
2402 $articleLink = $this->makeKnownLinkObj( $rc->getTitle(), '', "rcid={$rc_id}" );
2404 $articleLink = $this->makeKnownLinkObj( $rc->getTitle(), '' );
2407 $articleLink = '<strong>'.$articleLink.'</strong>';
2409 $s .= ' '.$articleLink;
2414 $s .= '; ' . $wgLang->time( $rc_timestamp, true, $wgRCSeconds ) . ' . . ';
2416 # User link (or contributions for unregistered users)
2417 if ( 0 == $rc_user ) {
2418 $userLink = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
2419 $rc_user_text, 'target=' . $rc_user_text );
2421 $userLink = $this->makeLink( $wgLang->getNsText( NS_USER
) . ':'.$rc_user_text, $rc_user_text );
2426 $talkname=$wgLang->getNsText(NS_TALK
); # use the shorter name
2427 global $wgDisableAnonTalk;
2428 if( 0 == $rc_user && $wgDisableAnonTalk ) {
2431 $utns=$wgLang->getNsText(NS_USER_TALK
);
2432 $userTalkLink= $this->makeLink($utns . ':'.$rc_user_text, $talkname );
2436 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2437 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2438 'Blockip' ), wfMsg( 'blocklink' ), 'ip='.$rc_user_text );
2442 if($userTalkLink) $userTalkLink .= ' | ';
2443 $userTalkLink .= $blockLink;
2445 if($userTalkLink) $s.=' ('.$userTalkLink.')';
2448 if ( '' != $rc_comment && '*' != $rc_comment && $rc_type != RC_MOVE
&& $rc_type != RC_MOVE_OVER_REDIRECT
) {
2449 $rc_comment=$this->formatComment($rc_comment,$rc->getTitle());
2450 $s .= $wgLang->emphasize(' (' . $rc_comment . ')');
2457 function recentChangesLineNew( &$baseRC, $watched = false ) {
2458 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds;
2460 # Create a specialised object
2461 $rc = RCCacheEntry
::newFromParent( $baseRC ) ;
2463 # Extract fields from DB into the function scope (rc_xxxx variables)
2464 extract( $rc->mAttribs
);
2465 $curIdEq = 'curid=' . $rc_cur_id;
2467 # If it's a new day, add the headline and flush the cache
2468 $date = $wgLang->date( $rc_timestamp, true);
2470 if ( $date != $this->lastdate
) {
2471 # Process current cache
2472 $ret = $this->recentChangesBlock () ;
2473 $this->rc_cache
= array() ;
2474 $ret .= "<h4>{$date}</h4>\n";
2475 $this->lastdate
= $date;
2479 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2480 $msg = ( $rc_type == RC_MOVE
) ?
"1movedto2" : "1movedto2_redir";
2481 $clink = wfMsg( $msg, $this->makeKnownLinkObj( $rc->getTitle(), '', 'redirect=no' ),
2482 $this->makeKnownLinkObj( $rc->getMovedToTitle(), '' ) );
2483 } elseif( $rc_namespace == NS_SPECIAL
&& preg_match( '!^Log/(.*)$!', $rc_title, $matches ) ) {
2485 $logtype = $matches[1];
2486 $logname = LogPage
::logName( $logtype );
2487 $clink = '(' . $this->makeKnownLinkObj( $rc->getTitle(), $logname ) . ')';
2489 $clink = $this->makeKnownLinkObj( $rc->getTitle(), '' ) ;
2492 $time = $wgLang->time( $rc_timestamp, true, $wgRCSeconds );
2493 $rc->watched
= $watched ;
2494 $rc->link
= $clink ;
2495 $rc->timestamp
= $time;
2497 # Make "cur" and "diff" links
2498 if ( ( $rc_type == RC_NEW
&& $rc_this_oldid == 0 ) ||
$rc_type == RC_LOG ||
$rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2499 $curLink = wfMsg( 'cur' );
2500 $diffLink = wfMsg( 'diff' );
2502 $query = $curIdEq.'&diff=0&oldid='.$rc_this_oldid;
2503 $aprops = ' tabindex="'.$baseRC->counter
.'"';
2504 $curLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'cur' ), $query, '' ,'' , $aprops );
2505 $diffLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'diff'), $query, '' ,'' , $aprops );
2509 $titleObj = $rc->getTitle();
2510 if ( $rc_last_oldid == 0 ||
$rc_type == RC_LOG ||
$rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2511 $lastLink = wfMsg( 'last' );
2513 $lastLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'last' ),
2514 $curIdEq.'&diff='.$rc_this_oldid.'&oldid='.$rc_last_oldid );
2517 # Make user link (or user contributions for unregistered users)
2518 if ( $rc_user == 0 ) {
2519 $userLink = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
2520 $rc_user_text, 'target=' . $rc_user_text );
2522 $userLink = $this->makeLink( $wgLang->getNsText(
2523 Namespace::getUser() ) . ':'.$rc_user_text, $rc_user_text );
2526 $rc->userlink
= $userLink;
2527 $rc->lastlink
= $lastLink;
2528 $rc->curlink
= $curLink;
2529 $rc->difflink
= $diffLink;
2531 # Make user talk link
2532 $utns=$wgLang->getNsText(NS_USER_TALK
);
2533 $talkname=$wgLang->getNsText(NS_TALK
); # use the shorter name
2534 $userTalkLink= $this->makeLink($utns . ':'.$rc_user_text, $talkname );
2536 global $wgDisableAnonTalk;
2537 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2538 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2539 'Blockip' ), wfMsg( 'blocklink' ), 'ip='.$rc_user_text );
2540 if( $wgDisableAnonTalk )
2541 $rc->usertalklink
= ' ('.$blockLink.')';
2543 $rc->usertalklink
= ' ('.$userTalkLink.' | '.$blockLink.')';
2545 if( $wgDisableAnonTalk && ($rc_user == 0) )
2546 $rc->usertalklink
= '';
2548 $rc->usertalklink
= ' ('.$userTalkLink.')';
2551 # Put accumulated information into the cache, for later display
2552 # Page moves go on their own line
2553 $title = $rc->getTitle();
2554 $secureName = $title->getPrefixedDBkey();
2555 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2556 # Use an @ character to prevent collision with page names
2557 $this->rc_cache
['@@' . ($this->rcMoveIndex++
)] = array($rc);
2559 if ( !isset ( $this->rc_cache
[$secureName] ) ) $this->rc_cache
[$secureName] = array() ;
2560 array_push ( $this->rc_cache
[$secureName] , $rc ) ;
2565 function endImageHistoryList() {
2571 * This function is called by all recent changes variants, by the page history,
2572 * and by the user contributions list. It is responsible for formatting edit
2573 * comments. It escapes any HTML in the comment, but adds some CSS to format
2574 * auto-generated comments (from section editing) and formats [[wikilinks]].
2576 * The &$title parameter must be a title OBJECT. It is used to generate a
2577 * direct link to the section in the autocomment.
2578 * @author Erik Moeller <moeller@scireview.de>
2580 * Note: there's not always a title to pass to this function.
2581 * Since you can't set a default parameter for a reference, I've turned it
2582 * temporarily to a value pass. Should be adjusted further. --brion
2584 function formatComment($comment, $title = NULL) {
2586 $comment = htmlspecialchars( $comment );
2588 # The pattern for autogen comments is / * foo * /, which makes for
2590 # We look for all comments, match any text before and after the comment,
2591 # add a separator where needed and format the comment itself with CSS
2592 while (preg_match('/(.*)\/\*\s*(.*?)\s*\*\/(.*)/', $comment,$match)) {
2600 # This is hackish but should work in most cases.
2601 $section=str_replace('[[','',$section);
2602 $section=str_replace(']]','',$section);
2603 $title->mFragment
=$section;
2604 $link=$this->makeKnownLinkObj($title,wfMsg('sectionlink'));
2608 if($pre) { $auto = $sep.' '.$auto; }
2609 if($post) { $auto .= ' '.$sep; }
2610 $auto='<span class="autocomment">'.$auto.'</span>';
2611 $comment=$pre.$auto.$post;
2614 # format regular and media links - all other wiki formatting
2616 $medians = $wgLang->getNsText(Namespace::getMedia()).':';
2617 while(preg_match('/\[\[(.*?)(\|(.*?))*\]\](.*)$/',$comment,$match)) {
2618 # Handle link renaming [[foo|text]] will show link as "text"
2619 if( "" != $match[3] ) {
2624 if( preg_match( '/^' . $medians . '(.*)$/i', $match[1], $submatch ) ) {
2625 # Media link; trail not supported.
2626 $linkRegexp = '/\[\[(.*?)\]\]/';
2627 $thelink = $this->makeMediaLink( $submatch[1], "", $text );
2629 # Other kind of link
2630 if( preg_match( wfMsg( "linktrail" ), $match[4], $submatch ) ) {
2631 $trail = $submatch[1];
2635 $linkRegexp = '/\[\[(.*?)\]\]' . preg_quote( $trail, '/' ) . '/';
2636 if ($match[1][0] == ':')
2637 $match[1] = substr($match[1], 1);
2638 $thelink = $this->makeLink( $match[1], $text, "", $trail );
2640 $comment = preg_replace( $linkRegexp, $thelink, $comment, 1 );
2645 function imageHistoryLine( $iscur, $timestamp, $img, $user, $usertext, $size, $description ) {
2646 global $wgUser, $wgLang, $wgTitle;
2648 $datetime = $wgLang->timeanddate( $timestamp, true );
2649 $del = wfMsg( 'deleteimg' );
2650 $delall = wfMsg( 'deleteimgcompletely' );
2651 $cur = wfMsg( 'cur' );
2654 $url = Image
::wfImageUrl( $img );
2656 if ( $wgUser->isSysop() ) {
2657 $link = $wgTitle->escapeLocalURL( 'image=' . $wgTitle->getPartialURL() .
2659 $style = $this->getInternalLinkAttributes( $link, $delall );
2661 $dlink = '<a href="'.$link.'"'.$style.'>'.$delall.'</a>';
2666 $url = htmlspecialchars( wfImageArchiveUrl( $img ) );
2667 if( $wgUser->getID() != 0 && $wgTitle->userCanEdit() ) {
2668 $rlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2669 wfMsg( 'revertimg' ), 'action=revert&oldimage=' .
2670 urlencode( $img ) );
2671 $dlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2672 $del, 'action=delete&oldimage=' . urlencode( $img ) );
2674 # Having live active links for non-logged in users
2675 # means that bots and spiders crawling our site can
2676 # inadvertently change content. Baaaad idea.
2677 $rlink = wfMsg( 'revertimg' );
2682 $userlink = $usertext;
2684 $userlink = $this->makeLink( $wgLang->getNsText( Namespace::getUser() ) .
2685 ':'.$usertext, $usertext );
2687 $nbytes = wfMsg( 'nbytes', $size );
2688 $style = $this->getInternalLinkAttributes( $url, $datetime );
2690 $s = "<li> ({$dlink}) ({$rlink}) <a href=\"{$url}\"{$style}>{$datetime}</a>"
2691 . " . . {$userlink} ({$nbytes})";
2693 if ( '' != $description && '*' != $description ) {
2694 $sk=$wgUser->getSkin();
2695 $s .= $wgLang->emphasize(' (' . $sk->formatComment($description,$wgTitle) . ')');
2701 function tocIndent($level) {
2702 return str_repeat( '<div class="tocindent">'."\n", $level>0 ?
$level : 0 );
2705 function tocUnindent($level) {
2706 return str_repeat( "</div>\n", $level>0 ?
$level : 0 );
2710 * parameter level defines if we are on an indentation level
2712 function tocLine( $anchor, $tocline, $level ) {
2713 $link = '<a href="#'.$anchor.'">'.$tocline.'</a><br />';
2717 return '<div class="tocline">'.$link."</div>\n";
2722 function tocTable($toc) {
2723 # note to CSS fanatics: putting this in a div does not work -- div won't auto-expand
2724 # try min-width & co when somebody gets a chance
2725 $hideline = ' <script type="text/javascript">showTocToggle("' . addslashes( wfMsg('showtoc') ) . '","' . addslashes( wfMsg('hidetoc') ) . '")</script>';
2727 '<table border="0" id="toc"><tr id="toctitle"><td align="center">'."\n".
2728 '<b>'.wfMsg('toc').'</b>' .
2730 '</td></tr><tr id="tocinside"><td>'."\n".
2731 $toc."</td></tr></table>\n";
2735 * These two do not check for permissions: check $wgTitle->userCanEdit
2736 * before calling them
2738 function editSectionScriptForOther( $title, $section, $head ) {
2739 $ttl = Title
::newFromText( $title );
2740 $url = $ttl->escapeLocalURL( 'action=edit§ion='.$section );
2741 return '<span oncontextmenu=\'document.location="'.$url.'";return false;\'>'.$head.'</span>';
2744 function editSectionScript( $section, $head ) {
2745 global $wgTitle, $wgRequest;
2746 if( $wgRequest->getInt( 'oldid' ) && ( $wgRequest->getVal( 'diff' ) != '0' ) ) {
2749 $url = $wgTitle->escapeLocalURL( 'action=edit§ion='.$section );
2750 return '<span oncontextmenu=\'document.location="'.$url.'";return false;\'>'.$head.'</span>';
2753 function editSectionLinkForOther( $title, $section ) {
2755 global $wgUser, $wgLang;
2757 $title = Title
::newFromText($title);
2758 $editurl = '§ion='.$section;
2759 $url = $this->makeKnownLink($title->getPrefixedText(),wfMsg('editsection'),'action=edit'.$editurl);
2761 if( $wgLang->isRTL() ) {
2763 $nearside = 'right';
2768 return "<div class=\"editsection\" style=\"float:$farside;margin-$nearside:5px;\">[".$url."]</div>";
2772 function editSectionLink( $section ) {
2774 global $wgTitle, $wgUser, $wgLang;
2776 if( $wgRequest->getInt( 'oldid' ) && ( $wgRequest->getVal( 'diff' ) != '0' ) ) {
2777 # Section edit links would be out of sync on an old page.
2778 # But, if we're diffing to the current page, they'll be
2783 $editurl = '§ion='.$section;
2784 $url = $this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg('editsection'),'action=edit'.$editurl);
2786 if( $wgLang->isRTL() ) {
2788 $nearside = 'right';
2793 return "<div class=\"editsection\" style=\"float:$farside;margin-$nearside:5px;\">[".$url."]</div>";
2798 * This function is called by EditPage.php and shows a bulletin board style
2799 * toolbar for common editing functions. It can be disabled in the user
2801 * The necessary JavaScript code can be found in style/wikibits.js.
2803 function getEditToolbar() {
2804 global $wgStylePath, $wgLang, $wgMimeType;
2807 * toolarray an array of arrays which each include the filename of
2808 * the button image (without path), the opening tag, the closing tag,
2809 * and optionally a sample text that is inserted between the two when no
2810 * selection is highlighted.
2811 * The tip text is shown when the user moves the mouse over the button.
2813 * Already here are accesskeys (key), which are not used yet until someone
2814 * can figure out a way to make them work in IE. However, we should make
2815 * sure these keys are not defined on the edit page.
2818 array( 'image'=>'button_bold.png',
2820 'close' => "\'\'\'",
2821 'sample'=> wfMsg('bold_sample'),
2822 'tip' => wfMsg('bold_tip'),
2825 array( 'image'=>'button_italic.png',
2828 'sample'=> wfMsg('italic_sample'),
2829 'tip' => wfMsg('italic_tip'),
2832 array( 'image'=>'button_link.png',
2835 'sample'=> wfMsg('link_sample'),
2836 'tip' => wfMsg('link_tip'),
2839 array( 'image'=>'button_extlink.png',
2842 'sample'=> wfMsg('extlink_sample'),
2843 'tip' => wfMsg('extlink_tip'),
2846 array( 'image'=>'button_headline.png',
2848 'close' => " ==\\n",
2849 'sample'=> wfMsg('headline_sample'),
2850 'tip' => wfMsg('headline_tip'),
2853 array( 'image'=>'button_image.png',
2854 'open' => '[['.$wgLang->getNsText(NS_IMAGE
).":",
2856 'sample'=> wfMsg('image_sample'),
2857 'tip' => wfMsg('image_tip'),
2860 array( 'image' => 'button_media.png',
2861 'open' => '[['.$wgLang->getNsText(NS_MEDIA
).':',
2863 'sample'=> wfMsg('media_sample'),
2864 'tip' => wfMsg('media_tip'),
2867 array( 'image' => 'button_math.png',
2868 'open' => "\\<math\\>",
2869 'close' => "\\</math\\>",
2870 'sample'=> wfMsg('math_sample'),
2871 'tip' => wfMsg('math_tip'),
2874 array( 'image' => 'button_nowiki.png',
2875 'open' => "\\<nowiki\\>",
2876 'close' => "\\</nowiki\\>",
2877 'sample'=> wfMsg('nowiki_sample'),
2878 'tip' => wfMsg('nowiki_tip'),
2881 array( 'image' => 'button_sig.png',
2885 'tip' => wfMsg('sig_tip'),
2888 array( 'image' => 'button_hr.png',
2889 'open' => "\\n----\\n",
2892 'tip' => wfMsg('hr_tip'),
2896 $toolbar ="<script type='text/javascript'>\n/*<![CDATA[*/\n";
2898 $toolbar.="document.writeln(\"<div id='toolbar'>\");\n";
2899 foreach($toolarray as $tool) {
2901 $image=$wgStylePath.'/common/images/'.$tool['image'];
2902 $open=$tool['open'];
2903 $close=$tool['close'];
2904 $sample = addslashes( $tool['sample'] );
2906 // Note that we use the tip both for the ALT tag and the TITLE tag of the image.
2907 // Older browsers show a "speedtip" type message only for ALT.
2908 // Ideally these should be different, realistically they
2909 // probably don't need to be.
2910 $tip = addslashes( $tool['tip'] );
2912 #$key = $tool["key"];
2914 $toolbar.="addButton('$image','$tip','$open','$close','$sample');\n";
2917 $toolbar.="addInfobox('" . addslashes( wfMsg( "infobox" ) ) . "','" . addslashes(wfMsg("infobox_alert")) . "');\n";
2918 $toolbar.="document.writeln(\"</div>\");\n";
2920 $toolbar.="/*]]>*/\n</script>";
2927 function suppressUrlExpansion() {