diff --git a/app/Console/Commands/UserAvatarDelete.php b/app/Console/Commands/UserAvatarDelete.php index 55a320ee9..69de12225 100644 --- a/app/Console/Commands/UserAvatarDelete.php +++ b/app/Console/Commands/UserAvatarDelete.php @@ -17,14 +17,22 @@ class UserAvatarDelete extends Command implements PromptsForMissingInput * * @var string */ - protected $signature = 'user:avatar-delete {username}'; + protected $signature = 'user:avatar-delete {username} {--force : Delete without confirmation prompts}'; /** * The console command description. * * @var string */ - protected $description = 'Delete user avatar'; + protected $description = 'Delete user avatar and reset to default'; + + /** + * @var array + */ + protected array $defaultPaths = [ + 'public/avatars/default.jpg', + 'public/avatars/default.png', + ]; /** * Prompt for missing input arguments using the returned questions. @@ -41,63 +49,93 @@ class UserAvatarDelete extends Command implements PromptsForMissingInput /** * Execute the console command. */ - public function handle() + public function handle(): int { $user = User::whereUsername($this->argument('username'))->first(); if (! $user) { $this->error('Could not find any user with that username'); - exit; + + return Command::FAILURE; } if (! $user->profile_id) { $this->error('Could not find the profile with that username'); - exit; + + return Command::FAILURE; } $pid = $user->profile_id; - $avatarModel = Avatar::where('profile_id', $pid)->first(); + $avatarModel = Avatar::whereProfileId($pid)->first(); if (! $avatarModel) { $this->error('No avatar model found'); - Cache::forget('avatar:'.$pid); - exit; - } + $this->forgetAvatarCaches($pid); - $defaultPaths = ['public/avatars/default.jpg', 'public/avatars/default.png']; - $mediaPath = $avatarModel->media_path; + return Command::FAILURE; + } - if (in_array($mediaPath, $defaultPaths)) { + if ($this->isDefaultAvatar($avatarModel->media_path)) { $this->info('Default avatar already used, aborting...'); - Cache::forget('avatar:'.$pid); - exit; - } + $this->forgetAvatarCaches($pid); - if (Storage::disk(config('filesystems.cloud'))->exists($mediaPath)) { - if ($this->confirm('Found a S3 avatar at '.$mediaPath.'! Are you sure you want to delete this?')) { - Storage::disk(config('filesystems.cloud'))->delete($mediaPath); - $this->info('Deleting S3 copy'); - } else { - exit; - } + return Command::SUCCESS; } - if (Storage::disk('local')->exists($mediaPath)) { - if ($this->confirm('Found a local avatar at '.$mediaPath.'! Are you sure you want to delete this?')) { - Storage::disk('local')->delete($mediaPath); - $this->info('Deleting local copy'); - } else { - exit; - } + if (! $this->deleteStoredAvatar($avatarModel->media_path)) { + $this->info('Aborted, no changes were made.'); + + return Command::SUCCESS; } $avatarModel->media_path = 'public/avatars/default.jpg'; $avatarModel->cdn_url = null; + $avatarModel->change_count = $avatarModel->change_count + 1; $avatarModel->save(); + + $this->forgetAvatarCaches($pid); + + $this->info('Successfully deleted user avatar!'); + + return Command::SUCCESS; + } + + protected function isDefaultAvatar(?string $path): bool + { + return in_array($path, $this->defaultPaths, true); + } + + protected function forgetAvatarCaches($pid): void + { Cache::forget('avatar:'.$pid); AccountService::del($pid); + } - $this->info('Successfully deleted user avatar!'); + protected function deleteStoredAvatar(string $path): bool + { + if ((bool) config_cache('pixelfed.cloud_storage')) { + $cloudDisk = Storage::disk(config('filesystems.cloud')); + + if ($cloudDisk->exists($path)) { + if (! $this->option('force') && ! $this->confirm("Found a cloud avatar at {$path}! Are you sure you want to delete this?")) { + return false; + } + + $cloudDisk->delete($path); + $this->info('Deleting cloud avatar copy'); + } + } + + if (Storage::disk('local')->exists($path)) { + if (! $this->option('force') && ! $this->confirm("Found a local avatar at {$path}! Are you sure you want to delete this?")) { + return false; + } + + Storage::disk('local')->delete($path); + $this->info('Deleting local avatar copy'); + } + + return true; } }