/** * @param string $identifier * @param \TYPO3\CMS\Fluid\Core\Parser\ParsingState $parsingState * @return void */ public function store($identifier, \TYPO3\CMS\Fluid\Core\Parser\ParsingState $parsingState) { $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\\CMS\\Fluid\\Core\\Compiler\\AbstractCompiledTemplate'; $templateCode = <<<EOD %s { public function getVariableContainer() { \t// @todo \treturn new \\TYPO3\\CMS\\Fluid\\Core\\ViewHelper\\TemplateVariableContainer(); } public function getLayoutName(\\TYPO3\\CMS\\Fluid\\Core\\Rendering\\RenderingContextInterface \$renderingContext) { \$currentVariableContainer = \$renderingContext->getTemplateVariableContainer(); %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); }
/** * Initialize the given ViewHelper and adds it to the current node and to * the stack. * * @param \TYPO3\CMS\Fluid\Core\Parser\ParsingState $state Current parsing state * @param string $namespaceIdentifier Namespace identifier - being looked up in $this->namespaces * @param string $methodIdentifier Method identifier * @param array $argumentsObjectTree Arguments object tree * @return void * @throws \TYPO3\CMS\Fluid\Core\Parser\Exception */ protected function initializeViewHelperAndAddItToStack(\TYPO3\CMS\Fluid\Core\Parser\ParsingState $state, $namespaceIdentifier, $methodIdentifier, $argumentsObjectTree) { if (!array_key_exists($namespaceIdentifier, $this->namespaces)) { throw new \TYPO3\CMS\Fluid\Core\Parser\Exception('Namespace could not be resolved. This exception should never be thrown!', 1224254792); } $viewHelper = $this->objectManager->get($this->resolveViewHelperName($namespaceIdentifier, $methodIdentifier)); $this->viewHelperNameToImplementationClassNameRuntimeCache[$namespaceIdentifier][$methodIdentifier] = get_class($viewHelper); // The following three checks are only done *in an uncached template*, and not needed anymore in the cached version $expectedViewHelperArguments = $viewHelper->prepareArguments(); $this->abortIfUnregisteredArgumentsExist($expectedViewHelperArguments, $argumentsObjectTree); $this->abortIfRequiredArgumentsAreMissing($expectedViewHelperArguments, $argumentsObjectTree); $this->rewriteBooleanNodesInArgumentsObjectTree($expectedViewHelperArguments, $argumentsObjectTree); $currentViewHelperNode = $this->objectManager->get(\TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\ViewHelperNode::class, $viewHelper, $argumentsObjectTree); $state->getNodeFromStack()->addChildNode($currentViewHelperNode); if ($viewHelper instanceof \TYPO3\CMS\Fluid\Core\ViewHelper\Facets\ChildNodeAccessInterface && !$viewHelper instanceof \TYPO3\CMS\Fluid\Core\ViewHelper\Facets\CompilableInterface) { $state->setCompilable(false); } // PostParse Facet if ($viewHelper instanceof \TYPO3\CMS\Fluid\Core\ViewHelper\Facets\PostParseInterface) { $viewHelper::postParseEvent($currentViewHelperNode, $argumentsObjectTree, $state->getVariableContainer()); } $this->callInterceptor($currentViewHelperNode, \TYPO3\CMS\Fluid\Core\Parser\InterceptorInterface::INTERCEPT_OPENING_VIEWHELPER, $state); $state->pushNodeToStack($currentViewHelperNode); }
/** * Initialize the given ViewHelper and adds it to the current node and to * the stack. * * @param ParsingState $state Current parsing state * @param string $namespaceIdentifier Namespace identifier - being looked up in $this->namespaces * @param string $methodIdentifier Method identifier * @param array $argumentsObjectTree Arguments object tree * @return void * @throws Exception */ protected function initializeViewHelperAndAddItToStack(ParsingState $state, $namespaceIdentifier, $methodIdentifier, $argumentsObjectTree) { if (!array_key_exists($namespaceIdentifier, $this->namespaces)) { throw new Exception('Namespace could not be resolved. This exception should never be thrown!', 1224254792); } $viewHelper = $this->objectManager->get($this->resolveViewHelperName($namespaceIdentifier, $methodIdentifier)); $this->viewHelperNameToImplementationClassNameRuntimeCache[$namespaceIdentifier][$methodIdentifier] = get_class($viewHelper); // Following three checks are only done *in an uncached template*, and not needed anymore in the cached version $expectedViewHelperArguments = $viewHelper->prepareArguments(); $this->abortIfUnregisteredArgumentsExist($expectedViewHelperArguments, $argumentsObjectTree); $this->abortIfRequiredArgumentsAreMissing($expectedViewHelperArguments, $argumentsObjectTree); $this->rewriteBooleanNodesInArgumentsObjectTree($expectedViewHelperArguments, $argumentsObjectTree); /** @var ViewHelperNode $currentViewHelperNode */ $currentViewHelperNode = $this->objectManager->get(ViewHelperNode::class, $viewHelper, $argumentsObjectTree); $state->getNodeFromStack()->addChildNode($currentViewHelperNode); if ($viewHelper instanceof ChildNodeAccessInterface && !$viewHelper instanceof CompilableInterface) { $state->setCompilable(false); } // PostParse Facet if ($viewHelper instanceof PostParseInterface) { // Don't just use $viewHelper::postParseEvent(...), // as this will break with PHP < 5.3. // @TODO: replace with static call; no more php <5.3 support required call_user_func([$viewHelper, 'postParseEvent'], $currentViewHelperNode, $argumentsObjectTree, $state->getVariableContainer()); } $this->callInterceptor($currentViewHelperNode, InterceptorInterface::INTERCEPT_OPENING_VIEWHELPER, $state); $state->pushNodeToStack($currentViewHelperNode); $this->viewHelpersUsed[] = ['namespace' => $namespaceIdentifier, 'viewhelper' => $methodIdentifier]; }