Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
78.62% covered (warning)
78.62%
125 / 159
66.67% covered (warning)
66.67%
10 / 15
CRAP
0.00% covered (danger)
0.00%
0 / 1
Mail
78.62% covered (warning)
78.62%
125 / 159
66.67% covered (warning)
66.67%
10 / 15
48.67
0.00% covered (danger)
0.00%
0 / 1
 readEntity
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
3
 readEntities
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
12
 readEntitiesIds
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
2
 readList
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
1 / 1
3
 readListIds
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
2
 readResolvedReferences
93.75% covered (success)
93.75%
15 / 16
0.00% covered (danger)
0.00%
0 / 1
4.00
 writeInQueueWithAdmin
100.00% covered (success)
100.00%
18 / 18
100.00% covered (success)
100.00%
1 / 1
1
 writeInQueue
100.00% covered (success)
100.00%
26 / 26
100.00% covered (success)
100.00%
1 / 1
7
 writeInQueueWithDailyProcessList
100.00% covered (success)
100.00%
16 / 16
100.00% covered (success)
100.00%
1 / 1
1
 writeMimeparts
100.00% covered (success)
100.00%
18 / 18
100.00% covered (success)
100.00%
1 / 1
6
 deleteEntity
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 deleteEntities
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 readReminderLastRun
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 writeReminderLastRun
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 readMultiPartByQueueId
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3namespace BO\Zmsbackend\Mail\Service;
4
5use BO\Zmsentities\Mail as Entity;
6use BO\Zmsentities\Mimepart;
7use BO\Zmsentities\Process as ProcessEntity;
8use BO\Zmsentities\Collection\MailList as Collection;
9
10/**
11 *
12 * @SuppressWarnings(CouplingBetweenObjects)
13 */
14class Mail extends \BO\Zmsbackend\Base
15{
16    /**
17     * Fetch status from db
18     *
19     * @return \BO\Zmsentities\Mail
20     *
21     * @param false|string $itemId
22     */
23    public function readEntity(string|false $itemId, $resolveReferences = 1)
24    {
25        $query = new \BO\Zmsbackend\Mail\Repository\MailQueue(\BO\Zmsbackend\Query\Base::SELECT);
26        $query->addEntityMapping()
27            ->addResolvedReferences($resolveReferences)
28            ->addConditionItemId($itemId);
29        $mail = $this->fetchOne($query, new Entity());
30        if ($mail && $mail->hasId()) {
31            $mail = $this->readResolvedReferences($mail, $resolveReferences);
32        }
33        return $mail;
34    }
35
36    public function readEntities(array $itemIds, $resolveReferences = 1, $limit = 300, string $order = 'ASC'): Collection
37    {
38        $mailList = new Collection();
39        $query = new \BO\Zmsbackend\Mail\Repository\MailQueue(\BO\Zmsbackend\Query\Base::SELECT);
40        $query->addEntityMapping()
41              ->addResolvedReferences($resolveReferences)
42              ->addWhereIn('id', $itemIds)
43              ->addOrderBy('createTimestamp', $order)
44              ->addLimit($limit);
45        $result = $this->fetchList($query, new Entity());
46
47        foreach ($result as $item) {
48            $entity = new Entity($item);
49            $entity = $this->readResolvedReferences($entity, $resolveReferences);
50            if ($entity instanceof Entity) {
51                $mailList->addEntity($entity);
52            }
53        }
54
55        return $mailList;
56    }
57
58
59    public function readEntitiesIds(array $itemIds, $resolveReferences = 1, $limit = 300, string $order = 'ASC')
60    {
61
62        $query = new \BO\Zmsbackend\Mail\Repository\MailQueue(\BO\Zmsbackend\Query\Base::SELECT);
63        $query->selectFields(['id', 'createTimestamp'])
64              ->addEntityMapping()
65              ->addResolvedReferences($resolveReferences)
66              ->addWhereIn('id', $itemIds)
67              ->addOrderBy('createTimestamp', $order)
68              ->addLimit($limit);
69
70        return $this->fetchList($query, new Entity());
71    }
72
73    public function readList($resolveReferences = 1, $limit = 300, string $order = 'ASC'): Collection
74    {
75        $mailList = new Collection();
76        $query = new \BO\Zmsbackend\Mail\Repository\MailQueue(\BO\Zmsbackend\Query\Base::SELECT);
77        $query->addEntityMapping()
78              ->addResolvedReferences($resolveReferences)
79              ->addOrderBy('createTimestamp', $order)
80              ->addLimit($limit);
81        $result = $this->fetchList($query, new Entity());
82
83        foreach ($result as $item) {
84            $entity = new Entity($item);
85            $entity = $this->readResolvedReferences($entity, $resolveReferences);
86            if ($entity instanceof Entity) {
87                $mailList->addEntity($entity);
88            }
89        }
90
91        return $mailList;
92    }
93
94
95    public function readListIds($resolveReferences = 1, $limit = 300, string $order = 'ASC')
96    {
97        $query = new \BO\Zmsbackend\Mail\Repository\MailQueue(\BO\Zmsbackend\Query\Base::SELECT);
98        $query->selectFields(['id', 'createTimestamp'])
99              ->addEntityMapping()
100              ->addResolvedReferences($resolveReferences)
101              ->addOrderBy('createTimestamp', $order)
102              ->addLimit($limit);
103
104        return $this->fetchList($query, new Entity());
105    }
106
107
108
109    /**
110     * @return Entity
111     */
112    #[\Override]
113    public function readResolvedReferences(\BO\Zmsentities\Schema\Entity $entity, $resolveReferences)
114    {
115        if (!$entity instanceof Entity) {
116            throw new \InvalidArgumentException('Expected ' . Entity::class);
117        }
118        $multiPart = $this->readMultiPartByQueueId($entity->id);
119        $entity->addMultiPart($multiPart);
120        if (1 <= $resolveReferences) {
121            $processQuery = new \BO\Zmsbackend\Process\Service\Process();
122            $authData = $processQuery->readAuthKeyByProcessId($entity->process['id']);
123            $entity->process = $processQuery
124                ->readEntity(
125                    $entity->process['id'],
126                    is_array($authData) ? $authData['authKey'] : null,
127                    $resolveReferences - 1
128                );
129            $entity->department = (new \BO\Zmsbackend\Department\Service\Department())
130                ->readEntity($entity->department['id'], $resolveReferences - 1);
131        }
132        return $entity;
133    }
134
135    public function writeInQueueWithAdmin(Entity $mail): Entity
136    {
137        $query = new \BO\Zmsbackend\Mail\Repository\MailQueue(\BO\Zmsbackend\Query\Base::INSERT);
138        $process = new \BO\Zmsentities\Process($mail->process);
139        $department = (new \BO\Zmsbackend\Department\Service\Department())->readByScopeId($process->getScopeId(), 0);
140        $query->addValues(
141            array(
142                'processID' => $mail->process['id'],
143                'departmentID' => $department->toProperty()->id->get(),
144                'createIP' => $mail->createIP,
145                'createTimestamp' => time(),
146                'subject' => $mail->subject,
147                'clientFamilyName' => $process->scope['contact']['name'],
148                'clientEmail' => $process->scope['contact']['email']
149            )
150        );
151        $this->writeItem($query);
152        $queueId = $this->getWriter()->lastInsertId();
153        $this->writeMimeparts($queueId, $mail->multipart);
154        return $this->readEntity($queueId);
155    }
156
157    public function writeInQueue(Entity $mail, \DateTimeInterface $dateTime, bool $count = true): Entity
158    {
159        $query = new \BO\Zmsbackend\Mail\Repository\MailQueue(\BO\Zmsbackend\Query\Base::INSERT);
160        $process = new \BO\Zmsentities\Process($mail->process);
161        $client = $mail->getFirstClient();
162        if (! $client->hasEmail()) {
163            throw new \BO\Zmsbackend\Mail\Exception\ClientWithoutEmail();
164        }
165        $department = ($mail->department && $mail->department->hasId()) ?
166            $mail->department :
167            (new \BO\Zmsbackend\Department\Service\Department())->readByScopeId($process->getScopeId(), 0);
168        $query->addValues(
169            array(
170                'processID' => $mail->process['id'],
171                'departmentID' => $department->getId(),
172                'createIP' => $mail->createIP,
173                'createTimestamp' => ($dateTime) ? $dateTime->format('U') : time(),
174                'subject' => $mail->subject,
175                'clientFamilyName' => $client->familyName,
176                'clientEmail' => $client->email
177            )
178        );
179        $success = $this->writeItem($query);
180        $queueId = $this->getWriter()->lastInsertId();
181        if ($count && $success) {
182            $client->emailSendCount += 1;
183            (new \BO\Zmsbackend\Process\Service\Process())->updateEntity($process, $dateTime);
184        }
185        $this->writeMimeparts($queueId, $mail->multipart);
186        return $this->readEntity($queueId);
187    }
188
189    public function writeInQueueWithDailyProcessList(
190        \BO\Zmsentities\Scope $scope,
191        Entity $mail
192    ): Entity {
193        $query = new \BO\Zmsbackend\Mail\Repository\MailQueue(\BO\Zmsbackend\Query\Base::INSERT);
194        $department = (new \BO\Zmsbackend\Department\Service\Department())->readByScopeId($scope->getId(), 0);
195        $query->addValues(
196            array(
197                'departmentID' => $department->toProperty()->id->get(),
198                'createTimestamp' => time(),
199                'createIP' => $mail->createIP,
200                'subject' => $mail->subject,
201                'clientFamilyName' => $mail->client->familyName,
202                'clientEmail' => $mail->client->email
203            )
204        );
205        $this->writeItem($query);
206        $queueId = $this->getWriter()->lastInsertId();
207        $this->writeMimeparts($queueId, $mail->multipart);
208        return $this->readEntity($queueId);
209    }
210
211    /**
212     * @param false|string $queueId
213     *
214     * @return true
215     */
216    protected function writeMimeparts(string|false $queueId, $multipart): bool
217    {
218        $success = true;
219        foreach ($multipart as $part) {
220            $query = new \BO\Zmsbackend\Mail\Repository\Mimepart(\BO\Zmsbackend\Query\Base::INSERT);
221            $query->addValues(
222                array(
223                    'queueId' => $queueId,
224                    'mime' => $part['mime'],
225                    'content' => $part['content'],
226                    'base64' => $part['base64'] ? 1 : 0
227                )
228            );
229            if (! isset($part['content']) || ! isset($part['mime']) || ! $success) {
230                $this->deleteEntity($queueId);
231                throw new \BO\Zmsbackend\Mail\Exception\MailWritePartFailed(
232                    'Failed to write part (' . $part['mime'] . ') of mail with id ' . $queueId
233                );
234            }
235            $success = $this->writeItem($query);
236        }
237        return true;
238    }
239
240    public function deleteEntity($itemId)
241    {
242        $query = \BO\Zmsbackend\Mail\Repository\MailQueue::QUERY_DELETE;
243        $status = $this->perform($query, [$itemId]);
244        return $status;
245    }
246
247    public function deleteEntities(array $itemIds)
248    {
249        $query = \BO\Zmsbackend\Mail\Repository\MailQueue::QUERY_MULTI_DELETE;
250        $placeholders = implode(',', array_fill(0, count($itemIds), '?'));
251        $query = str_replace('?', $placeholders, $query);
252        return $this->perform($query, $itemIds);
253    }
254
255    public function readReminderLastRun(\DateTimeInterface $now)
256    {
257        $lastRun = (new \BO\Zmsbackend\Config\Service\Config())->readProperty('status__mailReminderLastRun', false);
258        $lastRunDateTime = ($lastRun) ? new \DateTimeImmutable($lastRun) : $now;
259        return $lastRunDateTime;
260    }
261
262    public function writeReminderLastRun(\DateTimeInterface $now): void
263    {
264        (new \BO\Zmsbackend\Config\Service\Config())->replaceProperty('status__mailReminderLastRun', $now->format('Y-m-d H:i:s'));
265    }
266
267    protected function readMultiPartByQueueId($queueId)
268    {
269        $query = new \BO\Zmsbackend\Mail\Repository\Mimepart(\BO\Zmsbackend\Query\Base::SELECT);
270        $query->addEntityMapping()
271            ->addConditionQueueId($queueId);
272        return $this->fetchList($query, new Mimepart());
273    }
274}