/**
  * Pre-process the template source before it is returned to the TemplateParser or passed to
  * the next TemplateProcessorInterface instance.
  *
  * Detects all tags that carry an `xmlns:` definition using a Fluid-compatible prefix and a
  * conventional namespace URL (http://typo3.org/ns/). Extracts the detected namespaces and
  * removes the detected tag.
  *
  * @param string $templateSource
  * @return string
  */
 public function preProcessSource($templateSource)
 {
     $matches = array();
     $namespacePattern = 'xmlns:([a-z0-9]+)="(http\\:\\/\\/typo3\\.org\\/ns\\/[^"]+)"';
     $matched = preg_match('/<([a-z0-9]+)(?:[^>]*?)\\s+' . $namespacePattern . '[^>]*>/', $templateSource, $matches);
     if ($matched) {
         $namespaces = array();
         preg_match_all('/' . $namespacePattern . '/', $matches[0], $namespaces, PREG_SET_ORDER);
         foreach ($namespaces as $set) {
             $namespaceUrl = $set[2];
             $namespaceUri = substr($namespaceUrl, 20);
             $namespacePhp = str_replace('/', '\\', $namespaceUri);
             $this->renderingContext->getViewHelperResolver()->addNamespace($set[1], $namespacePhp);
         }
         if (strpos($matches[0], 'data-namespace-typo3-fluid="true"')) {
             $templateSource = str_replace($matches[0], '', $templateSource);
             $closingTagName = $matches[1];
             $closingTag = '</' . $closingTagName . '>';
             if (strpos($templateSource, $closingTag)) {
                 $templateSource = substr($templateSource, 0, strrpos($templateSource, $closingTag)) . substr($templateSource, strrpos($templateSource, $closingTag) + strlen($closingTag));
             }
         } else {
             if (!empty($namespaces)) {
                 $namespaceAttributesToRemove = [];
                 foreach ($namespaces as $namespace) {
                     $namespaceAttributesToRemove[] = preg_quote($namespace[1], '/') . '="' . preg_quote($namespace[2], '/') . '"';
                 }
                 $matchWithRemovedNamespaceAttributes = preg_replace('/(?:\\s*+xmlns:(?:' . implode('|', $namespaceAttributesToRemove) . ')\\s*+)++/', ' ', $matches[0]);
                 $templateSource = str_replace($matches[0], $matchWithRemovedNamespaceAttributes, $templateSource);
             }
         }
     }
     return $templateSource;
 }
Beispiel #2
0
 /**
  * Invoke the ViewHelper described by the ViewHelperNode, the properties
  * of which will already have been filled by the ViewHelperResolver.
  *
  * @param string|ViewHelperInterface $viewHelperClassName
  * @param array $arguments
  * @param RenderingContextInterface $renderingContext
  * @param \Closure $renderChildrenClosure
  * @return mixed
  */
 public function invoke($viewHelperClassNameOrInstance, array $arguments, RenderingContextInterface $renderingContext, \Closure $renderChildrenClosure = NULL)
 {
     if ($viewHelperClassNameOrInstance instanceof ViewHelperInterface) {
         $viewHelper = $viewHelperClassNameOrInstance;
     } else {
         $viewHelper = $this->viewHelperResolver->createViewHelperInstanceFromClassName($viewHelperClassNameOrInstance);
     }
     $expectedViewHelperArguments = $renderingContext->getViewHelperResolver()->getArgumentDefinitionsForViewHelper($viewHelper);
     // Rendering process
     $evaluatedArguments = array();
     foreach ($expectedViewHelperArguments as $argumentName => $argumentDefinition) {
         if (isset($arguments[$argumentName])) {
             /** @var NodeInterface|mixed $argumentValue */
             $argumentValue = $arguments[$argumentName];
             $evaluatedArguments[$argumentName] = $argumentValue instanceof NodeInterface ? $argumentValue->evaluate($renderingContext) : $argumentValue;
         } else {
             $evaluatedArguments[$argumentName] = $argumentDefinition->getDefaultValue();
         }
     }
     $this->abortIfUnregisteredArgumentsExist($expectedViewHelperArguments, $evaluatedArguments);
     $this->abortIfRequiredArgumentsAreMissing($expectedViewHelperArguments, $evaluatedArguments);
     $viewHelper->setArguments($evaluatedArguments);
     $viewHelper->setRenderingContext($renderingContext);
     if ($renderChildrenClosure) {
         $viewHelper->setRenderChildrenClosure($renderChildrenClosure);
     }
     return $viewHelper->initializeArgumentsAndRender();
 }
 /**
  * Throw an UnknownNamespaceException for any unknown and not ignored
  * namespace inside the template string
  *
  * @param string $templateSource
  * @return void
  */
 public function throwExceptionsForUnhandledNamespaces($templateSource)
 {
     $viewHelperResolver = $this->renderingContext->getViewHelperResolver();
     $splitTemplate = preg_split(Patterns::$SPLIT_PATTERN_TEMPLATE_DYNAMICTAGS, $templateSource, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
     foreach ($splitTemplate as $templateElement) {
         if (preg_match(Patterns::$SCAN_PATTERN_TEMPLATE_VIEWHELPERTAG, $templateElement, $matchedVariables) > 0) {
             if (!$viewHelperResolver->isNamespaceValidOrIgnored($matchedVariables['NamespaceIdentifier'])) {
                 throw new UnknownNamespaceException('Unkown Namespace: ' . htmlspecialchars($matchedVariables[0]));
             }
             continue;
         } elseif (preg_match(Patterns::$SCAN_PATTERN_TEMPLATE_CLOSINGVIEWHELPERTAG, $templateElement, $matchedVariables) > 0) {
             continue;
         }
         $sections = preg_split(Patterns::$SPLIT_PATTERN_SHORTHANDSYNTAX, $templateElement, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
         foreach ($sections as $section) {
             if (preg_match(Patterns::$SCAN_PATTERN_SHORTHANDSYNTAX_OBJECTACCESSORS, $section, $matchedVariables) > 0) {
                 preg_match_all(Patterns::$SPLIT_PATTERN_SHORTHANDSYNTAX_VIEWHELPER, $section, $shorthandViewHelpers, PREG_SET_ORDER);
                 if (is_array($shorthandViewHelpers) === true) {
                     foreach ($shorthandViewHelpers as $shorthandViewHelper) {
                         if (!$viewHelperResolver->isNamespaceValidOrIgnored($shorthandViewHelper['NamespaceIdentifier'])) {
                             throw new UnknownNamespaceException('Unkown Namespace: ' . $shorthandViewHelper['NamespaceIdentifier']);
                         }
                     }
                 }
             }
         }
     }
 }
Beispiel #4
0
 /**
  * Invoke the ViewHelper described by the ViewHelperNode, the properties
  * of which will already have been filled by the ViewHelperResolver.
  *
  * @param string|ViewHelperInterface $viewHelperClassNameOrInstance
  * @param array $arguments
  * @param RenderingContextInterface $renderingContext
  * @param null|\Closure $renderChildrenClosure
  * @return string
  */
 public function invoke($viewHelperClassNameOrInstance, array $arguments, RenderingContextInterface $renderingContext, \Closure $renderChildrenClosure = null)
 {
     $viewHelperResolver = $renderingContext->getViewHelperResolver();
     if ($viewHelperClassNameOrInstance instanceof ViewHelperInterface) {
         $viewHelper = $viewHelperClassNameOrInstance;
     } else {
         $viewHelper = $viewHelperResolver->createViewHelperInstanceFromClassName($viewHelperClassNameOrInstance);
     }
     $expectedViewHelperArguments = $viewHelperResolver->getArgumentDefinitionsForViewHelper($viewHelper);
     // Rendering process
     $evaluatedArguments = [];
     $undeclaredArguments = [];
     foreach ($expectedViewHelperArguments as $argumentName => $argumentDefinition) {
         if (isset($arguments[$argumentName])) {
             /** @var NodeInterface|mixed $argumentValue */
             $argumentValue = $arguments[$argumentName];
             $evaluatedArguments[$argumentName] = $argumentValue instanceof NodeInterface ? $argumentValue->evaluate($renderingContext) : $argumentValue;
         } else {
             $evaluatedArguments[$argumentName] = $argumentDefinition->getDefaultValue();
         }
     }
     foreach ($arguments as $argumentName => $argumentValue) {
         if (!array_key_exists($argumentName, $evaluatedArguments)) {
             $undeclaredArguments[$argumentName] = $argumentValue instanceof NodeInterface ? $argumentValue->evaluate($renderingContext) : $argumentValue;
         }
     }
     if ($renderChildrenClosure) {
         $viewHelper->setRenderChildrenClosure($renderChildrenClosure);
     }
     $viewHelper->setRenderingContext($renderingContext);
     $viewHelper->setArguments($evaluatedArguments);
     $viewHelper->handleAdditionalArguments($undeclaredArguments);
     return $viewHelper->initializeArgumentsAndRender();
 }
Beispiel #5
0
 /**
  * Constructor.
  *
  * @param RenderingContextInterface $renderingContext a RenderingContext, provided by invoker
  * @param string $namespace the namespace identifier of the ViewHelper.
  * @param string $identifier the name of the ViewHelper to render, inside the namespace provided.
  * @param NodeInterface[] $arguments Arguments of view helper - each value is a RootNode.
  * @param ParsingState $state
  */
 public function __construct(RenderingContextInterface $renderingContext, $namespace, $identifier, array $arguments, ParsingState $state)
 {
     $resolver = $renderingContext->getViewHelperResolver();
     $this->arguments = $arguments;
     $this->viewHelperClassName = $resolver->resolveViewHelperClassName($namespace, $identifier);
     $this->uninitializedViewHelper = $resolver->createViewHelperInstanceFromClassName($this->viewHelperClassName);
     $this->uninitializedViewHelper->setRenderingContext($renderingContext);
     $this->uninitializedViewHelper->setViewHelperNode($this);
     $this->argumentDefinitions = $resolver->getArgumentDefinitionsForViewHelper($this->uninitializedViewHelper);
     $this->rewriteBooleanNodesInArgumentsObjectTree($this->argumentDefinitions, $this->arguments);
     $this->validateArguments($this->argumentDefinitions, $this->arguments);
 }
Beispiel #6
0
 /**
  * Constructor.
  *
  * @param RenderingContextInterface $renderingContext a RenderingContext, provided by invoker
  * @param string $namespace the namespace identifier of the ViewHelper.
  * @param string $identifier the name of the ViewHelper to render, inside the namespace provided.
  * @param NodeInterface[] $arguments Arguments of view helper - each value is a RootNode.
  * @param ParsingState $state
  */
 public function __construct(RenderingContextInterface $renderingContext, $namespace, $identifier, array $arguments, ParsingState $state)
 {
     $resolver = $renderingContext->getViewHelperResolver();
     $this->arguments = $arguments;
     $this->viewHelperClassName = $resolver->resolveViewHelperClassName($namespace, $identifier);
     $this->uninitializedViewHelper = $resolver->createViewHelperInstanceFromClassName($this->viewHelperClassName);
     $this->uninitializedViewHelper->setViewHelperNode($this);
     // Note: RenderingContext required here though replaced later. See https://github.com/TYPO3Fluid/Fluid/pull/93
     $this->uninitializedViewHelper->setRenderingContext($renderingContext);
     $this->argumentDefinitions = $resolver->getArgumentDefinitionsForViewHelper($this->uninitializedViewHelper);
     $this->rewriteBooleanNodesInArgumentsObjectTree($this->argumentDefinitions, $this->arguments);
     $this->validateArguments($this->argumentDefinitions, $this->arguments);
 }
Beispiel #7
0
 /**
  * Handles a closing view helper tag
  *
  * @param ParsingState $state The current parsing state
  * @param string $namespaceIdentifier Namespace identifier for the closing tag.
  * @param string $methodIdentifier Method identifier.
  * @return boolean whether the viewHelper was found and added to the stack or not
  * @throws Exception
  */
 protected function closingViewHelperTagHandler(ParsingState $state, $namespaceIdentifier, $methodIdentifier)
 {
     $viewHelperResolver = $this->renderingContext->getViewHelperResolver();
     if (!$viewHelperResolver->isNamespaceValid($namespaceIdentifier)) {
         return FALSE;
     }
     $lastStackElement = $state->popNodeFromStack();
     if (!$lastStackElement instanceof ViewHelperNode) {
         throw new Exception('You closed a templating tag which you never opened!', 1224485838);
     }
     $actualViewHelperClassName = $viewHelperResolver->resolveViewHelperClassName($namespaceIdentifier, $methodIdentifier);
     $expectedViewHelperClassName = $lastStackElement->getViewHelperClassName();
     if ($actualViewHelperClassName !== $expectedViewHelperClassName) {
         throw new Exception('Templating tags not properly nested. Expected: ' . $expectedViewHelperClassName . '; Actual: ' . $actualViewHelperClassName, 1224485398);
     }
     $this->callInterceptor($lastStackElement, InterceptorInterface::INTERCEPT_CLOSING_VIEWHELPER, $state);
     $state->getNodeFromStack()->addChildNode($lastStackElement);
     return TRUE;
 }
Beispiel #8
0
    /**
     * @param string $identifier
     * @param ParsingState $parsingState
     * @return void
     */
    public function store($identifier, ParsingState $parsingState)
    {
        if ($this->isDisabled()) {
            if ($this->renderingContext->isCacheEnabled()) {
                // Compiler is disabled but cache is enabled. Flush cache to make sure.
                $this->renderingContext->getCache()->flush($identifier);
            }
            $parsingState->setCompilable(FALSE);
            return;
        }
        $identifier = $this->sanitizeIdentifier($identifier);
        $this->nodeConverter->setVariableCounter(0);
        $generatedRenderFunctions = $this->generateSectionCodeFromParsingState($parsingState);
        $generatedRenderFunctions .= $this->generateCodeForSection($this->nodeConverter->convertListOfSubNodes($parsingState->getRootNode()), 'render', 'Main Render function');
        $classDefinition = 'class ' . $identifier . ' extends \\TYPO3Fluid\\Fluid\\Core\\Compiler\\AbstractCompiledTemplate';
        $templateCode = <<<EOD
<?php

%s {

public function getLayoutName(\\TYPO3Fluid\\Fluid\\Core\\Rendering\\RenderingContextInterface \$renderingContext) {
\$layout = %s;
if (!\$layout) {
\$layout = '%s';
}
return \$layout;
}
public function hasLayout() {
return %s;
}
public function addCompiledNamespaces(\\TYPO3Fluid\\Fluid\\Core\\Rendering\\RenderingContextInterface \$renderingContext) {
\$renderingContext->getViewHelperResolver()->addNamespaces(%s);
}

%s

}
EOD;
        $templateCode = sprintf($templateCode, $classDefinition, '$renderingContext->getVariableProvider()->get(\'layoutName\')', $parsingState->getVariableContainer()->get('layoutName'), $parsingState->hasLayout() ? 'TRUE' : 'FALSE', var_export($this->renderingContext->getViewHelperResolver()->getNamespaces(), TRUE), $generatedRenderFunctions);
        $this->renderingContext->getCache()->set($identifier, $templateCode);
    }
 /**
  * @param RenderingContextInterface $renderingContext
  * @param string $expression
  * @param array $matches
  * @return mixed
  */
 public static function evaluateExpression(RenderingContextInterface $renderingContext, $expression, array $matches)
 {
     $renderingContext->getViewHelperResolver()->addNamespace($matches[1], $matches[2]);
 }
 /**
  * Public such that it is callable from within closures
  *
  * @param integer $uniqueCounter
  * @param RenderingContextInterface $renderingContext
  * @param string $viewHelperName
  * @return AbstractViewHelper
  */
 public function getViewHelper($uniqueCounter, RenderingContextInterface $renderingContext, $viewHelperName)
 {
     return $renderingContext->getViewHelperResolver()->createViewHelperInstanceFromClassName($viewHelperName);
 }
 /**
  * Gets the ViewHelperResolver instance from RenderingContext
  *
  * @return ViewHelperResolver
  */
 public function getViewHelperResolver()
 {
     return $this->baseRenderingContext->getViewHelperResolver();
 }