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