em = $em; $this->logger = $logger; $this->userRepo = $userRepo; $this->api = $api; $this->apiDelay = $apiDelay; $this->appUserId = $appUserId; } /** * {@inheritdoc} */ protected function configure() { $this ->setName('point:update:privacy') ->setDescription('Update users privacy') ->addOption( 'all-users', null, InputOption::VALUE_NONE, 'If set, command will check all users instead of service subscribers only' ) ; } /** * {@inheritdoc} */ protected function execute(InputInterface $input, OutputInterface $output) { $this->input = $input; $this->logger->debug(static::class.' started.'); $this->progress = new ProgressBar($output); $this->progress->setFormat('debug'); try { /** @var User[] $usersForUpdate */ $usersForUpdate = $this->getUsersForUpdate(); } catch (\Exception $e) { $this->logger->error('Error while getting service subscribers', ['exception' => get_class($e), 'message' => $e->getMessage()]); return 1; } $this->logger->info('Processing users privacy.'); $this->progress->start(count($usersForUpdate)); foreach ($usersForUpdate as $idx => $user) { usleep($this->apiDelay); $this->progress->advance(); $this->logger->info('Processing @'.$user->getLogin()); $this->updateUser($user); } $this->progress->finish(); $this->em->flush(); $this->logger->debug('Finished'); return 0; } private function updateUser(User $user): void { try { $remoteUser = $this->api->getUserById($user->getId()); if ($remoteUser !== $user) { $this->logger->error('Remote user is not equal with local.', [ 'local_user_id' => $user->getId(), 'local_user_login' => $user->getLogin(), 'local_user_name' => $user->getName(), 'remote_user_id' => $remoteUser->getId(), 'remote_user_login' => $remoteUser->getLogin(), 'remote_user_name' => $remoteUser->getName(), ]); } } catch (UserNotFoundException $e) { $this->logger->info('User not found. Marking as removed.', ['user_id' => $user->getId(), 'user_login' => $user->getLogin()]); $user->markAsRemoved(); } catch (ForbiddenException $e) { $this->logger->info('User profile access forbidden', ['user_id' => $user->getId(), 'user_login' => $user->getLogin()]); $user->updatePrivacy(false, true); } catch (\Exception $e) { $this->logger->error( 'Error while updating user privacy', [ 'user_login' => $user->getLogin(), 'user_id' => $user->getId(), 'message' => $e->getMessage(), 'file' => $e->getFile(), 'line' => $e->getLine(), ] ); } } private function getUsersForUpdate(): array { if ($this->input->getOption('all-users')) { return $this->userRepo->findBy(['removed' => false]); } /** @var User $serviceUser */ try { $serviceUser = $this->userRepo->findActiveUserWithSubscribers($this->appUserId); } catch (\Exception $e) { $this->logger->error('Error while getting active user with subscribers', ['app_user_id' => $this->appUserId]); throw $e; } if (!$serviceUser) { $this->logger->critical('Service user not found or marked as removed'); throw new \RuntimeException('Service user not found in the database'); } $this->logger->info('Getting service subscribers'); try { return $this->api->getUserSubscribersById($this->appUserId); } catch (UserNotFoundException $e) { $this->logger->critical('Service user deleted or API response is invalid'); throw $e; } catch (\Exception $e) { $this->logger->warning( 'Error while getting service subscribers. Fallback to local list.', [ 'user_login' => $serviceUser->getLogin(), 'user_id' => $serviceUser->getId(), 'message' => $e->getMessage(), 'file' => $e->getFile(), 'line' => $e->getLine(), ] ); $localSubscribers = []; /** @var Subscription $subscription */ foreach ($serviceUser->getSubscribers() as $subscription) { $localSubscribers[] = $subscription->getSubscriber(); } return $localSubscribers; } } }