Test Failed
Push — master ( 1e8aad...0e73f2 )
by Carlos
09:42
created

Cron::removeOldLogs()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 20
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 12
c 0
b 0
f 0
nc 3
nop 0
dl 0
loc 20
rs 9.8666
1
<?php
2
/**
3
 * This file is part of FacturaScripts
4
 * Copyright (C) 2017-2024 Carlos Garcia Gomez <[email protected]>
5
 *
6
 * This program is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU Lesser General Public License as
8
 * published by the Free Software Foundation, either version 3 of the
9
 * License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
 * GNU Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public License
17
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18
 */
19
20
namespace FacturaScripts\Core\Controller;
21
22
use Exception;
23
use FacturaScripts\Core\Contract\ControllerInterface;
24
use FacturaScripts\Core\Kernel;
25
use FacturaScripts\Core\Model\LogMessage;
26
use FacturaScripts\Core\Plugins;
27
use FacturaScripts\Core\Tools;
28
use FacturaScripts\Core\WorkQueue;
29
use FacturaScripts\Dinamic\Model\WorkEvent;
30
31
class Cron implements ControllerInterface
32
{
33
    public function __construct(string $className, string $url = '')
34
    {
35
    }
36
37
    public function getPageData(): array
38
    {
39
        return [];
40
    }
41
42
    public function run(): void
43
    {
44
        header('Content-Type: text/plain');
45
46
        echo <<<END
47
48
  ______         _                    _____           _       _       
49
 |  ____|       | |                  / ____|         (_)     | |      
50
 | |__ __ _  ___| |_ _   _ _ __ __ _| (___   ___ _ __ _ _ __ | |_ ___ 
51
 |  __/ _` |/ __| __| | | | '__/ _` |\___ \ / __| '__| | '_ \| __/ __|
52
 | | | (_| | (__| |_| |_| | | | (_| |____) | (__| |  | | |_) | |_\__ \
53
 |_|  \__,_|\___|\__|\__,_|_|  \__,_|_____/ \___|_|  |_| .__/ \__|___/
54
                                                       | |            
55
                                                       |_|
56
END;
57
58
        echo PHP_EOL . PHP_EOL . Tools::lang()->trans('starting-cron');
59
        Tools::log('cron')->notice('starting-cron');
60
61
        ob_flush();
62
63
        // ejecutamos el cron de cada plugin
64
        $this->runPlugins();
65
66
        // eliminamos los logs antiguos
67
        $this->removeOldLogs();
68
        $this->removeOldWorkEvents();
69
70
        // si se está ejecutando en modo cli, ejecutamos la cola de trabajos, máximo 100 trabajos
71
        $max = 100;
72
        while (PHP_SAPI === 'cli') {
73
            if (false === WorkQueue::run()) {
74
                break;
75
            }
76
77
            if (--$max <= 0) {
78
                break;
79
            }
80
        }
81
82
        // mostramos los mensajes del log
83
        $levels = ['critical', 'error', 'info', 'notice', 'warning'];
84
        foreach (Tools::log()::read('', $levels) as $message) {
85
            // si el canal no es master o database, no lo mostramos
86
            if (!in_array($message['channel'], ['master', 'database'])) {
87
                continue;
88
            }
89
90
            echo PHP_EOL . $message['message'];
91
            ob_flush();
92
        }
93
94
        $context = [
95
            '%timeNeeded%' => Kernel::getExecutionTime(3),
96
            '%memoryUsed%' => $this->getMemorySize(memory_get_peak_usage())
97
        ];
98
        echo PHP_EOL . PHP_EOL . Tools::lang()->trans('finished-cron', $context) . PHP_EOL . PHP_EOL;
99
        Tools::log()->notice('finished-cron', $context);
100
    }
101
102
    private function getMemorySize(int $size): string
103
    {
104
        $unit = ['b', 'kb', 'mb', 'gb', 'tb', 'pb'];
105
        return round($size / pow(1024, ($i = floor(log($size, 1024)))), 2) . $unit[$i];
106
    }
107
108
    protected function removeOldLogs(): void
109
    {
110
        $maxDays = Tools::settings('default', 'days_log_retention', 90);
111
        if ($maxDays <= 0) {
112
            return;
113
        }
114
115
        $minDate = Tools::dateTime('-' . $maxDays . ' days');
116
        echo PHP_EOL . PHP_EOL . Tools::lang()->trans('removing-logs-until', ['%date%' => $minDate]) . ' ... ';
117
118
        $query = LogMessage::table()
119
            ->whereNotEq('channel', 'audit')
120
            ->whereLt('time', $minDate);
121
122
        if (false === $query->delete()) {
123
            Tools::log('cron')->warning('old-logs-delete-error');
124
            return;
125
        }
126
127
        Tools::log('cron')->notice('old-logs-delete-ok');
128
    }
129
130
    protected function removeOldWorkEvents(): void
131
    {
132
        $maxDays = Tools::settings('default', 'days_log_retention', 90);
133
        if ($maxDays <= 0) {
134
            return;
135
        }
136
137
        $minDate = Tools::dateTime('-' . $maxDays . ' days');
138
139
        $query = WorkEvent::table()
140
            ->whereEq('done', true)
141
            ->whereLt('creation_date', $minDate);
142
143
        if (false === $query->delete()) {
144
            Tools::log('cron')->warning('old-work-events-delete-error');
145
            return;
146
        }
147
148
        Tools::log('cron')->notice('old-work-events-delete-ok');
149
    }
150
151
    protected function runPlugins(): void
152
    {
153
        foreach (Plugins::enabled() as $pluginName) {
154
            $cronClass = '\\FacturaScripts\\Plugins\\' . $pluginName . '\\Cron';
155
            if (false === class_exists($cronClass)) {
156
                continue;
157
            }
158
159
            echo PHP_EOL . Tools::lang()->trans('running-plugin-cron', ['%pluginName%' => $pluginName]) . ' ... ';
160
            Tools::log('cron')->notice('running-plugin-cron', ['%pluginName%' => $pluginName]);
161
162
            try {
163
                $cron = new $cronClass($pluginName);
164
                $cron->run();
165
            } catch (Exception $ex) {
166
                echo $ex->getMessage() . PHP_EOL;
167
                Tools::log()->error($ex->getMessage());
168
            }
169
170
            ob_flush();
171
172
            // si no se está ejecutando en modo cli y lleva más de 20 segundos, se detiene
173
            if (PHP_SAPI != 'cli' && Kernel::getExecutionTime() > 20) {
174
                break;
175
            }
176
        }
177
    }
178
}
179