monobookcbt.php
来自「php 开发的内容管理系统」· PHP 代码 · 共 1,391 行 · 第 1/3 页
PHP
1,391 行
<?phpif ( !defined( 'MEDIAWIKI' ) ) { die( "This file is part of MediaWiki, it is not a valid entry point\n" );}require_once( 'includes/cbt/CBTProcessor.php' );require_once( 'includes/cbt/CBTCompiler.php' );require_once( 'includes/SkinTemplate.php' );/** * MonoBook clone using the new dependency-tracking template processor. * EXPERIMENTAL - use only for testing and profiling at this stage. * * See includes/cbt/README for an explanation. * * The main thing that's missing is cache invalidation, on change of: * * messages * * user preferences * * source template * * source code and configuration files * * The other thing is that lots of dependencies that are declared in the callbacks * are not intelligently handled. There's some room for improvement there. * * The class is derived from SkinTemplate, but that's only temporary. Eventually * it'll be derived from Skin, and I've avoided using SkinTemplate functions as * much as possible. In fact, the only SkinTemplate dependencies I know of at the * moment are the functions to generate the gen=css and gen=js files. * */class SkinMonoBookCBT extends SkinTemplate { var $mOut, $mTitle; var $mStyleName = 'monobook'; var $mCompiling = false; var $mFunctionCache = array(); /****************************************************** * General functions * ******************************************************/ /** Execute the template and write out the result */ function outputPage( &$out ) { echo $this->execute( $out ); } function execute( &$out ) { global $wgTitle, $wgStyleDirectory, $wgParserCacheType; $fname = 'SkinMonoBookCBT::execute'; wfProfileIn( $fname ); wfProfileIn( "$fname-setup" ); Skin::initPage( $out ); $this->mOut =& $out; $this->mTitle =& $wgTitle; $sourceFile = "$wgStyleDirectory/MonoBook.tpl"; wfProfileOut( "$fname-setup" ); if ( $wgParserCacheType == CACHE_NONE ) { $template = file_get_contents( $sourceFile ); $text = $this->executeTemplate( $template ); } else { $compiled = $this->getCompiledTemplate( $sourceFile ); wfProfileIn( "$fname-eval" ); $text = eval( $compiled ); wfProfileOut( "$fname-eval" ); } wfProfileOut( $fname ); return $text; } function getCompiledTemplate( $sourceFile ) { global $wgDBname, $wgMemc, $wgRequest, $wgUser, $parserMemc; $fname = 'SkinMonoBookCBT::getCompiledTemplate'; $expiry = 3600; // Sandbox template execution if ( $this->mCompiling ) { return; } wfProfileIn( $fname ); // Is the request an ordinary page view? if ( $wgRequest->wasPosted() || count( array_diff( array_keys( $_GET ), array( 'title', 'useskin', 'recompile' ) ) ) != 0 ) { $type = 'nonview'; } else { $type = 'view'; } // Per-user compiled template // Put all logged-out users on the same cache key $cacheKey = "$wgDBname:monobookcbt:$type:" . $wgUser->getId(); $recompile = $wgRequest->getVal( 'recompile' ); if ( $recompile == 'user' ) { $recompileUser = true; $recompileGeneric = false; } elseif ( $recompile ) { $recompileUser = true; $recompileGeneric = true; } else { $recompileUser = false; $recompileGeneric = false; } if ( !$recompileUser ) { $php = $parserMemc->get( $cacheKey ); } if ( $recompileUser || !$php ) { if ( $wgUser->isLoggedIn() ) { // Perform staged compilation // First compile a generic template for all logged-in users $genericKey = "$wgDBname:monobookcbt:$type:loggedin"; if ( !$recompileGeneric ) { $template = $parserMemc->get( $genericKey ); } if ( $recompileGeneric || !$template ) { $template = file_get_contents( $sourceFile ); $ignore = array( 'loggedin', '!loggedin dynamic' ); if ( $type == 'view' ) { $ignore[] = 'nonview dynamic'; } $template = $this->compileTemplate( $template, $ignore ); $parserMemc->set( $genericKey, $template, $expiry ); } } else { $template = file_get_contents( $sourceFile ); } $ignore = array( 'lang', 'loggedin', 'user' ); if ( $wgUser->isLoggedIn() ) { $ignore[] = '!loggedin dynamic'; } else { $ignore[] = 'loggedin dynamic'; } if ( $type == 'view' ) { $ignore[] = 'nonview dynamic'; } $compiled = $this->compileTemplate( $template, $ignore ); // Reduce whitespace // This is done here instead of in CBTProcessor because we can be // more sure it is safe here. $compiled = preg_replace( '/^[ \t]+/m', '', $compiled ); $compiled = preg_replace( '/[\r\n]+/', "\n", $compiled ); // Compile to PHP $compiler = new CBTCompiler( $compiled ); $ret = $compiler->compile(); if ( $ret !== true ) { echo $ret; wfErrorExit(); } $php = $compiler->generatePHP( '$this' ); $parserMemc->set( $cacheKey, $php, $expiry ); } wfProfileOut( $fname ); return $php; } function compileTemplate( $template, $ignore ) { $tp = new CBTProcessor( $template, $this, $ignore ); $tp->mFunctionCache = $this->mFunctionCache; $this->mCompiling = true; $compiled = $tp->compile(); $this->mCompiling = false; if ( $tp->getLastError() ) { // If there was a compile error, don't save the template // Instead just print the error and exit echo $compiled; wfErrorExit(); } $this->mFunctionCache = $tp->mFunctionCache; return $compiled; } function executeTemplate( $template ) { $fname = 'SkinMonoBookCBT::executeTemplate'; wfProfileIn( $fname ); $tp = new CBTProcessor( $template, $this ); $tp->mFunctionCache = $this->mFunctionCache; $this->mCompiling = true; $text = $tp->execute(); $this->mCompiling = false; $this->mFunctionCache = $tp->mFunctionCache; wfProfileOut( $fname ); return $text; } /****************************************************** * Callbacks * ******************************************************/ function lang() { return $GLOBALS['wgContLanguageCode']; } function dir() { global $wgContLang; return $wgContLang->isRTL() ? 'rtl' : 'ltr'; } function mimetype() { return $GLOBALS['wgMimeType']; } function charset() { return $GLOBALS['wgOutputEncoding']; } function headlinks() { return cbt_value( $this->mOut->getHeadLinks(), 'dynamic' ); } function headscripts() { return cbt_value( $this->mOut->getScript(), 'dynamic' ); } function pagetitle() { return cbt_value( $this->mOut->getHTMLTitle(), array( 'title', 'lang' ) ); } function stylepath() { return $GLOBALS['wgStylePath']; } function stylename() { return $this->mStyleName; } function notprintable() { global $wgRequest; return cbt_value( !$wgRequest->getBool( 'printable' ), 'nonview dynamic' ); } function jsmimetype() { return $GLOBALS['wgJsMimeType']; } function jsvarurl() { global $wgUseSiteJs, $wgUser; if ( !$wgUseSiteJs ) return ''; if ( $wgUser->isLoggedIn() ) { $url = $this->makeUrl('-','action=raw&smaxage=0&gen=js'); } else { $url = $this->makeUrl('-','action=raw&gen=js'); } return cbt_value( $url, 'loggedin' ); } function pagecss() { global $wgHooks; $out = false; wfRunHooks( 'SkinTemplateSetupPageCss', array( &$out ) ); // Unknown dependencies return cbt_value( $out, 'dynamic' ); } function usercss() { if ( $this->isCssPreview() ) { global $wgRequest; $usercss = $this->makeStylesheetCdata( $wgRequest->getText('wpTextbox1') ); } else { $usercss = $this->makeStylesheetLink( $this->makeUrl($this->getUserPageText() . '/'.$this->mStyleName.'.css', 'action=raw&ctype=text/css' ) ); } // Dynamic when not an ordinary page view, also depends on the username return cbt_value( $usercss, array( 'nonview dynamic', 'user' ) ); } function sitecss() { global $wgUseSiteCss; if ( !$wgUseSiteCss ) { return ''; } global $wgSquidMaxage, $wgContLang, $wgStylePath; $query = "action=raw&ctype=text/css&smaxage=$wgSquidMaxage"; $sitecss = ''; if ( $wgContLang->isRTL() ) { $sitecss .= $this->makeStylesheetLink( $wgStylePath . '/' . $this->mStyleName . '/rtl.css' ) . "\n"; } $sitecss .= $this->makeStylesheetLink( $this->makeNSUrl('Common.css', $query, NS_MEDIAWIKI) ) . "\n"; $sitecss .= $this->makeStylesheetLink( $this->makeNSUrl( ucfirst($this->mStyleName) . '.css', $query, NS_MEDIAWIKI) ) . "\n"; // No deps return $sitecss; } function gencss() { global $wgUseSiteCss; if ( !$wgUseSiteCss ) return ''; global $wgSquidMaxage, $wgUser, $wgAllowUserCss; if ( $this->isCssPreview() ) { $siteargs = '&smaxage=0&maxage=0'; } else { $siteargs = '&maxage=' . $wgSquidMaxage; } if ( $wgAllowUserCss && $wgUser->isLoggedIn() ) { $siteargs .= '&ts={user_touched}'; $isTemplate = true; } else { $isTemplate = false; } $link = $this->makeStylesheetLink( $this->makeUrl('-','action=raw&gen=css' . $siteargs) ) . "\n"; if ( $wgAllowUserCss ) { $deps = 'loggedin'; } else { $deps = array(); } return cbt_value( $link, $deps, $isTemplate ); } function user_touched() { global $wgUser; return cbt_value( $wgUser->mTouched, 'dynamic' ); } function userjs() { global $wgAllowUserJs, $wgJsMimeType; if ( !$wgAllowUserJs ) return ''; if ( $this->isJsPreview() ) { $url = ''; } else { $url = $this->makeUrl($this->getUserPageText().'/'.$this->mStyleName.'.js', 'action=raw&ctype='.$wgJsMimeType.'&dontcountme=s'); } return cbt_value( $url, array( 'nonview dynamic', 'user' ) ); } function userjsprev() { global $wgAllowUserJs, $wgRequest; if ( !$wgAllowUserJs ) return ''; if ( $this->isJsPreview() ) { $js = '/*<![CDATA[*/ ' . $wgRequest->getText('wpTextbox1') . ' /*]]>*/'; } else { $js = ''; } return cbt_value( $js, array( 'nonview dynamic' ) ); } function trackbackhtml() { global $wgUseTrackbacks; if ( !$wgUseTrackbacks ) return ''; if ( $this->mOut->isArticleRelated() ) { $tb = $this->mTitle->trackbackRDF(); } else { $tb = ''; } return cbt_value( $tb, 'dynamic' ); } function body_ondblclick() { global $wgUser; if( $this->isEditable() && $wgUser->getOption("editondblclick") ) { $js = 'document.location = "' . $this->getEditUrl() .'";'; } else { $js = ''; } if ( User::getDefaultOption('editondblclick') ) { return cbt_value( $js, 'user', 'title' ); } else { // Optimise away for logged-out users return cbt_value( $js, 'loggedin dynamic' ); } } function body_onload() { global $wgUser; if ( $this->isEditable() && $wgUser->getOption( 'editsectiononrightclick' ) ) { $js = 'setupRightClickEdit()'; } else { $js = ''; } return cbt_value( $js, 'loggedin dynamic' ); } function nsclass() { return cbt_value( 'ns-' . $this->mTitle->getNamespace(), 'title' ); } function sitenotice() { // Perhaps this could be given special dependencies using our knowledge of what // wfGetSiteNotice() depends on. return cbt_value( wfGetSiteNotice(), 'dynamic' ); } function title() { return cbt_value( $this->mOut->getPageTitle(), array( 'title', 'lang' ) ); } function title_urlform() { return cbt_value( $this->getThisTitleUrlForm(), 'title' ); } function title_userurl() { return cbt_value( urlencode( $this->mTitle->getDBkey() ), 'title' ); } function subtitle() { $subpagestr = $this->subPageSubtitle(); if ( !empty( $subpagestr ) ) { $s = '<span class="subpages">'.$subpagestr.'</span>'.$this->mOut->getSubtitle(); } else { $s = $this->mOut->getSubtitle(); } return cbt_value( $s, array( 'title', 'nonview dynamic' ) ); } function undelete() { return cbt_value( $this->getUndeleteLink(), array( 'title', 'lang' ) ); } function newtalk() { global $wgUser, $wgDBname; $newtalks = $wgUser->getNewMessageLinks(); if (count($newtalks) == 1 && $newtalks[0]["wiki"] === $wgDBname) { $usertitle = $this->getUserPageTitle(); $usertalktitle = $usertitle->getTalkPage(); if( !$usertalktitle->equals( $this->mTitle ) ) { $ntl = wfMsg( 'youhavenewmessages', $this->makeKnownLinkObj( $usertalktitle, wfMsgHtml( 'newmessageslink' ), 'redirect=no' ), $this->makeKnownLinkObj( $usertalktitle, wfMsgHtml( 'newmessagesdifflink' ), 'diff=cur' ) ); # Disable Cache $this->mOut->setSquidMaxage(0); } } else if (count($newtalks)) { $sep = str_replace("_", " ", wfMsgHtml("newtalkseperator")); $msgs = array(); foreach ($newtalks as $newtalk) { $msgs[] = wfElement("a", array('href' => $newtalk["link"]), $newtalk["wiki"]); } $parts = implode($sep, $msgs); $ntl = wfMsgHtml('youhavenewmessagesmulti', $parts); $this->mOut->setSquidMaxage(0); } else { $ntl = ''; } return cbt_value( $ntl, 'dynamic' ); } function showjumplinks() { global $wgUser; return cbt_value( $wgUser->getOption( 'showjumplinks' ) ? 'true' : '', 'user' );
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?