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