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