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