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