Пример #1
0
 /**
  * Compiles the ExpressionNode, returning an array with
  * exactly two keys which contain strings:
  *
  * - "initialization" which contains variable initializations
  * - "execution" which contains the execution (that uses the variables)
  *
  * The expression and matches can be read from the local
  * instance - and the RenderingContext and other APIs
  * can be accessed via the TemplateCompiler.
  *
  * @param TemplateCompiler $templateCompiler
  * @return array
  */
 public function compile(TemplateCompiler $templateCompiler)
 {
     $handlerClass = get_class($this);
     $expressionVariable = $templateCompiler->variableName('string');
     $matchesVariable = $templateCompiler->variableName('array');
     $initializationPhpCode = sprintf('// Rendering %s node' . chr(10), $handlerClass);
     $initializationPhpCode .= sprintf('%s = \'%s\';', $expressionVariable, $this->getExpression()) . chr(10);
     $initializationPhpCode .= sprintf('%s = %s;', $matchesVariable, var_export($this->getMatches(), true)) . chr(10);
     return ['initialization' => $initializationPhpCode, 'execution' => sprintf('\\%s::evaluateExpression($renderingContext, %s, %s)', $handlerClass, $expressionVariable, $matchesVariable)];
 }
Пример #2
0
 /**
  * Convert a single ViewHelperNode into its cached representation. If the ViewHelper implements the "Compilable" facet,
  * the ViewHelper itself is asked for its cached PHP code representation. If not, a ViewHelper is built and then invoked.
  *
  * @param ViewHelperNode $node
  * @return array
  * @see convert()
  */
 protected function convertViewHelperNode(ViewHelperNode $node)
 {
     $initializationPhpCode = '// Rendering ViewHelper ' . $node->getViewHelperClassName() . chr(10);
     // Build up $arguments array
     $argumentsVariableName = $this->variableName('arguments');
     $initializationPhpCode .= sprintf('%s = array();', $argumentsVariableName) . chr(10);
     $alreadyBuiltArguments = array();
     foreach ($node->getArguments() as $argumentName => $argumentValue) {
         if ($argumentValue instanceof NodeInterface) {
             $converted = $this->convert($argumentValue);
         } else {
             $converted = array('initialization' => '', 'execution' => $argumentValue);
         }
         $initializationPhpCode .= $converted['initialization'];
         $initializationPhpCode .= sprintf('%s[\'%s\'] = %s;', $argumentsVariableName, $argumentName, $converted['execution']) . chr(10);
         $alreadyBuiltArguments[$argumentName] = TRUE;
     }
     $arguments = $node->getArgumentDefinitions();
     foreach ($arguments as $argumentName => $argumentDefinition) {
         if (!isset($alreadyBuiltArguments[$argumentName])) {
             $initializationPhpCode .= sprintf('%s[\'%s\'] = %s;', $argumentsVariableName, $argumentName, var_export($argumentDefinition->getDefaultValue(), TRUE)) . chr(10);
         }
     }
     // Build up closure which renders the child nodes
     $renderChildrenClosureVariableName = $this->variableName('renderChildrenClosure');
     $initializationPhpCode .= sprintf('%s = %s;', $renderChildrenClosureVariableName, $this->templateCompiler->wrapChildNodesInClosure($node)) . chr(10);
     $viewHelperInitializationPhpCode = '';
     $convertedViewHelperExecutionCode = $node->getUninitializedViewHelper()->compile($argumentsVariableName, $renderChildrenClosureVariableName, $viewHelperInitializationPhpCode, $node, $this->templateCompiler);
     $initializationPhpCode .= $viewHelperInitializationPhpCode;
     $initializationArray = array('initialization' => $initializationPhpCode, 'execution' => $convertedViewHelperExecutionCode === NULL ? 'NULL' : $convertedViewHelperExecutionCode);
     return $initializationArray;
 }
Пример #3
0
 /**
  * @param string $templateIdentifier
  * @param \Closure $templateSourceClosure Closure which returns the template source if needed
  * @return ParsedTemplateInterface
  */
 protected function getOrParseAndStoreTemplate($templateIdentifier, $templateSourceClosure)
 {
     if ($this->templateCompiler->has($templateIdentifier)) {
         $parsedTemplate = $this->templateCompiler->get($templateIdentifier);
     } else {
         $parsedTemplate = $this->templateParser->parse($templateSourceClosure($this, $this->templatePaths));
         if ($parsedTemplate->isCompilable()) {
             $this->templateCompiler->store($templateIdentifier, $parsedTemplate);
         }
     }
     return $parsedTemplate;
 }
 /**
  * This ViewHelper is used a *lot* because it is used by the escape interceptor.
  * Therefore we render it to raw PHP code during compilation
  *
  * @param string $argumentsName
  * @param string $closureName
  * @param string $initializationPhpCode
  * @param ViewHelperNode $node
  * @param TemplateCompiler $compiler
  * @return string
  */
 public function compile($argumentsName, $closureName, &$initializationPhpCode, ViewHelperNode $node, TemplateCompiler $compiler)
 {
     $valueVariableName = $compiler->variableName('value');
     $initializationPhpCode .= sprintf('%1$s = (%2$s[\'value\'] !== NULL ? %2$s[\'value\'] : %3$s());', $valueVariableName, $argumentsName, $closureName) . chr(10);
     return sprintf('!is_string(%1$s) && !(is_object(%1$s) && method_exists(%1$s, \'__toString\')) ? %1$s : htmlspecialchars(%1$s, (%2$s[\'keepQuotes\'] ? ENT_NOQUOTES : ENT_QUOTES), %2$s[\'encoding\'], %2$s[\'doubleEncode\'])', $valueVariableName, $argumentsName);
 }
 /**
  * @param string $argumentsName
  * @param string $closureName
  * @param string $initializationPhpCode
  * @param ViewHelperNode $node
  * @param TemplateCompiler $compiler
  * @return null
  */
 public function compile($argumentsName, $closureName, &$initializationPhpCode, ViewHelperNode $node, TemplateCompiler $compiler)
 {
     // @TODO: replace with a true compiling method to make compilable!
     $compiler->disable();
     return null;
 }
Пример #6
0
 /**
  * @test
  */
 public function testGetRenderingContextGetsRenderingContext()
 {
     $context = new RenderingContextFixture();
     $instance = new TemplateCompiler();
     $instance->setRenderingContext($context);
     $this->assertSame($context, $instance->getRenderingContext());
 }
 /**
  * @param string $argumentsName
  * @param string $closureName
  * @param string $initializationPhpCode
  * @param ViewHelperNode $node
  * @param TemplateCompiler $compiler
  * @return string
  */
 public function compile($argumentsName, $closureName, &$initializationPhpCode, ViewHelperNode $node, TemplateCompiler $compiler)
 {
     $compiler->disable();
     return "''";
 }
Пример #8
0
 /**
  * The compiled ViewHelper adds two new ViewHelper arguments: __thenClosure and __elseClosure.
  * These contain closures which are be executed to render the then(), respectively else() case.
  *
  * @param string $argumentsName
  * @param string $closureName
  * @param string $initializationPhpCode
  * @param ViewHelperNode $node
  * @param TemplateCompiler $compiler
  * @return string
  */
 public function compile($argumentsName, $closureName, &$initializationPhpCode, ViewHelperNode $node, TemplateCompiler $compiler)
 {
     $thenViewHelperEncountered = $elseViewHelperEncountered = false;
     foreach ($node->getChildNodes() as $childNode) {
         if ($childNode instanceof ViewHelperNode) {
             $viewHelperClassName = $childNode->getViewHelperClassName();
             if (substr($viewHelperClassName, -14) === 'ThenViewHelper') {
                 $thenViewHelperEncountered = true;
                 $childNodesAsClosure = $compiler->wrapChildNodesInClosure($childNode);
                 $initializationPhpCode .= sprintf('%s[\'__thenClosure\'] = %s;', $argumentsName, $childNodesAsClosure) . chr(10);
             } elseif (substr($viewHelperClassName, -14) === 'ElseViewHelper') {
                 $elseViewHelperEncountered = true;
                 $childNodesAsClosure = $compiler->wrapChildNodesInClosure($childNode);
                 $initializationPhpCode .= sprintf('%s[\'__elseClosures\'][] = %s;', $argumentsName, $childNodesAsClosure) . chr(10);
                 $arguments = $childNode->getArguments();
                 if (isset($arguments['if'])) {
                     // The "else" has an argument, indicating it has a secondary (elseif) condition.
                     // Compile a closure which will evaluate the condition.
                     $elseIfConditionAsClosure = $compiler->wrapViewHelperNodeArgumentEvaluationInClosure($childNode, 'if');
                     $initializationPhpCode .= sprintf('%s[\'__elseifClosures\'][] = %s;', $argumentsName, $elseIfConditionAsClosure) . chr(10);
                 }
             }
         }
     }
     if (!$thenViewHelperEncountered && !$elseViewHelperEncountered && !isset($node->getArguments()['then'])) {
         $initializationPhpCode .= sprintf('%s[\'__thenClosure\'] = %s;', $argumentsName, $closureName) . chr(10);
     }
     return parent::compile($argumentsName, $closureName, $initializationPhpCode, $node, $compiler);
 }
Пример #9
0
 /**
  * @test
  */
 public function testStoreWhenDisabledFlushesCache()
 {
     $cache = $this->getMock('TYPO3Fluid\\Fluid\\Core\\Cache\\SimpleFileCache', array('flush', 'store'));
     $cache->expects($this->never())->method('store');
     $cache->expects($this->once())->method('flush')->with('fakeidentifier');
     $state = new ParsingState();
     $instance = new TemplateCompiler();
     $instance->disable();
     $instance->setTemplateCache($cache);
     $instance->store('fakeidentifier', $state);
 }
Пример #10
0
 /**
  * @return ExposedTemplateCompiler
  */
 protected function getTemplateCompiler()
 {
     if ($this->assertCoreVersionAtLeast(8)) {
         $compiler = new TemplateCompiler();
         $compiler->setRenderingContext(new RenderingContext());
         return $compiler;
     }
     return $this->objectManager->get('FluidTYPO3\\Builder\\Parser\\ExposedTemplateCompiler');
 }
Пример #11
0
 /**
  * @param TemplateCompiler $templateCompiler
  * @return void
  */
 public function setTemplateCompiler(TemplateCompiler $templateCompiler)
 {
     $this->templateCompiler = $templateCompiler;
     $this->templateCompiler->setRenderingContext($this);
 }
Пример #12
0
    /**
     * Compiles the ExpressionNode, returning an array with
     * exactly two keys which contain strings:
     *
     * - "initialization" which contains variable initializations
     * - "execution" which contains the execution (that uses the variables)
     *
     * The expression and matches can be read from the local
     * instance - and the RenderingContext and other APIs
     * can be accessed via the TemplateCompiler.
     *
     * @param TemplateCompiler $templateCompiler
     * @return string
     */
    public function compile(TemplateCompiler $templateCompiler)
    {
        $parts = preg_split('/([\\?:])/s', $this->getExpression());
        $parts = array_map([__CLASS__, 'trimPart'], $parts);
        list($check, $then, $else) = $parts;
        $matchesVariable = $templateCompiler->variableName('array');
        $initializationPhpCode = '// Rendering TernaryExpression node' . chr(10);
        $initializationPhpCode .= sprintf('%s = %s;', $matchesVariable, var_export($this->getMatches(), true)) . chr(10);
        $parser = new BooleanParser();
        $compiledExpression = $parser->compile($check);
        $functionName = $templateCompiler->variableName('ternaryExpression');
        $initializationPhpCode .= sprintf('%s = function($context, $renderingContext) {
				if (%s::convertToBoolean(' . $compiledExpression . ', $renderingContext) === TRUE) {
					return %s::getTemplateVariableOrValueItself(%s, $renderingContext);
				} else {
					return %s::getTemplateVariableOrValueItself(%s, $renderingContext);
				}
			};' . chr(10), $functionName, BooleanNode::class, static::class, var_export($then, true), static::class, var_export($else, true));
        return ['initialization' => $initializationPhpCode, 'execution' => sprintf('%s(%s::gatherContext($renderingContext, %s[1]), $renderingContext)', $functionName, static::class, $matchesVariable)];
    }
Пример #13
0
 /**
  * Compiles the node structure to a native switch
  * statement which evaluates closures for each
  * case comparison and renders child node closures
  * only when value matches.
  *
  * @param string $argumentsName
  * @param string $closureName
  * @param string $initializationPhpCode
  * @param ViewHelperNode $node
  * @param TemplateCompiler $compiler
  * @return string
  */
 public function compile($argumentsName, $closureName, &$initializationPhpCode, ViewHelperNode $node, TemplateCompiler $compiler)
 {
     $phpCode = 'call_user_func_array(function($arguments) use ($renderingContext, $self) {' . PHP_EOL . 'switch ($arguments[\'expression\']) {' . PHP_EOL;
     foreach ($node->getChildNodes() as $childNode) {
         if ($this->isDefaultCaseNode($childNode)) {
             $childrenClosure = $compiler->wrapChildNodesInClosure($childNode);
             $phpCode .= sprintf('default: return call_user_func(%s);', $childrenClosure) . PHP_EOL;
         } elseif ($this->isCaseNode($childNode)) {
             /** @var ViewHelperNode $childNode */
             $valueClosure = $compiler->wrapViewHelperNodeArgumentEvaluationInClosure($childNode, 'value');
             $childrenClosure = $compiler->wrapChildNodesInClosure($childNode);
             $phpCode .= sprintf('case call_user_func(%s): return call_user_func(%s);', $valueClosure, $childrenClosure, $compiler->getNodeConverter()->convert($childNode)) . PHP_EOL;
         }
     }
     $phpCode .= '}' . PHP_EOL;
     $phpCode .= sprintf('}, array(%s))', $argumentsName);
     return $phpCode;
 }