'View source' link instead of 'protected page'
[lhc/web/wiklou.git] / includes / Skin.php
1 <?
2 # See skin.doc
3
4 # These are the INTERNAL names, which get mapped
5 # directly to class names. For display purposes, the
6 # Language class has internationalized names
7 #
8 /* private */ $wgValidSkinNames = array(
9 "Standard", "Nostalgia", "CologneBlue" #, "Smarty", "Montparnasse"
10 );
11
12 # For some odd PHP bug, this function can't be part of a class
13 function getCategories ()
14 {
15 global $wgOut , $wgTitle , $wgUseCategoryMagic , $wgUser ;
16 if ( !isset ( $wgUseCategoryMagic ) || !$wgUseCategoryMagic ) return "" ;
17 if ( count ( $wgOut->mCategoryLinks ) == 0 ) return "" ;
18 if ( !$wgOut->isArticle() ) return "" ;
19 $sk = $wgUser->getSkin() ;
20 $s = "" ;
21 $s .= "\n<br>\n";
22 $s .= $sk->makeKnownLink ( "Special:Categories" , "Categories" , "article=".$wgTitle->getDBkey() ) ;
23 $t = implode ( " | " , $wgOut->mCategoryLinks ) ;
24 if ( $t != "" ) $s .= " : " ;
25 $s .= $t ;
26 return $s ;
27 }
28
29
30 class RecentChangesClass {
31 var $secureName , $displayName , $link , $namespace ;
32 var $oldid , $diffid , $timestamp , $curlink , $lastlink , $usertalklink , $versionlink ;
33 var $usercomment , $userlink ;
34 var $isminor , $isnew , $watched , $islog ;
35 } ;
36
37 class Skin {
38
39 /* private */ var $lastdate, $lastline;
40
41 var $rc_cache ; # Cache for Enhanced Recent Changes
42 var $rccc ; # Recent Changes Cache Counter for visibility toggle
43
44
45 function Skin()
46 {
47 }
48
49 function getSkinNames()
50 {
51 global $wgValidSkinNames;
52 return $wgValidSkinNames;
53 }
54
55 function getStylesheet()
56 {
57 return "wikistandard.css";
58 }
59
60 function qbSetting()
61 {
62 global $wgOut, $wgUser;
63
64 if ( $wgOut->isQuickbarSupressed() ) { return 0; }
65 $q = $wgUser->getOption( "quickbar" );
66 if ( "" == $q ) { $q = 0; }
67 return $q;
68 }
69
70 function initPage()
71 {
72 global $wgOut, $wgStyleSheetPath;
73 $fname = "Skin::initPage";
74 wfProfileIn( $fname );
75
76 $wgOut->addLink( "shortcut icon", "", "/favicon.ico" );
77 if ( $wgOut->isPrintable() ) { $ss = "wikiprintable.css"; }
78 else { $ss = $this->getStylesheet(); }
79 $wgOut->addLink( "stylesheet", "", "{$wgStyleSheetPath}/{$ss}" );
80 wfProfileOut( $fname );
81 }
82
83 function outputPage( &$out ) {
84 wfProfileIn( "Skin::outputPage" );
85 $this->initPage();
86 $out->out( $out->headElement() );
87
88 $out->out( "\n<body" );
89 $ops = $this->getBodyOptions();
90 foreach ( $ops as $name => $val ) {
91 $out->out( " $name='$val'" );
92 }
93 $out->out( ">\n" );
94 if ( $wgDebugComments ) {
95 $out->out( "<!-- Wiki debugging output:\n" .
96 $out->mDebugtext . "-->\n" );
97 }
98 $out->out( $this->beforeContent() );
99
100 $out->out( $out->mBodytext );
101
102 $out->out( $this->afterContent() );
103
104 wfProfileClose();
105 $out->out( $out->reportTime() );
106
107 $out->out( "\n</body></html>" );
108 }
109
110 function getHeadScripts() {
111 global $wgStyleSheetPath;
112 $r = "<script type=\"text/javascript\" src=\"{$wgStyleSheetPath}/wikibits.js\"></script>\n";
113 return $r;
114 }
115
116 function getUserStyles()
117 {
118 $s = "<style type='text/css'><!--\n";
119 $s .= $this->doGetUserStyles();
120 $s .= "//--></style>\n";
121 return $s;
122 }
123
124 function doGetUserStyles()
125 {
126 global $wgUser;
127
128 $s = "";
129 if ( 1 == $wgUser->getOption( "underline" ) ) {
130 # Don't override browser settings
131 } else {
132 # CHECK MERGE @@@
133 # Force no underline
134 $s .= "a.stub, a.new, a.internal, a.external { " .
135 "text-decoration: none; }\n";
136 }
137 if ( 1 == $wgUser->getOption( "highlightbroken" ) ) {
138 $s .= "a.new, #quickbar a.new { color: #CC2200; }\n";
139 }
140 if ( 1 == $wgUser->getOption( "justify" ) ) {
141 $s .= "#article { text-align: justify; }\n";
142 }
143 return $s;
144 }
145
146 function getBodyOptions()
147 {
148 global $wgUser, $wgTitle, $wgNamespaceBackgrounds, $wgOut, $oldid, $redirect, $diff,$action;
149
150 if ( 0 != $wgTitle->getNamespace() ) {
151 $a = array( "bgcolor" => "#ffffec" );
152 }
153 else $a = array( "bgcolor" => "#FFFFFF" );
154 if($wgOut->isArticle() && $wgUser->getOption("editondblclick")
155 &&
156 (!$wgTitle->isProtected() || $wgUser->isSysop())
157
158 ) {
159 $n = $wgTitle->getPrefixedURL();
160 $t = wfMsg( "editthispage" );
161 $oid = $red = "";
162 if ( $redirect ) { $red = "&redirect={$redirect}"; }
163 if ( $oldid && ! isset( $diff ) ) {
164 $oid = "&oldid={$oldid}";
165 }
166 $s = wfLocalUrlE($n,"action=edit{$oid}{$red}");
167 $s = "document.location = \"" .$s ."\";";
168 $a += array ("ondblclick" => $s);
169
170 }
171 $a['onload'] = $wgOut->getOnloadHandler();
172 return $a;
173 }
174
175 function getExternalLinkAttributes( $link, $text )
176 {
177 global $wgUser, $wgOut, $wgLang;
178
179 $link = urldecode( $link );
180 $link = $wgLang->checkTitleEncoding( $link );
181 $link = str_replace( "_", " ", $link );
182 $link = wfEscapeHTML( $link );
183
184 if ( $wgOut->isPrintable() ) { $r = " class='printable'"; }
185 else { $r = " class='external'"; }
186
187 if ( 1 == $wgUser->getOption( "hover" ) ) {
188 $r .= " title=\"{$link}\"";
189 }
190 return $r;
191 }
192
193 function getInternalLinkAttributes( $link, $text, $broken = false )
194 {
195 global $wgUser, $wgOut;
196
197 $link = urldecode( $link );
198 $link = str_replace( "_", " ", $link );
199 $link = wfEscapeHTML( $link );
200
201 if ( $wgOut->isPrintable() ) {
202 $r = " class='printable'";
203 } else if ( $broken == "stub" ) {
204 $r = " class='stub'";
205 } else if ( $broken == "yes" ) {
206 $r = " class='new'";
207 } else {
208 $r = " class='internal'";
209 }
210
211 if ( 1 == $wgUser->getOption( "hover" ) ) {
212 $r .= " title=\"{$link}\"";
213 }
214 return $r;
215 }
216
217 function getInternalLinkAttributesObj( &$nt, $text, $broken = false )
218 {
219 global $wgUser, $wgOut;
220
221 if ( $wgOut->isPrintable() ) {
222 $r = " class='printable'";
223 } else if ( $broken == "stub" ) {
224 $r = " class='stub'";
225 } else if ( $broken == "yes" ) {
226 $r = " class='new'";
227 } else {
228 $r = " class='internal'";
229 }
230
231 if ( 1 == $wgUser->getOption( "hover" ) ) {
232 $r .= ' title ="' . $nt->getEscapedText() . '"';
233 }
234 return $r;
235 }
236
237 function getLogo()
238 {
239 global $wgLogo;
240 return $wgLogo;
241 }
242
243 # This will be called immediately after the <body> tag. Split into
244 # two functions to make it easier to subclass.
245 #
246 function beforeContent()
247 {
248 global $wgUser, $wgOut, $wgSiteNotice;
249
250 if ( $wgOut->isPrintable() ) {
251 $s = $this->pageTitle() . $this->pageSubtitle() . "\n";
252 $s .= "\n<div class='bodytext'>";
253 return $s;
254 }
255 if( $wgSiteNotice ) {
256 $note = "\n<div id='notice' style='font-weight: bold; color: red; text-align: center'>$wgSiteNotice</div>\n";
257 } else {
258 $note = "";
259 }
260 return $this->doBeforeContent() . $note;
261 }
262
263 function doBeforeContent()
264 {
265 global $wgUser, $wgOut, $wgTitle, $wgLang;
266 $fname = "Skin::doBeforeContent";
267 wfProfileIn( $fname );
268
269 $s = "";
270 $qb = $this->qbSetting();
271
272 if( $langlinks = $this->otherLanguages() ) {
273 $rows = 2;
274 $borderhack = "";
275 } else {
276 $rows = 1;
277 $langlinks = false;
278 $borderhack = "class='top'";
279 }
280
281 $s .= "\n<div id='content'>\n<div id='topbar'>" .
282 "<table width='98%' border=0 cellspacing=0><tr>";
283
284 $shove = ($qb != 0);
285 $left = ($qb == 1 || $qb == 3);
286 if($wgLang->isRTL()) $left = !$left;
287
288 if ( !$shove ) {
289 $s .= "<td class='top' align=left valign=top rowspan='{$rows}'>" .
290 $this->logoText() . "</td>";
291 } elseif( $left ) {
292 $s .= $this->getQuickbarCompensator( $rows );
293 }
294 $l = $wgLang->isRTL() ? "right" : "left";
295 $s .= "<td {$borderhack} align='$l' valign='top'>";
296
297 $s .= $this->topLinks() ;
298 $s .= "<p class='subtitle'>" . $this->pageTitleLinks();
299
300 $r = $wgLang->isRTL() ? "left" : "right";
301 $s .= "</td>\n<td {$borderhack} valign='top' align='$r' nowrap>";
302 $s .= $this->nameAndLogin();
303 $s .= "\n<br>" . $this->searchForm() . "</td>";
304
305 if ( $langlinks ) {
306 $s .= "</tr>\n<tr><td class='top' colspan=\"2\">$langlinks</td>";
307 }
308
309 if ( $shove && !$left ) { # Right
310 $s .= $this->getQuickbarCompensator( $rows );
311 }
312 $s .= "</tr></table>\n</div>\n";
313 $s .= "\n<div id='article'>";
314
315 $s .= $this->pageTitle();
316 $s .= $this->pageSubtitle() ;
317 $s .= getCategories(); // For some odd reason, zhis can't be a function of the object
318 $s .= "\n<p>";
319 wfProfileOut( $fname );
320 return $s;
321 }
322
323 function getQuickbarCompensator( $rows = 1 )
324 {
325 return "<td width='152' rowspan='{$rows}'>&nbsp;</td>";
326 }
327
328 # This gets called immediately before the </body> tag.
329 #
330 function afterContent()
331 {
332 global $wgUser, $wgOut, $wgServer;
333 global $wgTitle;
334
335 if ( $wgOut->isPrintable() ) {
336 $s = "\n</div>\n";
337
338 $u = htmlspecialchars( $wgServer . $wgTitle->getFullURL() );
339 $u = "<a href=\"$u\">$u</a>";
340 $rf = wfMsg( "retrievedfrom", $u );
341
342 if ( $wgOut->isArticle() ) {
343 $lm = "<br>" . $this->lastModified();
344 } else { $lm = ""; }
345
346 $cr = wfMsg( "gnunote" );
347 $s .= "<p><em>{$rf}{$lm} {$cr}</em>\n";
348 return $s;
349 }
350 return $this->doAfterContent();
351 }
352
353 function doAfterContent()
354 {
355 global $wgUser, $wgOut, $wgLang;
356 $fname = "Skin::doAfterContent";
357 wfProfileIn( $fname );
358 wfProfileIn( "$fname-1" );
359
360 $s = "\n</div><br clear=all>\n";
361 $s .= "\n<div id='footer'>";
362 $s .= "<table width='98%' border=0 cellspacing=0><tr>";
363
364 wfProfileOut( "$fname-1" );
365 wfProfileIn( "$fname-2" );
366
367 $qb = $this->qbSetting();
368 $shove = ($qb != 0);
369 $left = ($qb == 1 || $qb == 3);
370 if($wgLang->isRTL()) $left = !$left;
371
372 if ( $shove && $left ) { # Left
373 $s .= $this->getQuickbarCompensator();
374 }
375 wfProfileOut( "$fname-2" );
376 wfProfileIn( "$fname-3" );
377 $l = $wgLang->isRTL() ? "right" : "left";
378 $s .= "<td class='bottom' align='$l' valign='top'>";
379
380 $s .= $this->bottomLinks();
381 $s .= "\n<br>" . $this->mainPageLink()
382 . " | " . $this->aboutLink()
383 . " | " . $this->specialLink( "recentchanges" )
384 . " | " . $this->searchForm()
385 . "<br>" . $this->pageStats();
386
387 $s .= "</td>";
388 if ( $shove && !$left ) { # Right
389 $s .= $this->getQuickbarCompensator();
390 }
391 $s .= "</tr></table>\n</div>\n</div>\n";
392
393 wfProfileOut( "$fname-3" );
394 wfProfileIn( "$fname-4" );
395 if ( 0 != $qb ) { $s .= $this->quickBar(); }
396 wfProfileOut( "$fname-4" );
397 wfProfileOut( $fname );
398 return $s;
399 }
400
401 function pageTitleLinks()
402 {
403 global $wgOut, $wgTitle, $oldid, $action, $diff, $wgUser, $wgLang, $wgUseApproval ;
404
405 $s = $this->printableLink();
406
407 if ( $wgOut->isArticle() ) {
408 if ( $wgTitle->getNamespace() == Namespace::getImage() ) {
409 $name = $wgTitle->getDBkey();
410 $link = wfEscapeHTML( wfImageUrl( $name ) );
411 $style = $this->getInternalLinkAttributes( $link, $name );
412 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>";
413 }
414 # This will show the "Approve" link if $wgUseApproval=true;
415 if ( isset ( $wgUseApproval ) && $wgUseApproval )
416 {
417 $t = $wgTitle->getDBkey();
418 $name = "Approve this article" ;
419 $link = "http://test.wikipedia.org/w/magnus/wiki.phtml?title={$t}&action=submit&doit=1" ;
420 #wfEscapeHTML( wfImageUrl( $name ) );
421 $style = $this->getExternalLinkAttributes( $link, $name );
422 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>" ;
423 } }
424 if ( "history" == $action || isset( $diff ) || isset( $oldid ) ) {
425 $s .= " | " . $this->makeKnownLink( $wgTitle->getPrefixedText(),
426 wfMsg( "currentrev" ) );
427 }
428
429 if ( $wgUser->getNewtalk() ) {
430 # do not show "You have new messages" text when we are viewing our
431 # own talk page
432
433 if(!(strcmp($wgTitle->getText(),$wgUser->getName()) == 0 &&
434 $wgTitle->getNamespace()==Namespace::getTalk(Namespace::getUser()))) {
435 $n =$wgUser->getName();
436 $tl = $this->makeKnownLink( $wgLang->getNsText(
437 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
438 wfMsg("newmessageslink") );
439 $s.=" | <strong>". wfMsg( "newmessages", $tl ) . "</strong>";
440 }
441 }
442 if( $wgUser->isSysop() &&
443 (($wgTitle->getArticleId() == 0) || ($action == "history")) &&
444 ($n = $wgTitle->isDeleted() ) ) {
445 $s .= " | " . wfMsg( "thisisdeleted",
446 $this->makeKnownLink(
447 $wgLang->SpecialPage( "Undelete/" . $wgTitle->getPrefixedDBkey() ),
448 wfMsg( "restorelink", $n ) ) );
449 }
450 return $s;
451 }
452
453 function printableLink()
454 {
455 global $wgOut, $wgTitle, $oldid, $action;
456
457 $q = "";
458 foreach( $_GET as $var => $val ) {
459 if( $var != "title" && $var != "printable" )
460 $q .= urlencode( $var ) . "=" . urlencode( $val );
461 }
462 if( !empty( $q ) ) $q .= "&";
463
464 $s = $this->makeKnownLink( $wgTitle->getPrefixedText(),
465 WfMsg( "printableversion" ), "{$q}printable=yes" );
466 return $s;
467 }
468
469 function pageTitle()
470 {
471 global $wgOut, $wgTitle, $wgUser;
472
473 $s = "<h1 class='pagetitle'>" . $wgOut->getPageTitle() . "</h1>";
474 if($wgUser->getOption("editsectiononrightclick") && $wgTitle->userCanEdit()) { $s=$this->editSectionScript(0,$s);}
475 return $s;
476 }
477
478 function pageSubtitle()
479 {
480 global $wgOut,$wgTitle,$wgNamespacesWithSubpages;
481
482 $sub = $wgOut->getSubtitle();
483 if ( "" == $sub ) {
484 global $wgExtraSubtitle;
485 $sub = wfMsg( "fromwikipedia" ) . $wgExtraSubtitle;
486 }
487 if($wgOut->isArticle() && $wgNamespacesWithSubpages[$wgTitle->getNamespace()]) {
488 $ptext=$wgTitle->getPrefixedText();
489 if(preg_match("/\//",$ptext)) {
490 $sub.="</p><p class='subpages'>";
491 $links=explode("/",$ptext);
492 $c=0;
493 $growinglink="";
494 foreach($links as $link) {
495 $c++;
496 if ($c<count($links)) {
497 $growinglink .= $link;
498 $getlink = $this->makeLink( $growinglink, $link );
499 if(preg_match("/class='new'/i",$getlink)) { break; } # this is a hack, but it saves time
500 if ($c>1) {
501 $sub .= " | ";
502 } else {
503 $sub .="&lt; ";
504 }
505 $sub .= $getlink;
506 $growinglink.="/";
507 }
508
509 }
510 }
511 }
512 $s = "<p class='subtitle'>{$sub}\n";
513 return $s;
514 }
515
516 function nameAndLogin()
517 {
518 global $wgUser, $wgTitle, $wgLang, $wgShowIPinHeader;
519
520 $li = $wgLang->specialPage( "Userlogin" );
521 $lo = $wgLang->specialPage( "Userlogout" );
522
523 $s = "";
524 if ( 0 == $wgUser->getID() ) {
525 if( $wgShowIPinHeader ) {
526 $n = getenv( "REMOTE_ADDR" );
527
528 $tl = $this->makeKnownLink( $wgLang->getNsText(
529 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
530 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
531
532 $s .= $n . " (".$tl.")";
533 } else {
534 $s .= wfMsg("notloggedin");
535 }
536
537 $rt = $wgTitle->getPrefixedURL();
538 if ( 0 == strcasecmp( urlencode( $lo ), $rt ) ) {
539 $q = "";
540 } else { $q = "returnto={$rt}"; }
541
542 $s .= "\n<br>" . $this->makeKnownLink( $li,
543 wfMsg( "login" ), $q );
544 } else {
545 $n = $wgUser->getName();
546 $rt = $wgTitle->getPrefixedURL();
547 $tl = $this->makeKnownLink( $wgLang->getNsText(
548 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
549 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
550
551 $tl = " ({$tl})";
552
553 $s .= $this->makeKnownLink( $wgLang->getNsText(
554 Namespace::getUser() ) . ":{$n}", $n ) . "{$tl}<br>" .
555 $this->makeKnownLink( $lo, wfMsg( "logout" ),
556 "returnto={$rt}" ) . " | " .
557 $this->specialLink( "preferences" );
558 }
559 $s .= " | " . $this->makeKnownLink( wfMsg( "helppage" ),
560 wfMsg( "help" ) );
561
562 return $s;
563 }
564
565 function searchForm()
566 {
567 global $search;
568
569 $s = "<form name='search' class='inline' method=get action=\""
570 . wfLocalUrl( "" ) . "\">"
571 . "<input type=text name=\"search\" size=19 value=\""
572 . htmlspecialchars(substr($search,0,256)) . "\">\n"
573 . "<input type=submit name=\"go\" value=\"" . wfMsg ("go") . "\">&nbsp;"
574 . "<input type=submit value=\"" . wfMsg ("search") . "\"></form>";
575
576 return $s;
577 }
578
579 function topLinks()
580 {
581 global $wgOut;
582 $sep = " |\n";
583
584 $s = $this->mainPageLink() . $sep
585 . $this->specialLink( "recentchanges" );
586
587 if ( $wgOut->isArticle() ) {
588 $s .= $sep . $this->editThisPage()
589 . $sep . $this->historyLink();
590 }
591 # Many people don't like this dropdown box
592 #$s .= $sep . $this->specialPagesList();
593
594 return $s;
595 }
596
597 function bottomLinks()
598 {
599 global $wgOut, $wgUser, $wgTitle;
600 $sep = " |\n";
601
602 $s = "";
603 if ( $wgOut->isArticle() ) {
604 $s .= "<strong>" . $this->editThisPage() . "</strong>";
605 if ( 0 != $wgUser->getID() ) {
606 $s .= $sep . $this->watchThisPage();
607 }
608 $s .= $sep . $this->talkLink()
609 . $sep . $this->historyLink()
610 . $sep . $this->whatLinksHere()
611 . $sep . $this->watchPageLinksLink();
612
613 if ( $wgTitle->getNamespace() == Namespace::getUser()
614 || $wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser()) )
615
616 {
617 $id=User::idFromName($wgTitle->getText());
618 $ip=User::isIP($wgTitle->getText());
619
620 if($id || $ip) { # both anons and non-anons have contri list
621 $s .= $sep . $this->userContribsLink();
622 }
623 if ( 0 != $wgUser->getID() ) { # show only to signed in users
624 if($id) { # can only email non-anons
625 $s .= $sep . $this->emailUserLink();
626 }
627 }
628 }
629 if ( $wgUser->isSysop() && $wgTitle->getArticleId() ) {
630 $s .= "\n<br>" . $this->deleteThisPage() .
631 $sep . $this->protectThisPage() .
632 $sep . $this->moveThisPage();
633 }
634 $s .= "<br>\n" . $this->otherLanguages();
635 }
636 return $s;
637 }
638
639 function pageStats()
640 {
641 global $wgOut, $wgLang, $wgArticle;
642 global $oldid, $diff, $wgDisableCounters;
643
644 if ( ! $wgOut->isArticle() ) { return ""; }
645 if ( isset( $oldid ) || isset( $diff ) ) { return ""; }
646 if ( 0 == $wgArticle->getID() ) { return ""; }
647
648 if ( $wgDisableCounters ) {
649 $s = "";
650 } else {
651 $count = $wgArticle->getCount();
652 $s = wfMsg( "viewcount", $count );
653 }
654 $s .= $this->lastModified();
655 $s .= " " . wfMsg( "gnunote" );
656 return "<span id='pagestats'>{$s}</span>";
657 }
658
659 function lastModified()
660 {
661 global $wgLang, $wgArticle;
662
663 $d = $wgLang->timeanddate( $wgArticle->getTimestamp(), true );
664 $s = " " . wfMsg( "lastmodified", $d );
665 return $s;
666 }
667
668 function logoText( $align = "" )
669 {
670 if ( "" != $align ) { $a = " align='{$align}'"; }
671 else { $a = ""; }
672
673 $mp = wfMsg( "mainpage" );
674 $s = "<a href=\"" . wfLocalUrlE( urlencode( $mp ) )
675 . "\"><img{$a} border=0 src=\""
676 . $this->getLogo() . "\" alt=\"" . "[{$mp}]\"></a>";
677 return $s;
678 }
679
680 function quickBar()
681 {
682 global $wgOut, $wgTitle, $wgUser, $action, $wgLang;
683 global $wpPreview, $wgDisableUploads;
684
685 $fname = "Skin::quickBar";
686 wfProfileIn( $fname );
687
688 $tns=$wgTitle->getNamespace();
689
690 $s = "\n<div id='quickbar'>";
691 $s .= "\n" . $this->logoText() . "\n<hr class='sep'>";
692
693 $sep = "\n<br>";
694 $s .= $this->mainPageLink()
695 . $sep . $this->specialLink( "recentchanges" )
696 . $sep . $this->specialLink( "randompage" );
697 if ($wgUser->getID()) {
698 $s.= $sep . $this->specialLink( "watchlist" ) ;
699 $s .= $sep .$this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
700 wfMsg( "mycontris" ), "target=" . wfUrlencode($wgUser->getName() ) );
701
702 }
703 // only show watchlist link if logged in
704 if ( wfMsg ( "currentevents" ) != "-" ) $s .= $sep . $this->makeKnownLink( wfMsg( "currentevents" ), "" ) ;
705 $s .= "\n<br><hr class='sep'>";
706 $articleExists = $wgTitle->getArticleId();
707 if ( $wgOut->isArticle() || $action =="edit" || $action =="history" || $wpPreview) {
708 if($wgOut->isArticle()) {
709 $s .= "<strong>" . $this->editThisPage() . "</strong>";
710 } else { # backlink to the article in edit or history mode
711 if($articleExists){ # no backlink if no article
712 switch($tns) {
713 case 0:
714 $text = wfMsg("articlepage");
715 break;
716 case 1:
717 $text = wfMsg("viewtalkpage");
718 break;
719 case 2:
720 $text = wfMsg("userpage");
721 break;
722 case 3:
723 $text = wfMsg("viewtalkpage");
724 break;
725 case 4:
726 $text = wfMsg("wikipediapage");
727 break;
728 case 5:
729 $text = wfMsg("viewtalkpage");
730 break;
731 case 6:
732 $text = wfMsg("imagepage");
733 break;
734 case 7:
735 $text = wfMsg("viewtalkpage");
736 break;
737 default:
738 $text= wfMsg("articlepage");
739 }
740
741 $link = $wgTitle->getText();
742 if ($nstext = $wgLang->getNsText($tns) ) { # add namespace if necessary
743 $link = $nstext . ":" . $link ;
744 }
745
746 $s .= $this->makeLink( $link, $text );
747 } elseif( $wgTitle->getNamespace() != Namespace::getSpecial() ) {
748 # we just throw in a "New page" text to tell the user that he's in edit mode,
749 # and to avoid messing with the separator that is prepended to the next item
750 $s .= "<strong>" . wfMsg("newpage") . "</strong>";
751 }
752
753 }
754
755
756 if( $tns%2 && $action!="edit" && !$wpPreview) {
757 $s.="<br>".$this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg("postcomment"),"action=edit&section=new");
758 }
759
760 /*
761 watching could cause problems in edit mode:
762 if user edits article, then loads "watch this article" in background and then saves
763 article with "Watch this article" checkbox disabled, the article is transparently
764 unwatched. Therefore we do not show the "Watch this page" link in edit mode
765 */
766 if ( 0 != $wgUser->getID() && $articleExists) {
767 if($action!="edit" && $action!="history" &&
768 $action != "submit" )
769 {
770 $s .= $sep . $this->watchThisPage();
771 }
772 if ( $wgTitle->userCanEdit() )
773 $s .= $sep . $this->moveThisPage();
774 }
775 if ( $wgUser->isSysop() and $articleExists ) {
776 $s .= $sep . $this->deleteThisPage() .
777 $sep . $this->protectThisPage();
778 }
779 $s .= $sep . $this->talkLink();
780 if ($articleExists && $action !="history") {
781 $s .= $sep . $this->historyLink();
782 }
783 $s.=$sep . $this->whatLinksHere();
784
785 if($wgOut->isArticle()) {
786 $s .= $sep . $this->watchPageLinksLink();
787 }
788
789 if ( Namespace::getUser() == $wgTitle->getNamespace()
790 || $wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser())
791 ) {
792
793 $id=User::idFromName($wgTitle->getText());
794 $ip=User::isIP($wgTitle->getText());
795
796 if($id||$ip) {
797 $s .= $sep . $this->userContribsLink();
798 }
799 if ( 0 != $wgUser->getID() ) {
800 if($id) { # can only email real users
801 $s .= $sep . $this->emailUserLink();
802 }
803 }
804 }
805 $s .= "\n<br><hr class='sep'>";
806 }
807
808 if ( 0 != $wgUser->getID() && !$wgDisableUploads ) {
809 $s .= $this->specialLink( "upload" ) . $sep;
810 }
811 $s .= $this->specialLink( "specialpages" )
812 . $sep . $this->bugReportsLink();
813
814 global $wgSiteSupportPage;
815 if( $wgSiteSupportPage ) {
816 $s .= "\n<br><a href=\"" . htmlspecialchars( $wgSiteSupportPage ) .
817 "\" class=\"internal\">" . wfMsg( "sitesupport" ) . "</a>";
818 }
819
820 $s .= "\n<br></div>\n";
821 wfProfileOut( $fname );
822 return $s;
823 }
824
825 function specialPagesList()
826 {
827 global $wgUser, $wgOut, $wgLang, $wgServer, $wgRedirectScript;
828 $a = array();
829
830 $validSP = $wgLang->getValidSpecialPages();
831
832 foreach ( $validSP as $name => $desc ) {
833 if ( "" == $desc ) { continue; }
834 $a[$name] = $desc;
835 }
836 if ( $wgUser->isSysop() )
837 {
838 $sysopSP = $wgLang->getSysopSpecialPages();
839
840 foreach ( $sysopSP as $name => $desc ) {
841 if ( "" == $desc ) { continue; }
842 $a[$name] = $desc ;
843 }
844 }
845 if ( $wgUser->isDeveloper() )
846 {
847 $devSP = $wgLang->getDeveloperSpecialPages();
848
849 foreach ( $devSP as $name => $desc ) {
850 if ( "" == $desc ) { continue; }
851 $a[$name] = $desc ;
852 }
853 }
854 $go = wfMsg( "go" );
855 $sp = wfMsg( "specialpages" );
856 $spp = $wgLang->specialPage( "Specialpages" );
857
858 $s = "<form id=\"specialpages\" method=\"get\" class=\"inline\" " .
859 "action=\"{$wgServer}{$wgRedirectScript}\">\n";
860 $s .= "<select name=\"wpDropdown\">\n";
861 $s .= "<option value=\"{$spp}\">{$sp}</option>\n";
862
863 foreach ( $a as $name => $desc ) {
864 $p = $wgLang->specialPage( $name );
865 $s .= "<option value=\"{$p}\">{$desc}</option>\n";
866 }
867 $s .= "</select>\n";
868 $s .= "<input type=submit value=\"{$go}\" name=redirect>\n";
869 $s .= "</form>\n";
870 return $s;
871 }
872
873 function mainPageLink()
874 {
875 $mp = wfMsg( "mainpage" );
876 $s = $this->makeKnownLink( $mp, $mp );
877 return $s;
878 }
879
880 function copyrightLink()
881 {
882 $s = $this->makeKnownLink( wfMsg( "copyrightpage" ),
883 wfMsg( "copyrightpagename" ) );
884 return $s;
885 }
886
887 function aboutLink()
888 {
889 $s = $this->makeKnownLink( wfMsg( "aboutpage" ),
890 wfMsg( "aboutwikipedia" ) );
891 return $s;
892 }
893
894 function editThisPage()
895 {
896 global $wgOut, $wgTitle, $oldid, $redirect, $diff;
897
898 if ( ! $wgOut->isArticle() || $diff ) {
899 $s = wfMsg( "protectedpage" );
900 } else {
901 $n = $wgTitle->getPrefixedText();
902 if ( $wgTitle->userCanEdit() ) {
903 $t = wfMsg( "editthispage" );
904 } else {
905 #$t = wfMsg( "protectedpage" );
906 $t = wfMsg( "viewsource" );
907 }
908 $oid = $red = "";
909
910 if ( $redirect ) { $red = "&redirect={$redirect}"; }
911 if ( $oldid && ! isset( $diff ) ) {
912 $oid = "&oldid={$oldid}";
913 }
914 $s = $this->makeKnownLink( $n, $t, "action=edit{$oid}{$red}" );
915 }
916 return $s;
917 }
918
919 function deleteThisPage()
920 {
921 global $wgUser, $wgOut, $wgTitle, $diff;
922
923 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
924 $n = $wgTitle->getPrefixedText();
925 $t = wfMsg( "deletethispage" );
926
927 $s = $this->makeKnownLink( $n, $t, "action=delete" );
928 } else {
929 $s = "";
930 }
931 return $s;
932 }
933
934 function protectThisPage()
935 {
936 global $wgUser, $wgOut, $wgTitle, $diff;
937
938 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
939 $n = $wgTitle->getPrefixedText();
940
941 if ( $wgTitle->isProtected() ) {
942 $t = wfMsg( "unprotectthispage" );
943 $q = "action=unprotect";
944 } else {
945 $t = wfMsg( "protectthispage" );
946 $q = "action=protect";
947 }
948 $s = $this->makeKnownLink( $n, $t, $q );
949 } else {
950 $s = "";
951 }
952 return $s;
953 }
954
955 function watchThisPage()
956 {
957 global $wgUser, $wgOut, $wgTitle, $diff;
958
959 if ( $wgOut->isArticle() && ( ! $diff ) ) {
960 $n = $wgTitle->getPrefixedText();
961
962 if ( $wgTitle->userIsWatching() ) {
963 $t = wfMsg( "unwatchthispage" );
964 $q = "action=unwatch";
965 } else {
966 $t = wfMsg( "watchthispage" );
967 $q = "action=watch";
968 }
969 $s = $this->makeKnownLink( $n, $t, $q );
970 } else {
971 $s = wfMsg( "notanarticle" );
972 }
973 return $s;
974 }
975
976 function moveThisPage()
977 {
978 global $wgTitle, $wgLang;
979
980 if ( $wgTitle->userCanEdit() ) {
981 $s = $this->makeKnownLink( $wgLang->specialPage( "Movepage" ),
982 wfMsg( "movethispage" ), "target=" . $wgTitle->getPrefixedURL() );
983 } // no message if page is protected - would be redundant
984 return $s;
985 }
986
987 function historyLink()
988 {
989 global $wgTitle;
990
991 $s = $this->makeKnownLink( $wgTitle->getPrefixedText(),
992 wfMsg( "history" ), "action=history" );
993 return $s;
994 }
995
996 function whatLinksHere()
997 {
998 global $wgTitle, $wgLang;
999
1000 $s = $this->makeKnownLink( $wgLang->specialPage( "Whatlinkshere" ),
1001 wfMsg( "whatlinkshere" ), "target=" . $wgTitle->getPrefixedURL() );
1002 return $s;
1003 }
1004
1005 function userContribsLink()
1006 {
1007 global $wgTitle, $wgLang;
1008
1009 $s = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
1010 wfMsg( "contributions" ), "target=" . $wgTitle->getURL() );
1011 return $s;
1012 }
1013
1014 function emailUserLink()
1015 {
1016 global $wgTitle, $wgLang;
1017
1018 $s = $this->makeKnownLink( $wgLang->specialPage( "Emailuser" ),
1019 wfMsg( "emailuser" ), "target=" . $wgTitle->getURL() );
1020 return $s;
1021 }
1022
1023 function watchPageLinksLink()
1024 {
1025 global $wgOut, $wgTitle, $wgLang;
1026
1027 if ( ! $wgOut->isArticle() ) {
1028 $s = "(" . wfMsg( "notanarticle" ) . ")";
1029 } else {
1030 $s = $this->makeKnownLink( $wgLang->specialPage(
1031 "Recentchangeslinked" ), wfMsg( "recentchangeslinked" ),
1032 "target=" . $wgTitle->getPrefixedURL() );
1033 }
1034 return $s;
1035 }
1036
1037 function otherLanguages()
1038 {
1039 global $wgOut, $wgLang, $wgTitle;
1040
1041 $a = $wgOut->getLanguageLinks();
1042 # TEST THIS @@@
1043 if ( 0 == count( $a ) ) {
1044 if ( !$wgUseNewInterlanguage ) return "";
1045 $ns = $wgLang->getNsIndex ( $wgTitle->getNamespace () ) ;
1046 if ( $ns != 0 AND $ns != 1 ) return "" ;
1047 $pn = "Intl" ;
1048 $x = "mode=addlink&xt=".$wgTitle->getDBkey() ;
1049 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1050 wfMsg( "intl" ) , $x );
1051 }
1052
1053 if ( !$wgUseNewInterlanguage ) {
1054 $s = wfMsg( "otherlanguages" ) . ": ";
1055 } else {
1056 global $wgLanguageCode ;
1057 $x = "mode=zoom&xt=".$wgTitle->getDBkey() ;
1058 $x .= "&xl=".$wgLanguageCode ;
1059 $s = $this->makeKnownLink( $wgLang->specialPage( "Intl" ),
1060 wfMsg( "otherlanguages" ) , $x ) . ": " ;
1061 }
1062
1063 $s = wfMsg( "otherlanguages" ) . ": ";
1064 $first = true;
1065 if($wgLang->isRTL()) $s .= "<span dir='LTR'>";
1066 foreach( $a as $l ) {
1067 if ( ! $first ) { $s .= " | "; }
1068 $first = false;
1069
1070 $nt = Title::newFromText( $l );
1071 $url = $nt->getFullURL();
1072 $text = $wgLang->getLanguageName( $nt->getInterwiki() );
1073
1074 if ( "" == $text ) { $text = $l; }
1075 $style = $this->getExternalLinkAttributes( $l, $text );
1076 $s .= "<a href=\"{$url}\"{$style}>{$text}</a>";
1077 }
1078 if($wgLang->isRTL()) $s .= "</span>";
1079 return $s;
1080 }
1081
1082 function bugReportsLink()
1083 {
1084 $s = $this->makeKnownLink( wfMsg( "bugreportspage" ),
1085 wfMsg( "bugreports" ) );
1086 return $s;
1087 }
1088
1089 function dateLink()
1090 {
1091 global $wgLinkCache;
1092 $t1 = Title::newFromText( gmdate( "F j" ) );
1093 $t2 = Title::newFromText( gmdate( "Y" ) );
1094
1095 $wgLinkCache->suspend();
1096 $id = $t1->getArticleID();
1097 $wgLinkCache->resume();
1098
1099 if ( 0 == $id ) {
1100 $s = $this->makeBrokenLink( $t1->getText() );
1101 } else {
1102 $s = $this->makeKnownLink( $t1->getText() );
1103 }
1104 $s .= ", ";
1105
1106 $wgLinkCache->suspend();
1107 $id = $t2->getArticleID();
1108 $wgLinkCache->resume();
1109
1110 if ( 0 == $id ) {
1111 $s .= $this->makeBrokenLink( $t2->getText() );
1112 } else {
1113 $s .= $this->makeKnownLink( $t2->getText() );
1114 }
1115 return $s;
1116 }
1117
1118 function talkLink()
1119 {
1120 global $wgLang, $wgTitle, $wgLinkCache;
1121
1122 $tns = $wgTitle->getNamespace();
1123 if ( -1 == $tns ) { return ""; }
1124
1125 $pn = $wgTitle->getText();
1126 $tp = wfMsg( "talkpage" );
1127 if ( Namespace::isTalk( $tns ) ) {
1128 $lns = Namespace::getSubject( $tns );
1129 switch($tns) {
1130 case 1:
1131 $text = wfMsg("articlepage");
1132 break;
1133 case 3:
1134 $text = wfMsg("userpage");
1135 break;
1136 case 5:
1137 $text = wfMsg("wikipediapage");
1138 break;
1139 case 7:
1140 $text = wfMsg("imagepage");
1141 break;
1142 default:
1143 $text= wfMsg("articlepage");
1144 }
1145 } else {
1146
1147 $lns = Namespace::getTalk( $tns );
1148 $text=$tp;
1149 }
1150 $n = $wgLang->getNsText( $lns );
1151 if ( "" == $n ) { $link = $pn; }
1152 else { $link = "{$n}:{$pn}"; }
1153
1154 $wgLinkCache->suspend();
1155 $s = $this->makeLink( $link, $text );
1156 $wgLinkCache->resume();
1157
1158 return $s;
1159 }
1160
1161 function commentLink()
1162 {
1163 global $wgLang, $wgTitle, $wgLinkCache;
1164
1165 $tns = $wgTitle->getNamespace();
1166 if ( -1 == $tns ) { return ""; }
1167
1168 $lns = ( Namespace::isTalk( $tns ) ) ? $tns : Namespace::getTalk( $tns );
1169
1170 # assert Namespace::isTalk( $lns )
1171
1172 $n = $wgLang->getNsText( $lns );
1173 $pn = $wgTitle->getText();
1174
1175 $link = "{$n}:{$pn}";
1176
1177 $wgLinkCache->suspend();
1178 $s = $this->makeKnownLink($link, wfMsg("postcomment"), "action=edit&section=new");
1179 $wgLinkCache->resume();
1180
1181 return $s;
1182 }
1183
1184 # After all the page content is transformed into HTML, it makes
1185 # a final pass through here for things like table backgrounds.
1186 #
1187 function transformContent( $text )
1188 {
1189 return $text;
1190 }
1191
1192 # Note: This function MUST call getArticleID() on the link,
1193 # otherwise the cache won't get updated properly. See LINKCACHE.DOC.
1194 #
1195 function makeLink( $title, $text = "", $query = "", $trail = "" ) {
1196 wfProfileIn( "Skin::makeLink" );
1197 $nt = Title::newFromText( $title );
1198 if ($nt) {
1199 $result = $this->makeLinkObj( Title::newFromText( $title ), $text, $query, $trail );
1200 } else {
1201 wfDebug( "Invalid title passed to Skin::makeLink(): \"$title\"\n" );
1202 $result = $text == "" ? $title : $text;
1203 }
1204
1205 wfProfileOut( "Skin::makeLink" );
1206 return $result;
1207 }
1208
1209 function makeKnownLink( $title, $text = "", $query = "", $trail = "" ) {
1210 $nt = Title::newFromText( $title );
1211 if ($nt) {
1212 return $this->makeKnownLinkObj( Title::newFromText( $title ), $text, $query, $trail );
1213 } else {
1214 wfDebug( "Invalid title passed to Skin::makeKnownLink(): \"$title\"\n" );
1215 return $text == "" ? $title : $text;
1216 }
1217 }
1218
1219 function makeBrokenLink( $title, $text = "", $query = "", $trail = "" ) {
1220 $nt = Title::newFromText( $title );
1221 if ($nt) {
1222 return $this->makeBrokenLinkObj( Title::newFromText( $title ), $text, $query, $trail );
1223 } else {
1224 wfDebug( "Invalid title passed to Skin::makeBrokenLink(): \"$title\"\n" );
1225 return $text == "" ? $title : $text;
1226 }
1227 }
1228
1229 function makeStubLink( $title, $text = "", $query = "", $trail = "" ) {
1230 $nt = Title::newFromText( $title );
1231 if ($nt) {
1232 return $this->makeStubLinkObj( Title::newFromText( $title ), $text, $query, $trail );
1233 } else {
1234 wfDebug( "Invalid title passed to Skin::makeStubLink(): \"$title\"\n" );
1235 return $text == "" ? $title : $text;
1236 }
1237 }
1238
1239 # Pass a title object, not a title string
1240 function makeLinkObj( &$nt, $text= "", $query = "", $trail = "" )
1241 {
1242 global $wgOut, $wgUser;
1243 if ( $nt->isExternal() ) {
1244 $u = $nt->getFullURL();
1245 if ( "" == $text ) { $text = $nt->getPrefixedText(); }
1246 $style = $this->getExternalLinkAttributes( $link, $text );
1247
1248 $inside = "";
1249 if ( "" != $trail ) {
1250 if ( preg_match( "/^([a-z]+)(.*)$$/sD", $trail, $m ) ) {
1251 $inside = $m[1];
1252 $trail = $m[2];
1253 }
1254 }
1255 $retVal = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1256 } elseif ( 0 == $nt->getNamespace() && "" == $nt->getText() ) {
1257 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail );
1258 } elseif ( ( -1 == $nt->getNamespace() ) ||
1259 ( Namespace::getImage() == $nt->getNamespace() ) ) {
1260 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail );
1261 } else {
1262 $aid = $nt->getArticleID() ;
1263 if ( 0 == $aid ) {
1264 $retVal = $this->makeBrokenLinkObj( $nt, $text, $query, $trail );
1265 } else {
1266 $threshold = $wgUser->getOption("stubthreshold") ;
1267 if ( $threshold > 0 ) {
1268 $res = wfQuery ( "SELECT HIGH_PRIORITY length(cur_text) AS x, cur_namespace, cur_is_redirect FROM cur WHERE cur_id='{$aid}'", DB_READ ) ;
1269
1270 if ( wfNumRows( $res ) > 0 ) {
1271 $s = wfFetchObject( $res );
1272 $size = $s->x;
1273 if ( $s->cur_is_redirect OR $s->cur_namespace != 0 ) {
1274 $size = $threshold*2 ; # Really big
1275 }
1276 wfFreeResult( $res );
1277 } else {
1278 $size = $threshold*2 ; # Really big
1279 }
1280 } else {
1281 $size = 1 ;
1282 }
1283 if ( $size < $threshold ) {
1284 $retVal = $this->makeStubLinkObj( $nt, $text, $query, $trail );
1285 } else {
1286 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail );
1287 }
1288 }
1289 }
1290 return $retVal;
1291 }
1292
1293 # Pass a title object, not a title string
1294 function makeKnownLinkObj( &$nt, $text = "", $query = "", $trail = "" )
1295 {
1296 global $wgOut, $wgTitle;
1297
1298 $fname = "Skin::makeKnownLinkObj";
1299 wfProfileIn( $fname );
1300
1301 $link = $nt->getPrefixedURL();
1302
1303 if ( "" == $link ) {
1304 $u = "";
1305 if ( "" == $text ) { $text = $nt->getFragment(); }
1306 } else {
1307 $u = wfLocalUrlE( $link, $query );
1308 }
1309 if ( "" != $nt->getFragment() ) {
1310 $u .= "#" . wfEscapeHTML( $nt->getFragment() );
1311 }
1312 if ( "" == $text ) { $text = $nt->getPrefixedText(); }
1313 $style = $this->getInternalLinkAttributesObj( $nt, $text );
1314
1315 $inside = "";
1316 if ( "" != $trail ) {
1317 if ( preg_match( wfMsg("linktrail"), $trail, $m ) ) {
1318 $inside = $m[1];
1319 $trail = $m[2];
1320 }
1321 }
1322 $r = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1323 wfProfileOut( $fname );
1324 return $r;
1325 }
1326
1327 # Pass a title object, not a title string
1328 function makeBrokenLinkObj( &$nt, $text = "", $query = "", $trail = "" )
1329 {
1330 global $wgOut, $wgUser;
1331
1332 $fname = "Skin::makeBrokenLinkObj";
1333 wfProfileIn( $fname );
1334
1335 $link = $nt->getPrefixedURL();
1336
1337 if ( "" == $query ) { $q = "action=edit"; }
1338 else { $q = "action=edit&{$query}"; }
1339 $u = wfLocalUrlE( $link, $q );
1340
1341 if ( "" == $text ) { $text = $nt->getPrefixedText(); }
1342 $style = $this->getInternalLinkAttributesObj( $nt, $text, "yes" );
1343
1344 $inside = "";
1345 if ( "" != $trail ) {
1346 if ( preg_match( wfMsg("linktrail"), $trail, $m ) ) {
1347 $inside = $m[1];
1348 $trail = $m[2];
1349 }
1350 }
1351 if ( $wgOut->isPrintable() ||
1352 ( 1 == $wgUser->getOption( "highlightbroken" ) ) ) {
1353 $s = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1354 } else {
1355 $s = "{$text}{$inside}<a href=\"{$u}\"{$style}>?</a>{$trail}";
1356 }
1357
1358 wfProfileOut( $fname );
1359 return $s;
1360 }
1361
1362 # Pass a title object, not a title string
1363 function makeStubLinkObj( &$nt, $text = "", $query = "", $trail = "" )
1364 {
1365 global $wgOut, $wgUser;
1366
1367 $link = $nt->getPrefixedURL();
1368
1369 $u = wfLocalUrlE( $link, $query );
1370
1371 if ( "" == $text ) { $text = $nt->getPrefixedText(); }
1372 $style = $this->getInternalLinkAttributesObj( $nt, $text, "stub" );
1373
1374 $inside = "";
1375 if ( "" != $trail ) {
1376 if ( preg_match( wfMsg("linktrail"), $trail, $m ) ) {
1377 $inside = $m[1];
1378 $trail = $m[2];
1379 }
1380 }
1381 if ( $wgOut->isPrintable() ||
1382 ( 1 == $wgUser->getOption( "highlightbroken" ) ) ) {
1383 $s = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1384 } else {
1385 $s = "{$text}{$inside}<a href=\"{$u}\"{$style}>!</a>{$trail}";
1386 }
1387 return $s;
1388 }
1389
1390 function fnamePart( $url )
1391 {
1392 $basename = strrchr( $url, "/" );
1393 if ( false === $basename ) { $basename = $url; }
1394 else { $basename = substr( $basename, 1 ); }
1395 return wfEscapeHTML( $basename );
1396 }
1397
1398 function makeImage( $url, $alt = "" )
1399 {
1400 global $wgOut;
1401
1402 if ( "" == $alt ) { $alt = $this->fnamePart( $url ); }
1403 $s = "<img src=\"{$url}\" alt=\"{$alt}\">";
1404 return $s;
1405 }
1406
1407 function makeImageLink( $name, $url, $alt = "" ) {
1408 $nt = Title::makeTitle( Namespace::getImage(), $name );
1409 return $this->makeImageLinkObj( $nt, $alt );
1410 }
1411
1412 function makeImageLinkObj( $nt, $alt = "" ) {
1413 $link = $nt->getPrefixedURL();
1414 $name = $nt->getDBKey();
1415 $url = wfImageUrl( $name );
1416 if ( empty( $alt ) ) {
1417 $alt = preg_replace( '/\.(.+?)^/', '', $name );
1418 }
1419 $alt = htmlspecialchars( $alt );
1420
1421 $u = wfLocalUrlE( $link );
1422 $s = "<a href=\"{$u}\" class='image' title=\"{$alt}\">" .
1423 "<img border=\"0\" src=\"{$url}\" alt=\"{$alt}\"></a>";
1424 return $s;
1425 }
1426
1427 function makeMediaLink( $name, $url, $alt = "" ) {
1428 $nt = Title::makeTitle( Namespace::getMedia(), $name );
1429 return $this->makeMediaLinkObj( $nt, $alt );
1430 }
1431
1432 function makeMediaLinkObj( $nt, $alt = "" )
1433 {
1434 $name = $nt->getDBKey();
1435 $url = wfImageUrl( $name );
1436 if ( empty( $alt ) ) {
1437 $alt = preg_replace( '/\.(.+?)^/', '', $name );
1438 }
1439
1440 $u = htmlspecialchars( $url );
1441 $s = "<a href=\"{$u}\" class='internal' title=\"{$alt}\">{$alt}</a>";
1442 return $s;
1443 }
1444
1445 function specialLink( $name, $key = "" )
1446 {
1447 global $wgLang;
1448
1449 if ( "" == $key ) { $key = strtolower( $name ); }
1450 $pn = $wgLang->ucfirst( $name );
1451 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1452 wfMsg( $key ) );
1453 }
1454
1455 # Called by history lists and recent changes
1456 #
1457
1458 function beginRecentChangesList()
1459 {
1460 $rc_cache = array() ;
1461 $rccc = 0 ;
1462 $this->lastdate = "";
1463 return "";
1464 }
1465
1466 function beginImageHistoryList()
1467 {
1468 $s = "\n<h2>" . wfMsg( "imghistory" ) . "</h2>\n" .
1469 "<p>" . wfMsg( "imghistlegend" ) . "\n<ul>";
1470 return $s;
1471 }
1472
1473 function endRecentChangesList()
1474 {
1475 $s = $this->recentChangesBlock() ;
1476 $s .= "</ul>\n";
1477 return $s;
1478 }
1479
1480 function endImageHistoryList()
1481 {
1482 $s = "</ul>\n";
1483 return $s;
1484 }
1485
1486 function recentChangesBlockLine ( $y ) {
1487 global $wgUploadPath ;
1488
1489 $M = wfMsg( "minoreditletter" );
1490 $N = wfMsg( "newpageletter" );
1491 $r = "" ;
1492 $r .= "<img src='{$wgUploadPath}/Arr_.png' width=12 height=12 border=0>" ;
1493 $r .= "<tt>" ;
1494 if ( $y->isnew ) $r .= $N ;
1495 else $r .= "&nbsp;" ;
1496 if ( $y->isminor ) $r .= $M ;
1497 else $r .= "&nbsp;" ;
1498 $r .= " ".$y->timestamp." " ;
1499 $r .= "</tt>" ;
1500 $link = $y->link ;
1501 if ( $y->watched ) $link = "<strong>{$link}</strong>" ;
1502 $r .= $link ;
1503
1504 $r .= " (" ;
1505 $r .= $y->curlink ;
1506 $r .= "; " ;
1507 $r .= $this->makeKnownLink( $y->secureName, wfMsg( "hist" ), "action=history" );
1508
1509 $r .= ") . . ".$y->userlink ;
1510 $r .= $y->usertalklink ;
1511 if ( $y->usercomment != "" )
1512 $r .= " <em>(".wfEscapeHTML($y->usercomment).")</em>" ;
1513 $r .= "<br>\n" ;
1514 return $r ;
1515 }
1516
1517 function recentChangesBlockGroup ( $y ) {
1518 global $wgUploadPath ;
1519
1520 $r = "" ;
1521 $M = wfMsg( "minoreditletter" );
1522 $N = wfMsg( "newpageletter" );
1523 $isnew = false ;
1524 $userlinks = array () ;
1525 foreach ( $y AS $x ) {
1526 $oldid = $x->diffid ;
1527 if ( $x->isnew ) $isnew = true ;
1528 $u = $x->userlink ;
1529 if ( !isset ( $userlinks[$u] ) ) $userlinks[$u] = 0 ;
1530 $userlinks[$u]++ ;
1531 }
1532
1533 krsort ( $userlinks ) ;
1534 asort ( $userlinks ) ;
1535 $users = array () ;
1536 $u = array_keys ( $userlinks ) ;
1537 foreach ( $u as $x ) {
1538 $z = $x ;
1539 if ( $userlinks[$x] > 1 ) $z .= " ({$userlinks[$x]}&times;)" ;
1540 array_push ( $users , $z ) ;
1541 }
1542 $users = " <font size='-1'>[".implode("; ",$users)."]</font>" ;
1543
1544 $e = $y ;
1545 $e = array_shift ( $e ) ;
1546
1547 # Arrow
1548 $rci = "RCI{$this->rccc}" ;
1549 $rcl = "RCL{$this->rccc}" ;
1550 $rcm = "RCM{$this->rccc}" ;
1551 $tl = "<a href='javascript:toggleVisibility(\"{$rci}\",\"{$rcm}\",\"{$rcl}\")'>" ;
1552 $tl .= "<span id='{$rcm}'><img src='{$wgUploadPath}/Arr_r.png' width=12 height=12 border=0></span>" ;
1553 $tl .= "<span id='{$rcl}' style='display:none'><img src='{$wgUploadPath}/Arr_d.png' width=12 height=12 border=0></span>" ;
1554 $tl .= "</a>" ;
1555 $r .= $tl ;
1556
1557 # Main line
1558 $r .= "<tt>" ;
1559 if ( $isnew ) $r .= $N ;
1560 else $r .= "&nbsp;" ;
1561 $r .= "&nbsp;" ; # Minor
1562 $r .= " ".$e->timestamp." " ;
1563 $r .= "</tt>" ;
1564
1565 $link = $e->link ;
1566 if ( $e->watched ) $link = "<strong>{$link}</strong>" ;
1567 $r .= $link ;
1568
1569 if ( !$e->islog ) {
1570 $r .= " (".count($y)." " ;
1571 if ( $isnew ) $r .= wfMsg("changes");
1572 else $r .= $this->makeKnownLink( $e->secureName , wfMsg("changes") , "diff=0&oldid=".$oldid ) ;
1573 $r .= "; " ;
1574 $r .= $this->makeKnownLink( $e->secureName, wfMsg( "history" ), "action=history" );
1575 $r .= ")" ;
1576 }
1577
1578 $r .= $users ;
1579 $r .= "<br>\n" ;
1580
1581 # Sub-entries
1582 $r .= "<div id='{$rci}' style='display:none'>" ;
1583 foreach ( $y AS $x )
1584 {
1585 $r .= "<img src='{$wgUploadPath}/Arr_.png' width=12 height=12 border=0>";
1586 $r .= "<tt>&nbsp; &nbsp; &nbsp; &nbsp;" ;
1587 if ( $x->isnew ) $r .= $N ;
1588 else $r .= "&nbsp;" ;
1589 if ( $x->isminor ) $r .= $M ;
1590 else $r .= "&nbsp;" ;
1591 $r .= "</tt>" ;
1592
1593 $o = "" ;
1594 if ( $x->oldid != 0 ) $o = "oldid=".$x->oldid ;
1595 if ( $x->islog ) $link = $x->timestamp ;
1596 else $link = $this->makeKnownLink( $x->secureName, $x->timestamp , $o ) ;
1597 $link = "<tt>{$link}</tt>" ;
1598
1599
1600 $r .= $link ;
1601 $r .= " (" ;
1602 $r .= $x->curlink ;
1603 $r .= "; " ;
1604 $r .= $x->lastlink ;
1605 $r .= ") . . ".$x->userlink ;
1606 $r .= $x->usertalklink ;
1607 if ( $x->usercomment != "" )
1608 $r .= " <em>(".wfEscapeHTML($x->usercomment).")</em>" ;
1609 $r .= "<br>\n" ;
1610 }
1611 $r .= "</div>\n" ;
1612
1613 $this->rccc++ ;
1614 return $r ;
1615 }
1616
1617 function recentChangesBlock ()
1618 {
1619 global $wgUploadPath ;
1620 if ( count ( $this->rc_cache ) == 0 ) return "" ;
1621 $k = array_keys ( $this->rc_cache ) ;
1622 foreach ( $k AS $x )
1623 {
1624 $y = $this->rc_cache[$x] ;
1625 if ( count ( $y ) < 2 ) {
1626 $r .= $this->recentChangesBlockLine ( array_shift ( $y ) ) ;
1627 } else {
1628 $r .= $this->recentChangesBlockGroup ( $y ) ;
1629 }
1630 }
1631
1632 return "<div align=left>{$r}</div>" ;
1633 }
1634
1635 function recentChangesLine( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched = false, $oldid = 0 , $diffid = 0 )
1636 {
1637 global $wgUser ;
1638 $usenew = $wgUser->getOption( "usenewrc" );
1639 if ( $usenew )
1640 $r = $this->recentChangesLineNew ( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched , $oldid , $diffid ) ;
1641 else
1642 $r = $this->recentChangesLineOld ( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched , $oldid , $diffid ) ;
1643 return $r ;
1644 }
1645
1646 function recentChangesLineOld( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched = false, $oldid = 0, $diffid = 0 )
1647 {
1648 global $wgTitle, $wgLang, $wgUser;
1649
1650 $d = $wgLang->date( $ts, true);
1651 $s = "";
1652 if ( $d != $this->lastdate ) {
1653 if ( "" != $this->lastdate ) { $s .= "</ul>\n"; }
1654 $s .= "<h4>{$d}</h4>\n<ul>";
1655 $this->lastdate = $d;
1656 }
1657 $h = $wgLang->time( $ts, true );
1658 $t = Title::makeName( $ns, $ttl );
1659 $clink = $this->makeKnownLink( $t , "" );
1660 $nt = Title::newFromText( $t );
1661
1662 if ( $watched ) {
1663 $clink = "<strong>{$clink}</strong>";
1664 }
1665 $hlink = $this->makeKnownLink( $t, wfMsg( "hist" ), "action=history" );
1666 if ( $isnew || $nt->isLog() ) {
1667 $dlink = wfMsg( "diff" );
1668 } else {
1669 $dlink = $this->makeKnownLink( $t, wfMsg( "diff" ),
1670 "diff={$oldid}&oldid={$diffid}" ); # Finagle's law
1671 }
1672 if ( 0 == $u ) {
1673 $ul = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
1674 $ut, "target=" . $ut );
1675 } else {
1676 $ul = $this->makeLink( $wgLang->getNsText( Namespace::getUser() ) . ":{$ut}", $ut );
1677 }
1678
1679 $talkname=$wgLang->getNsText(Namespace::getTalk(0)); # use the shorter name
1680 global $wgDisableAnonTalk;
1681 if( 0 == $u && $wgDisableAnonTalk ) {
1682 $utl = "";
1683 } else {
1684 $utns=$wgLang->getNsText(Namespace::getTalk(Namespace::getUser()));
1685 $utl= $this->makeLink($utns . ":{$ut}", $talkname );
1686 }
1687 $cr = wfMsg( "currentrev" );
1688
1689 $s .= "<li> ({$dlink}) ({$hlink}) . .";
1690 $M = wfMsg( "minoreditletter" );
1691 $N = wfMsg( "newpageletter" );
1692 if ( $isminor ) { $s .= " <strong>{$M}</strong>"; }
1693 if ( $isnew ) { $s .= "<strong>{$N}</strong>"; }
1694 $s .= " {$clink}; {$h} . . {$ul}";
1695
1696 $blink="";
1697 if ( ( 0 == $u ) && $wgUser->isSysop() ) {
1698 $blink = $this->makeKnownLink( $wgLang->specialPage(
1699 "Blockip" ), wfMsg( "blocklink" ), "ip={$ut}" );
1700
1701 }
1702 if($blink) {
1703 if($utl) $utl .= " | ";
1704 $utl .= $blink;
1705 }
1706 if($utl) $s.=" ({$utl})";
1707
1708 if ( "" != $c && "*" != $c ) {
1709 $s .= " <em>(" . wfEscapeHTML( $c ) . ")</em>";
1710 }
1711 $s .= "</li>\n";
1712
1713 return $s;
1714 }
1715
1716 function recentChangesLineNew( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched = false, $oldid = 0 , $diffid = 0 )
1717 {
1718 global $wgTitle, $wgLang, $wgUser;
1719
1720 $rc = new RecentChangesClass ;
1721
1722 $d = $wgLang->date( $ts, true);
1723 $s = "";
1724 $ret = "" ;
1725 if ( $d != $this->lastdate ) {
1726 $ret = $this->recentChangesBlock () ;
1727 $this->rc_cache = array() ;
1728 $ret .= "<h4>{$d}</h4>\n";
1729 $this->lastdate = $d;
1730 }
1731 $h = $wgLang->time( $ts, true );
1732 $t = Title::makeName( $ns, $ttl );
1733 $clink = $this->makeKnownLink( $t, "" ) ;
1734 if ( $oldid == 0 ) $c2link = $clink ;
1735 else $c2link = $this->makeKnownLink( $t, "" , "oldid={$oldid}" );
1736 $nt = Title::newFromText( $t );
1737
1738 $rc->timestamp = $h ;
1739 $rc->oldid = $oldid ;
1740 $rc->diffid = $diffid ;
1741 $rc->watched = $watched ;
1742 $rc->isnew = $isnew ;
1743 $rc->isminor = $isminor ;
1744 $rc->secureName = $t ;
1745 $rc->displayName = $nt ;
1746 $rc->link = $clink ;
1747 $rc->usercomment = $c ;
1748 $rc->islog = $nt->isLog() ;
1749
1750 if ( ( $isnew && $oldid == 0 ) || $nt->isLog() ) {
1751 $dlink = wfMsg( "cur" );
1752 } else {
1753 $dlink = $this->makeKnownLink( $t, wfMsg( "cur" ),
1754 "diff=0&oldid={$oldid}" );
1755 }
1756
1757 if ( $diffid == 0 || $nt->isLog() ) {
1758 $plink = wfMsg( "last" );
1759 } else {
1760 $plink = $this->makeKnownLink( $t, wfMsg( "last" ),
1761 "diff={$oldid}&oldid={$diffid}" );
1762 }
1763
1764 if ( 0 == $u ) {
1765 $ul = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
1766 $ut, "target=" . $ut );
1767 } else { $ul = $this->makeLink( $wgLang->getNsText(
1768 Namespace::getUser() ) . ":{$ut}", $ut ); }
1769
1770 $rc->userlink = $ul ;
1771 $rc->lastlink = $plink ;
1772 $rc->curlink = $dlink ;
1773
1774 $utns=$wgLang->getNsText(Namespace::getTalk(Namespace::getUser()));
1775 $talkname=$wgLang->getNsText(Namespace::getTalk(0)); # use the shorter name
1776 $utl= $this->makeLink($utns . ":{$ut}", $talkname );
1777
1778 global $wgDisableAnonTalk;
1779 if ( ( 0 == $u ) && $wgUser->isSysop() ) {
1780 $blink = $this->makeKnownLink( $wgLang->specialPage(
1781 "Blockip" ), wfMsg( "blocklink" ), "ip={$ut}" );
1782 if( $wgDisableAnonTalk )
1783 $rc->usertalklink = " ({$blink})";
1784 else
1785 $rc->usertalklink = " ({$utl} | {$blink})";
1786 } else {
1787 if( $wgDisableAnonTalk && ($u == 0) )
1788 $rc->usertalklink = "";
1789 else
1790 $rc->usertalklink = " ({$utl})";
1791 }
1792
1793 if ( !isset ( $this->rc_cache[$t] ) ) $this->rc_cache[$t] = array() ;
1794 array_push ( $this->rc_cache[$t] , $rc ) ;
1795 return $ret;
1796 }
1797
1798
1799 function imageHistoryLine( $iscur, $ts, $img, $u, $ut, $size, $c )
1800 {
1801 global $wgUser, $wgLang, $wgTitle;
1802
1803 $dt = $wgLang->timeanddate( $ts, true );
1804 $del = wfMsg( "deleteimg" );
1805 $cur = wfMsg( "cur" );
1806
1807 if ( $iscur ) {
1808 $url = wfImageUrl( $img );
1809 $rlink = $cur;
1810 if ( $wgUser->isSysop() ) {
1811 $link = wfLocalUrlE( $wgTitle->getPrefixedText(), "image=" . $wgTitle->getURL() .
1812 "&action=delete" );
1813 $style = $this->getInternalLinkAttributes( $link, $del );
1814
1815 $dlink = "<a href=\"{$link}\"{$style}>{$del}</a>";
1816 } else {
1817 $dlink = $del;
1818 }
1819 } else {
1820 $url = wfEscapeHTML( wfImageArchiveUrl( $img ) );
1821 if( $wgUser->getID() != 0 ) {
1822 $rlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
1823 wfMsg( "revertimg" ), "action=revert&oldimage=" .
1824 urlencode( $img ) );
1825 $dlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
1826 $del, "action=delete&oldimage=" . urlencode( $img ) );
1827 } else {
1828 # Having live active links for non-logged in users
1829 # means that bots and spiders crawling our site can
1830 # inadvertently change content. Baaaad idea.
1831 $rlink = wfMsg( "revertimg" );
1832 $dlink = $del;
1833 }
1834 }
1835 if ( 0 == $u ) { $ul = $ut; }
1836 else { $ul = $this->makeLink( $wgLang->getNsText(
1837 Namespace::getUser() ) . ":{$ut}", $ut ); }
1838
1839 $nb = wfMsg( "nbytes", $size );
1840 $style = $this->getInternalLinkAttributes( $url, $dt );
1841
1842 $s = "<li> ({$dlink}) ({$rlink}) <a href=\"{$url}\"{$style}>{$dt}</a>"
1843 . " . . {$ul} ({$nb})";
1844
1845 if ( "" != $c && "*" != $c ) {
1846 $s .= " <em>(" . wfEscapeHTML( $c ) . ")</em>";
1847 }
1848 $s .= "</li>\n";
1849 return $s;
1850 }
1851
1852 function tocIndent($level) {
1853
1854 while($level-->0) $rv.="<div style=\"margin-left:2em;\">\n";
1855 return $rv;
1856
1857 }
1858
1859 function tocUnindent($level) {
1860 while($level-->0) $rv.="</div>\n";
1861 return $rv;
1862 }
1863
1864 // parameter level defines if we are on an indentation level
1865 function tocLine($anchor,$tocline,$level) {
1866
1867 if($level) {
1868
1869 return "<A CLASS=\"internal\" HREF=\"#".$anchor."\">".$tocline."</A><BR>\n";
1870 } else {
1871
1872 return "<div style=\"margin-bottom:0px;\">\n".
1873 "<A CLASS=\"internal\" HREF=\"#".$anchor."\">".$tocline."</A><BR>\n".
1874 "</div>\n";
1875 }
1876
1877 }
1878
1879 function tocTable($toc) {
1880 // note to CSS fanatics: putting this in a div does not work -- div won't auto-expand
1881 global $printable;
1882
1883 if (!$printable) {
1884 $hideline = " <script type='text/javascript'>showTocToggle(\"" . wfMsg("showtoc") . "\",\"" . wfMsg("hidetoc") . "\")</script>";
1885 }
1886 return
1887 "<p><table border=\"0\" id=\"toc\"><tr><td align=\"center\">\n".
1888 "<b>".wfMsg("toc")."</b>" .
1889 $hideline .
1890 "</td></tr><tr id='tocinside'><td align=\"left\">\n".
1891 $toc."</td></tr></table><P>\n";
1892 }
1893
1894 # These two do not check for permissions: check $wgTitle->userCanEdit before calling them
1895 function editSectionScript($section,$head) {
1896
1897 global $wgTitle,$wgUser,$oldid;
1898 if($oldid) return $head;
1899 $url = wfLocalUrlE(urlencode($wgTitle->getPrefixedText()),"action=edit&section=$section");
1900 return "<span onContextMenu='document.location=\"".$url."\";return false;'>{$head}</span>";
1901 }
1902
1903 function editSectionLink($section) {
1904
1905 global $printable;
1906 global $wgTitle,$wgUser,$oldid;
1907 if($oldid) return "";
1908 if ($printable) return "";
1909 $editurl="&section={$section}";
1910 $url=$this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg("editsection"),"action=edit".$editurl);
1911 return "<div style=\"float:right;margin-left:5px;\"><small>[".$url."]</small></div>";
1912
1913 }
1914 }
1915
1916 include_once( "SkinStandard.php" );
1917 include_once( "SkinNostalgia.php" );
1918 include_once( "SkinCologneBlue.php" );
1919
1920 #include_once( "SkinSmarty.php" );
1921
1922 ?>