Completed
Push — cleanup-service ( 73e309...ffbb72 )
by Romain
02:47
created

FormObject::injectConfigurationFactory()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
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;
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\Core;
21
use TYPO3\CMS\Extbase\Error\Result;
22
23
/**
24
 * This is the object representation of a form. In here we can manage which
25
 * properties the form does have, its configuration, and more.
26
 */
27
class FormObject
28
{
29
30
    /**
31
     * @var ConfigurationFactory
32
     */
33
    protected $configurationFactory;
34
35
    /**
36
     * Name of the form.
37
     *
38
     * @var string
39
     */
40
    protected $name;
41
42
    /**
43
     * @var string
44
     */
45
    protected $className;
46
47
    /**
48
     * The properties of the form.
49
     *
50
     * @var array
51
     */
52
    protected $properties = [];
53
54
    /**
55
     * Contains the form configuration.
56
     *
57
     * @var array
58
     */
59
    protected $configurationArray = [];
60
61
    /**
62
     * Contains the form configuration object, which was created from the
63
     * configuration array.
64
     *
65
     * @var ConfigurationObjectInstance
66
     */
67
    protected $configurationObject;
68
69
    /**
70
     * @var string
71
     */
72
    protected $hash;
73
74
    /**
75
     * @var bool
76
     */
77
    protected $hashShouldBeCalculated = true;
78
79
    /**
80
     * You should never create a new instance of this class directly, use the
81
     * `FormObjectFactory->getInstanceFromClassName()` function instead.
82
     *
83
     * @param string $className
84
     * @param string $name
85
     */
86
    public function __construct($className, $name)
87
    {
88
        $this->className = $className;
89
        $this->name = $name;
90
    }
91
92
    /**
93
     * Registers a new property for this form.
94
     *
95
     * @param string $name
96
     * @return $this
97
     */
98
    public function addProperty($name)
99
    {
100
        if (false === in_array($name, $this->properties)) {
101
            $this->properties[] = $name;
102
            $this->hashShouldBeCalculated = true;
103
        }
104
105
        return $this;
106
    }
107
108
    /**
109
     * @return Form
110
     */
111
    public function getConfiguration()
112
    {
113
        /** @var Form $configuration */
114
        $configuration = $this->getConfigurationObject()->getObject(true);
115
116
        return $configuration;
117
    }
118
119
    /**
120
     * @return string
121
     */
122
    public function getName()
123
    {
124
        return $this->name;
125
    }
126
127
    /**
128
     * @return string
129
     */
130
    public function getClassName()
131
    {
132
        return $this->className;
133
    }
134
135
    /**
136
     * @return array
137
     */
138
    public function getProperties()
139
    {
140
        return $this->properties;
141
    }
142
143
    /**
144
     * Returns the hash, which should be calculated only once for performance
145
     * concerns.
146
     *
147
     * @return string
148
     */
149
    public function getHash()
150
    {
151
        if (true === $this->hashShouldBeCalculated
152
            || null === $this->hash
153
        ) {
154
            $this->hashShouldBeCalculated = false;
155
            $this->hash = $this->calculateHash();
156
        }
157
158
        return $this->hash;
159
    }
160
161
    /**
162
     * @return array
163
     * @internal Should not be used, it is here only for unit tests.
164
     */
165
    public function getConfigurationArray()
166
    {
167
        return $this->configurationArray;
168
    }
169
170
    /**
171
     * @param array $configuration
172
     * @return $this
173
     */
174
    public function setConfigurationArray($configuration)
175
    {
176
        $this->configurationArray = $this->sanitizeConfiguration($configuration);
177
        $this->hashShouldBeCalculated = true;
178
179
        return $this;
180
    }
181
182
    /**
183
     * Returns an instance of configuration object. Checks if it was previously
184
     * stored in cache, otherwise it is created from scratch.
185
     *
186
     * @return ConfigurationObjectInstance
187
     * @internal
188
     */
189
    public function getConfigurationObject()
190
    {
191
        if (null === $this->configurationObject) {
192
            $cacheInstance = Core::get()->getCacheInstance();
193
            $cacheIdentifier = 'configuration-' . $this->getHash();
194
195
            if ($cacheInstance->has($cacheIdentifier)) {
196
                $configurationObject = $cacheInstance->get($cacheIdentifier);
197
            } else {
198
                $configurationObject = $this->buildConfigurationObject();
199
200
                if (false === $configurationObject->getValidationResult()->hasErrors()) {
201
                    $cacheInstance->set($cacheIdentifier, $configurationObject);
202
                }
203
            }
204
205
            $this->configurationObject = $configurationObject;
206
        }
207
208
        return $this->configurationObject;
209
    }
210
211
    /**
212
     * This function will merge and return the validation results of both the
213
     * global Formz configuration object, and this form configuration object.
214
     *
215
     * @return Result
216
     */
217
    public function getConfigurationValidationResult()
218
    {
219
        $result = new Result();
220
        $formzConfigurationValidationResult = $this->configurationFactory
221
            ->getFormzConfiguration()
222
            ->getValidationResult();
223
224
        $result->merge($formzConfigurationValidationResult);
225
226
        $result->forProperty('forms.' . $this->getClassName())
227
            ->merge($this->getConfigurationObject()->getValidationResult());
228
229
        return $result;
230
    }
231
232
    /**
233
     * @return ConfigurationObjectInstance
234
     */
235
    protected function buildConfigurationObject()
236
    {
237
        return ConfigurationObjectFactory::getInstance()
238
            ->get(Form::class, $this->configurationArray);
239
    }
240
241
    /**
242
     * This function will clean the configuration array by removing useless data
243
     * and updating needed ones.
244
     *
245
     * @param array $configuration
246
     * @return array
247
     */
248
    protected function sanitizeConfiguration(array $configuration)
249
    {
250
        // Removing configuration of fields which do not exist for this form.
251
        $sanitizedFieldsConfiguration = [];
252
        $fieldsConfiguration = (isset($configuration['fields']))
253
            ? $configuration['fields']
254
            : [];
255
256
        foreach ($this->properties as $property) {
257
            $sanitizedFieldsConfiguration[$property] = (isset($fieldsConfiguration[$property]))
258
                ? $fieldsConfiguration[$property]
259
                : [];
260
        }
261
262
        $configuration['fields'] = $sanitizedFieldsConfiguration;
263
264
        return $configuration;
265
    }
266
267
    /**
268
     * Returns the calculated hash of this class.
269
     *
270
     * @return string
271
     */
272
    protected function calculateHash()
273
    {
274
        return sha1(serialize($this));
275
    }
276
277
    /**
278
     * @param ConfigurationFactory $configurationFactory
279
     */
280
    public function injectConfigurationFactory(ConfigurationFactory $configurationFactory)
281
    {
282
        $this->configurationFactory = $configurationFactory;
283
    }
284
285
    /**
286
     * When this instance is saved in TYPO3 cache, we need not to store all the
287
     * properties to increase performance.
288
     *
289
     * @return array
290
     */
291
    public function __sleep()
292
    {
293
        return ['name', 'className', 'properties', 'configurationArray', 'hash'];
294
    }
295
296
    /**
297
     * When this class is unserialized, we update the flag to know if the hash
298
     * should be calculated or not (if it was calculated before it was
299
     * serialized, there is no need to calculate it again).
300
     */
301
    public function __wakeup()
302
    {
303
        $this->hashShouldBeCalculated = (null === $this->hash);
304
    }
305
}
306