Merge branch 'tasks' into v2.4.18
This commit is contained in:
commit
990b13947d
|
@ -24,6 +24,7 @@
|
||||||
"php": ">=5.6",
|
"php": ">=5.6",
|
||||||
"ext-curl": "*",
|
"ext-curl": "*",
|
||||||
"ext-dom": "*",
|
"ext-dom": "*",
|
||||||
|
"ext-fileinfo": "*",
|
||||||
"ext-intl": "*",
|
"ext-intl": "*",
|
||||||
"ext-json": "*",
|
"ext-json": "*",
|
||||||
"ext-libxml": "*",
|
"ext-libxml": "*",
|
||||||
|
@ -33,10 +34,10 @@
|
||||||
"ext-simplexml": "*",
|
"ext-simplexml": "*",
|
||||||
"ext-xsl": "*",
|
"ext-xsl": "*",
|
||||||
"ext-zip": "*",
|
"ext-zip": "*",
|
||||||
"ext-fileinfo": "*",
|
|
||||||
"aluguest/ical-easy-reader": "^1.5",
|
"aluguest/ical-easy-reader": "^1.5",
|
||||||
"danielstjules/stringy": "^3.1",
|
"danielstjules/stringy": "^3.1",
|
||||||
"davidepastore/codice-fiscale": "^0.4.0",
|
"davidepastore/codice-fiscale": "^0.4.0",
|
||||||
|
"dragonmantank/cron-expression": "^3.0",
|
||||||
"ezyang/htmlpurifier": "^4.8",
|
"ezyang/htmlpurifier": "^4.8",
|
||||||
"filp/whoops": "^2.1",
|
"filp/whoops": "^2.1",
|
||||||
"guzzlehttp/guzzle": "^6.3",
|
"guzzlehttp/guzzle": "^6.3",
|
||||||
|
@ -82,9 +83,6 @@
|
||||||
"sort-packages": true,
|
"sort-packages": true,
|
||||||
"optimize-autoloader": true,
|
"optimize-autoloader": true,
|
||||||
"apcu-autoloader": true,
|
"apcu-autoloader": true,
|
||||||
"prefer-stable": true,
|
"prefer-stable": true
|
||||||
"platform": {
|
|
||||||
"php": "5.6.4"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,135 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Script dedicato alla gestione delle operazioni di cron ricorrenti del gestionale.
|
||||||
|
* Una volta attivato, questo script rimane attivo in background per gestire l'esecuzione delle diverse operazioni come pianificate nella tabella zz_tasks.
|
||||||
|
*
|
||||||
|
* Il file viene richiamato in automatico al login di un utente.
|
||||||
|
* Per garantire che lo script resti attivo in ogni situazione, si consiglia di introdurre una chiamata nel relativo crontab di sistema secondo il seguente schema:
|
||||||
|
*/
|
||||||
|
// Schema crontab: "*/5 * * * * php <percorso_root>/cron.php"
|
||||||
|
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use Cron\CronExpression;
|
||||||
|
use Models\Cache;
|
||||||
|
use Monolog\Handler\RotatingFileHandler;
|
||||||
|
use Monolog\Logger;
|
||||||
|
use Tasks\Task;
|
||||||
|
|
||||||
|
// Rimozione delle limitazioni sull'esecuzione
|
||||||
|
set_time_limit(0);
|
||||||
|
ignore_user_abort(true);
|
||||||
|
|
||||||
|
// Chiusura della richiesta alla pagina
|
||||||
|
flush();
|
||||||
|
|
||||||
|
$skip_permissions = true;
|
||||||
|
include_once __DIR__.'/core.php';
|
||||||
|
|
||||||
|
// Controllo su possibili aggiornamenti per bloccare il sistema
|
||||||
|
$database_online = $database->isInstalled() && !Update::isUpdateAvailable();
|
||||||
|
if (!$database_online) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disabilita della sessione
|
||||||
|
session_write_close();
|
||||||
|
|
||||||
|
// Aggiunta di un logger specifico
|
||||||
|
$pattern = '[%datetime%] %level_name%: %message% %context%'.PHP_EOL;
|
||||||
|
$formatter = new Monolog\Formatter\LineFormatter($pattern);
|
||||||
|
|
||||||
|
$logger = new Logger('Tasks');
|
||||||
|
$handler = new RotatingFileHandler(DOCROOT.'/logs/cron.log', 7);
|
||||||
|
$handler->setFormatter($formatter);
|
||||||
|
$logger->pushHandler($handler);
|
||||||
|
|
||||||
|
// Lettura della cache
|
||||||
|
$ultima_esecuzione = Cache::get('Ultima esecuzione del cron');
|
||||||
|
$data = $ultima_esecuzione->content;
|
||||||
|
|
||||||
|
$riavvia = Cache::get('Riavvia cron');
|
||||||
|
$disattiva = Cache::get('Disabilita cron');
|
||||||
|
if (!empty($disattiva->content)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Impostazioni sugli slot di esecuzione
|
||||||
|
$slot_duration = 5;
|
||||||
|
|
||||||
|
// Controllo sull'ultima esecuzione
|
||||||
|
$data = $data ? new Carbon($data) : null;
|
||||||
|
$minimo_esecuzione = (new Carbon())->addMinutes($slot_duration * 5);
|
||||||
|
if (!empty($data) && $minimo_esecuzione->greaterThanOrEqualTo($data)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Registrazione dell'esecuzione
|
||||||
|
$adesso = new Carbon();
|
||||||
|
$ultima_esecuzione->set($adesso->__toString());
|
||||||
|
|
||||||
|
// Prima esecuzione immediata
|
||||||
|
$slot_minimo = $adesso->copy();
|
||||||
|
|
||||||
|
// Esecuzione ricorrente
|
||||||
|
$number = 1;
|
||||||
|
while (true) {
|
||||||
|
$riavvia->refresh();
|
||||||
|
$disattiva->refresh();
|
||||||
|
|
||||||
|
// Controllo su possibili aggiornamenti per bloccare il sistema
|
||||||
|
$database_online = $database->isInstalled() && !Update::isUpdateAvailable();
|
||||||
|
if (!$database_online || !empty($disattiva->content) || !empty($riavvia->content)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Risveglio programmato tramite slot
|
||||||
|
$timestamp = $slot_minimo->getTimestamp();
|
||||||
|
time_sleep_until($timestamp);
|
||||||
|
|
||||||
|
// Registrazione dell'iterazione nei log
|
||||||
|
$logger->info('Cron #'.$number.' iniziato', [
|
||||||
|
'slot' => $slot_minimo->toDateTimeString(),
|
||||||
|
'slot-unix' => $timestamp,
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Calcolo del primo slot disponibile per l'esecuzione successiva
|
||||||
|
$inizio_iterazione = new Carbon();
|
||||||
|
$slot_minimo = $inizio_iterazione->copy()->startOfHour();
|
||||||
|
while ($inizio_iterazione->greaterThanOrEqualTo($slot_minimo)) {
|
||||||
|
$slot_minimo->addMinutes($slot_duration);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Aggiornamento dei cron disponibili
|
||||||
|
$tasks = Task::all();
|
||||||
|
foreach ($tasks as $task) {
|
||||||
|
$adesso = new Carbon();
|
||||||
|
|
||||||
|
// Individuazione delle informazioni previste dalla relativa espressione
|
||||||
|
$cron = CronExpression::factory($task->expression);
|
||||||
|
$data_successiva = Carbon::instance($cron->getNextRunDate($adesso));
|
||||||
|
|
||||||
|
// Esecuzione diretta solo nel caso in cui sia prevista
|
||||||
|
if ($cron->isDue($inizio_iterazione) || $cron->isDue($adesso)) {
|
||||||
|
// Registrazione dell'esecuzione nei log
|
||||||
|
$logger->info($task->name.': '.$task->expression);
|
||||||
|
|
||||||
|
$task->execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calcolo dello successivo slot
|
||||||
|
if ($data_successiva->lessThan($slot_minimo)) {
|
||||||
|
$slot_minimo = $data_successiva;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Registrazione dello slot successivo nei log
|
||||||
|
$logger->info('Cron #'.$number.' concluso', [
|
||||||
|
'next-slot' => $slot_minimo->toDateTimeString(),
|
||||||
|
'next-slot-unix' => $timestamp,
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Registrazione dell'esecuzione
|
||||||
|
$adesso = new Carbon();
|
||||||
|
$ultima_esecuzione->set($adesso->__toString());
|
||||||
|
++$number;
|
||||||
|
}
|
|
@ -56,12 +56,15 @@ if (Auth::check()) {
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
// Toast
|
// Toast
|
||||||
alertPush();
|
alertPush();
|
||||||
|
|
||||||
// Orologio
|
// Orologio
|
||||||
clock();
|
clock();
|
||||||
|
|
||||||
// Hooks
|
// Hooks
|
||||||
startHooks();
|
startHooks();
|
||||||
|
|
||||||
|
// Abilitazione del cron autonoma
|
||||||
|
$.get(globals.rootdir + "/cron.php");
|
||||||
});
|
});
|
||||||
</script>';
|
</script>';
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,41 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Modules\Backups;
|
|
||||||
|
|
||||||
use Backup;
|
|
||||||
use Hooks\Manager;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Hook dedicato alla gestione del backup giornaliero automatico, se abilitato da Impostazioni.
|
|
||||||
*/
|
|
||||||
class BackupHook extends Manager
|
|
||||||
{
|
|
||||||
public function isSingleton()
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function needsExecution()
|
|
||||||
{
|
|
||||||
return setting('Backup automatico') && !Backup::isDailyComplete();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function execute()
|
|
||||||
{
|
|
||||||
$result = Backup::daily();
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function response()
|
|
||||||
{
|
|
||||||
$show = boolval(setting('Backup automatico')) && !Backup::isDailyComplete();
|
|
||||||
$message = $show ? tr('Backup in corso...') : tr('Backup automatico completato!');
|
|
||||||
|
|
||||||
return [
|
|
||||||
'icon' => 'fa fa-file-o text-success',
|
|
||||||
'message' => $message,
|
|
||||||
'show' => $show,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Modules\Backups;
|
||||||
|
|
||||||
|
use Backup;
|
||||||
|
use Tasks\Manager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Task dedicato alla gestione del backup giornaliero automatico, se abilitato da Impostazioni.
|
||||||
|
*/
|
||||||
|
class BackupTask extends Manager
|
||||||
|
{
|
||||||
|
public function needsExecution()
|
||||||
|
{
|
||||||
|
return setting('Backup automatico') && !Backup::isDailyComplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function execute()
|
||||||
|
{
|
||||||
|
if (setting('Backup automatico') && !Backup::isDailyComplete()) {
|
||||||
|
Backup::daily();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Tasks;
|
||||||
|
|
||||||
|
abstract class Manager implements TaskInterface
|
||||||
|
{
|
||||||
|
protected $task;
|
||||||
|
|
||||||
|
public function __construct(Task $task)
|
||||||
|
{
|
||||||
|
$this->task = $task;
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract public function execute();
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Tasks;
|
||||||
|
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use Common\Model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Risorsa per la gestione delle task ricorrenti del gestionale.
|
||||||
|
*/
|
||||||
|
class Task extends Model
|
||||||
|
{
|
||||||
|
protected $table = 'zz_tasks';
|
||||||
|
|
||||||
|
protected $dates = [
|
||||||
|
'last_executed_at',
|
||||||
|
];
|
||||||
|
|
||||||
|
public function execute()
|
||||||
|
{
|
||||||
|
// Individuazione del gestore
|
||||||
|
$class = $this->attributes['class'];
|
||||||
|
$manager = new $class($this);
|
||||||
|
|
||||||
|
// Esecuzione
|
||||||
|
$result = $manager->execute();
|
||||||
|
|
||||||
|
// Salvtagggio dell'esecuzione
|
||||||
|
$this->last_executed_at = new Carbon();
|
||||||
|
$this->save();
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function delete()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Tasks;
|
||||||
|
|
||||||
|
interface TaskInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function execute();
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
-- Miglioramento della cache interna
|
||||||
|
CREATE TABLE IF NOT EXISTS `zz_tasks` (
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`name` VARCHAR(255) NOT NULL,
|
||||||
|
`class` TEXT NOT NULL,
|
||||||
|
`expression` VARCHAR(255) NOT NULL,
|
||||||
|
`last_executed_at` timestamp NULL,
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) ENGINE=InnoDB;
|
||||||
|
|
||||||
|
INSERT INTO `zz_cache` (`id`, `name`, `content`, `valid_time`, `expire_at`) VALUES
|
||||||
|
(NULL, 'Ultima esecuzione del cron', '', '1 month', NULL),
|
||||||
|
(NULL, 'Riavvia cron', '', '1 month', NULL),
|
||||||
|
(NULL, 'Disabilita cron', '', '1 month', NULL);
|
||||||
|
|
||||||
|
INSERT INTO `zz_tasks` (`id`, `name`, `class`, `expression`, `last_executed_at`) VALUES
|
||||||
|
(NULL, 'Backup automatico', 'Modules\\Backups\\BackupTask', '0 0 * * *', NULL);
|
||||||
|
|
||||||
|
DELETE FROM `zz_hooks` WHERE `class` = 'Modules\\Backups\\BackupHook';
|
|
@ -120,6 +120,7 @@ return [
|
||||||
'zz_segments',
|
'zz_segments',
|
||||||
'zz_semaphores',
|
'zz_semaphores',
|
||||||
'zz_settings',
|
'zz_settings',
|
||||||
|
'zz_tasks',
|
||||||
'zz_tokens',
|
'zz_tokens',
|
||||||
'zz_users',
|
'zz_users',
|
||||||
'zz_user_sedi',
|
'zz_user_sedi',
|
||||||
|
|
Loading…
Reference in New Issue