Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
96.00% covered (success)
96.00%
48 / 50
80.00% covered (warning)
80.00%
8 / 10
CRAP
0.00% covered (danger)
0.00%
0 / 1
ReservedDataDeleteByCron
96.00% covered (success)
96.00%
48 / 50
80.00% covered (warning)
80.00%
8 / 10
17
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
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
2
 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        return $this->verbose && error_log($message);
81    }
82
83    protected function deleteExpiredReservations(ScopeList $scopeList): void
84    {
85        foreach ($scopeList as $scope) {
86            $countedProcesses = $this->deleteProcessesByScope($scope);
87            $this->countByScopeId[$scope->id] += $countedProcesses;
88        }
89    }
90
91    protected function getExpirationTimeByScopePreference(int $reservationDuration): \DateTimeInterface
92    {
93        $expirationTime = clone $this->nowTime;
94        $expiredTimestamp = ($this->nowTime->getTimestamp() - ($reservationDuration * 60));
95
96        return $expirationTime->setTimestamp($expiredTimestamp);
97    }
98
99    protected function deleteProcessesByScope(Scope $scope): int
100    {
101        $processCount = 0;
102        $processList  = $this->getProcessListByScope($scope);
103
104        foreach ($processList as $process) {
105            if ($process->status === 'reserved') {
106                $age = ($this->nowTime->getTimestamp() - $process->createTimestamp);
107                $this->log("INFO: found process($process->id) with a reservation age of $age seconds");
108                $this->writeDeleteProcess($process);
109            } else {
110                $this->log("INFO: Keep process $process->id with status $process->status");
111            }
112
113            $processCount++;
114        }
115
116        return $processCount;
117    }
118
119    protected function getProcessListByScope(Scope $scope): iterable
120    {
121        $reservationDuration = $scope->toProperty()->preferences->appointment->reservationDuration->get();
122        $expirationTime = $this->getExpirationTimeByScopePreference((int) $reservationDuration);
123        $processList = $this->processRepository
124            ->readExpiredReservationsList($expirationTime, $scope->id, $this->limit)
125            ->sortByCustomKey('createTimestamp');
126
127        if ($processList->count() === 0) {
128            return [];
129        }
130
131        $this->log(
132            "\nNow: " . $this->nowTime->format('H:i:s') .
133            "\nTime of expiration: " . $expirationTime->format('H:i:s') . " | scope " . $scope->id .
134            " | $reservationDuration minutes reservation time (" . $processList->count() . " found)" .
135            "\n-------------------------------------------------------------------"
136        );
137
138        return $processList;
139    }
140
141    protected function writeDeleteProcess(Process $process)
142    {
143        if ($this->isDryRun) {
144            return;
145        }
146
147        if ($this->processRepository->writeDeletedEntity($process->id)) {
148            $this->log("INFO: ($process->id) removed successfully\n");
149        } else {
150            $this->log("WARN: Could not remove process '$process->id'!\n");
151        }
152    }
153}