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