Completed
Push — middleware-wip ( e0880a...664dc8 )
by Romain
02:51
created

FormController::injectFormObjectFactory()   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 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\FormObjectFactory;
19
use Romm\Formz\Middleware\State\MiddlewareState;
20
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
21
use TYPO3\CMS\Extbase\Mvc\Controller\Argument;
22
use TYPO3\CMS\Extbase\Property\PropertyMapper;
23
use TYPO3\CMS\Extbase\Security\Cryptography\HashService;
24
25
class FormController extends ActionController
26
{
27
    /**
28
     * @var FormzControllerContext
29
     */
30
    protected $formzControllerContext;
31
32
    /**
33
     * @var HashService
34
     */
35
    protected $hashService;
36
37
    /**
38
     * @var FormObjectFactory
39
     */
40
    protected $formObjectFactory;
41
42
    /**
43
     * Main action used to dispatch the request properly, depending on FormZ
44
     * configuration.
45
     *
46
     * The request is based on the previously called controller action, and is
47
     * used to list which forms are handled (every argument of the action method
48
     * that implements the interface `FormInterface`).
49
     *
50
     * Middlewares will be called for each form argument, and may modify the
51
     * request, which is then dispatched again with modified data.
52
     */
53
    public function processFormAction()
54
    {
55
        $tt = new \TYPO3\CMS\Core\TimeTracker\TimeTracker();
56
        $tt->start();
57
58
        $request = $this->formzControllerContext->getRequest();
59
60
        $this->invokeMiddlewares();
61
62
        $this->formzControllerContext->setDispatched(true);
63
64
        $result = $request->getOriginalRequestMappingResults();
65
        $this->controllerContext->getRequest()->setOriginalRequestMappingResults($result);
66
67
        if ($result->hasErrors()) {
68
            $arguments = $request->getArguments();
69
            $request = $request->getReferringRequest();
70
71
            foreach ($arguments as $name => $value) {
72
                /** @var Argument $argument */
73
                $request->setArgument($name, $value);
74
            }
75
        }
76
77
        $this->forward(
78
            $request->getControllerActionName(),
79
            $request->getControllerName(),
80
            $request->getControllerExtensionName(),
81
            $request->getArguments()
82
        );
83
    }
84
85
    /**
86
     * Will fetch every form argument for this request, and dispatch every
87
     * middleware that was registered in its TypoScript configuration.
88
     */
89
    protected function invokeMiddlewares()
90
    {
91
        foreach ($this->getRequestFormArguments() as $argument) {
92
            $request = $this->formzControllerContext->getRequest();
93
            $formObject = $this->formObjectFactory->getInstanceFromClassName($argument->getDataType(), $argument->getName());
94
            $formObject->reset();
95
96
            if ($request->getMethod() === 'POST'
97
                && $request->hasArgument($argument->getName())
98
            ) {
99
                $formObject->markFormAsSubmitted();
100
            }
101
102
            /*
103
             * If the configuration contains errors, then the middlewares
104
             * configuration may be corrupted as well, so the risk to dispatch
105
             * middlewares can not be taken.
106
             */
107
            if (false === $formObject->getConfigurationValidationResult()->hasErrors()) {
108
                /** @var MiddlewareState $middlewareFactory */
109
                $middlewareFactory = Core::instantiate(MiddlewareState::class, $formObject, $this->formzControllerContext);
110
111
                $middlewareFactory->run();
112
            }
113
        }
114
    }
115
116
    /**
117
     * @return Argument[]
118
     */
119
    protected function getRequestFormArguments()
120
    {
121
        $formArguments = [];
122
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
                $formArguments[] = $argument;
131
            }
132
        }
133
134
        return $formArguments;
135
    }
136
137
    protected function aze()
138
    {
139
        $arguments = $this->formzControllerContext->getArguments();
140
141
        foreach ($arguments as $argument) {
142
            /** @var Argument $argument */
143
            if ($this->request->hasArgument($argument->getName())
144
                && true === class_exists($argument->getDataType())
145
                && true === in_array(FormInterface::class, class_implements($argument->getDataType()))
146
            ) {
147
                /** @var PropertyMapper $propertyMapper */
148
                $propertyMapper = Core::instantiate(PropertyMapper::class);
149
                $form = $propertyMapper->convert(
150
                    $this->request->getArgument($argument->getName()),
151
                    $argument->getDataType()
152
                );
153
                break;
154
            }
155
        }
156
157
        return $form;
0 ignored issues
show
Bug introduced by
The variable $form does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
158
    }
159
160
    /**
161
     * @todo
162
     *
163
     * @return array
164
     */
165
    protected function getRequestData()
166
    {
167
        $requestData = [];
168
169
        if ($this->request->hasArgument('formz')) {
170
            $requestData = $this->request->getArgument('formz');
171
            $requestData = $this->hashService->validateAndStripHmac($requestData);
172
            $requestData = unserialize(base64_decode($requestData));
173
        }
174
175
        return $requestData;
176
    }
177
178
    /**
179
     * @param FormzControllerContext $formzControllerContext
180
     */
181
    public function injectFormzControllerContext(FormzControllerContext $formzControllerContext)
182
    {
183
        $this->formzControllerContext = $formzControllerContext;
184
    }
185
186
    /**
187
     * @param HashService $hashService
188
     */
189
    public function injectHashService(HashService $hashService)
190
    {
191
        $this->hashService = $hashService;
192
    }
193
194
    /**
195
     * @param FormObjectFactory $formObjectFactory
196
     */
197
    public function injectFormObjectFactory(FormObjectFactory $formObjectFactory)
198
    {
199
        $this->formObjectFactory = $formObjectFactory;
200
    }
201
}
202