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