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