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