Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
n/a
0 / 0
n/a
0 / 0
CRAP
n/a
0 / 0
AppointmentDeleteByCron
n/a
0 / 0
n/a
0 / 0
32
n/a
0 / 0
 __construct
n/a
0 / 0
n/a
0 / 0
2
 log
n/a
0 / 0
n/a
0 / 0
2
 getCount
n/a
0 / 0
n/a
0 / 0
1
 setLimit
n/a
0 / 0
n/a
0 / 0
1
 setLoopCount
n/a
0 / 0
n/a
0 / 0
1
 startProcessing
n/a
0 / 0
n/a
0 / 0
2
 deleteExpiredProcesses
n/a
0 / 0
n/a
0 / 0
2
 deleteBlockedProcesses
n/a
0 / 0
n/a
0 / 0
1
 deleteByCallback
n/a
0 / 0
n/a
0 / 0
5
 removeProcess
n/a
0 / 0
n/a
0 / 0
6
 updateProcessStatus
n/a
0 / 0
n/a
0 / 0
2
 archiveProcess
n/a
0 / 0
n/a
0 / 0
3
 deleteProcess
n/a
0 / 0
n/a
0 / 0
4
1<?php
2
3namespace BO\Zmsdb\Helper;
4
5/**
6 * @codeCoverageIgnore
7 */
8class AppointmentDeleteByCron
9{
10    protected $verbose = false;
11
12    protected $limit = 10000;
13
14    protected $loopCount = 500;
15
16    protected $time;
17
18    protected $statuslist = [
19        "blocked",
20        "reserved",
21        "deleted",
22        "confirmed",
23        "preconfirmed",
24        "queued",
25        "called",
26        "missed",
27        'parked',
28        "processing",
29    ];
30
31    protected $archivelist = [
32        "confirmed",
33        "queued",
34        "called",
35        "missed",
36        'parked',
37        "processing",
38        "pending"
39    ];
40
41    protected $count = [];
42
43    public function __construct($timeIntervalDays, \DateTimeInterface $now, $verbose = false)
44    {
45        $deleteInSeconds = (24 * 60 * 60) * $timeIntervalDays;
46        $time = new \DateTimeImmutable();
47        $this->time = $time->setTimestamp($now->getTimestamp() - $deleteInSeconds);
48        if ($verbose) {
49            $this->log("INFO: Deleting appointments older than " . $this->time->format('c'));
50            $this->verbose = true;
51        }
52    }
53
54    protected function log($message)
55    {
56        if ($this->verbose) {
57            error_log($message);
58        }
59    }
60
61    public function getCount()
62    {
63        return $this->count;
64    }
65
66    public function setLimit($limit)
67    {
68        $this->limit = $limit;
69    }
70
71    public function setLoopCount($loopCount)
72    {
73        $this->loopCount = $loopCount;
74    }
75
76    public function startProcessing($commit, $pending = false)
77    {
78        if ($pending) {
79            $this->statuslist[] = "pending";
80        }
81        $this->count = array_fill_keys($this->statuslist, 0);
82        $this->deleteBlockedProcesses($commit);
83        $this->deleteExpiredProcesses($commit);
84        $this->log("\nSUMMARY: Deleted processes: " . var_export($this->count, true));
85    }
86
87    protected function deleteExpiredProcesses($commit)
88    {
89        foreach ($this->statuslist as $status) {
90            $this->log("\nDelete expired processes with status $status:");
91            $count = $this->deleteByCallback($commit, function ($limit, $offset) use ($status) {
92                $query = new \BO\Zmsdb\Process();
93                $processList = $query->readExpiredProcessListByStatus($this->time, $status, $limit, $offset);
94                return $processList;
95            });
96            $this->count[$status] += $count;
97        }
98    }
99
100    protected function deleteBlockedProcesses($commit)
101    {
102        $this->log("\nDelete blocked processes in the future:");
103        $count = $this->deleteByCallback($commit, function ($limit, $offset) {
104            $query = new \BO\Zmsdb\Process();
105            $processList = $query->readProcessListByScopeAndStatus(0, 'blocked', 0, $limit, $offset);
106            return $processList;
107        });
108        $this->count["blocked"] += $count;
109    }
110
111    protected function deleteByCallback($commit, \Closure $callback)
112    {
113        $processCount = 0;
114        $startposition = 0;
115        while ($processCount < $this->limit) {
116            $processList = $callback($this->loopCount, $startposition);
117            if (0 == $processList->count()) {
118                break;
119            }
120            foreach ($processList as $process) {
121                if (!$this->removeProcess($process, $commit, $processCount)) {
122                    $startposition++;
123                }
124                $processCount++;
125            }
126        }
127        return $processCount;
128    }
129
130    protected function removeProcess(\BO\Zmsentities\Process $process, $commit, $processCount)
131    {
132        $verbose = $this->verbose;
133        if (in_array($process->status, $this->statuslist)) {
134            if (in_array($process->status, $this->archivelist)) {
135                $this->log("INFO: $processCount. Archive $process");
136                $process = $this->updateProcessStatus($process);
137                if ($commit) {
138                    $this->archiveProcess($process);
139                }
140            }
141            $this->log("INFO: $processCount. Delete $process");
142            if ($commit) {
143                $this->deleteProcess($process);
144                return 1;
145            }
146        } elseif ($verbose) {
147            $this->log("INFO: Keep process $process");
148        }
149        return 0;
150    }
151
152    protected function updateProcessStatus(\BO\Zmsentities\Process $process)
153    {
154        if (in_array($process->status, ["confirmed", "queued", "called"])) {
155            $process->status = 'missed';
156        }
157        return $process;
158    }
159
160    protected function archiveProcess(\BO\Zmsentities\Process $process)
161    {
162        $verbose = $this->verbose;
163        $now = new \DateTimeImmutable();
164        $archiver = new \BO\Zmsdb\ProcessStatusArchived();
165        $archived = null;
166        $archived = $archiver->writeEntityFinished($process, $now);
167        if ($archived && $verbose) {
168            $this->log("INFO: Archived with Status=$process->status and Id=" . $archived->archiveId);
169        }
170    }
171
172    protected function deleteProcess(\BO\Zmsentities\Process $process)
173    {
174        $verbose = $this->verbose;
175        $query = new \BO\Zmsdb\Process();
176        if ($query->writeDeletedEntity($process->id)) {
177            if ($verbose) {
178                $this->log("INFO: Process $process->id successfully removed");
179            }
180        } else {
181            if ($verbose) {
182                $this->log("WARN: Could not remove process '$process->id'!");
183            }
184        }
185    }
186}