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