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