From fe5c9366814def8c6de9f64194bb3952461e5107 Mon Sep 17 00:00:00 2001 From: Alexey Skobkin Date: Sat, 4 Nov 2017 22:38:38 +0300 Subject: [PATCH] #38 fix. User privacy status update implemented ('point:update:privacy' command). Small refactoring and several bug fixes. Small optimization. --- .../Version20171104182713.php | 40 ++++ .../Command/RestoreRemovedUsersCommand.php | 6 +- .../Command/UpdateSubscriptionsCommand.php | 166 +++++++-------- .../Command/UpdateUsersPrivacyCommand.php | 200 ++++++++++++++++++ .../Controller/Api/CrawlerController.php | 6 +- .../Bundle/PointToolsBundle/Entity/User.php | 47 +++- .../Exception/Api/UserNotFoundException.php | 3 +- .../Repository/UserRepository.php | 2 +- .../Resources/config/services.yml | 34 ++- .../Service/Api/AbstractApi.php | 16 +- .../PointToolsBundle/Service/Api/UserApi.php | 12 +- .../Service/Factory/UserFactory.php | 4 + .../Telegram/IncomingUpdateDispatcher.php | 4 +- .../Service/Telegram/Notifier.php | 4 +- 14 files changed, 413 insertions(+), 131 deletions(-) create mode 100644 app/DoctrineMigrations/Version20171104182713.php create mode 100644 src/Skobkin/Bundle/PointToolsBundle/Command/UpdateUsersPrivacyCommand.php diff --git a/app/DoctrineMigrations/Version20171104182713.php b/app/DoctrineMigrations/Version20171104182713.php new file mode 100644 index 0000000..21130e5 --- /dev/null +++ b/app/DoctrineMigrations/Version20171104182713.php @@ -0,0 +1,40 @@ +abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', 'Migration can only be executed safely on \'postgresql\'.'); + + $this->addSql('ALTER TABLE users.users ADD public BOOLEAN DEFAULT FALSE NOT NULL'); + $this->addSql('ALTER TABLE users.users ADD whitelist_only BOOLEAN DEFAULT FALSE NOT NULL'); + $this->addSql('CREATE INDEX idx_user_public ON users.users (public)'); + $this->addSql('CREATE INDEX idx_user_removed ON users.users (is_removed)'); + } + + /** + * @param Schema $schema + */ + public function down(Schema $schema) + { + // this down() migration is auto-generated, please modify it to your needs + $this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', 'Migration can only be executed safely on \'postgresql\'.'); + + $this->addSql('DROP INDEX users.idx_user_public'); + $this->addSql('DROP INDEX users.idx_user_removed'); + $this->addSql('ALTER TABLE users.users DROP public'); + $this->addSql('ALTER TABLE users.users DROP whitelist_only'); + } +} diff --git a/src/Skobkin/Bundle/PointToolsBundle/Command/RestoreRemovedUsersCommand.php b/src/Skobkin/Bundle/PointToolsBundle/Command/RestoreRemovedUsersCommand.php index a5efac4..07e0d2e 100644 --- a/src/Skobkin/Bundle/PointToolsBundle/Command/RestoreRemovedUsersCommand.php +++ b/src/Skobkin/Bundle/PointToolsBundle/Command/RestoreRemovedUsersCommand.php @@ -38,8 +38,10 @@ class RestoreRemovedUsersCommand extends Command */ private $delay; - public function setDependencies(LoggerInterface $logger, EntityManagerInterface $em, UserRepository $userRepo, UserApi $userApi, int $delay): void + public function __construct(LoggerInterface $logger, EntityManagerInterface $em, UserRepository $userRepo, UserApi $userApi, int $delay) { + parent::__construct(); + $this->logger = $logger; $this->em = $em; $this->userRepo = $userRepo; @@ -77,6 +79,8 @@ class RestoreRemovedUsersCommand extends Command 'login' => $removedUser->getLogin(), ]); $removedUser->restore(); + + $this->em->flush(); } } catch (UserNotFoundException $e) { $this->logger->debug('User is really removed. Keep going.', [ diff --git a/src/Skobkin/Bundle/PointToolsBundle/Command/UpdateSubscriptionsCommand.php b/src/Skobkin/Bundle/PointToolsBundle/Command/UpdateSubscriptionsCommand.php index eca43b6..ad1458a 100644 --- a/src/Skobkin/Bundle/PointToolsBundle/Command/UpdateSubscriptionsCommand.php +++ b/src/Skobkin/Bundle/PointToolsBundle/Command/UpdateSubscriptionsCommand.php @@ -4,16 +4,13 @@ namespace Skobkin\Bundle\PointToolsBundle\Command; use Doctrine\ORM\EntityManagerInterface; use Psr\Log\LoggerInterface; -use Skobkin\Bundle\PointToolsBundle\Entity\Subscription; -use Skobkin\Bundle\PointToolsBundle\Entity\User; +use Skobkin\Bundle\PointToolsBundle\Entity\{Subscription, User}; use Skobkin\Bundle\PointToolsBundle\Exception\Api\UserNotFoundException; use Skobkin\Bundle\PointToolsBundle\Repository\UserRepository; -use Skobkin\Bundle\PointToolsBundle\Service\SubscriptionsManager; -use Skobkin\Bundle\PointToolsBundle\Service\Api\UserApi; +use Skobkin\Bundle\PointToolsBundle\Service\{SubscriptionsManager, Api\UserApi}; use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; use Symfony\Component\Console\Helper\ProgressBar; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Input\{InputInterface, InputOption}; use Symfony\Component\Console\Output\OutputInterface; /** @@ -51,6 +48,11 @@ class UpdateSubscriptionsCommand extends ContainerAwareCommand */ private $apiDelay = 500000; + /** + * @var int + */ + private $appUserId; + /** * @var SubscriptionsManager */ @@ -61,19 +63,24 @@ class UpdateSubscriptionsCommand extends ContainerAwareCommand */ private $progress; + public function __construct( + EntityManagerInterface $em, + LoggerInterface $logger, + UserRepository $userRepo, + UserApi $api, + SubscriptionsManager $subscriptionManager, + int $apiDelay, + int $appUserId + ) { + parent::__construct(); - public function setDeps(LoggerInterface $logger, EntityManagerInterface $em, UserRepository $userRepo, UserApi $userApi, SubscriptionsManager $subscriptionsManager): void - { - $this->logger = $logger; $this->em = $em; + $this->logger = $logger; $this->userRepo = $userRepo; - $this->api = $userApi; - $this->subscriptionManager = $subscriptionsManager; - } - - public function setApiDelay(int $microSecs): void - { - $this->apiDelay = $microSecs; + $this->api = $api; + $this->subscriptionManager = $subscriptionManager; + $this->apiDelay = $apiDelay; + $this->appUserId = $appUserId; } protected function configure() @@ -96,35 +103,21 @@ class UpdateSubscriptionsCommand extends ContainerAwareCommand ; } - /** - * @param InputInterface $input - * @param OutputInterface $output - * - * @return int - */ protected function execute(InputInterface $input, OutputInterface $output) { $this->input = $input; $this->logger->debug('UpdateSubscriptionsCommand started.'); - try { - $appUserId = $this->getContainer()->getParameter('point_id'); - } catch (\InvalidArgumentException $e) { - $this->logger->alert('Could not get point_id parameter from config file', ['exception_message' => $e->getMessage()]); - return 1; - } - $this->progress = new ProgressBar($output); $this->progress->setFormat('debug'); - // Beginning transaction for all changes - $this->em->beginTransaction(); - - $this->progress->setMessage('Getting service subscribers'); + if ($input->getOption('check-only')) { // Beginning transaction for all changes + $this->em->beginTransaction(); + } try { - $usersForUpdate = $this->getUsersForUpdate($appUserId); + $usersForUpdate = $this->getUsersForUpdate(); } catch (\Exception $e) { $this->logger->error('Error while getting service subscribers', ['exception' => get_class($e), 'message' => $e->getMessage()]); @@ -138,78 +131,75 @@ class UpdateSubscriptionsCommand extends ContainerAwareCommand } $this->logger->info('Processing users subscribers'); - $this->progress->setMessage('Processing users subscribers'); $this->progress->start(count($usersForUpdate)); - $this->updateUsersSubscribers($usersForUpdate); + foreach ($usersForUpdate as $user) { + usleep($this->apiDelay); + + $this->progress->advance(); + $this->logger->info('Processing @'.$user->getLogin()); + + $this->updateUser($user); + } $this->progress->finish(); - // Flushing all changes at once to database - $this->em->flush(); - $this->em->commit(); + + if ($input->getOption('check-only')) { // Flushing all changes at once to the database + $this->em->flush(); + $this->em->commit(); + } $this->logger->debug('Finished'); return 0; } - /** - * @param User[] $users - */ - private function updateUsersSubscribers(array $users): void + private function updateUser(User $user): void { - // Updating users subscribers - foreach ($users as $user) { - usleep($this->apiDelay); + try { + $userCurrentSubscribers = $this->api->getUserSubscribersById($user->getId()); + } catch (UserNotFoundException $e) { + $this->logger->warning('User not found. Marking as removed.', ['login' => $user->getLogin(), 'user_id' => $user->getId()]); - $this->progress->advance(); + $user->markAsRemoved(); - $this->logger->info('Processing @'.$user->getLogin()); + return; + } catch (\Exception $e) { + $this->logger->error( + 'Error while getting subscribers. Skipping.', + [ + 'user_login' => $user->getLogin(), + 'user_id' => $user->getId(), + 'message' => $e->getMessage(), + 'file' => $e->getFile(), + 'line' => $e->getLine(), + ] + ); - try { - $userCurrentSubscribers = $this->api->getUserSubscribersById($user->getId()); - } catch (UserNotFoundException $e) { - $this->logger->warning('User not found. Marking as removed', ['login' => $user->getLogin(), 'user_id' => $user->getId()]); - $user->markAsRemoved(); + return; + } - continue; - } catch (\Exception $e) { - $this->logger->error( - 'Error while getting subscribers. Skipping.', - [ - 'user_login' => $user->getLogin(), - 'user_id' => $user->getId(), - 'message' => $e->getMessage(), - 'file' => $e->getFile(), - 'line' => $e->getLine(), - ] - ); + $this->logger->debug('Updating user subscribers'); - continue; - } - - $this->logger->debug('Updating user subscribers'); - - try { - // Updating user subscribers - $this->subscriptionManager->updateUserSubscribers($user, $userCurrentSubscribers); - } catch (\Exception $e) { - $this->logger->error( - 'Error while updating user subscribers', - [ - 'user_login' => $user->getLogin(), - 'user_id' => $user->getId(), - 'message' => $e->getMessage(), - 'file' => $e->getFile(), - 'line' => $e->getLine(), - ] - ); - } + try { + // Updating user subscribers + $this->subscriptionManager->updateUserSubscribers($user, $userCurrentSubscribers); + } catch (\Exception $e) { + $this->logger->error( + 'Error while updating user subscribers', + [ + 'user_login' => $user->getLogin(), + 'user_id' => $user->getId(), + 'message' => $e->getMessage(), + 'file' => $e->getFile(), + 'line' => $e->getLine(), + ] + ); } } - private function getUsersForUpdate(int $appUserId): array + private function getUsersForUpdate(): array { $usersForUpdate = []; @@ -218,7 +208,7 @@ class UpdateSubscriptionsCommand extends ContainerAwareCommand } else { /** @var User $serviceUser */ try { - $serviceUser = $this->userRepo->findActiveUserWithSubscribers($appUserId); + $serviceUser = $this->userRepo->findActiveUserWithSubscribers($this->appUserId); } catch (\Exception $e) { $this->logger->error('Error while getting active user with subscribers', ['app_user_id' => $appUserId]); @@ -235,7 +225,7 @@ class UpdateSubscriptionsCommand extends ContainerAwareCommand $this->logger->info('Getting service subscribers'); try { - $usersForUpdate = $this->api->getUserSubscribersById($appUserId); + $usersForUpdate = $this->api->getUserSubscribersById($this->appUserId); } catch (UserNotFoundException $e) { $this->logger->critical('Service user deleted or API response is invalid'); diff --git a/src/Skobkin/Bundle/PointToolsBundle/Command/UpdateUsersPrivacyCommand.php b/src/Skobkin/Bundle/PointToolsBundle/Command/UpdateUsersPrivacyCommand.php new file mode 100644 index 0000000..1410aba --- /dev/null +++ b/src/Skobkin/Bundle/PointToolsBundle/Command/UpdateUsersPrivacyCommand.php @@ -0,0 +1,200 @@ +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); + + // Flushing each 10 users + if (0 === $idx % 10) { + $this->em->flush(); + } + } + + $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.', ['user_id' => $user->getId(), 'user_login' => $user->getLogin()]); + } + } 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; + } + } +} diff --git a/src/Skobkin/Bundle/PointToolsBundle/Controller/Api/CrawlerController.php b/src/Skobkin/Bundle/PointToolsBundle/Controller/Api/CrawlerController.php index 93b2711..c1f9906 100644 --- a/src/Skobkin/Bundle/PointToolsBundle/Controller/Api/CrawlerController.php +++ b/src/Skobkin/Bundle/PointToolsBundle/Controller/Api/CrawlerController.php @@ -2,9 +2,9 @@ namespace Skobkin\Bundle\PointToolsBundle\Controller\Api; +use Skobkin\Bundle\PointToolsBundle\DTO\Api\PostsPage; use Skobkin\Bundle\PointToolsBundle\Service\Factory\Blogs\PostFactory; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpFoundation\{Request, Response}; class CrawlerController extends AbstractApiController { @@ -21,7 +21,7 @@ class CrawlerController extends AbstractApiController $serializer = $this->get('jms_serializer'); - $page = $serializer->deserialize($json, 'Skobkin\Bundle\PointToolsBundle\DTO\Api\PostsPage', 'json'); + $page = $serializer->deserialize($json, PostsPage::class, 'json'); /** @var PostFactory $factory */ $factory = $this->get('app.point.post_factory'); diff --git a/src/Skobkin/Bundle/PointToolsBundle/Entity/User.php b/src/Skobkin/Bundle/PointToolsBundle/Entity/User.php index d1ac1d9..9a9fa04 100644 --- a/src/Skobkin/Bundle/PointToolsBundle/Entity/User.php +++ b/src/Skobkin/Bundle/PointToolsBundle/Entity/User.php @@ -6,15 +6,18 @@ use Doctrine\Common\Collections\ArrayCollection; use Doctrine\ORM\Mapping as ORM; /** - * @ORM\Table(name="users", schema="users") + * @ORM\Table(name="users", schema="users", indexes={ + * @ORM\Index(name="idx_user_public", columns={"public"}), + * @ORM\Index(name="idx_user_removed", columns={"is_removed"}) + * }) * @ORM\Entity(repositoryClass="Skobkin\Bundle\PointToolsBundle\Repository\UserRepository") * @ORM\HasLifecycleCallbacks */ class User { - const AVATAR_SIZE_SMALL = '24'; - const AVATAR_SIZE_MEDIUM = '40'; - const AVATAR_SIZE_LARGE = '80'; + public const AVATAR_SIZE_SMALL = '24'; + public const AVATAR_SIZE_MEDIUM = '40'; + public const AVATAR_SIZE_LARGE = '80'; /** * @var int @@ -52,6 +55,20 @@ class User */ private $updatedAt; + /** + * @var bool + * + * @ORM\Column(name="public", type="boolean", nullable=false, options={"default": false}) + */ + private $public = false; + + /** + * @var bool + * + * @ORM\Column(name="whitelist_only", type="boolean", nullable=false, options={"default": false}) + */ + private $whitelistOnly = false; + /** * @var ArrayCollection|Subscription[] * @@ -140,7 +157,7 @@ class User /** * @return Subscription[]|ArrayCollection */ - public function getSubscribers(): iterable + public function getSubscribers(): ArrayCollection { return $this->subscribers; } @@ -148,7 +165,7 @@ class User /** * @return Subscription[]|ArrayCollection */ - public function getSubscriptions(): iterable + public function getSubscriptions(): ArrayCollection { return $this->subscriptions; } @@ -163,7 +180,7 @@ class User /** * @return SubscriptionEvent[]|ArrayCollection */ - public function getNewSubscriberEvents(): iterable + public function getNewSubscriberEvents(): ArrayCollection { return $this->newSubscriberEvents; } @@ -178,6 +195,22 @@ class User return $this->updatedAt; } + public function updatePrivacy(?bool $public, ?bool $whitelistOnly): void + { + $this->public = $public; + $this->whitelistOnly = $whitelistOnly; + } + + public function isPublic(): ?bool + { + return $this->public; + } + + public function isWhitelistOnly(): ?bool + { + return $this->whitelistOnly; + } + public function isRemoved(): bool { return $this->removed; diff --git a/src/Skobkin/Bundle/PointToolsBundle/Exception/Api/UserNotFoundException.php b/src/Skobkin/Bundle/PointToolsBundle/Exception/Api/UserNotFoundException.php index 5cf5bff..31da7b5 100644 --- a/src/Skobkin/Bundle/PointToolsBundle/Exception/Api/UserNotFoundException.php +++ b/src/Skobkin/Bundle/PointToolsBundle/Exception/Api/UserNotFoundException.php @@ -2,7 +2,7 @@ namespace Skobkin\Bundle\PointToolsBundle\Exception\Api; -class UserNotFoundException extends ApiException +class UserNotFoundException extends NotFoundException { /** * @var int @@ -22,6 +22,7 @@ class UserNotFoundException extends ApiException public function __construct($message = 'User not found', $code = 0, \Exception $previous = null, $userId = null, $login = null) { parent::__construct($message, $code, $previous); + $this->userId = $userId; $this->login = $login; } diff --git a/src/Skobkin/Bundle/PointToolsBundle/Repository/UserRepository.php b/src/Skobkin/Bundle/PointToolsBundle/Repository/UserRepository.php index 9476ed1..52878bf 100644 --- a/src/Skobkin/Bundle/PointToolsBundle/Repository/UserRepository.php +++ b/src/Skobkin/Bundle/PointToolsBundle/Repository/UserRepository.php @@ -17,7 +17,7 @@ class UserRepository extends EntityRepository { $qb = $this->createQueryBuilder('u'); - // May be optimize hydration procedure + // @todo May be optimize hydration procedure return $qb ->select(['u', 's', 'us']) ->innerJoin('u.subscribers', 's') diff --git a/src/Skobkin/Bundle/PointToolsBundle/Resources/config/services.yml b/src/Skobkin/Bundle/PointToolsBundle/Resources/config/services.yml index 741fa69..deb75da 100644 --- a/src/Skobkin/Bundle/PointToolsBundle/Resources/config/services.yml +++ b/src/Skobkin/Bundle/PointToolsBundle/Resources/config/services.yml @@ -53,18 +53,40 @@ services: # Subsribers update app.point.update_subscribers_command: class: Skobkin\Bundle\PointToolsBundle\Command\UpdateSubscriptionsCommand - #autowire: [] - calls: - - [setDeps, ['@logger', '@doctrine.orm.entity_manager', '@app.point.user_repository', '@app.point.api_user', '@app.point.subscriptions_manager']] - - [setApiDelay, ['%point_api_delay%']] + arguments: + - '@doctrine.orm.entity_manager' + - '@logger' + - '@app.point.user_repository' + - '@app.point.api_user' + - '@app.point.subscriptions_manager' + - '%point_api_delay%' + - '%point_id%' tags: - { name: console.command } - { name: monolog.logger, channel: subscribers_update } + # Privacy update + app.point.update_privacy_command: + class: Skobkin\Bundle\PointToolsBundle\Command\UpdateUsersPrivacyCommand + #autowire: [] + arguments: + - '@doctrine.orm.entity_manager' + - '@logger' + - '@app.point.user_repository' + - '@app.point.api_user' + - '%point_api_delay%' + - '%point_id%' + tags: + - { name: console.command } + - { name: monolog.logger, channel: privacy_update } # Restore users removed by error app.point.restore_users: class: Skobkin\Bundle\PointToolsBundle\Command\RestoreRemovedUsersCommand - calls: - - [setDependencies, ['@logger', '@doctrine.orm.entity_manager', '@app.point.user_repository', '@app.point.api_user', '%point_api_delay%']] + arguments: + - '@logger' + - '@doctrine.orm.entity_manager' + - '@app.point.user_repository' + - '@app.point.api_user' + - '%point_api_delay%' tags: - { name: console.command } # Webhook management diff --git a/src/Skobkin/Bundle/PointToolsBundle/Service/Api/AbstractApi.php b/src/Skobkin/Bundle/PointToolsBundle/Service/Api/AbstractApi.php index 454ed38..73dc076 100644 --- a/src/Skobkin/Bundle/PointToolsBundle/Service/Api/AbstractApi.php +++ b/src/Skobkin/Bundle/PointToolsBundle/Service/Api/AbstractApi.php @@ -4,16 +4,10 @@ namespace Skobkin\Bundle\PointToolsBundle\Service\Api; use GuzzleHttp\ClientInterface; use GuzzleHttp\Exception\TransferException; -use JMS\Serializer\DeserializationContext; -use JMS\Serializer\Serializer; -use Psr\Http\Message\ResponseInterface; -use Psr\Http\Message\StreamInterface; +use JMS\Serializer\{DeserializationContext, Serializer}; +use Psr\Http\Message\{ResponseInterface, StreamInterface}; use Psr\Log\LoggerInterface; -use Skobkin\Bundle\PointToolsBundle\Exception\Api\ForbiddenException; -use Skobkin\Bundle\PointToolsBundle\Exception\Api\NetworkException; -use Skobkin\Bundle\PointToolsBundle\Exception\Api\NotFoundException; -use Skobkin\Bundle\PointToolsBundle\Exception\Api\ServerProblemException; -use Skobkin\Bundle\PointToolsBundle\Exception\Api\UnauthorizedException; +use Skobkin\Bundle\PointToolsBundle\Exception\Api\{ForbiddenException, NetworkException, NotFoundException, ServerProblemException, UnauthorizedException}; use Symfony\Component\HttpFoundation\Response as SymfonyResponse; class AbstractApi @@ -184,7 +178,9 @@ class AbstractApi // @todo remove after fix // Temporary fix until @arts fixes this bug if ('{"error": "UserNotFound"}' === (string) $response->getBody()) { - throw new NotFoundException($reason, $code); + throw new NotFoundException('Not found', SymfonyResponse::HTTP_NOT_FOUND); + } elseif ('{"message": "Forbidden", "code": 403, "error": "Forbidden"}' === (string) $response->getBody()) { + throw new ForbiddenException('Forbidden', SymfonyResponse::HTTP_FORBIDDEN); } switch ($code) { diff --git a/src/Skobkin/Bundle/PointToolsBundle/Service/Api/UserApi.php b/src/Skobkin/Bundle/PointToolsBundle/Service/Api/UserApi.php index e349838..7bf6404 100644 --- a/src/Skobkin/Bundle/PointToolsBundle/Service/Api/UserApi.php +++ b/src/Skobkin/Bundle/PointToolsBundle/Service/Api/UserApi.php @@ -3,16 +3,11 @@ namespace Skobkin\Bundle\PointToolsBundle\Service\Api; use GuzzleHttp\ClientInterface; -use JMS\Serializer\DeserializationContext; -use JMS\Serializer\Serializer; +use JMS\Serializer\{DeserializationContext, Serializer}; use Psr\Log\LoggerInterface; -use Skobkin\Bundle\PointToolsBundle\DTO\Api\Auth; -use Skobkin\Bundle\PointToolsBundle\DTO\Api\User as UserDTO; +use Skobkin\Bundle\PointToolsBundle\DTO\Api\{Auth, User as UserDTO}; use Skobkin\Bundle\PointToolsBundle\Entity\User; -use Skobkin\Bundle\PointToolsBundle\Exception\Api\ForbiddenException; -use Skobkin\Bundle\PointToolsBundle\Exception\Api\InvalidResponseException; -use Skobkin\Bundle\PointToolsBundle\Exception\Api\NotFoundException; -use Skobkin\Bundle\PointToolsBundle\Exception\Api\UserNotFoundException; +use Skobkin\Bundle\PointToolsBundle\Exception\Api\{ForbiddenException, InvalidResponseException, NotFoundException, UserNotFoundException}; use Skobkin\Bundle\PointToolsBundle\Service\Factory\UserFactory; /** @@ -177,6 +172,7 @@ class UserApi extends AbstractApi } catch (NotFoundException $e) { throw new UserNotFoundException('User not found', 0, $e, $id); } + // Not catching ForbiddenException right now return $this->userFactory->findOrCreateFromDTO($userData); } diff --git a/src/Skobkin/Bundle/PointToolsBundle/Service/Factory/UserFactory.php b/src/Skobkin/Bundle/PointToolsBundle/Service/Factory/UserFactory.php index d9ff639..4c97641 100644 --- a/src/Skobkin/Bundle/PointToolsBundle/Service/Factory/UserFactory.php +++ b/src/Skobkin/Bundle/PointToolsBundle/Service/Factory/UserFactory.php @@ -48,6 +48,10 @@ class UserFactory extends AbstractFactory $user->updateLoginAndName($userData->getLogin(), $userData->getName()); + if (null !== $userData->getDenyAnonymous() && null !== $userData->getPrivate()) { + $user->updatePrivacy(!$userData->getDenyAnonymous(), $userData->getPrivate()); + } + return $user; } diff --git a/src/Skobkin/Bundle/PointToolsBundle/Service/Telegram/IncomingUpdateDispatcher.php b/src/Skobkin/Bundle/PointToolsBundle/Service/Telegram/IncomingUpdateDispatcher.php index b3a993c..5a03c99 100644 --- a/src/Skobkin/Bundle/PointToolsBundle/Service/Telegram/IncomingUpdateDispatcher.php +++ b/src/Skobkin/Bundle/PointToolsBundle/Service/Telegram/IncomingUpdateDispatcher.php @@ -2,9 +2,7 @@ namespace Skobkin\Bundle\PointToolsBundle\Service\Telegram; -use unreal4u\TelegramAPI\Telegram\Types\Inline\Query; -use unreal4u\TelegramAPI\Telegram\Types\Message; -use unreal4u\TelegramAPI\Telegram\Types\Update; +use unreal4u\TelegramAPI\Telegram\Types\{Inline\Query, Message, Update}; /** * Dispatches incoming messages processing to corresponding services diff --git a/src/Skobkin/Bundle/PointToolsBundle/Service/Telegram/Notifier.php b/src/Skobkin/Bundle/PointToolsBundle/Service/Telegram/Notifier.php index dbcf707..c294486 100644 --- a/src/Skobkin/Bundle/PointToolsBundle/Service/Telegram/Notifier.php +++ b/src/Skobkin/Bundle/PointToolsBundle/Service/Telegram/Notifier.php @@ -2,9 +2,7 @@ namespace Skobkin\Bundle\PointToolsBundle\Service\Telegram; -use Skobkin\Bundle\PointToolsBundle\Entity\Telegram\Account; -use Skobkin\Bundle\PointToolsBundle\Entity\User; -use Skobkin\Bundle\PointToolsBundle\Entity\UserRenameEvent; +use Skobkin\Bundle\PointToolsBundle\Entity\{Telegram\Account, User, UserRenameEvent}; use Skobkin\Bundle\PointToolsBundle\Repository\Telegram\AccountRepository; /**