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