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