Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
94.23% covered (success)
94.23%
49 / 52
70.00% covered (warning)
70.00%
7 / 10
CRAP
0.00% covered (danger)
0.00%
0 / 1
ReservedDataDeleteByCron
94.23% covered (success)
94.23%
49 / 52
70.00% covered (warning)
70.00%
7 / 10
17.06
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
1
 getCount
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setLimit
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 startProcessing
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 log
66.67% covered (warning)
66.67%
2 / 3
0.00% covered (danger)
0.00%
0 / 1
2.15
 deleteExpiredReservations
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 getExpirationTimeByScopePreference
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 deleteProcessesByScope
90.00% covered (success)
90.00%
9 / 10
0.00% covered (danger)
0.00%
0 / 1
3.01
 getProcessListByScope
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
1 / 1
2
 writeDeleteProcess
80.00% covered (warning)
80.00%
4 / 5
0.00% covered (danger)
0.00%
0 / 1
3.07
1<?php
2
3/**
4 * @copyright BerlinOnline Stadtportal GmbH & Co. KG
5 **/
6
7namespace BO\Zmsdb\Helper;
8
9/**
10 * @codeCoverageIgnore
11 */
12
13use BO\Zmsdb\Process as ProcessRepository;
14use BO\Zmsdb\Scope as ScopeRepository;
15use BO\Zmsentities\Collection\ScopeList;
16use BO\Zmsentities\Process;
17use BO\Zmsentities\Scope;
18
19class ReservedDataDeleteByCron
20{
21    /** @var \DateTimeInterface */
22    protected $nowTime;
23
24    /** @var bool */
25    protected $verbose = false;
26
27    /** @var int */
28    protected $limit = 500;
29
30    /** @var bool */
31    protected $isDryRun = false;
32
33    /** @var int[] */
34    protected $countByScopeId = [];
35
36    /** @var Scope */
37    protected $scopeRepository;
38
39    protected $processRepository;
40
41    public function __construct(\DateTimeInterface $now, bool $verbose = false, bool $isDryRun = false)
42    {
43        $this->nowTime  = $now;
44        $this->verbose  = $verbose;
45        $this->isDryRun = $isDryRun;
46
47        $this->scopeRepository = new ScopeRepository();
48        $this->processRepository = new ProcessRepository();
49    }
50
51    /**
52     * @return int[]
53     */
54    public function getCount(): array
55    {
56        return $this->countByScopeId;
57    }
58
59    public function setLimit(int $limit): ReservedDataDeleteByCron
60    {
61        $this->limit = $limit;
62
63        return $this;
64    }
65
66    public function startProcessing(): void
67    {
68        $this->log("INFO: Deleting expired reservations older than scopes reservation duration");
69
70        $scopeList = $this->scopeRepository->readList();
71        $this->countByScopeId = array_fill_keys($scopeList->getIds(), 0);
72        $this->deleteExpiredReservations($scopeList);
73        $filteredCount = array_filter($this->getCount());
74
75        $this->log(PHP_EOL . "SUMMARY: Processed reservations: " . var_export($filteredCount, true));
76    }
77
78    protected function log($message): bool
79    {
80        if ($this->verbose) {
81            \App::$log->info($message);
82        }
83        return $this->verbose;
84    }
85
86    protected function deleteExpiredReservations(ScopeList $scopeList): void
87    {
88        foreach ($scopeList as $scope) {
89            $countedProcesses = $this->deleteProcessesByScope($scope);
90            $this->countByScopeId[$scope->id] += $countedProcesses;
91        }
92    }
93
94    protected function getExpirationTimeByScopePreference(int $reservationDuration): \DateTimeInterface
95    {
96        $expirationTime = clone $this->nowTime;
97        $expiredTimestamp = ($this->nowTime->getTimestamp() - ($reservationDuration * 60));
98
99        return $expirationTime->setTimestamp($expiredTimestamp);
100    }
101
102    protected function deleteProcessesByScope(Scope $scope): int
103    {
104        $processCount = 0;
105        $processList  = $this->getProcessListByScope($scope);
106
107        foreach ($processList as $process) {
108            if ($process->status === 'reserved') {
109                $age = ($this->nowTime->getTimestamp() - $process->createTimestamp);
110                $this->log("INFO: found process($process->id) with a reservation age of $age seconds");
111                $this->writeDeleteProcess($process);
112            } else {
113                $this->log("INFO: Keep process $process->id with status $process->status");
114            }
115
116            $processCount++;
117        }
118
119        return $processCount;
120    }
121
122    protected function getProcessListByScope(Scope $scope): iterable
123    {
124        $reservationDuration = $scope->toProperty()->preferences->appointment->reservationDuration->get();
125        $expirationTime = $this->getExpirationTimeByScopePreference((int) $reservationDuration);
126        $processList = $this->processRepository
127            ->readExpiredReservationsList($expirationTime, $scope->id, $this->limit)
128            ->sortByCustomKey('createTimestamp');
129
130        if ($processList->count() === 0) {
131            return [];
132        }
133
134        $this->log(
135            "\nNow: " . $this->nowTime->format('H:i:s') .
136            "\nTime of expiration: " . $expirationTime->format('H:i:s') . " | scope " . $scope->id .
137            " | $reservationDuration minutes reservation time (" . $processList->count() . " found)" .
138            "\n-------------------------------------------------------------------"
139        );
140
141        return $processList;
142    }
143
144    protected function writeDeleteProcess(Process $process)
145    {
146        if ($this->isDryRun) {
147            return;
148        }
149
150        if ($this->processRepository->writeDeletedEntity($process->id)) {
151            $this->log("INFO: ($process->id) removed successfully\n");
152        } else {
153            $this->log("WARN: Could not remove process '$process->id'!\n");
154        }
155    }
156}