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