skin.php
来自「php 开发的内容管理系统」· PHP 代码 · 共 1,500 行 · 第 1/3 页
PHP
1,500 行
<?phpif ( ! defined( 'MEDIAWIKI' ) ) die( 1 );/** * * @package MediaWiki * @subpackage Skins */# See skin.txt/** * The main skin class that provide methods and properties for all other skins. * This base class is also the "Standard" skin. * @package MediaWiki */class Skin extends Linker { /**#@+ * @private */ var $lastdate, $lastline; var $rc_cache ; # Cache for Enhanced Recent Changes var $rcCacheIndex ; # Recent Changes Cache Counter for visibility toggle var $rcMoveIndex; /**#@-*/ /** Constructor, call parent constructor */ function Skin() { parent::Linker(); } /** * Fetch the set of available skins. * @return array of strings * @static */ function &getSkinNames() { global $wgValidSkinNames; static $skinsInitialised = false; if ( !$skinsInitialised ) { # Get a list of available skins # Build using the regular expression '^(.*).php$' # Array keys are all lower case, array value keep the case used by filename # wfProfileIn( __METHOD__ . '-init' ); global $wgStyleDirectory; $skinDir = dir( $wgStyleDirectory ); # while code from www.php.net while (false !== ($file = $skinDir->read())) { // Skip non-PHP files, hidden files, and '.dep' includes if(preg_match('/^([^.]*)\.php$/',$file, $matches)) { $aSkin = $matches[1]; $wgValidSkinNames[strtolower($aSkin)] = $aSkin; } } $skinDir->close(); $skinsInitialised = true; wfProfileOut( __METHOD__ . '-init' ); } return $wgValidSkinNames; } /** * 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 * @return string * @static */ function normalizeKey( $key ) { global $wgDefaultSkin; $skinNames = Skin::getSkinNames(); if( $key == '' ) { // Don't return the default immediately; // in a misconfiguration we need to fall back. $key = $wgDefaultSkin; } if( isset( $skinNames[$key] ) ) { return $key; } // Older versions of the software used a numeric setting // in the user preferences. $fallback = array( 0 => $wgDefaultSkin, 1 => 'nostalgia', 2 => 'cologneblue' ); if( isset( $fallback[$key] ) ){ $key = $fallback[$key]; } if( isset( $skinNames[$key] ) ) { return $key; } else { // The old built-in skin return 'standard'; } } /** * Factory method for loading a skin of a given type * @param string $key 'monobook', 'standard', etc * @return Skin * @static */ function &newFromKey( $key ) { global $wgStyleDirectory; $key = Skin::normalizeKey( $key ); $skinNames = Skin::getSkinNames(); $skinName = $skinNames[$key]; # Grab the skin class and initialise it. wfSuppressWarnings(); // Preload base classes to work around APC/PHP5 bug include_once( "{$wgStyleDirectory}/{$skinName}.deps.php" ); wfRestoreWarnings(); require_once( "{$wgStyleDirectory}/{$skinName}.php" ); # Check if we got if not failback to default skin $className = 'Skin'.$skinName; if( !class_exists( $className ) ) { # DO NOT die if the class isn't found. This breaks maintenance # scripts and can cause a user account to be unrecoverable # except by SQL manipulation if a previously valid skin name # is no longer valid. wfDebug( "Skin class does not exist: $className\n" ); $className = 'SkinStandard'; require_once( "{$wgStyleDirectory}/Standard.php" ); } $skin =& new $className; return $skin; } /** @return string path to the skin stylesheet */ function getStylesheet() { return 'common/wikistandard.css?1'; } /** @return string skin name */ function getSkinName() { return 'standard'; } function qbSetting() { global $wgOut, $wgUser; if ( $wgOut->isQuickbarSuppressed() ) { return 0; } $q = $wgUser->getOption( 'quickbar' ); if ( '' == $q ) { $q = 0; } return $q; } function initPage( &$out ) { global $wgFavicon; $fname = 'Skin::initPage'; wfProfileIn( $fname ); if( false !== $wgFavicon ) { $out->addLink( array( 'rel' => 'shortcut icon', 'href' => $wgFavicon ) ); } $this->addMetadataLinks($out); $this->mRevisionId = $out->mRevisionId; $this->preloadExistence(); wfProfileOut( $fname ); } /** * Preload the existence of three commonly-requested pages in a single query */ function preloadExistence() { global $wgUser, $wgTitle; if ( $wgTitle->isTalkPage() ) { $otherTab = $wgTitle->getSubjectPage(); } else { $otherTab = $wgTitle->getTalkPage(); } $lb = new LinkBatch( array( $wgUser->getUserPage(), $wgUser->getTalkPage(), $otherTab )); $lb->execute(); } function addMetadataLinks( &$out ) { global $wgTitle, $wgEnableDublinCoreRdf, $wgEnableCreativeCommonsRdf; global $wgRightsPage, $wgRightsUrl; if( $out->isArticleRelated() ) { # note: buggy CC software only reads first "meta" link if( $wgEnableCreativeCommonsRdf ) { $out->addMetadataLink( array( 'title' => 'Creative Commons', 'type' => 'application/rdf+xml', 'href' => $wgTitle->getLocalURL( 'action=creativecommons') ) ); } if( $wgEnableDublinCoreRdf ) { $out->addMetadataLink( array( 'title' => 'Dublin Core', 'type' => 'application/rdf+xml', 'href' => $wgTitle->getLocalURL( 'action=dublincore' ) ) ); } } $copyright = ''; if( $wgRightsPage ) { $copy = Title::newFromText( $wgRightsPage ); if( $copy ) { $copyright = $copy->getLocalURL(); } } if( !$copyright && $wgRightsUrl ) { $copyright = $wgRightsUrl; } if( $copyright ) { $out->addLink( array( 'rel' => 'copyright', 'href' => $copyright ) ); } } function outputPage( &$out ) { global $wgDebugComments; wfProfileIn( 'Skin::outputPage' ); $this->initPage( $out ); $out->out( $out->headElement() ); $out->out( "\n<body" ); $ops = $this->getBodyOptions(); foreach ( $ops as $name => $val ) { $out->out( " $name='$val'" ); } $out->out( ">\n" ); if ( $wgDebugComments ) { $out->out( "<!-- Wiki debugging output:\n" . $out->mDebugtext . "-->\n" ); } $out->out( $this->beforeContent() ); $out->out( $out->mBodytext . "\n" ); $out->out( $this->afterContent() ); $out->out( $out->reportTime() ); $out->out( "\n</body></html>" ); } function getHeadScripts() { global $wgStylePath, $wgUser, $wgAllowUserJs, $wgJsMimeType; $r = "<script type=\"{$wgJsMimeType}\" src=\"{$wgStylePath}/common/wikibits.js\"></script>\n"; if( $wgAllowUserJs && $wgUser->isLoggedIn() ) { $userpage = $wgUser->getUserPage(); $userjs = htmlspecialchars( $this->makeUrl( $userpage->getPrefixedText().'/'.$this->getSkinName().'.js', 'action=raw&ctype='.$wgJsMimeType)); $r .= '<script type="'.$wgJsMimeType.'" src="'.$userjs."\"></script>\n"; } return $r; } /** * To make it harder for someone to slip a user a fake * user-JavaScript or user-CSS preview, a random token * is associated with the login session. If it's not * passed back with the preview request, we won't render * the code. * * @param string $action * @return bool * @private */ function userCanPreview( $action ) { global $wgTitle, $wgRequest, $wgUser; if( $action != 'submit' ) return false; if( !$wgRequest->wasPosted() ) return false; if( !$wgTitle->userCanEditCssJsSubpage() ) return false; return $wgUser->matchEditToken( $wgRequest->getVal( 'wpEditToken' ) ); } # get the user/site-specific stylesheet, SkinTemplate loads via RawPage.php (settings are cached that way) function getUserStylesheet() { global $wgStylePath, $wgRequest, $wgContLang, $wgSquidMaxage; $sheet = $this->getStylesheet(); $action = $wgRequest->getText('action'); $s = "@import \"$wgStylePath/$sheet\";\n"; if($wgContLang->isRTL()) $s .= "@import \"$wgStylePath/common/common_rtl.css\";\n"; $query = "action=raw&ctype=text/css&smaxage=$wgSquidMaxage"; $s .= '@import "' . $this->makeNSUrl( 'Common.css', $query, NS_MEDIAWIKI ) . "\";\n" . '@import "'.$this->makeNSUrl( ucfirst( $this->getSkinName() . '.css' ), $query, NS_MEDIAWIKI ) . "\";\n"; $s .= $this->doGetUserStyles(); return $s."\n"; } /** * placeholder, returns generated js in monobook */ function getUserJs() { return; } /** * Return html code that include User stylesheets */ function getUserStyles() { $s = "<style type='text/css'>\n"; $s .= "/*/*/ /*<![CDATA[*/\n"; # <-- Hide the styles from Netscape 4 without hiding them from IE/Mac $s .= $this->getUserStylesheet(); $s .= "/*]]>*/ /* */\n"; $s .= "</style>\n"; return $s; } /** * Some styles that are set by user through the user settings interface. */ function doGetUserStyles() { global $wgUser, $wgUser, $wgRequest, $wgTitle, $wgAllowUserCss; $s = ''; if( $wgAllowUserCss && $wgUser->isLoggedIn() ) { # logged in if($wgTitle->isCssSubpage() && $this->userCanPreview( $wgRequest->getText( 'action' ) ) ) { $s .= $wgRequest->getText('wpTextbox1'); } else { $userpage = $wgUser->getUserPage(); $s.= '@import "'.$this->makeUrl( $userpage->getPrefixedText().'/'.$this->getSkinName().'.css', 'action=raw&ctype=text/css').'";'."\n"; } } return $s . $this->reallyDoGetUserStyles(); } function reallyDoGetUserStyles() { global $wgUser; $s = ''; if (($undopt = $wgUser->getOption("underline")) != 2) { $underline = $undopt ? 'underline' : 'none'; $s .= "a { text-decoration: $underline; }\n"; } if( $wgUser->getOption( 'highlightbroken' ) ) { $s .= "a.new, #quickbar a.new { color: #CC2200; }\n"; } else { $s .= <<<ENDa.new, #quickbar a.new,a.stub, #quickbar a.stub { color: inherit; text-decoration: inherit;}a.new:after, #quickbar a.new:after { content: "?"; color: #CC2200; text-decoration: $underline;}a.stub:after, #quickbar a.stub:after { content: "!"; color: #772233; text-decoration: $underline;}END; } if( $wgUser->getOption( 'justify' ) ) { $s .= "#article, #bodyContent { text-align: justify; }\n"; } if( !$wgUser->getOption( 'showtoc' ) ) { $s .= "#toc { display: none; }\n"; } if( !$wgUser->getOption( 'editsection' ) ) { $s .= ".editsection { display: none; }\n"; } return $s; } function getBodyOptions() { global $wgUser, $wgTitle, $wgOut, $wgRequest; extract( $wgRequest->getValues( 'oldid', 'redirect', 'diff' ) ); if ( 0 != $wgTitle->getNamespace() ) { $a = array( 'bgcolor' => '#ffffec' ); } else $a = array( 'bgcolor' => '#FFFFFF' ); if($wgOut->isArticle() && $wgUser->getOption('editondblclick') && $wgTitle->userCanEdit() ) { $t = wfMsg( 'editthispage' ); $s = $wgTitle->getFullURL( $this->editUrlOptions() ); $s = 'document.location = "' .wfEscapeJSString( $s ) .'";'; $a += array ('ondblclick' => $s); } $a['onload'] = $wgOut->getOnloadHandler(); if( $wgUser->getOption( 'editsectiononrightclick' ) ) { if( $a['onload'] != '' ) { $a['onload'] .= ';'; } $a['onload'] .= 'setupRightClickEdit()'; } return $a; } /** * URL to the logo */ function getLogo() { global $wgLogo; return $wgLogo; } /** * This will be called immediately after the <body> tag. Split into * two functions to make it easier to subclass. */ function beforeContent() { return $this->doBeforeContent(); } function doBeforeContent() { global $wgContLang; $fname = 'Skin::doBeforeContent'; wfProfileIn( $fname ); $s = ''; $qb = $this->qbSetting(); if( $langlinks = $this->otherLanguages() ) { $rows = 2; $borderhack = ''; } else { $rows = 1; $langlinks = false; $borderhack = 'class="top"'; } $s .= "\n<div id='content'>\n<div id='topbar'>\n" . "<table border='0' cellspacing='0' width='98%'>\n<tr>\n"; $shove = ($qb != 0); $left = ($qb == 1 || $qb == 3); if($wgContLang->isRTL()) $left = !$left; if ( !$shove ) { $s .= "<td class='top' align='left' valign='top' rowspan='{$rows}'>\n" . $this->logoText() . '</td>'; } elseif( $left ) { $s .= $this->getQuickbarCompensator( $rows ); } $l = $wgContLang->isRTL() ? 'right' : 'left'; $s .= "<td {$borderhack} align='$l' valign='top'>\n"; $s .= $this->topLinks() ; $s .= "<p class='subtitle'>" . $this->pageTitleLinks() . "</p>\n"; $r = $wgContLang->isRTL() ? "left" : "right"; $s .= "</td>\n<td {$borderhack} valign='top' align='$r' nowrap='nowrap'>"; $s .= $this->nameAndLogin(); $s .= "\n<br />" . $this->searchForm() . "</td>"; if ( $langlinks ) { $s .= "</tr>\n<tr>\n<td class='top' colspan=\"2\">$langlinks</td>\n"; } if ( $shove && !$left ) { # Right $s .= $this->getQuickbarCompensator( $rows ); } $s .= "</tr>\n</table>\n</div>\n"; $s .= "\n<div id='article'>\n"; $notice = wfGetSiteNotice(); if( $notice ) { $s .= "\n<div id='siteNotice'>$notice</div>\n"; } $s .= $this->pageTitle(); $s .= $this->pageSubtitle() ; $s .= $this->getCategories(); wfProfileOut( $fname ); return $s; }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?