From: Alexander Ebert Date: Wed, 8 Feb 2012 14:33:37 +0000 (+0100) Subject: Prototype for static includes X-Git-Tag: 2.0.0_Beta_1~1360^2~1 X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=beb8dc42f8e27dc909d9f3a9c958f03271640398;p=GitHub%2FWoltLab%2FWCF.git Prototype for static includes EXPERIMENTAL/crash-for-sure --- diff --git a/wcfsetup/install/files/lib/system/template/TemplateCompiler.class.php b/wcfsetup/install/files/lib/system/template/TemplateCompiler.class.php index 20e52a08cd..568e9ec31d 100644 --- a/wcfsetup/install/files/lib/system/template/TemplateCompiler.class.php +++ b/wcfsetup/install/files/lib/system/template/TemplateCompiler.class.php @@ -19,17 +19,24 @@ class TemplateCompiler extends TemplateScriptingCompiler { * @param string $templateName * @param string $sourceContent * @param string $compiledFilename + * @param array $metaData */ - public function compile($templateName, $sourceContent, $compiledFilename) { - // build fileheader - $compiledHeader = "v['tpl']['template'] = '".addcslashes($templateName, "'\\")."';\n?>\n"; + public function compile($templateName, $sourceContent, $compiledFilename, $metaData) { + // build fileheader for template + $compiledHeader = "v['tpl']['template'] = '".addcslashes($templateName, "'\\")."';\n?>\n"; // include plug-ins - $compiledContent = $this->compileString($templateName, $sourceContent); + $compiledContent = $this->compileString($templateName, $sourceContent, $metaData); - // write compiled to file + // write compiled template to file $file = new File($compiledFilename); - $file->write($compiledHeader.$compiledContent); + $file->write($compiledHeader.$compiledContent['template']); + $file->close(); + + // write meta data to file + $file = new File($metaData['filename']); + $file->write("\n"); + $file->write(serialize($compiledContent['meta'])); $file->close(); } diff --git a/wcfsetup/install/files/lib/system/template/TemplateEngine.class.php b/wcfsetup/install/files/lib/system/template/TemplateEngine.class.php index 441e6b201d..01436f5774 100644 --- a/wcfsetup/install/files/lib/system/template/TemplateEngine.class.php +++ b/wcfsetup/install/files/lib/system/template/TemplateEngine.class.php @@ -300,11 +300,17 @@ class TemplateEngine extends SingletonFactory { $tplPackageID = $this->getPackageID($templateName, $packageID); $compiledFilename = $this->getCompiledFilename($templateName, $packageID); $sourceFilename = $this->getSourceFilename($templateName, $tplPackageID); + $metaDataFilename = $this->getMetaDataFilename($templateName, $packageID); + $metaData = $this->getMetaData($templateName, $metaDataFilename); // check if compilation is necessary - if (!$this->isCompiled($templateName, $sourceFilename, $compiledFilename)) { + if (!$this->isCompiled($templateName, $sourceFilename, $compiledFilename, $metaData)) { // compile - $this->compileTemplate($templateName, $sourceFilename, $compiledFilename); + $this->compileTemplate($templateName, $sourceFilename, $compiledFilename, array( + 'data' => $metaData, + 'filename' => $metaDataFilename, + 'packageID' => $packageID + )); } // assign current package id @@ -325,7 +331,7 @@ class TemplateEngine extends SingletonFactory { * @param integer $packageID * @return integer */ - protected function getPackageID($templateName, $packageID) { + public function getPackageID($templateName, $packageID) { if ($packageID != 1 && isset($this->templatePaths[$packageID])) { $path = $this->getPath($this->templatePaths[$packageID], $templateName); @@ -389,22 +395,33 @@ class TemplateEngine extends SingletonFactory { * Returns the absolute filename of a compiled template. * * @param string $templateName - * @return string $path + * @param integer $packageID */ public function getCompiledFilename($templateName, $packageID) { return $this->compileDir.$packageID.'_'.$this->templateGroupID.'_'.$this->languageID.'_'.$templateName.'.php'; } + /** + * Returns the absolute filename for template's meta data. + * + * @param string $templateName + * @param integer $packageID + */ + public function getMetaDataFilename($templateName, $packageID) { + return $this->compileDir.$packageID.'_'.$this->templateGroupID.'_'.$templateName.'.meta.php'; + } + /** * Checks wheater a template is already compiled or not. * * @param string $templateName * @param string $sourceFilename * @param string $compiledFilename + * @param array $metaData * @return boolean $isCompiled */ - protected function isCompiled($templateName, $sourceFilename, $compiledFilename) { - if ($this->forceCompile || !file_exists($compiledFilename)) { + protected function isCompiled($templateName, $sourceFilename, $compiledFilename, array $metaData) { + if ($this->forceCompile || !file_exists($compiledFilename) || !file_exists($metaDataFilename)) { return false; } else { @@ -415,6 +432,18 @@ class TemplateEngine extends SingletonFactory { return false; } else { + // check for meta data + if (!empty($metaData['include'])) { + foreach ($metaData['include'] as $template) { + $includedTemplateFilename = $this->getSourceFilename($template['templateName'], $packageID); + $includedMTime = @filemtime($includedTemplateFilename); + + if ($includedMTime >= $compileMTime) { + return false; + } + } + } + // check for template listeners if ($this->hasTemplateListeners($templateName)) { $this->loadTemplateListenerCode($templateName); @@ -436,8 +465,9 @@ class TemplateEngine extends SingletonFactory { * @param string $templateName * @param string $sourceFilename * @param string $compiledFilename + * @param array $metaData */ - protected function compileTemplate($templateName, $sourceFilename, $compiledFilename) { + protected function compileTemplate($templateName, $sourceFilename, $compiledFilename, array $metaData) { // get compiler if (!($this->compilerObj instanceof TemplateCompiler)) { $this->compilerObj = $this->getCompiler(); @@ -447,7 +477,7 @@ class TemplateEngine extends SingletonFactory { $sourceContent = $this->getSourceContent($sourceFilename); // compile template - $this->compilerObj->compile($templateName, $sourceContent, $compiledFilename); + $this->compilerObj->compile($templateName, $sourceContent, $compiledFilename, $metaData); } /** @@ -761,4 +791,35 @@ class TemplateEngine extends SingletonFactory { return ''; } + + /** + * Reads meta data from file. + * + * @param string $templateName + * @param string $filename + * @return array + */ + protected function getMetaData($templateName, $filename) { + if (!file_exists($filename) || !is_readable($filename)) { + return null; + } + + // get file contents + $contents = file_get_contents($filename); + + // find first newline + $position = strpos($contents, "\n"); + if ($position === false) throw new SystemException("Unable to load meta data for template '".$templateName."'"); + + // cut contents + $contents = substr($contents, $position + 1); + + // read serializes data + $data = @unserialize($contents); + if ($data === false || !is_array($data)) { + throw new SystemException("Invalid meta data for template '".$templateName."'"); + } + + return $data; + } } diff --git a/wcfsetup/install/files/lib/system/template/TemplateScriptingCompiler.class.php b/wcfsetup/install/files/lib/system/template/TemplateScriptingCompiler.class.php index a2ac07cc77..d71a8aa7e0 100644 --- a/wcfsetup/install/files/lib/system/template/TemplateScriptingCompiler.class.php +++ b/wcfsetup/install/files/lib/system/template/TemplateScriptingCompiler.class.php @@ -3,6 +3,7 @@ namespace wcf\system\template; use wcf\system\exception\SystemException; use wcf\system\template\plugin\ICompilerTemplatePlugin; use wcf\system\template\plugin\IPrefilterTemplatePlugin; +use wcf\system\WCF; use wcf\util\StringStack; use wcf\util\StringUtil; @@ -187,9 +188,10 @@ class TemplateScriptingCompiler { * * @param string $identifier * @param string $sourceContent + * @param array $metaData * @return string */ - public function compileString($identifier, $sourceContent) { + public function compileString($identifier, $sourceContent, array $metaData = array()) { // reset vars $this->autoloadPlugins = $this->tagStack = $this->stringStack = $this->literalStack = array(); $this->currentIdentifier = $identifier; @@ -219,7 +221,7 @@ class TemplateScriptingCompiler { $compiledTags = array(); for ($i = 0, $j = count($templateTags); $i < $j; $i++) { $this->currentLineNo += StringUtil::countSubstring($textBlocks[$i], "\n"); - $compiledTags[] = $this->compileTag($templateTags[$i]); + $compiledTags[] = $this->compileTag($templateTags[$i], $metaData); $this->currentLineNo += StringUtil::countSubstring($templateTags[$i], "\n"); } @@ -252,17 +254,9 @@ class TemplateScriptingCompiler { $compiledAutoloadPlugins = ''; if (count($this->autoloadPlugins) > 0) { $compiledAutoloadPlugins = "autoloadPlugins as $className/* => $fileName*/) { + foreach ($this->autoloadPlugins as $className) { $compiledAutoloadPlugins .= "use ".$className.";\n"; $compiledAutoloadPlugins .= "if (!isset(\$this->pluginObjects['$className'])) {\n"; - /* - if (WCF_DIR != '' && strpos($fileName, WCF_DIR) === 0) { - $compiledAutoloadPlugins .= "require_once(WCF_DIR.'".StringUtil::replace(WCF_DIR, '', $fileName)."');\n"; - } - else { - $compiledAutoloadPlugins .= "require_once('".$fileName."');\n"; - } - */ $compiledAutoloadPlugins .= "\$this->pluginObjects['$className'] = new $className;\n"; $compiledAutoloadPlugins .= "}\n"; } @@ -276,8 +270,9 @@ class TemplateScriptingCompiler { * Compiles a template tag. * * @param string $tag + * @param array $metaData */ - protected function compileTag($tag) { + protected function compileTag($tag, array &$metaData) { if (preg_match('~^'.$this->outputPattern.'~s', $tag)) { // variable output return $this->compileOutputTag($tag); @@ -324,7 +319,7 @@ class TemplateScriptingCompiler { return ''; case 'include': - return $this->compileIncludeTag($tagArgs); + return $this->compileIncludeTag($tagArgs, $metaData); case 'foreach': $this->pushTag('foreach'); @@ -681,9 +676,10 @@ class TemplateScriptingCompiler { * Compiles an include tag. * * @param string $includeTag - * @return string phpCode + * @param array $metaData + * @return string phpCode */ - protected function compileIncludeTag($includeTag) { + protected function compileIncludeTag($includeTag, array &$metaData) { $args = $this->parseTagArgs($includeTag, 'include'); $append = false; @@ -721,6 +717,12 @@ class TemplateScriptingCompiler { unset($args['once']); } + // check for static includes + if ($sandbox === false && $assignVar === false && $once === false) { + $content = WCF::getTPL()->fetch($file, array(), false, $metaData['packageID']); + return $metaData; + } + // make argument string $argString = $this->makeArgString($args);