Completed
Pull Request — master (#14)
by
unknown
02:13
created

FormObject::buildConfigurationObject()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

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