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