5c16a87fb12e1952750b09eb3528c4b84b7d294f
[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 $fname = 'Skin::makeLinkObj';
1444
1445 if ( $nt->isExternal() ) {
1446 $u = $nt->getFullURL();
1447 $link = $nt->getPrefixedURL();
1448 if ( '' == $text ) { $text = $nt->getPrefixedText(); }
1449 $style = $this->getExternalLinkAttributes( $link, $text, 'extiw' );
1450
1451 $inside = '';
1452 if ( '' != $trail ) {
1453 if ( preg_match( '/^([a-z]+)(.*)$$/sD', $trail, $m ) ) {
1454 $inside = $m[1];
1455 $trail = $m[2];
1456 }
1457 }
1458 $retVal = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1459 } elseif ( 0 == $nt->getNamespace() && "" == $nt->getText() ) {
1460 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1461 } elseif ( ( -1 == $nt->getNamespace() ) ||
1462 ( Namespace::getImage() == $nt->getNamespace() ) ) {
1463 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1464 } else {
1465 $aid = $nt->getArticleID() ;
1466 if ( 0 == $aid ) {
1467 $retVal = $this->makeBrokenLinkObj( $nt, $text, $query, $trail, $prefix );
1468 } else {
1469 $threshold = $wgUser->getOption('stubthreshold') ;
1470 if ( $threshold > 0 ) {
1471 $s = $dbr->getArray( 'cur',
1472 array( 'LENGTH(cur_text) AS x', 'cur_namespace', 'cur_is_redirect' ),
1473 array( 'cur_id' => $aid ),
1474 $fname
1475 );
1476
1477 if ( $s !== false ) {
1478 $size = $s->x;
1479 if ( $s->cur_is_redirect OR $s->cur_namespace != 0 ) {
1480 $size = $threshold*2 ; # Really big
1481 }
1482 } else {
1483 $size = $threshold*2 ; # Really big
1484 }
1485 } else {
1486 $size = 1 ;
1487 }
1488 if ( $size < $threshold ) {
1489 $retVal = $this->makeStubLinkObj( $nt, $text, $query, $trail, $prefix );
1490 } else {
1491 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1492 }
1493 }
1494 }
1495 return $retVal;
1496 }
1497
1498 # Pass a title object, not a title string
1499 function makeKnownLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' , $aprops = '')
1500 {
1501 global $wgOut, $wgTitle, $wgInputEncoding;
1502
1503 $fname = 'Skin::makeKnownLinkObj';
1504 wfProfileIn( $fname );
1505
1506 if ( !is_object( $nt ) ) {
1507 return $text;
1508 }
1509 $link = $nt->getPrefixedURL();
1510
1511 if ( '' == $link ) {
1512 $u = '';
1513 if ( '' == $text ) {
1514 $text = htmlspecialchars( $nt->getFragment() );
1515 }
1516 } else {
1517 $u = $nt->escapeLocalURL( $query );
1518 }
1519 if ( '' != $nt->getFragment() ) {
1520 $anchor = urlencode( do_html_entity_decode( str_replace(' ', '_', $nt->getFragment()), ENT_COMPAT, $wgInputEncoding ) );
1521 $replacearray = array(
1522 '%3A' => ':',
1523 '%' => '.'
1524 );
1525 $u .= '#' . str_replace(array_keys($replacearray),array_values($replacearray),$anchor);
1526 }
1527 if ( '' == $text ) {
1528 $text = htmlspecialchars( $nt->getPrefixedText() );
1529 }
1530 $style = $this->getInternalLinkAttributesObj( $nt, $text );
1531
1532 $inside = '';
1533 if ( '' != $trail ) {
1534 if ( preg_match( $this->linktrail, $trail, $m ) ) {
1535 $inside = $m[1];
1536 $trail = $m[2];
1537 }
1538 }
1539 $r = "<a href=\"{$u}\"{$style}{$aprops}>{$prefix}{$text}{$inside}</a>{$trail}";
1540 wfProfileOut( $fname );
1541 return $r;
1542 }
1543
1544 # Pass a title object, not a title string
1545 function makeBrokenLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
1546 {
1547 global $wgOut, $wgUser;
1548
1549 $fname = 'Skin::makeBrokenLinkObj';
1550 wfProfileIn( $fname );
1551
1552 if ( '' == $query ) {
1553 $q = 'action=edit';
1554 } else {
1555 $q = 'action=edit&'.$query;
1556 }
1557 $u = $nt->escapeLocalURL( $q );
1558
1559 if ( '' == $text ) {
1560 $text = htmlspecialchars( $nt->getPrefixedText() );
1561 }
1562 $style = $this->getInternalLinkAttributesObj( $nt, $text, "yes" );
1563
1564 $inside = '';
1565 if ( '' != $trail ) {
1566 if ( preg_match( $this->linktrail, $trail, $m ) ) {
1567 $inside = $m[1];
1568 $trail = $m[2];
1569 }
1570 }
1571 if ( $wgUser->getOption( 'highlightbroken' ) ) {
1572 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1573 } else {
1574 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>?</a>{$trail}";
1575 }
1576
1577 wfProfileOut( $fname );
1578 return $s;
1579 }
1580
1581 # Pass a title object, not a title string
1582 function makeStubLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
1583 {
1584 global $wgOut, $wgUser;
1585
1586 $link = $nt->getPrefixedURL();
1587
1588 $u = $nt->escapeLocalURL( $query );
1589
1590 if ( '' == $text ) {
1591 $text = htmlspecialchars( $nt->getPrefixedText() );
1592 }
1593 $style = $this->getInternalLinkAttributesObj( $nt, $text, 'stub' );
1594
1595 $inside = '';
1596 if ( '' != $trail ) {
1597 if ( preg_match( $this->linktrail, $trail, $m ) ) {
1598 $inside = $m[1];
1599 $trail = $m[2];
1600 }
1601 }
1602 if ( $wgUser->getOption( 'highlightbroken' ) ) {
1603 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1604 } else {
1605 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>!</a>{$trail}";
1606 }
1607 return $s;
1608 }
1609
1610 function makeSelfLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' )
1611 {
1612 $u = $nt->escapeLocalURL( $query );
1613 if ( '' == $text ) {
1614 $text = htmlspecialchars( $nt->getPrefixedText() );
1615 }
1616 $inside = '';
1617 if ( '' != $trail ) {
1618 if ( preg_match( $this->linktrail, $trail, $m ) ) {
1619 $inside = $m[1];
1620 $trail = $m[2];
1621 }
1622 }
1623 return "<strong>{$prefix}{$text}{$inside}</strong>{$trail}";
1624 }
1625
1626 /* these are used extensively in SkinPHPTal, but also some other places */
1627 /*static*/ function makeSpecialUrl( $name, $urlaction='' ) {
1628 $title = Title::makeTitle( NS_SPECIAL, $name );
1629 $this->checkTitle($title, $name);
1630 return $title->getLocalURL( $urlaction );
1631 }
1632 /*static*/ function makeTalkUrl ( $name, $urlaction='' ) {
1633 $title = Title::newFromText( $name );
1634 $title = $title->getTalkPage();
1635 $this->checkTitle($title, $name);
1636 return $title->getLocalURL( $urlaction );
1637 }
1638 /*static*/ function makeArticleUrl ( $name, $urlaction='' ) {
1639 $title = Title::newFromText( $name );
1640 $title= $title->getSubjectPage();
1641 $this->checkTitle($title, $name);
1642 return $title->getLocalURL( $urlaction );
1643 }
1644 /*static*/ function makeI18nUrl ( $name, $urlaction='' ) {
1645 $title = Title::newFromText( wfMsg($name) );
1646 $this->checkTitle($title, $name);
1647 return $title->getLocalURL( $urlaction );
1648 }
1649 /*static*/ function makeUrl ( $name, $urlaction='' ) {
1650 $title = Title::newFromText( $name );
1651 $this->checkTitle($title, $name);
1652 return $title->getLocalURL( $urlaction );
1653 }
1654 # this can be passed the NS number as defined in Language.php
1655 /*static*/ function makeNSUrl( $name, $urlaction='', $namespace=0 ) {
1656 $title = Title::makeTitle( $namespace, $name );
1657 $this->checkTitle($title, $name);
1658 return $title->getLocalURL( $urlaction );
1659 }
1660
1661 /* these return an array with the 'href' and boolean 'exists' */
1662 /*static*/ function makeUrlDetails ( $name, $urlaction='' ) {
1663 $title = Title::newFromText( $name );
1664 $this->checkTitle($title, $name);
1665 return array(
1666 'href' => $title->getLocalURL( $urlaction ),
1667 'exists' => $title->getArticleID() != 0?true:false
1668 );
1669 }
1670 /*static*/ function makeTalkUrlDetails ( $name, $urlaction='' ) {
1671 $title = Title::newFromText( $name );
1672 $title = $title->getTalkPage();
1673 $this->checkTitle($title, $name);
1674 return array(
1675 'href' => $title->getLocalURL( $urlaction ),
1676 'exists' => $title->getArticleID() != 0?true:false
1677 );
1678 }
1679 /*static*/ function makeArticleUrlDetails ( $name, $urlaction='' ) {
1680 $title = Title::newFromText( $name );
1681 $title= $title->getSubjectPage();
1682 $this->checkTitle($title, $name);
1683 return array(
1684 'href' => $title->getLocalURL( $urlaction ),
1685 'exists' => $title->getArticleID() != 0?true:false
1686 );
1687 }
1688 /*static*/ function makeI18nUrlDetails ( $name, $urlaction='' ) {
1689 $title = Title::newFromText( wfMsg($name) );
1690 $this->checkTitle($title, $name);
1691 return array(
1692 'href' => $title->getLocalURL( $urlaction ),
1693 'exists' => $title->getArticleID() != 0?true:false
1694 );
1695 }
1696
1697 # make sure we have some title to operate on
1698 /*static*/ function checkTitle ( &$title, &$name ) {
1699 if(!is_object($title)) {
1700 $title = Title::newFromText( $name );
1701 if(!is_object($title)) {
1702 $title = Title::newFromText( '--error: link target missing--' );
1703 }
1704 }
1705 }
1706
1707 function fnamePart( $url )
1708 {
1709 $basename = strrchr( $url, '/' );
1710 if ( false === $basename ) { $basename = $url; }
1711 else { $basename = substr( $basename, 1 ); }
1712 return wfEscapeHTML( $basename );
1713 }
1714
1715 function makeImage( $url, $alt = '' )
1716 {
1717 global $wgOut;
1718
1719 if ( '' == $alt ) { $alt = $this->fnamePart( $url ); }
1720 $s = '<img src="'.$url.'" alt="'.$alt.'" />';
1721 return $s;
1722 }
1723
1724 function makeImageLink( $name, $url, $alt = '' ) {
1725 $nt = Title::makeTitle( Namespace::getImage(), $name );
1726 return $this->makeImageLinkObj( $nt, $alt );
1727 }
1728
1729 function makeImageLinkObj( $nt, $alt = '' ) {
1730 global $wgLang, $wgUseImageResize;
1731 $img = Image::newFromTitle( $nt );
1732 $url = $img->getURL();
1733
1734 $align = '';
1735 $prefix = $postfix = '';
1736
1737 if ( $wgUseImageResize ) {
1738 # Check if the alt text is of the form "options|alt text"
1739 # Options are:
1740 # * thumbnail make a thumbnail with enlarge-icon and caption, alignment depends on lang
1741 # * left no resizing, just left align. label is used for alt= only
1742 # * right same, but right aligned
1743 # * none same, but not aligned
1744 # * ___px scale to ___ pixels width, no aligning. e.g. use in taxobox
1745 # * center center the image
1746 # * framed Keep original image size, no magnify-button.
1747
1748 $part = explode( '|', $alt);
1749
1750 $mwThumb =& MagicWord::get( MAG_IMG_THUMBNAIL );
1751 $mwLeft =& MagicWord::get( MAG_IMG_LEFT );
1752 $mwRight =& MagicWord::get( MAG_IMG_RIGHT );
1753 $mwNone =& MagicWord::get( MAG_IMG_NONE );
1754 $mwWidth =& MagicWord::get( MAG_IMG_WIDTH );
1755 $mwCenter =& MagicWord::get( MAG_IMG_CENTER );
1756 $mwFramed =& MagicWord::get( MAG_IMG_FRAMED );
1757 $alt = $part[count($part)-1];
1758
1759 $height = $framed = $thumb = false;
1760 $manual_thumb = "" ;
1761
1762 foreach( $part as $key => $val ) {
1763 $val_parts = explode ( "=" , $val , 2 ) ;
1764 $left_part = array_shift ( $val_parts ) ;
1765 if ( ! is_null( $mwThumb->matchVariableStartToEnd($val) ) ) {
1766 $thumb=true;
1767 } elseif ( count ( $val_parts ) == 1 && ! is_null( $mwThumb->matchVariableStartToEnd($left_part) ) ) {
1768 # use manually specified thumbnail
1769 $thumb=true;
1770 $manual_thumb = array_shift ( $val_parts ) ;
1771 } elseif ( ! is_null( $mwRight->matchVariableStartToEnd($val) ) ) {
1772 # remember to set an alignment, don't render immediately
1773 $align = 'right';
1774 } elseif ( ! is_null( $mwLeft->matchVariableStartToEnd($val) ) ) {
1775 # remember to set an alignment, don't render immediately
1776 $align = 'left';
1777 } elseif ( ! is_null( $mwCenter->matchVariableStartToEnd($val) ) ) {
1778 # remember to set an alignment, don't render immediately
1779 $align = 'center';
1780 } elseif ( ! is_null( $mwNone->matchVariableStartToEnd($val) ) ) {
1781 # remember to set an alignment, don't render immediately
1782 $align = 'none';
1783 } elseif ( ! is_null( $match = $mwWidth->matchVariableStartToEnd($val) ) ) {
1784 # $match is the image width in pixels
1785 if ( preg_match( '/^([0-9]*)x([0-9]*)$/', $match, $m ) ) {
1786 $width = intval( $m[1] );
1787 $height = intval( $m[2] );
1788 } else {
1789 $width = intval($match);
1790 }
1791 } elseif ( ! is_null( $mwFramed->matchVariableStartToEnd($val) ) ) {
1792 $framed=true;
1793 }
1794 }
1795 if ( 'center' == $align )
1796 {
1797 $prefix = '<span style="text-align: center">';
1798 $postfix = '</span>';
1799 $align = 'none';
1800 }
1801
1802 if ( $thumb || $framed ) {
1803
1804 # Create a thumbnail. Alignment depends on language
1805 # writing direction, # right aligned for left-to-right-
1806 # languages ("Western languages"), left-aligned
1807 # for right-to-left-languages ("Semitic languages")
1808 #
1809 # If thumbnail width has not been provided, it is set
1810 # here to 180 pixels
1811 if ( $align == '' ) {
1812 $align = $wgLang->isRTL() ? 'left' : 'right';
1813 }
1814 if ( ! isset($width) ) {
1815 $width = 180;
1816 }
1817 return $prefix.$this->makeThumbLinkObj( $img, $alt, $align, $width, $height, $framed, $manual_thumb ).$postfix;
1818
1819 } elseif ( isset($width) ) {
1820
1821 # Create a resized image, without the additional thumbnail
1822 # features
1823
1824 if ( ( ! $height === false )
1825 && ( $img->getHeight() * $width / $img->getWidth() > $height ) ) {
1826 print "height=$height<br>\nimg->getHeight() = ".$img->getHeight()."<br>\n";
1827 print 'rescaling by factor '. $height / $img->getHeight() . "<br>\n";
1828 $width = $img->getWidth() * $height / $img->getHeight();
1829 }
1830 if ( '' == $manual_thumb ) $url = $img->createThumb( $width );
1831 }
1832 } # endif $wgUseImageResize
1833
1834 if ( empty( $alt ) ) {
1835 $alt = preg_replace( '/\.(.+?)^/', '', $img->getName() );
1836 }
1837 $alt = htmlspecialchars( $alt );
1838
1839 $u = $nt->escapeLocalURL();
1840 if ( $url == '' )
1841 {
1842 $s = str_replace( "$1", $img->getName(), wfMsg('missingimage') );
1843 $s .= "<br>{$alt}<br>{$url}<br>\n";
1844 } else {
1845 $s = '<a href="'.$u.'" class="image" title="'.$alt.'">' .
1846 '<img src="'.$url.'" alt="'.$alt.'" /></a>';
1847 }
1848 if ( '' != $align ) {
1849 $s = "<div class=\"float{$align}\"><span>{$s}</span></div>";
1850 }
1851 return str_replace("\n", ' ',$prefix.$s.$postfix);
1852 }
1853
1854
1855 function makeThumbLinkObj( $img, $label = '', $align = 'right', $boxwidth = 180, $boxheight=false, $framed=false , $manual_thumb = "" ) {
1856 global $wgStylePath, $wgLang;
1857 # $image = Title::makeTitle( Namespace::getImage(), $name );
1858 $url = $img->getURL();
1859
1860 #$label = htmlspecialchars( $label );
1861 $alt = preg_replace( '/<[^>]*>/', '', $label);
1862 $alt = htmlspecialchars( $alt );
1863
1864 if ( $img->exists() )
1865 {
1866 $width = $img->getWidth();
1867 $height = $img->getHeight();
1868 } else {
1869 $width = $height = 200;
1870 }
1871 if ( $framed )
1872 {
1873 // Use image dimensions, don't scale
1874 $boxwidth = $width;
1875 $oboxwidth = $boxwidth + 2;
1876 $boxheight = $height;
1877 $thumbUrl = $url;
1878 } else {
1879 $h = intval( $height/($width/$boxwidth) );
1880 $oboxwidth = $boxwidth + 2;
1881 if ( ( ! $boxheight === false ) && ( $h > $boxheight ) )
1882 {
1883 $boxwidth *= $boxheight/$h;
1884 } else {
1885 $boxheight = $h;
1886 }
1887 if ( '' == $manual_thumb ) $thumbUrl = $img->createThumb( $boxwidth );
1888 }
1889
1890 if ( $manual_thumb != '' ) # Use manually specified thumbnail
1891 {
1892 $manual_title = Title::makeTitle( Namespace::getImage(), $manual_thumb ); #new Title ( $manual_thumb ) ;
1893 $manual_img = Image::newFromTitle( $manual_title );
1894 $thumbUrl = $manual_img->getURL();
1895 if ( $manual_img->exists() )
1896 {
1897 $width = $manual_img->getWidth();
1898 $height = $manual_img->getHeight();
1899 $boxwidth = $width ;
1900 $boxheight = $height ;
1901 $oboxwidth = $boxwidth + 2 ;
1902 }
1903 }
1904
1905 $u = $img->getEscapeLocalURL();
1906
1907 $more = htmlspecialchars( wfMsg( 'thumbnail-more' ) );
1908 $magnifyalign = $wgLang->isRTL() ? 'left' : 'right';
1909 $textalign = $wgLang->isRTL() ? ' style="text-align:right"' : '';
1910
1911 $s = "<div class=\"thumb t{$align}\"><div style=\"width:{$oboxwidth}px;\">";
1912 if ( $thumbUrl == '' ) {
1913 $s .= str_replace( "$1", $img->getName(), wfMsg('missingimage') );
1914 $zoomicon = '';
1915 } else {
1916 $s .= '<a href="'.$u.'" class="internal" title="'.$alt.'">'.
1917 '<img src="'.$thumbUrl.'" alt="'.$alt.'" ' .
1918 'width="'.$boxwidth.'" height="'.$boxheight.'" /></a>';
1919 if ( $framed ) {
1920 $zoomicon="";
1921 } else {
1922 $zoomicon = '<div class="magnify" style="float:'.$magnifyalign.'">'.
1923 '<a href="'.$u.'" class="internal" title="'.$more.'">'.
1924 '<img src="'.$wgStylePath.'/images/magnify-clip.png" ' .
1925 'width="15" height="11" alt="'.$more.'" /></a></div>';
1926 }
1927 }
1928 $s .= ' <div class="thumbcaption" '.$textalign.'>'.$zoomicon.$label."</div></div></div>";
1929 return str_replace("\n", ' ', $s);
1930 }
1931
1932 function makeMediaLink( $name, $url, $alt = "" ) {
1933 $nt = Title::makeTitle( Namespace::getMedia(), $name );
1934 return $this->makeMediaLinkObj( $nt, $alt );
1935 }
1936
1937 function makeMediaLinkObj( $nt, $alt = "" )
1938 {
1939 if ( ! isset( $nt ) )
1940 {
1941 ### HOTFIX. Instead of breaking, return empry string.
1942 $s = $alt;
1943 } else {
1944 $name = $nt->getDBKey();
1945 $url = Image::wfImageUrl( $name );
1946 if ( empty( $alt ) ) {
1947 $alt = preg_replace( '/\.(.+?)^/', '', $name );
1948 }
1949
1950 $u = htmlspecialchars( $url );
1951 $s = "<a href=\"{$u}\" class='internal' title=\"{$alt}\">{$alt}</a>";
1952 }
1953 return $s;
1954 }
1955
1956 function specialLink( $name, $key = "" )
1957 {
1958 global $wgLang;
1959
1960 if ( '' == $key ) { $key = strtolower( $name ); }
1961 $pn = $wgLang->ucfirst( $name );
1962 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1963 wfMsg( $key ) );
1964 }
1965
1966 function makeExternalLink( $url, $text, $escape = true ) {
1967 $style = $this->getExternalLinkAttributes( $url, $text );
1968 $url = htmlspecialchars( $url );
1969 if( $escape ) {
1970 $text = htmlspecialchars( $text );
1971 }
1972 return '<a href="'.$url.'"'.$style.'>'.$text.'</a>';
1973 }
1974
1975 # Called by history lists and recent changes
1976 #
1977
1978 # Returns text for the start of the tabular part of RC
1979 function beginRecentChangesList()
1980 {
1981 $this->rc_cache = array() ;
1982 $this->rcMoveIndex = 0;
1983 $this->rcCacheIndex = 0 ;
1984 $this->lastdate = '';
1985 $this->rclistOpen = false;
1986 return '';
1987 }
1988
1989 function beginImageHistoryList()
1990 {
1991 $s = "\n<h2>" . wfMsg( 'imghistory' ) . "</h2>\n" .
1992 "<p>" . wfMsg( 'imghistlegend' ) . "</p>\n".'<ul class="special">';
1993 return $s;
1994 }
1995
1996 # Returns text for the end of RC
1997 # If enhanced RC is in use, returns pretty much all the text
1998 function endRecentChangesList()
1999 {
2000 $s = $this->recentChangesBlock() ;
2001 if( $this->rclistOpen ) {
2002 $s .= "</ul>\n";
2003 }
2004 return $s;
2005 }
2006
2007 # Enhanced RC ungrouped line
2008 function recentChangesBlockLine ( $rcObj )
2009 {
2010 global $wgStylePath, $wgLang ;
2011
2012 # Get rc_xxxx variables
2013 extract( $rcObj->mAttribs ) ;
2014 $curIdEq = 'curid='.$rc_cur_id;
2015
2016 # Spacer image
2017 $r = '' ;
2018
2019 $r .= '<img src="'.$wgStylePath.'/images/Arr_.png" width="12" height="12" border="0" />' ;
2020 $r .= '<tt>' ;
2021
2022 if ( $rc_type == RC_MOVE || $rc_type == RC_MOVE_OVER_REDIRECT ) {
2023 $r .= '&nbsp;&nbsp;';
2024 } else {
2025 # M & N (minor & new)
2026 $M = wfMsg( 'minoreditletter' );
2027 $N = wfMsg( 'newpageletter' );
2028
2029 if ( $rc_type == RC_NEW ) {
2030 $r .= $N ;
2031 } else {
2032 $r .= '&nbsp;' ;
2033 }
2034 if ( $rc_minor ) {
2035 $r .= $M ;
2036 } else {
2037 $r .= '&nbsp;' ;
2038 }
2039 }
2040
2041 # Timestamp
2042 $r .= ' '.$rcObj->timestamp.' ' ;
2043 $r .= '</tt>' ;
2044
2045 # Article link
2046 $link = $rcObj->link ;
2047 if ( $rcObj->watched ) $link = '<strong>'.$link.'</strong>' ;
2048 $r .= $link ;
2049
2050 # Diff
2051 $r .= ' (' ;
2052 $r .= $rcObj->difflink ;
2053 $r .= '; ' ;
2054
2055 # Hist
2056 $r .= $this->makeKnownLinkObj( $rcObj->getTitle(), wfMsg( 'hist' ), $curIdEq.'&action=history' );
2057
2058 # User/talk
2059 $r .= ') . . '.$rcObj->userlink ;
2060 $r .= $rcObj->usertalklink ;
2061
2062 # Comment
2063 if ( $rc_comment != '' && $rc_type != RC_MOVE && $rc_type != RC_MOVE_OVER_REDIRECT ) {
2064 $rc_comment=$this->formatComment($rc_comment);
2065 $r .= $wgLang->emphasize( ' ('.$rc_comment.')' );
2066 }
2067
2068 $r .= "<br />\n" ;
2069 return $r ;
2070 }
2071
2072 # Enhanced RC group
2073 function recentChangesBlockGroup ( $block )
2074 {
2075 global $wgStylePath, $wgLang ;
2076
2077 $r = '' ;
2078 $M = wfMsg( 'minoreditletter' );
2079 $N = wfMsg( 'newpageletter' );
2080
2081 # Collate list of users
2082 $isnew = false ;
2083 $userlinks = array () ;
2084 foreach ( $block AS $rcObj ) {
2085 $oldid = $rcObj->mAttribs['rc_last_oldid'];
2086 if ( $rcObj->mAttribs['rc_new'] ) $isnew = true ;
2087 $u = $rcObj->userlink ;
2088 if ( !isset ( $userlinks[$u] ) ) $userlinks[$u] = 0 ;
2089 $userlinks[$u]++ ;
2090 }
2091
2092 # Sort the list and convert to text
2093 krsort ( $userlinks ) ;
2094 asort ( $userlinks ) ;
2095 $users = array () ;
2096 foreach ( $userlinks as $userlink => $count) {
2097 $text = $userlink ;
2098 if ( $count > 1 ) $text .= " ({$count}&times;)" ;
2099 array_push ( $users , $text ) ;
2100 }
2101 $users = ' <font size="-1">['.implode('; ',$users).']</font>' ;
2102
2103 # Arrow
2104 $rci = 'RCI'.$this->rcCacheIndex ;
2105 $rcl = 'RCL'.$this->rcCacheIndex ;
2106 $rcm = 'RCM'.$this->rcCacheIndex ;
2107 $toggleLink = "javascript:toggleVisibility('$rci','$rcm','$rcl')" ;
2108 $arrowdir = $wgLang->isRTL() ? 'l' : 'r';
2109 $tl = '<span id="'.$rcm.'"><a href="'.$toggleLink.'"><img src="'.$wgStylePath.'/images/Arr_'.$arrowdir.'.png" width="12" height="12" /></a></span>' ;
2110 $tl .= '<span id="'.$rcl.'" style="display:none"><a href="'.$toggleLink.'"><img src="'.$wgStylePath.'/images/Arr_d.png" width="12" height="12" /></a></span>' ;
2111 $r .= $tl ;
2112
2113 # Main line
2114 # M/N
2115 $r .= '<tt>' ;
2116 if ( $isnew ) $r .= $N ;
2117 else $r .= '&nbsp;' ;
2118 $r .= '&nbsp;' ; # Minor
2119
2120 # Timestamp
2121 $r .= ' '.$block[0]->timestamp.' ' ;
2122 $r .= '</tt>' ;
2123
2124 # Article link
2125 $link = $block[0]->link ;
2126 if ( $block[0]->watched ) $link = '<strong>'.$link.'</strong>' ;
2127 $r .= $link ;
2128
2129 $curIdEq = 'curid=' . $block[0]->mAttribs['rc_cur_id'];
2130 if ( $block[0]->mAttribs['rc_type'] != RC_LOG ) {
2131 # Changes
2132 $r .= ' ('.count($block).' ' ;
2133 if ( $isnew ) $r .= wfMsg('changes');
2134 else $r .= $this->makeKnownLinkObj( $block[0]->getTitle() , wfMsg('changes') ,
2135 $curIdEq.'&diff=0&oldid='.$oldid ) ;
2136 $r .= '; ' ;
2137
2138 # History
2139 $r .= $this->makeKnownLinkObj( $block[0]->getTitle(), wfMsg( 'history' ), $curIdEq.'&action=history' );
2140 $r .= ')' ;
2141 }
2142
2143 $r .= $users ;
2144 $r .= "<br />\n" ;
2145
2146 # Sub-entries
2147 $r .= '<div id="'.$rci.'" style="display:none">' ;
2148 foreach ( $block AS $rcObj ) {
2149 # Get rc_xxxx variables
2150 extract( $rcObj->mAttribs );
2151
2152 $r .= '<img src="'.$wgStylePath.'/images/Arr_.png" width="12" height="12" />';
2153 $r .= '<tt>&nbsp; &nbsp; &nbsp; &nbsp;' ;
2154 if ( $rc_new ) $r .= $N ;
2155 else $r .= '&nbsp;' ;
2156 if ( $rc_minor ) $r .= $M ;
2157 else $r .= '&nbsp;' ;
2158 $r .= '</tt>' ;
2159
2160 $o = '' ;
2161 if ( $rc_last_oldid != 0 ) {
2162 $o = 'oldid='.$rc_last_oldid ;
2163 }
2164 if ( $rc_type == RC_LOG ) {
2165 $link = $rcObj->timestamp ;
2166 } else {
2167 $link = $this->makeKnownLinkObj( $rcObj->getTitle(), $rcObj->timestamp , "{$curIdEq}&$o" ) ;
2168 }
2169 $link = '<tt>'.$link.'</tt>' ;
2170
2171 $r .= $link ;
2172 $r .= ' (' ;
2173 $r .= $rcObj->curlink ;
2174 $r .= '; ' ;
2175 $r .= $rcObj->lastlink ;
2176 $r .= ') . . '.$rcObj->userlink ;
2177 $r .= $rcObj->usertalklink ;
2178 if ( $rc_comment != '' ) {
2179 $rc_comment=$this->formatComment($rc_comment);
2180 $r .= $wgLang->emphasize( ' ('.$rc_comment.')' ) ;
2181 }
2182 $r .= "<br />\n" ;
2183 }
2184 $r .= "</div>\n" ;
2185
2186 $this->rcCacheIndex++ ;
2187 return $r ;
2188 }
2189
2190 # If enhanced RC is in use, this function takes the previously cached
2191 # RC lines, arranges them, and outputs the HTML
2192 function recentChangesBlock ()
2193 {
2194 global $wgStylePath ;
2195 if ( count ( $this->rc_cache ) == 0 ) return '' ;
2196 $blockOut = '';
2197 foreach ( $this->rc_cache AS $secureName => $block ) {
2198 if ( count ( $block ) < 2 ) {
2199 $blockOut .= $this->recentChangesBlockLine ( array_shift ( $block ) ) ;
2200 } else {
2201 $blockOut .= $this->recentChangesBlockGroup ( $block ) ;
2202 }
2203 }
2204
2205 return '<div>'.$blockOut.'</div>' ;
2206 }
2207
2208 # Called in a loop over all displayed RC entries
2209 # Either returns the line, or caches it for later use
2210 function recentChangesLine( &$rc, $watched = false )
2211 {
2212 global $wgUser ;
2213 $usenew = $wgUser->getOption( 'usenewrc' );
2214 if ( $usenew )
2215 $line = $this->recentChangesLineNew ( $rc, $watched ) ;
2216 else
2217 $line = $this->recentChangesLineOld ( $rc, $watched ) ;
2218 return $line ;
2219 }
2220
2221 function recentChangesLineOld( &$rc, $watched = false )
2222 {
2223 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds;
2224
2225 # Extract DB fields into local scope
2226 extract( $rc->mAttribs );
2227 $curIdEq = 'curid=' . $rc_cur_id;
2228
2229 # Make date header if necessary
2230 $date = $wgLang->date( $rc_timestamp, true);
2231 $s = '';
2232 if ( $date != $this->lastdate ) {
2233 if ( '' != $this->lastdate ) { $s .= "</ul>\n"; }
2234 $s .= "<h4>{$date}</h4>\n<ul class='special'>";
2235 $this->lastdate = $date;
2236 $this->rclistOpen = true;
2237 }
2238 $s .= '<li> ';
2239
2240 if ( $rc_type == RC_MOVE || $rc_type == RC_MOVE_OVER_REDIRECT ) {
2241 # Diff
2242 $s .= '(' . wfMsg( 'diff' ) . ') (';
2243 # Hist
2244 $s .= $this->makeKnownLinkObj( $rc->getMovedToTitle(), wfMsg( 'hist' ), 'action=history' ) .
2245 ') . . ';
2246
2247 # "[[x]] moved to [[y]]"
2248 if ( $rc_type == RC_MOVE ) {
2249 $msg = '1movedto2';
2250 } else {
2251 $msg = '1movedto2_redir';
2252 }
2253 $s .= wfMsg( $msg, $this->makeKnownLinkObj( $rc->getTitle(), '', 'redirect=no' ),
2254 $this->makeKnownLinkObj( $rc->getMovedToTitle(), '' ) );
2255 } else {
2256 # Diff link
2257 if ( $rc_type == RC_NEW || $rc_type == RC_LOG ) {
2258 $diffLink = wfMsg( 'diff' );
2259 } else {
2260 $diffLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'diff' ),
2261 $curIdEq.'&diff='.$rc_this_oldid.'&oldid='.$rc_last_oldid ,'' ,'' , ' tabindex="'.$rc->counter.'"');
2262 }
2263 $s .= '('.$diffLink.') (';
2264
2265 # History link
2266 $s .= $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'hist' ), $curIdEq.'&action=history' );
2267 $s .= ') . . ';
2268
2269 # M and N (minor and new)
2270 $M = wfMsg( 'minoreditletter' );
2271 $N = wfMsg( 'newpageletter' );
2272 if ( $rc_minor ) { $s .= ' <strong>'.$M.'</strong>'; }
2273 if ( $rc_type == RC_NEW ) { $s .= '<strong>'.$N.'</strong>'; }
2274
2275 # Article link
2276 $articleLink = $this->makeKnownLinkObj( $rc->getTitle(), '' );
2277
2278 if ( $watched ) {
2279 $articleLink = '<strong>'.$articleLink.'</strong>';
2280 }
2281 $s .= ' '.$articleLink;
2282
2283 }
2284
2285 # Timestamp
2286 $s .= '; ' . $wgLang->time( $rc_timestamp, true, $wgRCSeconds ) . ' . . ';
2287
2288 # User link (or contributions for unregistered users)
2289 if ( 0 == $rc_user ) {
2290 $userLink = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
2291 $rc_user_text, 'target=' . $rc_user_text );
2292 } else {
2293 $userLink = $this->makeLink( $wgLang->getNsText( NS_USER ) . ':'.$rc_user_text, $rc_user_text );
2294 }
2295 $s .= $userLink;
2296
2297 # User talk link
2298 $talkname=$wgLang->getNsText(NS_TALK); # use the shorter name
2299 global $wgDisableAnonTalk;
2300 if( 0 == $rc_user && $wgDisableAnonTalk ) {
2301 $userTalkLink = '';
2302 } else {
2303 $utns=$wgLang->getNsText(NS_USER_TALK);
2304 $userTalkLink= $this->makeLink($utns . ':'.$rc_user_text, $talkname );
2305 }
2306 # Block link
2307 $blockLink='';
2308 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2309 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2310 'Blockip' ), wfMsg( 'blocklink' ), 'ip='.$rc_user_text );
2311
2312 }
2313 if($blockLink) {
2314 if($userTalkLink) $userTalkLink .= ' | ';
2315 $userTalkLink .= $blockLink;
2316 }
2317 if($userTalkLink) $s.=' ('.$userTalkLink.')';
2318
2319 # Add comment
2320 if ( '' != $rc_comment && '*' != $rc_comment && $rc_type != RC_MOVE && $rc_type != RC_MOVE_OVER_REDIRECT ) {
2321 $rc_comment=$this->formatComment($rc_comment);
2322 $s .= $wgLang->emphasize(' (' . $rc_comment . ')');
2323 }
2324 $s .= "</li>\n";
2325
2326 return $s;
2327 }
2328
2329 # function recentChangesLineNew( $ts, $u, $ut, $ns, $ttl, $c, $isminor, $isnew, $watched = false, $oldid = 0 , $diffid = 0 )
2330 function recentChangesLineNew( &$baseRC, $watched = false )
2331 {
2332 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds;
2333
2334 # Create a specialised object
2335 $rc = RCCacheEntry::newFromParent( $baseRC ) ;
2336
2337 # Extract fields from DB into the function scope (rc_xxxx variables)
2338 extract( $rc->mAttribs );
2339 $curIdEq = 'curid=' . $rc_cur_id;
2340
2341 # If it's a new day, add the headline and flush the cache
2342 $date = $wgLang->date( $rc_timestamp, true);
2343 $ret = '' ;
2344 if ( $date != $this->lastdate ) {
2345 # Process current cache
2346 $ret = $this->recentChangesBlock () ;
2347 $this->rc_cache = array() ;
2348 $ret .= "<h4>{$date}</h4>\n";
2349 $this->lastdate = $date;
2350 }
2351
2352 # Make article link
2353 if ( $rc_type == RC_MOVE || $rc_type == RC_MOVE_OVER_REDIRECT ) {
2354 if ( $rc_type == RC_MOVE ) {
2355 $msg = "1movedto2";
2356 } else {
2357 $msg = "1movedto2_redir";
2358 }
2359 $clink = wfMsg( $msg, $this->makeKnownLinkObj( $rc->getTitle(), '', 'redirect=no' ),
2360 $this->makeKnownLinkObj( $rc->getMovedToTitle(), '' ) );
2361 } else {
2362 $clink = $this->makeKnownLinkObj( $rc->getTitle(), '' ) ;
2363 }
2364
2365 $time = $wgLang->time( $rc_timestamp, true, $wgRCSeconds );
2366 $rc->watched = $watched ;
2367 $rc->link = $clink ;
2368 $rc->timestamp = $time;
2369
2370 # Make "cur" and "diff" links
2371 if ( ( $rc_type == RC_NEW && $rc_this_oldid == 0 ) || $rc_type == RC_LOG || $rc_type == RC_MOVE || $rc_type == RC_MOVE_OVER_REDIRECT ) {
2372 $curLink = wfMsg( 'cur' );
2373 $diffLink = wfMsg( 'diff' );
2374 } else {
2375 $query = $curIdEq.'&diff=0&oldid='.$rc_this_oldid;
2376 $aprops = ' tabindex="'.$baseRC->counter.'"';
2377 $curLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'cur' ), $query, '' ,'' , $aprops );
2378 $diffLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'diff'), $query, '' ,'' , $aprops );
2379 }
2380
2381 # Make "last" link
2382 $titleObj = $rc->getTitle();
2383 if ( $rc_last_oldid == 0 || $rc_type == RC_LOG || $rc_type == RC_MOVE || $rc_type == RC_MOVE_OVER_REDIRECT ) {
2384 $lastLink = wfMsg( 'last' );
2385 } else {
2386 $lastLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'last' ),
2387 $curIdEq.'&diff='.$rc_this_oldid.'&oldid='.$rc_last_oldid );
2388 }
2389
2390 # Make user link (or user contributions for unregistered users)
2391 if ( 0 == $rc_user ) {
2392 $userLink = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
2393 $rc_user_text, 'target=' . $rc_user_text );
2394 } else {
2395 $userLink = $this->makeLink( $wgLang->getNsText(
2396 Namespace::getUser() ) . ':'.$rc_user_text, $rc_user_text );
2397 }
2398
2399 $rc->userlink = $userLink ;
2400 $rc->lastlink = $lastLink ;
2401 $rc->curlink = $curLink ;
2402 $rc->difflink = $diffLink;
2403
2404
2405 # Make user talk link
2406 $utns=$wgLang->getNsText(NS_USER_TALK);
2407 $talkname=$wgLang->getNsText(NS_TALK); # use the shorter name
2408 $userTalkLink= $this->makeLink($utns . ':'.$rc_user_text, $talkname );
2409
2410 global $wgDisableAnonTalk;
2411 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2412 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2413 'Blockip' ), wfMsg( 'blocklink' ), 'ip='.$rc_user_text );
2414 if( $wgDisableAnonTalk )
2415 $rc->usertalklink = ' ('.$blockLink.')';
2416 else
2417 $rc->usertalklink = ' ('.$userTalkLink.' | '.$blockLink.')';
2418 } else {
2419 if( $wgDisableAnonTalk && ($rc_user == 0) )
2420 $rc->usertalklink = '';
2421 else
2422 $rc->usertalklink = ' ('.$userTalkLink.')';
2423 }
2424
2425 # Put accumulated information into the cache, for later display
2426 # Page moves go on their own line
2427 $title = $rc->getTitle();
2428 $secureName = $title->getPrefixedDBkey();
2429 if ( $rc_type == RC_MOVE || $rc_type == RC_MOVE_OVER_REDIRECT ) {
2430 # Use an @ character to prevent collision with page names
2431 $this->rc_cache['@@' . ($this->rcMoveIndex++)] = array($rc);
2432 } else {
2433 if ( !isset ( $this->rc_cache[$secureName] ) ) $this->rc_cache[$secureName] = array() ;
2434 array_push ( $this->rc_cache[$secureName] , $rc ) ;
2435 }
2436 return $ret;
2437 }
2438
2439 function endImageHistoryList()
2440 {
2441 $s = "</ul>\n";
2442 return $s;
2443 }
2444
2445 /* This function is called by all recent changes variants, by the page history,
2446 and by the user contributions list. It is responsible for formatting edit
2447 comments. It escapes any HTML in the comment, but adds some CSS to format
2448 auto-generated comments (from section editing) and formats [[wikilinks]].
2449 Main author: Erik Möller (moeller@scireview.de)
2450 */
2451 function formatComment($comment)
2452 {
2453 global $wgLang;
2454 $comment=wfEscapeHTML($comment);
2455
2456 # The pattern for autogen comments is / * foo * /, which makes for
2457 # some nasty regex.
2458 # We look for all comments, match any text before and after the comment,
2459 # add a separator where needed and format the comment itself with CSS
2460 while (preg_match('/(.*)\/\*\s*(.*?)\s*\*\/(.*)/', $comment,$match)) {
2461 $pre=$match[1];
2462 $auto=$match[2];
2463 $post=$match[3];
2464 $sep='-';
2465 if($pre) { $auto = $sep.' '.$auto; }
2466 if($post) { $auto .= ' '.$sep; }
2467 $auto='<span class="autocomment">'.$auto.'</span>';
2468 $comment=$pre.$auto.$post;
2469 }
2470
2471 # format regular and media links - all other wiki formatting
2472 # is ignored
2473 while(preg_match('/\[\[(.*?)(\|(.*?))*\]\]/',$comment,$match)) {
2474
2475 $medians = $wgLang->getNsText(Namespace::getMedia()).':';
2476 $func='makeLink';
2477 if(preg_match('/^'.$medians.'/i',$match[1])) {
2478 $func='makeMediaLink';
2479 }
2480 # Handle link renaming [[foo|text]] will show link as "text"
2481 if(isset($match[3]) ) {
2482 $comment=
2483 preg_replace('/\[\[(.*?)\]\]/',
2484 $this->$func($match[1],$match[3]),$comment,1);
2485 } else {
2486 $comment=
2487 preg_replace('/\[\[(.*?)\]\]/',
2488 $this->$func($match[1],$match[1]),$comment,1);
2489 }
2490 }
2491
2492 return $comment;
2493
2494 }
2495
2496 function imageHistoryLine( $iscur, $timestamp, $img, $user, $usertext, $size, $description )
2497 {
2498 global $wgUser, $wgLang, $wgTitle;
2499
2500 $datetime = $wgLang->timeanddate( $timestamp, true );
2501 $del = wfMsg( 'deleteimg' );
2502 $cur = wfMsg( 'cur' );
2503
2504 if ( $iscur ) {
2505 $url = Image::wfImageUrl( $img );
2506 $rlink = $cur;
2507 if ( $wgUser->isSysop() ) {
2508 $link = $wgTitle->escapeLocalURL( 'image=' . $wgTitle->getPartialURL() .
2509 '&action=delete' );
2510 $style = $this->getInternalLinkAttributes( $link, $del );
2511
2512 $dlink = '<a href="'.$link.'"'.$style.'>'.$del.'</a>';
2513 } else {
2514 $dlink = $del;
2515 }
2516 } else {
2517 $url = wfEscapeHTML( wfImageArchiveUrl( $img ) );
2518 if( $wgUser->getID() != 0 ) {
2519 $rlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2520 wfMsg( 'revertimg' ), 'action=revert&oldimage=' .
2521 urlencode( $img ) );
2522 $dlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2523 $del, 'action=delete&oldimage=' . urlencode( $img ) );
2524 } else {
2525 # Having live active links for non-logged in users
2526 # means that bots and spiders crawling our site can
2527 # inadvertently change content. Baaaad idea.
2528 $rlink = wfMsg( 'revertimg' );
2529 $dlink = $del;
2530 }
2531 }
2532 if ( 0 == $user ) {
2533 $userlink = $usertext;
2534 } else {
2535 $userlink = $this->makeLink( $wgLang->getNsText( Namespace::getUser() ) .
2536 ':'.$usertext, $usertext );
2537 }
2538 $nbytes = wfMsg( 'nbytes', $size );
2539 $style = $this->getInternalLinkAttributes( $url, $datetime );
2540
2541 $s = "<li> ({$dlink}) ({$rlink}) <a href=\"{$url}\"{$style}>{$datetime}</a>"
2542 . " . . {$userlink} ({$nbytes})";
2543
2544 if ( '' != $description && '*' != $description ) {
2545 $sk=$wgUser->getSkin();
2546 $s .= $wgLang->emphasize(' (' . $sk->formatComment($description) . ')');
2547 }
2548 $s .= "</li>\n";
2549 return $s;
2550 }
2551
2552 function tocIndent($level) {
2553 return str_repeat( '<div class="tocindent">'."\n", $level>0 ? $level : 0 );
2554 }
2555
2556 function tocUnindent($level) {
2557 return str_repeat( "</div>\n", $level>0 ? $level : 0 );
2558 }
2559
2560 # parameter level defines if we are on an indentation level
2561 function tocLine( $anchor, $tocline, $level ) {
2562 $link = '<a href="#'.$anchor.'">'.$tocline.'</a><br />';
2563 if($level) {
2564 return $link."\n";
2565 } else {
2566 return '<div class="tocline">'.$link."</div>\n";
2567 }
2568
2569 }
2570
2571 function tocTable($toc) {
2572 # note to CSS fanatics: putting this in a div does not work -- div won't auto-expand
2573 # try min-width & co when somebody gets a chance
2574 $hideline = ' <script type="text/javascript">showTocToggle("' . addslashes( wfMsg('showtoc') ) . '","' . addslashes( wfMsg('hidetoc') ) . '")</script>';
2575 return
2576 '<table border="0" id="toc"><tr id="toctitle"><td align="center">'."\n".
2577 '<b>'.wfMsg('toc').'</b>' .
2578 $hideline .
2579 '</td></tr><tr id="tocinside"><td>'."\n".
2580 $toc."</td></tr></table>\n";
2581 }
2582
2583 # These two do not check for permissions: check $wgTitle->userCanEdit before calling them
2584 function editSectionScript( $section, $head ) {
2585 global $wgTitle, $wgRequest;
2586 if( $wgRequest->getInt( 'oldid' ) && ( $wgRequest->getVal( 'diff' ) != '0' ) ) {
2587 return $head;
2588 }
2589 $url = $wgTitle->escapeLocalURL( 'action=edit&section='.$section );
2590 return '<span oncontextmenu=\'document.location="'.$url.'";return false;\'>'.$head.'</span>';
2591 }
2592
2593 function editSectionLink( $section ) {
2594 global $wgRequest;
2595 global $wgTitle, $wgUser, $wgLang;
2596
2597 if( $wgRequest->getInt( 'oldid' ) && ( $wgRequest->getVal( 'diff' ) != '0' ) ) {
2598 # Section edit links would be out of sync on an old page.
2599 # But, if we're diffing to the current page, they'll be
2600 # correct.
2601 return '';
2602 }
2603
2604 $editurl = '&section='.$section;
2605 $url = $this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg('editsection'),'action=edit'.$editurl);
2606
2607 if( $wgLang->isRTL() ) {
2608 $farside = 'left';
2609 $nearside = 'right';
2610 } else {
2611 $farside = 'right';
2612 $nearside = 'left';
2613 }
2614 return "<div class=\"editsection\" style=\"float:$farside;margin-$nearside:5px;\">[".$url."]</div>";
2615
2616 }
2617
2618 // This function is called by EditPage.php and shows a bulletin board style
2619 // toolbar for common editing functions. It can be disabled in the user preferences.
2620 // The necsesary JavaScript code can be found in style/wikibits.js.
2621 function getEditToolbar() {
2622 global $wgStylePath, $wgLang, $wgMimeType;
2623
2624 // toolarray an array of arrays which each include the filename of
2625 // the button image (without path), the opening tag, the closing tag,
2626 // and optionally a sample text that is inserted between the two when no
2627 // selection is highlighted.
2628 // The tip text is shown when the user moves the mouse over the button.
2629
2630 // Already here are accesskeys (key), which are not used yet until someone
2631 // can figure out a way to make them work in IE. However, we should make
2632 // sure these keys are not defined on the edit page.
2633 $toolarray=array(
2634 array( 'image'=>'button_bold.png',
2635 'open'=>"\'\'\'",
2636 'close'=>"\'\'\'",
2637 'sample'=>wfMsg('bold_sample'),
2638 'tip'=>wfMsg('bold_tip'),
2639 'key'=>'B'
2640 ),
2641 array( "image"=>"button_italic.png",
2642 "open"=>"\'\'",
2643 "close"=>"\'\'",
2644 "sample"=>wfMsg("italic_sample"),
2645 "tip"=>wfMsg("italic_tip"),
2646 "key"=>"I"
2647 ),
2648 array( "image"=>"button_link.png",
2649 "open"=>"[[",
2650 "close"=>"]]",
2651 "sample"=>wfMsg("link_sample"),
2652 "tip"=>wfMsg("link_tip"),
2653 "key"=>"L"
2654 ),
2655 array( "image"=>"button_extlink.png",
2656 "open"=>"[",
2657 "close"=>"]",
2658 "sample"=>wfMsg("extlink_sample"),
2659 "tip"=>wfMsg("extlink_tip"),
2660 "key"=>"X"
2661 ),
2662 array( "image"=>"button_headline.png",
2663 "open"=>"\\n== ",
2664 "close"=>" ==\\n",
2665 "sample"=>wfMsg("headline_sample"),
2666 "tip"=>wfMsg("headline_tip"),
2667 "key"=>"H"
2668 ),
2669 array( "image"=>"button_image.png",
2670 "open"=>"[[".$wgLang->getNsText(NS_IMAGE).":",
2671 "close"=>"]]",
2672 "sample"=>wfMsg("image_sample"),
2673 "tip"=>wfMsg("image_tip"),
2674 "key"=>"D"
2675 ),
2676 array( "image"=>"button_media.png",
2677 "open"=>"[[".$wgLang->getNsText(NS_MEDIA).":",
2678 "close"=>"]]",
2679 "sample"=>wfMsg("media_sample"),
2680 "tip"=>wfMsg("media_tip"),
2681 "key"=>"M"
2682 ),
2683 array( "image"=>"button_math.png",
2684 "open"=>"\\<math\\>",
2685 "close"=>"\\</math\\>",
2686 "sample"=>wfMsg("math_sample"),
2687 "tip"=>wfMsg("math_tip"),
2688 "key"=>"C"
2689 ),
2690 array( "image"=>"button_nowiki.png",
2691 "open"=>"\\<nowiki\\>",
2692 "close"=>"\\</nowiki\\>",
2693 "sample"=>wfMsg("nowiki_sample"),
2694 "tip"=>wfMsg("nowiki_tip"),
2695 "key"=>"N"
2696 ),
2697 array( "image"=>"button_sig.png",
2698 "open"=>"--~~~~",
2699 "close"=>"",
2700 "sample"=>"",
2701 "tip"=>wfMsg("sig_tip"),
2702 "key"=>"Y"
2703 ),
2704 array( "image"=>"button_hr.png",
2705 "open"=>"\\n----\\n",
2706 "close"=>"",
2707 "sample"=>"",
2708 "tip"=>wfMsg("hr_tip"),
2709 "key"=>"R"
2710 )
2711 );
2712 $toolbar ="<script type='text/javascript'>\n/*<![CDATA[*/\n";
2713
2714 $toolbar.="document.writeln(\"<div id='toolbar'>\");\n";
2715 foreach($toolarray as $tool) {
2716
2717 $image=$wgStylePath.'/images/'.$tool['image'];
2718 $open=$tool['open'];
2719 $close=$tool['close'];
2720 $sample = addslashes( $tool['sample'] );
2721
2722 // Note that we use the tip both for the ALT tag and the TITLE tag of the image.
2723 // Older browsers show a "speedtip" type message only for ALT.
2724 // Ideally these should be different, realistically they
2725 // probably don't need to be.
2726 $tip = addslashes( $tool['tip'] );
2727
2728 #$key = $tool["key"];
2729
2730 $toolbar.="addButton('$image','$tip','$open','$close','$sample');\n";
2731 }
2732
2733 $toolbar.="addInfobox('" . addslashes( wfMsg( "infobox" ) ) . "','" . addslashes(wfMsg("infobox_alert")) . "');\n";
2734 $toolbar.="document.writeln(\"</div>\");\n";
2735
2736 $toolbar.="/*]]>*/\n</script>";
2737 return $toolbar;
2738 }
2739
2740 }
2741 ?>