Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 104
0.00% covered (danger)
0.00%
0 / 13
CRAP
0.00% covered (danger)
0.00%
0 / 1
AbstractPlattformKonfigService
0.00% covered (danger)
0.00%
0 / 104
0.00% covered (danger)
0.00%
0 / 13
1056
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 get
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
30
 set
0.00% covered (danger)
0.00%
0 / 20
0.00% covered (danger)
0.00%
0 / 1
30
 exists
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
56
 unset
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 1
12
 create
0.00% covered (danger)
0.00%
0 / 23
0.00% covered (danger)
0.00%
0 / 1
6
 parseCustomField
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
0
 setEncodedValue
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
0
 removeEncodedValue
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
0
 parsedConfigKey
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 loadConfiguration
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
12
 getCustmConfigurationField
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 configForKey
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
20
1<?php declare(strict_types=1);
2
3namespace Satag\AmicronEntityBundle\Service;
4
5use Doctrine\ORM\EntityManagerInterface;
6use Satag\AmicronEntityBundle\Entity\Kontakt;
7use Satag\AmicronEntityBundle\Util\PlattformKonfig\ConfigKeyStruct;
8
9abstract class AbstractPlattformKonfigService
10{
11    public const DEFAULT_KONTAKTART = 'PlattformKonfig';
12    public const DEFAULT_EINGANGAUSGANG = 'I';
13    public const DEFAULT_MITARBEITER = 'B0T';
14
15    /**
16     * @var array<string, mixed>
17     */
18    protected array $configArray = [];
19
20    /**
21     * @var array<string, mixed>
22     */
23    protected array $parsedConfig = [];
24
25    public function __construct(
26        protected EntityManagerInterface $entityManager
27    ) {
28        $this->loadConfiguration();
29    }
30
31    public function get(string $configKey): mixed
32    {
33        $parsedConfigKey = $this->parsedConfigKey($configKey);
34        if (!isset($this->configArray[$parsedConfigKey->getAnlass()])) {
35            throw new PlattformKonfigException(\sprintf("Konfiguration für Anlass %s (%s) nicht gefunden\r\n", $parsedConfigKey->getAnlass(), $configKey));
36        }
37
38        if (!isset($this->parsedConfig[$parsedConfigKey->getAnlass()]) && $this->configArray[$parsedConfigKey->getAnlass()] instanceof Kontakt) {
39            $this->parsedConfig[$parsedConfigKey->getAnlass()] = $this->parseCustomField($this->configArray[$parsedConfigKey->getAnlass()], $parsedConfigKey->getDataIdentifier());
40        }
41
42        if (!isset($this->parsedConfig[$parsedConfigKey->getAnlass()][$parsedConfigKey->getDataIdentifier()])) {
43            throw new PlattformKonfigException(\sprintf("Konfiguration %s nicht gefunden\r\n", $configKey));
44        }
45
46        return $this->configForKey($this->parsedConfig[$parsedConfigKey->getAnlass()][$parsedConfigKey->getDataIdentifier()], $parsedConfigKey->getParts());
47    }
48
49    public function set(string $configKey, mixed $value): void
50    {
51        $parsedConfigKey = $this->parsedConfigKey($configKey);
52        if (!isset($this->configArray[$parsedConfigKey->getAnlass()])) {
53            throw new PlattformKonfigException(\sprintf("Konfiguration für Anlass %s (%s) nicht gefunden\r\n", $parsedConfigKey->getAnlass(), $configKey));
54        }
55        if (\count($parsedConfigKey->getParts()) === 0 && !\is_array($value)) {
56            throw new PlattformKonfigException(\sprintf("Konfiguration %s konnte nicht gesetzt werden\r\n", $configKey));
57        }
58
59        $configEntity = $this->configArray[$parsedConfigKey->getAnlass()];
60        $currentConfig = $this->parseCustomField($configEntity, $parsedConfigKey->getDataIdentifier());
61
62        $parts = [$parsedConfigKey->getDataIdentifier()];
63        $parts = array_merge($parts, $parsedConfigKey->getParts());
64
65        $newValue = [];
66        $ref = &$newValue;
67        foreach ($parts as $part) {
68            $ref[$part] = [];
69            $ref = &$ref[$part];
70        }
71        $ref = $value;
72        $currentConfig = array_replace_recursive($currentConfig, $newValue);
73
74        $this->setEncodedValue($configEntity, $parsedConfigKey->getDataIdentifier(), $currentConfig[$parsedConfigKey->getDataIdentifier()]);
75
76        $this->entityManager->persist($configEntity);
77        $this->entityManager->flush();
78
79        $this->parsedConfig[$parsedConfigKey->getAnlass()] = $this->parseCustomField($configEntity, $parsedConfigKey->getDataIdentifier());
80    }
81
82    public function exists(string $configKey): bool
83    {
84        $parsedConfigKey = $this->parsedConfigKey($configKey);
85        if (!isset($this->configArray[$parsedConfigKey->getAnlass()])) {
86            return false;
87        }
88        if (!isset($this->parsedConfig[$parsedConfigKey->getAnlass()]) && $this->configArray[$parsedConfigKey->getAnlass()] instanceof Kontakt) {
89            $this->parsedConfig[$parsedConfigKey->getAnlass()] = $this->parseCustomField($this->configArray[$parsedConfigKey->getAnlass()], $parsedConfigKey->getDataIdentifier());
90        }
91        if (!isset($this->parsedConfig[$parsedConfigKey->getAnlass()][$parsedConfigKey->getDataIdentifier()])) {
92            return false;
93        }
94        if (\count($parsedConfigKey->getParts()) === 0) {
95            return true;
96        }
97        $value = $this->configForKey($this->parsedConfig[$parsedConfigKey->getAnlass()][$parsedConfigKey->getDataIdentifier()], $parsedConfigKey->getParts());
98        if ($value === null) {
99            return false;
100        }
101
102        return true;
103    }
104
105    public function unset(string $configKey): void
106    {
107        $parsedConfigKey = $this->parsedConfigKey($configKey);
108        $configEntity = $this->configArray[$parsedConfigKey->getAnlass()];
109        if (\count($parsedConfigKey->getParts()) === 0) {
110            $this->removeEncodedValue($configEntity, $parsedConfigKey->getDataIdentifier());
111            unset($this->parsedConfig[$parsedConfigKey->getAnlass()][$parsedConfigKey->getDataIdentifier()]);
112        } else {
113            $parts = [$parsedConfigKey->getDataIdentifier()];
114            $parts = array_merge($parts, $parsedConfigKey->getParts());
115
116            $currentConfig = $this->parseCustomField($configEntity, $parsedConfigKey->getDataIdentifier());
117
118            $ref = &$currentConfig;
119            foreach ($parts as $part) {
120                $ref = &$ref[$part];
121            }
122            $ref = null;
123            $this->setEncodedValue($configEntity, $parsedConfigKey->getDataIdentifier(), $currentConfig[$parsedConfigKey->getDataIdentifier()]);
124            $this->parsedConfig[$parsedConfigKey->getAnlass()] = $this->parseCustomField($configEntity, $parsedConfigKey->getDataIdentifier());
125        }
126        $this->entityManager->persist($configEntity);
127        $this->entityManager->flush();
128    }
129
130    public function create(string $configDomain, string $key, mixed $init): void
131    {
132        $kontaktRepository = $this->entityManager->getRepository(Kontakt::class);
133
134        $exists = $kontaktRepository->findOneBy(
135            [
136                'kontaktart' => self::DEFAULT_KONTAKTART,
137                'mitarbeiter' => self::DEFAULT_MITARBEITER,
138                'eingangausgang' => self::DEFAULT_EINGANGAUSGANG,
139                'anlass' => $configDomain,
140            ]
141        );
142        if ($exists) {
143            throw new PlattformKonfigException(\sprintf("Konfiguration %s kann nicht angelegt werden, bereits vorhanden\r\n", $configDomain));
144        }
145
146        $newConfig = new Kontakt();
147        $newConfig->setKontaktart(self::DEFAULT_KONTAKTART);
148        $newConfig->setMitarbeiter(self::DEFAULT_MITARBEITER);
149        $newConfig->setEingangausgang(self::DEFAULT_EINGANGAUSGANG);
150        $newConfig->setAnlass($configDomain);
151        $newConfig->setDatum(new \DateTime());
152
153        $this->setEncodedValue($newConfig, $key, $init);
154
155        $this->entityManager->persist($newConfig);
156        $this->entityManager->flush();
157
158        $anlass = $newConfig->getAnlass() ?? $configDomain;
159        $this->configArray[$anlass] = $newConfig;
160        $this->parsedConfig[$anlass] = $this->parseCustomField($newConfig, $key);
161    }
162
163    /**
164     * @return array<string, mixed>
165     */
166    abstract protected function parseCustomField(Kontakt $configEntity, string $dataIdentifier): array;
167
168    abstract protected function setEncodedValue(Kontakt $configEntity, string $dataIdentifier, mixed $data): void;
169
170    abstract protected function removeEncodedValue(Kontakt $configEntity, string $dataIdentifier): void;
171
172    protected function parsedConfigKey(string $configKey): ConfigKeyStruct
173    {
174        return new ConfigKeyStruct($configKey);
175    }
176
177    protected function loadConfiguration(): void
178    {
179        $kontaktRepository = $this->entityManager->getRepository(Kontakt::class);
180        $entities = $kontaktRepository->findBy([
181            'kontaktart' => self::DEFAULT_KONTAKTART,
182            'mitarbeiter' => self::DEFAULT_MITARBEITER,
183            'eingangausgang' => self::DEFAULT_EINGANGAUSGANG,
184        ]);
185        /**
186         * @var Kontakt[] $entities
187         */
188        foreach ($entities as $config) {
189            if ($config->getAnlass() !== null) {
190                $this->configArray[$config->getAnlass()] = $config;
191            }
192        }
193    }
194
195    protected function getCustmConfigurationField(): string
196    {
197        return 'bemerkung';
198    }
199
200    /**
201     * @param array<string, mixed> $config
202     * @param string[] $parts
203     *
204     * @return mixed|null
205     */
206    protected function configForKey(array $config, array $parts): mixed
207    {
208        $current = $config;
209        foreach ($parts as $part) {
210            if (!\is_array($current)) {
211                return null;
212            }
213            if (\array_key_exists($part, $current)) {
214                $current = $current[$part];
215
216                continue;
217            }
218
219            return null;
220        }
221
222        return $current;
223    }
224}