isActive()) { return; } $resolved = $this->resolve(); Config::set('filesystems.disks.files_external.key', $resolved['key']); Config::set('filesystems.disks.files_external.secret', $resolved['secret']); Config::set('filesystems.disks.files_external.region', $resolved['region']); Config::set('filesystems.disks.files_external.bucket', $resolved['bucket']); Config::set('filesystems.disks.files_external.endpoint', $resolved['endpoint']); Config::set('filesystems.disks.files_external.use_path_style_endpoint', $resolved['use_path_style']); if ($resolved['root'] !== null) { Config::set('filesystems.disks.files_external.root', $resolved['root']); } } public function flush(): void { Cache::forget(self::CACHE_KEY); } public function resolveDisk(ResolvingUploadDisk $event): void { if ($this->isActive()) { $event->disk = 'files_external'; } } /** * Whether 'files_external' is both fully configured (the DB row) and * permitted (the edition's capability) — the single live check every * caller in this class needs, kept in one place. Deliberately * uncached (see class docblock) so an edition change or a capability * flip is never one process-boot stale. */ public function isActive(): bool { return $this->resolve()['configured'] && $this->capabilities->has(Capability::StorageConfigure); } /** * Deliberately edition-independent: whether the DB row itself is fully * filled in and active, nothing more. Callers AND the capability check * live and uncached — see class docblock. * * @return array{configured: bool, key: string|null, secret: string|null, region: string|null, bucket: string|null, endpoint: string|null, use_path_style: bool, root: string|null} */ private function resolve(): array { $blank = [ 'configured' => false, 'key' => null, 'secret' => null, 'region' => null, 'bucket' => null, 'endpoint' => null, 'use_path_style' => false, 'root' => null, ]; // Through BootSettingsCache, not Cache directly: this runs on every // process boot, including the artisan commands that install the // application, and must survive a database that has no tables yet // (or none at all). See that class for the full story. return BootSettingsCache::rememberForever(self::CACHE_KEY, function () use ($blank): array { if (! Schema::hasTable('external_storage_settings')) { return $blank; } $settings = ExternalStorageSettings::current(); if (! $settings->isConfigured()) { return $blank; } return [ 'configured' => true, 'key' => $settings->key, 'secret' => $settings->secret, 'region' => $settings->region, 'bucket' => $settings->bucket, 'endpoint' => $settings->endpoint, 'use_path_style' => $settings->use_path_style, 'root' => $settings->root, ]; }, $blank); } }