Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 55
0.00% covered (danger)
0.00%
0 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
ProcessListSummaryMail
0.00% covered (danger)
0.00%
0 / 55
0.00% covered (danger)
0.00%
0 / 5
182
0.00% covered (danger)
0.00%
0 / 1
 readResponse
0.00% covered (danger)
0.00%
0 / 25
0.00% covered (danger)
0.00%
0 / 1
6
 readDepartment
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
20
 setWithProcessClient
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
12
 writeLogEntry
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
2
 testEventLogEntries
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
12
1<?php
2
3/**
4 * @copyright BerlinOnline Stadtportal GmbH & Co. KG
5 **/
6
7declare(strict_types=1);
8
9namespace BO\Zmsbackend\Process\Api;
10
11use BO\Slim\Render;
12use BO\Zmsbackend\Helper\Version;
13use BO\Zmsbackend\Config\Service\Config as ConfigRepository;
14use BO\Zmsbackend\EventLog\Service\EventLog as EventLogRepository;
15use BO\Zmsbackend\Mail\Service\Mail as Query;
16use BO\Zmsbackend\Process\Service\Process as ProcessRepository;
17use BO\Zmsbackend\Department\Service\Department as DepartmentRepository;
18use BO\Zmsentities\Client;
19use BO\Zmsentities\Mail;
20use BO\Zmsentities\Collection\ProcessList;
21use BO\Zmsentities\EventLog;
22use BO\Zmsentities\Process;
23use BO\Zmsentities\Department;
24use BO\Zmsentities\Helper\DateTime;
25use Psr\Http\Message\RequestInterface;
26use Psr\Http\Message\ResponseInterface;
27
28/**
29 * @SuppressWarnings(Coupling)
30 */
31class ProcessListSummaryMail extends \BO\Zmsbackend\Api\BaseController
32{
33    public const int PROCESSLIST_SUMMARY_REQUEST_REPETITION_SEC = 600;
34
35    /**
36     * @SuppressWarnings(Param)
37     *
38     * @param RequestInterface $request
39     * @param ResponseInterface $response
40     * @param array $args
41     *
42     * @return ResponseInterface
43     */
44    #[\Override]
45    public function readResponse(
46        RequestInterface $request,
47        ResponseInterface $response,
48        array $args
49    ) {
50        $validator = $request->getAttribute('validator');
51        $mailAddress = $validator->getParameter('mail')->isMail()->hasDNS()->assertValid()->getValue();
52        $limit = $validator->getParameter('limit')->isNumber()->setDefault(50)->getValue();
53        $this->testEventLogEntries($mailAddress);
54
55        $collection = (new ProcessRepository())->readListByMailAndStatusList(
56            $mailAddress,
57            [
58                \BO\Zmsentities\Process::STATUS_CONFIRMED
59            ],
60            2,
61            $limit
62        );
63
64        $config = (new ConfigRepository())->readEntity();
65        $department = $this->readDepartment($config, $collection->getFirst());
66
67        $mail = (new Mail())->toResolvedEntity($collection, $config, 'overview')->withDepartment($department);
68        $mail = $this->setWithProcessClient($mail, $mailAddress);
69        $mail->testValid();
70
71        $persisted = null;
72        if ($department) {
73            $persisted = (new Query())->writeInQueue($mail, \App::$now, false);
74        }
75
76        $message = \BO\Zmsbackend\Api\Response\Message::create($request);
77        $message->data = $persisted;
78
79        $this->writeLogEntry($mailAddress, $collection);
80        $response = Render::withLastModified($response, time(), '0');
81        return Render::withJson($response, $message->setUpdatedMetaData(), $message->getStatuscode());
82    }
83
84    protected function readDepartment(\BO\Zmsentities\Config $config, Process|null $process = null): Department
85    {
86        $department = (null != $process && null != $process->getScopeId()) ?
87            (new DepartmentRepository())->readByScopeId($process->getScopeId(), 0) :
88            (new DepartmentRepository())->readEntity($config->getPreference('mailings', 'noReplyDepartmentId'));
89        if (null === $department) {
90            throw new \BO\Zmsbackend\Mail\Exception\MailSenderFromMissing();
91        }
92        return $department;
93    }
94
95    protected function setWithProcessClient(Mail $entity, string $mailAddress): Mail
96    {
97        $process = new Process();
98        $client = $entity->getClient();
99        if ($client === null || !$client->hasEmail()) {
100            $process->getFirstClient()->email = $mailAddress;
101        }
102        $entity->process = $process;
103
104        return $entity;
105    }
106
107    protected function writeLogEntry(string $mailAddress, ProcessList $collection): void
108    {
109        $logRepository = new EventLogRepository();
110        $newLogEntry = new EventLog();
111        $newLogEntry->addData([
112            'name' => EventLog::CLIENT_PROCESSLIST_REQUEST,
113            'origin' => 'zmsbackend ' . Version::getString(),
114            'referenceType' => 'mail.recipient.hash',
115            'reference' => $logRepository->hashStringValue($mailAddress),
116            'context' => ['found' => $collection->getIds()],
117        ])->setSecondsToLive(EventLog::LIVETIME_DAY);
118
119        $logRepository->writeEntity($newLogEntry);
120    }
121
122    /**
123     * @return void
124     */
125    protected function testEventLogEntries($mailAddress)
126    {
127        $logRepository = new EventLogRepository();
128        $eventLogEntries = $logRepository->readByNameAndRef(
129            EventLog::CLIENT_PROCESSLIST_REQUEST,
130            $logRepository->hashStringValue($mailAddress)
131        );
132        $youngestTime = new DateTime('-' . self::PROCESSLIST_SUMMARY_REQUEST_REPETITION_SEC . ' seconds');
133        if ($eventLogEntries->count() > 0 && $eventLogEntries->getLast()->creationDateTime > $youngestTime) {
134            throw new \BO\Zmsbackend\Process\Exception\ProcessListSummaryTooOften();
135        }
136    }
137}