Completed
Push — feature/middleware-tmp ( 8f1e4d )
by Romain
01:57
created

ControllerProcessor   A

Complexity

Total Complexity 18

Size/Duplication

Total Lines 201
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 0
Metric Value
wmc 18
lcom 1
cbo 4
dl 0
loc 201
rs 10
c 0
b 0
f 0

9 Methods

Rating   Name   Duplication   Size   Complexity  
A setData() 0 19 2
A dispatch() 0 21 3
A checkFormObjectsErrors() 0 11 3
B getRequestForms() 0 23 5
A getRequest() 0 4 1
A getRequestArguments() 0 4 1
A getSettings() 0 4 1
A injectFormObjectFactory() 0 4 1
A prepare() 0 4 1
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\Controller\Processor;
15
16
use Romm\Formz\Form\FormInterface;
17
use Romm\Formz\Form\FormObject\FormObject;
18
use Romm\Formz\Form\FormObject\FormObjectFactory;
19
use Romm\Formz\Service\Traits\ExtendedSelfInstantiateTrait;
20
use TYPO3\CMS\Core\SingletonInterface;
21
use TYPO3\CMS\Extbase\Mvc\Controller\Argument;
22
use TYPO3\CMS\Extbase\Mvc\Controller\Arguments;
23
use TYPO3\CMS\Extbase\Mvc\Exception\StopActionException;
24
use TYPO3\CMS\Extbase\Mvc\Request as MvcRequest;
25
use TYPO3\CMS\Extbase\Mvc\Web\Request;
26
27
class ControllerProcessor implements SingletonInterface
28
{
29
    use ExtendedSelfInstantiateTrait;
30
31
    /**
32
     * @var FormObjectFactory
33
     */
34
    protected $formObjectFactory;
35
36
    /**
37
     * @var FormObject[]
38
     */
39
    protected $formArguments;
40
41
    /**
42
     * @var bool
43
     */
44
    protected $dispatched = false;
45
46
    /**
47
     * @var Request
48
     */
49
    protected $request;
50
51
    /**
52
     * @var Request
53
     */
54
    protected $realRequest;
55
56
    /**
57
     * @var Request
58
     */
59
    protected $originalRequest;
60
61
    /**
62
     * @var Arguments
63
     */
64
    protected $requestArguments;
65
66
    /**
67
     * @var array
68
     */
69
    protected $settings = [];
70
71
    /**
72
     * Contains information about the last request that was dispatched to FormZ.
73
     * It is used to prevent infinite loop.
74
     *
75
     * @var string
76
     */
77
    protected $lastDispatchedRequest;
78
79
    /**
80
     * @param MvcRequest $request
81
     * @param Arguments  $requestArguments
82
     * @return $this
83
     */
84
    public static function prepare(MvcRequest $request, Arguments $requestArguments)
85
    {
86
        return self::get()->setData($request, $requestArguments, []);
87
    }
88
89
    /**
90
     * Injects the data needed for this class to work properly. This method must
91
     * be called before the `dispatch` method is called.
92
     *
93
     * @param MvcRequest $request
94
     * @param Arguments  $requestArguments
95
     * @param array      $settings
96
     * @return $this
97
     */
98
    public function setData(MvcRequest $request, Arguments $requestArguments, array $settings)
99
    {
100
        /** @var Request $request */
101
        $dispatchedRequest = $request->getControllerObjectName() . '::' . $request->getControllerActionName();
102
103
        if ($dispatchedRequest !== $this->lastDispatchedRequest) {
104
            $this->lastDispatchedRequest = $dispatchedRequest;
105
106
            $this->realRequest = $request;
107
            $this->request = clone $request;
108
            $this->originalRequest = clone $request;
109
            $this->requestArguments = $requestArguments;
110
            $this->settings = $settings;
111
            $this->formArguments = null;
0 ignored issues
show
Documentation Bug introduced by
It seems like null of type null is incompatible with the declared type array<integer,object<Rom...FormObject\FormObject>> of property $formArguments.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
112
            $this->dispatched = false;
113
        }
114
115
        return $this;
116
    }
117
118
    /**
119
     * Will dispatch the current request to the form controller, which will take
120
     * care of processing everything properly.
121
     *
122
     * In case no form is found in the controller action parameters, the current
123
     * request is not killed.
124
     *
125
     * @throws StopActionException
126
     */
127
    public function dispatch()
128
    {
129
        if (false === $this->dispatched) {
130
            $this->dispatched = true;
131
132
            if (false === empty($this->getRequestForms())) {
133
                $this->realRequest->setDispatched(false);
134
                $this->realRequest->setControllerVendorName('Romm');
135
                $this->realRequest->setControllerName('Form');
136
                $this->realRequest->setControllerExtensionName('Formz');
137
                $this->realRequest->setControllerActionName('processForm');
138
                $this->realRequest->setArguments([
139
                    'originalRequest' => $this->originalRequest
140
                ]);
141
142
                $this->checkFormObjectsErrors();
143
144
                throw new StopActionException;
145
            }
146
        }
147
    }
148
149
    /**
150
     * Will check if the form objects found in the request arguments contain
151
     * configuration errors. If they do, we dispatch the request to the error
152
     * view, where all errors will be explained properly to the user.
153
     */
154
    protected function checkFormObjectsErrors()
155
    {
156
        foreach ($this->getRequestForms() as $formObject) {
157
            if ($formObject->getDefinitionValidationResult()->hasErrors()) {
158
                $this->realRequest->setControllerActionName('formObjectError');
159
                $this->realRequest->setArguments(['formObject' => $formObject]);
160
161
                break;
162
            }
163
        }
164
    }
165
166
    /**
167
     * Loops on the request arguments, and pick up each one that is a form
168
     * instance (it implements `FormInterface`).
169
     *
170
     * @return FormObject[]
171
     */
172
    public function getRequestForms()
173
    {
174
        if (null === $this->formArguments) {
175
            $this->formArguments = [];
176
177
            /** @var Argument $argument */
178
            foreach ($this->requestArguments as $argument) {
179
                $type = $argument->getDataType();
180
181
                if (class_exists($type)
182
                    && in_array(FormInterface::class, class_implements($type))
183
                ) {
184
                    $formClassName = $argument->getDataType();
185
                    $formName = $argument->getName();
186
187
                    $formObject = $this->formObjectFactory->getInstanceWithClassName($formClassName, $formName);
188
                    $this->formArguments[$formName] = $formObject;
189
                }
190
            }
191
        }
192
193
        return $this->formArguments;
194
    }
195
196
    /**
197
     * @return Request
198
     */
199
    public function getRequest()
200
    {
201
        return $this->request;
202
    }
203
204
    /**
205
     * @return Arguments
206
     */
207
    public function getRequestArguments()
208
    {
209
        return $this->requestArguments;
210
    }
211
212
    /**
213
     * @return array
214
     */
215
    public function getSettings()
216
    {
217
        return $this->settings;
218
    }
219
220
    /**
221
     * @param FormObjectFactory $formObjectFactory
222
     */
223
    public function injectFormObjectFactory(FormObjectFactory $formObjectFactory)
224
    {
225
        $this->formObjectFactory = $formObjectFactory;
226
    }
227
}
228