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