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