ba5c4d77820866cffa300693225afd578f53acd5
[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 ;
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
87 wfProfileOut( $fname );
88 }
89
90 function outputPage( &$out ) {
91 global $wgDebugComments;
92
93 wfProfileIn( "Skin::outputPage" );
94 $this->initPage( $out );
95 $out->out( $out->headElement() );
96
97 $out->out( "\n<body" );
98 $ops = $this->getBodyOptions();
99 foreach ( $ops as $name => $val ) {
100 $out->out( " $name='$val'" );
101 }
102 $out->out( ">\n" );
103 if ( $wgDebugComments ) {
104 $out->out( "<!-- Wiki debugging output:\n" .
105 $out->mDebugtext . "-->\n" );
106 }
107 $out->out( $this->beforeContent() );
108
109 $out->out( $out->mBodytext );
110
111 $out->out( $this->afterContent() );
112
113 wfProfileClose();
114 $out->out( $out->reportTime() );
115
116 $out->out( "\n</body></html>" );
117 }
118
119 function getHeadScripts() {
120 global $wgStyleSheetPath;
121 $r = "<script type=\"text/javascript\" src=\"{$wgStyleSheetPath}/wikibits.js\"></script>\n";
122 return $r;
123 }
124
125 function getUserStyles()
126 {
127 global $wgOut, $wgStyleSheetPath;
128 if( $wgOut->isPrintable() ) {
129 $sheet = "wikiprintable.css";
130 } else {
131 $sheet = $this->getStylesheet();
132 }
133 $s = "<style type='text/css'><!--\n";
134 $s .= "@import url(\"$wgStyleSheetPath/$sheet\");\n";
135 $s .= "/*/*/\n"; # <-- Hide the styles from Netscape 4 without hiding them from IE/Mac
136 $s .= $this->doGetUserStyles();
137 $s .= "/* */\n";
138 $s .= "//--></style>\n";
139 return $s;
140 }
141
142 function doGetUserStyles()
143 {
144 global $wgUser;
145
146 $s = "";
147 if ( 1 == $wgUser->getOption( "underline" ) ) {
148 # Don't override browser settings
149 } else {
150 # CHECK MERGE @@@
151 # Force no underline
152 $s .= "a.stub, a.new, a.internal, a.external { " .
153 "text-decoration: none; }\n";
154 }
155 if ( 1 == $wgUser->getOption( "highlightbroken" ) ) {
156 $s .= "a.new, #quickbar a.new { color: #CC2200; }\n";
157 }
158 if ( 1 == $wgUser->getOption( "justify" ) ) {
159 $s .= "#article { text-align: justify; }\n";
160 }
161 return $s;
162 }
163
164 function getBodyOptions()
165 {
166 global $wgUser, $wgTitle, $wgNamespaceBackgrounds, $wgOut, $oldid, $redirect, $diff,$action;
167
168 if ( 0 != $wgTitle->getNamespace() ) {
169 $a = array( "bgcolor" => "#ffffec" );
170 }
171 else $a = array( "bgcolor" => "#FFFFFF" );
172 if($wgOut->isArticle() && $wgUser->getOption("editondblclick")
173 &&
174 (!$wgTitle->isProtected() || $wgUser->isSysop())
175
176 ) {
177 $n = $wgTitle->getPrefixedURL();
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 = wfLocalUrlE($n,"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 = $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 $s = "<a href=\"" . wfLocalUrlE( urlencode( str_replace(' ','_',$mp) ) )
695 . "\"><img{$a} border=0 src=\""
696 . $this->getLogo() . "\" alt=\"" . "[{$mp}]\"></a>";
697 return $s;
698 }
699
700 function quickBar()
701 {
702 global $wgOut, $wgTitle, $wgUser, $action, $wgLang;
703 global $wpPreview, $wgDisableUploads, $wgRemoteUploads;
704
705 $fname = "Skin::quickBar";
706 wfProfileIn( $fname );
707
708 $tns=$wgTitle->getNamespace();
709
710 $s = "\n<div id='quickbar'>";
711 $s .= "\n" . $this->logoText() . "\n<hr class='sep'>";
712
713 $sep = "\n<br>";
714 $s .= $this->mainPageLink()
715 . $sep . $this->specialLink( "recentchanges" )
716 . $sep . $this->specialLink( "randompage" );
717 if ($wgUser->getID()) {
718 $s.= $sep . $this->specialLink( "watchlist" ) ;
719 $s .= $sep .$this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
720 wfMsg( "mycontris" ), "target=" . wfUrlencode($wgUser->getName() ) );
721
722 }
723 // only show watchlist link if logged in
724 if ( wfMsg ( "currentevents" ) != "-" ) $s .= $sep . $this->makeKnownLink( wfMsg( "currentevents" ), "" ) ;
725 $s .= "\n<br><hr class='sep'>";
726 $articleExists = $wgTitle->getArticleId();
727 if ( $wgOut->isArticle() || $action =="edit" || $action =="history" || $wpPreview) {
728 if($wgOut->isArticle()) {
729 $s .= "<strong>" . $this->editThisPage() . "</strong>";
730 } else { # backlink to the article in edit or history mode
731 if($articleExists){ # no backlink if no article
732 switch($tns) {
733 case 0:
734 $text = wfMsg("articlepage");
735 break;
736 case 1:
737 $text = wfMsg("viewtalkpage");
738 break;
739 case 2:
740 $text = wfMsg("userpage");
741 break;
742 case 3:
743 $text = wfMsg("viewtalkpage");
744 break;
745 case 4:
746 $text = wfMsg("wikipediapage");
747 break;
748 case 5:
749 $text = wfMsg("viewtalkpage");
750 break;
751 case 6:
752 $text = wfMsg("imagepage");
753 break;
754 case 7:
755 $text = wfMsg("viewtalkpage");
756 break;
757 default:
758 $text= wfMsg("articlepage");
759 }
760
761 $link = $wgTitle->getText();
762 if ($nstext = $wgLang->getNsText($tns) ) { # add namespace if necessary
763 $link = $nstext . ":" . $link ;
764 }
765
766 $s .= $this->makeLink( $link, $text );
767 } elseif( $wgTitle->getNamespace() != Namespace::getSpecial() ) {
768 # we just throw in a "New page" text to tell the user that he's in edit mode,
769 # and to avoid messing with the separator that is prepended to the next item
770 $s .= "<strong>" . wfMsg("newpage") . "</strong>";
771 }
772
773 }
774
775
776 if( $tns%2 && $action!="edit" && !$wpPreview) {
777 $s.="<br>".$this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg("postcomment"),"action=edit&section=new");
778 }
779
780 /*
781 watching could cause problems in edit mode:
782 if user edits article, then loads "watch this article" in background and then saves
783 article with "Watch this article" checkbox disabled, the article is transparently
784 unwatched. Therefore we do not show the "Watch this page" link in edit mode
785 */
786 if ( 0 != $wgUser->getID() && $articleExists) {
787 if($action!="edit" && $action != "submit" )
788 {
789 $s .= $sep . $this->watchThisPage();
790 }
791 if ( $wgTitle->userCanEdit() )
792 $s .= $sep . $this->moveThisPage();
793 }
794 if ( $wgUser->isSysop() and $articleExists ) {
795 $s .= $sep . $this->deleteThisPage() .
796 $sep . $this->protectThisPage();
797 }
798 $s .= $sep . $this->talkLink();
799 if ($articleExists && $action !="history") {
800 $s .= $sep . $this->historyLink();
801 }
802 $s.=$sep . $this->whatLinksHere();
803
804 if($wgOut->isArticleRelated()) {
805 $s .= $sep . $this->watchPageLinksLink();
806 }
807
808 if ( Namespace::getUser() == $wgTitle->getNamespace()
809 || $wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser())
810 ) {
811
812 $id=User::idFromName($wgTitle->getText());
813 $ip=User::isIP($wgTitle->getText());
814
815 if($id||$ip) {
816 $s .= $sep . $this->userContribsLink();
817 }
818 if ( 0 != $wgUser->getID() ) {
819 if($id) { # can only email real users
820 $s .= $sep . $this->emailUserLink();
821 }
822 }
823 }
824 $s .= "\n<br><hr class='sep'>";
825 }
826
827 if ( 0 != $wgUser->getID() && ( !$wgDisableUploads || $wgRemoteUploads ) ) {
828 $s .= $this->specialLink( "upload" ) . $sep;
829 }
830 $s .= $this->specialLink( "specialpages" )
831 . $sep . $this->bugReportsLink();
832
833 global $wgSiteSupportPage;
834 if( $wgSiteSupportPage ) {
835 $s .= "\n<br><a href=\"" . htmlspecialchars( $wgSiteSupportPage ) .
836 "\" class=\"internal\">" . wfMsg( "sitesupport" ) . "</a>";
837 }
838
839 $s .= "\n<br></div>\n";
840 wfProfileOut( $fname );
841 return $s;
842 }
843
844 function specialPagesList()
845 {
846 global $wgUser, $wgOut, $wgLang, $wgServer, $wgRedirectScript;
847 $a = array();
848
849 $validSP = $wgLang->getValidSpecialPages();
850
851 foreach ( $validSP as $name => $desc ) {
852 if ( "" == $desc ) { continue; }
853 $a[$name] = $desc;
854 }
855 if ( $wgUser->isSysop() )
856 {
857 $sysopSP = $wgLang->getSysopSpecialPages();
858
859 foreach ( $sysopSP as $name => $desc ) {
860 if ( "" == $desc ) { continue; }
861 $a[$name] = $desc ;
862 }
863 }
864 if ( $wgUser->isDeveloper() )
865 {
866 $devSP = $wgLang->getDeveloperSpecialPages();
867
868 foreach ( $devSP as $name => $desc ) {
869 if ( "" == $desc ) { continue; }
870 $a[$name] = $desc ;
871 }
872 }
873 $go = wfMsg( "go" );
874 $sp = wfMsg( "specialpages" );
875 $spp = $wgLang->specialPage( "Specialpages" );
876
877 $s = "<form id=\"specialpages\" method=\"get\" class=\"inline\" " .
878 "action=\"{$wgServer}{$wgRedirectScript}\">\n";
879 $s .= "<select name=\"wpDropdown\">\n";
880 $s .= "<option value=\"{$spp}\">{$sp}</option>\n";
881
882 foreach ( $a as $name => $desc ) {
883 $p = $wgLang->specialPage( $name );
884 $s .= "<option value=\"{$p}\">{$desc}</option>\n";
885 }
886 $s .= "</select>\n";
887 $s .= "<input type=submit value=\"{$go}\" name=redirect>\n";
888 $s .= "</form>\n";
889 return $s;
890 }
891
892 function mainPageLink()
893 {
894 $mp = wfMsg( "mainpage" );
895 $s = $this->makeKnownLink( $mp, $mp );
896 return $s;
897 }
898
899 function copyrightLink()
900 {
901 $s = $this->makeKnownLink( wfMsg( "copyrightpage" ),
902 wfMsg( "copyrightpagename" ) );
903 return $s;
904 }
905
906 function aboutLink()
907 {
908 $s = $this->makeKnownLink( wfMsg( "aboutpage" ),
909 wfMsg( "aboutwikipedia" ) );
910 return $s;
911 }
912
913
914 function disclaimerLink()
915 {
916 $s = $this->makeKnownLink( wfMsg( "disclaimerpage" ),
917 wfMsg( "disclaimers" ) );
918 return $s;
919 }
920
921 function editThisPage()
922 {
923 global $wgOut, $wgTitle, $oldid, $redirect, $diff;
924
925 if ( ! $wgOut->isArticleRelated() ) {
926 $s = wfMsg( "protectedpage" );
927 } else {
928 $n = $wgTitle->getPrefixedText();
929 if ( $wgTitle->userCanEdit() ) {
930 $t = wfMsg( "editthispage" );
931 } else {
932 #$t = wfMsg( "protectedpage" );
933 $t = wfMsg( "viewsource" );
934 }
935 $oid = $red = "";
936
937 if ( $redirect ) { $red = "&redirect={$redirect}"; }
938 if ( $oldid && ! isset( $diff ) ) {
939 $oid = "&oldid={$oldid}";
940 }
941 $s = $this->makeKnownLink( $n, $t, "action=edit{$oid}{$red}" );
942 }
943 return $s;
944 }
945
946 function deleteThisPage()
947 {
948 global $wgUser, $wgOut, $wgTitle, $diff;
949
950 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
951 $n = $wgTitle->getPrefixedText();
952 $t = wfMsg( "deletethispage" );
953
954 $s = $this->makeKnownLink( $n, $t, "action=delete" );
955 } else {
956 $s = "";
957 }
958 return $s;
959 }
960
961 function protectThisPage()
962 {
963 global $wgUser, $wgOut, $wgTitle, $diff;
964
965 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
966 $n = $wgTitle->getPrefixedText();
967
968 if ( $wgTitle->isProtected() ) {
969 $t = wfMsg( "unprotectthispage" );
970 $q = "action=unprotect";
971 } else {
972 $t = wfMsg( "protectthispage" );
973 $q = "action=protect";
974 }
975 $s = $this->makeKnownLink( $n, $t, $q );
976 } else {
977 $s = "";
978 }
979 return $s;
980 }
981
982 function watchThisPage()
983 {
984 global $wgUser, $wgOut, $wgTitle, $diff;
985
986 if ( $wgOut->isArticleRelated() ) {
987 $n = $wgTitle->getPrefixedText();
988
989 if ( $wgTitle->userIsWatching() ) {
990 $t = wfMsg( "unwatchthispage" );
991 $q = "action=unwatch";
992 } else {
993 $t = wfMsg( "watchthispage" );
994 $q = "action=watch";
995 }
996 $s = $this->makeKnownLink( $n, $t, $q );
997 } else {
998 $s = wfMsg( "notanarticle" );
999 }
1000 return $s;
1001 }
1002
1003 function moveThisPage()
1004 {
1005 global $wgTitle, $wgLang;
1006
1007 if ( $wgTitle->userCanEdit() ) {
1008 $s = $this->makeKnownLink( $wgLang->specialPage( "Movepage" ),
1009 wfMsg( "movethispage" ), "target=" . $wgTitle->getPrefixedURL() );
1010 } // no message if page is protected - would be redundant
1011 return $s;
1012 }
1013
1014 function historyLink()
1015 {
1016 global $wgTitle;
1017
1018 $s = $this->makeKnownLink( $wgTitle->getPrefixedText(),
1019 wfMsg( "history" ), "action=history" );
1020 return $s;
1021 }
1022
1023 function whatLinksHere()
1024 {
1025 global $wgTitle, $wgLang;
1026
1027 $s = $this->makeKnownLink( $wgLang->specialPage( "Whatlinkshere" ),
1028 wfMsg( "whatlinkshere" ), "target=" . $wgTitle->getPrefixedURL() );
1029 return $s;
1030 }
1031
1032 function userContribsLink()
1033 {
1034 global $wgTitle, $wgLang;
1035
1036 $s = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
1037 wfMsg( "contributions" ), "target=" . $wgTitle->getURL() );
1038 return $s;
1039 }
1040
1041 function emailUserLink()
1042 {
1043 global $wgTitle, $wgLang;
1044
1045 $s = $this->makeKnownLink( $wgLang->specialPage( "Emailuser" ),
1046 wfMsg( "emailuser" ), "target=" . $wgTitle->getURL() );
1047 return $s;
1048 }
1049
1050 function watchPageLinksLink()
1051 {
1052 global $wgOut, $wgTitle, $wgLang;
1053
1054 if ( ! $wgOut->isArticleRelated() ) {
1055 $s = "(" . wfMsg( "notanarticle" ) . ")";
1056 } else {
1057 $s = $this->makeKnownLink( $wgLang->specialPage(
1058 "Recentchangeslinked" ), wfMsg( "recentchangeslinked" ),
1059 "target=" . $wgTitle->getPrefixedURL() );
1060 }
1061 return $s;
1062 }
1063
1064 function otherLanguages()
1065 {
1066 global $wgOut, $wgLang, $wgTitle, $wgUseNewInterlanguage;
1067
1068 $a = $wgOut->getLanguageLinks();
1069 # TEST THIS @@@
1070 if ( 0 == count( $a ) ) {
1071 if ( !$wgUseNewInterlanguage ) return "";
1072 $ns = $wgLang->getNsIndex ( $wgTitle->getNamespace () ) ;
1073 if ( $ns != 0 AND $ns != 1 ) return "" ;
1074 $pn = "Intl" ;
1075 $x = "mode=addlink&xt=".$wgTitle->getDBkey() ;
1076 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1077 wfMsg( "intl" ) , $x );
1078 }
1079
1080 if ( !$wgUseNewInterlanguage ) {
1081 $s = wfMsg( "otherlanguages" ) . ": ";
1082 } else {
1083 global $wgLanguageCode ;
1084 $x = "mode=zoom&xt=".$wgTitle->getDBkey() ;
1085 $x .= "&xl=".$wgLanguageCode ;
1086 $s = $this->makeKnownLink( $wgLang->specialPage( "Intl" ),
1087 wfMsg( "otherlanguages" ) , $x ) . ": " ;
1088 }
1089
1090 $s = wfMsg( "otherlanguages" ) . ": ";
1091 $first = true;
1092 if($wgLang->isRTL()) $s .= "<span dir='LTR'>";
1093 foreach( $a as $l ) {
1094 if ( ! $first ) { $s .= " | "; }
1095 $first = false;
1096
1097 $nt = Title::newFromText( $l );
1098 $url = $nt->getFullURL();
1099 $text = $wgLang->getLanguageName( $nt->getInterwiki() );
1100
1101 if ( "" == $text ) { $text = $l; }
1102 $style = $this->getExternalLinkAttributes( $l, $text );
1103 $s .= "<a href=\"{$url}\"{$style}>{$text}</a>";
1104 }
1105 if($wgLang->isRTL()) $s .= "</span>";
1106 return $s;
1107 }
1108
1109 function bugReportsLink()
1110 {
1111 $s = $this->makeKnownLink( wfMsg( "bugreportspage" ),
1112 wfMsg( "bugreports" ) );
1113 return $s;
1114 }
1115
1116 function dateLink()
1117 {
1118 global $wgLinkCache;
1119 $t1 = Title::newFromText( gmdate( "F j" ) );
1120 $t2 = Title::newFromText( gmdate( "Y" ) );
1121
1122 $wgLinkCache->suspend();
1123 $id = $t1->getArticleID();
1124 $wgLinkCache->resume();
1125
1126 if ( 0 == $id ) {
1127 $s = $this->makeBrokenLink( $t1->getText() );
1128 } else {
1129 $s = $this->makeKnownLink( $t1->getText() );
1130 }
1131 $s .= ", ";
1132
1133 $wgLinkCache->suspend();
1134 $id = $t2->getArticleID();
1135 $wgLinkCache->resume();
1136
1137 if ( 0 == $id ) {
1138 $s .= $this->makeBrokenLink( $t2->getText() );
1139 } else {
1140 $s .= $this->makeKnownLink( $t2->getText() );
1141 }
1142 return $s;
1143 }
1144
1145 function talkLink()
1146 {
1147 global $wgLang, $wgTitle, $wgLinkCache;
1148
1149 $tns = $wgTitle->getNamespace();
1150 if ( -1 == $tns ) { return ""; }
1151
1152 $pn = $wgTitle->getText();
1153 $tp = wfMsg( "talkpage" );
1154 if ( Namespace::isTalk( $tns ) ) {
1155 $lns = Namespace::getSubject( $tns );
1156 switch($tns) {
1157 case 1:
1158 $text = wfMsg("articlepage");
1159 break;
1160 case 3:
1161 $text = wfMsg("userpage");
1162 break;
1163 case 5:
1164 $text = wfMsg("wikipediapage");
1165 break;
1166 case 7:
1167 $text = wfMsg("imagepage");
1168 break;
1169 default:
1170 $text= wfMsg("articlepage");
1171 }
1172 } else {
1173
1174 $lns = Namespace::getTalk( $tns );
1175 $text=$tp;
1176 }
1177 $n = $wgLang->getNsText( $lns );
1178 if ( "" == $n ) { $link = $pn; }
1179 else { $link = "{$n}:{$pn}"; }
1180
1181 $wgLinkCache->suspend();
1182 $s = $this->makeLink( $link, $text );
1183 $wgLinkCache->resume();
1184
1185 return $s;
1186 }
1187
1188 function commentLink()
1189 {
1190 global $wgLang, $wgTitle, $wgLinkCache;
1191
1192 $tns = $wgTitle->getNamespace();
1193 if ( -1 == $tns ) { return ""; }
1194
1195 $lns = ( Namespace::isTalk( $tns ) ) ? $tns : Namespace::getTalk( $tns );
1196
1197 # assert Namespace::isTalk( $lns )
1198
1199 $n = $wgLang->getNsText( $lns );
1200 $pn = $wgTitle->getText();
1201
1202 $link = "{$n}:{$pn}";
1203
1204 $wgLinkCache->suspend();
1205 $s = $this->makeKnownLink($link, wfMsg("postcomment"), "action=edit&section=new");
1206 $wgLinkCache->resume();
1207
1208 return $s;
1209 }
1210
1211 # After all the page content is transformed into HTML, it makes
1212 # a final pass through here for things like table backgrounds.
1213 #
1214 function transformContent( $text )
1215 {
1216 return $text;
1217 }
1218
1219 # Note: This function MUST call getArticleID() on the link,
1220 # otherwise the cache won't get updated properly. See LINKCACHE.DOC.
1221 #
1222 function makeLink( $title, $text = "", $query = "", $trail = "" ) {
1223 wfProfileIn( "Skin::makeLink" );
1224 $nt = Title::newFromText( $title );
1225 if ($nt) {
1226 $result = $this->makeLinkObj( Title::newFromText( $title ), $text, $query, $trail );
1227 } else {
1228 wfDebug( "Invalid title passed to Skin::makeLink(): \"$title\"\n" );
1229 $result = $text == "" ? $title : $text;
1230 }
1231
1232 wfProfileOut( "Skin::makeLink" );
1233 return $result;
1234 }
1235
1236 function makeKnownLink( $title, $text = "", $query = "", $trail = "" ) {
1237 $nt = Title::newFromText( $title );
1238 if ($nt) {
1239 return $this->makeKnownLinkObj( Title::newFromText( $title ), $text, $query, $trail );
1240 } else {
1241 wfDebug( "Invalid title passed to Skin::makeKnownLink(): \"$title\"\n" );
1242 return $text == "" ? $title : $text;
1243 }
1244 }
1245
1246 function makeBrokenLink( $title, $text = "", $query = "", $trail = "" ) {
1247 $nt = Title::newFromText( $title );
1248 if ($nt) {
1249 return $this->makeBrokenLinkObj( Title::newFromText( $title ), $text, $query, $trail );
1250 } else {
1251 wfDebug( "Invalid title passed to Skin::makeBrokenLink(): \"$title\"\n" );
1252 return $text == "" ? $title : $text;
1253 }
1254 }
1255
1256 function makeStubLink( $title, $text = "", $query = "", $trail = "" ) {
1257 $nt = Title::newFromText( $title );
1258 if ($nt) {
1259 return $this->makeStubLinkObj( Title::newFromText( $title ), $text, $query, $trail );
1260 } else {
1261 wfDebug( "Invalid title passed to Skin::makeStubLink(): \"$title\"\n" );
1262 return $text == "" ? $title : $text;
1263 }
1264 }
1265
1266 # Pass a title object, not a title string
1267 function makeLinkObj( &$nt, $text= "", $query = "", $trail = "", $prefix = "" )
1268 {
1269 global $wgOut, $wgUser;
1270 if ( $nt->isExternal() ) {
1271 $u = $nt->getFullURL();
1272 if ( "" == $text ) { $text = $nt->getPrefixedText(); }
1273 $style = $this->getExternalLinkAttributes( $link, $text );
1274
1275 $inside = "";
1276 if ( "" != $trail ) {
1277 if ( preg_match( "/^([a-z]+)(.*)$$/sD", $trail, $m ) ) {
1278 $inside = $m[1];
1279 $trail = $m[2];
1280 }
1281 }
1282 $retVal = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1283 } elseif ( 0 == $nt->getNamespace() && "" == $nt->getText() ) {
1284 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1285 } elseif ( ( -1 == $nt->getNamespace() ) ||
1286 ( Namespace::getImage() == $nt->getNamespace() ) ) {
1287 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1288 } else {
1289 $aid = $nt->getArticleID() ;
1290 if ( 0 == $aid ) {
1291 $retVal = $this->makeBrokenLinkObj( $nt, $text, $query, $trail, $prefix );
1292 } else {
1293 $threshold = $wgUser->getOption("stubthreshold") ;
1294 if ( $threshold > 0 ) {
1295 $res = wfQuery ( "SELECT LENGTH(cur_text) AS x, cur_namespace, cur_is_redirect FROM cur WHERE cur_id='{$aid}'", DB_READ ) ;
1296
1297 if ( wfNumRows( $res ) > 0 ) {
1298 $s = wfFetchObject( $res );
1299 $size = $s->x;
1300 if ( $s->cur_is_redirect OR $s->cur_namespace != 0 ) {
1301 $size = $threshold*2 ; # Really big
1302 }
1303 wfFreeResult( $res );
1304 } else {
1305 $size = $threshold*2 ; # Really big
1306 }
1307 } else {
1308 $size = 1 ;
1309 }
1310 if ( $size < $threshold ) {
1311 $retVal = $this->makeStubLinkObj( $nt, $text, $query, $trail, $prefix );
1312 } else {
1313 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1314 }
1315 }
1316 }
1317 return $retVal;
1318 }
1319
1320 # Pass a title object, not a title string
1321 function makeKnownLinkObj( &$nt, $text = "", $query = "", $trail = "", $prefix = "" )
1322 {
1323 global $wgOut, $wgTitle;
1324
1325 $fname = "Skin::makeKnownLinkObj";
1326 wfProfileIn( $fname );
1327
1328 $link = $nt->getPrefixedURL();
1329
1330 if ( "" == $link ) {
1331 $u = "";
1332 if ( "" == $text ) { $text = $nt->getFragment(); }
1333 } else {
1334 $u = wfLocalUrlE( $link, $query );
1335 }
1336 if ( "" != $nt->getFragment() ) {
1337 $u .= "#" . wfEscapeHTML( $nt->getFragment() );
1338 }
1339 if ( "" == $text ) { $text = $nt->getPrefixedText(); }
1340 $style = $this->getInternalLinkAttributesObj( $nt, $text );
1341
1342 $inside = "";
1343 if ( "" != $trail ) {
1344 if ( preg_match( wfMsg("linktrail"), $trail, $m ) ) {
1345 $inside = $m[1];
1346 $trail = $m[2];
1347 }
1348 }
1349 $r = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1350 wfProfileOut( $fname );
1351 return $r;
1352 }
1353
1354 # Pass a title object, not a title string
1355 function makeBrokenLinkObj( &$nt, $text = "", $query = "", $trail = "", $prefix = "" )
1356 {
1357 global $wgOut, $wgUser;
1358
1359 $fname = "Skin::makeBrokenLinkObj";
1360 wfProfileIn( $fname );
1361
1362 $link = $nt->getPrefixedURL();
1363
1364 if ( "" == $query ) { $q = "action=edit"; }
1365 else { $q = "action=edit&{$query}"; }
1366 $u = wfLocalUrlE( $link, $q );
1367
1368 if ( "" == $text ) { $text = $nt->getPrefixedText(); }
1369 $style = $this->getInternalLinkAttributesObj( $nt, $text, "yes" );
1370
1371 $inside = "";
1372 if ( "" != $trail ) {
1373 if ( preg_match( wfMsg("linktrail"), $trail, $m ) ) {
1374 $inside = $m[1];
1375 $trail = $m[2];
1376 }
1377 }
1378 if ( $wgOut->isPrintable() ||
1379 ( 1 == $wgUser->getOption( "highlightbroken" ) ) ) {
1380 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1381 } else {
1382 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>?</a>{$trail}";
1383 }
1384
1385 wfProfileOut( $fname );
1386 return $s;
1387 }
1388
1389 # Pass a title object, not a title string
1390 function makeStubLinkObj( &$nt, $text = "", $query = "", $trail = "", $prefix = "" )
1391 {
1392 global $wgOut, $wgUser;
1393
1394 $link = $nt->getPrefixedURL();
1395
1396 $u = wfLocalUrlE( $link, $query );
1397
1398 if ( "" == $text ) { $text = $nt->getPrefixedText(); }
1399 $style = $this->getInternalLinkAttributesObj( $nt, $text, "stub" );
1400
1401 $inside = "";
1402 if ( "" != $trail ) {
1403 if ( preg_match( wfMsg("linktrail"), $trail, $m ) ) {
1404 $inside = $m[1];
1405 $trail = $m[2];
1406 }
1407 }
1408 if ( $wgOut->isPrintable() ||
1409 ( 1 == $wgUser->getOption( "highlightbroken" ) ) ) {
1410 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1411 } else {
1412 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>!</a>{$trail}";
1413 }
1414 return $s;
1415 }
1416
1417 function fnamePart( $url )
1418 {
1419 $basename = strrchr( $url, "/" );
1420 if ( false === $basename ) { $basename = $url; }
1421 else { $basename = substr( $basename, 1 ); }
1422 return wfEscapeHTML( $basename );
1423 }
1424
1425 function makeImage( $url, $alt = "" )
1426 {
1427 global $wgOut;
1428
1429 if ( "" == $alt ) { $alt = $this->fnamePart( $url ); }
1430 $s = "<img src=\"{$url}\" alt=\"{$alt}\">";
1431 return $s;
1432 }
1433
1434 function makeImageLink( $name, $url, $alt = "" ) {
1435 $nt = Title::makeTitle( Namespace::getImage(), $name );
1436 return $this->makeImageLinkObj( $nt, $alt );
1437 }
1438
1439 function makeImageLinkObj( $nt, $alt = "" ) {
1440 global $wgLang, $wgUseImageResize;
1441 $link = $nt->getPrefixedURL();
1442 $name = $nt->getDBKey();
1443 $url = wfImageUrl( $name );
1444 $align = "";
1445 $prefix = $postfix = "";
1446
1447 if ( $wgUseImageResize ) {
1448 # Check if the alt text is of the form "options|alt text"
1449 # Options are:
1450 # * thumbnail make a thumbnail with enlarge-icon and caption, alignment depends on lang
1451 # * left no resizing, just left align. label is used for alt= only
1452 # * right same, but right aligned
1453 # * none same, but not aligned
1454 # * ___px scale to ___ pixels width, no aligning. e.g. use in taxobox
1455
1456 $part = explode( "|", $alt);
1457
1458 $mwThumb =& MagicWord::get( MAG_IMG_THUMBNAIL );
1459 $mwLeft =& MagicWord::get( MAG_IMG_LEFT );
1460 $mwRight =& MagicWord::get( MAG_IMG_RIGHT );
1461 $mwNone =& MagicWord::get( MAG_IMG_NONE );
1462 $mwWidth =& MagicWord::get( MAG_IMG_WIDTH );
1463 $mwCenter =& MagicWord::get( MAG_IMG_CENTER );
1464 $alt = $part[count($part)-1];
1465
1466 $thumb=false;
1467
1468 foreach( $part as $key => $val ) {
1469 if ( ! is_null( $mwThumb->matchVariableStartToEnd($val) ) ) {
1470 $thumb=true;
1471 } elseif ( ! is_null( $mwRight->matchVariableStartToEnd($val) ) ) {
1472 # remember to set an alignment, don't render immediately
1473 $align = "right";
1474 } elseif ( ! is_null( $mwLeft->matchVariableStartToEnd($val) ) ) {
1475 # remember to set an alignment, don't render immediately
1476 $align = "left";
1477 } elseif ( ! is_null( $mwCenter->matchVariableStartToEnd($val) ) ) {
1478 # remember to set an alignment, don't render immediately
1479 $align = "center";
1480 } elseif ( ! is_null( $mwNone->matchVariableStartToEnd($val) ) ) {
1481 # remember to set an alignment, don't render immediately
1482 $align = "none";
1483 } elseif ( ! is_null( $match = $mwWidth->matchVariableStartToEnd($val) ) ) {
1484 # $match is the image width in pixels
1485 $width = intval($match);
1486 }
1487 }
1488 if ( "center" == $align )
1489 {
1490 $prefix = "<center>";
1491 $postfix = "</center>";
1492 $align = "none";
1493 }
1494
1495 if ( $thumb ) {
1496
1497 # Create a thumbnail. Alignment depends on language
1498 # writing direction, # right aligned for left-to-right-
1499 # languages ("Western languages"), left-aligned
1500 # for right-to-left-languages ("Semitic languages")
1501 #
1502 # If thumbnail width has not been provided, it is set
1503 # here to 180 pixels
1504 if ( $align == "" ) {
1505 $align = $wgLang->isRTL() ? "left" : "right";
1506 }
1507 if ( ! isset($width) ) {
1508 $width = 180;
1509 }
1510 return $prefix.$this->makeThumbLinkObj( $nt, $alt, $align, $width ).$postfix;
1511
1512 } elseif ( isset($width) ) {
1513
1514 # Create a resized image, without the additional thumbnail
1515 # features
1516 $url = $this->createThumb( $name, $width );
1517 }
1518 } # endif $wgUseImageResize
1519
1520 if ( empty( $alt ) ) {
1521 $alt = preg_replace( '/\.(.+?)^/', '', $name );
1522 }
1523 $alt = htmlspecialchars( $alt );
1524
1525 $u = wfLocalUrlE( $link );
1526 $s = "<a href=\"{$u}\" class='image' title=\"{$alt}\">" .
1527 "<img border=\"0\" src=\"{$url}\" alt=\"{$alt}\"></a>";
1528 if ( "" != $align ) {
1529 $s = "<div class=\"float{$align}\">{$s}</div>";
1530 }
1531 return $prefix.$s.$postfix;
1532 }
1533
1534 function createThumb( $name, $width ) {
1535 global $wgUploadDirectory;
1536 global $wgImageMagickConvertCommand;
1537 global $wgUseImageMagick;
1538 global $wgUseSquid, $wgInternalServer;
1539 $imgPath = wfImagePath( $name );
1540 $thumbName = $width."px-".$icon.$name;
1541 $thumbPath = wfImageThumbDir( $thumbName )."/".$thumbName;
1542 $thumbUrl = wfImageThumbUrl( $thumbName );
1543
1544 if ( (! file_exists( $thumbPath ) && file_exists( $imgPath ))
1545 || ( filemtime($thumbPath) < filemtime($imgPath) ) ) {
1546 # Squid purging
1547 if ( $wgUseSquid ) {
1548 $urlArr = Array(
1549 $wgInternalServer.$thumbUrl
1550 );
1551 wfPurgeSquidServers($urlArr);
1552 }
1553
1554 if ( $wgUseImageMagick ) {
1555 # use ImageMagick
1556 $cmd = $wgImageMagickConvertCommand .
1557 " -quality 85 -geometry {$width} ".
1558 escapeshellarg($imgPath) . " " .
1559 escapeshellarg($thumbPath);
1560 $conv = shell_exec( $cmd );
1561 } else {
1562 # Use PHP's builtin GD library functions.
1563 #
1564 # First find out what kind of file this is, and select the correct
1565 # input routine for this.
1566 list($src_width, $src_height, $src_type, $src_attr) = getimagesize( $imgPath );
1567 switch( $src_type ) {
1568 case 1: # GIF
1569 $src_image = imagecreatefromgif( $imgPath );
1570 break;
1571 case 2: # JPG
1572 $src_image = imagecreatefromjpeg( $imgPath );
1573 break;
1574 case 3: # PNG
1575 $src_image = imagecreatefrompng( $imgPath );
1576 break;
1577 case 15: # WBMP for WML
1578 $src_image = imagecreatefromwbmp( $imgPath );
1579 break;
1580 case 16: # XBM
1581 $src_image = imagecreatefromxbm( $imgPath );
1582 break;
1583 default:
1584 return "Image type not supported";
1585 break;
1586 }
1587 $height = floor( $src_height * ( $width/$src_width ) );
1588 $dst_image = imagecreatetruecolor( $width, $height );
1589 imagecopyresampled( $dst_image, $src_image,
1590 0,0,0,0,
1591 $width, $height, $src_width, $src_height );
1592 switch( $src_type ) {
1593 case 1: # GIF
1594 case 3: # PNG
1595 case 15: # WBMP
1596 case 16: # XBM
1597 #$thumbUrl .= ".png";
1598 #$thumbPath .= ".png";
1599 imagepng( $dst_image, $thumbPath );
1600 break;
1601 case 2: # JPEG
1602 #$thumbUrl .= ".jpg";
1603 #$thumbPath .= ".jpg";
1604 imageinterlace( $dst_image );
1605 imagejpeg( $dst_image, $thumbPath, 95 );
1606 break;
1607 default:
1608 break;
1609 }
1610 imagedestroy( $dst_image );
1611 imagedestroy( $src_image );
1612
1613
1614 }
1615 #
1616 # Check for zero-sized thumbnails. Those can be generated when
1617 # no disk space is available or some other error occurs
1618 #
1619 $thumbstat = stat( $thumbPath );
1620 $imgstat = stat( $imgPath );
1621 if( $thumbstat["size"] == 0 )
1622 {
1623 unlink( $thumbPath );
1624 }
1625
1626 }
1627 return $thumbUrl;
1628 }
1629
1630 function makeThumbLinkObj( $nt, $label = "", $align = "right", $boxwidth = 180 ) {
1631 global $wgUploadPath;
1632 $name = $nt->getDBKey();
1633 $image = Title::makeTitle( Namespace::getImage(), $name );
1634 $link = $image->getPrefixedURL();
1635 $url = wfImageUrl( $name );
1636 $path = wfImagePath( $name );
1637
1638 $label = htmlspecialchars( $label );
1639
1640 list($width, $height, $type, $attr) = getimagesize( $path );
1641 $boxheight = intval( $height/($width/$boxwidth) );
1642 if ( $boxwidth > $width ) {
1643 $boxwidth = $width;
1644 $boxheight = $height;
1645 }
1646
1647 $thumbUrl = $this->createThumb( $name, $boxwidth );
1648
1649 $u = wfLocalUrlE( $link );
1650
1651 $more = wfMsg( "thumbnail-more" );
1652
1653 $s = "<div class=\"thumbnail-{$align}\" style=\"width:{$boxwidth}px;\">" .
1654 "<a href=\"{$u}\" class=\"internal\" title=\"{$label}\">" .
1655 "<img border=\"0\" src=\"{$thumbUrl}\" alt=\"{$label}\" width=\"{$boxwidth}\" height=\"{$boxheight}\"></a>" .
1656 "<a href=\"{$u}\" class=\"internal\" title=\"{$more}\">" .
1657 "<img border=\"0\" src=\"{$wgUploadPath}/magnify-clip.png\" width=\"26\" height=\"24\" align=\"right\" alt=\"{$more}\"></a>" .
1658 "<p>{$label}</p></div>";
1659 return $s;
1660 }
1661
1662 function makeMediaLink( $name, $url, $alt = "" ) {
1663 $nt = Title::makeTitle( Namespace::getMedia(), $name );
1664 return $this->makeMediaLinkObj( $nt, $alt );
1665 }
1666
1667 function makeMediaLinkObj( $nt, $alt = "" )
1668 {
1669 $name = $nt->getDBKey();
1670 $url = wfImageUrl( $name );
1671 if ( empty( $alt ) ) {
1672 $alt = preg_replace( '/\.(.+?)^/', '', $name );
1673 }
1674
1675 $u = htmlspecialchars( $url );
1676 $s = "<a href=\"{$u}\" class='internal' title=\"{$alt}\">{$alt}</a>";
1677 return $s;
1678 }
1679
1680 function specialLink( $name, $key = "" )
1681 {
1682 global $wgLang;
1683
1684 if ( "" == $key ) { $key = strtolower( $name ); }
1685 $pn = $wgLang->ucfirst( $name );
1686 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1687 wfMsg( $key ) );
1688 }
1689
1690 # Called by history lists and recent changes
1691 #
1692
1693 # Returns text for the start of the tabular part of RC
1694 function beginRecentChangesList()
1695 {
1696 $this->rc_cache = array() ;
1697 $this->rcMoveIndex = 0;
1698 $this->rcCacheIndex = 0 ;
1699 $this->lastdate = "";
1700 return "";
1701 }
1702
1703 function beginImageHistoryList()
1704 {
1705 $s = "\n<h2>" . wfMsg( "imghistory" ) . "</h2>\n" .
1706 "<p>" . wfMsg( "imghistlegend" ) . "\n<ul>";
1707 return $s;
1708 }
1709
1710 # Returns text for the end of RC
1711 # If enhanced RC is in use, returns pretty much all the text
1712 function endRecentChangesList()
1713 {
1714 $s = $this->recentChangesBlock() ;
1715 $s .= "</ul>\n";
1716 return $s;
1717 }
1718
1719 # Enhanced RC ungrouped line
1720 function recentChangesBlockLine ( $rcObj )
1721 {
1722 global $wgUploadPath, $wgLang ;
1723
1724 # Get rc_xxxx variables
1725 extract( $rcObj->mAttribs ) ;
1726 $curIdEq = "curid=$rc_cur_id";
1727
1728 # Spacer image
1729 $r = "" ;
1730 $r .= "<img src='{$wgUploadPath}/Arr_.png' width=12 height=12 border=0>" ; $r .= "<tt>" ;
1731
1732 if ( $rc_type == RC_MOVE ) {
1733 $r .= "&nbsp;&nbsp;";
1734 } else {
1735 # M & N (minor & new)
1736 $M = wfMsg( "minoreditletter" );
1737 $N = wfMsg( "newpageletter" );
1738
1739 if ( $rc_type == RC_NEW ) {
1740 $r .= $N ;
1741 } else {
1742 $r .= "&nbsp;" ;
1743 }
1744 if ( $rc_minor ) {
1745 $r .= $M ;
1746 } else {
1747 $r .= "&nbsp;" ;
1748 }
1749 }
1750
1751 # Timestamp
1752 $r .= " ".$rcObj->timestamp." " ;
1753 $r .= "</tt>" ;
1754
1755 # Article link
1756 $link = $rcObj->link ;
1757 if ( $rcObj->watched ) $link = "<strong>{$link}</strong>" ;
1758 $r .= $link ;
1759
1760 # Cur
1761 $r .= " (" ;
1762 $r .= $rcObj->curlink ;
1763 $r .= "; " ;
1764
1765 # Hist
1766 $r .= $this->makeKnownLinkObj( $rcObj->getTitle(), wfMsg( "hist" ), "{$curIdEq}&action=history" );
1767
1768 # User/talk
1769 $r .= ") . . ".$rcObj->userlink ;
1770 $r .= $rcObj->usertalklink ;
1771
1772 # Comment
1773 if ( $rc_comment != "" && $rc_type != RC_MOVE ) {
1774 $r .= $wgLang->emphasize( " (".wfEscapeHTML($rc_comment).")" );
1775 }
1776 $r .= "<br>\n" ;
1777 return $r ;
1778 }
1779
1780 # Enhanced RC group
1781 function recentChangesBlockGroup ( $block )
1782 {
1783 global $wgUploadPath, $wgLang ;
1784
1785 $r = "" ;
1786 $M = wfMsg( "minoreditletter" );
1787 $N = wfMsg( "newpageletter" );
1788
1789 # Collate list of users
1790 $isnew = false ;
1791 $userlinks = array () ;
1792 foreach ( $block AS $rcObj ) {
1793 $oldid = $rcObj->mAttribs['rc_last_oldid'];
1794 if ( $rcObj->mAttribs['rc_new'] ) $isnew = true ;
1795 $u = $rcObj->userlink ;
1796 if ( !isset ( $userlinks[$u] ) ) $userlinks[$u] = 0 ;
1797 $userlinks[$u]++ ;
1798 }
1799
1800 # Sort the list and convert to text
1801 krsort ( $userlinks ) ;
1802 asort ( $userlinks ) ;
1803 $users = array () ;
1804 foreach ( $userlinks as $userlink => $count) {
1805 $text = $userlink ;
1806 if ( $count > 1 ) $text .= " ({$count}&times;)" ;
1807 array_push ( $users , $text ) ;
1808 }
1809 $users = " <font size='-1'>[".implode("; ",$users)."]</font>" ;
1810
1811 # Arrow
1812 $rci = "RCI{$this->rcCacheIndex}" ;
1813 $rcl = "RCL{$this->rcCacheIndex}" ;
1814 $rcm = "RCM{$this->rcCacheIndex}" ;
1815 $tl = "<a href='javascript:toggleVisibility(\"{$rci}\",\"{$rcm}\",\"{$rcl}\")'>" ;
1816 $tl .= "<span id='{$rcm}'><img src='{$wgUploadPath}/Arr_r.png' width=12 height=12 border=0></span>" ;
1817 $tl .= "<span id='{$rcl}' style='display:none'><img src='{$wgUploadPath}/Arr_d.png' width=12 height=12 border=0></span>" ;
1818 $tl .= "</a>" ;
1819 $r .= $tl ;
1820
1821 # Main line
1822 # M/N
1823 $r .= "<tt>" ;
1824 if ( $isnew ) $r .= $N ;
1825 else $r .= "&nbsp;" ;
1826 $r .= "&nbsp;" ; # Minor
1827
1828 # Timestamp
1829 $r .= " ".$block[0]->timestamp." " ;
1830 $r .= "</tt>" ;
1831
1832 # Article link
1833 $link = $block[0]->link ;
1834 if ( $block[0]->watched ) $link = "<strong>{$link}</strong>" ;
1835 $r .= $link ;
1836
1837 $curIdEq = "curid=" . $block[0]->mAttribs['rc_cur_id'];
1838 if ( $block[0]->mAttribs['rc_type'] != RC_LOG ) {
1839 # Changes
1840 $r .= " (".count($block)." " ;
1841 if ( $isnew ) $r .= wfMsg("changes");
1842 else $r .= $this->makeKnownLinkObj( $block[0]->getTitle() , wfMsg("changes") ,
1843 "{$curIdEq}&diff=0&oldid=".$oldid ) ;
1844 $r .= "; " ;
1845
1846 # History
1847 $r .= $this->makeKnownLinkObj( $block[0]->getTitle(), wfMsg( "history" ), "{$curIdEq}&action=history" );
1848 $r .= ")" ;
1849 }
1850
1851 $r .= $users ;
1852 $r .= "<br>\n" ;
1853
1854 # Sub-entries
1855 $r .= "<div id='{$rci}' style='display:none'>" ;
1856 foreach ( $block AS $rcObj ) {
1857 # Get rc_xxxx variables
1858 extract( $rcObj->mAttribs );
1859
1860 $r .= "<img src='{$wgUploadPath}/Arr_.png' width=12 height=12 border=0>";
1861 $r .= "<tt>&nbsp; &nbsp; &nbsp; &nbsp;" ;
1862 if ( $rc_new ) $r .= $N ;
1863 else $r .= "&nbsp;" ;
1864 if ( $rc_minor ) $r .= $M ;
1865 else $r .= "&nbsp;" ;
1866 $r .= "</tt>" ;
1867
1868 $o = "" ;
1869 if ( $rc_last_oldid != 0 ) {
1870 $o = "oldid=".$rc_last_oldid ;
1871 }
1872 if ( $rc_type == RC_LOG ) {
1873 $link = $rcObj->timestamp ;
1874 } else {
1875 $link = $this->makeKnownLink( $rcObj->getTitle(), $rcObj->timestamp , "{$curIdEq}&$o" ) ;
1876 }
1877 $link = "<tt>{$link}</tt>" ;
1878
1879 $r .= $link ;
1880 $r .= " (" ;
1881 $r .= $rcObj->curlink ;
1882 $r .= "; " ;
1883 $r .= $rcObj->lastlink ;
1884 $r .= ") . . ".$rcObj->userlink ;
1885 $r .= $rcObj->usertalklink ;
1886 if ( $rc_comment != "" ) {
1887 $r .= $wgLang->emphasize( " (".wfEscapeHTML($rc_comment).")" ) ;
1888 }
1889 $r .= "<br>\n" ;
1890 }
1891 $r .= "</div>\n" ;
1892
1893 $this->rcCacheIndex++ ;
1894 return $r ;
1895 }
1896
1897 # If enhanced RC is in use, this function takes the previously cached
1898 # RC lines, arranges them, and outputs the HTML
1899 function recentChangesBlock ()
1900 {
1901 global $wgUploadPath ;
1902 if ( count ( $this->rc_cache ) == 0 ) return "" ;
1903 #$k = array_keys ( $this->rc_cache ) ;
1904 foreach ( $this->rc_cache AS $secureName => $block ) {
1905 if ( count ( $block ) < 2 ) {
1906 $r .= $this->recentChangesBlockLine ( array_shift ( $block ) ) ;
1907 } else {
1908 $r .= $this->recentChangesBlockGroup ( $block ) ;
1909 }
1910 }
1911
1912 return "<div align=left>{$r}</div>" ;
1913 }
1914
1915 # Called in a loop over all displayed RC entries
1916 # Either returns the line, or caches it for later use
1917 function recentChangesLine( &$rc, $watched = false )
1918 {
1919 global $wgUser ;
1920 $usenew = $wgUser->getOption( "usenewrc" );
1921 if ( $usenew )
1922 $line = $this->recentChangesLineNew ( $rc, $watched ) ;
1923 else
1924 $line = $this->recentChangesLineOld ( $rc, $watched ) ;
1925 return $line ;
1926 }
1927
1928 function recentChangesLineOld( &$rc, $watched = false )
1929 {
1930 global $wgTitle, $wgLang, $wgUser;
1931
1932 # Extract DB fields into local scope
1933 extract( $rc->mAttribs );
1934 $curIdEq = "curid=" . $rc_cur_id;
1935
1936 # Make date header if necessary
1937 $date = $wgLang->date( $rc_timestamp, true);
1938 $s = "";
1939 if ( $date != $this->lastdate ) {
1940 if ( "" != $this->lastdate ) { $s .= "</ul>\n"; }
1941 $s .= "<h4>{$date}</h4>\n<ul>";
1942 $this->lastdate = $date;
1943 }
1944 $s .= "<li> ";
1945
1946 if ( $rc_type == RC_MOVE ) {
1947 # Diff
1948 $s .= "(" . wfMsg( "diff" ) . ") (";
1949 # Hist
1950 $s .= $this->makeKnownLinkObj( $rc->getMovedToTitle(), wfMsg( "hist" ), "action=history" ) .
1951 ") . . ";
1952
1953 # "[[x]] moved to [[y]]"
1954
1955 $s .= wfMsg( "1movedto2", $this->makeKnownLinkObj( $rc->getTitle(), "", "redirect=no" ),
1956 $this->makeKnownLinkObj( $rc->getMovedToTitle(), "" ) );
1957
1958 } else {
1959 # Diff link
1960 if ( $rc_type == RC_NEW || $rc_type == RC_LOG ) {
1961 $diffLink = wfMsg( "diff" );
1962 } else {
1963 $diffLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( "diff" ),
1964 "{$curIdEq}&diff={$rc_this_oldid}&oldid={$rc_last_oldid}" );
1965 }
1966 $s .= "($diffLink) (";
1967
1968 # History link
1969 $s .= $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( "hist" ), "{$curIdEq}&action=history" );
1970 $s .= ") . . ";
1971
1972 # M and N (minor and new)
1973 $M = wfMsg( "minoreditletter" );
1974 $N = wfMsg( "newpageletter" );
1975 if ( $rc_minor ) { $s .= " <strong>{$M}</strong>"; }
1976 if ( $rc_type == RC_NEW ) { $s .= "<strong>{$N}</strong>"; }
1977
1978 # Article link
1979 $articleLink = $this->makeKnownLinkObj( $rc->getTitle(), "" );
1980
1981 if ( $watched ) {
1982 $articleLink = "<strong>{$articleLink}</strong>";
1983 }
1984 $s .= " $articleLink";
1985
1986 }
1987
1988 # Timestamp
1989 $s .= "; " . $wgLang->time( $rc_timestamp, true ) . " . . ";
1990
1991 # User link (or contributions for unregistered users)
1992 if ( 0 == $rc_user ) {
1993 $userLink = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
1994 $rc_user_text, "target=" . $rc_user_text );
1995 } else {
1996 $userLink = $this->makeLink( $wgLang->getNsText( NS_USER ) . ":{$rc_user_text}", $rc_user_text );
1997 }
1998 $s .= $userLink;
1999
2000 # User talk link
2001 $talkname=$wgLang->getNsText(NS_TALK); # use the shorter name
2002 global $wgDisableAnonTalk;
2003 if( 0 == $rc_user && $wgDisableAnonTalk ) {
2004 $userTalkLink = "";
2005 } else {
2006 $utns=$wgLang->getNsText(NS_USER_TALK);
2007 $userTalkLink= $this->makeLink($utns . ":{$rc_user_text}", $talkname );
2008 }
2009 # Block link
2010 $blockLink="";
2011 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2012 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2013 "Blockip" ), wfMsg( "blocklink" ), "ip={$rc_user_text}" );
2014
2015 }
2016 if($blockLink) {
2017 if($userTalkLink) $userTalkLink .= " | ";
2018 $userTalkLink .= $blockLink;
2019 }
2020 if($userTalkLink) $s.=" ({$userTalkLink})";
2021
2022 # Add comment
2023 if ( "" != $rc_comment && "*" != $rc_comment && $rc_type != RC_MOVE ) {
2024 $s .= $wgLang->emphasize(" (" . wfEscapeHTML( $rc_comment ) . ")");
2025 }
2026 $s .= "</li>\n";
2027
2028 return $s;
2029 }
2030
2031 # function recentChangesLineNew( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched = false, $oldid = 0 , $diffid = 0 )
2032 function recentChangesLineNew( &$baseRC, $watched = false )
2033 {
2034 global $wgTitle, $wgLang, $wgUser;
2035
2036 # Create a specialised object
2037 $rc = RCCacheEntry::newFromParent( $baseRC ) ;
2038
2039 # Extract fields from DB into the function scope (rc_xxxx variables)
2040 extract( $rc->mAttribs );
2041 $curIdEq = "curid=" . $rc_cur_id;
2042
2043 # If it's a new day, add the headline and flush the cache
2044 $date = $wgLang->date( $rc_timestamp, true);
2045 $ret = "" ;
2046 if ( $date != $this->lastdate ) {
2047 # Process current cache
2048 $ret = $this->recentChangesBlock () ;
2049 $this->rc_cache = array() ;
2050 $ret .= "<h4>{$date}</h4>\n";
2051 $this->lastdate = $date;
2052 }
2053
2054 # Make article link
2055 if ( $rc_type == RC_MOVE ) {
2056 $clink = $this->makeKnownLinkObj( $rc->getTitle(), "", "redirect=no" );
2057 $clink .= " " . wfMsg("movedto") . " ";
2058 $clink .= $this->makeKnownLinkObj( $rc->getMovedToTitle(), "" );
2059 } else {
2060 $clink = $this->makeKnownLinkObj( $rc->getTitle(), "" ) ;
2061 }
2062
2063 $time = $wgLang->time( $rc_timestamp, true );
2064 $rc->watched = $watched ;
2065 $rc->link = $clink ;
2066 $rc->timestamp = $time;
2067
2068 # Make "cur" link
2069 if ( ( $rc_type == RC_NEW && $rc_this_oldid == 0 ) || $rc_type == RC_LOG || $rc_type == RC_MOVE) {
2070 $curLink = wfMsg( "cur" );
2071 } else {
2072 $curLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( "cur" ),
2073 "{$curIdEq}&diff=0&oldid={$rc_this_oldid}" );
2074 }
2075
2076 # Make "last" link
2077 $titleObj = $rc->getTitle();
2078 if ( $rc_last_oldid == 0 || $rc_type == RC_LOG || $rc_type == RC_MOVE ) {
2079 $lastLink = wfMsg( "last" );
2080 } else {
2081 $lastLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( "last" ),
2082 "{$curIdEq}&diff={$rc_this_oldid}&oldid={$rc_last_oldid}" );
2083 }
2084
2085 # Make user link (or user contributions for unregistered users)
2086 if ( 0 == $rc_user ) {
2087 $userLink = $this->makeKnownLink( $wgLang->specialPage( "Contributions" ),
2088 $rc_user_text, "target=" . $rc_user_text );
2089 } else {
2090 $userLink = $this->makeLink( $wgLang->getNsText(
2091 Namespace::getUser() ) . ":{$rc_user_text}", $rc_user_text );
2092 }
2093
2094 $rc->userlink = $userLink ;
2095 $rc->lastlink = $lastLink ;
2096 $rc->curlink = $curLink ;
2097
2098 # Make user talk link
2099 $utns=$wgLang->getNsText(NS_USER_TALK);
2100 $talkname=$wgLang->getNsText(NS_TALK); # use the shorter name
2101 $userTalkLink= $this->makeLink($utns . ":{$rc_user_text}", $talkname );
2102
2103 global $wgDisableAnonTalk;
2104 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2105 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2106 "Blockip" ), wfMsg( "blocklink" ), "ip={$rc_user_text}" );
2107 if( $wgDisableAnonTalk )
2108 $rc->usertalklink = " ({$blockLink})";
2109 else
2110 $rc->usertalklink = " ({$userTalkLink} | {$blockLink})";
2111 } else {
2112 if( $wgDisableAnonTalk && ($rc_user == 0) )
2113 $rc->usertalklink = "";
2114 else
2115 $rc->usertalklink = " ({$userTalkLink})";
2116 }
2117
2118 # Put accumulated information into the cache, for later display
2119 # Page moves go on their own line
2120 $title = $rc->getTitle();
2121 $secureName = $title->getPrefixedDBkey();
2122 if ( $rc_type == RC_MOVE ) {
2123 # Use an @ character to prevent collision with page names
2124 $this->rc_cache["@@" . ($rcMoveIndex++)] = array($rc);
2125 } else {
2126 if ( !isset ( $this->rc_cache[$secureName] ) ) $this->rc_cache[$secureName] = array() ;
2127 array_push ( $this->rc_cache[$secureName] , $rc ) ;
2128 }
2129 return $ret;
2130 }
2131
2132 function endImageHistoryList()
2133 {
2134 $s = "</ul>\n";
2135 return $s;
2136 }
2137
2138 function imageHistoryLine( $iscur, $ts, $img, $u, $ut, $size, $c )
2139 {
2140 global $wgUser, $wgLang, $wgTitle;
2141
2142 $dt = $wgLang->timeanddate( $ts, true );
2143 $del = wfMsg( "deleteimg" );
2144 $cur = wfMsg( "cur" );
2145
2146 if ( $iscur ) {
2147 $url = wfImageUrl( $img );
2148 $rlink = $cur;
2149 if ( $wgUser->isSysop() ) {
2150 $link = wfLocalUrlE( $wgTitle->getPrefixedText(), "image=" . $wgTitle->getURL() .
2151 "&action=delete" );
2152 $style = $this->getInternalLinkAttributes( $link, $del );
2153
2154 $dlink = "<a href=\"{$link}\"{$style}>{$del}</a>";
2155 } else {
2156 $dlink = $del;
2157 }
2158 } else {
2159 $url = wfEscapeHTML( wfImageArchiveUrl( $img ) );
2160 if( $wgUser->getID() != 0 ) {
2161 $rlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2162 wfMsg( "revertimg" ), "action=revert&oldimage=" .
2163 urlencode( $img ) );
2164 $dlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2165 $del, "action=delete&oldimage=" . urlencode( $img ) );
2166 } else {
2167 # Having live active links for non-logged in users
2168 # means that bots and spiders crawling our site can
2169 # inadvertently change content. Baaaad idea.
2170 $rlink = wfMsg( "revertimg" );
2171 $dlink = $del;
2172 }
2173 }
2174 if ( 0 == $u ) { $ul = $ut; }
2175 else { $ul = $this->makeLink( $wgLang->getNsText(
2176 Namespace::getUser() ) . ":{$ut}", $ut ); }
2177
2178 $nb = wfMsg( "nbytes", $size );
2179 $style = $this->getInternalLinkAttributes( $url, $dt );
2180
2181 $s = "<li> ({$dlink}) ({$rlink}) <a href=\"{$url}\"{$style}>{$dt}</a>"
2182 . " . . {$ul} ({$nb})";
2183
2184 if ( "" != $c && "*" != $c ) {
2185 $s .= $wgLang->emphasize(" (" . wfEscapeHTML( $c ) . ")");
2186 }
2187 $s .= "</li>\n";
2188 return $s;
2189 }
2190
2191 function tocIndent($level) {
2192
2193 while($level-->0) $rv.="<div style=\"margin-left:2em;\">\n";
2194 return $rv;
2195
2196 }
2197
2198 function tocUnindent($level) {
2199 $rv = "";
2200 while($level-->0) $rv.="</div>\n";
2201 return $rv;
2202 }
2203
2204 // parameter level defines if we are on an indentation level
2205 function tocLine($anchor,$tocline,$level) {
2206
2207 if($level) {
2208
2209 return "<A CLASS=\"internal\" HREF=\"#".$anchor."\">".$tocline."</A><BR>\n";
2210 } else {
2211
2212 return "<div style=\"margin-bottom:0px;\">\n".
2213 "<A CLASS=\"internal\" HREF=\"#".$anchor."\">".$tocline."</A><BR>\n".
2214 "</div>\n";
2215 }
2216
2217 }
2218
2219 function tocTable($toc) {
2220 // note to CSS fanatics: putting this in a div does not work -- div won't auto-expand
2221 global $printable;
2222
2223 if (!$printable) {
2224 $hideline = " <script type='text/javascript'>showTocToggle(\"" . wfMsg("showtoc") . "\",\"" . wfMsg("hidetoc") . "\")</script>";
2225 }
2226 return
2227 "<p><table border=\"0\" id=\"toc\"><tr><td align=\"center\">\n".
2228 "<b>".wfMsg("toc")."</b>" .
2229 $hideline .
2230 "</td></tr><tr id='tocinside'><td>\n".
2231 $toc."</td></tr></table><P>\n";
2232 }
2233
2234 # These two do not check for permissions: check $wgTitle->userCanEdit before calling them
2235 function editSectionScript($section,$head) {
2236
2237 global $wgTitle,$wgUser,$oldid;
2238 if($oldid) return $head;
2239 $url = wfLocalUrlE(urlencode(str_replace(' ','_',$wgTitle->getPrefixedText())),"action=edit&section=$section");
2240 return "<span onContextMenu='document.location=\"".$url."\";return false;'>{$head}</span>";
2241 }
2242
2243 function editSectionLink($section) {
2244 global $printable,$oldid;
2245 global $wgTitle, $wgUser, $wgLang;
2246
2247 if( isset( $oldid ) ) return "";
2248 if( isset( $printable ) ) return "";
2249
2250 $editurl = "&section={$section}";
2251 $url = $this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg("editsection"),"action=edit".$editurl);
2252
2253 if( $wgLang->isRTL() ) {
2254 $farside = "left";
2255 $nearside = "right";
2256 } else {
2257 $farside = "right";
2258 $nearside = "left";
2259 }
2260 return "<div style=\"float:$farside;margin-$nearside:5px;\"><small>[".$url."]</small></div>";
2261
2262 }
2263
2264 // This function is called by EditPage.php and shows a bulletin board style
2265 // toolbar for common editing functions. It can be disabled in the user preferences.
2266 // The necsesary JavaScript code can be found in style/wikibits.js.
2267 function getEditToolbar() {
2268
2269 global $wgUploadPath,$wgLang;
2270
2271 // toolarray an array of arrays which each include the filename of
2272 // the button image (without path), the opening tag, the closing tag,
2273 // and optionally a sample text that is inserted between the two when no
2274 // selection is highlighted.
2275 // The tip text is shown when the user moves the mouse over the button.
2276 $toolarray=array(
2277 array( "image"=>"button_bold.gif",
2278 "open"=>"\'\'\'",
2279 "close"=>"\'\'\'",
2280 "sample"=>wfMsg("bold_sample"),
2281 "tip"=>wfMsg("bold_tip")),
2282 array( "image"=>"button_italic.gif",
2283 "open"=>"\'\'",
2284 "close"=>"\'\'",
2285 "sample"=>wfMsg("italic_sample"),
2286 "tip"=>wfMsg("italic_tip")),
2287 array( "image"=>"button_link.gif",
2288 "open"=>"[[",
2289 "close"=>"]]",
2290 "sample"=>wfMsg("link_sample"),
2291 "tip"=>wfMsg("link_tip")),
2292 array( "image"=>"button_extlink.gif",
2293 "open"=>"[",
2294 "close"=>"]",
2295 "sample"=>wfMsg("extlink_sample"),
2296 "tip"=>wfMsg("extlink_tip")),
2297 array( "image"=>"button_headline.gif",
2298 "open"=>"\\n== ",
2299 "close"=>" ==\\n",
2300 "sample"=>wfMsg("headline_sample"),
2301 "tip"=>wfMsg("headline_tip")),
2302 array( "image"=>"button_image.gif",
2303 "open"=>"[[".$wgLang->getNsText(NS_IMAGE).":",
2304 "close"=>"]]",
2305 "sample"=>wfMsg("image_sample"),
2306 "tip"=>wfMsg("image_tip")),
2307 array( "image"=>"button_media.gif",
2308 "open"=>"[[".$wgLang->getNsText(NS_MEDIA).":",
2309 "close"=>"]]",
2310 "sample"=>wfMsg("media_sample"),
2311 "tip"=>wfMsg("media_tip")),
2312 array( "image"=>"button_math.gif",
2313 "open"=>"\\<math\\>",
2314 "close"=>"\\</math\\>",
2315 "sample"=>wfMsg("math_sample"),
2316 "tip"=>wfMsg("math_tip")),
2317 array( "image"=>"button_nowiki.gif",
2318 "open"=>"\\<nowiki\\>",
2319 "close"=>"\\</nowiki\\>",
2320 "sample"=>wfMsg("nowiki_sample"),
2321 "tip"=>wfMsg("nowiki_tip")),
2322 array( "image"=>"button_sig.gif",
2323 "open"=>"--~~~~",
2324 "close"=>"",
2325 "sample"=>"",
2326 "tip"=>wfMsg("sig_tip")),
2327 array( "image"=>"button_hr.gif",
2328 "open"=>"\\n----\\n",
2329 "close"=>"",
2330 "sample"=>"",
2331 "tip"=>wfMsg("hr_tip"))
2332 );
2333 $toolbar.="<script type='text/javascript'>\n";
2334 $toolbar.="document.writeln(\"<div id='toolbar'>\");\n";
2335 foreach($toolarray as $tool) {
2336
2337 $image=$wgUploadPath."/".$tool["image"];
2338 $open=$tool["open"];
2339 $close=$tool["close"];
2340 $sample=$tool["sample"];
2341
2342 // Note that we use the tip both for the ALT tag and the TITLE tag of the image.
2343 // Older browsers show a "speedtip" type message only for ALT.
2344 // Ideally these should be different, realistically they
2345 // probably don't need to be.
2346 $tip=$tool["tip"];
2347 $toolbar.="addButton('$image','$tip','$open','$close','$sample');\n";
2348 }
2349
2350 $toolbar.="addInfobox('".wfMsg("infobox")."');\n";
2351 $toolbar.="document.writeln(\"</div>\");\n</script>";
2352 return $toolbar;
2353 }
2354 }
2355
2356 include_once( "SkinStandard.php" );
2357 include_once( "SkinNostalgia.php" );
2358 include_once( "SkinCologneBlue.php" );
2359
2360 #include_once( "SkinSmarty.php" );
2361
2362 ?>