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 + -
显示快捷键?