Completed
Push — wip/steps-v9-bis ( 28f03f )
by Romain
05:32
created

SlotContextEntry::getVariableProvider()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 0
1
<?php
2
/*
3
 * 2017 Romain CANON <[email protected]>
4
 *
5
 * This file is part of the TYPO3 FormZ project.
6
 * It is free software; you can redistribute it and/or modify it
7
 * under the terms of the GNU General Public License, either
8
 * version 3 of the License, or any later version.
9
 *
10
 * For the full copyright and license information, see:
11
 * http://www.gnu.org/licenses/gpl-3.0.html
12
 */
13
14
namespace Romm\Formz\Service\ViewHelper\Slot;
15
16
use Closure;
17
use Romm\Formz\Exceptions\EntryNotFoundException;
18
use TYPO3\CMS\Core\Utility\ArrayUtility;
19
use TYPO3\CMS\Core\Utility\VersionNumberUtility;
20
use TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface;
21
use TYPO3Fluid\Fluid\Core\Variables\VariableProviderInterface;
22
23
class SlotContextEntry
24
{
25
    /**
26
     * @var RenderingContextInterface|\TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface
27
     */
28
    protected $renderingContext;
29
30
    /**
31
     * Contains the closures which will render the registered slots. The keys
32
     * of this array are the names of the slots.
33
     *
34
     * @var Closure[]
35
     */
36
    protected $closures = [];
37
38
    /**
39
     * @var array[]
40
     */
41
    protected $arguments = [];
42
43
    /**
44
     * @var array[]
45
     */
46
    protected $injectedVariables = [];
47
48
    /**
49
     * @var array[]
50
     */
51
    protected $savedVariables = [];
52
53
    /**
54
     * @param RenderingContextInterface $renderingContext
55
     */
56
    public function __construct(RenderingContextInterface $renderingContext)
57
    {
58
        $this->renderingContext = $renderingContext;
59
    }
60
61
    /**
62
     * Adds a closure - used to render the slot with the given name - to the
63
     * private storage in this class.
64
     *
65
     * @param string $name
66
     * @param Closure $closure
67
     * @param array $arguments
68
     */
69
    public function addSlot($name, Closure $closure, array $arguments)
70
    {
71
        $this->closures[$name] = $closure;
72
        $this->arguments[$name] = $arguments;
73
    }
74
75
    /**
76
     * Returns the closure which will render the slot with the given name.
77
     *
78
     * @param string $name
79
     * @return Closure
80
     * @throws EntryNotFoundException
81
     */
82
    public function getSlotClosure($name)
83
    {
84
        if (false === $this->hasSlot($name)) {
85
            throw EntryNotFoundException::slotClosureSlotNotFound($name);
86
        }
87
88
        return $this->closures[$name];
89
    }
90
91
    /**
92
     * Returns the closure which will render the slot with the given name.
93
     *
94
     * @param string $name
95
     * @return array
96
     * @throws EntryNotFoundException
97
     */
98
    public function getSlotArguments($name)
99
    {
100
        if (false === $this->hasSlot($name)) {
101
            throw EntryNotFoundException::slotArgumentsSlotNotFound($name);
102
        }
103
104
        return $this->arguments[$name];
105
    }
106
107
    /**
108
     * @param string $name
109
     * @return bool
110
     */
111
    public function hasSlot($name)
112
    {
113
        return true === isset($this->closures[$name]);
114
    }
115
116
    /**
117
     * Will merge the given arguments with the ones registered by the given
118
     * slot, and inject them in the template variable container.
119
     *
120
     * Note that the variables that are already defined are first saved before
121
     * being overridden, so they can be restored later.
122
     *
123
     * @param string $slotName
124
     * @param array $arguments
125
     */
126
    public function addTemplateVariables($slotName, array $arguments)
127
    {
128
        $templateVariableContainer = $this->getVariableProvider();
129
        $savedArguments = [];
130
131
        ArrayUtility::mergeRecursiveWithOverrule(
132
            $arguments,
133
            $this->getSlotArguments($slotName)
134
        );
135
136
        foreach ($arguments as $key => $value) {
137
            if ($templateVariableContainer->exists($key)) {
138
                $savedArguments[$key] = $templateVariableContainer->get($key);
139
                $templateVariableContainer->remove($key);
140
            }
141
142
            $templateVariableContainer->add($key, $value);
143
        }
144
145
        $this->injectedVariables[$slotName] = $arguments;
146
        $this->savedVariables[$slotName] = $savedArguments;
147
    }
148
149
    /**
150
     * Will remove all variables previously injected in the template variable
151
     * container, and restore the ones that were saved before being overridden.
152
     *
153
     * @param string $slotName
154
     */
155
    public function restoreTemplateVariables($slotName)
156
    {
157
        $templateVariableContainer = $this->getVariableProvider();
158
        $mergedArguments = (isset($this->injectedVariables[$slotName])) ? $this->injectedVariables[$slotName] : [];
159
        $savedArguments = (isset($this->savedVariables[$slotName])) ? $this->savedVariables[$slotName] : [];
160
161
        foreach (array_keys($mergedArguments) as $key) {
162
            $templateVariableContainer->remove($key);
163
        }
164
165
        foreach ($savedArguments as $key => $value) {
166
            $templateVariableContainer->add($key, $value);
167
        }
168
    }
169
170
    /**
171
     * @return VariableProviderInterface
172
     */
173
    private function getVariableProvider()
174
    {
175
        return version_compare(VersionNumberUtility::getCurrentTypo3Version(), '8.0.0', '<')
176
            ? $this->renderingContext->getTemplateVariableContainer()
177
            : $this->renderingContext->getVariableProvider();
178
    }
179
}
180