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