[TASK] Sync CMS Fluid with Flow Fluid 1.1 (part1)
[Packages/TYPO3.CMS.git] / typo3 / sysext / fluid / Classes / Core / ViewHelper / AbstractConditionViewHelper.php
1 <?php
2 namespace TYPO3\CMS\Fluid\Core\ViewHelper;
3
4 /* *
5 * This script is backported from the TYPO3 Flow package "TYPO3.Fluid". *
6 * *
7 * It is free software; you can redistribute it and/or modify it under *
8 * the terms of the GNU Lesser General Public License, either version 3 *
9 * of the License, or (at your option) any later version. *
10 * *
11 * The TYPO3 project - inspiring people to share! *
12 * */
13
14 /**
15 * This view helper is an abstract ViewHelper which implements an if/else condition.
16 * @see TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\ViewHelperNode::convertArgumentValue() to find see how boolean arguments are evaluated
17 *
18 * = Usage =
19 *
20 * To create a custom Condition ViewHelper, you need to subclass this class, and
21 * implement your own render() method. Inside there, you should call $this->renderThenChild()
22 * if the condition evaluated to TRUE, and $this->renderElseChild() if the condition evaluated
23 * to FALSE.
24 *
25 * Every Condition ViewHelper has a "then" and "else" argument, so it can be used like:
26 * <[aConditionViewHelperName] .... then="condition true" else="condition false" />,
27 * or as well use the "then" and "else" child nodes.
28 *
29 * @see TYPO3\CMS\Fluid\ViewHelpers\IfViewHelper for a more detailed explanation and a simple usage example.
30 * Make sure to NOT OVERRIDE the constructor.
31 *
32 * @api
33 */
34 abstract class AbstractConditionViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper implements \TYPO3\CMS\Fluid\Core\ViewHelper\Facets\ChildNodeAccessInterface, \TYPO3\CMS\Fluid\Core\ViewHelper\Facets\CompilableInterface {
35
36 /**
37 * An array containing child nodes
38 *
39 * @var array<\TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode>
40 */
41 private $childNodes = array();
42
43 /**
44 * Setter for ChildNodes - as defined in ChildNodeAccessInterface
45 *
46 * @param array $childNodes Child nodes of this syntax tree node
47 * @return void
48 */
49 public function setChildNodes(array $childNodes) {
50 $this->childNodes = $childNodes;
51 }
52
53 /**
54 * Initializes the "then" and "else" arguments
55 */
56 public function __construct() {
57 $this->registerArgument('then', 'mixed', 'Value to be returned if the condition if met.', FALSE);
58 $this->registerArgument('else', 'mixed', 'Value to be returned if the condition if not met.', FALSE);
59 }
60
61 /**
62 * Returns value of "then" attribute.
63 * If then attribute is not set, iterates through child nodes and renders ThenViewHelper.
64 * If then attribute is not set and no ThenViewHelper and no ElseViewHelper is found, all child nodes are rendered
65 *
66 * @return string rendered ThenViewHelper or contents of <f:if> if no ThenViewHelper was found
67 * @api
68 */
69 protected function renderThenChild() {
70 if ($this->hasArgument('then')) {
71 return $this->arguments['then'];
72 }
73 if ($this->hasArgument('__thenClosure')) {
74 $thenClosure = $this->arguments['__thenClosure'];
75 return $thenClosure();
76 } elseif ($this->hasArgument('__elseClosure') || $this->hasArgument('else')) {
77 return '';
78 }
79
80 $elseViewHelperEncountered = FALSE;
81 foreach ($this->childNodes as $childNode) {
82 if ($childNode instanceof \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\ViewHelperNode
83 && $childNode->getViewHelperClassName() === 'TYPO3\\CMS\\Fluid\\ViewHelpers\\ThenViewHelper') {
84 $data = $childNode->evaluate($this->renderingContext);
85 return $data;
86 }
87 if ($childNode instanceof \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\ViewHelperNode
88 && $childNode->getViewHelperClassName() === 'TYPO3\\CMS\\Fluid\\ViewHelpers\\ElseViewHelper') {
89 $elseViewHelperEncountered = TRUE;
90 }
91 }
92
93 if ($elseViewHelperEncountered) {
94 return '';
95 } else {
96 return $this->renderChildren();
97 }
98 }
99
100 /**
101 * Returns value of "else" attribute.
102 * If else attribute is not set, iterates through child nodes and renders ElseViewHelper.
103 * If else attribute is not set and no ElseViewHelper is found, an empty string will be returned.
104 *
105 * @return string rendered ElseViewHelper or an empty string if no ThenViewHelper was found
106 * @api
107 */
108 protected function renderElseChild() {
109 if ($this->hasArgument('else')) {
110 return $this->arguments['else'];
111 }
112 if ($this->hasArgument('__elseClosure')) {
113 $elseClosure = $this->arguments['__elseClosure'];
114 return $elseClosure();
115 }
116 foreach ($this->childNodes as $childNode) {
117 if ($childNode instanceof \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\ViewHelperNode
118 && $childNode->getViewHelperClassName() === 'TYPO3\\CMS\\Fluid\\ViewHelpers\\ElseViewHelper') {
119 return $childNode->evaluate($this->renderingContext);
120 }
121 }
122
123 return '';
124 }
125
126 /**
127 * The compiled ViewHelper adds two new ViewHelper arguments: __thenClosure and __elseClosure.
128 * These contain closures which are be executed to render the then(), respectively else() case.
129 *
130 * @param string $argumentsVariableName
131 * @param string $renderChildrenClosureVariableName
132 * @param string $initializationPhpCode
133 * @param \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode $syntaxTreeNode
134 * @param \TYPO3\CMS\Fluid\Core\Compiler\TemplateCompiler $templateCompiler
135 * @return string
136 * @internal
137 */
138 public function compile($argumentsVariableName, $renderChildrenClosureVariableName, &$initializationPhpCode, \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode $syntaxTreeNode, \TYPO3\CMS\Fluid\Core\Compiler\TemplateCompiler $templateCompiler) {
139 foreach ($syntaxTreeNode->getChildNodes() as $childNode) {
140 if ($childNode instanceof \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\ViewHelperNode
141 && $childNode->getViewHelperClassName() === 'TYPO3\\CMS\\Fluid\\ViewHelpers\\ThenViewHelper') {
142
143 $childNodesAsClosure = $templateCompiler->wrapChildNodesInClosure($childNode);
144 $initializationPhpCode .= sprintf('%s[\'__thenClosure\'] = %s;', $argumentsVariableName, $childNodesAsClosure) . chr(10);
145 }
146 if ($childNode instanceof \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\ViewHelperNode
147 && $childNode->getViewHelperClassName() === 'TYPO3\\CMS\\Fluid\\ViewHelpers\\ElseViewHelper') {
148
149 $childNodesAsClosure = $templateCompiler->wrapChildNodesInClosure($childNode);
150 $initializationPhpCode .= sprintf('%s[\'__elseClosure\'] = %s;', $argumentsVariableName, $childNodesAsClosure) . chr(10);
151 }
152 }
153 return \TYPO3\CMS\Fluid\Core\Compiler\TemplateCompiler::SHOULD_GENERATE_VIEWHELPER_INVOCATION;
154 }
155 }
156
157 ?>