where('config_key', $key) ->orderByDesc('id') ->first(); } catch (\Throwable $e) { if (app()->runningInConsole()) { return null; } throw $e; } return $row ? (string) $row->config_value : null; } /** * Set configuration value by key. * If duplicates exist, update ALL of them to avoid inconsistent reads. */ public static function setConfigValueByKey(string $key, string $value): bool { $count = static::query()->where('config_key', $key)->count(); if ($count > 0) { $affected = static::query() ->where('config_key', $key) ->update(['config_value' => $value]); return $affected >= 0; } $row = static::query()->create([ 'config_key' => $key, 'config_value' => $value, ]); return !empty($row->id); } /** * Retrieve all configuration rows. */ public static function getAllConfigs() { return static::query()->get(); } /** * Update configuration by id. */ public static function updateConfig(int $id, array $data): bool { return static::query()->whereKey($id)->update($data) >= 0; } /** * Add new configuration row. */ public static function addConfig(array $data): int { $row = static::query()->create($data); return (int) $row->id; } /** * Backward-compatible helper (keeps your "semester" special-case). * * NOTE: In Laravel it’s better to call SemesterRangeService directly from services/controllers, * but this keeps behavior consistent with the legacy model. */ public static function getConfig(string $key): ?string { $key = (string) $key; if ($key === 'semester') { try { // If you have this service in Laravel, inject/resolve it from container. // This call assumes the service constructor can accept Configuration model (like legacy did). $semester = app(\App\Services\SemesterRangeService::class)->getSemesterForDate(); if (is_string($semester) && $semester !== '') { return $semester; } } catch (\Throwable $e) { // ignore and fall back } } return static::getConfigValueByKey($key); } }