3 # This is not a valid entry point, perform no further processing unless MEDIAWIKI is defined
4 if( defined( "MEDIAWIKI" ) ) {
8 require_once( 'Feed.php' ); // should not be called if the actual page isn't feed enabled
9 require_once( 'Image.php' );
11 # These are the INTERNAL names, which get mapped
12 # directly to class names. For display purposes, the
13 # Language class has internationalized names
15 /* private */ $wgValidSkinNames = array(
16 'standard' => 'Standard',
17 'nostalgia' => 'Nostalgia',
18 'cologneblue' => 'CologneBlue'
21 #$wgValidSkinNames[] = 'PHPTal';
22 #$wgValidSkinNames['davinci'] = 'DaVinci';
23 #$wgValidSkinNames['mono'] = 'Mono';
24 $wgValidSkinNames['monobook'] = 'MonoBook';
25 $wgValidSkinNames['myskin'] = 'MySkin';
26 #$wgValidSkinNames['monobookminimal'] = 'MonoBookMinimal';
27 $wgValidSkinNames['chick'] = 'Chick';
30 require_once( 'RecentChange.php' );
32 class RCCacheEntry
extends RecentChange
34 var $secureName, $link;
35 var $curlink , $difflink, $lastlink , $usertalklink , $versionlink ;
36 var $userlink, $timestamp, $watched;
38 function newFromParent( $rc )
40 $rc2 = new RCCacheEntry
;
41 $rc2->mAttribs
= $rc->mAttribs
;
42 $rc2->mExtra
= $rc->mExtra
;
48 # The main skin class that provide methods and properties for all other skins
49 # including PHPTal skins.
50 # This base class is also the "Standard" skin.
54 /* private */ var $lastdate, $lastline;
55 var $linktrail ; # linktrail regexp
56 var $rc_cache ; # Cache for Enhanced Recent Changes
57 var $rcCacheIndex ; # Recent Changes Cache Counter for visibility toggle
59 var $postParseLinkColour = true;
62 global $wgUseOldExistenceCheck;
63 $postParseLinkColour = !$wgUseOldExistenceCheck;
64 $this->linktrail
= wfMsg('linktrail');
67 function getSkinNames() {
68 global $wgValidSkinNames;
69 return $wgValidSkinNames;
72 function getStylesheet() {
73 return 'wikistandard.css';
76 function getSkinName() {
80 # Get/set accessor for delayed link colouring
81 function postParseLinkColour( $setting = NULL ) {
82 return wfSetVar( $this->postParseLinkColour
, $setting );
85 function qbSetting() {
86 global $wgOut, $wgUser;
88 if ( $wgOut->isQuickbarSuppressed() ) { return 0; }
89 $q = $wgUser->getOption( 'quickbar' );
90 if ( '' == $q ) { $q = 0; }
94 function initPage( &$out ) {
95 $fname = 'Skin::initPage';
96 wfProfileIn( $fname );
98 $out->addLink( array( 'rel' => 'shortcut icon', 'href' => '/favicon.ico' ) );
100 $this->addMetadataLinks($out);
102 wfProfileOut( $fname );
105 function addMetadataLinks( &$out ) {
106 global $wgTitle, $wgEnableDublinCoreRdf, $wgEnableCreativeCommonsRdf, $wgRdfMimeType, $action;
107 global $wgRightsPage, $wgRightsUrl;
109 if( $out->isArticleRelated() ) {
110 # note: buggy CC software only reads first "meta" link
111 if( $wgEnableCreativeCommonsRdf ) {
112 $out->addMetadataLink( array(
113 'title' => 'Creative Commons',
114 'type' => 'application/rdf+xml',
115 'href' => $wgTitle->getLocalURL( 'action=creativecommons') ) );
117 if( $wgEnableDublinCoreRdf ) {
118 $out->addMetadataLink( array(
119 'title' => 'Dublin Core',
120 'type' => 'application/rdf+xml',
121 'href' => $wgTitle->getLocalURL( 'action=dublincore' ) ) );
125 if( $wgRightsPage ) {
126 $copy = Title
::newFromText( $wgRightsPage );
128 $copyright = $copy->getLocalURL();
131 if( !$copyright && $wgRightsUrl ) {
132 $copyright = $wgRightsUrl;
135 $out->addLink( array(
136 'rel' => 'copyright',
137 'href' => $copyright ) );
141 function outputPage( &$out ) {
142 global $wgDebugComments;
144 wfProfileIn( 'Skin::outputPage' );
145 $this->initPage( $out );
146 $out->out( $out->headElement() );
148 $out->out( "\n<body" );
149 $ops = $this->getBodyOptions();
150 foreach ( $ops as $name => $val ) {
151 $out->out( " $name='$val'" );
154 if ( $wgDebugComments ) {
155 $out->out( "<!-- Wiki debugging output:\n" .
156 $out->mDebugtext
. "-->\n" );
158 $out->out( $this->beforeContent() );
160 $out->out( $out->mBodytext
. "\n" );
162 $out->out( $this->afterContent() );
165 $out->out( $out->reportTime() );
167 $out->out( "\n</body></html>" );
170 function getHeadScripts() {
171 global $wgStylePath, $wgUser, $wgLang, $wgAllowUserJs;
172 $r = "<script type=\"text/javascript\" src=\"{$wgStylePath}/wikibits.js\"></script>\n";
173 if( $wgAllowUserJs && $wgUser->getID() != 0 ) { # logged in
174 $userpage = $wgLang->getNsText( Namespace::getUser() ) . ":" . $wgUser->getName();
175 $userjs = htmlspecialchars($this->makeUrl($userpage.'/'.$this->getSkinName().'.js', 'action=raw&ctype=text/javascript'));
176 $r .= '<script type="text/javascript" src="'.$userjs."\"></script>\n";
181 # get the user/site-specific stylesheet, SkinPHPTal called from RawPage.php (settings are cached that way)
182 function getUserStylesheet() {
183 global $wgOut, $wgStylePath, $wgLang, $wgUser, $wgRequest, $wgTitle, $wgAllowUserCss;
184 $sheet = $this->getStylesheet();
185 $action = $wgRequest->getText('action');
186 $s = "@import \"$wgStylePath/$sheet\";\n";
187 if($wgLang->isRTL()) $s .= "@import \"$wgStylePath/common_rtl.css\";\n";
188 if( $wgAllowUserCss && $wgUser->getID() != 0 ) { # logged in
189 if($wgTitle->isCssSubpage() and $action == 'submit' and $wgTitle->userCanEditCssJsSubpage()) {
190 $s .= $wgRequest->getText('wpTextbox1');
192 $userpage = $wgLang->getNsText( Namespace::getUser() ) . ":" . $wgUser->getName();
193 $s.= '@import "'.$this->makeUrl($userpage.'/'.$this->getSkinName().'.css', 'action=raw&ctype=text/css').'";'."\n";
196 $s .= $this->doGetUserStyles();
200 # placeholder, returns generated js in monobook
201 function getUserJs() { return; }
203 # Return html code that include User stylesheets
204 function getUserStyles() {
205 global $wgOut, $wgStylePath, $wgLang;
206 $s = "<style type='text/css'>\n";
207 $s .= "/*/*/ /*<![CDATA[*/\n"; # <-- Hide the styles from Netscape 4 without hiding them from IE/Mac
208 $s .= $this->getUserStylesheet();
209 $s .= "/*]]>*/ /* */\n";
214 # Some styles that are set by user through the user settings interface.
215 function doGetUserStyles() {
216 global $wgUser, $wgLang;
218 $csspage = $wgLang->getNsText( NS_MEDIAWIKI
) . ':' . $this->getSkinName() . '.css';
219 $s = '@import "'.$this->makeUrl($csspage, 'action=raw&ctype=text/css')."\";\n";
221 if ( 1 == $wgUser->getOption( 'underline' ) ) {
222 # Don't override browser settings
226 $s .= "a { text-decoration: none; }\n";
228 if ( 1 == $wgUser->getOption( 'highlightbroken' ) ) {
229 $s .= "a.new, #quickbar a.new { color: #CC2200; }\n";
231 if ( 1 == $wgUser->getOption( 'justify' ) ) {
232 $s .= "#article { text-align: justify; }\n";
237 function getBodyOptions()
239 global $wgUser, $wgTitle, $wgNamespaceBackgrounds, $wgOut, $wgRequest;
241 extract( $wgRequest->getValues( 'oldid', 'redirect', 'diff' ) );
243 if ( 0 != $wgTitle->getNamespace() ) {
244 $a = array( 'bgcolor' => '#ffffec' );
246 else $a = array( 'bgcolor' => '#FFFFFF' );
247 if($wgOut->isArticle() && $wgUser->getOption('editondblclick') &&
248 (!$wgTitle->isProtected() ||
$wgUser->isSysop()) ) {
249 $t = wfMsg( 'editthispage' );
251 if ( !empty($redirect) ) {
252 $red = "&redirect={$redirect}";
254 if ( !empty($oldid) && ! isset( $diff ) ) {
255 $oid = "&oldid={$oldid}";
257 $s = $wgTitle->getFullURL( "action=edit{$oid}{$red}" );
258 $s = 'document.location = "' .$s .'";';
259 $a +
= array ('ondblclick' => $s);
262 $a['onload'] = $wgOut->getOnloadHandler();
266 function getExternalLinkAttributes( $link, $text, $class='' )
268 global $wgUser, $wgOut, $wgLang;
270 $link = urldecode( $link );
271 $link = $wgLang->checkTitleEncoding( $link );
272 $link = str_replace( '_', ' ', $link );
273 $link = htmlspecialchars( $link );
275 $r = ($class != '') ?
" class='$class'" : " class='external'";
277 if ( 1 == $wgUser->getOption( 'hover' ) ) {
278 $r .= " title=\"{$link}\"";
283 function getInternalLinkAttributes( $link, $text, $broken = false )
285 global $wgUser, $wgOut;
287 $link = urldecode( $link );
288 $link = str_replace( '_', ' ', $link );
289 $link = htmlspecialchars( $link );
291 if ( $broken == 'stub' ) {
292 $r = ' class="stub"';
293 } else if ( $broken == 'yes' ) {
299 if ( 1 == $wgUser->getOption( 'hover' ) ) {
300 $r .= " title=\"{$link}\"";
305 function getInternalLinkAttributesObj( &$nt, $text, $broken = false )
307 global $wgUser, $wgOut;
309 if ( $broken == 'stub' ) {
310 $r = ' class="stub"';
311 } else if ( $broken == 'yes' ) {
317 if ( 1 == $wgUser->getOption( 'hover' ) ) {
318 $r .= ' title ="' . $nt->getEscapedText() . '"';
329 # This will be called immediately after the <body> tag. Split into
330 # two functions to make it easier to subclass.
332 function beforeContent()
334 global $wgUser, $wgOut;
336 return $this->doBeforeContent();
339 function doBeforeContent()
341 global $wgUser, $wgOut, $wgTitle, $wgLang, $wgSiteNotice;
342 $fname = 'Skin::doBeforeContent';
343 wfProfileIn( $fname );
346 $qb = $this->qbSetting();
348 if( $langlinks = $this->otherLanguages() ) {
354 $borderhack = 'class="top"';
357 $s .= "\n<div id='content'>\n<div id='topbar'>\n" .
358 "<table border='0' cellspacing='0' width='98%'>\n<tr>\n";
361 $left = ($qb == 1 ||
$qb == 3);
362 if($wgLang->isRTL()) $left = !$left;
365 $s .= "<td class='top' align='left' valign='top' rowspan='{$rows}'>\n" .
366 $this->logoText() . '</td>';
368 $s .= $this->getQuickbarCompensator( $rows );
370 $l = $wgLang->isRTL() ?
'right' : 'left';
371 $s .= "<td {$borderhack} align='$l' valign='top'>\n";
373 $s .= $this->topLinks() ;
374 $s .= "<p class='subtitle'>" . $this->pageTitleLinks() . "</p>\n";
376 $r = $wgLang->isRTL() ?
"left" : "right";
377 $s .= "</td>\n<td {$borderhack} valign='top' align='$r' nowrap='nowrap'>";
378 $s .= $this->nameAndLogin();
379 $s .= "\n<br />" . $this->searchForm() . "</td>";
382 $s .= "</tr>\n<tr>\n<td class='top' colspan=\"2\">$langlinks</td>\n";
385 if ( $shove && !$left ) { # Right
386 $s .= $this->getQuickbarCompensator( $rows );
388 $s .= "</tr>\n</table>\n</div>\n";
389 $s .= "\n<div id='article'>\n";
391 if( $wgSiteNotice ) {
392 $s .= "\n<div id='siteNotice'>$wgSiteNotice</div>\n";
394 $s .= $this->pageTitle();
395 $s .= $this->pageSubtitle() ;
396 $s .= $this->getCategories();
397 wfProfileOut( $fname );
401 function getCategoryLinks () {
402 global $wgOut, $wgTitle, $wgUser, $wgParser;
403 global $wgUseCategoryMagic, $wgUseCategoryBrowser, $wgLang;
405 if( !$wgUseCategoryMagic ) return '' ;
406 if( count( $wgOut->mCategoryLinks
) == 0 ) return '';
408 # Taken out so that they will be displayed in previews -- TS
409 #if( !$wgOut->isArticle() ) return '';
411 $t = implode ( ' | ' , $wgOut->mCategoryLinks
) ;
412 $s = $this->makeKnownLink( 'Special:Categories',
413 wfMsg( 'categories' ), 'article=' . urlencode( $wgTitle->getPrefixedDBkey() ) )
416 # optional 'dmoz-like' category browser. Will be shown under the list
417 # of categories an article belong to
418 if($wgUseCategoryBrowser) {
421 # get a big array of the parents tree
422 $parenttree = $wgTitle->getCategorieBrowser();
424 # Render the array as a serie of links
425 function walkThrough ($tree) {
427 $sk = $wgUser->getSkin();
429 foreach($tree as $element => $parent) {
431 # element start a new list
434 # grab the others elements
435 $return .= walkThrough($parent);
437 # add our current element to the list
438 $eltitle = Title
::NewFromText($element);
439 # FIXME : should be makeLink() [AV]
440 $return .= $sk->makeKnownLink($element, $eltitle->getText()).' > ';
445 $s .= walkThrough($parenttree);
451 function getCategories() {
452 $catlinks=$this->getCategoryLinks();
453 if(!empty($catlinks)) {
454 return "<p class='catlinks'>{$catlinks}</p>";
458 function getQuickbarCompensator( $rows = 1 ) {
459 return "<td width='152' rowspan='{$rows}'> </td>";
462 # This gets called immediately before the </body> tag.
464 function afterContent() {
465 global $wgUser, $wgOut, $wgServer;
466 global $wgTitle, $wgLang;
468 $printfooter = "<div class=\"printfooter\">\n" . $this->printFooter() . "</div>\n";
469 return $printfooter . $this->doAfterContent();
472 function printSource() {
474 $url = htmlspecialchars( $wgTitle->getFullURL() );
475 return wfMsg( "retrievedfrom", "<a href=\"$url\">$url</a>" );
478 function printFooter() {
479 return "<p>" . $this->printSource() .
480 "</p>\n\n<p>" . $this->pageStats() . "</p>\n";
483 function doAfterContent() {
484 global $wgUser, $wgOut, $wgLang;
485 $fname = 'Skin::doAfterContent';
486 wfProfileIn( $fname );
487 wfProfileIn( $fname.'-1' );
489 $s = "\n</div><br style=\"clear:both\" />\n";
490 $s .= "\n<div id='footer'>";
491 $s .= '<table border="0" cellspacing="0"><tr>';
493 wfProfileOut( $fname.'-1' );
494 wfProfileIn( $fname.'-2' );
496 $qb = $this->qbSetting();
498 $left = ($qb == 1 ||
$qb == 3);
499 if($wgLang->isRTL()) $left = !$left;
501 if ( $shove && $left ) { # Left
502 $s .= $this->getQuickbarCompensator();
504 wfProfileOut( $fname.'-2' );
505 wfProfileIn( $fname.'-3' );
506 $l = $wgLang->isRTL() ?
'right' : 'left';
507 $s .= "<td class='bottom' align='$l' valign='top'>";
509 $s .= $this->bottomLinks();
510 $s .= "\n<br />" . $this->mainPageLink()
511 . ' | ' . $this->aboutLink()
512 . ' | ' . $this->specialLink( 'recentchanges' )
513 . ' | ' . $this->searchForm()
514 . '<br /><span id="pagestats">' . $this->pageStats() . '</span>';
517 if ( $shove && !$left ) { # Right
518 $s .= $this->getQuickbarCompensator();
520 $s .= "</tr></table>\n</div>\n</div>\n";
522 wfProfileOut( $fname.'-3' );
523 wfProfileIn( $fname.'-4' );
524 if ( 0 != $qb ) { $s .= $this->quickBar(); }
525 wfProfileOut( $fname.'-4' );
526 wfProfileOut( $fname );
530 function pageTitleLinks() {
531 global $wgOut, $wgTitle, $wgUser, $wgLang, $wgUseApproval, $wgRequest;
533 extract( $wgRequest->getValues( 'oldid', 'diff' ) );
534 $action = $wgRequest->getText( 'action' );
536 $s = $this->printableLink();
537 if ( wfMsg ( 'disclaimers' ) != '-' ) $s .= ' | ' . $this->makeKnownLink( wfMsg( 'disclaimerpage' ), wfMsg( 'disclaimers' ) ) ;
539 if ( $wgOut->isArticleRelated() ) {
540 if ( $wgTitle->getNamespace() == Namespace::getImage() ) {
541 $name = $wgTitle->getDBkey();
542 $link = htmlspecialchars( Image
::wfImageUrl( $name ) );
543 $style = $this->getInternalLinkAttributes( $link, $name );
544 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>";
546 # This will show the "Approve" link if $wgUseApproval=true;
547 if ( isset ( $wgUseApproval ) && $wgUseApproval )
549 $t = $wgTitle->getDBkey();
550 $name = 'Approve this article' ;
551 $link = "http://test.wikipedia.org/w/magnus/wiki.phtml?title={$t}&action=submit&doit=1" ;
552 #htmlspecialchars( wfImageUrl( $name ) );
553 $style = $this->getExternalLinkAttributes( $link, $name );
554 $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>" ;
557 if ( 'history' == $action ||
isset( $diff ) ||
isset( $oldid ) ) {
558 $s .= ' | ' . $this->makeKnownLink( $wgTitle->getPrefixedText(),
559 wfMsg( 'currentrev' ) );
562 if ( $wgUser->getNewtalk() ) {
563 # do not show "You have new messages" text when we are viewing our
566 if(!(strcmp($wgTitle->getText(),$wgUser->getName()) == 0 &&
567 $wgTitle->getNamespace()==Namespace::getTalk(Namespace::getUser()))) {
568 $n =$wgUser->getName();
569 $tl = $this->makeKnownLink( $wgLang->getNsText(
570 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
571 wfMsg('newmessageslink') );
572 $s.= ' | <strong>'. wfMsg( 'newmessages', $tl ) . '</strong>';
576 $undelete = $this->getUndeleteLink();
577 if( !empty( $undelete ) ) {
578 $s .= ' | '.$undelete;
583 function getUndeleteLink() {
584 global $wgUser, $wgTitle, $wgLang, $action;
585 if( $wgUser->isSysop() &&
586 (($wgTitle->getArticleId() == 0) ||
($action == "history")) &&
587 ($n = $wgTitle->isDeleted() ) ) {
588 return wfMsg( 'thisisdeleted',
589 $this->makeKnownLink(
590 $wgLang->SpecialPage( 'Undelete/' . $wgTitle->getPrefixedDBkey() ),
591 wfMsg( 'restorelink', $n ) ) );
596 function printableLink() {
597 global $wgOut, $wgFeedClasses, $wgRequest;
599 $baseurl = $_SERVER['REQUEST_URI'];
600 if( strpos( '?', $baseurl ) == false ) {
605 $baseurl = htmlspecialchars( $baseurl );
606 $printurl = $wgRequest->escapeAppendQuery( 'printable=yes' );
608 $s = "<a href=\"$printurl\">" . wfMsg( 'printableversion' ) . '</a>';
609 if( $wgOut->isSyndicated() ) {
610 foreach( $wgFeedClasses as $format => $class ) {
611 $feedurl = $wgRequest->escapeAppendQuery( "feed=$format" );
612 $s .= " | <a href=\"$feedurl\">{$format}</a>";
618 function pageTitle() {
619 global $wgOut, $wgTitle, $wgUser;
621 $s = '<h1 class="pagetitle">' . htmlspecialchars( $wgOut->getPageTitle() ) . '</h1>';
622 if($wgUser->getOption( 'editsectiononrightclick' ) && $wgTitle->userCanEdit()) { $s=$this->editSectionScript(0,$s);}
626 function pageSubtitle() {
629 $sub = $wgOut->getSubtitle();
631 global $wgExtraSubtitle;
632 $sub = wfMsg( 'fromwikipedia' ) . $wgExtraSubtitle;
634 $subpages = $this->subPageSubtitle();
635 $sub .= !empty($subpages)?
"</p><p class='subpages'>$subpages":'';
636 $s = "<p class='subtitle'>{$sub}</p>\n";
640 function subPageSubtitle() {
641 global $wgOut,$wgTitle,$wgNamespacesWithSubpages;
643 if($wgOut->isArticle() && !empty($wgNamespacesWithSubpages[$wgTitle->getNamespace()])) {
644 $ptext=$wgTitle->getPrefixedText();
645 if(preg_match('/\//',$ptext)) {
646 $links = explode('/',$ptext);
649 foreach($links as $link) {
651 if ($c<count($links)) {
652 $growinglink .= $link;
653 $getlink = $this->makeLink( $growinglink, $link );
654 if(preg_match('/class="new"/i',$getlink)) { break; } # this is a hack, but it saves time
658 $subpages .= '< ';
660 $subpages .= $getlink;
669 function nameAndLogin() {
670 global $wgUser, $wgTitle, $wgLang, $wgShowIPinHeader, $wgIP;
672 $li = $wgLang->specialPage( 'Userlogin' );
673 $lo = $wgLang->specialPage( 'Userlogout' );
676 if ( 0 == $wgUser->getID() ) {
677 if( $wgShowIPinHeader && isset( $_COOKIE[ini_get('session.name')] ) ) {
680 $tl = $this->makeKnownLink( $wgLang->getNsText(
681 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
682 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
684 $s .= $n . ' ('.$tl.')';
686 $s .= wfMsg('notloggedin');
689 $rt = $wgTitle->getPrefixedURL();
690 if ( 0 == strcasecmp( urlencode( $lo ), $rt ) ) {
692 } else { $q = "returnto={$rt}"; }
694 $s .= "\n<br />" . $this->makeKnownLink( $li,
695 wfMsg( 'login' ), $q );
697 $n = $wgUser->getName();
698 $rt = $wgTitle->getPrefixedURL();
699 $tl = $this->makeKnownLink( $wgLang->getNsText(
700 Namespace::getTalk( Namespace::getUser() ) ) . ":{$n}",
701 $wgLang->getNsText( Namespace::getTalk( 0 ) ) );
705 $s .= $this->makeKnownLink( $wgLang->getNsText(
706 Namespace::getUser() ) . ":{$n}", $n ) . "{$tl}<br />" .
707 $this->makeKnownLink( $lo, wfMsg( 'logout' ),
708 "returnto={$rt}" ) . ' | ' .
709 $this->specialLink( 'preferences' );
711 $s .= ' | ' . $this->makeKnownLink( wfMsg( 'helppage' ),
717 function getSearchLink() {
718 $searchPage =& Title
::makeTitle( NS_SPECIAL
, 'Search' );
719 return $searchPage->getLocalURL();
722 function escapeSearchLink() {
723 return htmlspecialchars( $this->getSearchLink() );
726 function searchForm() {
728 $search = $wgRequest->getText( 'search' );
730 $s = '<form name="search" class="inline" method="post" action="'
731 . $this->escapeSearchLink() . "\">\n"
732 . '<input type="text" name="search" size="19" value="'
733 . htmlspecialchars(substr($search,0,256)) . "\" />\n"
734 . '<input type="submit" name="go" value="' . wfMsg ('go') . '" /> '
735 . '<input type="submit" name="fulltext" value="' . wfMsg ('search') . "\" />\n</form>";
740 function topLinks() {
744 $s = $this->mainPageLink() . $sep
745 . $this->specialLink( 'recentchanges' );
747 if ( $wgOut->isArticleRelated() ) {
748 $s .= $sep . $this->editThisPage()
749 . $sep . $this->historyLink();
751 # Many people don't like this dropdown box
752 #$s .= $sep . $this->specialPagesList();
757 function bottomLinks() {
758 global $wgOut, $wgUser, $wgTitle;
762 if ( $wgOut->isArticleRelated() ) {
763 $s .= '<strong>' . $this->editThisPage() . '</strong>';
764 if ( 0 != $wgUser->getID() ) {
765 $s .= $sep . $this->watchThisPage();
767 $s .= $sep . $this->talkLink()
768 . $sep . $this->historyLink()
769 . $sep . $this->whatLinksHere()
770 . $sep . $this->watchPageLinksLink();
772 if ( $wgTitle->getNamespace() == Namespace::getUser()
773 ||
$wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser()) )
776 $id=User
::idFromName($wgTitle->getText());
777 $ip=User
::isIP($wgTitle->getText());
779 if($id ||
$ip) { # both anons and non-anons have contri list
780 $s .= $sep . $this->userContribsLink();
782 if ( 0 != $wgUser->getID() ) { # show only to signed in users
783 if($id) { # can only email non-anons
784 $s .= $sep . $this->emailUserLink();
788 if ( $wgUser->isSysop() && $wgTitle->getArticleId() ) {
789 $s .= "\n<br />" . $this->deleteThisPage() .
790 $sep . $this->protectThisPage() .
791 $sep . $this->moveThisPage();
793 $s .= "<br />\n" . $this->otherLanguages();
798 function pageStats() {
799 global $wgOut, $wgLang, $wgArticle, $wgRequest;
800 global $wgDisableCounters, $wgMaxCredits, $wgShowCreditsIfMax;
802 extract( $wgRequest->getValues( 'oldid', 'diff' ) );
803 if ( ! $wgOut->isArticle() ) { return ''; }
804 if ( isset( $oldid ) ||
isset( $diff ) ) { return ''; }
805 if ( 0 == $wgArticle->getID() ) { return ''; }
808 if ( !$wgDisableCounters ) {
809 $count = $wgLang->formatNum( $wgArticle->getCount() );
811 $s = wfMsg( 'viewcount', $count );
815 if (isset($wgMaxCredits) && $wgMaxCredits != 0) {
816 require_once("Credits.php");
817 $s .= ' ' . getCredits($wgArticle, $wgMaxCredits, $wgShowCreditsIfMax);
819 $s .= $this->lastModified();
822 return $s . ' ' . $this->getCopyright();
825 function getCopyright() {
826 global $wgRightsPage, $wgRightsUrl, $wgRightsText, $wgRequest;
829 $oldid = $wgRequest->getVal( 'oldid' );
830 $diff = $wgRequest->getVal( 'diff' );
832 if ( !is_null( $oldid ) && is_null( $diff ) && wfMsg( 'history_copyright' ) !== '-' ) {
833 $msg = 'history_copyright';
839 if( $wgRightsPage ) {
840 $link = $this->makeKnownLink( $wgRightsPage, $wgRightsText );
841 } elseif( $wgRightsUrl ) {
842 $link = $this->makeExternalLink( $wgRightsUrl, $wgRightsText );
847 $out .= wfMsg( $msg, $link );
851 function getCopyrightIcon() {
852 global $wgRightsPage, $wgRightsUrl, $wgRightsText, $wgRightsIcon;
854 if( $wgRightsIcon ) {
855 $icon = htmlspecialchars( $wgRightsIcon );
857 $url = htmlspecialchars( $wgRightsUrl );
858 $out .= '<a href="'.$url.'">';
860 $text = htmlspecialchars( $wgRightsText );
861 $out .= "<img src=\"$icon\" alt='$text' />";
869 function getPoweredBy() {
871 $url = htmlspecialchars( "$wgStylePath/images/poweredby_mediawiki_88x31.png" );
872 $img = '<a href="http://www.mediawiki.org/"><img src="'.$url.'" alt="MediaWiki" /></a>';
876 function lastModified() {
877 global $wgLang, $wgArticle;
879 $timestamp = $wgArticle->getTimestamp();
881 $d = $wgLang->timeanddate( $wgArticle->getTimestamp(), true );
882 $s = ' ' . wfMsg( 'lastmodified', $d );
889 function logoText( $align = '' ) {
890 if ( '' != $align ) { $a = " align='{$align}'"; }
893 $mp = wfMsg( 'mainpage' );
894 $titleObj = Title
::newFromText( $mp );
895 if ( is_object( $titleObj ) ) {
896 $url = $titleObj->escapeLocalURL();
901 $logourl = $this->getLogo();
902 $s = "<a href='{$url}'><img{$a} src='{$logourl}' alt='[{$mp}]' /></a>";
906 function quickBar() {
907 global $wgOut, $wgTitle, $wgUser, $wgRequest, $wgLang;
908 global $wgDisableUploads, $wgRemoteUploads;
910 $fname = 'Skin::quickBar';
911 wfProfileIn( $fname );
913 $action = $wgRequest->getText( 'action' );
914 $wpPreview = $wgRequest->getBool( 'wpPreview' );
915 $tns=$wgTitle->getNamespace();
917 $s = "\n<div id='quickbar'>";
918 $s .= "\n" . $this->logoText() . "\n<hr class='sep' />";
921 $s .= $this->mainPageLink()
922 . $sep . $this->specialLink( 'recentchanges' )
923 . $sep . $this->specialLink( 'randompage' );
924 if ($wgUser->getID()) {
925 $s.= $sep . $this->specialLink( 'watchlist' ) ;
926 $s .= $sep .$this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
927 wfMsg( 'mycontris' ), 'target=' . wfUrlencode($wgUser->getName() ) );
930 // only show watchlist link if logged in
931 if ( wfMsg ( 'currentevents' ) != '-' ) $s .= $sep . $this->makeKnownLink( wfMsg( 'currentevents' ), '' ) ;
932 $s .= "\n<br /><hr class='sep' />";
933 $articleExists = $wgTitle->getArticleId();
934 if ( $wgOut->isArticle() ||
$action =='edit' ||
$action =='history' ||
$wpPreview) {
935 if($wgOut->isArticle()) {
936 $s .= '<strong>' . $this->editThisPage() . '</strong>';
937 } else { # backlink to the article in edit or history mode
938 if($articleExists){ # no backlink if no article
941 $text = wfMsg('articlepage');
944 $text = wfMsg('viewtalkpage');
947 $text = wfMsg('userpage');
950 $text = wfMsg('viewtalkpage');
953 $text = wfMsg('wikipediapage');
956 $text = wfMsg('viewtalkpage');
959 $text = wfMsg('imagepage');
962 $text = wfMsg('viewtalkpage');
965 $text= wfMsg('articlepage');
968 $link = $wgTitle->getText();
969 if ($nstext = $wgLang->getNsText($tns) ) { # add namespace if necessary
970 $link = $nstext . ':' . $link ;
973 $s .= $this->makeLink( $link, $text );
974 } elseif( $wgTitle->getNamespace() != Namespace::getSpecial() ) {
975 # we just throw in a "New page" text to tell the user that he's in edit mode,
976 # and to avoid messing with the separator that is prepended to the next item
977 $s .= '<strong>' . wfMsg('newpage') . '</strong>';
983 if( $tns%2
&& $action!='edit' && !$wpPreview) {
984 $s.= '<br />'.$this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg('postcomment'),'action=edit§ion=new');
988 watching could cause problems in edit mode:
989 if user edits article, then loads "watch this article" in background and then saves
990 article with "Watch this article" checkbox disabled, the article is transparently
991 unwatched. Therefore we do not show the "Watch this page" link in edit mode
993 if ( 0 != $wgUser->getID() && $articleExists) {
994 if($action!='edit' && $action != 'submit' )
996 $s .= $sep . $this->watchThisPage();
998 if ( $wgTitle->userCanEdit() )
999 $s .= $sep . $this->moveThisPage();
1001 if ( $wgUser->isSysop() and $articleExists ) {
1002 $s .= $sep . $this->deleteThisPage() .
1003 $sep . $this->protectThisPage();
1005 $s .= $sep . $this->talkLink();
1006 if ($articleExists && $action !='history') {
1007 $s .= $sep . $this->historyLink();
1009 $s.=$sep . $this->whatLinksHere();
1011 if($wgOut->isArticleRelated()) {
1012 $s .= $sep . $this->watchPageLinksLink();
1015 if ( Namespace::getUser() == $wgTitle->getNamespace()
1016 ||
$wgTitle->getNamespace() == Namespace::getTalk(Namespace::getUser())
1019 $id=User
::idFromName($wgTitle->getText());
1020 $ip=User
::isIP($wgTitle->getText());
1023 $s .= $sep . $this->userContribsLink();
1025 if ( 0 != $wgUser->getID() ) {
1026 if($id) { # can only email real users
1027 $s .= $sep . $this->emailUserLink();
1031 $s .= "\n<br /><hr class='sep' />";
1034 if ( 0 != $wgUser->getID() && ( !$wgDisableUploads ||
$wgRemoteUploads ) ) {
1035 $s .= $this->specialLink( 'upload' ) . $sep;
1037 $s .= $this->specialLink( 'specialpages' )
1038 . $sep . $this->bugReportsLink();
1040 global $wgSiteSupportPage;
1041 if( $wgSiteSupportPage ) {
1042 $s .= "\n<br /><a href=\"" . htmlspecialchars( $wgSiteSupportPage ) .
1043 '" class="internal">' . wfMsg( 'sitesupport' ) . '</a>';
1046 $s .= "\n<br /></div>\n";
1047 wfProfileOut( $fname );
1051 function specialPagesList() {
1052 global $wgUser, $wgOut, $wgLang, $wgServer, $wgRedirectScript;
1053 require_once('SpecialPage.php');
1055 $pages = SpecialPage
::getPages();
1057 foreach ( $pages[''] as $name => $page ) {
1058 $a[$name] = $page->getDescription();
1060 if ( $wgUser->isSysop() )
1062 foreach ( $pages['sysop'] as $name => $page ) {
1063 $a[$name] = $page->getDescription();
1066 if ( $wgUser->isDeveloper() )
1068 foreach ( $pages['developer'] as $name => $page ) {
1069 $a[$name] = $page->getDescription() ;
1072 $go = wfMsg( 'go' );
1073 $sp = wfMsg( 'specialpages' );
1074 $spp = $wgLang->specialPage( 'Specialpages' );
1076 $s = '<form id="specialpages" method="get" class="inline" ' .
1077 'action="' . htmlspecialchars( "{$wgServer}{$wgRedirectScript}" ) . "\">\n";
1078 $s .= "<select name=\"wpDropdown\">\n";
1079 $s .= "<option value=\"{$spp}\">{$sp}</option>\n";
1081 foreach ( $a as $name => $desc ) {
1082 $p = $wgLang->specialPage( $name );
1083 $s .= "<option value=\"{$p}\">{$desc}</option>\n";
1085 $s .= "</select>\n";
1086 $s .= "<input type='submit' value=\"{$go}\" name='redirect' />\n";
1091 function mainPageLink() {
1092 $mp = wfMsg( 'mainpage' );
1093 $s = $this->makeKnownLink( $mp, $mp );
1097 function copyrightLink() {
1098 $s = $this->makeKnownLink( wfMsg( 'copyrightpage' ),
1099 wfMsg( 'copyrightpagename' ) );
1103 function aboutLink() {
1104 $s = $this->makeKnownLink( wfMsg( 'aboutpage' ),
1105 wfMsg( 'aboutwikipedia' ) );
1110 function disclaimerLink() {
1111 $s = $this->makeKnownLink( wfMsg( 'disclaimerpage' ),
1112 wfMsg( 'disclaimers' ) );
1116 function editThisPage() {
1117 global $wgOut, $wgTitle, $wgRequest;
1119 $oldid = $wgRequest->getVal( 'oldid' );
1120 $diff = $wgRequest->getVal( 'diff' );
1121 $redirect = $wgRequest->getVal( 'redirect' );
1123 if ( ! $wgOut->isArticleRelated() ) {
1124 $s = wfMsg( 'protectedpage' );
1126 $n = $wgTitle->getPrefixedText();
1127 if ( $wgTitle->userCanEdit() ) {
1128 $t = wfMsg( 'editthispage' );
1130 #$t = wfMsg( "protectedpage" );
1131 $t = wfMsg( 'viewsource' );
1135 if ( !is_null( $redirect ) ) { $red = "&redirect={$redirect}"; }
1136 if ( $oldid && ! isset( $diff ) ) {
1137 $oid = '&oldid='.$oldid;
1139 $s = $this->makeKnownLink( $n, $t, "action=edit{$oid}{$red}" );
1144 function deleteThisPage() {
1145 global $wgUser, $wgOut, $wgTitle, $wgRequest;
1147 $diff = $wgRequest->getVal( 'diff' );
1148 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
1149 $n = $wgTitle->getPrefixedText();
1150 $t = wfMsg( 'deletethispage' );
1152 $s = $this->makeKnownLink( $n, $t, 'action=delete' );
1159 function protectThisPage() {
1160 global $wgUser, $wgOut, $wgTitle, $wgRequest;
1162 $diff = $wgRequest->getVal( 'diff' );
1163 if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
1164 $n = $wgTitle->getPrefixedText();
1166 if ( $wgTitle->isProtected() ) {
1167 $t = wfMsg( 'unprotectthispage' );
1168 $q = 'action=unprotect';
1170 $t = wfMsg( 'protectthispage' );
1171 $q = 'action=protect';
1173 $s = $this->makeKnownLink( $n, $t, $q );
1180 function watchThisPage() {
1181 global $wgUser, $wgOut, $wgTitle;
1183 if ( $wgOut->isArticleRelated() ) {
1184 $n = $wgTitle->getPrefixedText();
1186 if ( $wgTitle->userIsWatching() ) {
1187 $t = wfMsg( 'unwatchthispage' );
1188 $q = 'action=unwatch';
1190 $t = wfMsg( 'watchthispage' );
1191 $q = 'action=watch';
1193 $s = $this->makeKnownLink( $n, $t, $q );
1195 $s = wfMsg( 'notanarticle' );
1200 function moveThisPage() {
1201 global $wgTitle, $wgLang;
1203 if ( $wgTitle->userCanEdit() ) {
1204 $s = $this->makeKnownLink( $wgLang->specialPage( 'Movepage' ),
1205 wfMsg( 'movethispage' ), 'target=' . $wgTitle->getPrefixedURL() );
1206 } // no message if page is protected - would be redundant
1210 function historyLink() {
1213 $s = $this->makeKnownLink( $wgTitle->getPrefixedText(),
1214 wfMsg( 'history' ), 'action=history' );
1218 function whatLinksHere() {
1219 global $wgTitle, $wgLang;
1221 $s = $this->makeKnownLink( $wgLang->specialPage( 'Whatlinkshere' ),
1222 wfMsg( 'whatlinkshere' ), 'target=' . $wgTitle->getPrefixedURL() );
1226 function userContribsLink() {
1227 global $wgTitle, $wgLang;
1229 $s = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
1230 wfMsg( 'contributions' ), 'target=' . $wgTitle->getPartialURL() );
1234 function emailUserLink() {
1235 global $wgTitle, $wgLang;
1237 $s = $this->makeKnownLink( $wgLang->specialPage( 'Emailuser' ),
1238 wfMsg( 'emailuser' ), 'target=' . $wgTitle->getPartialURL() );
1242 function watchPageLinksLink() {
1243 global $wgOut, $wgTitle, $wgLang;
1245 if ( ! $wgOut->isArticleRelated() ) {
1246 $s = '(' . wfMsg( 'notanarticle' ) . ')';
1248 $s = $this->makeKnownLink( $wgLang->specialPage(
1249 'Recentchangeslinked' ), wfMsg( 'recentchangeslinked' ),
1250 'target=' . $wgTitle->getPrefixedURL() );
1255 function otherLanguages() {
1256 global $wgOut, $wgLang, $wgTitle, $wgUseNewInterlanguage;
1258 $a = $wgOut->getLanguageLinks();
1259 if ( 0 == count( $a ) ) {
1260 if ( !$wgUseNewInterlanguage ) return '';
1261 $ns = $wgLang->getNsIndex ( $wgTitle->getNamespace () ) ;
1262 if ( $ns != 0 AND $ns != 1 ) return '' ;
1264 $x = 'mode=addlink&xt='.$wgTitle->getDBkey() ;
1265 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
1266 wfMsg( 'intl' ) , $x );
1269 if ( !$wgUseNewInterlanguage ) {
1270 $s = wfMsg( 'otherlanguages' ) . ': ';
1272 global $wgLanguageCode ;
1273 $x = 'mode=zoom&xt='.$wgTitle->getDBkey() ;
1274 $x .= '&xl='.$wgLanguageCode ;
1275 $s = $this->makeKnownLink( $wgLang->specialPage( 'Intl' ),
1276 wfMsg( 'otherlanguages' ) , $x ) . ': ' ;
1279 $s = wfMsg( 'otherlanguages' ) . ': ';
1281 if($wgLang->isRTL()) $s .= '<span dir="LTR">';
1282 foreach( $a as $l ) {
1283 if ( ! $first ) { $s .= ' | '; }
1286 $nt = Title
::newFromText( $l );
1287 $url = $nt->getFullURL();
1288 $text = $wgLang->getLanguageName( $nt->getInterwiki() );
1290 if ( '' == $text ) { $text = $l; }
1291 $style = $this->getExternalLinkAttributes( $l, $text );
1292 $s .= "<a href=\"{$url}\"{$style}>{$text}</a>";
1294 if($wgLang->isRTL()) $s .= '</span>';
1298 function bugReportsLink() {
1299 $s = $this->makeKnownLink( wfMsg( 'bugreportspage' ),
1300 wfMsg( 'bugreports' ) );
1304 function dateLink() {
1305 global $wgLinkCache;
1306 $t1 = Title
::newFromText( gmdate( 'F j' ) );
1307 $t2 = Title
::newFromText( gmdate( 'Y' ) );
1309 $wgLinkCache->suspend();
1310 $id = $t1->getArticleID();
1311 $wgLinkCache->resume();
1314 $s = $this->makeBrokenLink( $t1->getText() );
1316 $s = $this->makeKnownLink( $t1->getText() );
1320 $wgLinkCache->suspend();
1321 $id = $t2->getArticleID();
1322 $wgLinkCache->resume();
1325 $s .= $this->makeBrokenLink( $t2->getText() );
1327 $s .= $this->makeKnownLink( $t2->getText() );
1332 function talkLink() {
1333 global $wgLang, $wgTitle, $wgLinkCache;
1335 $tns = $wgTitle->getNamespace();
1336 if ( -1 == $tns ) { return ''; }
1338 $pn = $wgTitle->getText();
1339 $tp = wfMsg( 'talkpage' );
1340 if ( Namespace::isTalk( $tns ) ) {
1341 $lns = Namespace::getSubject( $tns );
1344 $text = wfMsg('articlepage');
1347 $text = wfMsg('userpage');
1350 $text = wfMsg('wikipediapage');
1353 $text = wfMsg('imagepage');
1356 $text= wfMsg('articlepage');
1360 $lns = Namespace::getTalk( $tns );
1363 $n = $wgLang->getNsText( $lns );
1364 if ( '' == $n ) { $link = $pn; }
1365 else { $link = $n.':'.$pn; }
1367 $wgLinkCache->suspend();
1368 $s = $this->makeLink( $link, $text );
1369 $wgLinkCache->resume();
1374 function commentLink() {
1375 global $wgLang, $wgTitle, $wgLinkCache;
1377 $tns = $wgTitle->getNamespace();
1378 if ( -1 == $tns ) { return ''; }
1380 $lns = ( Namespace::isTalk( $tns ) ) ?
$tns : Namespace::getTalk( $tns );
1382 # assert Namespace::isTalk( $lns )
1384 $n = $wgLang->getNsText( $lns );
1385 $pn = $wgTitle->getText();
1389 $wgLinkCache->suspend();
1390 $s = $this->makeKnownLink($link, wfMsg('postcomment'), 'action=edit§ion=new');
1391 $wgLinkCache->resume();
1396 # After all the page content is transformed into HTML, it makes
1397 # a final pass through here for things like table backgrounds.
1399 function transformContent( $text ) {
1403 # Note: This function MUST call getArticleID() on the link,
1404 # otherwise the cache won't get updated properly. See LINKCACHE.DOC.
1406 function makeLink( $title, $text = '', $query = '', $trail = '' ) {
1407 wfProfileIn( 'Skin::makeLink' );
1408 $nt = Title
::newFromText( $title );
1410 $result = $this->makeLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1412 wfDebug( 'Invalid title passed to Skin::makeLink(): "'.$title."\"\n" );
1413 $result = $text == "" ?
$title : $text;
1416 wfProfileOut( 'Skin::makeLink' );
1420 function makeKnownLink( $title, $text = '', $query = '', $trail = '', $prefix = '',$aprops = '') {
1421 $nt = Title
::newFromText( $title );
1423 return $this->makeKnownLinkObj( Title
::newFromText( $title ), $text, $query, $trail, $prefix , $aprops );
1425 wfDebug( 'Invalid title passed to Skin::makeKnownLink(): "'.$title."\"\n" );
1426 return $text == '' ?
$title : $text;
1430 function makeBrokenLink( $title, $text = '', $query = '', $trail = '' ) {
1431 $nt = Title
::newFromText( $title );
1433 return $this->makeBrokenLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1435 wfDebug( 'Invalid title passed to Skin::makeBrokenLink(): "'.$title."\"\n" );
1436 return $text == '' ?
$title : $text;
1440 function makeStubLink( $title, $text = '', $query = '', $trail = '' ) {
1441 $nt = Title
::newFromText( $title );
1443 return $this->makeStubLinkObj( Title
::newFromText( $title ), $text, $query, $trail );
1445 wfDebug( 'Invalid title passed to Skin::makeStubLink(): "'.$title."\"\n" );
1446 return $text == '' ?
$title : $text;
1450 # Pass a title object, not a title string
1451 function makeLinkObj( &$nt, $text= '', $query = '', $trail = '', $prefix = '' ) {
1452 global $wgOut, $wgUser;
1453 $fname = 'Skin::makeLinkObj';
1457 return "<!-- ERROR -->{$prefix}{$text}{$trail}";
1459 if ( $nt->isExternal() ) {
1460 $u = $nt->getFullURL();
1461 $link = $nt->getPrefixedURL();
1462 if ( '' == $text ) { $text = $nt->getPrefixedText(); }
1463 $style = $this->getExternalLinkAttributes( $link, $text, 'extiw' );
1466 if ( '' != $trail ) {
1467 if ( preg_match( '/^([a-z]+)(.*)$$/sD', $trail, $m ) ) {
1472 $retVal = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>{$trail}";
1473 } elseif ( 0 == $nt->getNamespace() && "" == $nt->getText() ) {
1474 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1475 } elseif ( ( -1 == $nt->getNamespace() ) ||
1476 ( Namespace::getImage() == $nt->getNamespace() ) ) {
1477 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1479 if ( $this->postParseLinkColour() ) {
1481 if ( '' != $trail ) {
1482 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1488 # Allows wiki to bypass using linkcache, see OutputPage::parseLinkHolders()
1489 $retVal = '<!--LINK ' . implode( ' ', array( $nt->getNamespace(), $nt->getDBkey(),
1490 $query, $prefix . $text . $inside ) ) . "-->{$trail}";
1492 # Work out link colour immediately
1493 $aid = $nt->getArticleID() ;
1495 $retVal = $this->makeBrokenLinkObj( $nt, $text, $query, $trail, $prefix );
1497 $threshold = $wgUser->getOption('stubthreshold') ;
1498 if ( $threshold > 0 ) {
1499 $dbr =& wfGetDB( DB_SLAVE
);
1500 $s = $dbr->selectRow( 'cur', array( 'LENGTH(cur_text) AS x', 'cur_namespace',
1501 'cur_is_redirect' ), array( 'cur_id' => $aid ), $fname ) ;
1502 if ( $s !== false ) {
1504 if ( $s->cur_is_redirect
OR $s->cur_namespace
!= 0 ) {
1505 $size = $threshold*2 ; # Really big
1507 $dbr->freeResult( $res );
1509 $size = $threshold*2 ; # Really big
1514 if ( $size < $threshold ) {
1515 $retVal = $this->makeStubLinkObj( $nt, $text, $query, $trail, $prefix );
1517 $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
1525 # Pass a title object, not a title string
1526 function makeKnownLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' , $aprops = '' ) {
1527 global $wgOut, $wgTitle, $wgInputEncoding;
1529 $fname = 'Skin::makeKnownLinkObj';
1530 wfProfileIn( $fname );
1532 if ( !is_object( $nt ) ) {
1535 $link = $nt->getPrefixedURL();
1536 # if ( '' != $section && substr($section,0,1) != "#" ) {
1539 if ( '' == $link ) {
1541 if ( '' == $text ) {
1542 $text = htmlspecialchars( $nt->getFragment() );
1545 $u = $nt->escapeLocalURL( $query );
1547 if ( '' != $nt->getFragment() ) {
1548 $anchor = urlencode( do_html_entity_decode( str_replace(' ', '_', $nt->getFragment()), ENT_COMPAT
, $wgInputEncoding ) );
1549 $replacearray = array(
1553 $u .= '#' . str_replace(array_keys($replacearray),array_values($replacearray),$anchor);
1555 if ( '' == $text ) {
1556 $text = htmlspecialchars( $nt->getPrefixedText() );
1558 $style = $this->getInternalLinkAttributesObj( $nt, $text );
1561 if ( '' != $trail ) {
1562 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1567 $r = "<a href=\"{$u}\"{$style}{$aprops}>{$prefix}{$text}{$inside}</a>{$trail}";
1568 wfProfileOut( $fname );
1572 # Pass a title object, not a title string
1573 function makeBrokenLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' ) {
1574 global $wgOut, $wgUser;
1578 return "<!-- ERROR -->{$prefix}{$text}{$trail}";
1580 $fname = 'Skin::makeBrokenLinkObj';
1581 wfProfileIn( $fname );
1583 if ( '' == $query ) {
1586 $q = 'action=edit&'.$query;
1588 $u = $nt->escapeLocalURL( $q );
1590 if ( '' == $text ) {
1591 $text = htmlspecialchars( $nt->getPrefixedText() );
1593 $style = $this->getInternalLinkAttributesObj( $nt, $text, "yes" );
1596 if ( '' != $trail ) {
1597 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1602 if ( $wgUser->getOption( 'highlightbroken' ) ) {
1603 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1605 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>?</a>{$trail}";
1608 wfProfileOut( $fname );
1612 # Pass a title object, not a title string
1613 function makeStubLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' ) {
1614 global $wgOut, $wgUser;
1616 $link = $nt->getPrefixedURL();
1618 $u = $nt->escapeLocalURL( $query );
1620 if ( '' == $text ) {
1621 $text = htmlspecialchars( $nt->getPrefixedText() );
1623 $style = $this->getInternalLinkAttributesObj( $nt, $text, 'stub' );
1626 if ( '' != $trail ) {
1627 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1632 if ( $wgUser->getOption( 'highlightbroken' ) ) {
1633 $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
1635 $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>!</a>{$trail}";
1640 function makeSelfLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' ) {
1641 $u = $nt->escapeLocalURL( $query );
1642 if ( '' == $text ) {
1643 $text = htmlspecialchars( $nt->getPrefixedText() );
1646 if ( '' != $trail ) {
1647 if ( preg_match( $this->linktrail
, $trail, $m ) ) {
1652 return "<strong>{$prefix}{$text}{$inside}</strong>{$trail}";
1655 /* these are used extensively in SkinPHPTal, but also some other places */
1656 /*static*/ function makeSpecialUrl( $name, $urlaction='' ) {
1657 $title = Title
::makeTitle( NS_SPECIAL
, $name );
1658 $this->checkTitle($title, $name);
1659 return $title->getLocalURL( $urlaction );
1661 /*static*/ function makeTalkUrl ( $name, $urlaction='' ) {
1662 $title = Title
::newFromText( $name );
1663 $title = $title->getTalkPage();
1664 $this->checkTitle($title, $name);
1665 return $title->getLocalURL( $urlaction );
1667 /*static*/ function makeArticleUrl ( $name, $urlaction='' ) {
1668 $title = Title
::newFromText( $name );
1669 $title= $title->getSubjectPage();
1670 $this->checkTitle($title, $name);
1671 return $title->getLocalURL( $urlaction );
1673 /*static*/ function makeI18nUrl ( $name, $urlaction='' ) {
1674 $title = Title
::newFromText( wfMsg($name) );
1675 $this->checkTitle($title, $name);
1676 return $title->getLocalURL( $urlaction );
1678 /*static*/ function makeUrl ( $name, $urlaction='' ) {
1679 $title = Title
::newFromText( $name );
1680 $this->checkTitle($title, $name);
1681 return $title->getLocalURL( $urlaction );
1683 # this can be passed the NS number as defined in Language.php
1684 /*static*/ function makeNSUrl( $name, $urlaction='', $namespace=0 ) {
1685 $title = Title
::makeTitleSafe( $namespace, $name );
1686 $this->checkTitle($title, $name);
1687 return $title->getLocalURL( $urlaction );
1690 /* these return an array with the 'href' and boolean 'exists' */
1691 /*static*/ function makeUrlDetails ( $name, $urlaction='' ) {
1692 $title = Title
::newFromText( $name );
1693 $this->checkTitle($title, $name);
1695 'href' => $title->getLocalURL( $urlaction ),
1696 'exists' => $title->getArticleID() != 0?
true:false
1699 /*static*/ function makeTalkUrlDetails ( $name, $urlaction='' ) {
1700 $title = Title
::newFromText( $name );
1701 $title = $title->getTalkPage();
1702 $this->checkTitle($title, $name);
1704 'href' => $title->getLocalURL( $urlaction ),
1705 'exists' => $title->getArticleID() != 0?
true:false
1708 /*static*/ function makeArticleUrlDetails ( $name, $urlaction='' ) {
1709 $title = Title
::newFromText( $name );
1710 $title= $title->getSubjectPage();
1711 $this->checkTitle($title, $name);
1713 'href' => $title->getLocalURL( $urlaction ),
1714 'exists' => $title->getArticleID() != 0?
true:false
1717 /*static*/ function makeI18nUrlDetails ( $name, $urlaction='' ) {
1718 $title = Title
::newFromText( wfMsg($name) );
1719 $this->checkTitle($title, $name);
1721 'href' => $title->getLocalURL( $urlaction ),
1722 'exists' => $title->getArticleID() != 0?
true:false
1726 # make sure we have some title to operate on
1727 /*static*/ function checkTitle ( &$title, &$name ) {
1728 if(!is_object($title)) {
1729 $title = Title
::newFromText( $name );
1730 if(!is_object($title)) {
1731 $title = Title
::newFromText( '--error: link target missing--' );
1736 function fnamePart( $url ) {
1737 $basename = strrchr( $url, '/' );
1738 if ( false === $basename ) {
1741 $basename = substr( $basename, 1 );
1743 return htmlspecialchars( $basename );
1746 function makeImage( $url, $alt = '' ) {
1750 $alt = $this->fnamePart( $url );
1752 $s = '<img src="'.$url.'" alt="'.$alt.'" />';
1756 function makeImageLink( $name, $url, $alt = '' ) {
1757 $nt = Title
::makeTitleSafe( NS_IMAGE
, $name );
1758 return $this->makeImageLinkObj( $nt, $alt );
1761 function makeImageLinkObj( $nt, $alt = '' ) {
1762 global $wgLang, $wgUseImageResize;
1763 $img = Image
::newFromTitle( $nt );
1764 $url = $img->getURL();
1767 $prefix = $postfix = '';
1769 if ( $wgUseImageResize ) {
1770 # Check if the alt text is of the form "options|alt text"
1772 # * thumbnail make a thumbnail with enlarge-icon and caption, alignment depends on lang
1773 # * left no resizing, just left align. label is used for alt= only
1774 # * right same, but right aligned
1775 # * none same, but not aligned
1776 # * ___px scale to ___ pixels width, no aligning. e.g. use in taxobox
1777 # * center center the image
1778 # * framed Keep original image size, no magnify-button.
1780 $part = explode( '|', $alt);
1782 $mwThumb =& MagicWord
::get( MAG_IMG_THUMBNAIL
);
1783 $mwLeft =& MagicWord
::get( MAG_IMG_LEFT
);
1784 $mwRight =& MagicWord
::get( MAG_IMG_RIGHT
);
1785 $mwNone =& MagicWord
::get( MAG_IMG_NONE
);
1786 $mwWidth =& MagicWord
::get( MAG_IMG_WIDTH
);
1787 $mwCenter =& MagicWord
::get( MAG_IMG_CENTER
);
1788 $mwFramed =& MagicWord
::get( MAG_IMG_FRAMED
);
1789 $alt = $part[count($part)-1];
1791 $height = $framed = $thumb = false;
1792 $manual_thumb = "" ;
1794 foreach( $part as $key => $val ) {
1795 $val_parts = explode ( "=" , $val , 2 ) ;
1796 $left_part = array_shift ( $val_parts ) ;
1797 if ( ! is_null( $mwThumb->matchVariableStartToEnd($val) ) ) {
1799 } elseif ( count ( $val_parts ) == 1 && ! is_null( $mwThumb->matchVariableStartToEnd($left_part) ) ) {
1800 # use manually specified thumbnail
1802 $manual_thumb = array_shift ( $val_parts ) ;
1803 } elseif ( ! is_null( $mwRight->matchVariableStartToEnd($val) ) ) {
1804 # remember to set an alignment, don't render immediately
1806 } elseif ( ! is_null( $mwLeft->matchVariableStartToEnd($val) ) ) {
1807 # remember to set an alignment, don't render immediately
1809 } elseif ( ! is_null( $mwCenter->matchVariableStartToEnd($val) ) ) {
1810 # remember to set an alignment, don't render immediately
1812 } elseif ( ! is_null( $mwNone->matchVariableStartToEnd($val) ) ) {
1813 # remember to set an alignment, don't render immediately
1815 } elseif ( ! is_null( $match = $mwWidth->matchVariableStartToEnd($val) ) ) {
1816 # $match is the image width in pixels
1817 if ( preg_match( '/^([0-9]*)x([0-9]*)$/', $match, $m ) ) {
1818 $width = intval( $m[1] );
1819 $height = intval( $m[2] );
1821 $width = intval($match);
1823 } elseif ( ! is_null( $mwFramed->matchVariableStartToEnd($val) ) ) {
1827 if ( 'center' == $align )
1829 $prefix = '<span style="text-align: center">';
1830 $postfix = '</span>';
1834 if ( $thumb ||
$framed ) {
1836 # Create a thumbnail. Alignment depends on language
1837 # writing direction, # right aligned for left-to-right-
1838 # languages ("Western languages"), left-aligned
1839 # for right-to-left-languages ("Semitic languages")
1841 # If thumbnail width has not been provided, it is set
1842 # here to 180 pixels
1843 if ( $align == '' ) {
1844 $align = $wgLang->isRTL() ?
'left' : 'right';
1846 if ( ! isset($width) ) {
1849 return $prefix.$this->makeThumbLinkObj( $img, $alt, $align, $width, $height, $framed, $manual_thumb ).$postfix;
1851 } elseif ( isset($width) ) {
1853 # Create a resized image, without the additional thumbnail
1856 if ( ( ! $height === false )
1857 && ( $img->getHeight() * $width / $img->getWidth() > $height ) ) {
1858 print "height=$height<br>\nimg->getHeight() = ".$img->getHeight()."<br>\n";
1859 print 'rescaling by factor '. $height / $img->getHeight() . "<br>\n";
1860 $width = $img->getWidth() * $height / $img->getHeight();
1862 if ( '' == $manual_thumb ) $url = $img->createThumb( $width );
1864 } # endif $wgUseImageResize
1866 if ( empty( $alt ) ) {
1867 $alt = preg_replace( '/\.(.+?)^/', '', $img->getName() );
1869 $alt = htmlspecialchars( $alt );
1871 $u = $nt->escapeLocalURL();
1874 $s = wfMsg( 'missingimage', $img->getName() );
1875 $s .= "<br>{$alt}<br>{$url}<br>\n";
1877 $s = '<a href="'.$u.'" class="image" title="'.$alt.'">' .
1878 '<img src="'.$url.'" alt="'.$alt.'" /></a>';
1880 if ( '' != $align ) {
1881 $s = "<div class=\"float{$align}\"><span>{$s}</span></div>";
1883 return str_replace("\n", ' ',$prefix.$s.$postfix);
1886 # Make HTML for a thumbnail including image, border and caption
1887 # $img is an Image object
1888 function makeThumbLinkObj( $img, $label = '', $align = 'right', $boxwidth = 180, $boxheight=false, $framed=false , $manual_thumb = "" ) {
1889 global $wgStylePath, $wgLang;
1890 # $image = Title::makeTitleSafe( NS_IMAGE, $name );
1891 $url = $img->getURL();
1893 #$label = htmlspecialchars( $label );
1894 $alt = preg_replace( '/<[^>]*>/', '', $label);
1895 $alt = htmlspecialchars( $alt );
1897 $width = $height = 0;
1898 if ( $img->exists() )
1900 $width = $img->getWidth();
1901 $height = $img->getHeight();
1903 if ( 0 == $width ||
0 == $height )
1905 $width = $height = 200;
1907 if ( $boxwidth == 0 )
1913 // Use image dimensions, don't scale
1915 $oboxwidth = $boxwidth +
2;
1916 $boxheight = $height;
1919 $h = intval( $height/($width/$boxwidth) );
1920 $oboxwidth = $boxwidth +
2;
1921 if ( ( ! $boxheight === false ) && ( $h > $boxheight ) )
1923 $boxwidth *= $boxheight/$h;
1927 if ( '' == $manual_thumb ) $thumbUrl = $img->createThumb( $boxwidth );
1930 if ( $manual_thumb != '' ) # Use manually specified thumbnail
1932 $manual_title = Title
::makeTitleSafe( NS_IMAGE
, $manual_thumb ); #new Title ( $manual_thumb ) ;
1933 $manual_img = Image
::newFromTitle( $manual_title );
1934 $thumbUrl = $manual_img->getURL();
1935 if ( $manual_img->exists() )
1937 $width = $manual_img->getWidth();
1938 $height = $manual_img->getHeight();
1939 $boxwidth = $width ;
1940 $boxheight = $height ;
1941 $oboxwidth = $boxwidth +
2 ;
1945 $u = $img->getEscapeLocalURL();
1947 $more = htmlspecialchars( wfMsg( 'thumbnail-more' ) );
1948 $magnifyalign = $wgLang->isRTL() ?
'left' : 'right';
1949 $textalign = $wgLang->isRTL() ?
' style="text-align:right"' : '';
1951 $s = "<div class=\"thumb t{$align}\"><div style=\"width:{$oboxwidth}px;\">";
1952 if ( $thumbUrl == '' ) {
1953 $s .= wfMsg( 'missingimage', $img->getName() );
1956 $s .= '<a href="'.$u.'" class="internal" title="'.$alt.'">'.
1957 '<img src="'.$thumbUrl.'" alt="'.$alt.'" ' .
1958 'width="'.$boxwidth.'" height="'.$boxheight.'" /></a>';
1962 $zoomicon = '<div class="magnify" style="float:'.$magnifyalign.'">'.
1963 '<a href="'.$u.'" class="internal" title="'.$more.'">'.
1964 '<img src="'.$wgStylePath.'/images/magnify-clip.png" ' .
1965 'width="15" height="11" alt="'.$more.'" /></a></div>';
1968 $s .= ' <div class="thumbcaption" '.$textalign.'>'.$zoomicon.$label."</div></div></div>";
1969 return str_replace("\n", ' ', $s);
1972 function makeMediaLink( $name, $url, $alt = '' ) {
1973 $nt = Title
::makeTitleSafe( Namespace::getMedia(), $name );
1974 return $this->makeMediaLinkObj( $nt, $alt );
1977 function makeMediaLinkObj( $nt, $alt = '' ) {
1978 if ( ! isset( $nt ) )
1980 ### HOTFIX. Instead of breaking, return empty string.
1983 $name = $nt->getDBKey();
1984 $url = Image
::wfImageUrl( $name );
1985 if ( empty( $alt ) ) {
1986 $alt = preg_replace( '/\.(.+?)^/', '', $name );
1989 $u = htmlspecialchars( $url );
1990 $s = "<a href=\"{$u}\" class='internal' title=\"{$alt}\">{$alt}</a>";
1995 function specialLink( $name, $key = '' ) {
1998 if ( '' == $key ) { $key = strtolower( $name ); }
1999 $pn = $wgLang->ucfirst( $name );
2000 return $this->makeKnownLink( $wgLang->specialPage( $pn ),
2004 function makeExternalLink( $url, $text, $escape = true ) {
2005 $style = $this->getExternalLinkAttributes( $url, $text );
2006 $url = htmlspecialchars( $url );
2008 $text = htmlspecialchars( $text );
2010 return '<a href="'.$url.'"'.$style.'>'.$text.'</a>';
2013 # Called by history lists and recent changes
2016 # Returns text for the start of the tabular part of RC
2017 function beginRecentChangesList() {
2018 $this->rc_cache
= array() ;
2019 $this->rcMoveIndex
= 0;
2020 $this->rcCacheIndex
= 0 ;
2021 $this->lastdate
= '';
2022 $this->rclistOpen
= false;
2026 function beginImageHistoryList() {
2027 $s = "\n<h2>" . wfMsg( 'imghistory' ) . "</h2>\n" .
2028 "<p>" . wfMsg( 'imghistlegend' ) . "</p>\n".'<ul class="special">';
2032 # Returns text for the end of RC
2033 # If enhanced RC is in use, returns pretty much all the text
2034 function endRecentChangesList() {
2035 $s = $this->recentChangesBlock() ;
2036 if( $this->rclistOpen
) {
2042 # Enhanced RC ungrouped line
2043 function recentChangesBlockLine ( $rcObj ) {
2044 global $wgStylePath, $wgLang ;
2046 # Get rc_xxxx variables
2047 extract( $rcObj->mAttribs
) ;
2048 $curIdEq = 'curid='.$rc_cur_id;
2053 $r .= '<img src="'.$wgStylePath.'/images/Arr_.png" width="12" height="12" border="0" />' ;
2056 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2057 $r .= ' ';
2059 # M & N (minor & new)
2060 $M = wfMsg( 'minoreditletter' );
2061 $N = wfMsg( 'newpageletter' );
2063 if ( $rc_type == RC_NEW
) {
2076 $r .= ' '.$rcObj->timestamp
.' ' ;
2080 $link = $rcObj->link
;
2081 if ( $rcObj->watched
) $link = '<strong>'.$link.'</strong>' ;
2086 $r .= $rcObj->difflink
;
2090 $r .= $this->makeKnownLinkObj( $rcObj->getTitle(), wfMsg( 'hist' ), $curIdEq.'&action=history' );
2093 $r .= ') . . '.$rcObj->userlink
;
2094 $r .= $rcObj->usertalklink
;
2097 if ( $rc_comment != '' && $rc_type != RC_MOVE
&& $rc_type != RC_MOVE_OVER_REDIRECT
) {
2098 $rc_comment=$this->formatComment($rc_comment, $rcObj->getTitle());
2099 $r .= $wgLang->emphasize( ' ('.$rc_comment.')' );
2107 function recentChangesBlockGroup ( $block ) {
2108 global $wgStylePath, $wgLang ;
2111 $M = wfMsg( 'minoreditletter' );
2112 $N = wfMsg( 'newpageletter' );
2114 # Collate list of users
2116 $userlinks = array () ;
2117 foreach ( $block AS $rcObj ) {
2118 $oldid = $rcObj->mAttribs
['rc_last_oldid'];
2119 if ( $rcObj->mAttribs
['rc_new'] ) $isnew = true ;
2120 $u = $rcObj->userlink
;
2121 if ( !isset ( $userlinks[$u] ) ) $userlinks[$u] = 0 ;
2125 # Sort the list and convert to text
2126 krsort ( $userlinks ) ;
2127 asort ( $userlinks ) ;
2129 foreach ( $userlinks as $userlink => $count) {
2131 if ( $count > 1 ) $text .= " ({$count}×)" ;
2132 array_push ( $users , $text ) ;
2134 $users = ' <font size="-1">['.implode('; ',$users).']</font>' ;
2137 $rci = 'RCI'.$this->rcCacheIndex
;
2138 $rcl = 'RCL'.$this->rcCacheIndex
;
2139 $rcm = 'RCM'.$this->rcCacheIndex
;
2140 $toggleLink = "javascript:toggleVisibility('$rci','$rcm','$rcl')" ;
2141 $arrowdir = $wgLang->isRTL() ?
'l' : 'r';
2142 $tl = '<span id="'.$rcm.'"><a href="'.$toggleLink.'"><img src="'.$wgStylePath.'/images/Arr_'.$arrowdir.'.png" width="12" height="12" /></a></span>' ;
2143 $tl .= '<span id="'.$rcl.'" style="display:none"><a href="'.$toggleLink.'"><img src="'.$wgStylePath.'/images/Arr_d.png" width="12" height="12" /></a></span>' ;
2149 if ( $isnew ) $r .= $N ;
2150 else $r .= ' ' ;
2151 $r .= ' ' ; # Minor
2154 $r .= ' '.$block[0]->timestamp
.' ' ;
2158 $link = $block[0]->link
;
2159 if ( $block[0]->watched
) $link = '<strong>'.$link.'</strong>' ;
2162 $curIdEq = 'curid=' . $block[0]->mAttribs
['rc_cur_id'];
2163 if ( $block[0]->mAttribs
['rc_type'] != RC_LOG
) {
2165 $r .= ' ('.count($block).' ' ;
2166 if ( $isnew ) $r .= wfMsg('changes');
2167 else $r .= $this->makeKnownLinkObj( $block[0]->getTitle() , wfMsg('changes') ,
2168 $curIdEq.'&diff=0&oldid='.$oldid ) ;
2172 $r .= $this->makeKnownLinkObj( $block[0]->getTitle(), wfMsg( 'history' ), $curIdEq.'&action=history' );
2180 $r .= '<div id="'.$rci.'" style="display:none">' ;
2181 foreach ( $block AS $rcObj ) {
2182 # Get rc_xxxx variables
2183 extract( $rcObj->mAttribs
);
2185 $r .= '<img src="'.$wgStylePath.'/images/Arr_.png" width="12" height="12" />';
2186 $r .= '<tt> ' ;
2187 if ( $rc_new ) $r .= $N ;
2188 else $r .= ' ' ;
2189 if ( $rc_minor ) $r .= $M ;
2190 else $r .= ' ' ;
2194 if ( $rc_last_oldid != 0 ) {
2195 $o = 'oldid='.$rc_last_oldid ;
2197 if ( $rc_type == RC_LOG
) {
2198 $link = $rcObj->timestamp
;
2200 $link = $this->makeKnownLinkObj( $rcObj->getTitle(), $rcObj->timestamp
, "{$curIdEq}&$o" ) ;
2202 $link = '<tt>'.$link.'</tt>' ;
2206 $r .= $rcObj->curlink
;
2208 $r .= $rcObj->lastlink
;
2209 $r .= ') . . '.$rcObj->userlink
;
2210 $r .= $rcObj->usertalklink
;
2211 if ( $rc_comment != '' ) {
2212 $rc_comment=$this->formatComment($rc_comment, $rcObj->getTitle());
2213 $r .= $wgLang->emphasize( ' ('.$rc_comment.')' ) ;
2219 $this->rcCacheIndex++
;
2223 # If enhanced RC is in use, this function takes the previously cached
2224 # RC lines, arranges them, and outputs the HTML
2225 function recentChangesBlock () {
2226 global $wgStylePath ;
2227 if ( count ( $this->rc_cache
) == 0 ) return '' ;
2229 foreach ( $this->rc_cache
AS $secureName => $block ) {
2230 if ( count ( $block ) < 2 ) {
2231 $blockOut .= $this->recentChangesBlockLine ( array_shift ( $block ) ) ;
2233 $blockOut .= $this->recentChangesBlockGroup ( $block ) ;
2237 return '<div>'.$blockOut.'</div>' ;
2240 # Called in a loop over all displayed RC entries
2241 # Either returns the line, or caches it for later use
2242 function recentChangesLine( &$rc, $watched = false ) {
2244 $usenew = $wgUser->getOption( 'usenewrc' );
2246 $line = $this->recentChangesLineNew ( $rc, $watched ) ;
2248 $line = $this->recentChangesLineOld ( $rc, $watched ) ;
2252 function recentChangesLineOld( &$rc, $watched = false ) {
2253 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds, $wgUseRCPatrol, $wgOnlySysopsCanPatrol;
2255 # Extract DB fields into local scope
2256 extract( $rc->mAttribs
);
2257 $curIdEq = 'curid=' . $rc_cur_id;
2259 # Make date header if necessary
2260 $date = $wgLang->date( $rc_timestamp, true);
2262 if ( $date != $this->lastdate
) {
2263 if ( '' != $this->lastdate
) { $s .= "</ul>\n"; }
2264 $s .= "<h4>{$date}</h4>\n<ul class='special'>";
2265 $this->lastdate
= $date;
2266 $this->rclistOpen
= true;
2269 # If this edit has not yet been patrolled, make it stick out
2270 $s .= ( ! $wgUseRCPatrol ||
$rc_patrolled ) ?
'<li> ' : '<li class="not_patrolled"> ';
2272 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2274 $s .= '(' . wfMsg( 'diff' ) . ') (';
2276 $s .= $this->makeKnownLinkObj( $rc->getMovedToTitle(), wfMsg( 'hist' ), 'action=history' ) .
2279 # "[[x]] moved to [[y]]"
2280 $msg = ( $rc_type == RC_MOVE
) ?
'1movedto2' : '1movedto2_redir';
2281 $s .= wfMsg( $msg, $this->makeKnownLinkObj( $rc->getTitle(), '', 'redirect=no' ),
2282 $this->makeKnownLinkObj( $rc->getMovedToTitle(), '' ) );
2283 } elseif( $rc_namespace == NS_SPECIAL
&& preg_match( '!^Log/(.*)$!', $rc_title, $matches ) ) {
2285 $logtype = $matches[1];
2286 $logname = LogPage
::logName( $logtype );
2287 $s .= '(' . $this->makeKnownLinkObj( $rc->getTitle(), $logname ) . ')';
2290 if ( $rc_type == RC_NEW ||
$rc_type == RC_LOG
) {
2291 $diffLink = wfMsg( 'diff' );
2293 if ( $wgUseRCPatrol && $rc_patrolled == 0 && $wgUser->getID() != 0 &&
2294 ( $wgUser->isSysop() ||
!$wgOnlySysopsCanPatrol ) )
2295 $rcidparam = "&rcid={$rc_id}";
2298 $diffLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'diff' ),
2299 "{$curIdEq}&diff={$rc_this_oldid}&oldid={$rc_last_oldid}{$rcidparam}",
2300 '', '', ' tabindex="'.$rc->counter
.'"');
2302 $s .= '('.$diffLink.') (';
2305 $s .= $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'hist' ), $curIdEq.'&action=history' );
2308 # M and N (minor and new)
2309 if ( $rc_minor ) { $s .= ' <span class="minor">'.wfMsg( "minoreditletter" ).'</span>'; }
2310 if ( $rc_type == RC_NEW
) { $s .= '<span class="newpage">'.wfMsg( "newpageletter" ).'</span>'; }
2313 # If it's a new article, there is no diff link, but if it hasn't been
2314 # patrolled yet, we need to give users a way to do so
2315 if ( $wgUseRCPatrol && $rc_type == RC_NEW
&& $rc_patrolled == 0 &&
2316 $wgUser->getID() != 0 && ( $wgUser->isSysop() ||
!$wgOnlySysopsCanPatrol ) )
2317 $articleLink = $this->makeKnownLinkObj( $rc->getTitle(), '', "rcid={$rc_id}" );
2319 $articleLink = $this->makeKnownLinkObj( $rc->getTitle(), '' );
2322 $articleLink = '<strong>'.$articleLink.'</strong>';
2324 $s .= ' '.$articleLink;
2329 $s .= '; ' . $wgLang->time( $rc_timestamp, true, $wgRCSeconds ) . ' . . ';
2331 # User link (or contributions for unregistered users)
2332 if ( 0 == $rc_user ) {
2333 $userLink = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
2334 $rc_user_text, 'target=' . $rc_user_text );
2336 $userLink = $this->makeLink( $wgLang->getNsText( NS_USER
) . ':'.$rc_user_text, $rc_user_text );
2341 $talkname=$wgLang->getNsText(NS_TALK
); # use the shorter name
2342 global $wgDisableAnonTalk;
2343 if( 0 == $rc_user && $wgDisableAnonTalk ) {
2346 $utns=$wgLang->getNsText(NS_USER_TALK
);
2347 $userTalkLink= $this->makeLink($utns . ':'.$rc_user_text, $talkname );
2351 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2352 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2353 'Blockip' ), wfMsg( 'blocklink' ), 'ip='.$rc_user_text );
2357 if($userTalkLink) $userTalkLink .= ' | ';
2358 $userTalkLink .= $blockLink;
2360 if($userTalkLink) $s.=' ('.$userTalkLink.')';
2363 if ( '' != $rc_comment && '*' != $rc_comment && $rc_type != RC_MOVE
&& $rc_type != RC_MOVE_OVER_REDIRECT
) {
2364 $rc_comment=$this->formatComment($rc_comment,$rc->getTitle());
2365 $s .= $wgLang->emphasize(' (' . $rc_comment . ')');
2372 function recentChangesLineNew( &$baseRC, $watched = false ) {
2373 global $wgTitle, $wgLang, $wgUser, $wgRCSeconds;
2375 # Create a specialised object
2376 $rc = RCCacheEntry
::newFromParent( $baseRC ) ;
2378 # Extract fields from DB into the function scope (rc_xxxx variables)
2379 extract( $rc->mAttribs
);
2380 $curIdEq = 'curid=' . $rc_cur_id;
2382 # If it's a new day, add the headline and flush the cache
2383 $date = $wgLang->date( $rc_timestamp, true);
2385 if ( $date != $this->lastdate
) {
2386 # Process current cache
2387 $ret = $this->recentChangesBlock () ;
2388 $this->rc_cache
= array() ;
2389 $ret .= "<h4>{$date}</h4>\n";
2390 $this->lastdate
= $date;
2394 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2395 $msg = ( $rc_type == RC_MOVE
) ?
"1movedto2" : "1movedto2_redir";
2396 $clink = wfMsg( $msg, $this->makeKnownLinkObj( $rc->getTitle(), '', 'redirect=no' ),
2397 $this->makeKnownLinkObj( $rc->getMovedToTitle(), '' ) );
2398 } elseif( $rc_namespace == NS_SPECIAL
&& preg_match( '!^Log/(.*)$!', $rc_title, $matches ) ) {
2400 $logtype = $matches[1];
2401 $logname = LogPage
::logName( $logtype );
2402 $clink = '(' . $this->makeKnownLinkObj( $rc->getTitle(), $logname ) . ')';
2404 $clink = $this->makeKnownLinkObj( $rc->getTitle(), '' ) ;
2407 $time = $wgLang->time( $rc_timestamp, true, $wgRCSeconds );
2408 $rc->watched
= $watched ;
2409 $rc->link
= $clink ;
2410 $rc->timestamp
= $time;
2412 # Make "cur" and "diff" links
2413 if ( ( $rc_type == RC_NEW
&& $rc_this_oldid == 0 ) ||
$rc_type == RC_LOG ||
$rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2414 $curLink = wfMsg( 'cur' );
2415 $diffLink = wfMsg( 'diff' );
2417 $query = $curIdEq.'&diff=0&oldid='.$rc_this_oldid;
2418 $aprops = ' tabindex="'.$baseRC->counter
.'"';
2419 $curLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'cur' ), $query, '' ,'' , $aprops );
2420 $diffLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'diff'), $query, '' ,'' , $aprops );
2424 $titleObj = $rc->getTitle();
2425 if ( $rc_last_oldid == 0 ||
$rc_type == RC_LOG ||
$rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2426 $lastLink = wfMsg( 'last' );
2428 $lastLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'last' ),
2429 $curIdEq.'&diff='.$rc_this_oldid.'&oldid='.$rc_last_oldid );
2432 # Make user link (or user contributions for unregistered users)
2433 if ( $rc_user == 0 ) {
2434 $userLink = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
2435 $rc_user_text, 'target=' . $rc_user_text );
2437 $userLink = $this->makeLink( $wgLang->getNsText(
2438 Namespace::getUser() ) . ':'.$rc_user_text, $rc_user_text );
2441 $rc->userlink
= $userLink;
2442 $rc->lastlink
= $lastLink;
2443 $rc->curlink
= $curLink;
2444 $rc->difflink
= $diffLink;
2446 # Make user talk link
2447 $utns=$wgLang->getNsText(NS_USER_TALK
);
2448 $talkname=$wgLang->getNsText(NS_TALK
); # use the shorter name
2449 $userTalkLink= $this->makeLink($utns . ':'.$rc_user_text, $talkname );
2451 global $wgDisableAnonTalk;
2452 if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
2453 $blockLink = $this->makeKnownLink( $wgLang->specialPage(
2454 'Blockip' ), wfMsg( 'blocklink' ), 'ip='.$rc_user_text );
2455 if( $wgDisableAnonTalk )
2456 $rc->usertalklink
= ' ('.$blockLink.')';
2458 $rc->usertalklink
= ' ('.$userTalkLink.' | '.$blockLink.')';
2460 if( $wgDisableAnonTalk && ($rc_user == 0) )
2461 $rc->usertalklink
= '';
2463 $rc->usertalklink
= ' ('.$userTalkLink.')';
2466 # Put accumulated information into the cache, for later display
2467 # Page moves go on their own line
2468 $title = $rc->getTitle();
2469 $secureName = $title->getPrefixedDBkey();
2470 if ( $rc_type == RC_MOVE ||
$rc_type == RC_MOVE_OVER_REDIRECT
) {
2471 # Use an @ character to prevent collision with page names
2472 $this->rc_cache
['@@' . ($this->rcMoveIndex++
)] = array($rc);
2474 if ( !isset ( $this->rc_cache
[$secureName] ) ) $this->rc_cache
[$secureName] = array() ;
2475 array_push ( $this->rc_cache
[$secureName] , $rc ) ;
2480 function endImageHistoryList() {
2485 /* This function is called by all recent changes variants, by the page history,
2486 and by the user contributions list. It is responsible for formatting edit
2487 comments. It escapes any HTML in the comment, but adds some CSS to format
2488 auto-generated comments (from section editing) and formats [[wikilinks]].
2490 The &$title parameter must be a title OBJECT. It is used to generate a
2491 direct link to the section in the autocomment.
2492 Main author: Erik Moeller (moeller@scireview.de)
2494 # Note: there's not always a title to pass to this function.
2495 # Since you can't set a default parameter for a reference, I've turned it
2496 # temporarily to a value pass. Should be adjusted further. --brion
2497 function formatComment($comment, $title = NULL) {
2499 $comment = htmlspecialchars( $comment );
2501 # The pattern for autogen comments is / * foo * /, which makes for
2503 # We look for all comments, match any text before and after the comment,
2504 # add a separator where needed and format the comment itself with CSS
2505 while (preg_match('/(.*)\/\*\s*(.*?)\s*\*\/(.*)/', $comment,$match)) {
2513 # This is hackish but should work in most cases.
2514 $section=str_replace('[[','',$section);
2515 $section=str_replace(']]','',$section);
2516 $title->mFragment
=$section;
2517 $link=$this->makeKnownLinkObj($title,wfMsg('sectionlink'));
2521 if($pre) { $auto = $sep.' '.$auto; }
2522 if($post) { $auto .= ' '.$sep; }
2523 $auto='<span class="autocomment">'.$auto.'</span>';
2524 $comment=$pre.$auto.$post;
2527 # format regular and media links - all other wiki formatting
2529 $medians = $wgLang->getNsText(Namespace::getMedia()).':';
2530 while(preg_match('/\[\[(.*?)(\|(.*?))*\]\](.*)$/',$comment,$match)) {
2531 # Handle link renaming [[foo|text]] will show link as "text"
2532 if( "" != $match[3] ) {
2537 if( preg_match( '/^' . $medians . '(.*)$/i', $match[1], $submatch ) ) {
2538 # Media link; trail not supported.
2539 $linkRegexp = '/\[\[(.*?)\]\]/';
2540 $thelink = $this->makeMediaLink( $submatch[1], "", $text );
2542 # Other kind of link
2543 if( preg_match( wfMsg( "linktrail" ), $match[4], $submatch ) ) {
2544 $trail = $submatch[1];
2548 $linkRegexp = '/\[\[(.*?)\]\]' . preg_quote( $trail, '/' ) . '/';
2549 if ($match[1][0] == ':')
2550 $match[1] = substr($match[1], 1);
2551 $thelink = $this->makeLink( $match[1], $text, "", $trail );
2553 $comment = preg_replace( $linkRegexp, $thelink, $comment, 1 );
2558 function imageHistoryLine( $iscur, $timestamp, $img, $user, $usertext, $size, $description ) {
2559 global $wgUser, $wgLang, $wgTitle;
2561 $datetime = $wgLang->timeanddate( $timestamp, true );
2562 $del = wfMsg( 'deleteimg' );
2563 $delall = wfMsg( 'deleteimgcompletely' );
2564 $cur = wfMsg( 'cur' );
2567 $url = Image
::wfImageUrl( $img );
2569 if ( $wgUser->isSysop() ) {
2570 $link = $wgTitle->escapeLocalURL( 'image=' . $wgTitle->getPartialURL() .
2572 $style = $this->getInternalLinkAttributes( $link, $delall );
2574 $dlink = '<a href="'.$link.'"'.$style.'>'.$delall.'</a>';
2579 $url = htmlspecialchars( wfImageArchiveUrl( $img ) );
2580 if( $wgUser->getID() != 0 && $wgTitle->userCanEdit() ) {
2581 $rlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2582 wfMsg( 'revertimg' ), 'action=revert&oldimage=' .
2583 urlencode( $img ) );
2584 $dlink = $this->makeKnownLink( $wgTitle->getPrefixedText(),
2585 $del, 'action=delete&oldimage=' . urlencode( $img ) );
2587 # Having live active links for non-logged in users
2588 # means that bots and spiders crawling our site can
2589 # inadvertently change content. Baaaad idea.
2590 $rlink = wfMsg( 'revertimg' );
2595 $userlink = $usertext;
2597 $userlink = $this->makeLink( $wgLang->getNsText( Namespace::getUser() ) .
2598 ':'.$usertext, $usertext );
2600 $nbytes = wfMsg( 'nbytes', $size );
2601 $style = $this->getInternalLinkAttributes( $url, $datetime );
2603 $s = "<li> ({$dlink}) ({$rlink}) <a href=\"{$url}\"{$style}>{$datetime}</a>"
2604 . " . . {$userlink} ({$nbytes})";
2606 if ( '' != $description && '*' != $description ) {
2607 $sk=$wgUser->getSkin();
2608 $s .= $wgLang->emphasize(' (' . $sk->formatComment($description,$wgTitle) . ')');
2614 function tocIndent($level) {
2615 return str_repeat( '<div class="tocindent">'."\n", $level>0 ?
$level : 0 );
2618 function tocUnindent($level) {
2619 return str_repeat( "</div>\n", $level>0 ?
$level : 0 );
2622 # parameter level defines if we are on an indentation level
2623 function tocLine( $anchor, $tocline, $level ) {
2624 $link = '<a href="#'.$anchor.'">'.$tocline.'</a><br />';
2628 return '<div class="tocline">'.$link."</div>\n";
2633 function tocTable($toc) {
2634 # note to CSS fanatics: putting this in a div does not work -- div won't auto-expand
2635 # try min-width & co when somebody gets a chance
2636 $hideline = ' <script type="text/javascript">showTocToggle("' . addslashes( wfMsg('showtoc') ) . '","' . addslashes( wfMsg('hidetoc') ) . '")</script>';
2638 '<table border="0" id="toc"><tr id="toctitle"><td align="center">'."\n".
2639 '<b>'.wfMsg('toc').'</b>' .
2641 '</td></tr><tr id="tocinside"><td>'."\n".
2642 $toc."</td></tr></table>\n";
2645 # These two do not check for permissions: check $wgTitle->userCanEdit before calling them
2646 function editSectionScript( $section, $head ) {
2647 global $wgTitle, $wgRequest;
2648 if( $wgRequest->getInt( 'oldid' ) && ( $wgRequest->getVal( 'diff' ) != '0' ) ) {
2651 $url = $wgTitle->escapeLocalURL( 'action=edit§ion='.$section );
2652 return '<span oncontextmenu=\'document.location="'.$url.'";return false;\'>'.$head.'</span>';
2655 function editSectionLink( $section ) {
2657 global $wgTitle, $wgUser, $wgLang;
2659 if( $wgRequest->getInt( 'oldid' ) && ( $wgRequest->getVal( 'diff' ) != '0' ) ) {
2660 # Section edit links would be out of sync on an old page.
2661 # But, if we're diffing to the current page, they'll be
2666 $editurl = '§ion='.$section;
2667 $url = $this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg('editsection'),'action=edit'.$editurl);
2669 if( $wgLang->isRTL() ) {
2671 $nearside = 'right';
2676 return "<div class=\"editsection\" style=\"float:$farside;margin-$nearside:5px;\">[".$url."]</div>";
2680 // This function is called by EditPage.php and shows a bulletin board style
2681 // toolbar for common editing functions. It can be disabled in the user preferences.
2682 // The necsesary JavaScript code can be found in style/wikibits.js.
2683 function getEditToolbar() {
2684 global $wgStylePath, $wgLang, $wgMimeType;
2686 // toolarray an array of arrays which each include the filename of
2687 // the button image (without path), the opening tag, the closing tag,
2688 // and optionally a sample text that is inserted between the two when no
2689 // selection is highlighted.
2690 // The tip text is shown when the user moves the mouse over the button.
2692 // Already here are accesskeys (key), which are not used yet until someone
2693 // can figure out a way to make them work in IE. However, we should make
2694 // sure these keys are not defined on the edit page.
2696 array( 'image'=>'button_bold.png',
2698 'close' => "\'\'\'",
2699 'sample'=> wfMsg('bold_sample'),
2700 'tip' => wfMsg('bold_tip'),
2703 array( 'image'=>'button_italic.png',
2706 'sample'=> wfMsg('italic_sample'),
2707 'tip' => wfMsg('italic_tip'),
2710 array( 'image'=>'button_link.png',
2713 'sample'=> wfMsg('link_sample'),
2714 'tip' => wfMsg('link_tip'),
2717 array( 'image'=>'button_extlink.png',
2720 'sample'=> wfMsg('extlink_sample'),
2721 'tip' => wfMsg('extlink_tip'),
2724 array( 'image'=>'button_headline.png',
2726 'close' => " ==\\n",
2727 'sample'=> wfMsg('headline_sample'),
2728 'tip' => wfMsg('headline_tip'),
2731 array( 'image'=>'button_image.png',
2732 'open' => '[['.$wgLang->getNsText(NS_IMAGE
).":",
2734 'sample'=> wfMsg('image_sample'),
2735 'tip' => wfMsg('image_tip'),
2738 array( 'image' => 'button_media.png',
2739 'open' => '[['.$wgLang->getNsText(NS_MEDIA
).':',
2741 'sample'=> wfMsg('media_sample'),
2742 'tip' => wfMsg('media_tip'),
2745 array( 'image' => 'button_math.png',
2746 'open' => "\\<math\\>",
2747 'close' => "\\</math\\>",
2748 'sample'=> wfMsg('math_sample'),
2749 'tip' => wfMsg('math_tip'),
2752 array( 'image' => 'button_nowiki.png',
2753 'open' => "\\<nowiki\\>",
2754 'close' => "\\</nowiki\\>",
2755 'sample'=> wfMsg('nowiki_sample'),
2756 'tip' => wfMsg('nowiki_tip'),
2759 array( 'image' => 'button_sig.png',
2763 'tip' => wfMsg('sig_tip'),
2766 array( 'image' => 'button_hr.png',
2767 'open' => "\\n----\\n",
2770 'tip' => wfMsg('hr_tip'),
2774 $toolbar ="<script type='text/javascript'>\n/*<![CDATA[*/\n";
2776 $toolbar.="document.writeln(\"<div id='toolbar'>\");\n";
2777 foreach($toolarray as $tool) {
2779 $image=$wgStylePath.'/images/'.$tool['image'];
2780 $open=$tool['open'];
2781 $close=$tool['close'];
2782 $sample = addslashes( $tool['sample'] );
2784 // Note that we use the tip both for the ALT tag and the TITLE tag of the image.
2785 // Older browsers show a "speedtip" type message only for ALT.
2786 // Ideally these should be different, realistically they
2787 // probably don't need to be.
2788 $tip = addslashes( $tool['tip'] );
2790 #$key = $tool["key"];
2792 $toolbar.="addButton('$image','$tip','$open','$close','$sample');\n";
2795 $toolbar.="addInfobox('" . addslashes( wfMsg( "infobox" ) ) . "','" . addslashes(wfMsg("infobox_alert")) . "');\n";
2796 $toolbar.="document.writeln(\"</div>\");\n";
2798 $toolbar.="/*]]>*/\n</script>";
2802 /* public */ function suppressUrlExpansion() {