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