clear:both
[lhc/web/wiklou.git] / includes / Skin.php
1 <?php
2
3 require_once( "Feed.php" );
4 require_once( "Image.php" );
5 require_once( "CardSet.php" );
6
7 # See skin.doc
8
9 # These are the INTERNAL names, which get mapped
10 # directly to class names. For display purposes, the
11 # Language class has internationalized names
12 #
13 /* private */ $wgValidSkinNames = array(
14 'standard' => "Standard",
15 'nostalgia' => "Nostalgia",
16 'cologneblue' => "CologneBlue"
17 );
18 if( $wgUsePHPTal ) {
19 #$wgValidSkinNames[] = "PHPTal";
20 #$wgValidSkinNames['davinci'] = "DaVinci";
21 #$wgValidSkinNames['mono'] = "Mono";
22 $wgValidSkinNames['monobook'] = "MonoBook";
23 #$wgValidSkinNames['monobookminimal'] = "MonoBookMinimal";
24 }
25
26 require_once( "RecentChange.php" );
27
28 class RCCacheEntry extends RecentChange
29 {
30 var $secureName, $link;
31 var $curlink , $lastlink , $usertalklink , $versionlink ;
32 var $userlink, $timestamp, $watched;
33
34 function newFromParent( $rc )
35 {
36 $rc2 = new RCCacheEntry;
37 $rc2->mAttribs = $rc->mAttribs;
38 $rc2->mExtra = $rc->mExtra;
39 return $rc2;
40 }
41 } ;
42
43 class Skin {
44
45 /* private */ var $lastdate, $lastline;
46 var $linktrail ; # linktrail regexp
47 var $rc_cache ; # Cache for Enhanced Recent Changes
48 var $rcCacheIndex ; # Recent Changes Cache Counter for visibility toggle
49 var $rcMoveIndex;
50
51 function Skin()
52 {
53 $this->linktrail = wfMsg("linktrail");
54 }
55
56 function getSkinNames()
57 {
58 global $wgValidSkinNames;
59 return $wgValidSkinNames;
60 }
61
62 function getStylesheet()
63 {
64 return "wikistandard.css";
65 }
66
67 function qbSetting()
68 {
69 global $wgOut, $wgUser;
70
71 if ( $wgOut->isQuickbarSuppressed() ) { return 0; }
72 $q = $wgUser->getOption( "quickbar" );
73 if ( "" == $q ) { $q = 0; }
74 return $q;
75 }
76
77 function initPage( &$out )
78 {
79 $fname = "Skin::initPage";
80 wfProfileIn( $fname );
81
82 $out->addLink( array( "rel" => "shortcut icon", "href" => "/favicon.ico" ) );
83
84 $this->addMetadataLinks($out);
85
86 wfProfileOut( $fname );
87 }
88
89 function addMetadataLinks( &$out ) {
90 global $wgTitle, $wgEnableDublinCoreRdf, $wgEnableCreativeCommonsRdf, $wgRdfMimeType, $action;
91 global $wgRightsPage, $wgRightsUrl;
92
93 if( $out->isArticleRelated() ) {
94 # note: buggy CC software only reads first "meta" link
95 if( $wgEnableCreativeCommonsRdf ) {
96 $out->addMetadataLink( array(
97 'title' => 'Creative Commons',
98 'type' => 'application/rdf+xml',
99 'href' => $wgTitle->getLocalURL( "action=creativecommons") ) );
100 }
101 if( $wgEnableDublinCoreRdf ) {
102 $out->addMetadataLink( array(
103 'title' => 'Dublin Core',
104 'type' => 'application/rdf+xml',
105 'href' => $wgTitle->getLocalURL( "action=dublincore" ) ) );
106 }
107 }
108 $copyright = "";
109 if( $wgRightsPage ) {
110 $copy = Title::newFromText( $wgRightsPage );
111 if( $copy ) {
112 $copyright = $copy->getLocalURL();
113 }
114 }
115 if( !$copyright && $wgRightsUrl ) {
116 $copyright = $wgRightsUrl;
117 }
118 if( $copyright ) {
119 $out->addLink( array(
120 "rel" => "copyright",
121 "href" => $copyright ) );
122 }
123 }
124
125 function outputPage( &$out ) {
126 global $wgDebugComments;
127
128 wfProfileIn( "Skin::outputPage" );
129 $this->initPage( $out );
130 $out->out( $out->headElement() );
131
132 $out->out( "\n<body" );
133 $ops = $this->getBodyOptions();
134 foreach ( $ops as $name => $val ) {
135 $out->out( " $name='$val'" );
136 }
137 $out->out( ">\n" );
138 if ( $wgDebugComments ) {
139 $out->out( "<!-- Wiki debugging output:\n" .
140 $out->mDebugtext . "-->\n" );
141 }
142 $out->out( $this->beforeContent() );
143
144 $out->out( $out->mBodytext . "\n" );
145
146 $out->out( $this->afterContent() );
147
148 wfProfileClose();
149 $out->out( $out->reportTime() );
150
151 $out->out( "\n</body></html>" );
152 }
153
154 function getHeadScripts() {
155 global $wgStylePath;
156 $r = "<script type=\"text/javascript\" src=\"{$wgStylePath}/wikibits.js\"></script>\n";
157 return $r;
158 }
159
160 function getUserStyles()
161 {
162 global $wgOut, $wgStylePath;
163 $sheet = $this->getStylesheet();
164 $s = "<style type='text/css'>\n";
165 $s .= "/*/*/\n"; # <-- Hide the styles from Netscape 4 without hiding them from IE/Mac
166 $s .= "@import url(\"$wgStylePath/$sheet\");\n";
167 $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
1037 $validSP = $wgLang->getValidSpecialPages();
1038
1039 foreach ( $validSP as $name => $desc ) {
1040 if ( "" == $desc ) { continue; }
1041 $a[$name] = $desc;
1042 }
1043 if ( $wgUser->isSysop() )
1044 {
1045 $sysopSP = $wgLang->getSysopSpecialPages();
1046
1047 foreach ( $sysopSP as $name => $desc ) {
1048 if ( "" == $desc ) { continue; }
1049 $a[$name] = $desc ;
1050 }
1051 }
1052 if ( $wgUser->isDeveloper() )
1053 {
1054 $devSP = $wgLang->getDeveloperSpecialPages();
1055
1056 foreach ( $devSP as $name => $desc ) {
1057 if ( "" == $desc ) { continue; }
1058 $a[$name] = $desc ;
1059 }
1060 }
1061 $go = wfMsg( "go" );
1062 $sp = wfMsg( "specialpages" );
1063 $spp = $wgLang->specialPage( "Specialpages" );
1064
1065 $s = "<form id=\"specialpages\" method=\"get\" class=\"inline\" " .
1066 "action=\"" . htmlspecialchars( "{$wgServer}{$wgRedirectScript}" ) . "\">\n";
1067 $s .= "<select name=\"wpDropdown\">\n";
1068 $s .= "<option value=\"{$spp}\">{$sp}</option>\n";
1069
1070 foreach ( $a as $name => $desc ) {
1071 $p = $wgLang->specialPage( $name );
1072 $s .= "<option value=\"{$p}\">{$desc}</option>\n";
1073 }
1074 $s .= "</select>\n";
1075 $s .= "<input type='submit' value=\"{$go}\" name='redirect' />\n";
1076 $s .= "</form>\n";
1077 return $s;
1078 }
1079
1080 function mainPageLink()
1081 {
1082 $mp = wfMsg( "mainpage" );
1083 $s = $this->makeKnownLink( $mp, $mp );
1084 return $s;
1085 }
1086
1087 function copyrightLink()
1088 {
1089 $s = $this->makeKnownLink( wfMsg( "copyrightpage" ),
1090 wfMsg( "copyrightpagename" ) );
1091 return $s;
1092 }
1093
1094 function aboutLink()
1095 {
1096 $s = $this->makeKnownLink( wfMsg( "aboutpage" ),
1097 wfMsg( "aboutwikipedia" ) );
1098 return $s;
1099 }
1100
1101
1102 function disclaimerLink()
1103 {
1104 $s = $this->makeKnownLink( wfMsg( "disclaimerpage" ),
1105 wfMsg( "disclaimers" ) );
1106 return $s;
1107 }
1108
1109 function editThisPage()
1110 {
1111 global $wgOut, $wgTitle, $wgRequest;
1112
1113 $oldid = $wgRequest->getVal( 'oldid' );
1114 $diff = $wgRequest->getVal( 'diff' );
1115 $redirect = $wgRequest->getVal( 'redirect' );
1116
1117 if ( ! $wgOut->isArticleRelated() ) {
1118 $s = wfMsg( "protectedpage" );
1119 } else {
1120 $n = $wgTitle->getPrefixedText();
1121 if ( $wgTitle->userCanEdit() ) {
1122 $t = wfMsg( "editthispage" );
1123 } else {
1124 #$t = wfMsg( "protectedpage" );
1125 $t = wfMsg( "viewsource" );
1126 }
1127 $oid = $red = "";
1128
1129 if ( !is_null( $redirect ) ) { $red = "&redirect={$redirect}"; }
1130 if ( $oldid && ! isset( $diff ) ) {
1131 $oid = "&oldid={$oldid}";
1132 }
1133 $s = $this->makeKnownLink( $n, $t, "action=edit{$oid}{$red}" );
1134 }
1135 return $s;
1136 }
1137
1138 function deleteThisPage()
1139 {
1140 global $wgUser, $wgOut, $wgTitle, $wgRequest;
1141
1142 $diff = $wgRequest->getVal( 'diff' );
1143 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
1144 $n = $wgTitle->getPrefixedText();
1145 $t = wfMsg( "deletethispage" );
1146
1147 $s = $this->makeKnownLink( $n, $t, "action=delete" );
1148 } else {
1149 $s = "";
1150 }
1151 return $s;
1152 }
1153
1154 function protectThisPage()
1155 {
1156 global $wgUser, $wgOut, $wgTitle, $wgRequest;
1157
1158 $diff = $wgRequest->getVal( 'diff' );
1159 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
1160 $n = $wgTitle->getPrefixedText();
1161
1162 if ( $wgTitle->isProtected() ) {
1163 $t = wfMsg( "unprotectthispage" );
1164 $q = "action=unprotect";
1165 } else {
1166 $t = wfMsg( "protectthispage" );
1167 $q = "action=protect";
1168 }
1169 $s = $this->makeKnownLink( $n, $t, $q );
1170 } else {
1171 $s = "";
1172 }
1173 return $s;
1174 }
1175
1176 function watchThisPage()
1177 {
1178 global $wgUser, $wgOut, $wgTitle;
1179
1180 if ( $wgOut->isArticleRelated() ) {
1181 $n = $wgTitle->getPrefixedText();
1182
1183 if ( $wgTitle->userIsWatching() ) {
1184 $t = wfMsg( "unwatchthispage" );
1185 $q = "action=unwatch";
1186 } else {
1187 $t = wfMsg( "watchthispage" );
1188 $q = "action=watch";
1189 }
1190 $s = $this->makeKnownLink( $n, $t, $q );
1191 } else {
1192 $s = wfMsg( "notanarticle" );
1193 }
1194 return $s;
1195 }
1196
1197 function moveThisPage()
1198 {
1199 global $wgTitle, $wgLang;
1200
1201 if ( $wgTitle->userCanEdit() ) {
1202 $s = $this->makeKnownLink( $wgLang->specialPage( "Movepage" ),
1203 wfMsg( "movethispage" ), "target=" . $wgTitle->getPrefixedURL() );
1204 } // no message if page is protected - would be redundant
1205 return $s;
1206 }
1207
1208 function historyLink()
1209 {
1210 global $wgTitle;
1211
1212 $s = $this->makeKnownLink( $wgTitle->getPrefixedText(),
1213 wfMsg( "history" ), "action=history" );
1214 return $s;
1215 }
1216
1217 function whatLinksHere()
1218 {
1219 global $wgTitle, $wgLang;
1220
1221 $s = $this->makeKnownLink( $wgLang->specialPage( "Whatlinkshere" ),
1222 wfMsg( "whatlinkshere" ), "target=" . $wgTitle->getPrefixedURL() );
1223 return $s;
1224 }
1225
1226 function userContribsLink()
1227 {
1228 global $wgTitle, $wgLang;
1229
1230 $s = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
1231 wfMsg( "contributions" ), "target=" . $wgTitle->getPartialURL() );
1232 return $s;
1233 }
1234
1235 function emailUserLink()
1236 {
1237 global $wgTitle, $wgLang;
1238
1239 $s = $this->makeKnownLink( $wgLang->specialPage( "Emailuser" ),
1240 wfMsg( "emailuser" ), "target=" . $wgTitle->getPartialURL() );
1241 return $s;
1242 }
1243
1244 function watchPageLinksLink()
1245 {
1246 global $wgOut, $wgTitle, $wgLang;
1247
1248 if ( ! $wgOut->isArticleRelated() ) {
1249 $s = "(" . wfMsg( "notanarticle" ) . ")";
1250 } else {
1251 $s = $this->makeKnownLink( $wgLang->specialPage(
1252 "Recentchangeslinked" ), wfMsg( "recentchangeslinked" ),
1253 "target=" . $wgTitle->getPrefixedURL() );
1254 }
1255 return $s;
1256 }
1257
1258 function otherLanguages()
1259 {
1260 global $wgOut, $wgLang, $wgTitle, $wgUseNewInterlanguage;
1261
1262 $a = $wgOut->getLanguageLinks();
1263 if ( 0 == count( $a ) ) {
1264 if ( !$wgUseNewInterlanguage ) return "";
1265 $ns = $wgLang->getNsIndex ( $wgTitle->getNamespace () ) ;
1266 if ( $ns != 0 AND $ns != 1 ) return "" ;
1267 $pn = "Intl" ;
1268 $x = "mode=addlink&xt=".$wgTitle->getDBkey() ;
1269 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1270 wfMsg( "intl" ) , $x );
1271 }
1272
1273 if ( !$wgUseNewInterlanguage ) {
1274 $s = wfMsg( "otherlanguages" ) . ": ";
1275 } else {
1276 global $wgLanguageCode ;
1277 $x = "mode=zoom&xt=".$wgTitle->getDBkey() ;
1278 $x .= "&xl=".$wgLanguageCode ;
1279 $s = $this->makeKnownLink( $wgLang->specialPage( "Intl" ),
1280 wfMsg( "otherlanguages" ) , $x ) . ": " ;
1281 }
1282
1283 $s = wfMsg( "otherlanguages" ) . ": ";
1284 $first = true;
1285 if($wgLang->isRTL()) $s .= "<span dir='LTR'>";
1286 foreach( $a as $l ) {
1287 if ( ! $first ) { $s .= " | "; }
1288 $first = false;
1289
1290 $nt = Title::newFromText( $l );
1291 $url = $nt->getFullURL();
1292 $text = $wgLang->getLanguageName( $nt->getInterwiki() );
1293
1294 if ( "" == $text ) { $text = $l; }
1295 $style = $this->getExternalLinkAttributes( $l, $text );
1296 $s .= "<a href=\"{$url}\"{$style}>{$text}</a>";
1297 }
1298 if($wgLang->isRTL()) $s .= "</span>";
1299 return $s;
1300 }
1301
1302 function bugReportsLink()
1303 {
1304 $s = $this->makeKnownLink( wfMsg( "bugreportspage" ),
1305 wfMsg( "bugreports" ) );
1306 return $s;
1307 }
1308
1309 function dateLink()
1310 {
1311 global $wgLinkCache;
1312 $t1 = Title::newFromText( gmdate( "F j" ) );
1313 $t2 = Title::newFromText( gmdate( "Y" ) );
1314
1315 $wgLinkCache->suspend();
1316 $id = $t1->getArticleID();
1317 $wgLinkCache->resume();
1318
1319 if ( 0 == $id ) {
1320 $s = $this->makeBrokenLink( $t1->getText() );
1321 } else {
1322 $s = $this->makeKnownLink( $t1->getText() );
1323 }
1324 $s .= ", ";
1325
1326 $wgLinkCache->suspend();
1327 $id = $t2->getArticleID();
1328 $wgLinkCache->resume();
1329
1330 if ( 0 == $id ) {
1331 $s .= $this->makeBrokenLink( $t2->getText() );
1332 } else {
1333 $s .= $this->makeKnownLink( $t2->getText() );
1334 }
1335 return $s;
1336 }
1337
1338 function talkLink()
1339 {
1340 global $wgLang, $wgTitle, $wgLinkCache;
1341
1342 $tns = $wgTitle->getNamespace();
1343 if ( -1 == $tns ) { return ""; }
1344
1345 $pn = $wgTitle->getText();
1346 $tp = wfMsg( "talkpage" );
1347 if ( Namespace::isTalk( $tns ) ) {
1348 $lns = Namespace::getSubject( $tns );
1349 switch($tns) {
1350 case 1:
1351 $text = wfMsg("articlepage");
1352 break;
1353 case 3:
1354 $text = wfMsg("userpage");
1355 break;
1356 case 5:
1357 $text = wfMsg("wikipediapage");
1358 break;
1359 case 7:
1360 $text = wfMsg("imagepage");
1361 break;
1362 default:
1363 $text= wfMsg("articlepage");
1364 }
1365 } else {
1366
1367 $lns = Namespace::getTalk( $tns );
1368 $text=$tp;
1369 }
1370 $n = $wgLang->getNsText( $lns );
1371 if ( "" == $n ) { $link = $pn; }
1372 else { $link = "{$n}:{$pn}"; }
1373
1374 $wgLinkCache->suspend();
1375 $s = $this->makeLink( $link, $text );
1376 $wgLinkCache->resume();
1377
1378 return $s;
1379 }
1380
1381 function commentLink()
1382 {
1383 global $wgLang, $wgTitle, $wgLinkCache;
1384
1385 $tns = $wgTitle->getNamespace();
1386 if ( -1 == $tns ) { return ""; }
1387
1388 $lns = ( Namespace::isTalk( $tns ) ) ? $tns : Namespace::getTalk( $tns );
1389
1390 # assert Namespace::isTalk( $lns )
1391
1392 $n = $wgLang->getNsText( $lns );
1393 $pn = $wgTitle->getText();
1394
1395 $link = "{$n}:{$pn}";
1396
1397 $wgLinkCache->suspend();
1398 $s = $this->makeKnownLink($link, wfMsg("postcomment"), "action=edit&section=new");
1399 $wgLinkCache->resume();
1400
1401 return $s;
1402 }
1403
1404 # After all the page content is transformed into HTML, it makes
1405 # a final pass through here for things like table backgrounds.
1406 #
1407 function transformContent( $text )
1408 {
1409 return $text;
1410 }
1411
1412 # Note: This function MUST call getArticleID() on the link,
1413 # otherwise the cache won't get updated properly. See LINKCACHE.DOC.
1414 #
1415 function makeLink( $title, $text = "", $query = "", $trail = "" ) {
1416 wfProfileIn( "Skin::makeLink" );
1417 $nt = Title::newFromText( $title );
1418 if ($nt) {
1419 $result = $this->makeLinkObj( Title::newFromText( $title ), $text, $query, $trail );
1420 } else {
1421 wfDebug( "Invalid title passed to Skin::makeLink(): \"$title\"\n" );
1422 $result = $text == "" ? $title : $text;
1423 }
1424
1425 wfProfileOut( "Skin::makeLink" );
1426 return $result;
1427 }
1428
1429 function makeKnownLink( $title, $text = "", $query = "", $trail = "", $prefix = '',$aprops = '') {
1430 $nt = Title::newFromText( $title );
1431 if ($nt) {
1432 return $this->makeKnownLinkObj( Title::newFromText( $title ), $text, $query, $trail, $prefix , $aprops );
1433 } else {
1434 wfDebug( "Invalid title passed to Skin::makeKnownLink(): \"$title\"\n" );
1435 return $text == "" ? $title : $text;
1436 }
1437 }
1438
1439 function makeBrokenLink( $title, $text = "", $query = "", $trail = "" ) {
1440 $nt = Title::newFromText( $title );
1441 if ($nt) {
1442 return $this->makeBrokenLinkObj( Title::newFromText( $title ), $text, $query, $trail );
1443 } else {
1444 wfDebug( "Invalid title passed to Skin::makeBrokenLink(): \"$title\"\n" );
1445 return $text == "" ? $title : $text;
1446 }
1447 }
1448
1449 function makeStubLink( $title, $text = "", $query = "", $trail = "" ) {
1450 $nt = Title::newFromText( $title );
1451 if ($nt) {
1452 return $this->makeStubLinkObj( Title::newFromText( $title ), $text, $query, $trail );
1453 } else {
1454 wfDebug( "Invalid title passed to Skin::makeStubLink(): \"$title\"\n" );
1455 return $text == "" ? $title : $text;
1456 }
1457 }
1458
1459 # Pass a title object, not a title string
1460 function makeLinkObj( &$nt, $text= "", $query = "", $trail = "", $prefix = "" )
1461 {
1462 global $wgOut, $wgUser;
1463 if ( $nt->isExternal() ) {
1464 $u = $nt->getFullURL();
1465 $link = $nt->getPrefixedURL();
1466 if ( "" == $text ) { $text = $nt->getPrefixedText(); }
1467 $style = $this->getExternalLinkAttributes( $link, $text );
1468
1469 $inside = "";
1470 if ( "" != $trail ) {
1471 if ( preg_match( "/^([a-z]+)(.*)$$/sD", $trail, $m ) ) {
1472 $inside = $m[1];
1473 $trail = $m[2];
1474 }
1475 }
1476 $retVal = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1477 } elseif ( 0 == $nt->getNamespace() && "" == $nt->getText() ) {
1478 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1479 } elseif ( ( -1 == $nt->getNamespace() ) ||
1480 ( Namespace::getImage() == $nt->getNamespace() ) ) {
1481 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1482 } else {
1483 $aid = $nt->getArticleID() ;
1484 if ( 0 == $aid ) {
1485 $retVal = $this->makeBrokenLinkObj( $nt, $text, $query, $trail, $prefix );
1486 } else {
1487 $threshold = $wgUser->getOption("stubthreshold") ;
1488 if ( $threshold > 0 ) {
1489 $res = wfQuery ( "SELECT LENGTH(cur_text) AS x, cur_namespace, cur_is_redirect FROM cur WHERE cur_id='{$aid}'", DB_READ ) ;
1490
1491 if ( wfNumRows( $res ) > 0 ) {
1492 $s = wfFetchObject( $res );
1493 $size = $s->x;
1494 if ( $s->cur_is_redirect OR $s->cur_namespace != 0 ) {
1495 $size = $threshold*2 ; # Really big
1496 }
1497 wfFreeResult( $res );
1498 } else {
1499 $size = $threshold*2 ; # Really big
1500 }
1501 } else {
1502 $size = 1 ;
1503 }
1504 if ( $size < $threshold ) {
1505 $retVal = $this->makeStubLinkObj( $nt, $text, $query, $trail, $prefix );
1506 } else {
1507 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1508 }
1509 }
1510 }
1511 return $retVal;
1512 }
1513
1514 # Pass a title object, not a title string
1515 function makeKnownLinkObj( &$nt, $text = "", $query = "", $trail = "", $prefix = "" , $aprops = '')
1516 {
1517 global $wgOut, $wgTitle;
1518
1519 $fname = "Skin::makeKnownLinkObj";
1520 wfProfileIn( $fname );
1521
1522 $link = $nt->getPrefixedURL();
1523
1524 if ( "" == $link ) {
1525 $u = "";
1526 if ( "" == $text ) {
1527 $text = htmlspecialchars( $nt->getFragment() );
1528 }
1529 } else {
1530 $u = $nt->escapeLocalURL( $query );
1531 }
1532 if ( "" != $nt->getFragment() ) {
1533 $u .= "#" . htmlspecialchars( $nt->getFragment() );
1534 }
1535 if ( "" == $text ) {
1536 $text = htmlspecialchars( $nt->getPrefixedText() );
1537 }
1538 $style = $this->getInternalLinkAttributesObj( $nt, $text );
1539
1540 $inside = "";
1541 if ( "" != $trail ) {
1542 if ( preg_match( $this->linktrail, $trail, $m ) ) {
1543 $inside = $m[1];
1544 $trail = $m[2];
1545 }
1546 }
1547 $r = "<a href=\"{$u}\"{$style}{$aprops}>{$prefix}{$text}{$inside}</a>{$trail}";
1548 wfProfileOut( $fname );
1549 return $r;
1550 }
1551
1552 # Pass a title object, not a title string
1553 function makeBrokenLinkObj( &$nt, $text = "", $query = "", $trail = "", $prefix = "" )
1554 {
1555 global $wgOut, $wgUser;
1556
1557 $fname = "Skin::makeBrokenLinkObj";
1558 wfProfileIn( $fname );
1559
1560 if ( "" == $query ) {
1561 $q = "action=edit";
1562 } else {
1563 $q = "action=edit&{$query}";
1564 }
1565 $u = $nt->escapeLocalURL( $q );
1566
1567 if ( "" == $text ) {
1568 $text = htmlspecialchars( $nt->getPrefixedText() );
1569 }
1570 $style = $this->getInternalLinkAttributesObj( $nt, $text, "yes" );
1571
1572 $inside = "";
1573 if ( "" != $trail ) {
1574 if ( preg_match( $this->linktrail, $trail, $m ) ) {
1575 $inside = $m[1];
1576 $trail = $m[2];
1577 }
1578 }
1579 if ( $wgUser->getOption( "highlightbroken" ) ) {
1580 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1581 } else {
1582 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>?</a>{$trail}";
1583 }
1584
1585 wfProfileOut( $fname );
1586 return $s;
1587 }
1588
1589 # Pass a title object, not a title string
1590 function makeStubLinkObj( &$nt, $text = "", $query = "", $trail = "", $prefix = "" )
1591 {
1592 global $wgOut, $wgUser;
1593
1594 $link = $nt->getPrefixedURL();
1595
1596 $u = $nt->escapeLocalURL( $query );
1597
1598 if ( "" == $text ) {
1599 $text = htmlspecialchars( $nt->getPrefixedText() );
1600 }
1601 $style = $this->getInternalLinkAttributesObj( $nt, $text, "stub" );
1602
1603 $inside = "";
1604 if ( "" != $trail ) {
1605 if ( preg_match( $this->linktrail, $trail, $m ) ) {
1606 $inside = $m[1];
1607 $trail = $m[2];
1608 }
1609 }
1610 if ( $wgUser->getOption( "highlightbroken" ) ) {
1611 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1612 } else {
1613 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>!</a>{$trail}";
1614 }
1615 return $s;
1616 }
1617
1618 function makeSelfLinkObj( &$nt, $text = "", $query = "", $trail = "", $prefix = "" )
1619 {
1620 $u = $nt->escapeLocalURL( $query );
1621 if ( "" == $text ) {
1622 $text = htmlspecialchars( $nt->getPrefixedText() );
1623 }
1624 $inside = "";
1625 if ( "" != $trail ) {
1626 if ( preg_match( $this->linktrail, $trail, $m ) ) {
1627 $inside = $m[1];
1628 $trail = $m[2];
1629 }
1630 }
1631 return "<strong>{$prefix}{$text}{$inside}</strong>{$trail}";
1632 }
1633
1634 /* these are used extensively in SkinPHPTal, but also some other places */
1635 /*static*/ function makeSpecialUrl( $name, $urlaction='' ) {
1636 $title = Title::makeTitle( NS_SPECIAL, $name );
1637 $this->checkTitle($title, $name);
1638 return $title->getLocalURL( $urlaction );
1639 }
1640 /*static*/ function makeTalkUrl ( $name, $urlaction='' ) {
1641 $title = Title::newFromText( $name );
1642 $title = $title->getTalkPage();
1643 $this->checkTitle($title, $name);
1644 return $title->getLocalURL( $urlaction );
1645 }
1646 /*static*/ function makeArticleUrl ( $name, $urlaction='' ) {
1647 $title = Title::newFromText( $name );
1648 $title= $title->getSubjectPage();
1649 $this->checkTitle($title, $name);
1650 return $title->getLocalURL( $urlaction );
1651 }
1652 /*static*/ function makeI18nUrl ( $name, $urlaction='' ) {
1653 $title = Title::newFromText( wfMsg($name) );
1654 $this->checkTitle($title, $name);
1655 return $title->getLocalURL( $urlaction );
1656 }
1657 /*static*/ function makeUrl ( $name, $urlaction='' ) {
1658 $title = Title::newFromText( $name );
1659 $this->checkTitle($title, $name);
1660 return $title->getLocalURL( $urlaction );
1661 }
1662
1663 /* these return an array with the 'href' and boolean 'exists' */
1664 /*static*/ function makeUrlDetails ( $name, $urlaction='' ) {
1665 $title = Title::newFromText( $name );
1666 $this->checkTitle($title, $name);
1667 return array(
1668 'href' => $title->getLocalURL( $urlaction ),
1669 'exists' => $title->getArticleID() != 0?true:false
1670 );
1671 }
1672 /*static*/ function makeTalkUrlDetails ( $name, $urlaction='' ) {
1673 $title = Title::newFromText( $name );
1674 $title = $title->getTalkPage();
1675 $this->checkTitle($title, $name);
1676 return array(
1677 'href' => $title->getLocalURL( $urlaction ),
1678 'exists' => $title->getArticleID() != 0?true:false
1679 );
1680 }
1681 /*static*/ function makeArticleUrlDetails ( $name, $urlaction='' ) {
1682 $title = Title::newFromText( $name );
1683 $title= $title->getSubjectPage();
1684 $this->checkTitle($title, $name);
1685 return array(
1686 'href' => $title->getLocalURL( $urlaction ),
1687 'exists' => $title->getArticleID() != 0?true:false
1688 );
1689 }
1690 /*static*/ function makeI18nUrlDetails ( $name, $urlaction='' ) {
1691 $title = Title::newFromText( wfMsg($name) );
1692 $this->checkTitle($title, $name);
1693 return array(
1694 'href' => $title->getLocalURL( $urlaction ),
1695 'exists' => $title->getArticleID() != 0?true:false
1696 );
1697 }
1698
1699 # make sure we have some title to operate on
1700 /*static*/ function checkTitle ( &$title, &$name ) {
1701 if(!is_object($title)) {
1702 $title = Title::newFromText( $name );
1703 if(!is_object($title)) {
1704 $title = Title::newFromText( '<error: link target missing>' );
1705 }
1706 }
1707 }
1708
1709 function fnamePart( $url )
1710 {
1711 $basename = strrchr( $url, "/" );
1712 if ( false === $basename ) { $basename = $url; }
1713 else { $basename = substr( $basename, 1 ); }
1714 return wfEscapeHTML( $basename );
1715 }
1716
1717 function makeImage( $url, $alt = "" )
1718 {
1719 global $wgOut;
1720
1721 if ( "" == $alt ) { $alt = $this->fnamePart( $url ); }
1722 $s = "<img src=\"{$url}\" alt=\"{$alt}\" />";
1723 return $s;
1724 }
1725
1726 function makeImageLink( $name, $url, $alt = "" ) {
1727 $nt = Title::makeTitle( Namespace::getImage(), $name );
1728 return $this->makeImageLinkObj( $nt, $alt );
1729 }
1730
1731 function makeImageLinkObj( $nt, $alt = "" ) {
1732 global $wgLang, $wgUseImageResize;
1733 $img = Image::newFromTitle( $nt );
1734 $url = $img->getURL();
1735
1736 $align = "";
1737 $prefix = $postfix = "";
1738
1739 if ( $wgUseImageResize ) {
1740 # Check if the alt text is of the form "options|alt text"
1741 # Options are:
1742 # * thumbnail make a thumbnail with enlarge-icon and caption, alignment depends on lang
1743 # * left no resizing, just left align. label is used for alt= only
1744 # * right same, but right aligned
1745 # * none same, but not aligned
1746 # * ___px scale to ___ pixels width, no aligning. e.g. use in taxobox
1747 # * center center the image
1748 # * framed Keep original image size, no magnify-button.
1749
1750 $part = explode( "|", $alt);
1751
1752 $mwThumb =& MagicWord::get( MAG_IMG_THUMBNAIL );
1753 $mwLeft =& MagicWord::get( MAG_IMG_LEFT );
1754 $mwRight =& MagicWord::get( MAG_IMG_RIGHT );
1755 $mwNone =& MagicWord::get( MAG_IMG_NONE );
1756 $mwWidth =& MagicWord::get( MAG_IMG_WIDTH );
1757 $mwCenter =& MagicWord::get( MAG_IMG_CENTER );
1758 $mwFramed =& MagicWord::get( MAG_IMG_FRAMED );
1759 $alt = $part[count($part)-1];
1760
1761 $height = $framed = $thumb = false;
1762
1763 foreach( $part as $key => $val ) {
1764 if ( ! is_null( $mwThumb->matchVariableStartToEnd($val) ) ) {
1765 $thumb=true;
1766 } elseif ( ! is_null( $mwRight->matchVariableStartToEnd($val) ) ) {
1767 # remember to set an alignment, don't render immediately
1768 $align = "right";
1769 } elseif ( ! is_null( $mwLeft->matchVariableStartToEnd($val) ) ) {
1770 # remember to set an alignment, don't render immediately
1771 $align = "left";
1772 } elseif ( ! is_null( $mwCenter->matchVariableStartToEnd($val) ) ) {
1773 # remember to set an alignment, don't render immediately
1774 $align = "center";
1775 } elseif ( ! is_null( $mwNone->matchVariableStartToEnd($val) ) ) {
1776 # remember to set an alignment, don't render immediately
1777 $align = "none";
1778 } elseif ( ! is_null( $match = $mwWidth->matchVariableStartToEnd($val) ) ) {
1779 # $match is the image width in pixels
1780 if ( preg_match( "/^([0-9]*)x([0-9]*)$/", $match, $m ) ) {
1781 $width = intval( $m[1] );
1782 $height = intval( $m[2] );
1783 } else {
1784 $width = intval($match);
1785 }
1786 } elseif ( ! is_null( $mwFramed->matchVariableStartToEnd($val) ) ) {
1787 $framed=true;
1788 }
1789 }
1790 if ( "center" == $align )
1791 {
1792 $prefix = '<span style="text-align: center">';
1793 $postfix = '</span>';
1794 $align = "none";
1795 }
1796
1797 if ( $thumb || $framed ) {
1798
1799 # Create a thumbnail. Alignment depends on language
1800 # writing direction, # right aligned for left-to-right-
1801 # languages ("Western languages"), left-aligned
1802 # for right-to-left-languages ("Semitic languages")
1803 #
1804 # If thumbnail width has not been provided, it is set
1805 # here to 180 pixels
1806 if ( $align == "" ) {
1807 $align = $wgLang->isRTL() ? "left" : "right";
1808 }
1809 if ( ! isset($width) ) {
1810 $width = 180;
1811 }
1812 return $prefix.$this->makeThumbLinkObj( $img, $alt, $align, $width, $height, $framed ).$postfix;
1813
1814 } elseif ( isset($width) ) {
1815
1816 # Create a resized image, without the additional thumbnail
1817 # features
1818
1819 if ( ( ! $height === false )
1820 && ( $img->getHeight() * $width / $img->getWidth() > $height ) ) {
1821 print "height=$height<br>\nimg->getHeight() = ".$img->getHeight()."<br>\n";
1822 print "rescaling by factor ". $height / $img->getHeight() . "<br>\n";
1823 $width = $img->getWidth() * $height / $img->getHeight();
1824 }
1825 $url = $img->createThumb( $width );
1826 }
1827 } # endif $wgUseImageResize
1828
1829 if ( empty( $alt ) ) {
1830 $alt = preg_replace( '/\.(.+?)^/', '', $img->getName() );
1831 }
1832 $alt = htmlspecialchars( $alt );
1833
1834 $u = $nt->escapeLocalURL();
1835 if ( $url == "" )
1836 {
1837 $s = str_replace( "$1", $img->getName(), wfMsg("missingimage") );
1838 $s .= "<br>{$alt}<br>{$url}<br>\n";
1839 } else {
1840 $s = "<a href=\"{$u}\" class='image' title=\"{$alt}\">" .
1841 "<img src=\"{$url}\" alt=\"{$alt}\" /></a>";
1842 }
1843 if ( "" != $align ) {
1844 $s = "<div class=\"float{$align}\"><span>{$s}</span>\n</div>";
1845 }
1846 return $prefix.$s.$postfix;
1847 }
1848
1849
1850 function makeThumbLinkObj( $img, $label = "", $align = "right", $boxwidth = 180, $boxheight=false, $framed=false ) {
1851 global $wgStylePath, $wgLang;
1852 # $image = Title::makeTitle( Namespace::getImage(), $name );
1853 $url = $img->getURL();
1854
1855 #$label = htmlspecialchars( $label );
1856 $alt = preg_replace( "/<[^>]*>/", "", $label);
1857 $alt = htmlspecialchars( $alt );
1858
1859 if ( $img->exists() )
1860 {
1861 $width = $img->getWidth();
1862 $height = $img->getHeight();
1863 } else {
1864 $width = $height = 200;
1865 }
1866 if ( $framed )
1867 {
1868 // Use image dimensions, don't scale
1869 $boxwidth = $width;
1870 $oboxwidth = $boxwidth + 2;
1871 $boxheight = $height;
1872 $thumbUrl = $url;
1873 } else {
1874 $h = intval( $height/($width/$boxwidth) );
1875 $oboxwidth = $boxwidth + 2;
1876 if ( ( ! $boxheight === false ) && ( $h > $boxheight ) )
1877 {
1878 $boxwidth *= $boxheight/$h;
1879 } else {
1880 $boxheight = $h;
1881 }
1882 $thumbUrl = $img->createThumb( $boxwidth );
1883 }
1884
1885 $u = $img->getEscapeLocalURL();
1886
1887 $more = htmlspecialchars( wfMsg( "thumbnail-more" ) );
1888 $magnifyalign = $wgLang->isRTL() ? "left" : "right";
1889 $textalign = $wgLang->isRTL() ? ' style="text-align:right"' : "";
1890
1891 $s = "<div class=\"thumb t{$align}\"><div style=\"width:{$oboxwidth}px;\">";
1892 if ( $thumbUrl == "" ) {
1893 $s .= str_replace( "$1", $img->getName(), wfMsg("missingimage") );
1894 $zoomicon = '';
1895 } else {
1896 $s .= '<a href="'.$u.'" class="internal" title="'.$alt.'">'.
1897 '<img src="'.$thumbUrl.'" alt="'.$alt.'" ' .
1898 'width="'.$boxwidth.'" height="'.$boxheight.'" /></a>';
1899 if ( $framed ) {
1900 $zoomicon="";
1901 } else {
1902 $zoomicon = '<div class="magnify" style="float:'.$magnifyalign.'">'.
1903 '<a href="'.$u.'" class="internal" title="'.$more.'">'.
1904 '<img src="'.$wgStylePath.'/images/magnify-clip.png" ' .
1905 'width="15" height="11" alt="'.$more.'" /></a></div>';
1906 }
1907 }
1908 $s .= ' <div class="thumbcaption" '.$textalign.'>'.$zoomicon.$label."</div></div>\n</div>";
1909 return $s;
1910 }
1911
1912 function makeMediaLink( $name, $url, $alt = "" ) {
1913 $nt = Title::makeTitle( Namespace::getMedia(), $name );
1914 return $this->makeMediaLinkObj( $nt, $alt );
1915 }
1916
1917 function makeMediaLinkObj( $nt, $alt = "" )
1918 {
1919 $name = $nt->getDBKey();
1920 $url = Image::wfImageUrl( $name );
1921 if ( empty( $alt ) ) {
1922 $alt = preg_replace( '/\.(.+?)^/', '', $name );
1923 }
1924
1925 $u = htmlspecialchars( $url );
1926 $s = "<a href=\"{$u}\" class='internal' title=\"{$alt}\">{$alt}</a>";
1927 return $s;
1928 }
1929
1930 function specialLink( $name, $key = "" )
1931 {
1932 global $wgLang;
1933
1934 if ( "" == $key ) { $key = strtolower( $name ); }
1935 $pn = $wgLang->ucfirst( $name );
1936 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1937 wfMsg( $key ) );
1938 }
1939
1940 function makeExternalLink( $url, $text, $escape = true ) {
1941 $style = $this->getExternalLinkAttributes( $url, $text );
1942 $url = htmlspecialchars( $url );
1943 if( $escape ) {
1944 $text = htmlspecialchars( $text );
1945 }
1946 return "<a href=\"$url\"$style>$text</a>";
1947 }
1948
1949 # Called by history lists and recent changes
1950 #
1951
1952 # Returns text for the start of the tabular part of RC
1953 function beginRecentChangesList()
1954 {
1955 $this->rc_cache = array() ;
1956 $this->rcMoveIndex = 0;
1957 $this->rcCacheIndex = 0 ;
1958 $this->lastdate = "";
1959 $this->rclistOpen = false;
1960 return "";
1961 }
1962
1963 function beginImageHistoryList()
1964 {
1965 $s = "\n<h2>" . wfMsg( "imghistory" ) . "</h2>\n" .
1966 "<p>" . wfMsg( "imghistlegend" ) . "</p>\n<ul class='special'>";
1967 return $s;
1968 }
1969
1970 # Returns text for the end of RC
1971 # If enhanced RC is in use, returns pretty much all the text
1972 function endRecentChangesList()
1973 {
1974 $s = $this->recentChangesBlock() ;
1975 if( $this->rclistOpen ) {
1976 $s .= "</ul>\n";
1977 }
1978 return $s;
1979 }
1980
1981 # Enhanced RC ungrouped line
1982 function recentChangesBlockLine ( $rcObj )
1983 {
1984 global $wgStylePath, $wgLang ;
1985
1986 # Get rc_xxxx variables
1987 extract( $rcObj->mAttribs ) ;
1988 $curIdEq = "curid=$rc_cur_id";
1989
1990 # Spacer image
1991 $r = "" ;
1992
1993 $r .= "<img src='{$wgStylePath}/images/Arr_.png' width='12' height='12' border='0' />" ; $r .= "<tt>" ;
1994
1995 if ( $rc_type == RC_MOVE ) {
1996 $r .= "&nbsp;&nbsp;";
1997 } else {
1998 # M & N (minor & new)
1999 $M = wfMsg( "minoreditletter" );
2000 $N = wfMsg( "newpageletter" );
2001
2002 if ( $rc_type == RC_NEW ) {
2003 $r .= $N ;
2004 } else {
2005 $r .= "&nbsp;" ;
2006 }
2007 if ( $rc_minor ) {
2008 $r .= $M ;
2009 } else {
2010 $r .= "&nbsp;" ;
2011 }
2012 }
2013
2014 # Timestamp
2015 $r .= " ".$rcObj->timestamp." " ;
2016 $r .= "</tt>" ;
2017
2018 # Article link
2019 $link = $rcObj->link ;
2020 if ( $rcObj->watched ) $link = "<strong>{$link}</strong>" ;
2021 $r .= $link ;
2022
2023 # Cur
2024 $r .= " (" ;
2025 $r .= $rcObj->curlink ;
2026 $r .= "; " ;
2027
2028 # Hist
2029 $r .= $this->makeKnownLinkObj( $rcObj->getTitle(), wfMsg( "hist" ), "{$curIdEq}&action=history" );
2030
2031 # User/talk
2032 $r .= ") . . ".$rcObj->userlink ;
2033 $r .= $rcObj->usertalklink ;
2034
2035 # Comment
2036 if ( $rc_comment != "" && $rc_type != RC_MOVE ) {
2037 $rc_comment=$this->formatComment($rc_comment);
2038 $r .= $wgLang->emphasize( " (".$rc_comment.")" );
2039 }
2040
2041 $r .= "<br />\n" ;
2042 return $r ;
2043 }
2044
2045 # Enhanced RC group
2046 function recentChangesBlockGroup ( $block )
2047 {
2048 global $wgStylePath, $wgLang ;
2049
2050 $r = "" ;
2051 $M = wfMsg( "minoreditletter" );
2052 $N = wfMsg( "newpageletter" );
2053
2054 # Collate list of users
2055 $isnew = false ;
2056 $userlinks = array () ;
2057 foreach ( $block AS $rcObj ) {
2058 $oldid = $rcObj->mAttribs['rc_last_oldid'];
2059 if ( $rcObj->mAttribs['rc_new'] ) $isnew = true ;
2060 $u = $rcObj->userlink ;
2061 if ( !isset ( $userlinks[$u] ) ) $userlinks[$u] = 0 ;
2062 $userlinks[$u]++ ;
2063 }
2064
2065 # Sort the list and convert to text
2066 krsort ( $userlinks ) ;
2067 asort ( $userlinks ) ;
2068 $users = array () ;
2069 foreach ( $userlinks as $userlink => $count) {
2070 $text = $userlink ;
2071 if ( $count > 1 ) $text .= " ({$count}&times;)" ;
2072 array_push ( $users , $text ) ;
2073 }
2074 $users = " <font size='-1'>[".implode("; ",$users)."]</font>" ;
2075
2076 # Arrow
2077 $rci = "RCI{$this->rcCacheIndex}" ;
2078 $rcl = "RCL{$this->rcCacheIndex}" ;
2079 $rcm = "RCM{$this->rcCacheIndex}" ;
2080 $toggleLink = "javascript:toggleVisibility(\"{$rci}\",\"{$rcm}\",\"{$rcl}\")" ;
2081 $arrowdir = $wgLang->isRTL() ? "l" : "r";
2082 $tl = "<span id='{$rcm}'><a href='$toggleLink'><img src='{$wgStylePath}/images/Arr_{$arrowdir}.png' width='12' height='12' /></a></span>" ;
2083 $tl .= "<span id='{$rcl}' style='display:none'><a href='$toggleLink'><img src='{$wgStylePath}/images/Arr_d.png' width='12' height='12' /></a></span>" ;
2084 $r .= $tl ;
2085
2086 # Main line
2087 # M/N
2088 $r .= "<tt>" ;
2089 if ( $isnew ) $r .= $N ;
2090 else $r .= "&nbsp;" ;
2091 $r .= "&nbsp;" ; # Minor
2092
2093 # Timestamp
2094 $r .= " ".$block[0]->timestamp." " ;
2095 $r .= "</tt>" ;
2096
2097 # Article link
2098 $link = $block[0]->link ;
2099 if ( $block[0]->watched ) $link = "<strong>{$link}</strong>" ;
2100 $r .= $link ;
2101
2102 $curIdEq = "curid=" . $block[0]->mAttribs['rc_cur_id'];
2103 if ( $block[0]->mAttribs['rc_type'] != RC_LOG ) {
2104 # Changes
2105 $r .= " (".count($block)." " ;
2106 if ( $isnew ) $r .= wfMsg("changes");
2107 else $r .= $this->makeKnownLinkObj( $block[0]->getTitle() , wfMsg("changes") ,
2108 "{$curIdEq}&diff=0&oldid=".$oldid ) ;
2109 $r .= "; " ;
2110
2111 # History
2112 $r .= $this->makeKnownLinkObj( $block[0]->getTitle(), wfMsg( "history" ), "{$curIdEq}&action=history" );
2113 $r .= ")" ;
2114 }
2115
2116 $r .= $users ;
2117 $r .= "<br />\n" ;
2118
2119 # Sub-entries
2120 $r .= "<div id='{$rci}' style='display:none'>" ;
2121 foreach ( $block AS $rcObj ) {
2122 # Get rc_xxxx variables
2123 extract( $rcObj->mAttribs );
2124
2125 $r .= "<img src='{$wgStylePath}/images/Arr_.png' width=12 height=12 />";
2126 $r .= "<tt>&nbsp; &nbsp; &nbsp; &nbsp;" ;
2127 if ( $rc_new ) $r .= $N ;
2128 else $r .= "&nbsp;" ;
2129 if ( $rc_minor ) $r .= $M ;
2130 else $r .= "&nbsp;" ;
2131 $r .= "</tt>" ;
2132
2133 $o = "" ;
2134 if ( $rc_last_oldid != 0 ) {
2135 $o = "oldid=".$rc_last_oldid ;
2136 }
2137 if ( $rc_type == RC_LOG ) {
2138 $link = $rcObj->timestamp ;
2139 } else {
2140 $link = $this->makeKnownLinkObj( $rcObj->getTitle(), $rcObj->timestamp , "{$curIdEq}&$o" ) ;
2141 }
2142 $link = "<tt>{$link}</tt>" ;
2143
2144 $r .= $link ;
2145 $r .= " (" ;
2146 $r .= $rcObj->curlink ;
2147 $r .= "; " ;
2148 $r .= $rcObj->lastlink ;
2149 $r .= ") . . ".$rcObj->userlink ;
2150 $r .= $rcObj->usertalklink ;
2151 if ( $rc_comment != "" ) {
2152 $rc_comment=$this->formatComment($rc_comment);
2153 $r .= $wgLang->emphasize( " (".$rc_comment.")" ) ;
2154 }
2155 $r .= "<br />\n" ;
2156 }
2157 $r .= "</div>\n" ;
2158
2159 $this->rcCacheIndex++ ;
2160 return $r ;
2161 }
2162
2163 # If enhanced RC is in use, this function takes the previously cached
2164 # RC lines, arranges them, and outputs the HTML
2165 function recentChangesBlock ()
2166 {
2167 global $wgStylePath ;
2168 if ( count ( $this->rc_cache ) == 0 ) return "" ;
2169 $blockOut = "";
2170 foreach ( $this->rc_cache AS $secureName => $block ) {
2171 if ( count ( $block ) < 2 ) {
2172 $blockOut .= $this->recentChangesBlockLine ( array_shift ( $block ) ) ;
2173 } else {
2174 $blockOut .= $this->recentChangesBlockGroup ( $block ) ;
2175 }
2176 }
2177
2178 return "<div>{$blockOut}</div>" ;
2179 }
2180
2181 # Called in a loop over all displayed RC entries
2182 # Either returns the line, or caches it for later use
2183 function recentChangesLine( &$rc, $watched = false )
2184 {
2185 global $wgUser ;
2186 $usenew = $wgUser->getOption( "usenewrc" );
2187 if ( $usenew )
2188 $line = $this->recentChangesLineNew ( $rc, $watched ) ;
2189 else
2190 $line = $this->recentChangesLineOld ( $rc, $watched ) ;
2191 return $line ;
2192 }
2193
2194 function recentChangesLineOld( &$rc, $watched = false )
2195 {
2196 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds;
2197
2198 # Extract DB fields into local scope
2199 extract( $rc->mAttribs );
2200 $curIdEq = "curid=" . $rc_cur_id;
2201
2202 # Make date header if necessary
2203 $date = $wgLang->date( $rc_timestamp, true);
2204 $s = "";
2205 if ( $date != $this->lastdate ) {
2206 if ( "" != $this->lastdate ) { $s .= "</ul>\n"; }
2207 $s .= "<h4>{$date}</h4>\n<ul class='special'>";
2208 $this->lastdate = $date;
2209 $this->rclistOpen = true;
2210 }
2211 $s .= "<li> ";
2212
2213 if ( $rc_type == RC_MOVE ) {
2214 # Diff
2215 $s .= "(" . wfMsg( "diff" ) . ") (";
2216 # Hist
2217 $s .= $this->makeKnownLinkObj( $rc->getMovedToTitle(), wfMsg( "hist" ), "action=history" ) .
2218 ") . . ";
2219
2220 # "[[x]] moved to [[y]]"
2221
2222 $s .= wfMsg( "1movedto2", $this->makeKnownLinkObj( $rc->getTitle(), "", "redirect=no" ),
2223 $this->makeKnownLinkObj( $rc->getMovedToTitle(), "" ) );
2224
2225 } else {
2226 # Diff link
2227 if ( $rc_type == RC_NEW || $rc_type == RC_LOG ) {
2228 $diffLink = wfMsg( "diff" );
2229 } else {
2230 $diffLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( "diff" ),
2231 "{$curIdEq}&diff={$rc_this_oldid}&oldid={$rc_last_oldid}" ,'' ,'' , ' tabindex="'.$rc->counter.'"');
2232 }
2233 $s .= "($diffLink) (";
2234
2235 # History link
2236 $s .= $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( "hist" ), "{$curIdEq}&action=history" );
2237 $s .= ") . . ";
2238
2239 # M and N (minor and new)
2240 $M = wfMsg( "minoreditletter" );
2241 $N = wfMsg( "newpageletter" );
2242 if ( $rc_minor ) { $s .= " <strong>{$M}</strong>"; }
2243 if ( $rc_type == RC_NEW ) { $s .= "<strong>{$N}</strong>"; }
2244
2245 # Article link
2246 $articleLink = $this->makeKnownLinkObj( $rc->getTitle(), "" );
2247
2248 if ( $watched ) {
2249 $articleLink = "<strong>{$articleLink}</strong>";
2250 }
2251 $s .= " $articleLink";
2252
2253 }
2254
2255 # Timestamp
2256 $s .= "; " . $wgLang->time( $rc_timestamp, true, $wgRCSeconds ) . " . . ";
2257
2258 # User link (or contributions for unregistered users)
2259 if ( 0 == $rc_user ) {
2260 $userLink = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
2261 $rc_user_text, "target=" . $rc_user_text );
2262 } else {
2263 $userLink = $this->makeLink( $wgLang->getNsText( NS_USER ) . ":{$rc_user_text}", $rc_user_text );
2264 }
2265 $s .= $userLink;
2266
2267 # User talk link
2268 $talkname=$wgLang->getNsText(NS_TALK); # use the shorter name
2269 global $wgDisableAnonTalk;
2270 if( 0 == $rc_user && $wgDisableAnonTalk ) {
2271 $userTalkLink = "";
2272 } else {
2273 $utns=$wgLang->getNsText(NS_USER_TALK);
2274 $userTalkLink= $this->makeLink($utns . ":{$rc_user_text}", $talkname );
2275 }
2276 # Block link
2277 $blockLink="";
2278 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2279 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2280 "Blockip" ), wfMsg( "blocklink" ), "ip={$rc_user_text}" );
2281
2282 }
2283 if($blockLink) {
2284 if($userTalkLink) $userTalkLink .= " | ";
2285 $userTalkLink .= $blockLink;
2286 }
2287 if($userTalkLink) $s.=" ({$userTalkLink})";
2288
2289 # Add comment
2290 if ( "" != $rc_comment && "*" != $rc_comment && $rc_type != RC_MOVE ) {
2291 $rc_comment=$this->formatComment($rc_comment);
2292 $s .= $wgLang->emphasize(" (" . $rc_comment . ")");
2293 }
2294 $s .= "</li>\n";
2295
2296 return $s;
2297 }
2298
2299 # function recentChangesLineNew( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched = false, $oldid = 0 , $diffid = 0 )
2300 function recentChangesLineNew( &$baseRC, $watched = false )
2301 {
2302 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds;
2303
2304 # Create a specialised object
2305 $rc = RCCacheEntry::newFromParent( $baseRC ) ;
2306
2307 # Extract fields from DB into the function scope (rc_xxxx variables)
2308 extract( $rc->mAttribs );
2309 $curIdEq = "curid=" . $rc_cur_id;
2310
2311 # If it's a new day, add the headline and flush the cache
2312 $date = $wgLang->date( $rc_timestamp, true);
2313 $ret = "" ;
2314 if ( $date != $this->lastdate ) {
2315 # Process current cache
2316 $ret = $this->recentChangesBlock () ;
2317 $this->rc_cache = array() ;
2318 $ret .= "<h4>{$date}</h4>\n";
2319 $this->lastdate = $date;
2320 }
2321
2322 # Make article link
2323 if ( $rc_type == RC_MOVE ) {
2324 $clink = $this->makeKnownLinkObj( $rc->getTitle(), "", "redirect=no" );
2325 $clink .= " " . wfMsg("movedto") . " ";
2326 $clink .= $this->makeKnownLinkObj( $rc->getMovedToTitle(), "" );
2327 } else {
2328 $clink = $this->makeKnownLinkObj( $rc->getTitle(), "" ) ;
2329 }
2330
2331 $time = $wgLang->time( $rc_timestamp, true, $wgRCSeconds );
2332 $rc->watched = $watched ;
2333 $rc->link = $clink ;
2334 $rc->timestamp = $time;
2335
2336 # Make "cur" link
2337 if ( ( $rc_type == RC_NEW && $rc_this_oldid == 0 ) || $rc_type == RC_LOG || $rc_type == RC_MOVE) {
2338 $curLink = wfMsg( "cur" );
2339 } else {
2340 $curLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( "cur" ),
2341 "{$curIdEq}&diff=0&oldid={$rc_this_oldid}" ,'' ,'' , ' tabindex="'.$baseRC->counter.'"' );
2342 }
2343
2344 # Make "last" link
2345 $titleObj = $rc->getTitle();
2346 if ( $rc_last_oldid == 0 || $rc_type == RC_LOG || $rc_type == RC_MOVE ) {
2347 $lastLink = wfMsg( "last" );
2348 } else {
2349 $lastLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( "last" ),
2350 "{$curIdEq}&diff={$rc_this_oldid}&oldid={$rc_last_oldid}" );
2351 }
2352
2353 # Make user link (or user contributions for unregistered users)
2354 if ( 0 == $rc_user ) {
2355 $userLink = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
2356 $rc_user_text, "target=" . $rc_user_text );
2357 } else {
2358 $userLink = $this->makeLink( $wgLang->getNsText(
2359 Namespace::getUser() ) . ":{$rc_user_text}", $rc_user_text );
2360 }
2361
2362 $rc->userlink = $userLink ;
2363 $rc->lastlink = $lastLink ;
2364 $rc->curlink = $curLink ;
2365
2366 # Make user talk link
2367 $utns=$wgLang->getNsText(NS_USER_TALK);
2368 $talkname=$wgLang->getNsText(NS_TALK); # use the shorter name
2369 $userTalkLink= $this->makeLink($utns . ":{$rc_user_text}", $talkname );
2370
2371 global $wgDisableAnonTalk;
2372 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2373 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2374 "Blockip" ), wfMsg( "blocklink" ), "ip={$rc_user_text}" );
2375 if( $wgDisableAnonTalk )
2376 $rc->usertalklink = " ({$blockLink})";
2377 else
2378 $rc->usertalklink = " ({$userTalkLink} | {$blockLink})";
2379 } else {
2380 if( $wgDisableAnonTalk && ($rc_user == 0) )
2381 $rc->usertalklink = "";
2382 else
2383 $rc->usertalklink = " ({$userTalkLink})";
2384 }
2385
2386 # Put accumulated information into the cache, for later display
2387 # Page moves go on their own line
2388 $title = $rc->getTitle();
2389 $secureName = $title->getPrefixedDBkey();
2390 if ( $rc_type == RC_MOVE ) {
2391 # Use an @ character to prevent collision with page names
2392 $this->rc_cache["@@" . ($this->rcMoveIndex++)] = array($rc);
2393 } else {
2394 if ( !isset ( $this->rc_cache[$secureName] ) ) $this->rc_cache[$secureName] = array() ;
2395 array_push ( $this->rc_cache[$secureName] , $rc ) ;
2396 }
2397 return $ret;
2398 }
2399
2400 function endImageHistoryList()
2401 {
2402 $s = "</ul>\n";
2403 return $s;
2404 }
2405
2406 /* This function is called by all recent changes variants, by the page history,
2407 and by the user contributions list. It is responsible for formatting edit
2408 comments. It escapes any HTML in the comment, but adds some CSS to format
2409 auto-generated comments (from section editing) and formats [[wikilinks]].
2410 Main author: Erik Möller (moeller@scireview.de)
2411 */
2412 function formatComment($comment)
2413 {
2414 global $wgLang;
2415 $comment=wfEscapeHTML($comment);
2416
2417 # The pattern for autogen comments is / * foo * /, which makes for
2418 # some nasty regex.
2419 # We look for all comments, match any text before and after the comment,
2420 # add a separator where needed and format the comment itself with CSS
2421 while (preg_match("/(.*)\/\*\s*(.*?)\s*\*\/(.*)/", $comment,$match)) {
2422 $pre=$match[1];
2423 $auto=$match[2];
2424 $post=$match[3];
2425 $sep="-";
2426 if($pre) { $auto="$sep ".$auto; }
2427 if($post) { $auto.=" $sep"; }
2428 $auto="<span class=\"autocomment\">".$auto."</span>";
2429 $comment=$pre.$auto.$post;
2430 }
2431
2432 # format regular and media links - all other wiki formatting
2433 # is ignored
2434 while(preg_match("/\[\[(.*?)(\|(.*?))*\]\]/",$comment,$match)) {
2435
2436 $medians = $wgLang->getNsText(Namespace::getMedia());
2437 $func="makeLink";
2438 if(preg_match("/^".$medians."/i",$match[1])) {
2439 $func="makeMediaLink";
2440 }
2441 if(isset($match[3]) ) {
2442 $comment=
2443 preg_replace("/\[\[(.*?)\]\]/",
2444 $this->$func($match[1],$match[3]),$comment,1);
2445 } else {
2446 $comment=
2447 preg_replace("/\[\[(.*?)\]\]/",
2448 $this->$func($match[1],$match[1]),$comment,1);
2449 }
2450 }
2451
2452 return $comment;
2453
2454 }
2455
2456 function imageHistoryLine( $iscur, $timestamp, $img, $user, $usertext, $size, $description )
2457 {
2458 global $wgUser, $wgLang, $wgTitle;
2459
2460 $datetime = $wgLang->timeanddate( $timestamp, true );
2461 $del = wfMsg( "deleteimg" );
2462 $cur = wfMsg( "cur" );
2463
2464 if ( $iscur ) {
2465 $url = Image::wfImageUrl( $img );
2466 $rlink = $cur;
2467 if ( $wgUser->isSysop() ) {
2468 $link = $wgTitle->escapeLocalURL( "image=" . $wgTitle->getPartialURL() .
2469 "&action=delete" );
2470 $style = $this->getInternalLinkAttributes( $link, $del );
2471
2472 $dlink = "<a href=\"{$link}\"{$style}>{$del}</a>";
2473 } else {
2474 $dlink = $del;
2475 }
2476 } else {
2477 $url = wfEscapeHTML( wfImageArchiveUrl( $img ) );
2478 if( $wgUser->getID() != 0 ) {
2479 $rlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2480 wfMsg( "revertimg" ), "action=revert&oldimage=" .
2481 urlencode( $img ) );
2482 $dlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2483 $del, "action=delete&oldimage=" . urlencode( $img ) );
2484 } else {
2485 # Having live active links for non-logged in users
2486 # means that bots and spiders crawling our site can
2487 # inadvertently change content. Baaaad idea.
2488 $rlink = wfMsg( "revertimg" );
2489 $dlink = $del;
2490 }
2491 }
2492 if ( 0 == $user ) {
2493 $userlink = $usertext;
2494 } else {
2495 $userlink = $this->makeLink( $wgLang->getNsText( Namespace::getUser() ) .
2496 ":{$usertext}", $usertext );
2497 }
2498 $nbytes = wfMsg( "nbytes", $size );
2499 $style = $this->getInternalLinkAttributes( $url, $datetime );
2500
2501 $s = "<li> ({$dlink}) ({$rlink}) <a href=\"{$url}\"{$style}>{$datetime}</a>"
2502 . " . . {$userlink} ({$nbytes})";
2503
2504 if ( "" != $description && "*" != $description ) {
2505 $sk=$wgUser->getSkin();
2506 $s .= $wgLang->emphasize(" (" . $sk->formatComment($description) . ")");
2507 }
2508 $s .= "</li>\n";
2509 return $s;
2510 }
2511
2512 function tocIndent($level) {
2513 return str_repeat( "<div class='tocindent'>\n", $level>0 ? $level : 0 );
2514 }
2515
2516 function tocUnindent($level) {
2517 return str_repeat( "</div>\n", $level>0 ? $level : 0 );
2518 }
2519
2520 # parameter level defines if we are on an indentation level
2521 function tocLine( $anchor, $tocline, $level ) {
2522 $link = "<a href=\"#$anchor\">$tocline</a><br />";
2523 if($level) {
2524 return "$link\n";
2525 } else {
2526 return "<div class='tocline'>$link</div>\n";
2527 }
2528
2529 }
2530
2531 function tocTable($toc) {
2532 # note to CSS fanatics: putting this in a div does not work -- div won't auto-expand
2533 # try min-width & co when somebody gets a chance
2534 $hideline = " <script type='text/javascript'>showTocToggle(\"" . addslashes( wfMsg("showtoc") ) . "\",\"" . addslashes( wfMsg("hidetoc") ) . "\")</script>";
2535 return
2536 "<table border=\"0\" id=\"toc\"><tr><td align=\"center\">\n".
2537 "<b>".wfMsg("toc")."</b>" .
2538 $hideline .
2539 "</td></tr><tr id='tocinside'><td>\n".
2540 $toc."</td></tr></table>\n";
2541 }
2542
2543 # These two do not check for permissions: check $wgTitle->userCanEdit before calling them
2544 function editSectionScript( $section, $head ) {
2545 global $wgTitle, $wgRequest;
2546 if( $wgRequest->getInt( "oldid" ) && ( $wgRequest->getVal( "diff" ) != "0" ) ) {
2547 return $head;
2548 }
2549 $url = $wgTitle->escapeLocalURL( "action=edit&section=$section" );
2550 return "<span oncontextmenu='document.location=\"$url\";return false;'>{$head}</span>";
2551 }
2552
2553 function editSectionLink( $section ) {
2554 global $wgRequest;
2555 global $wgTitle, $wgUser, $wgLang;
2556
2557 if( $wgRequest->getInt( "oldid" ) && ( $wgRequest->getVal( "diff" ) != "0" ) ) {
2558 # Section edit links would be out of sync on an old page.
2559 # But, if we're diffing to the current page, they'll be
2560 # correct.
2561 return "";
2562 }
2563
2564 $editurl = "&section={$section}";
2565 $url = $this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg("editsection"),"action=edit".$editurl);
2566
2567 if( $wgLang->isRTL() ) {
2568 $farside = "left";
2569 $nearside = "right";
2570 } else {
2571 $farside = "right";
2572 $nearside = "left";
2573 }
2574 return "<div class=\"editsection\" style=\"float:$farside;margin-$nearside:5px;\">[".$url."]</div>";
2575
2576 }
2577
2578 // This function is called by EditPage.php and shows a bulletin board style
2579 // toolbar for common editing functions. It can be disabled in the user preferences.
2580 // The necsesary JavaScript code can be found in style/wikibits.js.
2581 function getEditToolbar() {
2582 global $wgStylePath, $wgLang, $wgMimeType;
2583
2584 // toolarray an array of arrays which each include the filename of
2585 // the button image (without path), the opening tag, the closing tag,
2586 // and optionally a sample text that is inserted between the two when no
2587 // selection is highlighted.
2588 // The tip text is shown when the user moves the mouse over the button.
2589
2590 // Already here are accesskeys (key), which are not used yet until someone
2591 // can figure out a way to make them work in IE. However, we should make
2592 // sure these keys are not defined on the edit page.
2593 $toolarray=array(
2594 array( "image"=>"button_bold.png",
2595 "open"=>"\'\'\'",
2596 "close"=>"\'\'\'",
2597 "sample"=>wfMsg("bold_sample"),
2598 "tip"=>wfMsg("bold_tip"),
2599 "key"=>"B"
2600 ),
2601 array( "image"=>"button_italic.png",
2602 "open"=>"\'\'",
2603 "close"=>"\'\'",
2604 "sample"=>wfMsg("italic_sample"),
2605 "tip"=>wfMsg("italic_tip"),
2606 "key"=>"I"
2607 ),
2608 array( "image"=>"button_link.png",
2609 "open"=>"[[",
2610 "close"=>"]]",
2611 "sample"=>wfMsg("link_sample"),
2612 "tip"=>wfMsg("link_tip"),
2613 "key"=>"L"
2614 ),
2615 array( "image"=>"button_extlink.png",
2616 "open"=>"[",
2617 "close"=>"]",
2618 "sample"=>wfMsg("extlink_sample"),
2619 "tip"=>wfMsg("extlink_tip"),
2620 "key"=>"X"
2621 ),
2622 array( "image"=>"button_headline.png",
2623 "open"=>"\\n== ",
2624 "close"=>" ==\\n",
2625 "sample"=>wfMsg("headline_sample"),
2626 "tip"=>wfMsg("headline_tip"),
2627 "key"=>"H"
2628 ),
2629 array( "image"=>"button_image.png",
2630 "open"=>"[[".$wgLang->getNsText(NS_IMAGE).":",
2631 "close"=>"]]",
2632 "sample"=>wfMsg("image_sample"),
2633 "tip"=>wfMsg("image_tip"),
2634 "key"=>"D"
2635 ),
2636 array( "image"=>"button_media.png",
2637 "open"=>"[[".$wgLang->getNsText(NS_MEDIA).":",
2638 "close"=>"]]",
2639 "sample"=>wfMsg("media_sample"),
2640 "tip"=>wfMsg("media_tip"),
2641 "key"=>"M"
2642 ),
2643 array( "image"=>"button_math.png",
2644 "open"=>"\\<math\\>",
2645 "close"=>"\\</math\\>",
2646 "sample"=>wfMsg("math_sample"),
2647 "tip"=>wfMsg("math_tip"),
2648 "key"=>"C"
2649 ),
2650 array( "image"=>"button_nowiki.png",
2651 "open"=>"\\<nowiki\\>",
2652 "close"=>"\\</nowiki\\>",
2653 "sample"=>wfMsg("nowiki_sample"),
2654 "tip"=>wfMsg("nowiki_tip"),
2655 "key"=>"N"
2656 ),
2657 array( "image"=>"button_sig.png",
2658 "open"=>"--~~~~",
2659 "close"=>"",
2660 "sample"=>"",
2661 "tip"=>wfMsg("sig_tip"),
2662 "key"=>"Y"
2663 ),
2664 array( "image"=>"button_hr.png",
2665 "open"=>"\\n----\\n",
2666 "close"=>"",
2667 "sample"=>"",
2668 "tip"=>wfMsg("hr_tip"),
2669 "key"=>"R"
2670 )
2671 );
2672 $toolbar ="<script type='text/javascript'>\n/*<![CDATA[*/\n";
2673
2674 $toolbar.="document.writeln(\"<div id='toolbar'>\");\n";
2675 foreach($toolarray as $tool) {
2676
2677 $image=$wgStylePath."/images/".$tool["image"];
2678 $open=$tool["open"];
2679 $close=$tool["close"];
2680 $sample = addslashes( $tool["sample"] );
2681
2682 // Note that we use the tip both for the ALT tag and the TITLE tag of the image.
2683 // Older browsers show a "speedtip" type message only for ALT.
2684 // Ideally these should be different, realistically they
2685 // probably don't need to be.
2686 $tip = addslashes( $tool["tip"] );
2687
2688 #$key = $tool["key"];
2689
2690 $toolbar.="addButton('$image','$tip','$open','$close','$sample');\n";
2691 }
2692
2693 $toolbar.="addInfobox('" . addslashes( wfMsg( "infobox" ) ) . "','" . addslashes(wfMsg("infobox_alert")) . "');\n";
2694 $toolbar.="document.writeln(\"</div>\");\n";
2695
2696 $toolbar.="/*]]>*/\n</script>";
2697 return $toolbar;
2698 }
2699
2700 // Return a new cardset.
2701 // By overloading this function, Skins can alter the appearance of e.g. the preferences
2702 function newCardSet( $title = "")
2703 {
2704 return new CardSet( $title );
2705 }
2706 }
2707
2708 require_once( "SkinStandard.php" );
2709 require_once( "SkinNostalgia.php" );
2710 require_once( "SkinCologneBlue.php" );
2711
2712 if( $wgUsePHPTal ) {
2713 require_once( "SkinPHPTal.php" );
2714 }
2715
2716
2717 ?>