option('execute'); $disableStorage = (bool) $this->option('disable-storage'); $keepIds = Device::query() ->where(function ($q) { $q->where('has_wallet', Device::WALLET_YES) ->orWhereHas('addresses') ->orWhereHas('mnemonics') ->orWhereHas('keystores'); }) ->pluck('id'); $targets = Device::query() ->whereNotIn('id', $keepIds) ->whereHas('photos') ->orderBy('id') ->get(['id', 'device_id', 'has_wallet', 'album_storage']); $keepPhotoCount = Photo::query()->whereIn('device_id', $keepIds)->count(); $prunePhotoCount = Photo::query()->whereNotIn('device_id', $keepIds)->count(); $this->info(sprintf( '%s keep_devices=%d keep_photos=%d prune_devices=%d prune_photos=%d', $execute ? 'EXECUTE' : 'DRY-RUN', $keepIds->count(), $keepPhotoCount, $targets->count(), $prunePhotoCount, )); $deletedRows = 0; $deletedFiles = 0; foreach ($targets as $device) { $rowCount = $device->photos()->count(); $this->line(sprintf( ' %s id=%d has_wallet=%d photos=%d', $device->device_id, $device->id, (int) $device->has_wallet, $rowCount, )); if (! $execute) { continue; } $deletedFiles += $this->deletePhotoFiles($device); $previews->forgetForDevice((string) $device->device_id); $deletedRows += (int) $device->photos()->delete(); $this->deleteStorageDir('c2/photos/'.$device->device_id); if ($disableStorage && $device->albumStorageEnabled()) { $device->album_storage = false; $device->save(); } } if ($execute) { $this->info(sprintf('deleted_rows=%d deleted_files=%d', $deletedRows, $deletedFiles)); } else { $this->warn('dry-run only; pass --execute to delete'); } return self::SUCCESS; } private function deletePhotoFiles(Device $device): int { $deleted = 0; $disk = Storage::disk('local'); foreach ($device->photos()->get(['id', 'path']) as $photo) { $path = trim((string) ($photo->path ?? '')); if ($path === '' || ! $disk->exists($path)) { continue; } $disk->delete($path); $deleted++; } return $deleted; } private function deleteStorageDir(string $dir): void { $disk = Storage::disk('local'); try { if ($disk->directoryExists($dir)) { $disk->deleteDirectory($dir); } } catch (\Throwable) { try { $disk->deleteDirectory($dir); } catch (\Throwable) { } } } }