Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
98.15% covered (success)
98.15%
53 / 54
80.00% covered (warning)
80.00%
4 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
ProcessListSummaryMail
98.15% covered (success)
98.15%
53 / 54
80.00% covered (warning)
80.00%
4 / 5
12
0.00% covered (danger)
0.00%
0 / 1
 readResponse
100.00% covered (success)
100.00%
25 / 25
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            ],
56            2,
57            $limit
58        );
59
60        $config = (new ConfigRepository())->readEntity();
61        $department = $this->readDepartment($config, $collection->getFirst());
62
63        $mail = (new Mail())->toResolvedEntity($collection, $config, 'overview')->withDepartment($department);
64        $mail = $this->setWithProcessClient($mail, $mailAddress);
65        $mail->testValid();
66
67        $persisted = null;
68        if ($department) {
69            $persisted = (new Query())->writeInQueue($mail, \App::$now, false);
70        }
71
72        $message = Response\Message::create($request);
73        $message->data = $persisted;
74
75        $this->writeLogEntry($mailAddress, $collection);
76        $response = Render::withLastModified($response, time(), '0');
77        return Render::withJson($response, $message->setUpdatedMetaData(), $message->getStatuscode());
78    }
79
80    protected function readDepartment($config, $process = null): Department
81    {
82        $department = (null != $process && null != $process->getScopeId()) ?
83            (new DepartmentRepository())->readByScopeId($process->getScopeId(), 0) :
84            (new DepartmentRepository())->readEntity($config->getPreference('mailings', 'noReplyDepartmentId'));
85        if (null === $department) {
86            throw new Exception\Mail\MailSenderFromMissing();
87        }
88        return $department;
89    }
90
91    protected function setWithProcessClient(Mail $entity, $mailAddress): Mail
92    {
93        $process = new Process();
94        $client = $entity->getClient();
95        $client = ($client->hasEmail()) ? $client : $process->getFirstClient()->email = $mailAddress;
96        $entity->process = $process ;
97        return $entity;
98    }
99
100    protected function writeLogEntry($mailAddress, ProcessList $collection)
101    {
102        $logRepository = new EventLogRepository();
103        $newLogEntry = new EventLog();
104        $newLogEntry->addData([
105            'name' => EventLog::CLIENT_PROCESSLIST_REQUEST,
106            'origin' => 'zmsapi ' . Version::getString(),
107            'referenceType' => 'mail.recipient.hash',
108            'reference' => $logRepository->hashStringValue($mailAddress),
109            'context' => ['found' => $collection->getIds()],
110        ])->setSecondsToLive(EventLog::LIVETIME_DAY);
111
112        $logRepository->writeEntity($newLogEntry);
113    }
114
115    protected function testEventLogEntries($mailAddress)
116    {
117        $logRepository = new EventLogRepository();
118        $eventLogEntries = $logRepository->readByNameAndRef(
119            EventLog::CLIENT_PROCESSLIST_REQUEST,
120            $logRepository->hashStringValue($mailAddress)
121        );
122        $youngestTime = new DateTime('-' . self::PROCESSLIST_SUMMARY_REQUEST_REPETITION_SEC . ' seconds');
123        if ($eventLogEntries->count() > 0 && $eventLogEntries->getLast()->creationDateTime > $youngestTime) {
124            throw new Exception\Process\ProcessListSummaryTooOften();
125        }
126    }
127}