| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192 |
- <?php
- declare(strict_types=1);
- namespace App\Support;
- use DateTimeImmutable;
- use DateTimeZone;
- /** Framework independent; keep the member API copy identical except for its namespace. */
- final class MaintenancePolicy
- {
- public const CATEGORIES = ['third:1' => '真人', 'third:2' => '电子', 'third:3' => '彩票',
- 'third:4' => '体育', 'third:5' => '电竞', 'third:6' => '捕鱼', 'third:7' => '棋牌',
- 'self:sport' => 'F1体育', 'self:lottery' => 'F1彩票'];
- public const LANGUAGES = ['zh' => '中文', 'en' => '英文', 'vi' => '越南语'];
- public const STATES = ['disabled' => '已关闭', 'scheduled' => '待开始', 'active' => '维护中', 'expired' => '已结束'];
- public const SITE_CODE = 11001;
- public const GAME_CODE = 11002;
- public static function scopes(): array { return ['site' => '整站'] + self::CATEGORIES; }
- public static function platform($value): ?string
- {
- return is_string($value) && in_array(strtoupper(trim($value)), ['PC', 'H5', 'APP'], true)
- ? strtoupper(trim($value)) : null;
- }
- public static function language($value): ?string
- {
- if (!is_string($value)) return null;
- $value = strtolower(str_replace('_', '-', trim($value)));
- $value = explode('-', $value)[0];
- return isset(self::LANGUAGES[$value]) ? $value : null;
- }
- public static function state(array $row, int $now): string
- {
- if (!(int) $row['enabled']) return 'disabled';
- if (self::timestamp($row['starts_at']) > $now) return 'scheduled';
- if ($row['ends_at'] !== null && self::timestamp($row['ends_at']) <= $now) return 'expired';
- return 'active';
- }
- public static function platforms(array $row): array
- {
- return is_array($row['platforms']) ? $row['platforms'] : json_decode($row['platforms'], true, 512, JSON_THROW_ON_ERROR);
- }
- public static function matches(array $row, ?string $platform, int $now): bool
- {
- // Unknown clients conservatively match every platform; omission cannot bypass a rule.
- return self::state($row, $now) === 'active' && ($platform === null || in_array($platform, self::platforms($row), true));
- }
- public static function select(array $rows, ?string $platform, ?string $category, int $now): ?array
- {
- $game = null;
- foreach ($rows as $row) {
- if (!self::matches($row, $platform, $now)) continue;
- if ($row['scope_code'] === 'site') return $row;
- if ($row['scope_code'] === $category) $game = $row;
- }
- return $game;
- }
- public static function publicRule(array $row, string $language): array
- {
- $zone = new DateTimeZone($row['timezone']);
- $start = new DateTimeImmutable($row['starts_at'], new DateTimeZone('UTC'));
- $end = $row['ends_at'] === null ? null : new DateTimeImmutable($row['ends_at'], new DateTimeZone('UTC'));
- $fallback = ['zh' => '系统维护中,请稍后再试', 'en' => 'Maintenance in progress. Please try again later.',
- 'vi' => 'Hệ thống đang bảo trì. Vui lòng thử lại sau.'];
- $content = (string) ($row['content'] ?? '');
- return ['scope' => $row['scope_code'] === 'site' ? 'site' : 'game',
- 'category' => $row['scope_code'] === 'site' ? null : $row['scope_code'],
- 'platforms' => self::platforms($row), 'timezone' => $row['timezone'],
- 'starts_at' => $start->setTimezone($zone)->format('Y-m-d H:i:s'),
- 'ends_at' => $end ? $end->setTimezone($zone)->format('Y-m-d H:i:s') : null,
- 'starts_at_utc' => $start->format('Y-m-d\TH:i:s\Z'), 'ends_at_utc' => $end ? $end->format('Y-m-d\TH:i:s\Z') : null,
- 'language' => $language, 'content' => trim($content) === '' ? $fallback[$language] : $content];
- }
- public static function failure(array $row, ?string $platform, string $language, int $now): array
- {
- $data = self::publicRule($row, $language) + ['platform' => $platform, 'platform_unknown' => $platform === null,
- 'server_time' => gmdate('Y-m-d\TH:i:s\Z', $now)];
- return ['code' => $row['scope_code'] === 'site' ? self::SITE_CODE : self::GAME_CODE, 'msg' => $data['content'], 'data' => $data];
- }
- private static function timestamp(string $value): int { return (new DateTimeImmutable($value, new DateTimeZone('UTC')))->getTimestamp(); }
- }
|