Completed
Push — wip/steps ( 83acbb...995792 )
by Romain
02:56
created

FormObjectSteps::fetchCurrentStep()   C

Complexity

Conditions 11
Paths 12

Size

Total Lines 47
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 47
rs 5.2653
cc 11
eloc 24
nc 12
nop 3

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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\Form\FormObject\Service;
15
16
use Romm\Formz\Core\Core;
17
use Romm\Formz\Form\Definition\Step\Step\Step;
18
use Romm\Formz\Form\Definition\Step\Step\StepDefinition;
19
use Romm\Formz\Form\Definition\Step\Step\Substep\SubstepDefinition;
20
use Romm\Formz\Form\FormObject\FormObject;
21
use Romm\Formz\Form\FormObject\Service\Step\FormStepPersistence;
22
use TYPO3\CMS\Core\Utility\GeneralUtility;
23
24
class FormObjectSteps
25
{
26
    const METADATA_STEP_PERSISTENCE_KEY = 'core.formStepPersistence';
27
28
    /**
29
     * @var FormObject
30
     */
31
    protected $formObject;
32
33
    /**
34
     * Step persistence is saved in the form metadata.
35
     *
36
     * It allows having essential information about the form steps whenever it
37
     * is needed: submitted form values, as well as steps that were already
38
     * validated.
39
     *
40
     * @var FormStepPersistence
41
     */
42
    protected $stepPersistence;
43
44
    /**
45
     * @var Step
46
     */
47
    protected $currentStep;
48
49
    /**
50
     * @todo ADD REQUEST CONTEXT INSIDE THE FORM OBJECT ?!
51
     *
52
     * @var string
53
     */
54
    protected $currentHash;
55
56
    /**
57
     * @var SubstepDefinition
58
     */
59
    protected $currentSubstepDefinition;
60
61
    /**
62
     * @var int
63
     */
64
    protected $substepsLevel = 1;
65
66
    /**
67
     * @var bool
68
     */
69
    protected $lastSubstepValidated = false;
70
71
    /**
72
     * @param FormObject $formObject
73
     */
74
    public function __construct(FormObject $formObject)
75
    {
76
        $this->formObject = $formObject;
77
    }
78
79
    /**
80
     * This function will search among the registered steps to find the one that
81
     * has the same controller parameters.
82
     *
83
     * It is also possible not to find any step, in this case `null` is
84
     * returned.
85
     *
86
     * @todo: memoization with request spl object storage
87
     *
88
     * @param string $extensionName
89
     * @param string $controllerName
90
     * @param string $actionName
91
     */
92
    public function fetchCurrentStep($extensionName, $controllerName, $actionName)
93
    {
94
        $this->currentHash = "$extensionName:$controllerName->$actionName";
95
96
        if (null !== $this->currentStep[$this->currentHash]) {
97
            return;
98
        }
99
100
        $this->currentStep[$this->currentHash] = false;
101
102
        $definition = $this->formObject->getDefinition();
103
104
        if ($definition->hasSteps()) {
105
            foreach ($definition->getSteps()->getEntries() as $step) {
106
                $data = [
107
                    $step->getExtension() => $extensionName,
108
                    $step->getController() => $controllerName
109
                ];
110
111
                foreach ($data as $stepData => $requestData) {
112
                    if (false === empty($stepData)
113
                        && $stepData !== $requestData
114
                    ) {
115
                        continue 2;
116
                    }
117
                }
118
119
                if ($step->getPageUid()
120
                    && $step->getPageUid() !== Core::get()->getPageController()->id
0 ignored issues
show
Unused Code Bug introduced by
The strict comparison !== seems to always evaluate to true as the types of $step->getPageUid() (integer) and \Romm\Formz\Core\Core::g...getPageController()->id (string) can never be identical. Maybe you want to use a loose comparison != instead?
Loading history...
121
                ) {
122
                    continue;
123
                }
124
125
                $actionList = $step->getAuthorizedActions();
126
127
                if (false === in_array($actionName, $actionList)) {
128
                    continue;
129
                }
130
131
                if ($this->currentStep[$this->currentHash] instanceof Step) {
132
                    throw new \Exception('todo'); // @todo
133
                }
134
135
                $this->currentStep[$this->currentHash] = $step;
136
            }
137
        }
138
    }
139
140
    /**
141
     * @param Step $step
142
     */
143
    public function setCurrentStep(Step $step)
144
    {
145
        $this->currentStep[$this->currentHash] = $step;
146
    }
147
148
    /**
149
     * @return Step|null
150
     */
151
    public function getCurrentStep()
152
    {
153
        if (null === $this->currentStep[$this->currentHash]) {
154
            throw new \Exception('todo'); // @todo
155
        }
156
157
        return $this->currentStep[$this->currentHash] ?: null;
158
    }
159
160
    /**
161
     * @param Step $step
162
     * @return StepDefinition|null
163
     */
164
    public function getStepDefinition(Step $step)
165
    {
166
        return $this->findStepDefinition($step, $this->formObject->getDefinition()->getSteps()->getFirstStepDefinition());
167
    }
168
169
    /**
170
     * @param Step           $step
171
     * @param StepDefinition $stepDefinition
172
     * @return StepDefinition|null
173
     */
174
    protected function findStepDefinition(Step $step, StepDefinition $stepDefinition)
175
    {
176
        if ($stepDefinition->getStep() === $step) {
177
            return $stepDefinition;
178
        }
179
180
        if ($stepDefinition->hasNextStep()) {
181
            $result = $this->findStepDefinition($step, $stepDefinition->getNextStep());
182
183
            if ($result instanceof StepDefinition) {
184
                return $result;
185
            }
186
        }
187
188
        if ($stepDefinition->hasDivergence()) {
189
            foreach ($stepDefinition->getDivergenceSteps() as $divergenceStep) {
190
                $result = $this->findStepDefinition($step, $divergenceStep);
191
192
                if ($result instanceof StepDefinition) {
193
                    return $result;
194
                }
195
            }
196
        }
197
198
        return null;
199
    }
200
201
    /**
202
     * Fetches the step persistence object for the form, which may have been
203
     * stored in the form metadata.
204
     *
205
     * If the form object hash did change since the persistence object was saved
206
     * it is "refreshed" with the new hash (some data are also deleted as they
207
     * are no longer considered as valid).
208
     *
209
     * @return FormStepPersistence
210
     */
211
    public function getStepPersistence()
212
    {
213
        // @todo check configuration has steps or fatal error
214
        if (null === $this->stepPersistence) {
215
            $objectHash = $this->formObject->getObjectHash();
216
            $metadata = $this->formObject->getFormMetadata();
217
218
            if ($metadata->has(self::METADATA_STEP_PERSISTENCE_KEY)) {
219
                $this->stepPersistence = $metadata->get(self::METADATA_STEP_PERSISTENCE_KEY);
220
221
                if (false === $this->stepPersistence instanceof FormStepPersistence) {
222
                    unset($this->stepPersistence);
223
                } elseif ($objectHash !== $this->stepPersistence->getObjectHash()) {
224
                    $this->stepPersistence->refreshObjectHash($objectHash);
225
                }
226
            }
227
228
            if (null === $this->stepPersistence) {
229
                $this->stepPersistence = GeneralUtility::makeInstance(FormStepPersistence::class, $objectHash);
230
                $metadata->set(self::METADATA_STEP_PERSISTENCE_KEY, $this->stepPersistence);
231
            }
232
        }
233
234
        return $this->stepPersistence;
235
    }
236
237
    /**
238
     * @return SubstepDefinition
239
     */
240
    public function getCurrentSubstepDefinition()
241
    {
242
        return $this->currentSubstepDefinition ?: $this->getCurrentStep()->getSubsteps()->getFirstSubstepDefinition();
243
    }
244
245
    /**
246
     * @param SubstepDefinition $currentSubstepDefinition
247
     */
248
    public function setCurrentSubstepDefinition(SubstepDefinition $currentSubstepDefinition)
249
    {
250
        $this->currentSubstepDefinition = $currentSubstepDefinition;
251
    }
252
253
    /**
254
     * @param int $level
255
     */
256
    public function setSubstepsLevel($level)
257
    {
258
        $this->substepsLevel = max(1, (int)$level);
259
    }
260
261
    /**
262
     * @return int
263
     */
264
    public function getSubstepsLevel()
265
    {
266
        return $this->substepsLevel;
267
    }
268
269
    /**
270
     * @todo
271
     */
272
    public function markLastSubstepAsValidated()
273
    {
274
        $this->lastSubstepValidated = true;
275
    }
276
277
    /**
278
     * @return bool
279
     */
280
    public function lastSubstepWasValidated()
281
    {
282
        return $this->lastSubstepValidated;
283
    }
284
}
285