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