예제 #1
0
 /**
  * Loads the template source and render the template.
  * If "layoutName" is set in a PostParseFacet callback, it will render the file with the given layout.
  *
  * @param string $actionName If set, this action's template will be rendered instead of the one defined in the context.
  * @return string Rendered Template
  * @api
  */
 public function render($actionName = NULL)
 {
     $this->templateParser->setConfiguration($this->buildParserConfiguration());
     $this->templateParser->setVariableProvider($this->baseRenderingContext->getVariableProvider());
     $this->templateParser->setViewHelperResolver($this->viewHelperResolver);
     $this->baseRenderingContext->setViewHelperResolver($this->viewHelperResolver);
     $controllerName = $this->baseRenderingContext->getControllerName();
     if (!$actionName) {
         $actionName = $this->baseRenderingContext->getControllerAction();
     }
     $actionName = ucfirst($actionName);
     if (empty($templateIdentifier)) {
         $templateIdentifier = $this->templatePaths->getTemplateIdentifier($controllerName, $actionName);
     }
     $parsedTemplate = $this->getOrParseAndStoreTemplate($templateIdentifier, function ($parent, TemplatePaths $paths) use($controllerName, $actionName) {
         return $paths->getTemplateSource($controllerName, $actionName);
     });
     $parsedTemplate->addCompiledNamespaces($this->baseRenderingContext);
     if (!$parsedTemplate->hasLayout()) {
         $this->startRendering(self::RENDERING_TEMPLATE, $parsedTemplate, $this->baseRenderingContext);
         $output = $parsedTemplate->render($this->baseRenderingContext);
         $this->stopRendering();
     } else {
         $layoutName = $parsedTemplate->getLayoutName($this->baseRenderingContext);
         $layoutIdentifier = $this->templatePaths->getLayoutIdentifier($layoutName);
         $parsedLayout = $this->getOrParseAndStoreTemplate($layoutIdentifier, function ($parent, TemplatePaths $paths) use($layoutName) {
             return $paths->getLayoutSource($layoutName);
         });
         $this->startRendering(self::RENDERING_LAYOUT, $parsedTemplate, $this->baseRenderingContext);
         $output = $parsedLayout->render($this->baseRenderingContext);
         $this->stopRendering();
     }
     return $output;
 }
예제 #2
0
 /**
  * Assigns multiple values to the JSON output.
  * However, only the key "value" is accepted.
  *
  * @param array $values Keys and values - only a value with key "value" is considered
  * @return $this
  * @api
  */
 public function assignMultiple(array $values)
 {
     $templateVariableContainer = $this->baseRenderingContext->getVariableProvider();
     foreach ($values as $key => $value) {
         $templateVariableContainer->add($key, $value);
     }
     return $this;
 }
 /**
  * @param RenderingContextInterface $renderingContext
  * @return void
  */
 public function setRenderingContext(RenderingContextInterface $renderingContext)
 {
     $this->renderingContext = $renderingContext;
     $this->templateVariableContainer = $renderingContext->getVariableProvider();
     $this->viewHelperVariableContainer = $renderingContext->getViewHelperVariableContainer();
     if ($renderingContext instanceof FlowAwareRenderingContextInterface) {
         $this->controllerContext = $renderingContext->getControllerContext();
     }
 }
예제 #4
0
 /**
  * Evaluate this node and return the correct object.
  *
  * Handles each part (denoted by .) in $this->objectPath in the following order:
  * - call appropriate getter
  * - call public property, if exists
  * - fail
  *
  * The first part of the object path has to be a variable in the
  * VariableProvider.
  *
  * @param RenderingContextInterface $renderingContext
  * @return mixed The evaluated object, can be any object type.
  */
 public function evaluate(RenderingContextInterface $renderingContext)
 {
     $objectPath = strtolower($this->objectPath);
     $variableProvider = $renderingContext->getVariableProvider();
     if ($objectPath === '_all') {
         return $variableProvider->getAll();
     }
     return VariableExtractor::extract($variableProvider, $this->objectPath, $this->accessors);
 }
예제 #5
0
 /**
  * @return ParsingState
  */
 protected function getParsingState()
 {
     $rootNode = new RootNode();
     $variableProvider = $this->renderingContext->getVariableProvider();
     $state = new ParsingState();
     $state->setRootNode($rootNode);
     $state->pushNodeToStack($rootNode);
     $state->setVariableProvider($variableProvider->getScopeCopy($variableProvider->getAll()));
     return $state;
 }
예제 #6
0
 /**
  * @param mixed $candidate
  * @param RenderingContextInterface $renderingContext
  * @return mixed
  */
 protected static function getTemplateVariableOrValueItself($candidate, RenderingContextInterface $renderingContext)
 {
     $variables = $renderingContext->getVariableProvider()->getAll();
     $extractor = new VariableExtractor();
     $suspect = $extractor->getByPath($variables, $candidate);
     if (NULL === $suspect) {
         return $candidate;
     }
     return $suspect;
 }
예제 #7
0
 /**
  * @param array $arguments
  * @param \Closure $renderChildrenClosure
  * @param RenderingContextInterface $renderingContext
  * @return mixed
  */
 public static function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext)
 {
     $values = $arguments['values'];
     $as = $arguments['as'];
     if ($values === null) {
         return $renderChildrenClosure();
     }
     $values = static::initializeValues($values);
     $index = static::initializeIndex($as, $renderingContext->getViewHelperVariableContainer());
     $currentValue = isset($values[$index]) ? $values[$index] : null;
     $renderingContext->getVariableProvider()->add($as, $currentValue);
     $output = $renderChildrenClosure();
     $renderingContext->getVariableProvider()->remove($as);
     $index++;
     if (!isset($values[$index])) {
         $index = 0;
     }
     $renderingContext->getViewHelperVariableContainer()->addOrUpdate(static::class, $as, $index);
     return $output;
 }
예제 #8
0
 /**
  * @param array $arguments
  * @param \Closure $renderChildrenClosure
  * @param RenderingContextInterface $renderingContext
  * @return mixed
  */
 public static function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext)
 {
     $templateVariableContainer = $renderingContext->getVariableProvider();
     $map = $arguments['map'];
     foreach ($map as $aliasName => $value) {
         $templateVariableContainer->add($aliasName, $value);
     }
     $output = $renderChildrenClosure();
     foreach ($map as $aliasName => $value) {
         $templateVariableContainer->remove($aliasName);
     }
     return $output;
 }
예제 #9
0
 /**
  * Evaluate this node and return the correct object.
  *
  * Handles each part (denoted by .) in $this->objectPath in the following order:
  * - call appropriate getter
  * - call public property, if exists
  * - fail
  *
  * The first part of the object path has to be a variable in the
  * VariableProvider.
  *
  * @param RenderingContextInterface $renderingContext
  * @return object The evaluated object, can be any object type.
  */
 public function evaluate(RenderingContextInterface $renderingContext)
 {
     $variableProvider = $renderingContext->getVariableProvider();
     switch (strtolower($this->objectPath)) {
         case '_all':
             return $variableProvider->getAll();
         case 'true':
         case 'on':
         case 'yes':
             return TRUE;
         case 'false':
         case 'off':
         case 'no':
             return FALSE;
         default:
             return VariableExtractor::extract($variableProvider, $this->objectPath, $this->accessors);
     }
 }
예제 #10
0
 /**
  * @param RenderingContextInterface $renderingContext
  * @param string $expression
  * @param array $matches
  * @return integer|float
  */
 public static function evaluateExpression(RenderingContextInterface $renderingContext, $expression, array $matches)
 {
     // Split the expression on all recognized operators
     $matches = array();
     preg_match_all('/([+\\-*\\^\\/\\%]|[a-z0-9\\.]+)/s', $expression, $matches);
     $matches[0] = array_map('trim', $matches[0]);
     // Like the BooleanNode, we dumb down the processing logic to not apply
     // any special precedence on the priority of operators. We simply process
     // them in order.
     $variables = $renderingContext->getVariableProvider()->getAll();
     $result = array_shift($matches[0]);
     $result = parent::getTemplateVariableOrValueItself($result, $renderingContext);
     $operator = NULL;
     $operators = array('*', '^', '-', '+', '/', '%');
     foreach ($matches[0] as $part) {
         if (in_array($part, $operators)) {
             $operator = $part;
         } else {
             $part = parent::getTemplateVariableOrValueItself($part, $renderingContext);
             $result = self::evaluateOperation($result, $operator, $part);
         }
     }
     return $result;
 }
예제 #11
0
 /**
  * Overlay variables by replacing the VariableProvider with a
  * ChainedVariableProvider using dual data sources. Returns the
  * original VariableProvider which must replace the temporary
  * one again once the rendering/compiling is done.
  *
  * @param RenderingContextInterface $renderingContext
  * @param array $variables
  * @return VariableProviderInterface
  */
 protected static function overlayVariablesIfNotSet(RenderingContextInterface $renderingContext, array $variables)
 {
     $currentProvider = $renderingContext->getVariableProvider();
     $chainedVariableProvider = new ChainedVariableProvider([$currentProvider, new StandardVariableProvider($variables)]);
     $renderingContext->setVariableProvider($chainedVariableProvider);
     return $currentProvider;
 }
예제 #12
0
 /**
  * @param RenderingContextInterface $renderingContext
  * @return void
  */
 public function setRenderingContext(RenderingContextInterface $renderingContext)
 {
     $this->renderingContext = $renderingContext;
     $this->templateVariableContainer = $renderingContext->getVariableProvider();
     $this->viewHelperVariableContainer = $renderingContext->getViewHelperVariableContainer();
 }
예제 #13
0
 /**
  * Returns the name of the layout that is defined within the current template via <f:layout name="..." />
  * If no layout is defined, this returns NULL
  * This requires the current rendering context in order to be able to evaluate the layout name
  *
  * @param RenderingContextInterface $renderingContext
  * @return string
  * @throws View\Exception
  */
 public function getLayoutName(RenderingContextInterface $renderingContext)
 {
     return $renderingContext->getVariableProvider()->get('layoutName');
 }
예제 #14
0
 /**
  * @param array $arguments
  * @param \Closure $renderChildrenClosure
  * @param RenderingContextInterface $renderingContext
  * @return string
  * @throws ViewHelper\Exception
  */
 public static function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext)
 {
     $templateVariableContainer = $renderingContext->getVariableProvider();
     if ($arguments['each'] === NULL) {
         return '';
     }
     if (is_object($arguments['each']) && !$arguments['each'] instanceof \Traversable) {
         throw new ViewHelper\Exception('ForViewHelper only supports arrays and objects implementing \\Traversable interface', 1248728393);
     }
     if ($arguments['reverse'] === TRUE) {
         // array_reverse only supports arrays
         if (is_object($arguments['each'])) {
             /** @var $each \Traversable */
             $each = $arguments['each'];
             $arguments['each'] = iterator_to_array($each);
         }
         $arguments['each'] = array_reverse($arguments['each']);
     }
     $iterationData = array('index' => 0, 'cycle' => 1, 'total' => count($arguments['each']));
     $output = '';
     foreach ($arguments['each'] as $keyValue => $singleElement) {
         $templateVariableContainer->add($arguments['as'], $singleElement);
         if ($arguments['key'] !== '') {
             $templateVariableContainer->add($arguments['key'], $keyValue);
         }
         if ($arguments['iteration'] !== NULL) {
             $iterationData['isFirst'] = $iterationData['cycle'] === 1;
             $iterationData['isLast'] = $iterationData['cycle'] === $iterationData['total'];
             $iterationData['isEven'] = $iterationData['cycle'] % 2 === 0;
             $iterationData['isOdd'] = !$iterationData['isEven'];
             $templateVariableContainer->add($arguments['iteration'], $iterationData);
             $iterationData['index']++;
             $iterationData['cycle']++;
         }
         $output .= $renderChildrenClosure();
         $templateVariableContainer->remove($arguments['as']);
         if ($arguments['key'] !== '') {
             $templateVariableContainer->remove($arguments['key']);
         }
         if ($arguments['iteration'] !== NULL) {
             $templateVariableContainer->remove($arguments['iteration']);
         }
     }
     return $output;
 }
예제 #15
0
 /**
  * @test
  */
 public function templateVariableContainerCanBeReadCorrectly()
 {
     $templateVariableContainer = $this->getMock(StandardVariableProvider::class);
     $this->renderingContext->setVariableProvider($templateVariableContainer);
     $this->assertSame($this->renderingContext->getVariableProvider(), $templateVariableContainer, 'Template Variable Container could not be read out again.');
 }
예제 #16
0
 /**
  * @param array $arguments
  * @param \Closure $renderChildrenClosure
  * @param RenderingContextInterface $renderingContext
  * @return mixed
  */
 public static function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext)
 {
     $each = $arguments['each'];
     $as = $arguments['as'];
     $groupBy = $arguments['groupBy'];
     $groupKey = $arguments['groupKey'];
     $output = '';
     if ($each === NULL) {
         return '';
     }
     if (is_object($each)) {
         if (!$each instanceof \Traversable) {
             throw new ViewHelper\Exception('GroupedForViewHelper only supports arrays and objects implementing \\Traversable interface', 1253108907);
         }
         $each = iterator_to_array($each);
     }
     $groups = static::groupElements($each, $groupBy);
     $templateVariableContainer = $renderingContext->getVariableProvider();
     foreach ($groups['values'] as $currentGroupIndex => $group) {
         $templateVariableContainer->add($groupKey, $groups['keys'][$currentGroupIndex]);
         $templateVariableContainer->add($as, $group);
         $output .= $renderChildrenClosure();
         $templateVariableContainer->remove($groupKey);
         $templateVariableContainer->remove($as);
     }
     return $output;
 }
 /**
  * @param \TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface $renderingContext
  * @return void
  */
 public function setRenderingContext(\TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface $renderingContext)
 {
     $this->renderingContext = $renderingContext;
     $this->templateVariableContainer = $renderingContext->getVariableProvider();
     $this->viewHelperVariableContainer = $renderingContext->getViewHelperVariableContainer();
     if ($renderingContext instanceof \TYPO3\CMS\Fluid\Core\Rendering\RenderingContext) {
         $this->controllerContext = $renderingContext->getControllerContext();
     }
 }
예제 #18
0
 /**
  * Warm up a single template file.
  *
  * Performs reading, parsing and attempts compiling of a single
  * template file. Catches errors that may occur and reports them
  * in a FailedCompilingState (which can then be `add()`'ed to
  * the FluidCacheWarmupResult to assimilate the information within.
  *
  * Adds basic mitigation suggestions for each specific type of error,
  * giving hints to developers if a certain template fails to compile.
  *
  * @param string $templatePathAndFilename
  * @param string $identifier
  * @param RenderingContextInterface $renderingContext
  * @return ParsedTemplateInterface
  */
 protected function warmSingleFile($templatePathAndFilename, $identifier, RenderingContextInterface $renderingContext)
 {
     $parsedTemplate = new FailedCompilingState();
     $parsedTemplate->setVariableProvider($renderingContext->getVariableProvider());
     $parsedTemplate->setCompilable(false);
     $parsedTemplate->setIdentifier($identifier);
     try {
         $parsedTemplate = $renderingContext->getTemplateParser()->getOrParseAndStoreTemplate($identifier, function (TemplateParser $parser, TemplatePaths $templatePaths) use($templatePathAndFilename) {
             return file_get_contents($templatePathAndFilename, FILE_TEXT);
         });
     } catch (StopCompilingException $error) {
         $parsedTemplate->setFailureReason(sprintf('Compiling is intentionally disabled. Specific reason unknown. Message: "%s"', $error->getMessage()));
         $parsedTemplate->setMitigations(['Can be caused by specific ViewHelpers. If this is is not intentional: avoid ViewHelpers which disable caches.', 'If cache is intentionally disabled: consider using `f:cache.static` to cause otherwise uncompilable ViewHelpers\' output to be replaced with a static string in compiled templates.']);
     } catch (ExpressionException $error) {
         $parsedTemplate->setFailureReason(sprintf('ExpressionNode evaluation error: %s', $error->getMessage()));
         $parsedTemplate->setMitigations(['Emulate variables used in ExpressionNode using `f:cache.warmup` or assign in warming RenderingContext']);
     } catch (\TYPO3Fluid\Fluid\Core\Parser\Exception $error) {
         $parsedTemplate->setFailureReason($error->getMessage());
         $parsedTemplate->setMitigations(['Fix possible syntax errors.', 'Check that all ViewHelpers are correctly referenced and namespaces loaded (note: namespaces may be added externally!)', 'Check that all ExpressionNode types used by the template are loaded (note: may depend on RenderingContext implementation!)', 'Emulate missing variables used in expressions by using `f:cache.warmup` around your template code.']);
     } catch (\TYPO3Fluid\Fluid\Core\ViewHelper\Exception $error) {
         $parsedTemplate->setFailureReason(sprintf('ViewHelper threw Exception: %s', $error->getMessage()));
         $parsedTemplate->setMitigations(['Emulate missing variables using `f:cache.warmup` around failing ViewHelper.', 'Emulate globals / context required by ViewHelper.', 'Disable caching for template if ViewHelper depends on globals / context that cannot be emulated.']);
     } catch (\TYPO3Fluid\Fluid\Core\Exception $error) {
         $parsedTemplate->setFailureReason(sprintf('Fluid engine error: %s', $error->getMessage()));
         $parsedTemplate->setMitigations(['Search online for additional information about specific error.']);
     } catch (Exception $error) {
         $parsedTemplate->setFailureReason(sprintf('Fluid view error: %s', $error->getMessage()));
         $parsedTemplate->setMitigations(['Investigate reported error in View class for missing variable checks, missing configuration etc.', 'Consider using a different View class for rendering in warmup mode (a custom rendering context can provide it)']);
     } catch (\RuntimeException $error) {
         $parsedTemplate->setFailureReason(sprintf('General error: %s line %s threw %s (code: %d)', get_class($error), $error->getFile(), $error->getLine(), $error->getMessage(), $error->getCode()));
         $parsedTemplate->setMitigations(['There are no automated suggestions for mitigating this issue. An online search may yield more information.']);
     }
     return $parsedTemplate;
 }