Completed
Push — master ( 60e1ff...4cc4cc )
by Marc
02:30
created

CycleViewHelper::render()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
namespace TYPO3Fluid\Fluid\ViewHelpers;
3
4
/*
5
 * This file belongs to the package "TYPO3 Fluid".
6
 * See LICENSE.txt that was shipped with this package.
7
 */
8
9
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
10
use TYPO3Fluid\Fluid\Core\ViewHelper;
11
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
12
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
13
14
/**
15
 * This ViewHelper cycles through the specified values.
16
 * This can be often used to specify CSS classes for example.
17
 * **Note:** To achieve the "zebra class" effect in a loop you can also use the "iteration" argument of the **for** ViewHelper.
18
 *
19
 * = Examples =
20
 *
21
 * <code title="Simple">
22
 * <f:for each="{0:1, 1:2, 2:3, 3:4}" as="foo"><f:cycle values="{0: 'foo', 1: 'bar', 2: 'baz'}" as="cycle">{cycle}</f:cycle></f:for>
23
 * </code>
24
 * <output>
25
 * foobarbazfoo
26
 * </output>
27
 *
28
 * <code title="Alternating CSS class">
29
 * <ul>
30
 *   <f:for each="{0:1, 1:2, 2:3, 3:4}" as="foo">
31
 *     <f:cycle values="{0: 'odd', 1: 'even'}" as="zebraClass">
32
 *       <li class="{zebraClass}">{foo}</li>
33
 *     </f:cycle>
34
 *   </f:for>
35
 * </ul>
36
 * </code>
37
 * <output>
38
 * <ul>
39
 *   <li class="odd">1</li>
40
 *   <li class="even">2</li>
41
 *   <li class="odd">3</li>
42
 *   <li class="even">4</li>
43
 * </ul>
44
 * </output>
45
 *
46
 * Note: The above examples could also be achieved using the "iteration" argument of the ForViewHelper
47
 *
48
 * @api
49
 */
50
class CycleViewHelper extends AbstractViewHelper
51
{
52
    use CompileWithRenderStatic;
53
54
    /**
55
     * @var boolean
56
     */
57
    protected $escapeOutput = false;
58
59
    /**
60
     * @return void
61
     */
62
    public function initializeArguments()
63
    {
64
        parent::initializeArguments();
65
        $this->registerArgument('values', 'array', 'The array or object implementing \ArrayAccess (for example \SplObjectStorage) to iterated over');
66
        $this->registerArgument('as', 'strong', 'The name of the iteration variable', true);
67
    }
68
69
    /**
70
     * @param array $arguments
71
     * @param \Closure $renderChildrenClosure
72
     * @param RenderingContextInterface $renderingContext
73
     * @return mixed
74
     */
75
    public static function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext)
76
    {
77
        $values = $arguments['values'];
78
        $as = $arguments['as'];
79
        if ($values === null) {
80
            return $renderChildrenClosure();
81
        }
82
        $values = static::initializeValues($values);
83
        $index = static::initializeIndex($as, $renderingContext->getViewHelperVariableContainer());
84
85
        $currentValue = isset($values[$index]) ? $values[$index] : null;
86
87
        $renderingContext->getVariableProvider()->add($as, $currentValue);
88
        $output = $renderChildrenClosure();
89
        $renderingContext->getVariableProvider()->remove($as);
90
91
        $index++;
92
        if (!isset($values[$index])) {
93
            $index = 0;
94
        }
95
        $renderingContext->getViewHelperVariableContainer()->addOrUpdate(static::class, $as, $index);
96
97
        return $output;
98
    }
99
100
    /**
101
     * @param mixed $values
102
     * @return array
103
     * @throws ViewHelper\Exception
104
     */
105
    protected static function initializeValues($values)
106
    {
107
        if (is_array($values)) {
108
            return array_values($values);
109
        }
110
111
        if (is_object($values) && $values instanceof \Traversable) {
112
            return iterator_to_array($values, false);
113
        }
114
115
        throw new ViewHelper\Exception('CycleViewHelper only supports arrays and objects implementing \Traversable interface', 1248728393);
116
    }
117
118
    /**
119
     * @param string $as
120
     * @param ViewHelper\ViewHelperVariableContainer $viewHelperVariableContainer
121
     * @return integer
122
     */
123
    protected static function initializeIndex($as, ViewHelper\ViewHelperVariableContainer $viewHelperVariableContainer)
124
    {
125
        $index = 0;
126
        if ($viewHelperVariableContainer->exists(static::class, $as)) {
127
            $index = $viewHelperVariableContainer->get(static::class, $as);
128
        }
129
130
        return $index;
131
    }
132
}
133