Completed
Push — middleware-wip ( 7e7b3d...2c3646 )
by Romain
02:25
created

FormController::aze()   B

Complexity

Conditions 5
Paths 3

Size

Total Lines 22
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 22
rs 8.6737
c 0
b 0
f 0
cc 5
eloc 12
nc 3
nop 0

2 Methods

Rating   Name   Duplication   Size   Complexity  
A FormController::injectHashService() 0 4 1
A FormController::injectFormObjectFactory() 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;
15
16
use Romm\Formz\Core\Core;
17
use Romm\Formz\Form\FormInterface;
18
use Romm\Formz\Form\FormObject;
19
use Romm\Formz\Form\FormObjectFactory;
20
use Romm\Formz\Middleware\State\MiddlewareState;
21
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
22
use TYPO3\CMS\Extbase\Mvc\Controller\Argument;
23
use TYPO3\CMS\Extbase\Security\Cryptography\HashService;
24
25
class FormController extends ActionController
26
{
27
    /**
28
     * @var FormObject[]
29
     */
30
    protected $formArguments = [];
31
32
    /**
33
     * @var FormzControllerContext
34
     */
35
    protected $formzControllerContext;
36
37
    /**
38
     * @var HashService
39
     */
40
    protected $hashService;
41
42
    /**
43
     * @var FormObjectFactory
44
     */
45
    protected $formObjectFactory;
46
47
    /**
48
     * Main action used to dispatch the request properly, depending on FormZ
49
     * configuration.
50
     *
51
     * The request is based on the previously called controller action, and is
52
     * used to list which forms are handled (every argument of the action method
53
     * that implements the interface `FormInterface`).
54
     *
55
     * Middlewares will be called for each form argument, and may modify the
56
     * request, which is then dispatched again with modified data.
57
     */
58
    public function processFormAction()
59
    {
60
        $tt = new \TYPO3\CMS\Core\TimeTracker\TimeTracker();
61
        $tt->start();
62
63
        $request = $this->formzControllerContext->getRequest();
64
65
        $this->invokeMiddlewares();
66
67
        $this->formzControllerContext->setDispatched(true);
68
69
        $result = $request->getOriginalRequestMappingResults();
70
        $this->controllerContext->getRequest()->setOriginalRequestMappingResults($result);
71
72
        if ($result->hasErrors()) {
73
            $arguments = $request->getArguments();
74
            $request = $request->getReferringRequest();
75
76
            foreach ($arguments as $name => $value) {
77
                /** @var Argument $argument */
78
                $request->setArgument($name, $value);
79
            }
80
        }
81
82
        $this->request->setControllerVendorName($this->formzControllerContext->getVendorName());
83
        $this->forward(
84
            $request->getControllerActionName(),
85
            $request->getControllerName(),
86
            $request->getControllerExtensionName(),
87
            $request->getArguments()
88
        );
89
    }
90
91
    /**
92
     * Will fetch every form argument for this request, and dispatch every
93
     * middleware that was registered in its TypoScript configuration.
94
     */
95
    protected function invokeMiddlewares()
96
    {
97
        foreach ($this->getRequestForms() as $formObject) {
98
            $formObject->reset();
99
100
            /*
101
             * If the configuration contains errors, then the middlewares
102
             * configuration may be corrupted as well, so the risk to dispatch
103
             * middlewares can not be taken.
104
             */
105
            if (false === $formObject->getConfigurationValidationResult()->hasErrors()) {
106
                /** @var MiddlewareState $middlewareFactory */
107
                $middlewareFactory = Core::instantiate(MiddlewareState::class, $formObject, $this->formzControllerContext);
108
109
                $middlewareFactory->run();
110
            }
111
        }
112
    }
113
114
    /**
115
     * Loops on the request arguments, and pick up each one that is a form
116
     * instance (it implements `FormInterface`).
117
     *
118
     * @return FormObject[]
119
     */
120
    protected function getRequestForms()
121
    {
122
        if (empty($this->formArguments)) {
123
            /** @var Argument $argument */
124
            foreach ($this->formzControllerContext->getArguments() as $argument) {
125
                $type = $argument->getDataType();
126
127
                if (class_exists($type)
128
                    && in_array(FormInterface::class, class_implements($type))
129
                ) {
130
                    $formClassName = $argument->getDataType();
131
                    $formName = $argument->getName();
132
133
                    $formObject = $this->formObjectFactory->getInstanceFromClassName($formClassName, $formName);
134
                    $this->formArguments[$formName] = $formObject;
135
                }
136
            }
137
        }
138
139
        return $this->formArguments;
140
    }
141
142
    /**
143
     * @todo
144
     *
145
     * @return array
146
     */
147
    protected function getRequestData()
148
    {
149
        $requestData = [];
150
151
        if ($this->request->hasArgument('formz')) {
152
            $requestData = $this->request->getArgument('formz');
153
            $requestData = $this->hashService->validateAndStripHmac($requestData);
154
            $requestData = unserialize(base64_decode($requestData));
155
        }
156
157
        return $requestData;
158
    }
159
160
    /**
161
     * @param FormzControllerContext $formzControllerContext
162
     */
163
    public function injectFormzControllerContext(FormzControllerContext $formzControllerContext)
164
    {
165
        $this->formzControllerContext = $formzControllerContext;
166
    }
167
168
    /**
169
     * @param HashService $hashService
170
     */
171
    public function injectHashService(HashService $hashService)
172
    {
173
        $this->hashService = $hashService;
174
    }
175
176
    /**
177
     * @param FormObjectFactory $formObjectFactory
178
     */
179
    public function injectFormObjectFactory(FormObjectFactory $formObjectFactory)
180
    {
181
        $this->formObjectFactory = $formObjectFactory;
182
    }
183
}
184