5, 'log_retention_days' => 90, 'snapshot_count' => 20]; /** * Hard cap for transfers held in memory as a whole and passed through the MCP response or * request as Base64 (lit-media-download, lit/media-upload): above it, PHP memory and the * JSON payload become the problem, whatever upload_mb says. URL imports stream to disk * and only use upload_mb. */ public const INLINE_MAX_MB = 10; private const BOUNDS = ['upload_mb' => [1, 32], 'log_retention_days' => [1, 3650], 'snapshot_count' => [1, 100]]; public function uploadBytes(): int { return $this->uploadMegabytes() * 1024 * 1024; } public function uploadMegabytes(): int { return $this->all()['upload_mb']; } /** Limit for Base64 transfers: the upload limit, at most INLINE_MAX_MB. */ public function inlineBytes(): int { return $this->inlineMegabytes() * 1024 * 1024; } public function inlineMegabytes(): int { return min($this->uploadMegabytes(), self::INLINE_MAX_MB); } public function logRetentionDays(): int { return $this->all()['log_retention_days']; } /** Reserved for design-system snapshots (Etappe 3); LimitsTab keeps the field hidden until then. */ public function snapshotCount(): int { return $this->all()['snapshot_count']; } /** @return array{upload_mb: int, log_retention_days: int, snapshot_count: int} */ public function all(): array { return self::sanitize(get_option(self::OPTION, [])); } /** * The [min, max] each field is clamped to by sanitize() – for admin UI form attributes, * so they can't drift from the actual bounds. * * @return array */ public static function bounds(): array { return self::BOUNDS; } /** * Settings API sanitize callback: always returns all keys, clamped to their bounds. * * @return array{upload_mb: int, log_retention_days: int, snapshot_count: int} */ public static function sanitize(mixed $input): array { $input = is_array($input) ? $input : []; $clean = self::DEFAULTS; foreach (self::BOUNDS as $key => [$min, $max]) { if (isset($input[$key]) && is_numeric($input[$key])) { $clean[$key] = max($min, min($max, (int) $input[$key])); } } return $clean; } }