Completed
Push — master ( f5cbef...dba98a )
by Craig
09:56 queued 04:13
created

VariableApi::del()   A

Complexity

Conditions 6
Paths 7

Size

Total Lines 17
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 9
nc 7
nop 2
dl 0
loc 17
rs 9.2222
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Zikula package.
7
 *
8
 * Copyright Zikula - https://ziku.la/
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Zikula\ExtensionsModule\Api;
15
16
use InvalidArgumentException;
17
use Zikula\Bundle\CoreBundle\HttpKernel\ZikulaHttpKernelInterface;
18
use Zikula\ExtensionsModule\Api\ApiInterface\VariableApiInterface;
19
use Zikula\ExtensionsModule\Entity\ExtensionVarEntity;
20
use Zikula\ExtensionsModule\Entity\RepositoryInterface\ExtensionVarRepositoryInterface;
21
22
/**
23
 * Class VariableApi
24
 *
25
 * This class manages the storage and retrieval of extension variables
26
 */
27
class VariableApi implements VariableApiInterface
28
{
29
    public const CONFIG = 'ZConfig';
30
31
    /**
32
     * @var bool
33
     */
34
    private $isInitialized = false;
35
36
    /**
37
     * @var boolean Site is installed or not
38
     */
39
    private $installed;
40
41
    /**
42
     * @var ExtensionVarRepositoryInterface
43
     */
44
    private $repository;
45
46
    /**
47
     * @var ZikulaHttpKernelInterface
48
     */
49
    private $kernel;
50
51
    /**
52
     * @var array
53
     */
54
    private $protectedSystemVars;
55
56
    /**
57
     * @var array
58
     */
59
    private $variables;
60
61
    public function __construct(
62
        string $installed,
63
        ExtensionVarRepositoryInterface $repository,
64
        ZikulaHttpKernelInterface $kernel,
65
        array $multisitesParameters
66
    ) {
67
        $this->installed = '0.0.0' !== $installed;
68
        $this->repository = $repository;
69
        $this->kernel = $kernel;
70
        $this->protectedSystemVars = $multisitesParameters['protected.systemvars'];
71
    }
72
73
    /**
74
     * Loads extension vars for all extensions to reduce sql statements.
75
     */
76
    private function initialize(): bool
77
    {
78
        if (!$this->installed) {
79
            return false;
80
        }
81
82
        // The empty arrays for handlers and settings are required to prevent messages with E_ALL error reporting
83
        $this->variables = [
84
            'ZikulaSettingsModule' => [],
85
            self::CONFIG => [],
86
        ];
87
88
        // Load all variables into the variables property.
89
        /** @var ExtensionVarEntity[] $vars */
90
        $vars = $this->repository->findAll();
91
        foreach ($vars as $var) {
92
            if (!array_key_exists($var->getModname(), $this->variables)) {
93
                $this->variables[$var->getModname()] = [];
94
            }
95
            $this->variables[$var->getModname()][$var->getName()] = $var->getValue();
96
        }
97
98
        // Pre-load the variables array with empty arrays for known extensions that do not define any variables to
99
        // prevent unnecessary queries to the database.
100
        foreach ($this->kernel->getBundles() as $bundle) {
101
            if (!array_key_exists($bundle->getName(), $this->variables)) {
102
                $this->variables[$bundle->getName()] = [];
103
            }
104
        }
105
        // set default values for localized variables
106
        $this->localizeVariables('en');
107
108
        $this->isInitialized = true;
109
110
        return true;
111
    }
112
113
    public function localizeVariables(string $lang): void
114
    {
115
        $items = ['sitename', 'slogan', 'defaultpagetitle', 'defaultmetadescription', 'startController'];
116
        foreach ($items as $item) {
117
            $indexSource = $item . '_en';
118
            $indexTarget = $item . '_' . $lang;
119
            if (isset($this->variables[self::CONFIG][$indexSource])) {
120
                $this->variables[self::CONFIG][$item] = !empty($this->variables[self::CONFIG][$indexTarget]) ? $this->variables[self::CONFIG][$indexTarget] : $this->variables[self::CONFIG][$indexSource];
121
            }
122
        }
123
    }
124
125
    public function has(string $extensionName, string $variableName): bool
126
    {
127
        if (empty($extensionName) || empty($variableName)) {
128
            throw new InvalidArgumentException();
129
        }
130
        if (!$this->isInitialized && !$this->initialize()) {
131
            return false;
132
        }
133
134
        return isset($this->variables[$extensionName]) && array_key_exists($variableName, $this->variables[$extensionName]);
135
    }
136
137
    public function get(string $extensionName, string $variableName, $default = false)
138
    {
139
        if (empty($extensionName) || empty($variableName)) {
140
            throw new InvalidArgumentException();
141
        }
142
        if (!$this->isInitialized && !$this->initialize()) {
143
            return $default;
144
        }
145
146
        if (isset($this->variables[$extensionName]) && array_key_exists($variableName, $this->variables[$extensionName])) {
147
            return $this->variables[$extensionName][$variableName];
148
        }
149
150
        return $default;
151
    }
152
153
    public function getSystemVar(string $variableName, $default = false)
154
    {
155
        return $this->get(self::CONFIG, $variableName, $default);
156
    }
157
158
    public function getAll(string $extensionName): array
159
    {
160
        if (empty($extensionName)) {
161
            throw new InvalidArgumentException();
162
        }
163
        if (!$this->isInitialized && !$this->initialize()) {
164
            return [];
165
        }
166
167
        return $this->variables[$extensionName] ?? [];
168
    }
169
170
    public function set(string $extensionName, string $variableName, $value = ''): bool
171
    {
172
        if (empty($extensionName) || empty($variableName)) {
173
            throw new InvalidArgumentException();
174
        }
175
        if (!$this->isInitialized) {
176
            $this->initialize();
177
        }
178
        if (self::CONFIG === $extensionName && in_array($variableName, $this->protectedSystemVars, true)) {
179
            return false;
180
        }
181
182
        $entities = $this->repository->findBy(['modname' => $extensionName, 'name' => $variableName]);
183
        $amountOfEntities = count($entities);
184
        if (1 === $amountOfEntities) {
185
            $entity = $entities[0];
186
        } else {
187
            if (1 < $amountOfEntities) {
188
                /** @var ExtensionVarEntity $entity */
189
                foreach ($entities as $entity) {
190
                    // possible duplicates exist. remove all (refs #2385)
191
                    $this->repository->remove($entity);
192
                }
193
            }
194
            $entity = new ExtensionVarEntity();
195
            $entity->setModname($extensionName);
196
            $entity->setName($variableName);
197
        }
198
        $entity->setValue($value);
199
        $this->repository->persistAndFlush($entity);
200
        $this->variables[$extensionName][$variableName] = $value;
201
202
        return true;
203
    }
204
205
    public function setAll(string $extensionName, array $variables = []): bool
206
    {
207
        $ok = true;
208
        foreach ($variables as $var => $value) {
209
            $ok = $ok && $this->set($extensionName, $var, $value);
210
        }
211
212
        return $ok;
213
    }
214
215
    public function del(string $extensionName, string $variableName): bool
216
    {
217
        if (empty($extensionName) || empty($variableName)) {
218
            throw new InvalidArgumentException();
219
        }
220
        if (!$this->isInitialized) {
221
            $this->initialize();
222
        }
223
224
        if (!isset($this->variables[$extensionName])) {
225
            return true;
226
        }
227
        if (array_key_exists($variableName, $this->variables[$extensionName])) {
228
            unset($this->variables[$extensionName][$variableName]);
229
        }
230
231
        return $this->repository->deleteByExtensionAndName($extensionName, $variableName);
232
    }
233
234
    public function delAll(string $extensionName): bool
235
    {
236
        if (empty($extensionName)) {
237
            throw new InvalidArgumentException();
238
        }
239
        if (!$this->isInitialized) {
240
            $this->initialize();
241
        }
242
243
        if (array_key_exists($extensionName, $this->variables)) {
244
            unset($this->variables[$extensionName]);
245
        }
246
247
        return $this->repository->deleteByExtension($extensionName);
248
    }
249
}
250