Completed
Push — middleware-wip-tmp2 ( 6948fe...51115e )
by Romain
02:32
created

injectDependenciesInConfiguration()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 9
rs 9.6666
c 0
b 0
f 0
cc 2
eloc 4
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\Form\FormObject\Service;
15
16
use Romm\ConfigurationObject\ConfigurationObjectFactory;
17
use Romm\ConfigurationObject\ConfigurationObjectInstance;
18
use Romm\Formz\Configuration\ConfigurationFactory;
19
use Romm\Formz\Configuration\Form\Form;
20
use Romm\Formz\Core\Container;
21
use Romm\Formz\Form\FormObject\FormObjectStatic;
22
use Romm\Formz\Service\CacheService;
23
use Romm\Formz\Validation\Validator\Internal\FormConfigurationValidator;
24
use TYPO3\CMS\Core\Cache\Frontend\FrontendInterface;
25
use TYPO3\CMS\Extbase\Error\Result;
26
27
class FormObjectConfiguration
28
{
29
    /**
30
     * @var FormObjectStatic
31
     */
32
    protected $static;
33
34
    /**
35
     * @var array
36
     */
37
    protected $configurationArray = [];
38
39
    /**
40
     * Contains the form configuration object, which was created from the
41
     * configuration array.
42
     *
43
     * @var ConfigurationObjectInstance
44
     */
45
    protected $configurationObject;
46
47
    /**
48
     * @var Result
49
     */
50
    protected $configurationValidationResult;
51
52
    /**
53
     * Flag to know if the form configuration is valid or not: if the
54
     * configuration is fetched from cache, then we know the configuration is
55
     * valid because it saved in cache only when no error is found.
56
     *
57
     * @var bool
58
     */
59
    protected $configurationIsValid = false;
60
61
    /**
62
     * @param FormObjectStatic $static
63
     * @param array            $configurationArray
64
     */
65
    public function __construct(FormObjectStatic $static, array $configurationArray)
66
    {
67
        $this->static = $static;
68
        $this->configurationArray = $configurationArray;
69
    }
70
71
    /**
72
     * Returns an instance of configuration object. Checks if it was previously
73
     * stored in cache, otherwise it is created from scratch.
74
     *
75
     * @return ConfigurationObjectInstance
76
     */
77
    public function getConfigurationObject()
78
    {
79
        if (null === $this->configurationObject) {
80
            $this->configurationObject = $this->getConfigurationObjectFromCache();
81
        }
82
83
        return $this->configurationObject;
84
    }
85
86
    /**
87
     * This function will merge and return the validation results of both the
88
     * global FormZ configuration object, and this form configuration object.
89
     *
90
     * @return Result
91
     */
92
    public function getConfigurationValidationResult()
93
    {
94
        if (null === $this->configurationValidationResult) {
95
            $this->configurationValidationResult = $this->getGlobalConfigurationValidationResult();
96
        }
97
98
        return $this->configurationValidationResult;
99
    }
100
101
    /**
102
     * Resets the validation result and merges it with the global FormZ
103
     * configuration.
104
     *
105
     * @return Result
106
     */
107
    protected function getGlobalConfigurationValidationResult()
108
    {
109
        $result = new Result;
110
        $formzConfigurationValidationResult = ConfigurationFactory::get()
111
            ->getFormzConfiguration()
112
            ->getValidationResult();
113
114
        $result->merge($formzConfigurationValidationResult);
115
116
        if (false === $this->configurationIsValid) {
117
            $propertyName = 'forms.' . $this->static->getClassName();
118
            $formValidationResult = $this->getFormConfigurationValidationResult($this->getConfigurationObject());
119
120
            $result->forProperty($propertyName)->merge($formValidationResult);
121
        }
122
123
        return $result;
124
    }
125
126
    /**
127
     * @param ConfigurationObjectInstance $configurationObject
128
     * @return Result
129
     */
130
    protected function getFormConfigurationValidationResult(ConfigurationObjectInstance $configurationObject)
131
    {
132
        $baseResult = $configurationObject->getValidationResult();
133
134
        if (false === $baseResult->hasErrors()) {
135
            $validator = new FormConfigurationValidator;
136
            $extendedResult = $validator->validate($configurationObject->getObject(true));
137
138
            $baseResult->merge($extendedResult);
139
        }
140
141
        return $baseResult;
142
    }
143
144
    /**
145
     * @return ConfigurationObjectInstance
146
     */
147
    protected function getConfigurationObjectFromCache()
148
    {
149
        $cacheInstance = $this->getCacheInstance();
150
        $cacheIdentifier = 'configuration-' . $this->static->getObjectHash();
151
152
        if ($cacheInstance->has($cacheIdentifier)) {
153
            $configurationObject = $cacheInstance->get($cacheIdentifier);
154
            $this->injectDependenciesInConfiguration($configurationObject);
155
156
            $this->configurationIsValid = true;
157
        } else {
158
            $configurationArray = $this->sanitizeConfiguration($this->configurationArray);
159
            $configurationObject = $this->getConfigurationObjectInstance($configurationArray);
160
161
            if (false === $this->getFormConfigurationValidationResult($configurationObject)->hasErrors()) {
162
                $cacheInstance->set($cacheIdentifier, $configurationObject);
163
            }
164
        }
165
166
        return $configurationObject;
167
    }
168
169
    /**
170
     * This function will clean the configuration array by removing useless data
171
     * and updating needed ones.
172
     *
173
     * @param array $configuration
174
     * @return array
175
     */
176
    protected function sanitizeConfiguration(array $configuration)
177
    {
178
        // Removing configuration of fields which do not exist for this form.
179
        $sanitizedFieldsConfiguration = [];
180
        $fieldsConfiguration = (isset($configuration['fields']))
181
            ? $configuration['fields']
182
            : [];
183
184
        foreach ($this->static->getProperties() as $property) {
185
            $sanitizedFieldsConfiguration[$property] = (isset($fieldsConfiguration[$property]))
186
                ? $fieldsConfiguration[$property]
187
                : [];
188
        }
189
190
        $configuration['fields'] = $sanitizedFieldsConfiguration;
191
192
        return $configuration;
193
    }
194
195
    /**
196
     * Middlewares of the form are stored in cache, so their dependencies must
197
     * be injected again when they are fetched from cache.
198
     *
199
     * @param ConfigurationObjectInstance $configurationObject
200
     */
201
    protected function injectDependenciesInConfiguration(ConfigurationObjectInstance $configurationObject)
202
    {
203
        /** @var Form $formConfiguration */
204
        $formConfiguration = $configurationObject->getObject(true);
205
206
        foreach ($formConfiguration->getAllMiddlewares() as $middleware) {
207
            Container::get()->injectDependenciesInInstance($middleware);
208
        }
209
    }
210
211
    /**
212
     * @param array $configuration
213
     * @return ConfigurationObjectInstance
214
     */
215
    protected function getConfigurationObjectInstance(array $configuration)
216
    {
217
        return ConfigurationObjectFactory::getInstance()->get(Form::class, $configuration);
218
    }
219
220
    /**
221
     * @return FrontendInterface
222
     */
223
    protected function getCacheInstance()
224
    {
225
        return CacheService::get()->getCacheInstance();
226
    }
227
228
    /**
229
     * @return array
230
     */
231
    public function __sleep()
232
    {
233
        return ['static', 'configurationArray'];
234
    }
235
}
236