Completed
Push — middleware-wip ( 94fd4a...c7460e )
by Romain
03:33
created

getActivationConditionTreeForSubstep()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 12
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 6
nc 2
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\Condition\Processor;
15
16
use Romm\Formz\Condition\Parser\ConditionParserFactory;
17
use Romm\Formz\Condition\Parser\Node\ConditionNode;
18
use Romm\Formz\Condition\Parser\Node\NodeInterface;
19
use Romm\Formz\Condition\Parser\Tree\ConditionTree;
20
use Romm\Formz\Condition\Parser\Tree\EmptyConditionTree;
21
use Romm\Formz\Form\Definition\Condition\ActivationInterface;
22
use Romm\Formz\Form\Definition\Field\Field;
23
use Romm\Formz\Form\Definition\Field\Validation\Validator;
24
use Romm\Formz\Form\Definition\Step\Step\Substep\ConditionalSubstepDefinition;
25
use Romm\Formz\Form\FormObject\FormObject;
26
27
class ConditionProcessor
28
{
29
    /**
30
     * @var FormObject
31
     */
32
    private $formObject;
33
34
    /**
35
     * @var ConditionTree[]
36
     */
37
    private $fieldsTrees = [];
38
39
    /**
40
     * @var ConditionTree[]
41
     */
42
    private $conditionTrees = [];
43
44
    /**
45
     * @var ConditionTree[]
46
     */
47
    private $substepTree = [];
48
49
    /**
50
     * @var array
51
     */
52
    private $javaScriptFiles = [];
53
54
    /**
55
     * @param FormObject $formObject
56
     */
57
    public function __construct(FormObject $formObject)
58
    {
59
        $this->attachFormObject($formObject);
60
    }
61
62
    /**
63
     * Returns the condition tree for a given field instance, giving access to
64
     * CSS, JavaScript and PHP transpiled results.
65
     *
66
     * @param Field $field
67
     * @return ConditionTree
68
     */
69
    public function getActivationConditionTreeForField(Field $field)
70
    {
71
        $key = $field->getName();
72
73
        if (false === array_key_exists($key, $this->fieldsTrees)) {
74
            $this->fieldsTrees[$key] = $field->hasActivation()
75
                ? $this->getConditionTree($field->getActivation())
76
                : EmptyConditionTree::get();
77
        }
78
79
        if ($field->hasActivation()) {
80
            $this->fieldsTrees[$key]->injectDependencies($this, $field->getActivation());
81
        }
82
83
        return $this->fieldsTrees[$key];
84
    }
85
86
    /**
87
     * Returns the condition tree for a given validator instance, giving access
88
     * to CSS, JavaScript and PHP transpiled results.
89
     *
90
     * @param Validator $validator
91
     * @return ConditionTree
92
     */
93
    public function getActivationConditionTreeForValidator(Validator $validator)
94
    {
95
        $key = $validator->getParentField()->getName() . '->' . $validator->getName();
96
97
        if (false === array_key_exists($key, $this->conditionTrees)) {
98
            $this->conditionTrees[$key] = $validator->hasActivation()
99
                ? $this->getConditionTree($validator->getActivation())
100
                : EmptyConditionTree::get();
101
        }
102
103
        if ($validator->hasActivation()) {
104
            $this->conditionTrees[$key]->injectDependencies($this, $validator->getActivation());
105
        }
106
107
        return $this->conditionTrees[$key];
108
    }
109
110
    /**
111
     * Returns the condition tree for a given validator instance, giving access
112
     * to CSS, JavaScript and PHP transpiled results.
113
     *
114
     * @param ConditionalSubstepDefinition $substep
115
     * @return ConditionTree
116
     */
117
    public function getActivationConditionTreeForSubstep(ConditionalSubstepDefinition $substep)
118
    {
119
        $key = 'substep-' . serialize($substep);
120
121
        if (false === array_key_exists($key, $this->substepTree)) {
122
            $this->substepTree[$key] = $this->getConditionTree($substep->getActivation());
123
        }
124
125
        $this->substepTree[$key]->injectDependencies($this, $substep->getActivation());
126
127
        return $this->substepTree[$key];
128
    }
129
130
    /**
131
     * Function that will calculate all trees from fields and their validators.
132
     *
133
     * This is useful to be able to store this instance in cache.
134
     */
135
    public function calculateAllTrees()
136
    {
137
        $fields = $this->formObject->getDefinition()->getFields();
138
139
        foreach ($fields as $field) {
140
            $this->getActivationConditionTreeForField($field);
141
142
            foreach ($field->getValidators() as $validator) {
143
                $this->getActivationConditionTreeForValidator($validator);
144
            }
145
        }
146
    }
147
148
    /**
149
     * @param ActivationInterface $activation
150
     * @return ConditionTree
151
     */
152
    protected function getConditionTree(ActivationInterface $activation)
153
    {
154
        $tree = $this->getNewConditionTreeFromActivation($activation);
155
        $tree->alongNodes(function (NodeInterface $node) {
156
            $this->attachNodeJavaScriptFiles($node);
157
        });
158
159
        return $tree;
160
    }
161
162
    /**
163
     * @param ActivationInterface $activation
164
     * @return ConditionTree
165
     */
166
    protected function getNewConditionTreeFromActivation(ActivationInterface $activation)
167
    {
168
        return ConditionParserFactory::get()
169
            ->parse($activation);
170
    }
171
172
    /**
173
     * @param NodeInterface $node
174
     */
175
    protected function attachNodeJavaScriptFiles(NodeInterface $node)
176
    {
177
        if ($node instanceof ConditionNode) {
178
            $files = $node->getCondition()->getJavaScriptFiles();
179
180
            foreach ($files as $file) {
181
                if (false === in_array($file, $this->javaScriptFiles)) {
182
                    $this->javaScriptFiles[] = $file;
183
                }
184
            }
185
        }
186
    }
187
188
    /**
189
     * @param FormObject $formObject
190
     */
191
    public function attachFormObject(FormObject $formObject)
192
    {
193
        $this->formObject = $formObject;
194
    }
195
196
    /**
197
     * @return FormObject
198
     */
199
    public function getFormObject()
200
    {
201
        return $this->formObject;
202
    }
203
204
    /**
205
     * @return array
206
     */
207
    public function getJavaScriptFiles()
208
    {
209
        return $this->javaScriptFiles;
210
    }
211
212
    /**
213
     * @return array
214
     */
215
    public function __sleep()
216
    {
217
        return ['fieldsTrees', 'conditionTrees', 'javaScriptFiles'];
218
    }
219
}
220