<?php
namespace SHServ\Controllers;
use \SHServ\Models\Devices;
use \SHServ\Tools\DeviceScanner;
use \SHServ\Middleware\ControlScripts;
use \SHServ\Models\Scripts;
class CronController extends \SHServ\Middleware\Controller {
protected function ensure_localhost_only() {
$remote_addr = $_SERVER['REMOTE_ADDR'] ?? '';
if(!in_array($remote_addr, ['127.0.0.1', '::1'])) {
http_response_code(403);
header('Content-Type: application/json');
echo json_encode([
"status" => false,
"error_alias" => "forbidden",
"msg" => "Forbidden: local access only"
]);
exit;
}
}
protected function createDeviceScanner(): DeviceScanner {
return new DeviceScanner();
}
protected function run_script_cli(String $alias): int {
$output = [];
$returnCode = 0;
$consolePath = __DIR__ . "/../../console.php";
exec("php " . escapeshellarg($consolePath) . " run-regular-script " . escapeshellarg($alias) . " 2>&1", $output, $returnCode);
if($returnCode !== 0) {
\Fury\Kernel\Logging::ins() -> set(
"CronController@run_regular_cron_scripts",
"Regular script {$alias} exited with code {$returnCode}",
implode("\n", $output)
);
}
return $returnCode;
}
public function run_regular_cron_scripts() {
$this -> ensure_localhost_only();
$scripts_model = new Scripts();
$regular_scripts = ControlScripts::get_regular_scripts();
foreach($regular_scripts as $alias => $script) {
if(!$scripts_model -> script_state("regular", $alias)) {
continue;
}
$this -> run_script_cli($alias);
}
}
public function status_update_scanning() {
$this -> ensure_localhost_only();
$threshold = FCONF["device_offline_threshold"] ?? 300;
$now = time();
$devices_model = new Devices();
$active_devices = $devices_model -> get_device_list();
// 1. Помечаем оффлайн устройства с устаревшим last_contact
foreach($active_devices as $device) {
$last_contact_ts = strtotime($device -> last_contact);
if($last_contact_ts === false) {
continue;
}
$seconds_since_contact = $now - $last_contact_ts;
if($seconds_since_contact > $threshold) {
if($device -> connection_status != "lost") {
$device -> connection_status = "lost";
$device -> update();
}
}
}
// 2. Сканируем сеть — восстанавливаем lost и обновляем IP при роуминге
$device_scanner = $this -> createDeviceScanner();
$found_devices = $device_scanner -> scan_range(FCONF["device_ip_range"][0], FCONF["device_ip_range"][1]);
$found_by_hard_id = [];
foreach($found_devices as $found) {
$found_by_hard_id[$found["device_id"]] = $found;
}
foreach($active_devices as $device) {
if(!isset($found_by_hard_id[$device -> device_hard_id])) {
continue;
}
$found = $found_by_hard_id[$device -> device_hard_id];
$is_changed = false;
if($device -> device_ip != $found["ip_address"]) {
$device -> device_ip = $found["ip_address"];
$is_changed = true;
}
if($device -> connection_status != "active") {
$device -> connection_status = "active";
$is_changed = true;
}
if($is_changed) {
$device -> update();
}
// HTTP-ответ от устройства = контакт
$device -> touch_last_contact();
}
}
}