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