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