Completed
Push — middleware-wip ( 3d734d...55159c )
by Romain
02:44
created

MiddlewareState::getArguments()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
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\Middleware\State;
15
16
use Romm\Formz\Controller\ControllerState;
17
use Romm\Formz\Error\FormResult;
18
use Romm\Formz\Form\FormObject;
19
use Romm\Formz\Middleware\Item\Begin\BeginMiddleware;
20
use Romm\Formz\Middleware\Item\End\EndMiddleware;
21
use Romm\Formz\Middleware\MiddlewareInterface;
22
use TYPO3\CMS\Extbase\Mvc\Controller\Arguments;
23
use TYPO3\CMS\Extbase\Mvc\Web\Request;
24
25
/**
26
 * @todo: loop on middlewares and detect which ones are using signals that wont
27
 * be processed. This should probably be a validator put on:
28
 *      \Romm\Formz\Configuration\Form\Form::$middlewares
29
 */
30
class MiddlewareState
31
{
32
    /**
33
     * @var MiddlewareInterface[]
34
     */
35
    protected $list = [];
36
37
    /**
38
     * @var FormObject
39
     */
40
    protected $formObject;
41
42
    /**
43
     * @var FormResult
44
     */
45
    protected $result;
46
47
    /**
48
     * @var Request
49
     */
50
    protected $request;
51
52
    /**
53
     * @var Arguments
54
     */
55
    protected $arguments;
56
57
    /**
58
     * @var array
59
     */
60
    protected $settings;
61
62
    /**
63
     * @see getSignalSortedMiddlewares()
64
     *
65
     * @var array
66
     */
67
    protected $signalSortedMiddlewares = [];
68
69
    /**
70
     * This context is activated when the request is validating a specific field
71
     * and not the whole form. In this case, special behaviours may occur, and
72
     * the state instance should be aware of it.
73
     *
74
     * @var bool
75
     */
76
    protected $singleFieldValidationContext = false;
77
78
    /**
79
     * @param FormObject      $formObject
80
     * @param ControllerState $controllerState
81
     */
82
    public function __construct(FormObject $formObject, ControllerState $controllerState)
83
    {
84
        $this->formObject = $formObject;
85
        $this->request = $controllerState->getRequest();
86
        $this->arguments = $controllerState->getArguments();
87
        $this->settings = $controllerState->getSettings();
88
89
        foreach ($this->formObject->getConfiguration()->getMiddlewares() as $middleware) {
90
            $middleware->bindMiddlewareState($this);
91
            $middleware->initialize();
92
        }
93
    }
94
95
    /**
96
     * Will run and process trough every middleware registered for the current
97
     * form object.
98
     */
99
    public function run()
100
    {
101
        $beginMiddleware = new BeginMiddleware;
102
        $beginMiddleware->bindMiddlewareState($this);
103
        $beginMiddleware->execute();
104
105
        $endMiddleware = new EndMiddleware;
106
        $endMiddleware->bindMiddlewareState($this);
107
        $endMiddleware->execute();
108
    }
109
110
    /**
111
     * Returns the sorted list of middlewares bound to the given signal name.
112
     *
113
     * @param string $signalName
114
     * @return array
115
     */
116
    public function getMiddlewaresBoundToSignal($signalName)
117
    {
118
        $signalSortedMiddlewares = $this->getSignalSortedMiddlewares();
119
120
        return (isset($signalSortedMiddlewares[$signalName]))
121
            ? $signalSortedMiddlewares[$signalName]
122
            : [];
123
    }
124
125
    /**
126
     * Returns a sorted list of the registered middlewares: the first level is
127
     * the signal used by the group, and the second level is the group of
128
     * middlewares, sorted by descendant priority of each middleware.
129
     *
130
     * @return array
131
     */
132
    protected function getSignalSortedMiddlewares()
133
    {
134
        if (empty($this->signalSortedMiddlewares)) {
135
            $this->signalSortedMiddlewares = [];
136
            $middlewareList = [];
137
138
            foreach ($this->getFilteredMiddlewares() as $middleware) {
139
                $signal = $middleware->getBoundSignalName();
140
141
                if (false === isset($middlewareList[$signal])) {
142
                    $middlewareList[$signal] = [];
143
                }
144
145
                $middlewareList[$signal][] = $middleware;
146
            }
147
148
            foreach ($middlewareList as $key => $list) {
149
                $this->signalSortedMiddlewares[$key] = $this->sortMiddlewaresListByPriority($list);
150
            }
151
        }
152
153
        return $this->signalSortedMiddlewares;
154
    }
155
156
    /**
157
     * @return MiddlewareInterface[]
158
     */
159
    protected function getFilteredMiddlewares()
160
    {
161
        $middlewares = $this->formObject->getConfiguration()->getMiddlewares();
162
163
        if ($this->inSingleFieldValidationContext()) {
164
            foreach ($middlewares as $key => $middleware) {
165
                if ($middleware instanceof RemoveFromSingleFieldValidationContext) {
166
                    unset($middlewares[$key]);
167
                }
168
            }
169
        }
170
171
        return $middlewares;
172
    }
173
174
    /**
175
     * Will sort and return a middlewares list based on the priority of each
176
     * middleware. The middlewares with the highest priority will be placed at
177
     * the top of the list.
178
     *
179
     * @param array $list
180
     * @return array
181
     */
182
    private function sortMiddlewaresListByPriority(array $list)
183
    {
184
        usort($list, function (MiddlewareInterface $a, MiddlewareInterface $b) {
185
            $priorityA = (int)$a->getPriority();
186
            $priorityB = (int)$b->getPriority();
187
188
            if ($priorityA === $priorityB) {
189
                return 0;
190
            }
191
192
            return $priorityA < $priorityB
193
                ? 1
194
                : -1;
195
        });
196
197
        return $list;
198
    }
199
200
    /**
201
     * @return FormObject
202
     */
203
    public function getFormObject()
204
    {
205
        return $this->formObject;
206
    }
207
208
    /**
209
     * @return FormResult
210
     */
211
    public function getResult()
212
    {
213
        if (null === $this->result) {
214
            $this->result = new FormResult;
215
        }
216
217
        return $this->result;
218
    }
219
220
    /**
221
     * @return Request
222
     */
223
    public function getRequest()
224
    {
225
        return $this->request;
226
    }
227
228
    /**
229
     * @return Arguments
230
     */
231
    public function getArguments()
232
    {
233
        return $this->arguments;
234
    }
235
236
    /**
237
     * @return array
238
     */
239
    public function getSettings()
240
    {
241
        return $this->settings;
242
    }
243
244
    /**
245
     * @return bool
246
     */
247
    public function inSingleFieldValidationContext()
248
    {
249
        return $this->singleFieldValidationContext;
250
    }
251
252
    /**
253
     * @see $singleFieldValidationContext
254
     */
255
    public function activateSingleFieldValidationContext()
256
    {
257
        $this->singleFieldValidationContext = true;
258
    }
259
}
260