X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2FSkin.php;h=f000fbfffe82dd7dc28bbc8de6232f360e1cbc2c;hb=4074968ddfebc6dee917b95114a428673b6e7bac;hp=866493f03d26e13f1a80fac08c94513bc164d6ec;hpb=22fabc32e58409542f2d13efc3b65796c4419389;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/Skin.php b/includes/Skin.php index 866493f03d..f000fbfffe 100644 --- a/includes/Skin.php +++ b/includes/Skin.php @@ -3,8 +3,9 @@ * @defgroup Skins Skins */ -if ( ! defined( 'MEDIAWIKI' ) ) +if ( !defined( 'MEDIAWIKI' ) ) { die( 1 ); +} /** * The main skin class that provide methods and properties for all other skins. @@ -24,16 +25,17 @@ class Skin extends Linker { /**#@-*/ protected $mRevisionId; // The revision ID we're looking at, null if not applicable. protected $skinname = 'standard'; - // @fixme Should be protected :-\ + // @todo Fixme: should be protected :-\ var $mTitle = null; /** Constructor, call parent constructor */ - function Skin() { parent::__construct(); } + function __construct() { + parent::__construct(); + } /** * Fetch the set of available skins. * @return array of strings - * @static */ static function getSkinNames() { global $wgValidSkinNames; @@ -53,7 +55,7 @@ class Skin extends Linker { $matches = array(); if( preg_match( '/^([^.]*)\.php$/', $file, $matches ) ) { $aSkin = $matches[1]; - $wgValidSkinNames[strtolower($aSkin)] = $aSkin; + $wgValidSkinNames[strtolower( $aSkin )] = $aSkin; } } $skinDir->close(); @@ -62,7 +64,7 @@ class Skin extends Linker { } return $wgValidSkinNames; } - + /** * Fetch the list of usable skins in regards to $wgSkipSkins. * Useful for Special:Preferences and other places where you @@ -82,9 +84,8 @@ class Skin extends Linker { * Normalize a skin preference value to a form that can be loaded. * If a skin can't be found, it will fall back to the configured * default (or the old 'Classic' skin if that's broken). - * @param string $key + * @param $key String: 'monobook', 'standard', etc. * @return string - * @static */ static function normalizeKey( $key ) { global $wgDefaultSkin; @@ -105,24 +106,26 @@ class Skin extends Linker { $fallback = array( 0 => $wgDefaultSkin, 1 => 'nostalgia', - 2 => 'cologneblue' ); + 2 => 'cologneblue' + ); - if( isset( $fallback[$key] ) ){ + if( isset( $fallback[$key] ) ) { $key = $fallback[$key]; } if( isset( $skinNames[$key] ) ) { return $key; + } else if( isset( $skinNames[$wgDefaultSkin] ) ) { + return $wgDefaultSkin; } else { - return 'monobook'; + return 'vector'; } } /** * Factory method for loading a skin of a given type - * @param string $key 'monobook', 'standard', etc + * @param $key String: 'monobook', 'standard', etc. * @return Skin - * @static */ static function &newFromKey( $key ) { global $wgStyleDirectory; @@ -131,13 +134,15 @@ class Skin extends Linker { $skinNames = Skin::getSkinNames(); $skinName = $skinNames[$key]; - $className = 'Skin'.ucfirst($key); + $className = 'Skin' . ucfirst( $key ); # Grab the skin class and initialise it. if ( !class_exists( $className ) ) { // Preload base classes to work around APC/PHP5 bug $deps = "{$wgStyleDirectory}/{$skinName}.deps.php"; - if( file_exists( $deps ) ) include_once( $deps ); + if( file_exists( $deps ) ) { + include_once( $deps ); + } require_once( "{$wgStyleDirectory}/{$skinName}.php" ); # Check if we got if not failback to default skin @@ -147,8 +152,8 @@ class Skin extends Linker { # except by SQL manipulation if a previously valid skin name # is no longer valid. wfDebug( "Skin class does not exist: $className\n" ); - $className = 'SkinMonobook'; - require_once( "{$wgStyleDirectory}/MonoBook.php" ); + $className = 'SkinVector'; + require_once( "{$wgStyleDirectory}/Vector.php" ); } } $skin = new $className; @@ -168,7 +173,9 @@ class Skin extends Linker { function qbSetting() { global $wgOut, $wgUser; - if ( $wgOut->isQuickbarSuppressed() ) { return 0; } + if ( $wgOut->isQuickbarSuppressed() ) { + return 0; + } $q = $wgUser->getOption( 'quickbar', 0 ); return $q; } @@ -180,7 +187,7 @@ class Skin extends Linker { # Generally the order of the favicon and apple-touch-icon links # should not matter, but Konqueror (3.5.9 at least) incorrectly - # uses whichever one appears later in the HTML source. Make sure + # uses whichever one appears later in the HTML source. Make sure # apple-touch-icon is specified first to avoid this. if( false !== $wgAppleTouchIcon ) { $out->addLink( array( 'rel' => 'apple-touch-icon', 'href' => $wgAppleTouchIcon ) ); @@ -229,6 +236,11 @@ class Skin extends Linker { $lb->execute(); } + /** + * Adds metadata links (Creative Commons/Dublin Core/copyright) to the HTML + * output. + * @param $out Object: instance of OutputPage + */ function addMetadataLinks( OutputPage $out ) { global $wgEnableDublinCoreRdf, $wgEnableCreativeCommonsRdf; global $wgRightsPage, $wgRightsUrl; @@ -271,26 +283,30 @@ class Skin extends Linker { /** * Set some local variables */ - protected function setMembers(){ + protected function setMembers() { global $wgUser; $this->mUser = $wgUser; $this->userpage = $wgUser->getUserPage()->getPrefixedText(); $this->usercss = false; } - + /** * Set the title - * @param Title $t The title to use + * @param $t Title object to use */ public function setTitle( $t ) { $this->mTitle = $t; } - + /** Get the title */ public function getTitle() { return $this->mTitle; } + /** + * Outputs the HTML generated by other functions. + * @param $out Object: instance of OutputPage + */ function outputPage( OutputPage $out ) { global $wgDebugComments; wfProfileIn( __METHOD__ ); @@ -303,12 +319,6 @@ class Skin extends Linker { $out->out( $out->headElement( $this ) ); - $out->out( "\ngetBodyOptions(); - foreach ( $ops as $name => $val ) { - $out->out( " $name='$val'" ); - } - $out->out( ">\n" ); if ( $wgDebugComments ) { $out->out( "\n" ); @@ -319,7 +329,7 @@ class Skin extends Linker { $out->out( $out->mBodytext . "\n" ); $out->out( $this->afterContent() ); - + $out->out( $afterContent ); $out->out( $this->bottomScripts() ); @@ -331,37 +341,42 @@ class Skin extends Linker { } static function makeVariablesScript( $data ) { - global $wgJsMimeType; - - $r = array( "\n"; - - return implode( "\n\t\t", $r ); } /** * Make a " ); - global $wgUseSiteJs; - if( $wgUseSiteJs ) { - $jsCache = $wgUser->isLoggedIn() ? '&smaxage=0' : ''; - $r[] = ""; - } - if( $allowUserJs && $wgUser->isLoggedIn() ) { - $userpage = $wgUser->getUserPage(); - $userjs = htmlspecialchars( self::makeUrl( - $userpage->getPrefixedText().'/'.$this->getSkinName().'.js', - 'action=raw&ctype='.$wgJsMimeType ) ); - $r[] = '"; - } - return $vars . "\t\t" . implode ( "\n\t\t", $r ); - } - /** * To make it harder for someone to slip a user a fake * user-JavaScript or user-CSS preview, a random token @@ -472,25 +471,30 @@ class Skin extends Linker { * passed back with the preview request, we won't render * the code. * - * @param string $action + * @param $action String: 'edit', 'submit' etc. * @return bool - * @private */ - function userCanPreview( $action ) { + public function userCanPreview( $action ) { global $wgRequest, $wgUser; - if( $action != 'submit' ) + if( $action != 'submit' ) { + return false; + } + if( !$wgRequest->wasPosted() ) { return false; - if( !$wgRequest->wasPosted() ) + } + if( !$this->mTitle->userCanEditCssSubpage() ) { return false; - if( !$this->mTitle->userCanEditCssJsSubpage() ) + } + if( !$this->mTitle->userCanEditJsSubpage() ) { return false; + } return $wgUser->matchEditToken( $wgRequest->getVal( 'wpEditToken' ) ); } /** - * generated JavaScript action=raw&gen=js + * Generated JavaScript action=raw&gen=js * This returns MediaWiki:Common.js and MediaWiki:[Skinname].js concate- * nated together. For some bizarre reason, it does *not* return any * custom user JS from subpages. Huh? @@ -500,27 +504,31 @@ class Skin extends Linker { * top. For now Monobook.js will be maintained, but it should be consi- * dered deprecated. * + * @param $skinName String: If set, overrides the skin name * @return string */ - public function generateUserJs() { + public function generateUserJs( $skinName = null ) { global $wgStylePath; wfProfileIn( __METHOD__ ); + if( !$skinName ) { + $skinName = $this->getSkinName(); + } $s = "/* generated javascript */\n"; - $s .= "var skin = '" . Xml::escapeJsString( $this->getSkinName() ) . "';\n"; + $s .= "var skin = '" . Xml::escapeJsString( $skinName ) . "';\n"; $s .= "var stylepath = '" . Xml::escapeJsString( $wgStylePath ) . "';"; $s .= "\n\n/* MediaWiki:Common.js */\n"; - $commonJs = wfMsgForContent( 'common.js' ); + $commonJs = wfMsgExt( 'common.js', 'content' ); if ( !wfEmptyMsg( 'common.js', $commonJs ) ) { $s .= $commonJs; } - $s .= "\n\n/* MediaWiki:".ucfirst( $this->getSkinName() ).".js */\n"; + $s .= "\n\n/* MediaWiki:" . ucfirst( $skinName ) . ".js */\n"; // avoid inclusion of non defined user JavaScript (with custom skins only) // by checking for default message content - $msgKey = ucfirst( $this->getSkinName() ).'.js'; - $userJS = wfMsgForContent( $msgKey ); + $msgKey = ucfirst( $skinName ) . '.js'; + $userJS = wfMsgExt( $msgKey, 'content' ); if ( !wfEmptyMsg( $msgKey, $userJS ) ) { $s .= $userJS; } @@ -539,11 +547,12 @@ class Skin extends Linker { wfProfileOut( __METHOD__ ); return $s; } - + /** * Split for easier subclassing in SkinSimple, SkinStandard and SkinCologneBlue + * Anything in here won't be generated if $wgAllowUserCssPrefs is false. */ - protected function reallyGenerateUserStylesheet(){ + protected function reallyGenerateUserStylesheet() { global $wgUser; $s = ''; if( ( $undopt = $wgUser->getOption( 'underline' ) ) < 2 ) { @@ -553,7 +562,7 @@ class Skin extends Linker { if( $wgUser->getOption( 'highlightbroken' ) ) { $s .= "a.new, #quickbar a.new { color: #CC2200; }\n"; } else { - $s .= <<getOption( 'justify' ) ) { $s .= "#article, #bodyContent, #mw_content { text-align: justify; }\n"; @@ -577,6 +586,10 @@ END; if( !$wgUser->getOption( 'editsection' ) ) { $s .= ".editsection { display: none; }\n"; } + $fontstyle = $wgUser->getOption( 'editfont' ); + if ( $fontstyle !== 'default' ) { + $s .= "textarea { font-family: $fontstyle; }\n"; + } return $s; } @@ -584,8 +597,8 @@ END; * @private */ function setupUserCss( OutputPage $out ) { - global $wgRequest, $wgContLang, $wgUser; - global $wgAllowUserCss, $wgUseSiteCss, $wgSquidMaxage, $wgStylePath; + global $wgRequest, $wgUser; + global $wgAllowUserCss, $wgUseSiteCss, $wgSquidMaxage; wfProfileIn( __METHOD__ ); @@ -597,19 +610,15 @@ END; ); // Add any extension CSS - foreach( $out->getExtStyle() as $tag ) { - $out->addStyle( $tag['href'] ); + foreach ( $out->getExtStyle() as $url ) { + $out->addStyle( $url ); } // If we use the site's dynamic CSS, throw that in, too // Per-site custom styles if( $wgUseSiteCss ) { global $wgHandheldStyle; - $query = wfArrayToCGI( array( - 'usemsgcache' => 'yes', - 'ctype' => 'text/css', - 'smaxage' => $wgSquidMaxage - ) + $siteargs ); + $query = wfArrayToCGI( self::getDynamicStylesheetQuery() ); # Site settings must override extension css! (bug 15025) $out->addStyle( self::makeNSUrl( 'Common.css', $query, NS_MEDIAWIKI ) ); $out->addStyle( self::makeNSUrl( 'Print.css', $query, NS_MEDIAWIKI ), 'print' ); @@ -619,35 +628,58 @@ END; $out->addStyle( self::makeNSUrl( $this->getSkinName() . '.css', $query, NS_MEDIAWIKI ) ); } - if( $wgUser->isLoggedIn() ) { - // Ensure that logged-in users' generated CSS isn't clobbered - // by anons' publicly cacheable generated CSS. - $siteargs['smaxage'] = '0'; - $siteargs['ts'] = $wgUser->mTouched; - } - // Per-user styles based on preferences - $siteargs['gen'] = 'css'; - if( ( $us = $wgRequest->getVal( 'useskin', '' ) ) !== '' ) { - $siteargs['useskin'] = $us; + global $wgAllowUserCssPrefs; + if( $wgAllowUserCssPrefs ){ + if( $wgUser->isLoggedIn() ) { + // Ensure that logged-in users' generated CSS isn't clobbered + // by anons' publicly cacheable generated CSS. + $siteargs['smaxage'] = '0'; + $siteargs['ts'] = $wgUser->mTouched; + } + // Per-user styles based on preferences + $siteargs['gen'] = 'css'; + if( ( $us = $wgRequest->getVal( 'useskin', '' ) ) !== '' ) { + $siteargs['useskin'] = $us; + } + $out->addStyle( self::makeUrl( '-', wfArrayToCGI( $siteargs ) ) ); } - $out->addStyle( self::makeUrl( '-', wfArrayToCGI( $siteargs ) ) ); // Per-user custom style pages if( $wgAllowUserCss && $wgUser->isLoggedIn() ) { $action = $wgRequest->getVal( 'action' ); # If we're previewing the CSS page, use it if( $this->mTitle->isCssSubpage() && $this->userCanPreview( $action ) ) { - $previewCss = $wgRequest->getText( 'wpTextbox1' ); // @FIXME: properly escape the cdata! - $this->usercss = "/**/"; + $out->addInlineStyle( $wgRequest->getText( 'wpTextbox1' ) ); } else { - $out->addStyle( self::makeUrl( $this->userpage . '/' . $this->getSkinName() .'.css', - 'action=raw&ctype=text/css' ) ); + $names = array( 'common', $this->getSkinName() ); + foreach( $names as $name ) { + $out->addStyle( self::makeUrl( + $this->userpage . '/' . $name . '.css', + 'action=raw&ctype=text/css' ) + ); + } } } wfProfileOut( __METHOD__ ); } + + /** + * Get the query to generate a dynamic stylesheet + * + * @return array + */ + public static function getDynamicStylesheetQuery() { + global $wgSquidMaxage; + return array( + 'action' => 'raw', + 'maxage' => $wgSquidMaxage, + 'usemsgcache' => 'yes', + 'ctype' => 'text/css', + 'smaxage' => $wgSquidMaxage, + ); + } /** * Add skin specific stylesheets @@ -660,32 +692,8 @@ END; $out->addStyle( 'common/common_rtl.css', '', '', 'rtl' ); } - function getBodyOptions() { - global $wgUser, $wgOut, $wgRequest, $wgContLang; - - extract( $wgRequest->getValues( 'oldid', 'redirect', 'diff' ) ); - - if ( 0 != $this->mTitle->getNamespace() ) { - $a = array( 'bgcolor' => '#ffffec' ); - } - else $a = array( 'bgcolor' => '#FFFFFF' ); - if( $wgOut->isArticle() && $wgUser->getOption( 'editondblclick' ) && - $this->mTitle->quickUserCan( 'edit' ) ) { - $s = $this->mTitle->getFullURL( $this->editUrlOptions() ); - $s = 'document.location = "' .Xml::escapeJsString( $s ) .'";'; - $a += array( 'ondblclick' => $s ); - } - $a['onload'] = $wgOut->getOnloadHandler(); - $a['class'] = - 'mediawiki' . - ' '.( $wgContLang->isRTL() ? 'rtl' : 'ltr' ). - ' '.$this->getPageClasses( $this->mTitle ) . - ' skin-'. Sanitizer::escapeClass( $this->getSkinName() ); - return $a; - } - function getPageClasses( $title ) { - $numeric = 'ns-'.$title->getNamespace(); + $numeric = 'ns-' . $title->getNamespace(); if( $title->getNamespace() == NS_SPECIAL ) { $type = 'ns-special'; } elseif( $title->isTalkPage() ) { @@ -693,7 +701,7 @@ END; } else { $type = 'ns-subject'; } - $name = Sanitizer::escapeClass( 'page-'.$title->getPrefixedText() ); + $name = Sanitizer::escapeClass( 'page-' . $title->getPrefixedText() ); return "$numeric $type $name"; } @@ -720,7 +728,8 @@ END; $s = ''; $qb = $this->qbSetting(); - if( $langlinks = $this->otherLanguages() ) { + $langlinks = $this->otherLanguages(); + if( $langlinks ) { $rows = 2; $borderhack = ''; } else { @@ -734,24 +743,26 @@ END; $shove = ( $qb != 0 ); $left = ( $qb == 1 || $qb == 3 ); - if( $wgContLang->isRTL() ) $left = !$left; + if( $wgContLang->isRTL() ) { + $left = !$left; + } if( !$shove ) { $s .= "\n" . - $this->logoText() . ''; + $this->logoText() . ''; } elseif( $left ) { $s .= $this->getQuickbarCompensator( $rows ); } - $l = $wgContLang->isRTL() ? 'right' : 'left'; + $l = $wgContLang->alignStart(); $s .= "\n"; $s .= $this->topLinks(); - $s .= "

" . $this->pageTitleLinks() . "

\n"; + $s .= '

' . $this->pageTitleLinks() . "

\n"; - $r = $wgContLang->isRTL() ? 'left' : 'right'; + $r = $wgContLang->alignEnd(); $s .= "\n"; $s .= $this->nameAndLogin(); - $s .= "\n
" . $this->searchForm() . ""; + $s .= "\n
" . $this->searchForm() . ''; if ( $langlinks ) { $s .= "\n\n$langlinks\n"; @@ -774,19 +785,20 @@ END; return $s; } - function getCategoryLinks() { global $wgOut, $wgUseCategoryBrowser; global $wgContLang, $wgUser; - if( count( $wgOut->mCategoryLinks ) == 0 ) return ''; + if( count( $wgOut->mCategoryLinks ) == 0 ) { + return ''; + } # Separator $sep = wfMsgExt( 'catseparator', array( 'parsemag', 'escapenoentities' ) ); // Use Unicode bidi embedding override characters, // to make sure links don't smash each other up in ugly ways. - $dir = $wgContLang->isRTL() ? 'rtl' : 'ltr'; + $dir = $wgContLang->getDir(); $embed = ""; $pop = ''; @@ -814,19 +826,19 @@ END; $s .= "
" . wfMsgExt( 'hidden-categories', array( 'parsemag', 'escapenoentities' ), count( $allCats['hidden'] ) ) . $colon . $embed . implode( "$pop $sep $embed", $allCats['hidden'] ) . $pop . - "
"; + ''; } # optional 'dmoz-like' category browser. Will be shown under the list # of categories an article belong to - if( $wgUseCategoryBrowser ){ + if( $wgUseCategoryBrowser ) { $s .= '

'; # get a big array of the parents tree $parenttree = $this->mTitle->getParentCategoryTree(); # Skin object passed by reference cause it can not be # accessed under the method subfunction drawCategoryBrowser - $tempout = explode( "\n", Skin::drawCategoryBrowser( $parenttree, $this ) ); + $tempout = explode( "\n", $this->drawCategoryBrowser( $parenttree, $this ) ); # Clean out bogus first entry and sort them unset( $tempout[0] ); asort( $tempout ); @@ -843,7 +855,7 @@ END; * @param &skin Object: skin passed by reference * @return String separated by >, terminate with "\n" */ - function drawCategoryBrowser( $tree, &$skin ){ + function drawCategoryBrowser( $tree, &$skin ) { $return = ''; foreach( $tree as $element => $parent ) { if( empty( $parent ) ) { @@ -851,7 +863,7 @@ END; $return .= "\n"; } else { # grab the others elements - $return .= Skin::drawCategoryBrowser( $parent, $skin ) . ' > '; + $return .= $this->drawCategoryBrowser( $parent, $skin ) . ' > '; } # add our current element to the list $eltitle = Title::newFromText( $element ); @@ -861,22 +873,25 @@ END; } function getCategories() { - $catlinks=$this->getCategoryLinks(); + $catlinks = $this->getCategoryLinks(); $classes = 'catlinks'; - if( strpos( $catlinks, ''; + } function pageTitleLinks() { global $wgOut, $wgUser, $wgRequest, $wgLang; @@ -1035,7 +1088,7 @@ END; } function getUndeleteLink() { - global $wgUser, $wgContLang, $wgLang, $wgRequest; + global $wgUser, $wgLang, $wgRequest; $action = $wgRequest->getVal( 'action', 'view' ); @@ -1066,9 +1119,13 @@ END; function printableLink() { global $wgOut, $wgFeedClasses, $wgRequest, $wgLang; - $printurl = $wgRequest->escapeAppendQuery( 'printable=yes' ); + $s = array(); + + if ( !$wgOut->isPrintable() ) { + $printurl = $wgRequest->escapeAppendQuery( 'printable=yes' ); + $s[] = "" . wfMsg( 'printableversion' ) . ''; + } - $s[] = "" . wfMsg( 'printableversion' ) . ''; if( $wgOut->isSyndicated() ) { foreach( $wgFeedClasses as $format => $class ) { $feedurl = $wgRequest->escapeAppendQuery( "feed=$format" ); @@ -1079,6 +1136,10 @@ END; return $wgLang->pipeList( $s ); } + /** + * Gets the h1 element with the page title. + * @return string + */ function pageTitle() { global $wgOut; $s = '

' . $wgOut->getPageTitle() . '

'; @@ -1089,7 +1150,7 @@ END; global $wgOut; $sub = $wgOut->getSubtitle(); - if ( '' == $sub ) { + if ( $sub == '' ) { global $wgExtraSubtitle; $sub = wfMsgExt( 'tagline', 'parsemag' ) . $wgExtraSubtitle; } @@ -1101,8 +1162,9 @@ END; function subPageSubtitle() { $subpages = ''; - if( !wfRunHooks( 'SkinSubPageSubtitle', array( &$subpages ) ) ) + if( !wfRunHooks( 'SkinSubPageSubtitle', array( &$subpages ) ) ) { return $subpages; + } global $wgOut; if( $wgOut->isArticle() && MWNamespace::hasSubpages( $this->mTitle->getNamespace() ) ) { @@ -1117,7 +1179,7 @@ END; $growinglink .= $link; $display .= $link; $linkObj = Title::newFromText( $growinglink ); - if( is_object( $linkObj ) && $linkObj->exists() ){ + if( is_object( $linkObj ) && $linkObj->exists() ) { $getlink = $this->link( $linkObj, htmlspecialchars( $display ), @@ -1222,16 +1284,17 @@ END; global $wgRequest, $wgUseTwoButtonsSearchForm; $search = $wgRequest->getText( 'search' ); - $s = '
searchboxes . '" name="search" class="inline" method="post" action="' . $this->escapeSearchLink() . "\">\n" - . '\n" . ''; - if( $wgUseTwoButtonsSearchForm ) - $s .= ' \n"; - else + if( $wgUseTwoButtonsSearchForm ) { + $s .= ' \n"; + } else { $s .= ' \n"; + } $s .= '
'; @@ -1307,11 +1370,12 @@ END; if( !$wgDisableLangConversion && sizeof( $variants ) > 1 ) { foreach( $variants as $code ) { $varname = $wgContLang->getVariantname( $code ); - if( $varname == 'disable' ) + if( $varname == 'disable' ) { continue; + } $s = $wgLang->pipeList( array( $s, - '' . htmlspecialchars( $varname ) . '' + '' . htmlspecialchars( $varname ) . '' ) ); } } @@ -1333,29 +1397,41 @@ END; $element[] = $this->whatLinksHere(); $element[] = $this->watchPageLinksLink(); - if( $wgUseTrackbacks ) + if( $wgUseTrackbacks ) { $element[] = $this->trackbackLink(); + } - if ( $this->mTitle->getNamespace() == NS_USER - || $this->mTitle->getNamespace() == NS_USER_TALK ){ + if ( + $this->mTitle->getNamespace() == NS_USER || + $this->mTitle->getNamespace() == NS_USER_TALK + ) + { $id = User::idFromName( $this->mTitle->getText() ); $ip = User::isIP( $this->mTitle->getText() ); - if( $id || $ip ) { # both anons and non-anons have contri list + # Both anons and non-anons have contributions list + if( $id || $ip ) { $element[] = $this->userContribsLink(); } if( $this->showEmailUser( $id ) ) { $element[] = $this->emailUserLink(); } } - + $s = implode( $element, $sep ); if ( $this->mTitle->getArticleId() ) { $s .= "\n
"; - if( $wgUser->isAllowed( 'delete' ) ) { $s .= $this->deleteThisPage(); } - if( $wgUser->isAllowed( 'protect' ) ) { $s .= $sep . $this->protectThisPage(); } - if( $wgUser->isAllowed( 'move' ) ) { $s .= $sep . $this->moveThisPage(); } + // Delete/protect/move links for privileged users + if( $wgUser->isAllowed( 'delete' ) ) { + $s .= $this->deleteThisPage(); + } + if( $wgUser->isAllowed( 'protect' ) ) { + $s .= $sep . $this->protectThisPage(); + } + if( $wgUser->isAllowed( 'move' ) ) { + $s .= $sep . $this->moveThisPage(); + } } $s .= "
\n" . $this->otherLanguages(); } @@ -1369,10 +1445,18 @@ END; $oldid = $wgRequest->getVal( 'oldid' ); $diff = $wgRequest->getVal( 'diff' ); - if ( ! $wgOut->isArticle() ) { return ''; } - if( !$wgArticle instanceOf Article ) { return ''; } - if ( isset( $oldid ) || isset( $diff ) ) { return ''; } - if ( 0 == $wgArticle->getID() ) { return ''; } + if ( !$wgOut->isArticle() ) { + return ''; + } + if( !$wgArticle instanceof Article ) { + return ''; + } + if ( isset( $oldid ) || isset( $diff ) ) { + return ''; + } + if ( 0 == $wgArticle->getID() ) { + return ''; + } $s = ''; if ( !$wgDisableCounters ) { @@ -1382,7 +1466,7 @@ END; } } - if( $wgMaxCredits != 0 ){ + if( $wgMaxCredits != 0 ) { $s .= ' ' . Credits::getCredits( $wgArticle, $wgMaxCredits, $wgShowCreditsIfMax ); } else { $s .= $this->lastModified(); @@ -1390,9 +1474,13 @@ END; if( $wgPageShowWatchingUsers && $wgUser->getOption( 'shownumberswatching' ) ) { $dbr = wfGetDB( DB_SLAVE ); - $res = $dbr->select( 'watchlist', + $res = $dbr->select( + 'watchlist', array( 'COUNT(*) AS n' ), - array( 'wl_title' => $dbr->strencode( $this->mTitle->getDBkey() ), 'wl_namespace' => $this->mTitle->getNamespace() ), + array( + 'wl_title' => $dbr->strencode( $this->mTitle->getDBkey() ), + 'wl_namespace' => $this->mTitle->getNamespace() + ), __METHOD__ ); $x = $dbr->fetchObject( $res ); @@ -1436,7 +1524,17 @@ END; # Give up now return $out; } - $out .= wfMsgForContent( $msg, $link ); + // Allow for site and per-namespace customization of copyright notice. + $forContent = true; + if( isset( $wgArticle ) ) { + wfRunHooks( 'SkinCopyrightFooter', array( $wgArticle->getTitle(), $type, &$msg, &$link, &$forContent ) ); + } + + if ( $forContent ) { + $out .= wfMsgForContent( $msg, $link ); + } else { + $out .= wfMsg( $msg, $link ); + } return $out; } @@ -1445,14 +1543,14 @@ END; $out = ''; if ( isset( $wgCopyrightIcon ) && $wgCopyrightIcon ) { $out = $wgCopyrightIcon; - } else if ( $wgRightsIcon ) { + } elseif ( $wgRightsIcon ) { $icon = htmlspecialchars( $wgRightsIcon ); if ( $wgRightsUrl ) { $url = htmlspecialchars( $wgRightsUrl ); $out .= ''; } $text = htmlspecialchars( $wgRightsText ); - $out .= "$text"; + $out .= "\"$text\""; if ( $wgRightsUrl ) { $out .= ''; } @@ -1460,16 +1558,20 @@ END; return $out; } + /** + * Gets the powered by MediaWiki icon. + * @return string + */ function getPoweredBy() { global $wgStylePath; $url = htmlspecialchars( "$wgStylePath/common/images/poweredby_mediawiki_88x31.png" ); - $img = 'Powered by MediaWiki'; + $img = 'Powered by MediaWiki'; return $img; } function lastModified() { global $wgLang, $wgArticle; - if( $this->mRevisionId ) { + if( $this->mRevisionId && $this->mRevisionId != $wgArticle->getLatest() ) { $timestamp = Revision::getTimestampFromId( $wgArticle->getTitle(), $this->mRevisionId ); } else { $timestamp = $wgArticle->getTimestamp(); @@ -1488,7 +1590,7 @@ END; } function logoText( $align = '' ) { - if ( '' != $align ) { + if ( $align != '' ) { $a = " align='{$align}'"; } else { $a = ''; @@ -1504,10 +1606,10 @@ END; } /** - * show a drop-down box of special pages + * Show a drop-down box of special pages */ function specialPagesList() { - global $wgUser, $wgContLang, $wgServer, $wgRedirectScript; + global $wgContLang, $wgServer, $wgRedirectScript; $pages = array_merge( SpecialPage::getRegularPages(), SpecialPage::getRestrictedPages() ); foreach ( $pages as $name => $page ) { $pages[$name] = $page->getDescription(); @@ -1533,6 +1635,10 @@ END; return $s; } + /** + * Gets the link to the wiki's main page. + * @return string + */ function mainPageLink() { $s = $this->link( Title::newMainPage(), @@ -1544,16 +1650,7 @@ END; return $s; } - function copyrightLink() { - $title = Title::newFromText( wfMsgForContent( 'copyrightpage' ) ); - $s = $this->linkKnown( - $title, - wfMsg( 'copyrightpagename' ) - ); - return $s; - } - - private function footerLink ( $desc, $page ) { + private function footerLink( $desc, $page ) { // if the link description has been set to "-" in the default language, if ( wfMsgForContent( $desc ) == '-') { // then it is disabled, for all languages. @@ -1562,7 +1659,7 @@ END; // Otherwise, we display the link for the user, described in their // language (which may or may not be the same as the default language), // but we make the link target be the one site-wide page. - $title = Title::newFromText( $page ); + $title = Title::newFromText( wfMsgForContent( $page ) ); return $this->linkKnown( $title, wfMsgExt( $desc, array( 'parsemag', 'escapenoentities' ) ) @@ -1570,14 +1667,23 @@ END; } } + /** + * Gets the link to the wiki's privacy policy page. + */ function privacyLink() { return $this->footerLink( 'privacy', 'privacypage' ); } + /** + * Gets the link to the wiki's about page. + */ function aboutLink() { return $this->footerLink( 'aboutsite', 'aboutpage' ); } + /** + * Gets the link to the wiki's general disclaimers page. + */ function disclaimerLink() { return $this->footerLink( 'disclaimers', 'disclaimerpage' ); } @@ -1617,7 +1723,7 @@ END; function editUrlOptions() { global $wgArticle; - $options = array( 'action' => 'edit' ); + $options = array( 'action' => 'edit' ); if( $this->mRevisionId && ! $wgArticle->isCurrent() ) { $options['oldid'] = intval( $this->mRevisionId ); @@ -1706,7 +1812,7 @@ END; SpecialPage::getTitleFor( 'Movepage' ), wfMsg( 'movethispage' ), array(), - array( 'target' => $this->mTitle->getPrefixedURL() ), + array( 'target' => $this->mTitle->getPrefixedDBkey() ), array( 'known', 'noclasses' ) ); } else { @@ -1747,7 +1853,7 @@ END; function showEmailUser( $id ) { global $wgUser; $targetUser = User::newFromId( $id ); - return $wgUser->canSendEmail() && # the sending user must have a confirmed email address + return $wgUser->canSendEmail() && # the sending user must have a confirmed email address $targetUser->canReceiveEmail(); # the target user must have a confirmed email address and allow emails from users } @@ -1763,7 +1869,7 @@ END; function watchPageLinksLink() { global $wgOut; - if ( ! $wgOut->isArticleRelated() ) { + if ( !$wgOut->isArticleRelated() ) { return '(' . wfMsg( 'notanarticle' ) . ')'; } else { return $this->link( @@ -1795,7 +1901,9 @@ END; $s = wfMsg( 'otherlanguages' ) . wfMsg( 'colon-separator' ); $first = true; - if( $wgContLang->isRTL() ) $s .= ''; + if( $wgContLang->isRTL() ) { + $s .= ''; + } foreach( $a as $l ) { if ( !$first ) { $s .= wfMsgExt( 'pipe-separator', 'escapenoentities' ); @@ -1805,12 +1913,17 @@ END; $nt = Title::newFromText( $l ); $url = $nt->escapeFullURL(); $text = $wgContLang->getLanguageName( $nt->getInterwiki() ); + $title = htmlspecialchars( $nt->getText() ); - if ( '' == $text ) { $text = $l; } - $style = $this->getExternalLinkAttributes( $l, $text ); - $s .= "{$text}"; + if ( $text == '' ) { + $text = $l; + } + $style = $this->getExternalLinkAttributes(); + $s .= "{$text}"; + } + if( $wgContLang->isRTL() ) { + $s .= ''; } - if( $wgContLang->isRTL() ) $s .= ''; return $s; } @@ -1895,6 +2008,23 @@ END; ); } + function getUploadLink() { + global $wgUploadNavigationUrl; + + if( $wgUploadNavigationUrl ) { + # Using an empty class attribute to avoid automatic setting of "external" class + return $this->makeExternalLink( $wgUploadNavigationUrl, wfMsgHtml( 'upload' ), false, null, array( 'class' => '') ); + } else { + return $this->link( + SpecialPage::getTitleFor('Upload'), + wfMsgHtml( 'upload' ), + array(), + array(), + array( 'known', 'noclasses' ) + ); + } + } + /* these are used extensively in SkinTemplate, but also some other places */ static function makeMainPageUrl( $urlaction = '' ) { $title = Title::newMainPage(); @@ -1924,8 +2054,10 @@ END; return $title->getLocalURL( $urlaction ); } - # If url string starts with http, consider as external URL, else - # internal + /** + * If url string starts with http, consider as external URL, else + * internal + */ static function makeInternalOrExternalUrl( $name ) { if ( preg_match( '/^(?:' . wfUrlProtocols() . ')/', $name ) ) { return $name; @@ -1994,26 +2126,64 @@ END; } $bar = array(); - $lines = explode( "\n", wfMsgForContent( 'sidebar' ) ); + $this->addToSidebar( $bar, 'sidebar' ); + + wfRunHooks( 'SkinBuildSidebar', array( $this, &$bar ) ); + if ( $wgEnableSidebarCache ) { + $parserMemc->set( $key, $bar, $wgSidebarCacheExpiry ); + } + wfProfileOut( __METHOD__ ); + return $bar; + } + /** + * Add content from a sidebar system message + * Currently only used for MediaWiki:Sidebar (but may be used by Extensions) + * + * This is just a wrapper around addToSidebarPlain() for backwards compatibility + * + * @param &$bar array + * @param $message String + */ + function addToSidebar( &$bar, $message ) { + $this->addToSidebarPlain( $bar, wfMsgForContent( $message ) ); + } + + /** + * Add content from plain text + * @since 1.17 + * @param &$bar array + * @param $text string + */ + function addToSidebarPlain( &$bar, $text ) { + $lines = explode( "\n", $text ); + $wikiBar = array(); # We need to handle the wikitext on a different variable, to avoid trying to do an array operation on text, which would be a fatal error. + $heading = ''; foreach( $lines as $line ) { - if( strpos( $line, '*' ) !== 0 ) + if( strpos( $line, '*' ) !== 0 ) { continue; + } if( strpos( $line, '**') !== 0 ) { $heading = trim( $line, '* ' ); - if( !array_key_exists( $heading, $bar ) ) $bar[$heading] = array(); + if( !array_key_exists( $heading, $bar ) ) { + $bar[$heading] = array(); + } } else { + $line = trim( $line, '* ' ); if( strpos( $line, '|' ) !== false ) { // sanity check - $line = array_map( 'trim', explode( '|', trim( $line, '* ' ), 2 ) ); + $line = array_map( 'trim', explode( '|', $line, 2 ) ); $link = wfMsgForContent( $line[0] ); - if( $link == '-' ) + if( $link == '-' ) { continue; + } $text = wfMsgExt( $line[1], 'parsemag' ); - if( wfEmptyMsg( $line[1], $text ) ) + if( wfEmptyMsg( $line[1], $text ) ) { $text = $line[1]; - if( wfEmptyMsg( $line[0], $link ) ) + } + if( wfEmptyMsg( $line[0], $link ) ) { $link = $line[0]; + } if ( preg_match( '/^(?:' . wfUrlProtocols() . ')/', $link ) ) { $href = $link; @@ -2033,12 +2203,93 @@ END; 'id' => 'n-' . strtr( $line[1], ' ', '-' ), 'active' => false ); - } else { continue; } + } else if ( (substr($line, 0, 2) == '{{') && (substr($line, -2) == '}}') ) { + global $wgParser, $wgTitle; + + $line = substr($line, 2, strlen($line) - 4 ); + + if (is_null($wgParser->mOptions)) + $wgParser->mOptions = new ParserOptions(); + + $wgParser->mOptions->setEditSection(false); + $wikiBar[$heading] = $wgParser->parse( wfMsgForContentNoTrans( $line ) , $wgTitle, $wgParser->mOptions )->getText(); + } else { + continue; + } } } - wfRunHooks( 'SkinBuildSidebar', array( $this, &$bar ) ); - if ( $wgEnableSidebarCache ) $parserMemc->set( $key, $bar, $wgSidebarCacheExpiry ); - wfProfileOut( __METHOD__ ); + + if ( count($wikiBar) > 0 ) + $bar = array_merge($bar, $wikiBar); + return $bar; } + + /** + * Should we include common/wikiprintable.css? Skins that have their own + * print stylesheet should override this and return false. (This is an + * ugly hack to get Monobook to play nicely with + * OutputPage::headElement().) + * + * @return bool + */ + public function commonPrintStylesheet() { + return true; + } + + /** + * Gets new talk page messages for the current user. + * @return MediaWiki message or if no new talk page messages, nothing + */ + function getNewtalks() { + global $wgUser, $wgOut; + $newtalks = $wgUser->getNewMessageLinks(); + $ntl = ''; + + if( count( $newtalks ) == 1 && $newtalks[0]['wiki'] === wfWikiID() ) { + $userTitle = $this->mUser->getUserPage(); + $userTalkTitle = $userTitle->getTalkPage(); + + if( !$userTalkTitle->equals( $this->mTitle ) ) { + $newMessagesLink = $this->link( + $userTalkTitle, + wfMsgHtml( 'newmessageslink' ), + array(), + array( 'redirect' => 'no' ), + array( 'known', 'noclasses' ) + ); + + $newMessagesDiffLink = $this->link( + $userTalkTitle, + wfMsgHtml( 'newmessagesdifflink' ), + array(), + array( 'diff' => 'cur' ), + array( 'known', 'noclasses' ) + ); + + $ntl = wfMsg( + 'youhavenewmessages', + $newMessagesLink, + $newMessagesDiffLink + ); + # Disable Squid cache + $wgOut->setSquidMaxage( 0 ); + } + } elseif( count( $newtalks ) ) { + // _>" " for BC <= 1.16 + $sep = str_replace( '_', ' ', wfMsgHtml( 'newtalkseparator' ) ); + $msgs = array(); + foreach( $newtalks as $newtalk ) { + $msgs[] = Xml::element( + 'a', + array( 'href' => $newtalk['link'] ), $newtalk['wiki'] + ); + } + $parts = implode( $sep, $msgs ); + $ntl = wfMsgHtml( 'youhavenewmessagesmulti', $parts ); + $wgOut->setSquidMaxage( 0 ); + } + return $ntl; + } + }