| 
									
										
										
										
											2023-09-19 01:07:30 +08:00
										 |  |  | <?php | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace BookStack\Console\Commands; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | use BookStack\Users\Models\User; | 
					
						
							| 
									
										
										
										
											2023-09-19 22:53:01 +08:00
										 |  |  | use Exception; | 
					
						
							| 
									
										
										
										
											2023-09-19 01:07:30 +08:00
										 |  |  | use Illuminate\Console\Command; | 
					
						
							|  |  |  | use BookStack\Uploads\UserAvatars; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-19 22:53:01 +08:00
										 |  |  | class RefreshAvatarCommand extends Command | 
					
						
							| 
									
										
										
										
											2023-09-19 01:07:30 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2023-09-19 22:53:01 +08:00
										 |  |  |     use HandlesSingleUser; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-19 01:07:30 +08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * The name and signature of the console command. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @var string | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     protected $signature = 'bookstack:refresh-avatar | 
					
						
							|  |  |  |                             {--id= : Numeric ID of the user to refresh avatar for} | 
					
						
							|  |  |  |                             {--email= : Email address of the user to refresh avatar for} | 
					
						
							|  |  |  |                             {--users-without-avatars : Refresh avatars for users that currently have no avatar} | 
					
						
							| 
									
										
										
										
											2023-09-19 22:53:01 +08:00
										 |  |  |                             {--a|all : Refresh avatars for all users} | 
					
						
							|  |  |  |                             {--f|force : Actually run the update, Defaults to a dry-run}'; | 
					
						
							| 
									
										
										
										
											2023-09-19 01:07:30 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * The console command description. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @var string | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2023-09-19 22:53:01 +08:00
										 |  |  |     protected $description = 'Refresh avatar for the given user(s)'; | 
					
						
							| 
									
										
										
										
											2023-09-19 01:07:30 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     public function handle(UserAvatars $userAvatar): int | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2023-09-19 22:53:01 +08:00
										 |  |  |         if (!$userAvatar->avatarFetchEnabled()) { | 
					
						
							|  |  |  |             $this->error("Avatar fetching is disabled on this instance."); | 
					
						
							|  |  |  |             return self::FAILURE; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-09-19 01:07:30 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if ($this->option('users-without-avatars')) { | 
					
						
							| 
									
										
										
										
											2023-09-19 22:53:01 +08:00
										 |  |  |             return $this->processUsers(User::query()->whereDoesntHave('avatar')->get()->all(), $userAvatar); | 
					
						
							| 
									
										
										
										
											2023-09-19 01:07:30 +08:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if ($this->option('all')) { | 
					
						
							| 
									
										
										
										
											2023-09-19 22:53:01 +08:00
										 |  |  |             return $this->processUsers(User::query()->get()->all(), $userAvatar); | 
					
						
							| 
									
										
										
										
											2023-09-19 01:07:30 +08:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-19 22:53:01 +08:00
										 |  |  |         try { | 
					
						
							|  |  |  |             $user = $this->fetchProvidedUser(); | 
					
						
							|  |  |  |             return $this->processUsers([$user], $userAvatar); | 
					
						
							|  |  |  |         } catch (Exception $exception) { | 
					
						
							|  |  |  |             $this->error($exception->getMessage()); | 
					
						
							|  |  |  |             return self::FAILURE; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-09-19 01:07:30 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-19 22:53:01 +08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * @param User[] $users | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     private function processUsers(array $users, UserAvatars $userAvatar): int | 
					
						
							| 
									
										
										
										
											2023-09-19 01:07:30 +08:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2023-09-19 22:53:01 +08:00
										 |  |  |         $dryRun = !$this->option('force'); | 
					
						
							|  |  |  |         $this->info(count($users) . " user(s) found to update avatars for."); | 
					
						
							| 
									
										
										
										
											2023-09-19 01:07:30 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-19 22:53:01 +08:00
										 |  |  |         if (count($users) === 0) { | 
					
						
							|  |  |  |             return self::SUCCESS; | 
					
						
							| 
									
										
										
										
											2023-09-19 01:07:30 +08:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!$dryRun) { | 
					
						
							| 
									
										
										
										
											2023-09-19 22:53:01 +08:00
										 |  |  |             $fetchHost = parse_url($userAvatar->getAvatarUrl(), PHP_URL_HOST); | 
					
						
							|  |  |  |             $this->warn("This will destroy any existing avatar images these users have, and attempt to fetch new avatar images from {$fetchHost}."); | 
					
						
							|  |  |  |             $proceed = !$this->input->isInteractive() || $this->confirm('Are you sure you want to proceed?'); | 
					
						
							| 
									
										
										
										
											2023-09-19 01:07:30 +08:00
										 |  |  |             if (!$proceed) { | 
					
						
							|  |  |  |                 return self::SUCCESS; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-19 22:53:01 +08:00
										 |  |  |         $this->info(""); | 
					
						
							| 
									
										
										
										
											2023-09-19 01:07:30 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         $exitCode = self::SUCCESS; | 
					
						
							|  |  |  |         foreach ($users as $user) { | 
					
						
							| 
									
										
										
										
											2023-09-19 22:53:01 +08:00
										 |  |  |             $linePrefix = "[ID: {$user->id}] $user->email -"; | 
					
						
							| 
									
										
										
										
											2023-09-19 01:07:30 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |             if ($dryRun) { | 
					
						
							| 
									
										
										
										
											2023-09-19 22:53:01 +08:00
										 |  |  |                 $this->warn("{$linePrefix} Not updated"); | 
					
						
							| 
									
										
										
										
											2023-09-19 01:07:30 +08:00
										 |  |  |                 continue; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if ($this->fetchAvatar($userAvatar, $user)) { | 
					
						
							| 
									
										
										
										
											2023-09-19 22:53:01 +08:00
										 |  |  |                 $this->info("{$linePrefix} Updated"); | 
					
						
							| 
									
										
										
										
											2023-09-19 01:07:30 +08:00
										 |  |  |             } else { | 
					
						
							| 
									
										
										
										
											2023-09-19 22:53:01 +08:00
										 |  |  |                 $this->error("{$linePrefix} Not updated"); | 
					
						
							| 
									
										
										
										
											2023-09-19 01:07:30 +08:00
										 |  |  |                 $exitCode = self::FAILURE; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if ($dryRun) { | 
					
						
							| 
									
										
										
										
											2023-09-19 22:53:01 +08:00
										 |  |  |             $this->comment(""); | 
					
						
							|  |  |  |             $this->comment("Dry run, no avatars were updated."); | 
					
						
							|  |  |  |             $this->comment('Run with -f or --force to perform the update.'); | 
					
						
							| 
									
										
										
										
											2023-09-19 01:07:30 +08:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $exitCode; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private function fetchAvatar(UserAvatars $userAvatar, User $user): bool | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $oldId = $user->avatar->id ?? 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $userAvatar->fetchAndAssignToUser($user); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $user->refresh(); | 
					
						
							|  |  |  |         $newId = $user->avatar->id ?? $oldId; | 
					
						
							|  |  |  |         return $oldId !== $newId; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } |