Localize the 'Categories:' link.
[lhc/web/wiklou.git] / includes / Skin.php
1 <?php
2
3 include_once( "Feed.php" );
4 include_once( "Image.php" );
5
6 # See skin.doc
7
8 # These are the INTERNAL names, which get mapped
9 # directly to class names. For display purposes, the
10 # Language class has internationalized names
11 #
12 /* private */ $wgValidSkinNames = array(
13 'standard' => "Standard",
14 'nostalgia' => "Nostalgia",
15 'cologneblue' => "CologneBlue"
16 );
17 if( $wgUsePHPTal ) {
18 #$wgValidSkinNames[] = "PHPTal";
19 #$wgValidSkinNames['davinci'] = "DaVinci";
20 #$wgValidSkinNames['mono'] = "Mono";
21 $wgValidSkinNames['monobook'] = "MonoBook";
22 #$wgValidSkinNames['monobookminimal'] = "MonoBookMinimal";
23 }
24
25 include_once( "RecentChange.php" );
26
27 class RCCacheEntry extends RecentChange
28 {
29 var $secureName, $link;
30 var $curlink , $lastlink , $usertalklink , $versionlink ;
31 var $userlink, $timestamp, $watched;
32
33 function newFromParent( $rc )
34 {
35 $rc2 = new RCCacheEntry;
36 $rc2->mAttribs = $rc->mAttribs;
37 $rc2->mExtra = $rc->mExtra;
38 return $rc2;
39 }
40 } ;
41
42 class Skin {
43
44 /* private */ var $lastdate, $lastline;
45 var $linktrail ; # linktrail regexp
46 var $rc_cache ; # Cache for Enhanced Recent Changes
47 var $rcCacheIndex ; # Recent Changes Cache Counter for visibility toggle
48 var $rcMoveIndex;
49
50 function Skin()
51 {
52 $this->linktrail = wfMsg("linktrail");
53 }
54
55 function getSkinNames()
56 {
57 global $wgValidSkinNames;
58 return $wgValidSkinNames;
59 }
60
61 function getStylesheet()
62 {
63 return "wikistandard.css";
64 }
65
66 function qbSetting()
67 {
68 global $wgOut, $wgUser;
69
70 if ( $wgOut->isQuickbarSuppressed() ) { return 0; }
71 $q = $wgUser->getOption( "quickbar" );
72 if ( "" == $q ) { $q = 0; }
73 return $q;
74 }
75
76 function initPage( &$out )
77 {
78 $fname = "Skin::initPage";
79 wfProfileIn( $fname );
80
81 $out->addLink( array( "rel" => "shortcut icon", "href" => "/favicon.ico" ) );
82
83 $this->addMetadataLinks($out);
84
85 wfProfileOut( $fname );
86 }
87
88 function addMetadataLinks( &$out ) {
89 global $wgTitle, $wgEnableDublinCoreRdf, $wgEnableCreativeCommonsRdf, $wgRdfMimeType, $action;
90 global $wgRightsPage, $wgRightsUrl;
91
92 if( $out->isArticleRelated() ) {
93 # note: buggy CC software only reads first "meta" link
94 if( $wgEnableCreativeCommonsRdf ) {
95 $out->addMetadataLink( array(
96 'title' => 'Creative Commons',
97 'type' => 'application/rdf+xml',
98 'href' => $wgTitle->getLocalURL( "action=creativecommons") ) );
99 }
100 if( $wgEnableDublinCoreRdf ) {
101 $out->addMetadataLink( array(
102 'title' => 'Dublin Core',
103 'type' => 'application/rdf+xml',
104 'href' => $wgTitle->getLocalURL( "action=dublincore" ) ) );
105 }
106 }
107 $copyright = "";
108 if( $wgRightsPage ) {
109 $copy = Title::newFromText( $wgRightsPage );
110 if( $copy ) {
111 $copyright = $copy->getLocalURL();
112 }
113 }
114 if( !$copyright && $wgRightsUrl ) {
115 $copyright = $wgRightsUrl;
116 }
117 if( $copyright ) {
118 $out->addLink( array(
119 "rel" => "copyright",
120 "href" => $copyright ) );
121 }
122 }
123
124 function outputPage( &$out ) {
125 global $wgDebugComments;
126
127 wfProfileIn( "Skin::outputPage" );
128 $this->initPage( $out );
129 $out->out( $out->headElement() );
130
131 $out->out( "\n<body" );
132 $ops = $this->getBodyOptions();
133 foreach ( $ops as $name => $val ) {
134 $out->out( " $name='$val'" );
135 }
136 $out->out( ">\n" );
137 if ( $wgDebugComments ) {
138 $out->out( "<!-- Wiki debugging output:\n" .
139 $out->mDebugtext . "-->\n" );
140 }
141 $out->out( $this->beforeContent() );
142
143 $out->out( $out->mBodytext . "\n" );
144
145 $out->out( $this->afterContent() );
146
147 wfProfileClose();
148 $out->out( $out->reportTime() );
149
150 $out->out( "\n</body></html>" );
151 }
152
153 function getHeadScripts() {
154 global $wgStylePath;
155 $r = "<script type=\"text/javascript\" src=\"{$wgStylePath}/wikibits.js\"></script>\n";
156 return $r;
157 }
158
159 function getUserStyles()
160 {
161 global $wgOut, $wgStylePath;
162 $sheet = $this->getStylesheet();
163 $s = "<style type='text/css'>\n";
164 $s .= "/*/*/\n"; # <-- Hide the styles from Netscape 4 without hiding them from IE/Mac
165 $s .= "@import url(\"$wgStylePath/$sheet\");\n";
166 $s .= $this->doGetUserStyles();
167 $s .= "/* */\n";
168 $s .= "</style>\n";
169 return $s;
170 }
171
172 function doGetUserStyles()
173 {
174 global $wgUser;
175
176 $s = "";
177 if ( 1 == $wgUser->getOption( "underline" ) ) {
178 # Don't override browser settings
179 } else {
180 # CHECK MERGE @@@
181 # Force no underline
182 $s .= "a { " .
183 "text-decoration: none; }\n";
184 }
185 if ( 1 == $wgUser->getOption( "highlightbroken" ) ) {
186 $s .= "a.new, #quickbar a.new { color: #CC2200; }\n";
187 }
188 if ( 1 == $wgUser->getOption( "justify" ) ) {
189 $s .= "#article { text-align: justify; }\n";
190 }
191 return $s;
192 }
193
194 function getBodyOptions()
195 {
196 global $wgUser, $wgTitle, $wgNamespaceBackgrounds, $wgOut, $wgRequest;
197
198 extract( $wgRequest->getValues( 'oldid', 'redirect', 'diff' ) );
199
200 if ( 0 != $wgTitle->getNamespace() ) {
201 $a = array( "bgcolor" => "#ffffec" );
202 }
203 else $a = array( "bgcolor" => "#FFFFFF" );
204 if($wgOut->isArticle() && $wgUser->getOption("editondblclick") &&
205 (!$wgTitle->isProtected() || $wgUser->isSysop()) ) {
206 $t = wfMsg( "editthispage" );
207 $oid = $red = "";
208 if ( !empty($redirect) ) {
209 $red = "&redirect={$redirect}";
210 }
211 if ( !empty($oldid) && ! isset( $diff ) ) {
212 $oid = "&oldid={$oldid}";
213 }
214 $s = $wgTitle->getFullURL( "action=edit{$oid}{$red}" );
215 $s = "document.location = \"" .$s ."\";";
216 $a += array ("ondblclick" => $s);
217
218 }
219 $a['onload'] = $wgOut->getOnloadHandler();
220 return $a;
221 }
222
223 function getExternalLinkAttributes( $link, $text )
224 {
225 global $wgUser, $wgOut, $wgLang;
226
227 $link = urldecode( $link );
228 $link = $wgLang->checkTitleEncoding( $link );
229 $link = str_replace( "_", " ", $link );
230 $link = wfEscapeHTML( $link );
231
232 $r = " class='external'";
233
234 if ( 1 == $wgUser->getOption( "hover" ) ) {
235 $r .= " title=\"{$link}\"";
236 }
237 return $r;
238 }
239
240 function getInternalLinkAttributes( $link, $text, $broken = false )
241 {
242 global $wgUser, $wgOut;
243
244 $link = urldecode( $link );
245 $link = str_replace( "_", " ", $link );
246 $link = wfEscapeHTML( $link );
247
248 if ( $broken == "stub" ) {
249 $r = " class='stub'";
250 } else if ( $broken == "yes" ) {
251 $r = " class='new'";
252 } else {
253 $r = "";
254 }
255
256 if ( 1 == $wgUser->getOption( "hover" ) ) {
257 $r .= " title=\"{$link}\"";
258 }
259 return $r;
260 }
261
262 function getInternalLinkAttributesObj( &$nt, $text, $broken = false )
263 {
264 global $wgUser, $wgOut;
265
266 if ( $broken == "stub" ) {
267 $r = " class='stub'";
268 } else if ( $broken == "yes" ) {
269 $r = " class='new'";
270 } else {
271 $r = "";
272 }
273
274 if ( 1 == $wgUser->getOption( "hover" ) ) {
275 $r .= ' title ="' . $nt->getEscapedText() . '"';
276 }
277 return $r;
278 }
279
280 function getLogo()
281 {
282 global $wgLogo;
283 return $wgLogo;
284 }
285
286 # This will be called immediately after the <body> tag. Split into
287 # two functions to make it easier to subclass.
288 #
289 function beforeContent()
290 {
291 global $wgUser, $wgOut, $wgSiteNotice;
292
293 if( $wgSiteNotice ) {
294 $note = "\n<div id='notice' style='font-weight: bold; color: red; text-align: center'>$wgSiteNotice</div>\n";
295 } else {
296 $note = "";
297 }
298 return $this->doBeforeContent() . $note;
299 }
300
301 function doBeforeContent()
302 {
303 global $wgUser, $wgOut, $wgTitle, $wgLang;
304 $fname = "Skin::doBeforeContent";
305 wfProfileIn( $fname );
306
307 $s = "";
308 $qb = $this->qbSetting();
309
310 if( $langlinks = $this->otherLanguages() ) {
311 $rows = 2;
312 $borderhack = "";
313 } else {
314 $rows = 1;
315 $langlinks = false;
316 $borderhack = "class='top'";
317 }
318
319 $s .= "\n<div id='content'>\n<div id='topbar'>\n" .
320 "<table border='0' cellspacing='0' width='98%'>\n<tr>\n";
321
322 $shove = ($qb != 0);
323 $left = ($qb == 1 || $qb == 3);
324 if($wgLang->isRTL()) $left = !$left;
325
326 if ( !$shove ) {
327 $s .= "<td class='top' align='left' valign='top' rowspan='{$rows}'>\n" .
328 $this->logoText() . "</td>";
329 } elseif( $left ) {
330 $s .= $this->getQuickbarCompensator( $rows );
331 }
332 $l = $wgLang->isRTL() ? "right" : "left";
333 $s .= "<td {$borderhack} align='$l' valign='top'>\n";
334
335 $s .= $this->topLinks() ;
336 $s .= "<p class='subtitle'>" . $this->pageTitleLinks() . "</p>\n";
337
338 $r = $wgLang->isRTL() ? "left" : "right";
339 $s .= "</td>\n<td {$borderhack} valign='top' align='$r' nowrap='nowrap'>";
340 $s .= $this->nameAndLogin();
341 $s .= "\n<br />" . $this->searchForm() . "</td>";
342
343 if ( $langlinks ) {
344 $s .= "</tr>\n<tr>\n<td class='top' colspan=\"2\">$langlinks</td>\n";
345 }
346
347 if ( $shove && !$left ) { # Right
348 $s .= $this->getQuickbarCompensator( $rows );
349 }
350 $s .= "</tr>\n</table>\n</div>\n";
351 $s .= "\n<div id='article'>\n";
352
353 $s .= $this->pageTitle();
354 $s .= $this->pageSubtitle() ;
355 $s .= $this->getCategories();
356 wfProfileOut( $fname );
357 return $s;
358 }
359
360 function getCategories () {
361 global $wgOut, $wgTitle, $wgUser, $wgParser;
362 global $wgUseCategoryMagic;
363 if( !$wgUseCategoryMagic ) return "" ;
364 if( count( $wgOut->mCategoryLinks ) == 0 ) return "";
365 if( !$wgOut->isArticle() ) return "";
366
367 $t = implode ( " | " , $wgOut->mCategoryLinks ) ;
368 $s = $this->makeKnownLink( "Special:Categories",
369 wfMsg( "categories" ), "article=" . urlencode( $wgTitle->getPrefixedDBkey() ) )
370 . ": " . $t;
371 return "<p class='catlinks'>$s</p>";
372 }
373
374 function getQuickbarCompensator( $rows = 1 )
375 {
376 return "<td width='152' rowspan='{$rows}'>&nbsp;</td>";
377 }
378
379 # This gets called immediately before the </body> tag.
380 #
381 function afterContent()
382 {
383 global $wgUser, $wgOut, $wgServer;
384 global $wgTitle, $wgLang;
385
386 $printfooter = "<div class=\"printfooter\">\n" . $this->printFooter() . "</div>\n";
387 return $printfooter . $this->doAfterContent();
388 }
389
390 function printFooter() {
391 global $wgTitle;
392 $url = htmlspecialchars( $wgTitle->getFullURL() );
393 return "<p>" . wfMsg( "retrievedfrom", "<a href=\"$url\">$url</a>" ) .
394 "</p>\n\n<p>" . $this->pageStats() . "</p>\n";
395 }
396
397 function doAfterContent()
398 {
399 global $wgUser, $wgOut, $wgLang;
400 $fname = "Skin::doAfterContent";
401 wfProfileIn( $fname );
402 wfProfileIn( "$fname-1" );
403
404 $s = "\n</div><br clear='all' />\n";
405 $s .= "\n<div id='footer'>";
406 $s .= "<table border='0' cellspacing='0'><tr>";
407
408 wfProfileOut( "$fname-1" );
409 wfProfileIn( "$fname-2" );
410
411 $qb = $this->qbSetting();
412 $shove = ($qb != 0);
413 $left = ($qb == 1 || $qb == 3);
414 if($wgLang->isRTL()) $left = !$left;
415
416 if ( $shove && $left ) { # Left
417 $s .= $this->getQuickbarCompensator();
418 }
419 wfProfileOut( "$fname-2" );
420 wfProfileIn( "$fname-3" );
421 $l = $wgLang->isRTL() ? "right" : "left";
422 $s .= "<td class='bottom' align='$l' valign='top'>";
423
424 $s .= $this->bottomLinks();
425 $s .= "\n<br />" . $this->mainPageLink()
426 . " | " . $this->aboutLink()
427 . " | " . $this->specialLink( "recentchanges" )
428 . " | " . $this->searchForm()
429 . "<br /><span id='pagestats'>" . $this->pageStats() . "</span>";
430
431 $s .= "</td>";
432 if ( $shove && !$left ) { # Right
433 $s .= $this->getQuickbarCompensator();
434 }
435 $s .= "</tr></table>\n</div>\n</div>\n";
436
437 wfProfileOut( "$fname-3" );
438 wfProfileIn( "$fname-4" );
439 if ( 0 != $qb ) { $s .= $this->quickBar(); }
440 wfProfileOut( "$fname-4" );
441 wfProfileOut( $fname );
442 return $s;
443 }
444
445 function pageTitleLinks()
446 {
447 global $wgOut, $wgTitle, $wgUser, $wgLang, $wgUseApproval, $wgRequest;
448
449 extract( $wgRequest->getValues( 'oldid', 'diff' ) );
450 $action = $wgRequest->getText( 'action' );
451
452 $s = $this->printableLink();
453 if ( wfMsg ( "disclaimers" ) != "-" ) $s .= " | " . $this->makeKnownLink( wfMsg( "disclaimerpage" ), wfMsg( "disclaimers" ) ) ;
454
455 if ( $wgOut->isArticleRelated() ) {
456 if ( $wgTitle->getNamespace() == Namespace::getImage() ) {
457 $name = $wgTitle->getDBkey();
458 $link = wfEscapeHTML( Image::wfImageUrl( $name ) );
459 $style = $this->getInternalLinkAttributes( $link, $name );
460 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>";
461 }
462 # This will show the "Approve" link if $wgUseApproval=true;
463 if ( isset ( $wgUseApproval ) && $wgUseApproval )
464 {
465 $t = $wgTitle->getDBkey();
466 $name = "Approve this article" ;
467 $link = "http://test.wikipedia.org/w/magnus/wiki.phtml?title={$t}&action=submit&doit=1" ;
468 #wfEscapeHTML( wfImageUrl( $name ) );
469 $style = $this->getExternalLinkAttributes( $link, $name );
470 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>" ;
471 }
472 }
473 if ( "history" == $action || isset( $diff ) || isset( $oldid ) ) {
474 $s .= " | " . $this->makeKnownLink( $wgTitle->getPrefixedText(),
475 wfMsg( "currentrev" ) );
476 }
477
478 if ( $wgUser->getNewtalk() ) {
479 # do not show "You have new messages" text when we are viewing our
480 # own talk page
481
482 if(!(strcmp($wgTitle->getText(),$wgUser->getName()) == 0 &&
483 $wgTitle->getNamespace()==Namespace::getTalk(Namespace::getUser()))) {
484 $n =$wgUser->getName();
485 $tl = $this->makeKnownLink( $wgLang->getNsText(
486 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
487 wfMsg("newmessageslink") );
488 $s.=" | <strong>". wfMsg( "newmessages", $tl ) . "</strong>";
489 }
490 }
491 if( $wgUser->isSysop() &&
492 (($wgTitle->getArticleId() == 0) || ($action == "history")) &&
493 ($n = $wgTitle->isDeleted() ) ) {
494 $s .= " | " . wfMsg( "thisisdeleted",
495 $this->makeKnownLink(
496 $wgLang->SpecialPage( "Undelete/" . $wgTitle->getPrefixedDBkey() ),
497 wfMsg( "restorelink", $n ) ) );
498 }
499 return $s;
500 }
501
502 function printableLink()
503 {
504 global $wgOut, $wgFeedClasses, $wgRequest;
505
506 $baseurl = $_SERVER['REQUEST_URI'];
507 if( strpos( "?", $baseurl ) == false ) {
508 $baseurl .= "?";
509 } else {
510 $baseurl .= "&";
511 }
512 $baseurl = htmlspecialchars( $baseurl );
513 $printurl = $wgRequest->escapeAppendQuery( "printable=yes" );
514
515 $s = "<a href=\"$printurl\">" . wfMsg( "printableversion" ) . "</a>";
516 if( $wgOut->isSyndicated() ) {
517 foreach( $wgFeedClasses as $format => $class ) {
518 $feedurl = $wgRequest->escapeAppendQuery( "feed=$format" );
519 $s .= " | <a href=\"$feedurl\">{$format}</a>";
520 }
521 }
522 return $s;
523 }
524
525 function pageTitle()
526 {
527 global $wgOut, $wgTitle, $wgUser;
528
529 $s = "<h1 class='pagetitle'>" . htmlspecialchars( $wgOut->getPageTitle() ) . "</h1>";
530 if($wgUser->getOption("editsectiononrightclick") && $wgTitle->userCanEdit()) { $s=$this->editSectionScript(0,$s);}
531 return $s;
532 }
533
534 function pageSubtitle()
535 {
536 global $wgOut,$wgTitle,$wgNamespacesWithSubpages;
537
538 $sub = $wgOut->getSubtitle();
539 if ( "" == $sub ) {
540 global $wgExtraSubtitle;
541 $sub = wfMsg( "fromwikipedia" ) . $wgExtraSubtitle;
542 }
543 if($wgOut->isArticle() && !empty($wgNamespacesWithSubpages[$wgTitle->getNamespace()])) {
544 $ptext=$wgTitle->getPrefixedText();
545 if(preg_match("/\//",$ptext)) {
546 $sub.="</p><p class='subpages'>";
547 $links=explode("/",$ptext);
548 $c=0;
549 $growinglink="";
550 foreach($links as $link) {
551 $c++;
552 if ($c<count($links)) {
553 $growinglink .= $link;
554 $getlink = $this->makeLink( $growinglink, $link );
555 if(preg_match("/class='new'/i",$getlink)) { break; } # this is a hack, but it saves time
556 if ($c>1) {
557 $sub .= " | ";
558 } else {
559 $sub .="&lt; ";
560 }
561 $sub .= $getlink;
562 $growinglink.="/";
563 }
564
565 }
566 }
567 }
568 $s = "<p class='subtitle'>{$sub}</p>\n";
569 return $s;
570 }
571
572 function nameAndLogin()
573 {
574 global $wgUser, $wgTitle, $wgLang, $wgShowIPinHeader, $wgIP;
575
576 $li = $wgLang->specialPage( "Userlogin" );
577 $lo = $wgLang->specialPage( "Userlogout" );
578
579 $s = "";
580 if ( 0 == $wgUser->getID() ) {
581 if( $wgShowIPinHeader && isset( $_COOKIE[ini_get("session.name")] ) ) {
582 $n = $wgIP;
583
584 $tl = $this->makeKnownLink( $wgLang->getNsText(
585 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
586 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
587
588 $s .= $n . " (".$tl.")";
589 } else {
590 $s .= wfMsg("notloggedin");
591 }
592
593 $rt = $wgTitle->getPrefixedURL();
594 if ( 0 == strcasecmp( urlencode( $lo ), $rt ) ) {
595 $q = "";
596 } else { $q = "returnto={$rt}"; }
597
598 $s .= "\n<br />" . $this->makeKnownLink( $li,
599 wfMsg( "login" ), $q );
600 } else {
601 $n = $wgUser->getName();
602 $rt = $wgTitle->getPrefixedURL();
603 $tl = $this->makeKnownLink( $wgLang->getNsText(
604 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
605 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
606
607 $tl = " ({$tl})";
608
609 $s .= $this->makeKnownLink( $wgLang->getNsText(
610 Namespace::getUser() ) . ":{$n}", $n ) . "{$tl}<br />" .
611 $this->makeKnownLink( $lo, wfMsg( "logout" ),
612 "returnto={$rt}" ) . " | " .
613 $this->specialLink( "preferences" );
614 }
615 $s .= " | " . $this->makeKnownLink( wfMsg( "helppage" ),
616 wfMsg( "help" ) );
617
618 return $s;
619 }
620
621 function getSearchLink() {
622 $searchPage =& Title::makeTitle( NS_SPECIAL, "Search" );
623 return $searchPage->getLocalURL();
624 }
625
626 function escapeSearchLink() {
627 return htmlspecialchars( $this->getSearchLink() );
628 }
629
630 function searchForm()
631 {
632 global $wgRequest;
633 $search = $wgRequest->getText( 'search' );
634
635 $s = "<form name='search' class='inline' method='post' action=\""
636 . $this->escapeSearchLink() . "\">\n"
637 . "<input type='text' name=\"search\" size='19' value=\""
638 . htmlspecialchars(substr($search,0,256)) . "\" />\n"
639 . "<input type='submit' name=\"go\" value=\"" . wfMsg ("go") . "\" />&nbsp;"
640 . "<input type='submit' name=\"fulltext\" value=\"" . wfMsg ("search") . "\" />\n</form>";
641
642 return $s;
643 }
644
645 function topLinks()
646 {
647 global $wgOut;
648 $sep = " |\n";
649
650 $s = $this->mainPageLink() . $sep
651 . $this->specialLink( "recentchanges" );
652
653 if ( $wgOut->isArticleRelated() ) {
654 $s .= $sep . $this->editThisPage()
655 . $sep . $this->historyLink();
656 }
657 # Many people don't like this dropdown box
658 #$s .= $sep . $this->specialPagesList();
659
660 return $s;
661 }
662
663 function bottomLinks()
664 {
665 global $wgOut, $wgUser, $wgTitle;
666 $sep = " |\n";
667
668 $s = "";
669 if ( $wgOut->isArticleRelated() ) {
670 $s .= "<strong>" . $this->editThisPage() . "</strong>";
671 if ( 0 != $wgUser->getID() ) {
672 $s .= $sep . $this->watchThisPage();
673 }
674 $s .= $sep . $this->talkLink()
675 . $sep . $this->historyLink()
676 . $sep . $this->whatLinksHere()
677 . $sep . $this->watchPageLinksLink();
678
679 if ( $wgTitle->getNamespace() == Namespace::getUser()
680 || $wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser()) )
681
682 {
683 $id=User::idFromName($wgTitle->getText());
684 $ip=User::isIP($wgTitle->getText());
685
686 if($id || $ip) { # both anons and non-anons have contri list
687 $s .= $sep . $this->userContribsLink();
688 }
689 if ( 0 != $wgUser->getID() ) { # show only to signed in users
690 if($id) { # can only email non-anons
691 $s .= $sep . $this->emailUserLink();
692 }
693 }
694 }
695 if ( $wgUser->isSysop() && $wgTitle->getArticleId() ) {
696 $s .= "\n<br />" . $this->deleteThisPage() .
697 $sep . $this->protectThisPage() .
698 $sep . $this->moveThisPage();
699 }
700 $s .= "<br />\n" . $this->otherLanguages();
701 }
702 return $s;
703 }
704
705 function pageStats()
706 {
707 global $wgOut, $wgLang, $wgArticle, $wgRequest;
708 global $wgDisableCounters, $wgMaxCredits;
709
710 extract( $wgRequest->getValues( 'oldid', 'diff' ) );
711 if ( ! $wgOut->isArticle() ) { return ""; }
712 if ( isset( $oldid ) || isset( $diff ) ) { return ""; }
713 if ( 0 == $wgArticle->getID() ) { return ""; }
714
715 $s = "";
716 if ( !$wgDisableCounters ) {
717 $count = $wgLang->formatNum( $wgArticle->getCount() );
718 if ( $count ) {
719 $s = wfMsg( "viewcount", $count );
720 }
721 }
722 if (!isset($wgMaxCredits) || $wgMaxCredits <= 0) {
723 $s .= $this->lastModified();
724 } else {
725 $s .= " " . $this->getCredits();
726 }
727
728 return $s . " " . $this->getCopyright();
729 }
730
731 function getCredits() {
732 $s = $this->getAuthorCredits();
733 $s .= "<br />\n " . $this->getContributorCredits();
734 return $s;
735 }
736
737 function getAuthorCredits() {
738 global $wgLang, $wgArticle;
739
740 $last_author = $wgArticle->getUser();
741
742 if ($last_author == 0) {
743 $author_credit = wfMsg("anonymous");
744 } else {
745 $real_name = User::whoIsReal($last_author);
746 if (!empty($real_name)) {
747 $author_credit = $real_name;
748 } else {
749 $author_credit = wfMsg("siteuser", User::whoIs($last_author));
750 }
751 }
752
753 $timestamp = $wgArticle->getTimestamp();
754 if ( $timestamp ) {
755 $d = $wgLang->timeanddate( $wgArticle->getTimestamp(), true );
756 } else {
757 $d = "";
758 }
759 return wfMsg("lastmodifiedby", $d, $author_credit);
760 }
761
762 function getContributorCredits() {
763
764 global $wgArticle, $wgMaxCredits, $wgLang;
765
766 $contributors = $wgArticle->getContributors($wgMaxCredits);
767
768 $real_names = array();
769 $user_names = array();
770
771 # Sift for real versus user names
772
773 foreach ($contributors as $user_id => $user_parts) {
774 if ($user_id != 0) {
775 if (!empty($user_parts[1])) {
776 $real_names[$user_id] = $user_parts[1];
777 } else {
778 $user_names[$user_id] = $user_parts[0];
779 }
780 }
781 }
782
783 $real = $wgLang->listToText(array_values($real_names));
784 $user = $wgLang->listToText(array_values($user_names));
785
786 if (!empty($user)) {
787 $user = wfMsg("siteusers", $user);
788 }
789
790 if ($contributors[0] && $contributors[0][0] > 0) {
791 $anon = wfMsg("anonymous");
792 } else {
793 $anon = '';
794 }
795
796 $creds = $wgLang->listToText(array($real, $user, $anon));
797
798 return wfMsg("contributions", $creds);
799 }
800
801 function getCopyright() {
802 global $wgRightsPage, $wgRightsUrl, $wgRightsText;
803 $out = "";
804 if( $wgRightsPage ) {
805 $link = $this->makeKnownLink( $wgRightsPage, $wgRightsText );
806 } elseif( $wgRightsUrl ) {
807 $link = $this->makeExternalLink( $wgRightsUrl, $wgRightsText );
808 } else {
809 # Give up now
810 return $out;
811 }
812 $out .= wfMsg( "copyright", $link );
813 return $out;
814 }
815
816 function getCopyrightIcon() {
817 global $wgRightsPage, $wgRightsUrl, $wgRightsText, $wgRightsIcon;
818 $out = "";
819 if( $wgRightsIcon ) {
820 $icon = htmlspecialchars( $wgRightsIcon );
821 if( $wgRightsUrl ) {
822 $url = htmlspecialchars( $wgRightsUrl );
823 $out .= "<a href=\"$url\">";
824 }
825 $text = htmlspecialchars( $wgRightsText );
826 $out .= "<img src=\"$icon\" alt='$text' />";
827 if( $wgRightsUrl ) {
828 $out .= "</a>";
829 }
830 }
831 return $out;
832 }
833
834 function getPoweredBy() {
835 global $wgStylePath;
836 $url = htmlspecialchars( "$wgStylePath/images/poweredby_mediawiki_88x31.png" );
837 $img = "<a href='http://www.mediawiki.org/'><img src='$url' alt='MediaWiki' /></a>";
838 return $img;
839 }
840
841 function lastModified()
842 {
843 global $wgLang, $wgArticle;
844
845 $timestamp = $wgArticle->getTimestamp();
846 if ( $timestamp ) {
847 $d = $wgLang->timeanddate( $wgArticle->getTimestamp(), true );
848 $s = " " . wfMsg( "lastmodified", $d );
849 } else {
850 $s = "";
851 }
852 return $s;
853 }
854
855 function logoText( $align = "" )
856 {
857 if ( "" != $align ) { $a = " align='{$align}'"; }
858 else { $a = ""; }
859
860 $mp = wfMsg( "mainpage" );
861 $titleObj = Title::newFromText( $mp );
862 $s = "<a href=\"" . $titleObj->escapeLocalURL()
863 . "\"><img{$a} src=\""
864 . $this->getLogo() . "\" alt=\"" . "[{$mp}]\" /></a>";
865 return $s;
866 }
867
868 function quickBar()
869 {
870 global $wgOut, $wgTitle, $wgUser, $wgRequest, $wgLang;
871 global $wgDisableUploads, $wgRemoteUploads;
872
873 $fname = "Skin::quickBar";
874 wfProfileIn( $fname );
875
876 $action = $wgRequest->getText( 'action' );
877 $wpPreview = $wgRequest->getBool( 'wpPreview' );
878 $tns=$wgTitle->getNamespace();
879
880 $s = "\n<div id='quickbar'>";
881 $s .= "\n" . $this->logoText() . "\n<hr class='sep' />";
882
883 $sep = "\n<br />";
884 $s .= $this->mainPageLink()
885 . $sep . $this->specialLink( "recentchanges" )
886 . $sep . $this->specialLink( "randompage" );
887 if ($wgUser->getID()) {
888 $s.= $sep . $this->specialLink( "watchlist" ) ;
889 $s .= $sep .$this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
890 wfMsg( "mycontris" ), "target=" . wfUrlencode($wgUser->getName() ) );
891
892 }
893 // only show watchlist link if logged in
894 if ( wfMsg ( "currentevents" ) != "-" ) $s .= $sep . $this->makeKnownLink( wfMsg( "currentevents" ), "" ) ;
895 $s .= "\n<br /><hr class='sep' />";
896 $articleExists = $wgTitle->getArticleId();
897 if ( $wgOut->isArticle() || $action =="edit" || $action =="history" || $wpPreview) {
898 if($wgOut->isArticle()) {
899 $s .= "<strong>" . $this->editThisPage() . "</strong>";
900 } else { # backlink to the article in edit or history mode
901 if($articleExists){ # no backlink if no article
902 switch($tns) {
903 case 0:
904 $text = wfMsg("articlepage");
905 break;
906 case 1:
907 $text = wfMsg("viewtalkpage");
908 break;
909 case 2:
910 $text = wfMsg("userpage");
911 break;
912 case 3:
913 $text = wfMsg("viewtalkpage");
914 break;
915 case 4:
916 $text = wfMsg("wikipediapage");
917 break;
918 case 5:
919 $text = wfMsg("viewtalkpage");
920 break;
921 case 6:
922 $text = wfMsg("imagepage");
923 break;
924 case 7:
925 $text = wfMsg("viewtalkpage");
926 break;
927 default:
928 $text= wfMsg("articlepage");
929 }
930
931 $link = $wgTitle->getText();
932 if ($nstext = $wgLang->getNsText($tns) ) { # add namespace if necessary
933 $link = $nstext . ":" . $link ;
934 }
935
936 $s .= $this->makeLink( $link, $text );
937 } elseif( $wgTitle->getNamespace() != Namespace::getSpecial() ) {
938 # we just throw in a "New page" text to tell the user that he's in edit mode,
939 # and to avoid messing with the separator that is prepended to the next item
940 $s .= "<strong>" . wfMsg("newpage") . "</strong>";
941 }
942
943 }
944
945
946 if( $tns%2 && $action!="edit" && !$wpPreview) {
947 $s.="<br />".$this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg("postcomment"),"action=edit&section=new");
948 }
949
950 /*
951 watching could cause problems in edit mode:
952 if user edits article, then loads "watch this article" in background and then saves
953 article with "Watch this article" checkbox disabled, the article is transparently
954 unwatched. Therefore we do not show the "Watch this page" link in edit mode
955 */
956 if ( 0 != $wgUser->getID() && $articleExists) {
957 if($action!="edit" && $action != "submit" )
958 {
959 $s .= $sep . $this->watchThisPage();
960 }
961 if ( $wgTitle->userCanEdit() )
962 $s .= $sep . $this->moveThisPage();
963 }
964 if ( $wgUser->isSysop() and $articleExists ) {
965 $s .= $sep . $this->deleteThisPage() .
966 $sep . $this->protectThisPage();
967 }
968 $s .= $sep . $this->talkLink();
969 if ($articleExists && $action !="history") {
970 $s .= $sep . $this->historyLink();
971 }
972 $s.=$sep . $this->whatLinksHere();
973
974 if($wgOut->isArticleRelated()) {
975 $s .= $sep . $this->watchPageLinksLink();
976 }
977
978 if ( Namespace::getUser() == $wgTitle->getNamespace()
979 || $wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser())
980 ) {
981
982 $id=User::idFromName($wgTitle->getText());
983 $ip=User::isIP($wgTitle->getText());
984
985 if($id||$ip) {
986 $s .= $sep . $this->userContribsLink();
987 }
988 if ( 0 != $wgUser->getID() ) {
989 if($id) { # can only email real users
990 $s .= $sep . $this->emailUserLink();
991 }
992 }
993 }
994 $s .= "\n<br /><hr class='sep' />";
995 }
996
997 if ( 0 != $wgUser->getID() && ( !$wgDisableUploads || $wgRemoteUploads ) ) {
998 $s .= $this->specialLink( "upload" ) . $sep;
999 }
1000 $s .= $this->specialLink( "specialpages" )
1001 . $sep . $this->bugReportsLink();
1002
1003 global $wgSiteSupportPage;
1004 if( $wgSiteSupportPage ) {
1005 $s .= "\n<br /><a href=\"" . htmlspecialchars( $wgSiteSupportPage ) .
1006 "\" class=\"internal\">" . wfMsg( "sitesupport" ) . "</a>";
1007 }
1008
1009 $s .= "\n<br /></div>\n";
1010 wfProfileOut( $fname );
1011 return $s;
1012 }
1013
1014 function specialPagesList()
1015 {
1016 global $wgUser, $wgOut, $wgLang, $wgServer, $wgRedirectScript;
1017 $a = array();
1018
1019 $validSP = $wgLang->getValidSpecialPages();
1020
1021 foreach ( $validSP as $name => $desc ) {
1022 if ( "" == $desc ) { continue; }
1023 $a[$name] = $desc;
1024 }
1025 if ( $wgUser->isSysop() )
1026 {
1027 $sysopSP = $wgLang->getSysopSpecialPages();
1028
1029 foreach ( $sysopSP as $name => $desc ) {
1030 if ( "" == $desc ) { continue; }
1031 $a[$name] = $desc ;
1032 }
1033 }
1034 if ( $wgUser->isDeveloper() )
1035 {
1036 $devSP = $wgLang->getDeveloperSpecialPages();
1037
1038 foreach ( $devSP as $name => $desc ) {
1039 if ( "" == $desc ) { continue; }
1040 $a[$name] = $desc ;
1041 }
1042 }
1043 $go = wfMsg( "go" );
1044 $sp = wfMsg( "specialpages" );
1045 $spp = $wgLang->specialPage( "Specialpages" );
1046
1047 $s = "<form id=\"specialpages\" method=\"get\" class=\"inline\" " .
1048 "action=\"" . htmlspecialchars( "{$wgServer}{$wgRedirectScript}" ) . "\">\n";
1049 $s .= "<select name=\"wpDropdown\">\n";
1050 $s .= "<option value=\"{$spp}\">{$sp}</option>\n";
1051
1052 foreach ( $a as $name => $desc ) {
1053 $p = $wgLang->specialPage( $name );
1054 $s .= "<option value=\"{$p}\">{$desc}</option>\n";
1055 }
1056 $s .= "</select>\n";
1057 $s .= "<input type='submit' value=\"{$go}\" name='redirect' />\n";
1058 $s .= "</form>\n";
1059 return $s;
1060 }
1061
1062 function mainPageLink()
1063 {
1064 $mp = wfMsg( "mainpage" );
1065 $s = $this->makeKnownLink( $mp, $mp );
1066 return $s;
1067 }
1068
1069 function copyrightLink()
1070 {
1071 $s = $this->makeKnownLink( wfMsg( "copyrightpage" ),
1072 wfMsg( "copyrightpagename" ) );
1073 return $s;
1074 }
1075
1076 function aboutLink()
1077 {
1078 $s = $this->makeKnownLink( wfMsg( "aboutpage" ),
1079 wfMsg( "aboutwikipedia" ) );
1080 return $s;
1081 }
1082
1083
1084 function disclaimerLink()
1085 {
1086 $s = $this->makeKnownLink( wfMsg( "disclaimerpage" ),
1087 wfMsg( "disclaimers" ) );
1088 return $s;
1089 }
1090
1091 function editThisPage()
1092 {
1093 global $wgOut, $wgTitle, $wgRequest;
1094
1095 $oldid = $wgRequest->getVal( 'oldid' );
1096 $diff = $wgRequest->getVal( 'diff' );
1097 $redirect = $wgRequest->getVal( 'redirect' );
1098
1099 if ( ! $wgOut->isArticleRelated() ) {
1100 $s = wfMsg( "protectedpage" );
1101 } else {
1102 $n = $wgTitle->getPrefixedText();
1103 if ( $wgTitle->userCanEdit() ) {
1104 $t = wfMsg( "editthispage" );
1105 } else {
1106 #$t = wfMsg( "protectedpage" );
1107 $t = wfMsg( "viewsource" );
1108 }
1109 $oid = $red = "";
1110
1111 if ( !is_null( $redirect ) ) { $red = "&redirect={$redirect}"; }
1112 if ( $oldid && ! isset( $diff ) ) {
1113 $oid = "&oldid={$oldid}";
1114 }
1115 $s = $this->makeKnownLink( $n, $t, "action=edit{$oid}{$red}" );
1116 }
1117 return $s;
1118 }
1119
1120 function deleteThisPage()
1121 {
1122 global $wgUser, $wgOut, $wgTitle, $wgRequest;
1123
1124 $diff = $wgRequest->getVal( 'diff' );
1125 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
1126 $n = $wgTitle->getPrefixedText();
1127 $t = wfMsg( "deletethispage" );
1128
1129 $s = $this->makeKnownLink( $n, $t, "action=delete" );
1130 } else {
1131 $s = "";
1132 }
1133 return $s;
1134 }
1135
1136 function protectThisPage()
1137 {
1138 global $wgUser, $wgOut, $wgTitle, $wgRequest;
1139
1140 $diff = $wgRequest->getVal( 'diff' );
1141 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
1142 $n = $wgTitle->getPrefixedText();
1143
1144 if ( $wgTitle->isProtected() ) {
1145 $t = wfMsg( "unprotectthispage" );
1146 $q = "action=unprotect";
1147 } else {
1148 $t = wfMsg( "protectthispage" );
1149 $q = "action=protect";
1150 }
1151 $s = $this->makeKnownLink( $n, $t, $q );
1152 } else {
1153 $s = "";
1154 }
1155 return $s;
1156 }
1157
1158 function watchThisPage()
1159 {
1160 global $wgUser, $wgOut, $wgTitle;
1161
1162 if ( $wgOut->isArticleRelated() ) {
1163 $n = $wgTitle->getPrefixedText();
1164
1165 if ( $wgTitle->userIsWatching() ) {
1166 $t = wfMsg( "unwatchthispage" );
1167 $q = "action=unwatch";
1168 } else {
1169 $t = wfMsg( "watchthispage" );
1170 $q = "action=watch";
1171 }
1172 $s = $this->makeKnownLink( $n, $t, $q );
1173 } else {
1174 $s = wfMsg( "notanarticle" );
1175 }
1176 return $s;
1177 }
1178
1179 function moveThisPage()
1180 {
1181 global $wgTitle, $wgLang;
1182
1183 if ( $wgTitle->userCanEdit() ) {
1184 $s = $this->makeKnownLink( $wgLang->specialPage( "Movepage" ),
1185 wfMsg( "movethispage" ), "target=" . $wgTitle->getPrefixedURL() );
1186 } // no message if page is protected - would be redundant
1187 return $s;
1188 }
1189
1190 function historyLink()
1191 {
1192 global $wgTitle;
1193
1194 $s = $this->makeKnownLink( $wgTitle->getPrefixedText(),
1195 wfMsg( "history" ), "action=history" );
1196 return $s;
1197 }
1198
1199 function whatLinksHere()
1200 {
1201 global $wgTitle, $wgLang;
1202
1203 $s = $this->makeKnownLink( $wgLang->specialPage( "Whatlinkshere" ),
1204 wfMsg( "whatlinkshere" ), "target=" . $wgTitle->getPrefixedURL() );
1205 return $s;
1206 }
1207
1208 function userContribsLink()
1209 {
1210 global $wgTitle, $wgLang;
1211
1212 $s = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
1213 wfMsg( "contributions" ), "target=" . $wgTitle->getPartialURL() );
1214 return $s;
1215 }
1216
1217 function emailUserLink()
1218 {
1219 global $wgTitle, $wgLang;
1220
1221 $s = $this->makeKnownLink( $wgLang->specialPage( "Emailuser" ),
1222 wfMsg( "emailuser" ), "target=" . $wgTitle->getPartialURL() );
1223 return $s;
1224 }
1225
1226 function watchPageLinksLink()
1227 {
1228 global $wgOut, $wgTitle, $wgLang;
1229
1230 if ( ! $wgOut->isArticleRelated() ) {
1231 $s = "(" . wfMsg( "notanarticle" ) . ")";
1232 } else {
1233 $s = $this->makeKnownLink( $wgLang->specialPage(
1234 "Recentchangeslinked" ), wfMsg( "recentchangeslinked" ),
1235 "target=" . $wgTitle->getPrefixedURL() );
1236 }
1237 return $s;
1238 }
1239
1240 function otherLanguages()
1241 {
1242 global $wgOut, $wgLang, $wgTitle, $wgUseNewInterlanguage;
1243
1244 $a = $wgOut->getLanguageLinks();
1245 if ( 0 == count( $a ) ) {
1246 if ( !$wgUseNewInterlanguage ) return "";
1247 $ns = $wgLang->getNsIndex ( $wgTitle->getNamespace () ) ;
1248 if ( $ns != 0 AND $ns != 1 ) return "" ;
1249 $pn = "Intl" ;
1250 $x = "mode=addlink&xt=".$wgTitle->getDBkey() ;
1251 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1252 wfMsg( "intl" ) , $x );
1253 }
1254
1255 if ( !$wgUseNewInterlanguage ) {
1256 $s = wfMsg( "otherlanguages" ) . ": ";
1257 } else {
1258 global $wgLanguageCode ;
1259 $x = "mode=zoom&xt=".$wgTitle->getDBkey() ;
1260 $x .= "&xl=".$wgLanguageCode ;
1261 $s = $this->makeKnownLink( $wgLang->specialPage( "Intl" ),
1262 wfMsg( "otherlanguages" ) , $x ) . ": " ;
1263 }
1264
1265 $s = wfMsg( "otherlanguages" ) . ": ";
1266 $first = true;
1267 if($wgLang->isRTL()) $s .= "<span dir='LTR'>";
1268 foreach( $a as $l ) {
1269 if ( ! $first ) { $s .= " | "; }
1270 $first = false;
1271
1272 $nt = Title::newFromText( $l );
1273 $url = $nt->getFullURL();
1274 $text = $wgLang->getLanguageName( $nt->getInterwiki() );
1275
1276 if ( "" == $text ) { $text = $l; }
1277 $style = $this->getExternalLinkAttributes( $l, $text );
1278 $s .= "<a href=\"{$url}\"{$style}>{$text}</a>";
1279 }
1280 if($wgLang->isRTL()) $s .= "</span>";
1281 return $s;
1282 }
1283
1284 function bugReportsLink()
1285 {
1286 $s = $this->makeKnownLink( wfMsg( "bugreportspage" ),
1287 wfMsg( "bugreports" ) );
1288 return $s;
1289 }
1290
1291 function dateLink()
1292 {
1293 global $wgLinkCache;
1294 $t1 = Title::newFromText( gmdate( "F j" ) );
1295 $t2 = Title::newFromText( gmdate( "Y" ) );
1296
1297 $wgLinkCache->suspend();
1298 $id = $t1->getArticleID();
1299 $wgLinkCache->resume();
1300
1301 if ( 0 == $id ) {
1302 $s = $this->makeBrokenLink( $t1->getText() );
1303 } else {
1304 $s = $this->makeKnownLink( $t1->getText() );
1305 }
1306 $s .= ", ";
1307
1308 $wgLinkCache->suspend();
1309 $id = $t2->getArticleID();
1310 $wgLinkCache->resume();
1311
1312 if ( 0 == $id ) {
1313 $s .= $this->makeBrokenLink( $t2->getText() );
1314 } else {
1315 $s .= $this->makeKnownLink( $t2->getText() );
1316 }
1317 return $s;
1318 }
1319
1320 function talkLink()
1321 {
1322 global $wgLang, $wgTitle, $wgLinkCache;
1323
1324 $tns = $wgTitle->getNamespace();
1325 if ( -1 == $tns ) { return ""; }
1326
1327 $pn = $wgTitle->getText();
1328 $tp = wfMsg( "talkpage" );
1329 if ( Namespace::isTalk( $tns ) ) {
1330 $lns = Namespace::getSubject( $tns );
1331 switch($tns) {
1332 case 1:
1333 $text = wfMsg("articlepage");
1334 break;
1335 case 3:
1336 $text = wfMsg("userpage");
1337 break;
1338 case 5:
1339 $text = wfMsg("wikipediapage");
1340 break;
1341 case 7:
1342 $text = wfMsg("imagepage");
1343 break;
1344 default:
1345 $text= wfMsg("articlepage");
1346 }
1347 } else {
1348
1349 $lns = Namespace::getTalk( $tns );
1350 $text=$tp;
1351 }
1352 $n = $wgLang->getNsText( $lns );
1353 if ( "" == $n ) { $link = $pn; }
1354 else { $link = "{$n}:{$pn}"; }
1355
1356 $wgLinkCache->suspend();
1357 $s = $this->makeLink( $link, $text );
1358 $wgLinkCache->resume();
1359
1360 return $s;
1361 }
1362
1363 function commentLink()
1364 {
1365 global $wgLang, $wgTitle, $wgLinkCache;
1366
1367 $tns = $wgTitle->getNamespace();
1368 if ( -1 == $tns ) { return ""; }
1369
1370 $lns = ( Namespace::isTalk( $tns ) ) ? $tns : Namespace::getTalk( $tns );
1371
1372 # assert Namespace::isTalk( $lns )
1373
1374 $n = $wgLang->getNsText( $lns );
1375 $pn = $wgTitle->getText();
1376
1377 $link = "{$n}:{$pn}";
1378
1379 $wgLinkCache->suspend();
1380 $s = $this->makeKnownLink($link, wfMsg("postcomment"), "action=edit&section=new");
1381 $wgLinkCache->resume();
1382
1383 return $s;
1384 }
1385
1386 # After all the page content is transformed into HTML, it makes
1387 # a final pass through here for things like table backgrounds.
1388 #
1389 function transformContent( $text )
1390 {
1391 return $text;
1392 }
1393
1394 # Note: This function MUST call getArticleID() on the link,
1395 # otherwise the cache won't get updated properly. See LINKCACHE.DOC.
1396 #
1397 function makeLink( $title, $text = "", $query = "", $trail = "" ) {
1398 wfProfileIn( "Skin::makeLink" );
1399 $nt = Title::newFromText( $title );
1400 if ($nt) {
1401 $result = $this->makeLinkObj( Title::newFromText( $title ), $text, $query, $trail );
1402 } else {
1403 wfDebug( "Invalid title passed to Skin::makeLink(): \"$title\"\n" );
1404 $result = $text == "" ? $title : $text;
1405 }
1406
1407 wfProfileOut( "Skin::makeLink" );
1408 return $result;
1409 }
1410
1411 function makeKnownLink( $title, $text = "", $query = "", $trail = "", $prefix = '',$aprops = '') {
1412 $nt = Title::newFromText( $title );
1413 if ($nt) {
1414 return $this->makeKnownLinkObj( Title::newFromText( $title ), $text, $query, $trail, $prefix , $aprops );
1415 } else {
1416 wfDebug( "Invalid title passed to Skin::makeKnownLink(): \"$title\"\n" );
1417 return $text == "" ? $title : $text;
1418 }
1419 }
1420
1421 function makeBrokenLink( $title, $text = "", $query = "", $trail = "" ) {
1422 $nt = Title::newFromText( $title );
1423 if ($nt) {
1424 return $this->makeBrokenLinkObj( Title::newFromText( $title ), $text, $query, $trail );
1425 } else {
1426 wfDebug( "Invalid title passed to Skin::makeBrokenLink(): \"$title\"\n" );
1427 return $text == "" ? $title : $text;
1428 }
1429 }
1430
1431 function makeStubLink( $title, $text = "", $query = "", $trail = "" ) {
1432 $nt = Title::newFromText( $title );
1433 if ($nt) {
1434 return $this->makeStubLinkObj( Title::newFromText( $title ), $text, $query, $trail );
1435 } else {
1436 wfDebug( "Invalid title passed to Skin::makeStubLink(): \"$title\"\n" );
1437 return $text == "" ? $title : $text;
1438 }
1439 }
1440
1441 # Pass a title object, not a title string
1442 function makeLinkObj( &$nt, $text= "", $query = "", $trail = "", $prefix = "" )
1443 {
1444 global $wgOut, $wgUser;
1445 if ( $nt->isExternal() ) {
1446 $u = $nt->getFullURL();
1447 $link = $nt->getPrefixedURL();
1448 if ( "" == $text ) { $text = $nt->getPrefixedText(); }
1449 $style = $this->getExternalLinkAttributes( $link, $text );
1450
1451 $inside = "";
1452 if ( "" != $trail ) {
1453 if ( preg_match( "/^([a-z]+)(.*)$$/sD", $trail, $m ) ) {
1454 $inside = $m[1];
1455 $trail = $m[2];
1456 }
1457 }
1458 $retVal = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1459 } elseif ( 0 == $nt->getNamespace() && "" == $nt->getText() ) {
1460 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1461 } elseif ( ( -1 == $nt->getNamespace() ) ||
1462 ( Namespace::getImage() == $nt->getNamespace() ) ) {
1463 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1464 } else {
1465 $aid = $nt->getArticleID() ;
1466 if ( 0 == $aid ) {
1467 $retVal = $this->makeBrokenLinkObj( $nt, $text, $query, $trail, $prefix );
1468 } else {
1469 $threshold = $wgUser->getOption("stubthreshold") ;
1470 if ( $threshold > 0 ) {
1471 $res = wfQuery ( "SELECT LENGTH(cur_text) AS x, cur_namespace, cur_is_redirect FROM cur WHERE cur_id='{$aid}'", DB_READ ) ;
1472
1473 if ( wfNumRows( $res ) > 0 ) {
1474 $s = wfFetchObject( $res );
1475 $size = $s->x;
1476 if ( $s->cur_is_redirect OR $s->cur_namespace != 0 ) {
1477 $size = $threshold*2 ; # Really big
1478 }
1479 wfFreeResult( $res );
1480 } else {
1481 $size = $threshold*2 ; # Really big
1482 }
1483 } else {
1484 $size = 1 ;
1485 }
1486 if ( $size < $threshold ) {
1487 $retVal = $this->makeStubLinkObj( $nt, $text, $query, $trail, $prefix );
1488 } else {
1489 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1490 }
1491 }
1492 }
1493 return $retVal;
1494 }
1495
1496 # Pass a title object, not a title string
1497 function makeKnownLinkObj( &$nt, $text = "", $query = "", $trail = "", $prefix = "" , $aprops = '')
1498 {
1499 global $wgOut, $wgTitle;
1500
1501 $fname = "Skin::makeKnownLinkObj";
1502 wfProfileIn( $fname );
1503
1504 $link = $nt->getPrefixedURL();
1505
1506 if ( "" == $link ) {
1507 $u = "";
1508 if ( "" == $text ) {
1509 $text = htmlspecialchars( $nt->getFragment() );
1510 }
1511 } else {
1512 $u = $nt->escapeLocalURL( $query );
1513 }
1514 if ( "" != $nt->getFragment() ) {
1515 $u .= "#" . htmlspecialchars( $nt->getFragment() );
1516 }
1517 if ( "" == $text ) {
1518 $text = htmlspecialchars( $nt->getPrefixedText() );
1519 }
1520 $style = $this->getInternalLinkAttributesObj( $nt, $text );
1521
1522 $inside = "";
1523 if ( "" != $trail ) {
1524 if ( preg_match( $this->linktrail, $trail, $m ) ) {
1525 $inside = $m[1];
1526 $trail = $m[2];
1527 }
1528 }
1529 $r = "<a href=\"{$u}\"{$style}{$aprops}>{$prefix}{$text}{$inside}</a>{$trail}";
1530 wfProfileOut( $fname );
1531 return $r;
1532 }
1533
1534 # Pass a title object, not a title string
1535 function makeBrokenLinkObj( &$nt, $text = "", $query = "", $trail = "", $prefix = "" )
1536 {
1537 global $wgOut, $wgUser;
1538
1539 $fname = "Skin::makeBrokenLinkObj";
1540 wfProfileIn( $fname );
1541
1542 if ( "" == $query ) {
1543 $q = "action=edit";
1544 } else {
1545 $q = "action=edit&{$query}";
1546 }
1547 $u = $nt->escapeLocalURL( $q );
1548
1549 if ( "" == $text ) {
1550 $text = htmlspecialchars( $nt->getPrefixedText() );
1551 }
1552 $style = $this->getInternalLinkAttributesObj( $nt, $text, "yes" );
1553
1554 $inside = "";
1555 if ( "" != $trail ) {
1556 if ( preg_match( $this->linktrail, $trail, $m ) ) {
1557 $inside = $m[1];
1558 $trail = $m[2];
1559 }
1560 }
1561 if ( $wgUser->getOption( "highlightbroken" ) ) {
1562 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1563 } else {
1564 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>?</a>{$trail}";
1565 }
1566
1567 wfProfileOut( $fname );
1568 return $s;
1569 }
1570
1571 # Pass a title object, not a title string
1572 function makeStubLinkObj( &$nt, $text = "", $query = "", $trail = "", $prefix = "" )
1573 {
1574 global $wgOut, $wgUser;
1575
1576 $link = $nt->getPrefixedURL();
1577
1578 $u = $nt->escapeLocalURL( $query );
1579
1580 if ( "" == $text ) {
1581 $text = htmlspecialchars( $nt->getPrefixedText() );
1582 }
1583 $style = $this->getInternalLinkAttributesObj( $nt, $text, "stub" );
1584
1585 $inside = "";
1586 if ( "" != $trail ) {
1587 if ( preg_match( $this->linktrail, $trail, $m ) ) {
1588 $inside = $m[1];
1589 $trail = $m[2];
1590 }
1591 }
1592 if ( $wgUser->getOption( "highlightbroken" ) ) {
1593 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1594 } else {
1595 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>!</a>{$trail}";
1596 }
1597 return $s;
1598 }
1599
1600 function makeSelfLinkObj( &$nt, $text = "", $query = "", $trail = "", $prefix = "" )
1601 {
1602 $u = $nt->escapeLocalURL( $query );
1603 if ( "" == $text ) {
1604 $text = htmlspecialchars( $nt->getPrefixedText() );
1605 }
1606 $inside = "";
1607 if ( "" != $trail ) {
1608 if ( preg_match( $this->linktrail, $trail, $m ) ) {
1609 $inside = $m[1];
1610 $trail = $m[2];
1611 }
1612 }
1613 return "<strong>{$prefix}{$text}{$inside}</strong>{$trail}";
1614 }
1615
1616 function fnamePart( $url )
1617 {
1618 $basename = strrchr( $url, "/" );
1619 if ( false === $basename ) { $basename = $url; }
1620 else { $basename = substr( $basename, 1 ); }
1621 return wfEscapeHTML( $basename );
1622 }
1623
1624 function makeImage( $url, $alt = "" )
1625 {
1626 global $wgOut;
1627
1628 if ( "" == $alt ) { $alt = $this->fnamePart( $url ); }
1629 $s = "<img src=\"{$url}\" alt=\"{$alt}\" />";
1630 return $s;
1631 }
1632
1633 function makeImageLink( $name, $url, $alt = "" ) {
1634 $nt = Title::makeTitle( Namespace::getImage(), $name );
1635 return $this->makeImageLinkObj( $nt, $alt );
1636 }
1637
1638 function makeImageLinkObj( $nt, $alt = "" ) {
1639 global $wgLang, $wgUseImageResize;
1640 $img = Image::newFromTitle( $nt );
1641 $url = $img->getURL();
1642
1643 $align = "";
1644 $prefix = $postfix = "";
1645
1646 if ( $wgUseImageResize ) {
1647 # Check if the alt text is of the form "options|alt text"
1648 # Options are:
1649 # * thumbnail make a thumbnail with enlarge-icon and caption, alignment depends on lang
1650 # * left no resizing, just left align. label is used for alt= only
1651 # * right same, but right aligned
1652 # * none same, but not aligned
1653 # * ___px scale to ___ pixels width, no aligning. e.g. use in taxobox
1654 # * center center the image
1655 # * framed Keep original image size, no magnify-button.
1656
1657 $part = explode( "|", $alt);
1658
1659 $mwThumb =& MagicWord::get( MAG_IMG_THUMBNAIL );
1660 $mwLeft =& MagicWord::get( MAG_IMG_LEFT );
1661 $mwRight =& MagicWord::get( MAG_IMG_RIGHT );
1662 $mwNone =& MagicWord::get( MAG_IMG_NONE );
1663 $mwWidth =& MagicWord::get( MAG_IMG_WIDTH );
1664 $mwCenter =& MagicWord::get( MAG_IMG_CENTER );
1665 $mwFramed =& MagicWord::get( MAG_IMG_FRAMED );
1666 $alt = $part[count($part)-1];
1667
1668 $framed=$thumb=false;
1669
1670 foreach( $part as $key => $val ) {
1671 if ( ! is_null( $mwThumb->matchVariableStartToEnd($val) ) ) {
1672 $thumb=true;
1673 } elseif ( ! is_null( $mwRight->matchVariableStartToEnd($val) ) ) {
1674 # remember to set an alignment, don't render immediately
1675 $align = "right";
1676 } elseif ( ! is_null( $mwLeft->matchVariableStartToEnd($val) ) ) {
1677 # remember to set an alignment, don't render immediately
1678 $align = "left";
1679 } elseif ( ! is_null( $mwCenter->matchVariableStartToEnd($val) ) ) {
1680 # remember to set an alignment, don't render immediately
1681 $align = "center";
1682 } elseif ( ! is_null( $mwNone->matchVariableStartToEnd($val) ) ) {
1683 # remember to set an alignment, don't render immediately
1684 $align = "none";
1685 } elseif ( ! is_null( $match = $mwWidth->matchVariableStartToEnd($val) ) ) {
1686 # $match is the image width in pixels
1687 $width = intval($match);
1688 } elseif ( ! is_null( $mwFramed->matchVariableStartToEnd($val) ) ) {
1689 $framed=true;
1690 }
1691 }
1692 if ( "center" == $align )
1693 {
1694 $prefix = '<span style="text-align: center">';
1695 $postfix = '</span>';
1696 $align = "none";
1697 }
1698
1699 if ( $thumb || $framed ) {
1700
1701 # Create a thumbnail. Alignment depends on language
1702 # writing direction, # right aligned for left-to-right-
1703 # languages ("Western languages"), left-aligned
1704 # for right-to-left-languages ("Semitic languages")
1705 #
1706 # If thumbnail width has not been provided, it is set
1707 # here to 180 pixels
1708 if ( $align == "" ) {
1709 $align = $wgLang->isRTL() ? "left" : "right";
1710 }
1711 if ( ! isset($width) ) {
1712 $width = 180;
1713 }
1714 return $prefix.$this->makeThumbLinkObj( $img, $alt, $align, $width, $framed ).$postfix;
1715
1716 } elseif ( isset($width) ) {
1717
1718 # Create a resized image, without the additional thumbnail
1719 # features
1720 $url = $img->createThumb( $width );
1721 }
1722 } # endif $wgUseImageResize
1723
1724 if ( empty( $alt ) ) {
1725 $alt = preg_replace( '/\.(.+?)^/', '', $img->getName() );
1726 }
1727 $alt = htmlspecialchars( $alt );
1728
1729 $u = $nt->escapeLocalURL();
1730 if ( $url == "" )
1731 {
1732 $s = str_replace( "$1", $img->getName(), wfMsg("missingimage") );
1733 $s .= "<br>{$alt}<br>{$url}<br>\n";
1734 } else {
1735 $s = "<a href=\"{$u}\" class='image' title=\"{$alt}\">" .
1736 "<img src=\"{$url}\" alt=\"{$alt}\" /></a>";
1737 }
1738 if ( "" != $align ) {
1739 $s = "<div class=\"float{$align}\"><span>{$s}</span>\n</div>";
1740 }
1741 return $prefix.$s.$postfix;
1742 }
1743
1744
1745 function makeThumbLinkObj( $img, $label = "", $align = "right", $boxwidth = 180, $framed=false ) {
1746 global $wgStylePath, $wgLang;
1747 # $image = Title::makeTitle( Namespace::getImage(), $name );
1748 $url = $img->getURL();
1749
1750 #$label = htmlspecialchars( $label );
1751 $alt = preg_replace( "/<[^>]*>/", "", $label);
1752 $alt = htmlspecialchars( $alt );
1753
1754 if ( $img->exists() )
1755 {
1756 $width = $img->getWidth();
1757 $height = $img->getHeight();
1758 } else {
1759 $width = $height = 200;
1760 }
1761 if ( $framed )
1762 {
1763 // Use image dimensions, don't scale
1764 $boxwidth = $width;
1765 $boxheight = $height;
1766 $thumbUrl = $url;
1767 } else {
1768 $boxheight = intval( $height/($width/$boxwidth) );
1769 if ( $boxwidth > $width ) {
1770 $boxwidth = $width;
1771 $boxheight = $height;
1772 }
1773 $thumbUrl = $img->createThumb( $boxwidth );
1774 }
1775 $oboxwidth = $boxwidth + 2;
1776
1777 $u = $img->getEscapeLocalURL();
1778
1779 $more = htmlspecialchars( wfMsg( "thumbnail-more" ) );
1780 $magnifyalign = $wgLang->isRTL() ? "left" : "right";
1781 $textalign = $wgLang->isRTL() ? ' style="text-align:right"' : "";
1782
1783 $s = "<div class=\"thumb t{$align}\"><div style=\"width:{$oboxwidth}px;\">";
1784 if ( $thumbUrl == "" ) {
1785 $s .= str_replace( "$1", $img->getName(), wfMsg("missingimage") );
1786 $zoomicon = '';
1787 } else {
1788 $s .= '<a href="'.$u.'" class="internal" title="'.$alt.'">'.
1789 '<img src="'.$thumbUrl.'" alt="'.$alt.'" ' .
1790 'width="'.$boxwidth.'" height="'.$boxheight.'" /></a>';
1791 if ( $framed ) {
1792 $zoomicon="";
1793 } else {
1794 $zoomicon = '<div class="magnify" style="float:'.$magnifyalign.'">'.
1795 '<a href="'.$u.'" class="internal" title="'.$more.'">'.
1796 '<img src="'.$wgStylePath.'/images/magnify-clip.png" ' .
1797 'width="15" height="11" alt="'.$more.'" /></a></div>';
1798 }
1799 }
1800 $s .= ' <div class="thumbcaption" '.$textalign.'>'.$zoomicon.$label."</div></div>\n</div>";
1801 return $s;
1802 }
1803
1804 function makeMediaLink( $name, $url, $alt = "" ) {
1805 $nt = Title::makeTitle( Namespace::getMedia(), $name );
1806 return $this->makeMediaLinkObj( $nt, $alt );
1807 }
1808
1809 function makeMediaLinkObj( $nt, $alt = "" )
1810 {
1811 $name = $nt->getDBKey();
1812 $url = Image::wfImageUrl( $name );
1813 if ( empty( $alt ) ) {
1814 $alt = preg_replace( '/\.(.+?)^/', '', $name );
1815 }
1816
1817 $u = htmlspecialchars( $url );
1818 $s = "<a href=\"{$u}\" class='internal' title=\"{$alt}\">{$alt}</a>";
1819 return $s;
1820 }
1821
1822 function specialLink( $name, $key = "" )
1823 {
1824 global $wgLang;
1825
1826 if ( "" == $key ) { $key = strtolower( $name ); }
1827 $pn = $wgLang->ucfirst( $name );
1828 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1829 wfMsg( $key ) );
1830 }
1831
1832 function makeExternalLink( $url, $text, $escape = true ) {
1833 $style = $this->getExternalLinkAttributes( $url, $text );
1834 $url = htmlspecialchars( $url );
1835 if( $escape ) {
1836 $text = htmlspecialchars( $text );
1837 }
1838 return "<a href=\"$url\"$style>$text</a>";
1839 }
1840
1841 # Called by history lists and recent changes
1842 #
1843
1844 # Returns text for the start of the tabular part of RC
1845 function beginRecentChangesList()
1846 {
1847 $this->rc_cache = array() ;
1848 $this->rcMoveIndex = 0;
1849 $this->rcCacheIndex = 0 ;
1850 $this->lastdate = "";
1851 $this->rclistOpen = false;
1852 return "";
1853 }
1854
1855 function beginImageHistoryList()
1856 {
1857 $s = "\n<h2>" . wfMsg( "imghistory" ) . "</h2>\n" .
1858 "<p>" . wfMsg( "imghistlegend" ) . "</p>\n<ul class='special'>";
1859 return $s;
1860 }
1861
1862 # Returns text for the end of RC
1863 # If enhanced RC is in use, returns pretty much all the text
1864 function endRecentChangesList()
1865 {
1866 $s = $this->recentChangesBlock() ;
1867 if( $this->rclistOpen ) {
1868 $s .= "</ul>\n";
1869 }
1870 return $s;
1871 }
1872
1873 # Enhanced RC ungrouped line
1874 function recentChangesBlockLine ( $rcObj )
1875 {
1876 global $wgStylePath, $wgLang ;
1877
1878 # Get rc_xxxx variables
1879 extract( $rcObj->mAttribs ) ;
1880 $curIdEq = "curid=$rc_cur_id";
1881
1882 # Spacer image
1883 $r = "" ;
1884
1885 $r .= "<img src='{$wgStylePath}/images/Arr_.png' width='12' height='12' border='0' />" ; $r .= "<tt>" ;
1886
1887 if ( $rc_type == RC_MOVE ) {
1888 $r .= "&nbsp;&nbsp;";
1889 } else {
1890 # M & N (minor & new)
1891 $M = wfMsg( "minoreditletter" );
1892 $N = wfMsg( "newpageletter" );
1893
1894 if ( $rc_type == RC_NEW ) {
1895 $r .= $N ;
1896 } else {
1897 $r .= "&nbsp;" ;
1898 }
1899 if ( $rc_minor ) {
1900 $r .= $M ;
1901 } else {
1902 $r .= "&nbsp;" ;
1903 }
1904 }
1905
1906 # Timestamp
1907 $r .= " ".$rcObj->timestamp." " ;
1908 $r .= "</tt>" ;
1909
1910 # Article link
1911 $link = $rcObj->link ;
1912 if ( $rcObj->watched ) $link = "<strong>{$link}</strong>" ;
1913 $r .= $link ;
1914
1915 # Cur
1916 $r .= " (" ;
1917 $r .= $rcObj->curlink ;
1918 $r .= "; " ;
1919
1920 # Hist
1921 $r .= $this->makeKnownLinkObj( $rcObj->getTitle(), wfMsg( "hist" ), "{$curIdEq}&action=history" );
1922
1923 # User/talk
1924 $r .= ") . . ".$rcObj->userlink ;
1925 $r .= $rcObj->usertalklink ;
1926
1927 # Comment
1928 if ( $rc_comment != "" && $rc_type != RC_MOVE ) {
1929 $rc_comment=$this->formatComment($rc_comment);
1930 $r .= $wgLang->emphasize( " (".$rc_comment.")" );
1931 }
1932
1933 $r .= "<br />\n" ;
1934 return $r ;
1935 }
1936
1937 # Enhanced RC group
1938 function recentChangesBlockGroup ( $block )
1939 {
1940 global $wgStylePath, $wgLang ;
1941
1942 $r = "" ;
1943 $M = wfMsg( "minoreditletter" );
1944 $N = wfMsg( "newpageletter" );
1945
1946 # Collate list of users
1947 $isnew = false ;
1948 $userlinks = array () ;
1949 foreach ( $block AS $rcObj ) {
1950 $oldid = $rcObj->mAttribs['rc_last_oldid'];
1951 if ( $rcObj->mAttribs['rc_new'] ) $isnew = true ;
1952 $u = $rcObj->userlink ;
1953 if ( !isset ( $userlinks[$u] ) ) $userlinks[$u] = 0 ;
1954 $userlinks[$u]++ ;
1955 }
1956
1957 # Sort the list and convert to text
1958 krsort ( $userlinks ) ;
1959 asort ( $userlinks ) ;
1960 $users = array () ;
1961 foreach ( $userlinks as $userlink => $count) {
1962 $text = $userlink ;
1963 if ( $count > 1 ) $text .= " ({$count}&times;)" ;
1964 array_push ( $users , $text ) ;
1965 }
1966 $users = " <font size='-1'>[".implode("; ",$users)."]</font>" ;
1967
1968 # Arrow
1969 $rci = "RCI{$this->rcCacheIndex}" ;
1970 $rcl = "RCL{$this->rcCacheIndex}" ;
1971 $rcm = "RCM{$this->rcCacheIndex}" ;
1972 $toggleLink = "javascript:toggleVisibility(\"{$rci}\",\"{$rcm}\",\"{$rcl}\")" ;
1973 $arrowdir = $wgLang->isRTL() ? "l" : "r";
1974 $tl = "<span id='{$rcm}'><a href='$toggleLink'><img src='{$wgStylePath}/images/Arr_{$arrowdir}.png' width='12' height='12' /></a></span>" ;
1975 $tl .= "<span id='{$rcl}' style='display:none'><a href='$toggleLink'><img src='{$wgStylePath}/images/Arr_d.png' width='12' height='12' /></a></span>" ;
1976 $r .= $tl ;
1977
1978 # Main line
1979 # M/N
1980 $r .= "<tt>" ;
1981 if ( $isnew ) $r .= $N ;
1982 else $r .= "&nbsp;" ;
1983 $r .= "&nbsp;" ; # Minor
1984
1985 # Timestamp
1986 $r .= " ".$block[0]->timestamp." " ;
1987 $r .= "</tt>" ;
1988
1989 # Article link
1990 $link = $block[0]->link ;
1991 if ( $block[0]->watched ) $link = "<strong>{$link}</strong>" ;
1992 $r .= $link ;
1993
1994 $curIdEq = "curid=" . $block[0]->mAttribs['rc_cur_id'];
1995 if ( $block[0]->mAttribs['rc_type'] != RC_LOG ) {
1996 # Changes
1997 $r .= " (".count($block)." " ;
1998 if ( $isnew ) $r .= wfMsg("changes");
1999 else $r .= $this->makeKnownLinkObj( $block[0]->getTitle() , wfMsg("changes") ,
2000 "{$curIdEq}&diff=0&oldid=".$oldid ) ;
2001 $r .= "; " ;
2002
2003 # History
2004 $r .= $this->makeKnownLinkObj( $block[0]->getTitle(), wfMsg( "history" ), "{$curIdEq}&action=history" );
2005 $r .= ")" ;
2006 }
2007
2008 $r .= $users ;
2009 $r .= "<br />\n" ;
2010
2011 # Sub-entries
2012 $r .= "<div id='{$rci}' style='display:none'>" ;
2013 foreach ( $block AS $rcObj ) {
2014 # Get rc_xxxx variables
2015 extract( $rcObj->mAttribs );
2016
2017 $r .= "<img src='{$wgStylePath}/images/Arr_.png' width=12 height=12 />";
2018 $r .= "<tt>&nbsp; &nbsp; &nbsp; &nbsp;" ;
2019 if ( $rc_new ) $r .= $N ;
2020 else $r .= "&nbsp;" ;
2021 if ( $rc_minor ) $r .= $M ;
2022 else $r .= "&nbsp;" ;
2023 $r .= "</tt>" ;
2024
2025 $o = "" ;
2026 if ( $rc_last_oldid != 0 ) {
2027 $o = "oldid=".$rc_last_oldid ;
2028 }
2029 if ( $rc_type == RC_LOG ) {
2030 $link = $rcObj->timestamp ;
2031 } else {
2032 $link = $this->makeKnownLinkObj( $rcObj->getTitle(), $rcObj->timestamp , "{$curIdEq}&$o" ) ;
2033 }
2034 $link = "<tt>{$link}</tt>" ;
2035
2036 $r .= $link ;
2037 $r .= " (" ;
2038 $r .= $rcObj->curlink ;
2039 $r .= "; " ;
2040 $r .= $rcObj->lastlink ;
2041 $r .= ") . . ".$rcObj->userlink ;
2042 $r .= $rcObj->usertalklink ;
2043 if ( $rc_comment != "" ) {
2044 $rc_comment=$this->formatComment($rc_comment);
2045 $r .= $wgLang->emphasize( " (".$rc_comment.")" ) ;
2046 }
2047 $r .= "<br />\n" ;
2048 }
2049 $r .= "</div>\n" ;
2050
2051 $this->rcCacheIndex++ ;
2052 return $r ;
2053 }
2054
2055 # If enhanced RC is in use, this function takes the previously cached
2056 # RC lines, arranges them, and outputs the HTML
2057 function recentChangesBlock ()
2058 {
2059 global $wgStylePath ;
2060 if ( count ( $this->rc_cache ) == 0 ) return "" ;
2061 $blockOut = "";
2062 foreach ( $this->rc_cache AS $secureName => $block ) {
2063 if ( count ( $block ) < 2 ) {
2064 $blockOut .= $this->recentChangesBlockLine ( array_shift ( $block ) ) ;
2065 } else {
2066 $blockOut .= $this->recentChangesBlockGroup ( $block ) ;
2067 }
2068 }
2069
2070 return "<div>{$blockOut}</div>" ;
2071 }
2072
2073 # Called in a loop over all displayed RC entries
2074 # Either returns the line, or caches it for later use
2075 function recentChangesLine( &$rc, $watched = false )
2076 {
2077 global $wgUser ;
2078 $usenew = $wgUser->getOption( "usenewrc" );
2079 if ( $usenew )
2080 $line = $this->recentChangesLineNew ( $rc, $watched ) ;
2081 else
2082 $line = $this->recentChangesLineOld ( $rc, $watched ) ;
2083 return $line ;
2084 }
2085
2086 function recentChangesLineOld( &$rc, $watched = false )
2087 {
2088 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds;
2089
2090 # Extract DB fields into local scope
2091 extract( $rc->mAttribs );
2092 $curIdEq = "curid=" . $rc_cur_id;
2093
2094 # Make date header if necessary
2095 $date = $wgLang->date( $rc_timestamp, true);
2096 $s = "";
2097 if ( $date != $this->lastdate ) {
2098 if ( "" != $this->lastdate ) { $s .= "</ul>\n"; }
2099 $s .= "<h4>{$date}</h4>\n<ul class='special'>";
2100 $this->lastdate = $date;
2101 $this->rclistOpen = true;
2102 }
2103 $s .= "<li> ";
2104
2105 if ( $rc_type == RC_MOVE ) {
2106 # Diff
2107 $s .= "(" . wfMsg( "diff" ) . ") (";
2108 # Hist
2109 $s .= $this->makeKnownLinkObj( $rc->getMovedToTitle(), wfMsg( "hist" ), "action=history" ) .
2110 ") . . ";
2111
2112 # "[[x]] moved to [[y]]"
2113
2114 $s .= wfMsg( "1movedto2", $this->makeKnownLinkObj( $rc->getTitle(), "", "redirect=no" ),
2115 $this->makeKnownLinkObj( $rc->getMovedToTitle(), "" ) );
2116
2117 } else {
2118 # Diff link
2119 if ( $rc_type == RC_NEW || $rc_type == RC_LOG ) {
2120 $diffLink = wfMsg( "diff" );
2121 } else {
2122 $diffLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( "diff" ),
2123 "{$curIdEq}&diff={$rc_this_oldid}&oldid={$rc_last_oldid}" ,'' ,'' , ' tabindex="'.$rc->counter.'"');
2124 }
2125 $s .= "($diffLink) (";
2126
2127 # History link
2128 $s .= $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( "hist" ), "{$curIdEq}&action=history" );
2129 $s .= ") . . ";
2130
2131 # M and N (minor and new)
2132 $M = wfMsg( "minoreditletter" );
2133 $N = wfMsg( "newpageletter" );
2134 if ( $rc_minor ) { $s .= " <strong>{$M}</strong>"; }
2135 if ( $rc_type == RC_NEW ) { $s .= "<strong>{$N}</strong>"; }
2136
2137 # Article link
2138 $articleLink = $this->makeKnownLinkObj( $rc->getTitle(), "" );
2139
2140 if ( $watched ) {
2141 $articleLink = "<strong>{$articleLink}</strong>";
2142 }
2143 $s .= " $articleLink";
2144
2145 }
2146
2147 # Timestamp
2148 $s .= "; " . $wgLang->time( $rc_timestamp, true, $wgRCSeconds ) . " . . ";
2149
2150 # User link (or contributions for unregistered users)
2151 if ( 0 == $rc_user ) {
2152 $userLink = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
2153 $rc_user_text, "target=" . $rc_user_text );
2154 } else {
2155 $userLink = $this->makeLink( $wgLang->getNsText( NS_USER ) . ":{$rc_user_text}", $rc_user_text );
2156 }
2157 $s .= $userLink;
2158
2159 # User talk link
2160 $talkname=$wgLang->getNsText(NS_TALK); # use the shorter name
2161 global $wgDisableAnonTalk;
2162 if( 0 == $rc_user && $wgDisableAnonTalk ) {
2163 $userTalkLink = "";
2164 } else {
2165 $utns=$wgLang->getNsText(NS_USER_TALK);
2166 $userTalkLink= $this->makeLink($utns . ":{$rc_user_text}", $talkname );
2167 }
2168 # Block link
2169 $blockLink="";
2170 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2171 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2172 "Blockip" ), wfMsg( "blocklink" ), "ip={$rc_user_text}" );
2173
2174 }
2175 if($blockLink) {
2176 if($userTalkLink) $userTalkLink .= " | ";
2177 $userTalkLink .= $blockLink;
2178 }
2179 if($userTalkLink) $s.=" ({$userTalkLink})";
2180
2181 # Add comment
2182 if ( "" != $rc_comment && "*" != $rc_comment && $rc_type != RC_MOVE ) {
2183 $rc_comment=$this->formatComment($rc_comment);
2184 $s .= $wgLang->emphasize(" (" . $rc_comment . ")");
2185 }
2186 $s .= "</li>\n";
2187
2188 return $s;
2189 }
2190
2191 # function recentChangesLineNew( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched = false, $oldid = 0 , $diffid = 0 )
2192 function recentChangesLineNew( &$baseRC, $watched = false )
2193 {
2194 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds;
2195
2196 # Create a specialised object
2197 $rc = RCCacheEntry::newFromParent( $baseRC ) ;
2198
2199 # Extract fields from DB into the function scope (rc_xxxx variables)
2200 extract( $rc->mAttribs );
2201 $curIdEq = "curid=" . $rc_cur_id;
2202
2203 # If it's a new day, add the headline and flush the cache
2204 $date = $wgLang->date( $rc_timestamp, true);
2205 $ret = "" ;
2206 if ( $date != $this->lastdate ) {
2207 # Process current cache
2208 $ret = $this->recentChangesBlock () ;
2209 $this->rc_cache = array() ;
2210 $ret .= "<h4>{$date}</h4>\n";
2211 $this->lastdate = $date;
2212 }
2213
2214 # Make article link
2215 if ( $rc_type == RC_MOVE ) {
2216 $clink = $this->makeKnownLinkObj( $rc->getTitle(), "", "redirect=no" );
2217 $clink .= " " . wfMsg("movedto") . " ";
2218 $clink .= $this->makeKnownLinkObj( $rc->getMovedToTitle(), "" );
2219 } else {
2220 $clink = $this->makeKnownLinkObj( $rc->getTitle(), "" ) ;
2221 }
2222
2223 $time = $wgLang->time( $rc_timestamp, true, $wgRCSeconds );
2224 $rc->watched = $watched ;
2225 $rc->link = $clink ;
2226 $rc->timestamp = $time;
2227
2228 # Make "cur" link
2229 if ( ( $rc_type == RC_NEW && $rc_this_oldid == 0 ) || $rc_type == RC_LOG || $rc_type == RC_MOVE) {
2230 $curLink = wfMsg( "cur" );
2231 } else {
2232 $curLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( "cur" ),
2233 "{$curIdEq}&diff=0&oldid={$rc_this_oldid}" ,'' ,'' , ' tabindex="'.$baseRC->counter.'"' );
2234 }
2235
2236 # Make "last" link
2237 $titleObj = $rc->getTitle();
2238 if ( $rc_last_oldid == 0 || $rc_type == RC_LOG || $rc_type == RC_MOVE ) {
2239 $lastLink = wfMsg( "last" );
2240 } else {
2241 $lastLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( "last" ),
2242 "{$curIdEq}&diff={$rc_this_oldid}&oldid={$rc_last_oldid}" );
2243 }
2244
2245 # Make user link (or user contributions for unregistered users)
2246 if ( 0 == $rc_user ) {
2247 $userLink = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
2248 $rc_user_text, "target=" . $rc_user_text );
2249 } else {
2250 $userLink = $this->makeLink( $wgLang->getNsText(
2251 Namespace::getUser() ) . ":{$rc_user_text}", $rc_user_text );
2252 }
2253
2254 $rc->userlink = $userLink ;
2255 $rc->lastlink = $lastLink ;
2256 $rc->curlink = $curLink ;
2257
2258 # Make user talk link
2259 $utns=$wgLang->getNsText(NS_USER_TALK);
2260 $talkname=$wgLang->getNsText(NS_TALK); # use the shorter name
2261 $userTalkLink= $this->makeLink($utns . ":{$rc_user_text}", $talkname );
2262
2263 global $wgDisableAnonTalk;
2264 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2265 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2266 "Blockip" ), wfMsg( "blocklink" ), "ip={$rc_user_text}" );
2267 if( $wgDisableAnonTalk )
2268 $rc->usertalklink = " ({$blockLink})";
2269 else
2270 $rc->usertalklink = " ({$userTalkLink} | {$blockLink})";
2271 } else {
2272 if( $wgDisableAnonTalk && ($rc_user == 0) )
2273 $rc->usertalklink = "";
2274 else
2275 $rc->usertalklink = " ({$userTalkLink})";
2276 }
2277
2278 # Put accumulated information into the cache, for later display
2279 # Page moves go on their own line
2280 $title = $rc->getTitle();
2281 $secureName = $title->getPrefixedDBkey();
2282 if ( $rc_type == RC_MOVE ) {
2283 # Use an @ character to prevent collision with page names
2284 $this->rc_cache["@@" . ($this->rcMoveIndex++)] = array($rc);
2285 } else {
2286 if ( !isset ( $this->rc_cache[$secureName] ) ) $this->rc_cache[$secureName] = array() ;
2287 array_push ( $this->rc_cache[$secureName] , $rc ) ;
2288 }
2289 return $ret;
2290 }
2291
2292 function endImageHistoryList()
2293 {
2294 $s = "</ul>\n";
2295 return $s;
2296 }
2297
2298 /* This function is called by all recent changes variants, by the page history,
2299 and by the user contributions list. It is responsible for formatting edit
2300 comments. It escapes any HTML in the comment, but adds some CSS to format
2301 auto-generated comments (from section editing) and formats [[wikilinks]].
2302 Main author: Erik Möller (moeller@scireview.de)
2303 */
2304 function formatComment($comment)
2305 {
2306 global $wgLang;
2307 $comment=wfEscapeHTML($comment);
2308
2309 # The pattern for autogen comments is / * foo * /, which makes for
2310 # some nasty regex.
2311 # We look for all comments, match any text before and after the comment,
2312 # add a separator where needed and format the comment itself with CSS
2313 while (preg_match("/(.*)\/\*\s*(.*?)\s*\*\/(.*)/", $comment,$match)) {
2314 $pre=$match[1];
2315 $auto=$match[2];
2316 $post=$match[3];
2317 $sep="-";
2318 if($pre) { $auto="$sep ".$auto; }
2319 if($post) { $auto.=" $sep"; }
2320 $auto="<span class=\"autocomment\">".$auto."</span>";
2321 $comment=$pre.$auto.$post;
2322 }
2323
2324 # format regular and media links - all other wiki formatting
2325 # is ignored
2326 while(preg_match("/\[\[(.*?)(\|(.*?))*\]\]/",$comment,$match)) {
2327
2328 $medians = $wgLang->getNsText(Namespace::getMedia());
2329 $func="makeLink";
2330 if(preg_match("/^".$medians."/i",$match[1])) {
2331 $func="makeMediaLink";
2332 }
2333 if(isset($match[3]) ) {
2334 $comment=
2335 preg_replace("/\[\[(.*?)\]\]/",
2336 $this->$func($match[1],$match[3]),$comment,1);
2337 } else {
2338 $comment=
2339 preg_replace("/\[\[(.*?)\]\]/",
2340 $this->$func($match[1],$match[1]),$comment,1);
2341 }
2342 }
2343
2344 return $comment;
2345
2346 }
2347
2348 function imageHistoryLine( $iscur, $ts, $img, $u, $ut, $size, $c )
2349 {
2350 global $wgUser, $wgLang, $wgTitle;
2351
2352 $dt = $wgLang->timeanddate( $ts, true );
2353 $del = wfMsg( "deleteimg" );
2354 $cur = wfMsg( "cur" );
2355
2356 if ( $iscur ) {
2357 $url = Image::wfImageUrl( $img );
2358 $rlink = $cur;
2359 if ( $wgUser->isSysop() ) {
2360 $link = $wgTitle->escapeLocalURL( "image=" . $wgTitle->getPartialURL() .
2361 "&action=delete" );
2362 $style = $this->getInternalLinkAttributes( $link, $del );
2363
2364 $dlink = "<a href=\"{$link}\"{$style}>{$del}</a>";
2365 } else {
2366 $dlink = $del;
2367 }
2368 } else {
2369 $url = wfEscapeHTML( wfImageArchiveUrl( $img ) );
2370 if( $wgUser->getID() != 0 ) {
2371 $rlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2372 wfMsg( "revertimg" ), "action=revert&oldimage=" .
2373 urlencode( $img ) );
2374 $dlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2375 $del, "action=delete&oldimage=" . urlencode( $img ) );
2376 } else {
2377 # Having live active links for non-logged in users
2378 # means that bots and spiders crawling our site can
2379 # inadvertently change content. Baaaad idea.
2380 $rlink = wfMsg( "revertimg" );
2381 $dlink = $del;
2382 }
2383 }
2384 if ( 0 == $u ) { $ul = $ut; }
2385 else { $ul = $this->makeLink( $wgLang->getNsText(
2386 Namespace::getUser() ) . ":{$ut}", $ut ); }
2387
2388 $nb = wfMsg( "nbytes", $size );
2389 $style = $this->getInternalLinkAttributes( $url, $dt );
2390
2391 $s = "<li> ({$dlink}) ({$rlink}) <a href=\"{$url}\"{$style}>{$dt}</a>"
2392 . " . . {$ul} ({$nb})";
2393
2394 if ( "" != $c && "*" != $c ) {
2395 $sk=$wgUser->getSkin();
2396 $s .= $wgLang->emphasize(" (" . $sk->formatComment($c) . ")");
2397 }
2398 $s .= "</li>\n";
2399 return $s;
2400 }
2401
2402 function tocIndent($level) {
2403 return str_repeat( "<div class='tocindent'>\n", $level>0 ? $level : 0 );
2404 }
2405
2406 function tocUnindent($level) {
2407 return str_repeat( "</div>\n", $level>0 ? $level : 0 );
2408 }
2409
2410 # parameter level defines if we are on an indentation level
2411 function tocLine( $anchor, $tocline, $level ) {
2412 $link = "<a href=\"#$anchor\">$tocline</a><br />";
2413 if($level) {
2414 return "$link\n";
2415 } else {
2416 return "<div class='tocline'>$link</div>\n";
2417 }
2418
2419 }
2420
2421 function tocTable($toc) {
2422 # note to CSS fanatics: putting this in a div does not work -- div won't auto-expand
2423 # try min-width & co when somebody gets a chance
2424 $hideline = " <script type='text/javascript'>showTocToggle(\"" . addslashes( wfMsg("showtoc") ) . "\",\"" . addslashes( wfMsg("hidetoc") ) . "\")</script>";
2425 return
2426 "<table border=\"0\" id=\"toc\"><tr><td align=\"center\">\n".
2427 "<b>".wfMsg("toc")."</b>" .
2428 $hideline .
2429 "</td></tr><tr id='tocinside'><td>\n".
2430 $toc."</td></tr></table>\n";
2431 }
2432
2433 # These two do not check for permissions: check $wgTitle->userCanEdit before calling them
2434 function editSectionScript( $section, $head ) {
2435 global $wgTitle, $wgRequest;
2436 if( $wgRequest->getInt( "oldid" ) && ( $wgRequest->getVal( "diff" ) != "0" ) ) {
2437 return $head;
2438 }
2439 $url = $wgTitle->escapeLocalURL( "action=edit&section=$section" );
2440 return "<span oncontextmenu='document.location=\"$url\";return false;'>{$head}</span>";
2441 }
2442
2443 function editSectionLink( $section ) {
2444 global $wgRequest;
2445 global $wgTitle, $wgUser, $wgLang;
2446
2447 if( $wgRequest->getInt( "oldid" ) && ( $wgRequest->getVal( "diff" ) != "0" ) ) {
2448 # Section edit links would be out of sync on an old page.
2449 # But, if we're diffing to the current page, they'll be
2450 # correct.
2451 return "";
2452 }
2453
2454 $editurl = "&section={$section}";
2455 $url = $this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg("editsection"),"action=edit".$editurl);
2456
2457 if( $wgLang->isRTL() ) {
2458 $farside = "left";
2459 $nearside = "right";
2460 } else {
2461 $farside = "right";
2462 $nearside = "left";
2463 }
2464 return "<div class=\"editsection\" style=\"float:$farside;margin-$nearside:5px;\">[".$url."]</div>";
2465
2466 }
2467
2468 // This function is called by EditPage.php and shows a bulletin board style
2469 // toolbar for common editing functions. It can be disabled in the user preferences.
2470 // The necsesary JavaScript code can be found in style/wikibits.js.
2471 function getEditToolbar() {
2472 global $wgStylePath, $wgLang, $wgMimeType;
2473
2474 // toolarray an array of arrays which each include the filename of
2475 // the button image (without path), the opening tag, the closing tag,
2476 // and optionally a sample text that is inserted between the two when no
2477 // selection is highlighted.
2478 // The tip text is shown when the user moves the mouse over the button.
2479
2480 // Already here are accesskeys (key), which are not used yet until someone
2481 // can figure out a way to make them work in IE. However, we should make
2482 // sure these keys are not defined on the edit page.
2483 $toolarray=array(
2484 array( "image"=>"button_bold.png",
2485 "open"=>"\'\'\'",
2486 "close"=>"\'\'\'",
2487 "sample"=>wfMsg("bold_sample"),
2488 "tip"=>wfMsg("bold_tip"),
2489 "key"=>"B"
2490 ),
2491 array( "image"=>"button_italic.png",
2492 "open"=>"\'\'",
2493 "close"=>"\'\'",
2494 "sample"=>wfMsg("italic_sample"),
2495 "tip"=>wfMsg("italic_tip"),
2496 "key"=>"I"
2497 ),
2498 array( "image"=>"button_link.png",
2499 "open"=>"[[",
2500 "close"=>"]]",
2501 "sample"=>wfMsg("link_sample"),
2502 "tip"=>wfMsg("link_tip"),
2503 "key"=>"L"
2504 ),
2505 array( "image"=>"button_extlink.png",
2506 "open"=>"[",
2507 "close"=>"]",
2508 "sample"=>wfMsg("extlink_sample"),
2509 "tip"=>wfMsg("extlink_tip"),
2510 "key"=>"X"
2511 ),
2512 array( "image"=>"button_headline.png",
2513 "open"=>"\\n== ",
2514 "close"=>" ==\\n",
2515 "sample"=>wfMsg("headline_sample"),
2516 "tip"=>wfMsg("headline_tip"),
2517 "key"=>"H"
2518 ),
2519 array( "image"=>"button_image.png",
2520 "open"=>"[[".$wgLang->getNsText(NS_IMAGE).":",
2521 "close"=>"]]",
2522 "sample"=>wfMsg("image_sample"),
2523 "tip"=>wfMsg("image_tip"),
2524 "key"=>"D"
2525 ),
2526 array( "image"=>"button_media.png",
2527 "open"=>"[[".$wgLang->getNsText(NS_MEDIA).":",
2528 "close"=>"]]",
2529 "sample"=>wfMsg("media_sample"),
2530 "tip"=>wfMsg("media_tip"),
2531 "key"=>"M"
2532 ),
2533 array( "image"=>"button_math.png",
2534 "open"=>"\\<math\\>",
2535 "close"=>"\\</math\\>",
2536 "sample"=>wfMsg("math_sample"),
2537 "tip"=>wfMsg("math_tip"),
2538 "key"=>"C"
2539 ),
2540 array( "image"=>"button_nowiki.png",
2541 "open"=>"\\<nowiki\\>",
2542 "close"=>"\\</nowiki\\>",
2543 "sample"=>wfMsg("nowiki_sample"),
2544 "tip"=>wfMsg("nowiki_tip"),
2545 "key"=>"N"
2546 ),
2547 array( "image"=>"button_sig.png",
2548 "open"=>"--~~~~",
2549 "close"=>"",
2550 "sample"=>"",
2551 "tip"=>wfMsg("sig_tip"),
2552 "key"=>"Y"
2553 ),
2554 array( "image"=>"button_hr.png",
2555 "open"=>"\\n----\\n",
2556 "close"=>"",
2557 "sample"=>"",
2558 "tip"=>wfMsg("hr_tip"),
2559 "key"=>"R"
2560 )
2561 );
2562 $toolbar ="<script type='text/javascript'>\n/*<![CDATA[*/\n";
2563
2564 $toolbar.="document.writeln(\"<div id='toolbar'>\");\n";
2565 foreach($toolarray as $tool) {
2566
2567 $image=$wgStylePath."/images/".$tool["image"];
2568 $open=$tool["open"];
2569 $close=$tool["close"];
2570 $sample = addslashes( $tool["sample"] );
2571
2572 // Note that we use the tip both for the ALT tag and the TITLE tag of the image.
2573 // Older browsers show a "speedtip" type message only for ALT.
2574 // Ideally these should be different, realistically they
2575 // probably don't need to be.
2576 $tip = addslashes( $tool["tip"] );
2577
2578 #$key = $tool["key"];
2579
2580 $toolbar.="addButton('$image','$tip','$open','$close','$sample');\n";
2581 }
2582
2583 $toolbar.="addInfobox('" . addslashes( wfMsg( "infobox" ) ) . "','" . addslashes(wfMsg("infobox_alert")) . "');\n";
2584 $toolbar.="document.writeln(\"</div>\");\n";
2585
2586 $toolbar.="/*]]>*/\n</script>";
2587 return $toolbar;
2588 }
2589 }
2590
2591 include_once( "SkinStandard.php" );
2592 include_once( "SkinNostalgia.php" );
2593 include_once( "SkinCologneBlue.php" );
2594
2595 if( $wgUsePHPTal ) {
2596 include_once( "SkinPHPTal.php" );
2597 }
2598
2599
2600 ?>