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