Remove outdated edge gateway object classes, add new agent implementation

Transitioned from obsolete gateway object classes (`edge_gateway_shell_action_jobs_o`, `edge_gateway_shell_events_o`, `edge_gateway_shell_sessions_o`, `edge_gateway_update_jobs_o`) to the new agent implementation (`edge-gateway-agent/agent.php`).
This commit is contained in:
Jeppe Bundgaard
2026-04-21 14:13:17 +02:00
parent d30a006457
commit 7d450e285e
90 changed files with 11811 additions and 2760 deletions
@@ -0,0 +1,201 @@
<?php
namespace classes;
use Throwable;
class order_bookings_counts_cache
{
public const PREFIX = 'order_bookings:counts:v1:';
/**
* Optional runtime adapter for tests.
*/
private static ?object $adapter = null;
public static function setAdapterForTests(?object $adapter): void
{
self::$adapter = $adapter;
}
public static function getTtl(): int
{
$raw = getenv('ORDER_BOOKINGS_COUNTS_CACHE_TTL');
if ($raw === false || trim((string)$raw) === '') {
return 30;
}
return max(0, (int)$raw);
}
public static function buildKey(array $context): string
{
$normalized = self::normalizeValue($context);
$encoded = json_encode($normalized, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
if (!is_string($encoded)) {
$encoded = serialize($normalized);
}
return self::PREFIX . md5($encoded);
}
public static function getCounts(string $key): ?array
{
$raw = self::redisGet($key);
if ($raw === null || $raw === '') {
return null;
}
$decoded = json_decode($raw, true);
if (!is_array($decoded)) {
return null;
}
return self::normalizeCounts($decoded);
}
public static function storeCounts(string $key, array $counts, ?int $ttl = null): void
{
$cacheTtl = $ttl ?? self::getTtl();
if ($cacheTtl <= 0) {
return;
}
$normalized = self::normalizeCounts($counts);
if ($normalized === null) {
return;
}
$encoded = json_encode($normalized, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
if (!is_string($encoded)) {
return;
}
self::redisSetEx($key, $encoded, $cacheTtl);
}
public static function clearAll(): void
{
self::clearPattern(self::PREFIX . '*');
}
private static function normalizeCounts(array $counts): ?array
{
if (!array_key_exists('past', $counts) || !array_key_exists('current', $counts) || !array_key_exists('future', $counts)) {
return null;
}
return [
'past' => max(0, (int)$counts['past']),
'current' => max(0, (int)$counts['current']),
'future' => max(0, (int)$counts['future']),
];
}
private static function normalizeValue(mixed $value): mixed
{
if (!is_array($value)) {
return self::normalizeScalar($value);
}
$normalized = array_map([self::class, 'normalizeValue'], $value);
if (array_is_list($normalized)) {
if (self::isScalarList($normalized)) {
sort($normalized);
}
return $normalized;
}
ksort($normalized);
return $normalized;
}
private static function normalizeScalar(mixed $value): mixed
{
if (!is_string($value)) {
return $value;
}
if (preg_match('/^-?\d+$/', $value) === 1) {
return (int)$value;
}
if (is_numeric($value)) {
return (float)$value;
}
return $value;
}
private static function isScalarList(array $value): bool
{
foreach ($value as $item) {
if (is_array($item) || is_object($item)) {
return false;
}
}
return true;
}
private static function clearPattern(string $pattern): void
{
try {
$client = self::redisClient();
if ($client === null) {
return;
}
$client->clear_keys($pattern);
} catch (Throwable) {
// Cache invalidation must never break request flow.
}
}
private static function redisSetEx(string $key, string $value, int $ttl): void
{
try {
$client = self::redisClient();
if ($client === null) {
return;
}
$client->setEx($key, $value, $ttl);
} catch (Throwable) {
// Best-effort cache write.
}
}
private static function redisGet(string $key): ?string
{
try {
$client = self::redisClient();
if ($client === null) {
return null;
}
$value = $client->get($key);
return is_string($value) ? $value : null;
} catch (Throwable) {
return null;
}
}
private static function redisClient(): ?object
{
if (self::$adapter !== null) {
return self::$adapter;
}
try {
if (defined('redis')) {
$instance = constant('redis');
if (is_object($instance)) {
return $instance;
}
}
return (new redis())->connect();
} catch (Throwable) {
return null;
}
}
}