/** * 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(); }
/** * @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; }
/** * 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; }
/** * 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); } }
/** * @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; }
/** * @test */ public function viewHelperVariableContainerCanBeReadCorrectly() { $viewHelperVariableContainer = $this->getMock('NamelessCoder\\Fluid\\Core\\ViewHelper\\ViewHelperVariableContainer'); $this->renderingContext->injectViewHelperVariableContainer($viewHelperVariableContainer); $this->assertSame($viewHelperVariableContainer, $this->renderingContext->getViewHelperVariableContainer()); }
/** * @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; }
/** * @param RenderingContextInterface $renderingContext * @return void */ public function setRenderingContext(RenderingContextInterface $renderingContext) { $this->renderingContext = $renderingContext; $this->templateVariableContainer = $renderingContext->getVariableProvider(); $this->viewHelperVariableContainer = $renderingContext->getViewHelperVariableContainer(); }
/** * 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); }
/** * 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'); }