Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
42.86% covered (danger)
42.86%
60 / 140
25.00% covered (danger)
25.00%
5 / 20
CRAP
0.00% covered (danger)
0.00%
0 / 1
MailTemplates
42.86% covered (danger)
42.86%
60 / 140
25.00% covered (danger)
25.00%
5 / 20
497.00
0.00% covered (danger)
0.00%
0 / 1
 readEntity
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 readList
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 readListWithoutProvider
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
1
 readListByProvider
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
1
 readCustomizedListForProvider
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 readTemplate
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 readTemplateById
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 deleteTemplateById
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 updateTemplateContent
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
2
 updateTemplateContentById
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
2
 createCustomizationForProvider
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
2
 copyCustomizationToProviders
100.00% covered (success)
100.00%
20 / 20
100.00% covered (success)
100.00%
1 / 1
9
 writeCustomizationsToProviders
70.00% covered (warning)
70.00%
14 / 20
0.00% covered (danger)
0.00%
0 / 1
8.32
 updateEntity
0.00% covered (danger)
0.00%
0 / 20
0.00% covered (danger)
0.00%
0 / 1
56
 readProperty
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 replaceProperty
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 deleteProperty
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 fetchData
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
6
 getSpecifiedValue
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
12
 mergeMailTemplatesWithCustomizations
81.82% covered (warning)
81.82%
9 / 11
0.00% covered (danger)
0.00%
0 / 1
6.22
1<?php
2
3namespace BO\Zmsbackend\Mail\Service;
4
5use BO\Zmsentities\Mailtemplate as Mailtemplate;
6
7class MailTemplates extends \BO\Zmsbackend\Base
8{
9    /**
10     *
11     * @return \BO\Zmsentities\Mailtemplate
12     */
13    public function readEntity()
14    {
15        $query = \BO\Zmsbackend\Mail\Repository\Mailtemplate::QUERY_SELECT;
16        $config = $this->fetchData($query);
17        return $config;
18    }
19
20
21    /**
22     * @psalm-api
23     */
24    public function readList(): \BO\Zmsentities\Collection\MailtemplateList
25    {
26        $query = new \BO\Zmsbackend\Mail\Repository\Mailtemplate(\BO\Zmsbackend\Query\Base::SELECT);
27        $query->addEntityMapping();
28        $logList = new \BO\Zmsentities\Collection\MailtemplateList($this->fetchList($query, new Mailtemplate()));
29        return $logList;
30    }
31
32    public function readListWithoutProvider(): \BO\Zmsentities\Collection\MailtemplateList
33    {
34        $query = new \BO\Zmsbackend\Mail\Repository\Mailtemplate(\BO\Zmsbackend\Query\Base::SELECT);
35        $query->addEntityMapping();
36        $query->addConditionWithoutProvider();
37        $logList = new \BO\Zmsentities\Collection\MailtemplateList($this->fetchList($query, new Mailtemplate()));
38        return $logList;
39    }
40
41    public function readListByProvider($providerId): \BO\Zmsentities\Collection\MailtemplateList
42    {
43        $query = new \BO\Zmsbackend\Mail\Repository\Mailtemplate(\BO\Zmsbackend\Query\Base::SELECT);
44        $query->addEntityMapping();
45        $query->addConditionProviderId($providerId);
46        $logList = new \BO\Zmsentities\Collection\MailtemplateList($this->fetchList($query, new Mailtemplate()));
47        return $logList;
48    }
49
50    public function readCustomizedListForProvider($providerId)
51    {
52        $generalTemplates = $this->readListWithoutProvider();
53        $customTemplates = $this->readListByProvider($providerId);
54        return $this->mergeMailTemplatesWithCustomizations($generalTemplates, $customTemplates);
55    }
56
57
58    public function readTemplate($templateName): Mailtemplate
59    {
60        $query = new \BO\Zmsbackend\Mail\Repository\Mailtemplate(\BO\Zmsbackend\Query\Base::SELECT);
61        $query->addEntityMapping()
62            ->addConditionName($templateName);
63        return $this->fetchOne($query, new Mailtemplate());
64    }
65
66    public function readTemplateById($templateId): Mailtemplate
67    {
68        $query = new \BO\Zmsbackend\Mail\Repository\Mailtemplate(\BO\Zmsbackend\Query\Base::SELECT);
69        $query->addEntityMapping()
70            ->addConditionId($templateId);
71        return $this->fetchOne($query, new Mailtemplate());
72    }
73
74    public function deleteTemplateById($templateId): bool
75    {
76        $query = new \BO\Zmsbackend\Mail\Repository\Mailtemplate(\BO\Zmsbackend\Query\Base::DELETE);
77        $query->addConditionId($templateId);
78        return $this->deleteItem($query);
79    }
80
81    /** @psalm-api */
82    public function updateTemplateContent($templateName, $templateContent)
83    {
84        $query = new \BO\Zmsbackend\Mail\Repository\Mailtemplate(\BO\Zmsbackend\Query\Base::UPDATE);
85        $query->addConditionName($templateName);
86        $query->addTemplateContent($templateContent);
87        $this->writeItem($query);
88        return $this->readTemplate($templateName);
89        //return $this->readEntity($templateName, 1);
90    }
91
92    public function updateTemplateContentById($templateId, $templateContent)
93    {
94        $query = new \BO\Zmsbackend\Mail\Repository\Mailtemplate(\BO\Zmsbackend\Query\Base::UPDATE);
95        $query->addConditionId($templateId);
96        $query->addTemplateContent($templateContent);
97        $this->writeItem($query);
98        return $this->readTemplateById($templateId);
99        //return $this->readEntity($templateName, 1);
100    }
101
102
103    public function createCustomizationForProvider($providerId, $templateName, $templateContent)
104    {
105        $query = new \BO\Zmsbackend\Mail\Repository\Mailtemplate(\BO\Zmsbackend\Query\Base::INSERT);
106        $query->addValues(array(
107            'name' => $templateName,
108            'value' => $templateContent,
109            'provider' => $providerId,
110            'changeTimestamp' => (new \DateTimeImmutable())->format('Y-m-d H:i:s')
111        ));
112        $this->writeItem($query);
113        return $this->readTemplate($templateName);
114    }
115
116    public function copyCustomizationToProviders(
117        int $sourceTemplateId,
118        string $sourceProviderId,
119        array $targetProviderIds
120    ): Mailtemplate {
121        $sourceTemplate = $this->readTemplateById($sourceTemplateId);
122
123        if (
124            !isset($sourceTemplate->id)
125            || !$sourceTemplate->id
126            || empty($sourceTemplate->provider)
127            || (string) $sourceTemplate->provider !== $sourceProviderId
128        ) {
129            throw new \BO\Zmsbackend\Mail\Exception\MailTemplateCustomizationNotFound();
130        }
131
132        $targetProviderIds = array_values(
133            array_unique(array_map('strval', $targetProviderIds))
134        );
135
136        if (
137            empty($targetProviderIds)
138            || in_array($sourceProviderId, $targetProviderIds, true)
139        ) {
140            throw new \BO\Zmsbackend\Mail\Exception\MailTemplateCopyInvalidInput();
141        }
142
143        foreach ($targetProviderIds as $targetProviderId) {
144            if ($targetProviderId === '') {
145                throw new \BO\Zmsbackend\Mail\Exception\MailTemplateCopyInvalidInput();
146            }
147        }
148
149        $this->writeCustomizationsToProviders(
150            $sourceTemplate,
151            $targetProviderIds
152        );
153
154        return $sourceTemplate;
155    }
156
157    /**
158     * @param string[] $targetProviderIds
159     */
160    private function writeCustomizationsToProviders(
161        Mailtemplate $sourceTemplate,
162        array $targetProviderIds
163    ): void {
164        $connection = $this->getWriter();
165        $startedTransaction = false;
166        if (!$connection->inTransaction()) {
167            $connection->beginTransaction();
168            $startedTransaction = true;
169        }
170
171        try {
172            foreach ($targetProviderIds as $targetProviderId) {
173                $this->perform(
174                    \BO\Zmsbackend\Mail\Repository\Mailtemplate::QUERY_UPSERT_CUSTOMIZATION,
175                    [
176                        'name' => (string) $sourceTemplate->name,
177                        'value' => (string) $sourceTemplate->value,
178                        'provider' => $targetProviderId,
179                    ]
180                );
181            }
182
183            if ($startedTransaction) {
184                $connection->commit();
185            }
186        } catch (\Throwable $exception) {
187            if ($startedTransaction && $connection->inTransaction()) {
188                $connection->rollBack();
189            }
190
191            throw $exception;
192        }
193    }
194
195    /**
196     * @psalm-api
197     */
198    public function updateEntity(MailTemplate $config): Mailtemplate|null
199    {
200        $compareEntity = $this->readEntity();
201        $result = false;
202        $query = new \BO\Zmsbackend\Mail\Repository\Mailtemplate(\BO\Zmsbackend\Query\Base::REPLACE);
203        foreach ($config as $key => $item) {
204            if (is_array($item)) {
205                foreach ($item as $itemName => $itemValue) {
206                    if ($itemValue && $compareEntity->getPreference($key, $itemName) != $itemValue) {
207                        $query->addValues(array(
208                            'name' => $key . '__' . $itemName,
209                            'value' => $this->getSpecifiedValue($itemValue),
210                            'changeTimestamp' => (new \DateTimeImmutable())->format('Y-m-d H:i:s')
211                        ));
212                        $result = $this->writeItem($query);
213                    }
214                }
215            } else {
216                $query->addValues(array(
217                    'name' => $key,
218                    'value' => $this->getSpecifiedValue($item),
219                    'changeTimestamp' => (new \DateTimeImmutable())->format('Y-m-d H:i:s')
220                ));
221                $result = $this->writeItem($query);
222            }
223        }
224        return ($result) ? $this->readEntity() : null;
225    }
226
227    /** @psalm-api */
228    public function readProperty($property, bool $forUpdate = false)
229    {
230        $sql = \BO\Zmsbackend\Mail\Repository\Mailtemplate::QUERY_SELECT_PROPERTY;
231        if ($forUpdate) {
232            $sql .= " FOR UPDATE";
233        }
234        return $this->fetchValue($sql, [$property]);
235    }
236
237    /** @psalm-api */
238    public function replaceProperty($property, $value)
239    {
240        return $this->perform(\BO\Zmsbackend\Mail\Repository\Mailtemplate::QUERY_REPLACE_PROPERTY, [
241            'property' => $property,
242            'value' => $value,
243        ]);
244    }
245
246    /**
247     * remove config data
248     *
249     *
250     * @return bool
251     * @psalm-api
252     */
253    public function deleteProperty($property)
254    {
255        $query = new \BO\Zmsbackend\Mail\Repository\Mailtemplate(\BO\Zmsbackend\Query\Base::DELETE);
256        $query->addConditionName($property);
257        return $this->deleteItem($query);
258    }
259
260    protected function fetchData(string $querySql): Mailtemplate
261    {
262        $splittedHash = array();
263        $dataList = $this->getReader()->fetchAll($querySql);
264        foreach ($dataList as $data) {
265            $splittedHash[$data['name']] = $data['value'];
266        }
267
268        return new Mailtemplate($splittedHash);
269    }
270
271    protected function getSpecifiedValue($value): int|string
272    {
273        if (is_bool($value)) {
274            return ($value) ? 1 : 0;
275        }
276        return trim($value);
277    }
278
279    protected function mergeMailTemplatesWithCustomizations($generalTemplates, $customTemplates): array
280    {
281
282        $customTemplatesByName = [];
283
284        if ($customTemplates) {
285            foreach ($customTemplates as $template) {
286                $customTemplatesByName[$template['name']] = $template;
287            }
288        }
289
290        $mergedTemplates = [];
291
292        if ($generalTemplates) {
293            foreach ($generalTemplates as $template) {
294                if (isset($customTemplatesByName[$template['name']])) {
295                    $mergedTemplates[] = $customTemplatesByName[$template['name']];
296                } else {
297                    $mergedTemplates[] = $template;
298                }
299            }
300        }
301
302        return $mergedTemplates;
303    }
304}