Completed
Push — middleware-wip ( a29b16...4a8d7b )
by Romain
11:57
created

StepMiddlewareService::getNextStepDefinition()   B

Complexity

Conditions 5
Paths 8

Size

Total Lines 27
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 27
rs 8.439
c 0
b 0
f 0
cc 5
eloc 16
nc 8
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\Middleware\Item\Step\Service;
15
16
use Romm\Formz\Condition\Processor\ConditionProcessorFactory;
17
use Romm\Formz\Condition\Processor\DataObject\PhpConditionDataObject;
18
use Romm\Formz\Form\Definition\Step\Step\Step;
19
use Romm\Formz\Form\Definition\Step\Step\StepDefinition;
20
use Romm\Formz\Form\FormObject\FormObject;
21
use Romm\Formz\Form\FormObject\FormObjectFactory;
22
use Romm\Formz\Form\FormObject\Service\Step\FormStepPersistence;
23
use Romm\Formz\Middleware\Request\Redirect;
24
use Romm\Formz\Service\Traits\SelfInstantiateTrait;
25
use Romm\Formz\Validation\Validator\Form\DataObject\FormValidatorDataObject;
26
use Romm\Formz\Validation\Validator\Form\FormValidatorExecutor;
27
use TYPO3\CMS\Core\SingletonInterface;
28
use TYPO3\CMS\Core\Utility\GeneralUtility;
29
30
/**
31
 * This service allows extended form steps manipulation.
32
 */
33
class StepMiddlewareService implements SingletonInterface
34
{
35
    use SelfInstantiateTrait;
36
37
    /**
38
     * @var FormObject
39
     */
40
    protected $formObject;
41
42
    /**
43
     * @var StepMiddlewareValidationService
44
     */
45
    protected $validationService;
46
47
    /**
48
     * @var FormStepPersistence
49
     */
50
    protected $persistence;
51
52
    /**
53
     * @param FormObject $formObject
54
     */
55
    public function reset(FormObject $formObject)
56
    {
57
        $this->formObject = $formObject;
58
59
        $proxy = FormObjectFactory::get()->getProxy($formObject->getForm());
60
        $this->persistence = $proxy->getStepPersistence();
61
62
        $this->validationService = GeneralUtility::makeInstance(StepMiddlewareValidationService::class, $this);
63
    }
64
65
    /**
66
     * @see \Romm\Formz\Middleware\Item\Step\Service\StepMiddlewareValidationService::markStepAsValidated
67
     *
68
     * @param StepDefinition $stepDefinition
69
     * @param array          $formValues
70
     */
71
    public function markStepAsValidated(StepDefinition $stepDefinition, array $formValues)
72
    {
73
        $this->validationService->markStepAsValidated($stepDefinition, $formValues);
74
    }
75
76
    /**
77
     * @see \Romm\Formz\Middleware\Item\Step\Service\StepMiddlewareValidationService::addValidatedFields
78
     *
79
     * @param array $validatedFields
80
     */
81
    public function addValidatedFields(array $validatedFields)
82
    {
83
        $this->validationService->addValidatedFields($validatedFields);
84
    }
85
86
    /**
87
     * @see \Romm\Formz\Middleware\Item\Step\Service\StepMiddlewareValidationService::stepDefinitionIsValid
88
     *
89
     * @param StepDefinition $stepDefinition
90
     * @return bool
91
     */
92
    public function stepIsValid(StepDefinition $stepDefinition)
93
    {
94
        return $this->validationService->stepDefinitionIsValid($stepDefinition);
95
    }
96
97
    /**
98
     * @see \Romm\Formz\Middleware\Item\Step\Service\StepMiddlewareValidationService::getFirstInvalidStep
99
     *
100
     * @param Step $step
101
     * @return StepDefinition|null
102
     */
103
    public function getFirstInvalidStep(Step $step)
104
    {
105
        return $this->validationService->getFirstInvalidStep($step);
106
    }
107
108
    /**
109
     * @param StepDefinition $step
110
     * @return StepDefinition
111
     */
112
    public function getNextStepDefinition(StepDefinition $step)
113
    {
114
        $nextStep = null;
115
116
        if ($step->hasDetour()) {
117
            $detourSteps = $step->getDetourSteps();
118
            $conditionProcessor = ConditionProcessorFactory::getInstance()->get($this->getFormObject());
119
120
            foreach ($detourSteps as $detourStep) {
121
                $tree = $conditionProcessor->getActivationConditionTreeForStep($detourStep);
122
                $todo = new FormValidatorExecutor($this->getFormObject(), new FormValidatorDataObject());
123
                $dataObject = new PhpConditionDataObject($this->getFormObject()->getForm(), $todo);
124
                $phpResult = $tree->getPhpResult($dataObject);
125
126
                if (true === $phpResult) {
127
                    $nextStep = $detourStep;
128
                    break;
129
                }
130
            }
131
        }
132
133
        if (null === $nextStep) {
134
            $nextStep = $step->getNextStep();
135
        }
136
137
        return $nextStep;
138
    }
139
140
    /**
141
     * @param StepDefinition $stepDefinition
142
     * @param Redirect       $redirect
143
     */
144
    public function moveForwardToStep(StepDefinition $stepDefinition, Redirect $redirect)
145
    {
146
        $this->getStepPersistence()->setStepLevel($stepDefinition);
147
        $this->redirectToStep($stepDefinition->getStep(), $redirect);
148
    }
149
150
    /**
151
     * Redirects the current request to the given step.
152
     *
153
     * @param Step     $step
154
     * @param Redirect $redirect
155
     */
156
    public function redirectToStep(Step $step, Redirect $redirect)
157
    {
158
        $redirect->toPage($step->getPageUid())
159
            ->toExtension($step->getExtension())
160
            ->toController($step->getController())
161
            ->toAction($step->getAction())
162
            ->withArguments([
163
                'fz-hash' => [
164
                    $this->formObject->getName() => $this->formObject->getFormHash()
165
                ]
166
            ])
167
            ->dispatch();
168
    }
169
170
    /**
171
     * @param Step $step
172
     * @return StepDefinition|null
173
     */
174
    public function getStepDefinition(Step $step)
175
    {
176
        return $this->findStep($step, $this->getFirstStepDefinition());
177
    }
178
179
    /**
180
     * @param Step           $step
181
     * @param StepDefinition $stepDefinition
182
     * @return StepDefinition|null
183
     */
184
    protected function findStep(Step $step, StepDefinition $stepDefinition)
185
    {
186
        if ($stepDefinition->getStep() === $step) {
187
            return $stepDefinition;
188
        }
189
190
        if ($stepDefinition->hasNextStep()) {
191
            $result = $this->findStep($step, $stepDefinition->getNextStep());
192
193
            if ($result instanceof StepDefinition) {
194
                return $result;
195
            }
196
        }
197
198
        if ($stepDefinition->hasDetour()) {
199
            foreach ($stepDefinition->getDetourSteps() as $detourStep) {
200
                $result = $this->findStep($step, $detourStep);
201
202
                if ($result instanceof StepDefinition) {
203
                    return $result;
204
                }
205
            }
206
        }
207
208
        if ($stepDefinition->hasDivergence()) {
209
            foreach ($stepDefinition->getDivergenceSteps() as $divergenceStep) {
210
                $result = $this->findStep($step, $divergenceStep);
211
212
                if ($result instanceof StepDefinition) {
213
                    return $result;
214
                }
215
            }
216
        }
217
218
        return null;
219
    }
220
221
    /**
222
     * @return FormStepPersistence
223
     */
224
    public function getStepPersistence()
225
    {
226
        return $this->persistence;
227
    }
228
229
    /**
230
     * @return FormObject
231
     */
232
    public function getFormObject()
233
    {
234
        return $this->formObject;
235
    }
236
237
    /**
238
     * @return StepDefinition
239
     */
240
    public function getFirstStepDefinition()
241
    {
242
        return $this->formObject->getDefinition()->getSteps()->getFirstStepDefinition();
243
    }
244
}
245