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