Completed
Pull Request — master (#429)
by Claus
01:56
created

getTopmostDelegateVariableProvider()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
namespace TYPO3Fluid\Fluid\Core\ViewHelper;
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\Variables\VariableProviderInterface;
10
use TYPO3Fluid\Fluid\View\ViewInterface;
11
12
/**
13
 * A key/value store that can be used by ViewHelpers to communicate between each other.
14
 *
15
 * @api
16
 */
17
class ViewHelperVariableContainer
18
{
19
20
    /**
21
     * Two-dimensional object array storing the values. The first dimension is the fully qualified ViewHelper name,
22
     * and the second dimension is the identifier for the data the ViewHelper wants to store.
23
     *
24
     * @var array
25
     */
26
    protected $objects = [];
27
28
    /**
29
     * @var ViewInterface
30
     */
31
    protected $view;
32
33
    /**
34
     * @var VariableProviderInterface[]
35
     */
36
    protected $delegates = [];
37
38
    /**
39
     * Push a new delegate variable container to a stack.
40
     *
41
     * If a ViewHelper requires a storage to collect variables which, for
42
     * example, are filled by evaluating the child (tag content) closure,
43
     * this method can be used to add a special delegate variable container
44
     * stored in a stack. Once the variables you need to collect have been
45
     * collected, calling `popDelegateVariableProvider` removes the delegate
46
     * from the stack.
47
     *
48
     * The point of a stack is to avoid resetting a storage every time a
49
     * ViewHelper is rendered. In the case of `f:render` it means one storage
50
     * is created and filled for every one call to the ViewHelper.
51
     *
52
     * It is VITAL that you also "pop" any delegate you push to this stack!
53
     *
54
     * @param VariableProviderInterface $variableProvider
55
     */
56
    public function pushDelegateVariableProvider(VariableProviderInterface $variableProvider)
57
    {
58
        $this->delegates[] = $variableProvider;
59
    }
60
61
    /**
62
     * Get the topmost delegate variable container that was previously pushed
63
     * onto the stack by pushDelegateVariableContainer(). This method returns
64
     * a reference to the storage that was last added to the stack without
65
     * removing the variable provider from the stack.
66
     *
67
     * Is used in ViewHelpers that assign variables in variable providers in
68
     * the stack - as a means to get the variable storage used by the "closest
69
     * parent", e.g. when called in `f:argument` used inside `f:render`, will
70
     * read the delegate variable provider inserted by that parent `f:render`.
71
     *
72
     * @return VariableProviderInterface|null
73
     */
74
    public function getTopmostDelegateVariableProvider()
75
    {
76
        return end($this->delegates) ?: null;
77
    }
78
79
    /**
80
     * Return and REMOVE the topmost delegate variable provider. This method
81
     * must be called after you finish sub-rendering with a delegated variable
82
     * provider that was added with `pushDelegateVariableProvider`. Calling
83
     * the method removes the delegate and returns the stack to the previous
84
     * state it was in.
85
     *
86
     * To avoid removing from the stack, use `getTopmostDelegateVariableProvider`.
87
     *
88
     * @param string $viewHelperClassName
0 ignored issues
show
Bug introduced by
There is no parameter named $viewHelperClassName. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
89
     * @return VariableProviderInterface|null
90
     */
91
    public function popDelegateVariableProvider()
92
    {
93
        return array_pop($this->delegates);
94
    }
95
96
    /**
97
     * Add a variable to the Variable Container. Make sure that $viewHelperName is ALWAYS set
98
     * to your fully qualified ViewHelper Class Name
99
     *
100
     * @param string $viewHelperName The ViewHelper Class name (Fully qualified, like "TYPO3Fluid\Fluid\ViewHelpers\ForViewHelper")
101
     * @param string $key Key of the data
102
     * @param mixed $value The value to store
103
     * @return void
104
     * @api
105
     */
106
    public function add($viewHelperName, $key, $value)
107
    {
108
        $this->addOrUpdate($viewHelperName, $key, $value);
109
    }
110
111
    /**
112
     * Adds, or overrides recursively, all current variables defined in associative
113
     * array or Traversable (with string keys!).
114
     *
115
     * @param string $viewHelperName The ViewHelper Class name (Fully qualified, like "TYPO3Fluid\Fluid\ViewHelpers\ForViewHelper")
116
     * @param array|\Traversable $variables An associative array of all variables to add
117
     * @return void
118
     * @api
119
     */
120
    public function addAll($viewHelperName, $variables)
121
    {
122
        if (!is_array($variables) && !$variables instanceof \Traversable) {
123
            throw new \InvalidArgumentException(
124
                'Invalid argument type for $variables in ViewHelperVariableContainer->addAll(). Expects array/Traversable ' .
125
                'but received ' . (is_object($variables) ? get_class($variables) : gettype($variables)),
126
                1501425195
127
            );
128
        }
129
        $this->objects[$viewHelperName] = array_replace_recursive(
130
            isset($this->objects[$viewHelperName]) ? $this->objects[$viewHelperName] : [],
131
            $variables instanceof \Traversable ? iterator_to_array($variables) : $variables
132
        );
133
    }
134
135
    /**
136
     * Add a variable to the Variable Container. Make sure that $viewHelperName is ALWAYS set
137
     * to your fully qualified ViewHelper Class Name.
138
     * In case the value is already inside, it is silently overridden.
139
     *
140
     * @param string $viewHelperName The ViewHelper Class name (Fully qualified, like "TYPO3Fluid\Fluid\ViewHelpers\ForViewHelper")
141
     * @param string $key Key of the data
142
     * @param mixed $value The value to store
143
     * @return void
144
     */
145
    public function addOrUpdate($viewHelperName, $key, $value)
146
    {
147
        if (!isset($this->objects[$viewHelperName])) {
148
            $this->objects[$viewHelperName] = [];
149
        }
150
        $this->objects[$viewHelperName][$key] = $value;
151
    }
152
153
    /**
154
     * Gets a variable which is stored
155
     *
156
     * @param string $viewHelperName The ViewHelper Class name (Fully qualified, like "TYPO3Fluid\Fluid\ViewHelpers\ForViewHelper")
157
     * @param string $key Key of the data
158
     * @param mixed $default Default value to use if no value is found.
159
     * @return mixed The object stored
160
     * @api
161
     */
162
    public function get($viewHelperName, $key, $default = null)
163
    {
164
        return $this->exists($viewHelperName, $key) ? $this->objects[$viewHelperName][$key] : $default;
165
    }
166
167
    /**
168
     * Gets all variables stored for a particular ViewHelper
169
     *
170
     * @param string $viewHelperName The ViewHelper Class name (Fully qualified, like "TYPO3Fluid\Fluid\ViewHelpers\ForViewHelper")
171
     * @param mixed $default
172
     * @return array
173
     */
174
    public function getAll($viewHelperName, $default = null)
175
    {
176
        return array_key_exists($viewHelperName, $this->objects) ? $this->objects[$viewHelperName] : $default;
177
    }
178
179
    /**
180
     * Determine whether there is a variable stored for the given key
181
     *
182
     * @param string $viewHelperName The ViewHelper Class name (Fully qualified, like "TYPO3Fluid\Fluid\ViewHelpers\ForViewHelper")
183
     * @param string $key Key of the data
184
     * @return boolean TRUE if a value for the given ViewHelperName / Key is stored, FALSE otherwise.
185
     * @api
186
     */
187
    public function exists($viewHelperName, $key)
188
    {
189
        return isset($this->objects[$viewHelperName]) && array_key_exists($key, $this->objects[$viewHelperName]);
190
    }
191
192
    /**
193
     * Remove a value from the variable container
194
     *
195
     * @param string $viewHelperName The ViewHelper Class name (Fully qualified, like "TYPO3Fluid\Fluid\ViewHelpers\ForViewHelper")
196
     * @param string $key Key of the data to remove
197
     * @return void
198
     * @api
199
     */
200
    public function remove($viewHelperName, $key)
201
    {
202
        unset($this->objects[$viewHelperName][$key]);
203
    }
204
205
    /**
206
     * Set the view to pass it to ViewHelpers.
207
     *
208
     * @param ViewInterface $view View to set
209
     * @return void
210
     */
211
    public function setView(ViewInterface $view)
212
    {
213
        $this->view = $view;
214
    }
215
216
    /**
217
     * Get the view.
218
     *
219
     * !!! This is NOT a public API and might still change!!!
220
     *
221
     * @return ViewInterface The View
222
     */
223
    public function getView()
224
    {
225
        return $this->view;
226
    }
227
228
    /**
229
     * Clean up for serializing.
230
     *
231
     * @return array
232
     */
233
    public function __sleep()
234
    {
235
        return ['objects'];
236
    }
237
}
238