Completed
Push — wip/steps ( 551eb2...b236f9 )
by Romain
03:12
created

FormObjectSteps::getCurrentSubstepDefinition()   B

Complexity

Conditions 5
Paths 10

Size

Total Lines 14
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 14
rs 8.8571
c 0
b 0
f 0
cc 5
eloc 7
nc 10
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\Form\FormObject\Service;
15
16
use Romm\Formz\Form\Definition\Step\Step\Step;
17
use Romm\Formz\Form\Definition\Step\Step\Substep\Substep;
18
use Romm\Formz\Form\Definition\Step\Step\Substep\SubstepDefinition;
19
use Romm\Formz\Form\FormObject\FormObject;
20
use Romm\Formz\Form\FormObject\Service\Step\FormStepPersistence;
21
use TYPO3\CMS\Core\Utility\GeneralUtility;
22
use TYPO3\CMS\Extbase\Mvc\Web\Request;
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
     * @var SubstepDefinition
51
     */
52
    protected $currentSubstepDefinition;
53
54
    /**
55
     * @var Substep[]
56
     */
57
    protected $substepsPath;
58
59
    /**
60
     * @var bool
61
     */
62
    protected $lastSubstepValidated = false;
63
64
    /**
65
     * @param FormObject $formObject
66
     */
67
    public function __construct(FormObject $formObject)
68
    {
69
        $this->formObject = $formObject;
70
    }
71
72
    /**
73
     * This function will search among the registered steps to find the one that
74
     * has the same controller parameters.
75
     *
76
     * It is also possible not to find any step, in this case `null` is
77
     * returned.
78
     *
79
     * @todo: memoization with request spl object storage
80
     *
81
     * @param Request $request
82
     */
83
    public function fetchCurrentStep(Request $request)
84
    {
85
        if (null !== $this->currentStep) {
86
            return;
87
        }
88
89
        $this->currentStep = false;
0 ignored issues
show
Documentation Bug introduced by
It seems like false of type false is incompatible with the declared type object<Romm\Formz\Form\Definition\Step\Step\Step> of property $currentStep.

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...
90
91
        $configuration = $this->formObject->getDefinition();
92
93
        if ($configuration->hasSteps()) {
94
            foreach ($configuration->getSteps()->getEntries() as $step) {
95
                $data = [
96
                    // @todo: no page uid to fetch?
97
//                $step->getPageUid()    => Core::get()->getPageController()->id,
98
                    $step->getExtension()  => $request->getControllerExtensionName(),
99
                    $step->getController() => $request->getControllerName()
100
                ];
101
102
                foreach ($data as $stepData => $requestData) {
103
                    if (false === empty($stepData)
104
                        && $stepData !== $requestData
105
                    ) {
106
                        continue 2;
107
                    }
108
                }
109
110
                $actionList = GeneralUtility::trimExplode(',', $step->getAction());
111
112
                if (false === in_array($request->getControllerActionName(), $actionList)) {
113
                    continue;
114
                }
115
116
                if ($this->currentStep instanceof Step) {
117
                    throw new \Exception('todo'); // @todo
118
                }
119
120
                $this->currentStep = $step;
121
            }
122
        }
123
    }
124
125
    /**
126
     * @return Step|null
127
     */
128
    public function getCurrentStep()
129
    {
130
        if (null === $this->currentStep) {
131
            throw new \Exception('todo'); // @todo
132
        }
133
134
        return $this->currentStep ?: null;
135
    }
136
137
    /**
138
     * Fetches the step persistence object for the form, which may have been
139
     * stored in the form metadata.
140
     *
141
     * If the form object hash did change since the persistence object was saved
142
     * it is "refreshed" with the new hash (some data are also deleted as they
143
     * are no longer considered as valid).
144
     *
145
     * @return FormStepPersistence
146
     */
147
    public function getStepPersistence()
148
    {
149
        // @todo check configuration has steps or fatal error
150
        if (null === $this->stepPersistence) {
151
            $objectHash = $this->formObject->getObjectHash();
152
            $metadata = $this->formObject->getFormMetadata();
153
154
            if ($metadata->has(self::METADATA_STEP_PERSISTENCE_KEY)) {
155
                $this->stepPersistence = $metadata->get(self::METADATA_STEP_PERSISTENCE_KEY);
156
157
                if (false === $this->stepPersistence instanceof FormStepPersistence) {
158
                    unset($this->stepPersistence);
159
                } elseif ($objectHash !== $this->stepPersistence->getObjectHash()) {
160
                    $this->stepPersistence->refreshObjectHash($objectHash);
161
                }
162
            }
163
164
            if (null === $this->stepPersistence) {
165
                $this->stepPersistence = GeneralUtility::makeInstance(FormStepPersistence::class, $objectHash);
166
                $metadata->set(self::METADATA_STEP_PERSISTENCE_KEY, $this->stepPersistence);
167
            }
168
        }
169
170
        return $this->stepPersistence;
171
    }
172
173
    /**
174
     * @return SubstepDefinition|null
175
     */
176
    public function getCurrentSubstepDefinition()
177
    {
178
        // @todo check current step has been set?
179
180
        if (null === $this->currentSubstepDefinition) {
181
            $currentStep = $this->getCurrentStep();
182
183
            $this->currentSubstepDefinition = ($currentStep && $currentStep->hasSubsteps())
0 ignored issues
show
Documentation Bug introduced by
It seems like $currentStep && $current...tepDefinition() : false can also be of type false. However, the property $currentSubstepDefinition is declared as type object<Romm\Formz\Form\D...step\SubstepDefinition>. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
184
                ? $currentStep->getSubsteps()->getFirstSubstepDefinition()
185
                : false;
186
        }
187
188
        return $this->currentSubstepDefinition ?: null;
189
    }
190
191
    /**
192
     * @param SubstepDefinition $currentSubstepDefinition
193
     */
194
    public function setCurrentSubstepDefinition(SubstepDefinition $currentSubstepDefinition)
195
    {
196
        // @todo check current step has been set?
197
        $this->currentSubstepDefinition = $currentSubstepDefinition;
198
    }
199
200
    /**
201
     * @return Substep[]
202
     */
203
    public function getSubstepsPath()
204
    {
205
        return $this->substepsPath ?: [$this->getCurrentStep()->getSubsteps()->getFirstSubstepDefinition()->getSubstep()];
206
    }
207
208
    /**
209
     * @param Substep[] $substepsPath
210
     */
211
    public function setSubstepsPath(array $substepsPath)
212
    {
213
        $this->substepsPath = $substepsPath;
214
    }
215
216
    /**
217
     * @param Substep $substep
218
     */
219
    public function addSubstepToPath(Substep $substep)
220
    {
221
        $this->substepsPath[] = $substep;
222
    }
223
224
    /**
225
     * @todo
226
     */
227
    public function markLastSubstepAsValidated()
228
    {
229
        $this->lastSubstepValidated = true;
230
    }
231
232
    /**
233
     * @return bool
234
     */
235
    public function lastSubstepWasValidated()
236
    {
237
        return $this->lastSubstepValidated;
238
    }
239
}
240