Completed
Push — unit-test-services ( f70ec7...99caba )
by Romain
02:28
created

SlotViewHelperService::restoreTemplateVariables()   B

Complexity

Conditions 5
Paths 16

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 14
rs 8.8571
c 0
b 0
f 0
cc 5
eloc 8
nc 16
nop 2
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;
15
16
use Closure;
17
use Romm\Formz\Exceptions\EntryNotFoundException;
18
use TYPO3\CMS\Core\SingletonInterface;
19
use TYPO3\CMS\Core\Utility\ArrayUtility;
20
use TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface;
21
22
class SlotViewHelperService implements SingletonInterface
23
{
24
    /**
25
     * Contains the closures which will render the registered slots. The keys
26
     * of this array are the names of the slots.
27
     *
28
     * @var Closure[]
29
     */
30
    private $closures = [];
31
32
    /**
33
     * @var array[]
34
     */
35
    private $arguments = [];
36
37
    /**
38
     * @var array[]
39
     */
40
    private $injectedVariables = [];
41
42
    /**
43
     * @var array[]
44
     */
45
    private $savedVariables = [];
46
47
    /**
48
     * Adds a closure - which will render the slot with the given name - to the
49
     * private storage in this class.
50
     *
51
     * @param string  $name
52
     * @param Closure $closure
53
     * @param array   $arguments
54
     */
55
    public function addSlot($name, Closure $closure, array $arguments)
56
    {
57
        $this->closures[$name] = $closure;
58
        $this->arguments[$name] = $arguments;
59
    }
60
61
    /**
62
     * Returns the closure which will render the slot with the given name.
63
     *
64
     * @param string $name
65
     * @return Closure
66
     * @throws EntryNotFoundException
67
     */
68
    public function getSlotClosure($name)
69
    {
70
        if (false === $this->hasSlot($name)) {
71
            throw EntryNotFoundException::slotClosureSlotNotFound($name);
72
        }
73
74
        return $this->closures[$name];
75
    }
76
77
    /**
78
     * Returns the closure which will render the slot with the given name.
79
     *
80
     * @param string $name
81
     * @return array
82
     * @throws EntryNotFoundException
83
     */
84
    public function getSlotArguments($name)
85
    {
86
        if (false === $this->hasSlot($name)) {
87
            throw EntryNotFoundException::slotArgumentsSlotNotFound($name);
88
        }
89
90
        return $this->arguments[$name];
91
    }
92
93
    /**
94
     * @param string $name
95
     * @return bool
96
     */
97
    public function hasSlot($name)
98
    {
99
        return true === isset($this->closures[$name]);
100
    }
101
102
    /**
103
     * Will merge the given arguments with the ones registered by the given
104
     * slot, and inject them in the template variable container.
105
     *
106
     * Note that the variables that are already defined are first saved before
107
     * being overridden, so they can be restored later.
108
     *
109
     * @param string                    $slotName
110
     * @param array                     $arguments
111
     * @param RenderingContextInterface $renderingContext
112
     */
113
    public function addTemplateVariables($slotName, array $arguments, RenderingContextInterface $renderingContext)
114
    {
115
        $templateVariableContainer = $renderingContext->getTemplateVariableContainer();
0 ignored issues
show
Bug introduced by
The method getTemplateVariableContainer() does not seem to exist on object<TYPO3\CMS\Fluid\C...deringContextInterface>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
116
        $savedArguments = [];
117
118
        ArrayUtility::mergeRecursiveWithOverrule(
119
            $arguments,
120
            $this->getSlotArguments($slotName)
121
        );
122
123
        foreach ($arguments as $key => $value) {
124
            if ($templateVariableContainer->exists($key)) {
125
                $savedArguments[$key] = $templateVariableContainer->get($key);
126
                $templateVariableContainer->remove($key);
127
            }
128
129
            $templateVariableContainer->add($key, $value);
130
        }
131
132
        $this->injectedVariables[$slotName] = $arguments;
133
        $this->savedVariables[$slotName] = $savedArguments;
134
    }
135
136
    /**
137
     * Will remove all variables previously injected in the template variable
138
     * container, and restore the ones that were saved before being overridden.
139
     *
140
     * @param string                    $slotName
141
     * @param RenderingContextInterface $renderingContext
142
     */
143
    public function restoreTemplateVariables($slotName, RenderingContextInterface $renderingContext)
144
    {
145
        $templateVariableContainer = $renderingContext->getTemplateVariableContainer();
0 ignored issues
show
Bug introduced by
The method getTemplateVariableContainer() does not seem to exist on object<TYPO3\CMS\Fluid\C...deringContextInterface>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
146
        $mergedArguments = (isset($this->injectedVariables[$slotName])) ? $this->injectedVariables[$slotName] : [];
147
        $savedArguments = (isset($this->savedVariables[$slotName])) ? $this->savedVariables[$slotName] : [];
148
149
        foreach (array_keys($mergedArguments) as $key) {
150
            $templateVariableContainer->remove($key);
151
        }
152
153
        foreach ($savedArguments as $key => $value) {
154
            $templateVariableContainer->add($key, $value);
155
        }
156
    }
157
158
    /**
159
     * Resets the service variables.
160
     */
161
    public function resetState()
162
    {
163
        $this->closures = [];
164
        $this->arguments = [];
165
        $this->injectedVariables = [];
166
        $this->savedVariables = [];
167
    }
168
}
169