/** * Shutdown the Evaluator and save created expressions overwriting any existing expressions * * @return void */ public function shutdownObject() { if ($this->newExpressions === array()) { return; } $codeToBeCached = 'return array (' . chr(10); foreach ($this->newExpressions as $name => $function) { $codeToBeCached .= "'" . $name . "' => " . $function . ',' . chr(10); } $codeToBeCached .= ');'; $this->runtimeExpressionsCache->set('Flow_Aop_RuntimeExpressions', $codeToBeCached); }
/** * Shutdown the Evaluator */ public function shutdownObject() { if (count($this->newExpressions) > 0) { $changesToPersist = FALSE; $codeToBeCached = $this->expressionCache->get('cachedExpressionClosures'); /** * At this point a race condition could happen, that we try to prevent with an additional check. * So we compare the evaluated expressions during this request with the methods the cache has at * this point and only add methods that are not present. Only if we added anything we write the cache. */ foreach ($this->newExpressions as $functionName => $newExpression) { if (strpos($codeToBeCached, $functionName) === FALSE) { $codeToBeCached .= $newExpression . chr(10); $changesToPersist = TRUE; } } if ($changesToPersist) { $this->expressionCache->set('cachedExpressionClosures', $codeToBeCached); } } }
/** * Reads the specified class file, appends ORIGINAL_CLASSNAME_SUFFIX to its * class name and stores the result in the proxy classes cache. * * @param string $className Short class name of the class to copy * @param string $pathAndFilename Full path and filename of the original class file * @param string $proxyClassCode The code that makes up the proxy class * @return void * * @throws Exception If the original class filename doesn't match the actual class name inside the file. */ protected function cacheOriginalClassFileAndProxyCode($className, $pathAndFilename, $proxyClassCode) { $classCode = file_get_contents($pathAndFilename); $classCode = preg_replace('/^<\\?php.*\\n/', '', $classCode); $classNameSuffix = self::ORIGINAL_CLASSNAME_SUFFIX; $classCode = preg_replace_callback('/^([a-z ]*)(interface|class)\\s+([a-zA-Z0-9_]+)/m', function ($matches) use($pathAndFilename, $classNameSuffix) { $classNameAccordingToFileName = basename($pathAndFilename, '.php'); if ($matches[3] !== $classNameAccordingToFileName) { throw new Exception('The name of the class "' . $matches[3] . '" is not the same as the filename which is "' . basename($pathAndFilename) . '". Path: ' . $pathAndFilename, 1398356897); } return $matches[1] . $matches[2] . ' ' . $matches[3] . $classNameSuffix; }, $classCode); $classCode = preg_replace('/\\?>[\\n\\s\\r]*$/', '', $classCode); $this->classesCache->set(str_replace('\\', '_', $className), $classCode . $proxyClassCode); }
/** * @param string $identifier * @param ParsingState $parsingState * @return void */ public function store($identifier, ParsingState $parsingState) { if (!$this->templateCache instanceof FrontendInterface) { return; } $identifier = $this->sanitizeIdentifier($identifier); $this->variableCounter = 0; $generatedRenderFunctions = ''; if ($parsingState->getVariableContainer()->exists('sections')) { $sections = $parsingState->getVariableContainer()->get('sections'); // TODO: refactor to $parsedTemplate->getSections() foreach ($sections as $sectionName => $sectionRootNode) { $generatedRenderFunctions .= $this->generateCodeForSection($this->convertListOfSubNodes($sectionRootNode), 'section_' . sha1($sectionName), 'section ' . $sectionName); } } $generatedRenderFunctions .= $this->generateCodeForSection($this->convertListOfSubNodes($parsingState->getRootNode()), 'render', 'Main Render function'); $convertedLayoutNameNode = $parsingState->hasLayout() ? $this->convert($parsingState->getLayoutNameNode()) : array('initialization' => '', 'execution' => 'NULL'); $classDefinition = 'class FluidCache_' . $identifier . ' extends \\TYPO3\\Fluid\\Core\\Compiler\\AbstractCompiledTemplate'; $templateCode = <<<EOD %s { public function getVariableContainer() { \t// TODO \treturn new \\TYPO3\\Fluid\\Core\\ViewHelper\\TemplateVariableContainer(); } public function getLayoutName(\\TYPO3\\Fluid\\Core\\Rendering\\RenderingContextInterface \$renderingContext) { \$self = \$this; %s return %s; } public function hasLayout() { return %s; } %s } EOD; $templateCode = sprintf($templateCode, $classDefinition, $convertedLayoutNameNode['initialization'], $convertedLayoutNameNode['execution'], $parsingState->hasLayout() ? 'TRUE' : 'FALSE', $generatedRenderFunctions); $this->templateCache->set($identifier, $templateCode); }