Backup is built first. Those are * explicit requests and somebody is waiting on the notification. */ $queued = backupRunQueued($mysqli); if ($queued > 0) { echo "Built $queued queued backup(s)\n"; } /* * Then the scheduled one. The dispatcher only calls this script when the schedule says so, * so reaching here means a scheduled backup is due. * * Skipped if a backup of the same type already completed today - the day-match trap from * CONTRIBUTING's cron rules. A second dispatch in the same day (a manual Run Now, a catch-up * after downtime) must not produce a second scheduled archive. */ $type = in_array($config_backup_cron_type, backupUnattendedTypes(), true) ? $config_backup_cron_type : BACKUP_TYPE_FULL; $type_esc = escapeSql($type); $already = mysqli_num_rows(mysqli_query($mysqli, "SELECT backup_id FROM backups WHERE backup_source = 'Cron' AND backup_type = '$type_esc' AND backup_status = 'Complete' AND backup_completed_at >= CURDATE()")); if ($already > 0) { echo "Scheduled backup already ran today\n"; } else { $error = null; $backup_id = backupCreate($mysqli, $type, 'Cron', 'Cron', $error); if ($backup_id > 0) { echo "Scheduled " . backupTypeLabel($type) . " complete\n"; appNotify("Backup", "Scheduled " . backupTypeLabel($type) . " is ready to download", "/admin/backup.php"); logAudit("Backup", "Create", "Scheduled " . backupTypeLabel($type) . " completed"); } else { echo "Scheduled backup FAILED: $error\n"; appNotify("Backup", "Scheduled backup failed: $error", "/admin/backup.php"); logAudit("Backup", "Create", "Scheduled backup failed: $error"); logApp("Backup", "error", "Scheduled backup failed: $error"); } }