Passed
Pull Request — main (#9)
by
unknown
02:49
created

ConfigManager::filterValueByRole()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 2
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 4
rs 10
1
<?php
2
3
namespace Xiidea\EasyConfigBundle\Services\Manager;
4
5
use Doctrine\DBAL\Types\Types;
6
use Symfony\Component\Form\FormFactoryInterface;
7
use Symfony\Component\Form\FormInterface;
8
use Symfony\Component\Form\FormView;
9
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
10
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
11
use Xiidea\EasyConfigBundle\Model\BaseConfig;
12
use Xiidea\EasyConfigBundle\Services\FormGroup\ConfigGroupInterface;
13
use Xiidea\EasyConfigBundle\Services\Repository\ConfigRepositoryInterface;
14
15
class ConfigManager
16
{
17
    private array $groups = [];
18
19
    public function __construct(
20
        private ConfigRepositoryInterface     $repository,
21
        private FormFactoryInterface          $formFactory,
22
        private TokenStorageInterface         $tokenStorage,
23
        private AuthorizationCheckerInterface $checker,
24
                                              $configurationGroups = [])
25
    {
26
        foreach ($configurationGroups as $group) {
27
            $this->groups[$group->getNameSpace()] = $group;
28
        }
29
    }
30
31
    public function addConfigGroup(ConfigGroupInterface $group)
32
    {
33
        $this->groups[$group->getNameSpace()] = $group;
34
    }
35
36
    /**
37
     * @return ConfigGroupInterface[]
38
     */
39
    public function getConfigurationGroups(): array
40
    {
41
        $username = $this->getUsername();
42
        $groups = [];
43
44
        foreach ($this->groups as $key => $group) {
45
            $groups[str_replace($username . '.', '', $key)] = $group;
46
        }
47
48
        return $groups;
49
    }
50
51
    public function getConfigurationGroupForms(): array
52
    {
53
        $return = [];
54
55
        foreach ($this->groups as $groupKey => $policyGroup) {
56
            $return[] = [
57
                'key' => $groupKey,
58
                'label' => $policyGroup->getLabel(),
59
                'form' => $this->createFormView($policyGroup, $groupKey),
60
                'isEditable' => $this->checker->isGranted($policyGroup->getAuthorSecurityLevels()),
61
            ];
62
        }
63
64
        return $return;
65
    }
66
67
    public function getConfigurationsByGroup(string $groupKey): array
68
    {
69
        $username = $this->getUsername();
70
        $configurations = $this->repository->getConfigurationByUsernameAndGroup(
71
            $username,
72
            $groupKey
73
        );
74
        $results = [];
75
76
        /**
77
         * @var BaseConfig $configuration
78
         */
79
        foreach ($configurations as $configuration) {
80
            $key = str_replace($username . '.', '', $configuration->getId());
81
            $key = str_replace($groupKey . '.', '', $key);
82
83
            if (str_contains($configuration->getId(), $username)) {
84
                $results[$key] = $configuration->getValue();
85
            } elseif (!array_key_exists($key, $results)) {
86
                $results[$key] = $configuration->getValue();
87
            }
88
        }
89
90
        return $results;
91
    }
92
93
    public function getConfigurationValueByKey(string $key): string
94
    {
95
        $username = $this->getUsername();
96
        $config = $this->repository->findByKey($key);
97
98
        if ($config && strtolower($config->getType()) === 'json') {
99
            return $this->getJsonConfigurationValues($key);
100
        }
101
102
        $configurations = $this->repository->getConfigurationByUsernameAndKey($username, $key);
103
        $value = '';
104
105
        /**
106
         * @var BaseConfig $configuration
107
         */
108
        foreach ($configurations as $configuration) {
109
            $value = $configuration->getValue();
110
111
            if (str_contains($configuration->getId(), $username . $key)) {
112
                break;
113
            }
114
        }
115
116
        return $value;
117
    }
118
119
    /**
120
     * @param $policyGroup
121
     * @param $groupKey
122
     */
123
    protected function createFormView(ConfigGroupInterface $policyGroup, $groupKey): FormView
124
    {
125
        return $policyGroup
126
            ->getForm($this->formFactory, $this->getConfigurationsByGroupKey($groupKey))
127
            ->createView();
128
    }
129
130
    public function getConfigurationsByGroupKey($group): array
131
    {
132
        return $this->repository->getValuesByGroupKey($group);
133
    }
134
135
    public function getConfigurationGroup($key): ConfigGroupInterface
136
    {
137
        return $this->groups[$key];
138
    }
139
140
    private function guessType(FormInterface $item): ?string
141
    {
142
        $getNormData = $item->getNormData();
143
144
        if (is_string($getNormData)) {
145
            return null;
146
        }
147
148
        if ($getNormData instanceof \DateTime) {
149
            return Types::DATE_MUTABLE;
150
        }
151
152
        if (is_array($getNormData)) {
153
            return 'json';
154
        }
155
156
        if (is_int($getNormData)) {
157
            return Types::INTEGER;
158
        }
159
160
        return null;
161
    }
162
163
    public function saveGroupData($key, FormInterface $form)
164
    {
165
        $types = [];
166
167
        foreach ($form->all() as $item) {
168
            $types[$item->getName()] = $this->guessType($item);
169
        }
170
171
        $this->repository->saveMultiple($key, $form->getData(), $types);
172
    }
173
174
    public function saveUserGroupData($key, FormInterface $form)
175
    {
176
        $types = [];
177
178
        foreach ($form->all() as $item) {
179
            $types[$item->getName()] = $this->guessType($item);
180
        }
181
182
        $formData = $form->getData();
183
184
        foreach ($formData as $k => $val) {
185
            $checkBoxKey = $k . 'Preference';
186
187
            if (array_key_exists($checkBoxKey, $formData)) {
188
                if ($formData[$checkBoxKey]) {
189
                    unset($formData[$k]);
190
                    $this->repository->removeByKey($key . '.' . $k);
191
                }
192
193
                unset($types[$checkBoxKey]);
194
                unset($formData[$checkBoxKey]);
195
            }
196
        }
197
198
        $this->repository->saveMultiple($key, $formData, $types);
199
    }
200
201
    public function getConfigurationGroupForm($group, $data = null): FormInterface
202
    {
203
        if (null === $data) {
204
            $data = $this->getConfigurationsByGroupKey($group);
205
        }
206
207
        return $this->groups[$group]->getForm($this->formFactory, $data);
208
    }
209
210
    public function getConfigurationGroupLabel($group): string
211
    {
212
        return $this->groups[$group]->getLabel();
213
    }
214
215
    public function getUserConfigurationValuesByGroupKey($groupKey): array
216
    {
217
        $username = $this->getUsername();
218
        $configurations = $this->repository->getConfigurationByUsernameAndGroup(
219
            $username,
220
            $groupKey
221
        );
222
        $values = [];
223
224
        foreach ($configurations as $configuration) {
225
            $key = str_replace("{$username}.", '', $configuration->getId());
226
            $key = str_replace("{$groupKey}.", '', $key);
227
228
            if (str_contains($configuration->getId(), $username)) {
229
                $values[$key] = $configuration->getValue();
230
                $values[$key . 'Preference'] = false;
231
            } elseif (!array_key_exists($key, $values)) {
232
                $values[$key] = $configuration->getValue();
233
                $values[$key . 'Preference'] = true;
234
            }
235
        }
236
237
        return $values;
238
    }
239
240
    public function concatUsernameWithKey($key): string
241
    {
242
        $username = $this->getUsername();
243
244
        if (!str_starts_with($key, $username)) {
245
            $key = "{$username}.{$key}";
246
        }
247
248
        return $key;
249
    }
250
251
    public function getValueByKey(int $isGlobal, string $key): string
252
    {
253
        $username = $this->getUsername();
254
        $key = str_replace("{$username}.", '', $key);
255
256
        if (!$isGlobal) {
257
            $key = $username . '.' . $key;
258
        }
259
260
        $result = $this->repository->getConfigurationValue($key);
261
262
        if ($result === null) {
263
            $result = '';
264
        }
265
266
        return $result;
267
    }
268
269
    private function getUsername(): ?string
270
    {
271
        if (null == $this->tokenStorage->getToken()) {
272
            return '';
273
        }
274
275
        return $this->tokenStorage->getToken()->getUser()->getUserIdentifier();
276
    }
277
278
    protected function typeCast($value, $type)
279
    {
280
        if (empty($value)) {
281
            return null;
282
        }
283
284
        switch ($type) {
285
            case Types::DATE_MUTABLE:
286
            case Types::DATETIME_MUTABLE:
287
                return new \DateTime($value);
288
            case Types::BOOLEAN:
289
                return (bool)$value;
290
            case Types::INTEGER:
291
                return (int)$value;
292
            case Types::JSON:
293
                return json_decode($value);
294
            default:
295
                return $value;
296
        }
297
    }
298
299
    public function getConfigurationValue($id, $type = null)
300
    {
301
        $key = $this->concatUsernameWithKey($id);
302
        $value = $this->repository->getConfigurationValue($key);
303
        if (null === $value) {
304
            $value = $this->repository->getConfigurationValue($id);
305
        }
306
307
        if (null === $type) {
308
            return $value;
309
        }
310
311
        return $this->typeCast($value, $type);
312
    }
313
314
    public function getFrontendConfigValuesByGroup($group): array
315
    {
316
        $items = $this->repository->loadAllByGroup($group, true, true);
317
        $userItems = $this->repository->loadAllByGroup(
318
            $this->concatUsernameWithKey($group),
319
            true,
320
            true
321
        );
322
        foreach ($userItems as $key => $item) {
323
            if ('DEFAULT' === $item) {
324
                continue;
325
            }
326
            $items[$key] = $item;
327
        }
328
329
        return $items;
330
    }
331
332
    private function getJsonConfigurationValues(string $key, string $uniqueKey = 'componentId'): ?string
333
    {
334
        [$globalRow, $userRow] = $this->repository->getConfigurationByUsernameAndKey($this->getUsername(), $key) + [null, null];
335
        $configurations = $this->filterValueByRole($globalRow?->getValue() ? json_decode($globalRow->getValue(), true) : []);
336
        $userConfigurations = $this->filterValueByRole($userRow?->getValue() ? json_decode($userRow->getValue(), true) : []);
337
338
        if (empty($userConfigurations)) {
339
            return json_encode($configurations);
340
        }
341
342
        foreach ($configurations as $k => $globalConfig) {
343
            foreach ($userConfigurations as $userConfiguration) {
344
                if ($globalConfig[$uniqueKey] === $userConfiguration[$uniqueKey]) {
345
                    $configurations[$k] = $userConfiguration;
346
                    break;
347
                }
348
            }
349
        }
350
351
        return json_encode($configurations);
352
    }
353
354
    private function filterValueByRole(array $configValues): array
355
    {
356
        return array_values(array_filter($configValues, function ($config) {
357
            return !isset($config['role']) || $this->checker->isGranted($config['role']);
358
        }));
359
    }
360
}
361