[FEATURE] Fallback/default case for SwitchViewhelper
[Packages/TYPO3.CMS.git] / typo3 / sysext / fluid / Classes / ViewHelpers / SwitchViewHelper.php
1 <?php
2 namespace TYPO3\CMS\Fluid\ViewHelpers;
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 * Switch view helper which can be used to render content depending on a value or expression.
16 * Implements what a basic switch()-PHP-method does.
17 *
18 * = Examples =
19 *
20 * <code title="Simple Switch statement">
21 * <f:switch expression="{person.gender}">
22 * <f:case value="male">Mr.</f:case>
23 * <f:case value="female">Mrs.</f:case>
24 * <f:case default="TRUE">Mrs. or Mr.</f:case>
25 * </f:switch>
26 * </code>
27 * <output>
28 * Mr. / Mrs. (depending on the value of {person.gender}) or if no value evaluates to TRUE, default case
29 * </output>
30 *
31 * Note: Using this view helper can be a sign of weak architecture. If you end up using it extensively
32 * you might want to consider restructuring your controllers/actions and/or use partials and sections.
33 * E.g. the above example could be achieved with <f:render partial="title.{person.gender}" /> and the partials
34 * "title.male.html", "title.female.html", ...
35 * Depending on the scenario this can be easier to extend and possibly contains less duplication.
36 *
37 * @api
38 */
39 class SwitchViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper implements \TYPO3\CMS\Fluid\Core\ViewHelper\Facets\ChildNodeAccessInterface {
40
41 /**
42 * An array of \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode
43 * @var array
44 */
45 private $childNodes = array();
46
47 /**
48 * @var mixed
49 */
50 protected $backupSwitchExpression = NULL;
51
52 /**
53 * @var boolean
54 */
55 protected $backupBreakState = FALSE;
56
57 /**
58 * Setter for ChildNodes - as defined in ChildNodeAccessInterface
59 *
60 * @param array $childNodes Child nodes of this syntax tree node
61 * @return void
62 */
63 public function setChildNodes(array $childNodes) {
64 $this->childNodes = $childNodes;
65 }
66
67 /**
68 * @param mixed $expression
69 * @return string the rendered string
70 * @api
71 */
72 public function render($expression) {
73 $content = '';
74 $this->backupSwitchState();
75 $templateVariableContainer = $this->renderingContext->getViewHelperVariableContainer();
76
77 $templateVariableContainer->addOrUpdate('TYPO3\CMS\Fluid\ViewHelpers\SwitchViewHelper', 'switchExpression', $expression);
78 $templateVariableContainer->addOrUpdate('TYPO3\CMS\Fluid\ViewHelpers\SwitchViewHelper', 'break', FALSE);
79
80 foreach ($this->childNodes as $childNode) {
81 if (
82 !$childNode instanceof \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\ViewHelperNode
83 || $childNode->getViewHelperClassName() !== 'TYPO3\CMS\Fluid\ViewHelpers\CaseViewHelper'
84 ) {
85 continue;
86 }
87 $content = $childNode->evaluate($this->renderingContext);
88 if ($templateVariableContainer->get('TYPO3\CMS\Fluid\ViewHelpers\SwitchViewHelper', 'break') === TRUE) {
89 break;
90 }
91 }
92
93 $templateVariableContainer->remove('TYPO3\CMS\Fluid\ViewHelpers\SwitchViewHelper', 'switchExpression');
94 $templateVariableContainer->remove('TYPO3\CMS\Fluid\ViewHelpers\SwitchViewHelper', 'break');
95
96 $this->restoreSwitchState();
97 return $content;
98 }
99
100 /**
101 * Backups "switch expression" and "break" state of a possible parent switch ViewHelper to support nesting
102 *
103 * @return void
104 */
105 protected function backupSwitchState() {
106 if ($this->renderingContext->getViewHelperVariableContainer()->exists('TYPO3\CMS\Fluid\ViewHelpers\SwitchViewHelper', 'switchExpression')) {
107 $this->backupSwitchExpression = $this->renderingContext->getViewHelperVariableContainer()->get('TYPO3\CMS\Fluid\ViewHelpers\SwitchViewHelper', 'switchExpression');
108 }
109 if ($this->renderingContext->getViewHelperVariableContainer()->exists('TYPO3\CMS\Fluid\ViewHelpers\SwitchViewHelper', 'break')) {
110 $this->backupBreakState = $this->renderingContext->getViewHelperVariableContainer()->get('TYPO3\CMS\Fluid\ViewHelpers\SwitchViewHelper', 'break');
111 }
112 }
113
114 /**
115 * Restores "switch expression" and "break" states that might have been backed up in backupSwitchState() before
116 *
117 * @return void
118 */
119 protected function restoreSwitchState() {
120 if ($this->backupSwitchExpression !== NULL) {
121 $this->renderingContext->getViewHelperVariableContainer()->addOrUpdate(
122 'TYPO3\CMS\Fluid\ViewHelpers\SwitchViewHelper',
123 'switchExpression',
124 $this->backupSwitchExpression
125 );
126 }
127 if ($this->backupBreakState !== FALSE) {
128 $this->renderingContext->getViewHelperVariableContainer()->addOrUpdate('TYPO3\CMS\Fluid\ViewHelpers\SwitchViewHelper', 'break', TRUE);
129 }
130 }
131 }