addSeconds($this->cacheSeconds()), fn (): array => $this->freshStatus() ); } catch (Throwable) { return $this->freshStatus(); } } public function formatBytes(?int $bytes): string { if ($bytes === null) { return 'неизвестно'; } $units = ['Б', 'КБ', 'МБ', 'ГБ', 'ТБ']; $value = (float) $bytes; $unitIndex = 0; while ($value >= 1024 && $unitIndex < count($units) - 1) { $value /= 1024; $unitIndex++; } return sprintf('%s %s', round($value, $unitIndex === 0 ? 0 : 2), $units[$unitIndex]); } /** * @return array{warning: bool, free_bytes: int|null, threshold_bytes: int, path: string, checked_at: string|null} */ private function freshStatus(): array { $path = $this->path(); $thresholdBytes = $this->thresholdBytes(); $freeBytes = @disk_free_space($path); $freeBytes = $freeBytes === false ? null : (int) $freeBytes; return [ 'warning' => $freeBytes !== null && $freeBytes < $thresholdBytes, 'free_bytes' => $freeBytes, 'threshold_bytes' => $thresholdBytes, 'path' => $path, 'checked_at' => now()->toDateTimeString(), ]; } private function path(): string { return (string) config('app.disk_space_warning.path', storage_path()); } private function thresholdBytes(): int { return max(0, (int) config('app.disk_space_warning.threshold_bytes', 1024 * 1024 * 1024)); } private function cacheSeconds(): int { return max(1, (int) config('app.disk_space_warning.cache_seconds', 300)); } }