Completed
Push — feature/improve-form-definitio... ( 0cba0f...350a13 )
by Romain
02:18
created

ConfigurationFactory::buildRootConfiguration()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 11
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 6
nc 1
nop 0
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\Configuration;
15
16
use Romm\ConfigurationObject\ConfigurationObjectFactory;
17
use Romm\ConfigurationObject\ConfigurationObjectInstance;
18
use Romm\Formz\Service\CacheService;
19
use Romm\Formz\Service\ContextService;
20
use Romm\Formz\Service\HashService;
21
use Romm\Formz\Service\Traits\ExtendedSelfInstantiateTrait;
22
use Romm\Formz\Service\TypoScriptService;
23
use TYPO3\CMS\Core\SingletonInterface;
24
25
/**
26
 * This class is used to build and manage the whole FormZ configuration: from a
27
 * plain configuration array, it builds an entire tree object which will give
28
 * all the features from the `configuration_object` extension (parent
29
 * inheritance, array keys save, etc.).
30
 */
31
class ConfigurationFactory implements SingletonInterface
32
{
33
    use ExtendedSelfInstantiateTrait;
34
35
    /**
36
     * @var TypoScriptService
37
     */
38
    protected $typoScriptService;
39
40
    /**
41
     * @var ConfigurationObjectInstance[]
42
     */
43
    protected $instances = [];
44
45
    /**
46
     * @var array
47
     */
48
    protected $cacheIdentifiers = [];
49
50
    /**
51
     * Returns the global FormZ configuration.
52
     *
53
     * Two cache layers are used:
54
     *
55
     * - A local cache which will avoid fetching the configuration every time
56
     *   the current script needs it.
57
     * - A system cache, which will store the configuration instance when it has
58
     *   been built, improving performance for next scripts.
59
     *
60
     * @return ConfigurationObjectInstance
61
     */
62
    public function getRootConfiguration()
63
    {
64
        $cacheIdentifier = $this->getCacheIdentifier();
65
66
        if (false === array_key_exists($cacheIdentifier, $this->instances)) {
67
            $this->instances[$cacheIdentifier] = $this->getRootConfigurationFromCache($cacheIdentifier);
68
        }
69
70
        return $this->instances[$cacheIdentifier];
71
    }
72
73
    /**
74
     * Will fetch the configuration from cache, and build it if not found. It
75
     * wont be stored in cache if any error is found. This is done this way to
76
     * avoid the integrator to be forced to flush caches when errors are found.
77
     *
78
     * @param string $cacheIdentifier
79
     * @return ConfigurationObjectInstance
80
     */
81
    protected function getRootConfigurationFromCache($cacheIdentifier)
82
    {
83
        $cacheInstance = CacheService::get()->getCacheInstance();
84
85
        if ($cacheInstance->has($cacheIdentifier)) {
86
            $instance = $cacheInstance->get($cacheIdentifier);
87
        } else {
88
            $instance = $this->buildRootConfiguration();
89
90
            if (false === $instance->getValidationResult()->hasErrors()) {
91
                $cacheInstance->set($cacheIdentifier, $instance);
92
            }
93
        }
94
95
        return $instance;
96
    }
97
98
    /**
99
     * @see getRootConfiguration()
100
     *
101
     * @return ConfigurationObjectInstance
102
     */
103
    protected function buildRootConfiguration()
104
    {
105
        $configuration = $this->typoScriptService->getFormzConfiguration();
106
        $instance = ConfigurationObjectFactory::convert(Configuration::class, $configuration);
107
108
        /** @var Configuration $instanceObject */
109
        $instanceObject = $instance->getObject(true);
110
        $instanceObject->calculateHash();
111
112
        return $instance;
113
    }
114
115
    /**
116
     * @return string
117
     */
118
    protected function getCacheIdentifier()
119
    {
120
        $contextHash = ContextService::get()->getContextHash();
121
122
        if (false === array_key_exists($contextHash, $this->cacheIdentifiers)) {
123
            $configuration = $this->typoScriptService->getFormzConfiguration();
124
125
            $this->cacheIdentifiers[$contextHash] = 'formz-configuration-' . HashService::get()->getHash(serialize($configuration));
126
        }
127
128
        return $this->cacheIdentifiers[$contextHash];
129
    }
130
131
    /**
132
     * @param TypoScriptService $typoScriptService
133
     */
134
    public function injectTypoScriptService(TypoScriptService $typoScriptService)
135
    {
136
        $this->typoScriptService = $typoScriptService;
137
    }
138
}
139