completion > 100) { $this->completion = 100; } } /** * Build settings from a raw Settings table array (mixed snake-case keys, * stringly-typed values, possible nulls/empty strings). * * @param array $dbSettings */ public static function forDatabase(array $dbSettings): self { $getInt = static fn (string $key, int $default): int => (isset($dbSettings[$key]) && $dbSettings[$key] !== '') ? (int) $dbSettings[$key] : $default; return new self( collectionDelayTime: $getInt('delaytime', 2), crossPostTime: $getInt('crossposttime', 2), releaseCreationLimit: $getInt('maxnzbsprocessed', 1000), completion: $getInt('completionpercent', 0), collectionTimeout: $getInt('collection_timeout', 48), maxSizeToFormRelease: $getInt('maxsizetoformrelease', 0), minSizeToFormRelease: $getInt('minsizetoformrelease', 0), minFilesToFormRelease: $getInt('minfilestoformrelease', 0), releaseRetentionDays: $getInt('releaseretentiondays', 0), deletePasswordedRelease: ((int) ($dbSettings['deletepasswordedrelease'] ?? 0)) === 1, miscOtherRetentionHours: $getInt('miscotherretentionhours', 0), miscHashedRetentionHours: $getInt('mischashedretentionhours', 0), partRetentionHours: $getInt('partretentionhours', 24), lastRunTime: ! empty($dbSettings['last_run_time']) ? (string) $dbSettings['last_run_time'] : null, ); } public function hasValidCompletion(): bool { return $this->completion >= 0 && $this->completion <= 100; } public function hasRetentionCleanup(): bool { return $this->releaseRetentionDays > 0; } public function hasCrossPostDetection(): bool { return $this->crossPostTime > 0; } public function hasCompletionCleanup(): bool { return $this->completion > 0; } }