Revert: Revert: User removal support.
This commit is contained in:
parent
38d0ab50be
commit
76b332155b
34
app/DoctrineMigrations/Version20170116224555.php
Normal file
34
app/DoctrineMigrations/Version20170116224555.php
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Application\Migrations;
|
||||||
|
|
||||||
|
use Doctrine\DBAL\Migrations\AbstractMigration;
|
||||||
|
use Doctrine\DBAL\Schema\Schema;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User removal support
|
||||||
|
*/
|
||||||
|
class Version20170116224555 extends AbstractMigration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param Schema $schema
|
||||||
|
*/
|
||||||
|
public function up(Schema $schema)
|
||||||
|
{
|
||||||
|
// this up() 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('ALTER TABLE users.users ADD is_removed BOOLEAN DEFAULT FALSE NOT NULL');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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('ALTER TABLE users.users DROP is_removed');
|
||||||
|
}
|
||||||
|
}
|
|
@ -75,15 +75,9 @@ class ImportUsersCommand extends ContainerAwareCommand
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$createdAt = \DateTime::createFromFormat('Y-m-d_H:i:s', $row[3]);
|
$createdAt = \DateTime::createFromFormat('Y-m-d_H:i:s', $row[3]) ?: new \DateTime();
|
||||||
|
|
||||||
if (!$createdAt) {
|
$user = new User($row[0], $createdAt, $row[1], $row[2]);
|
||||||
$createdAt = new \DateTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
$user = (new User($row[0], $row[1], $row[2]))
|
|
||||||
->setCreatedAt($createdAt)
|
|
||||||
;
|
|
||||||
|
|
||||||
if (!$input->getOption('check-only')) {
|
if (!$input->getOption('check-only')) {
|
||||||
$em->persist($user);
|
$em->persist($user);
|
||||||
|
|
|
@ -6,6 +6,7 @@ use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
use Skobkin\Bundle\PointToolsBundle\Entity\Subscription;
|
use Skobkin\Bundle\PointToolsBundle\Entity\Subscription;
|
||||||
use Skobkin\Bundle\PointToolsBundle\Entity\User;
|
use Skobkin\Bundle\PointToolsBundle\Entity\User;
|
||||||
|
use Skobkin\Bundle\PointToolsBundle\Exception\Api\UserNotFoundException;
|
||||||
use Skobkin\Bundle\PointToolsBundle\Repository\UserRepository;
|
use Skobkin\Bundle\PointToolsBundle\Repository\UserRepository;
|
||||||
use Skobkin\Bundle\PointToolsBundle\Service\SubscriptionsManager;
|
use Skobkin\Bundle\PointToolsBundle\Service\SubscriptionsManager;
|
||||||
use Skobkin\Bundle\PointToolsBundle\Service\Api\UserApi;
|
use Skobkin\Bundle\PointToolsBundle\Service\Api\UserApi;
|
||||||
|
@ -185,6 +186,11 @@ class UpdateSubscriptionsCommand extends ContainerAwareCommand
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$userCurrentSubscribers = $this->api->getUserSubscribersById($user->getId());
|
$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();
|
||||||
|
|
||||||
|
continue;
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
$this->logger->error(
|
$this->logger->error(
|
||||||
'Error while getting subscribers. Skipping.',
|
'Error while getting subscribers. Skipping.',
|
||||||
|
@ -222,14 +228,16 @@ class UpdateSubscriptionsCommand extends ContainerAwareCommand
|
||||||
|
|
||||||
private function getUsersForUpdate(int $appUserId): array
|
private function getUsersForUpdate(int $appUserId): array
|
||||||
{
|
{
|
||||||
|
$usersForUpdate = [];
|
||||||
|
|
||||||
if ($this->input->getOption('all-users')) {
|
if ($this->input->getOption('all-users')) {
|
||||||
$usersForUpdate = $this->userRepo->findAll();
|
$usersForUpdate = $this->userRepo->findBy(['removed' => false]);
|
||||||
} else {
|
} else {
|
||||||
/** @var User $serviceUser */
|
/** @var User $serviceUser */
|
||||||
$serviceUser = $this->userRepo->find($appUserId);
|
$serviceUser = $this->userRepo->findActiveUserWithSubscribers($appUserId);
|
||||||
|
|
||||||
if (!$serviceUser) {
|
if (!$serviceUser) {
|
||||||
$this->logger->info('Service user not found');
|
$this->logger->critical('Service user not found or marked as removed');
|
||||||
// @todo Retrieving user
|
// @todo Retrieving user
|
||||||
|
|
||||||
throw new \RuntimeException('Service user not found in the database');
|
throw new \RuntimeException('Service user not found in the database');
|
||||||
|
@ -239,6 +247,10 @@ class UpdateSubscriptionsCommand extends ContainerAwareCommand
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$usersForUpdate = $this->api->getUserSubscribersById($appUserId);
|
$usersForUpdate = $this->api->getUserSubscribersById($appUserId);
|
||||||
|
} catch (UserNotFoundException $e) {
|
||||||
|
$this->logger->critical('Service user deleted or API response is invalid');
|
||||||
|
|
||||||
|
throw $e;
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
$this->logger->warning(
|
$this->logger->warning(
|
||||||
'Error while getting service subscribers. Fallback to local list.',
|
'Error while getting service subscribers. Fallback to local list.',
|
||||||
|
@ -251,8 +263,6 @@ class UpdateSubscriptionsCommand extends ContainerAwareCommand
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
$usersForUpdate = [];
|
|
||||||
|
|
||||||
/** @var Subscription $subscription */
|
/** @var Subscription $subscription */
|
||||||
foreach ((array) $serviceUser->getSubscribers() as $subscription) {
|
foreach ((array) $serviceUser->getSubscribers() as $subscription) {
|
||||||
$usersForUpdate[] = $subscription->getSubscriber();
|
$usersForUpdate[] = $subscription->getSubscriber();
|
||||||
|
|
|
@ -27,9 +27,7 @@ class LoadUserData extends AbstractFixture implements OrderedFixtureInterface
|
||||||
$userId = 99999;
|
$userId = 99999;
|
||||||
|
|
||||||
foreach ($this->users as $userData) {
|
foreach ($this->users as $userData) {
|
||||||
$user = (new User($userId--, $userData['login'], $userData['name']))
|
$user = new User($userId--, new \DateTime(), $userData['login'], $userData['name']);
|
||||||
->setCreatedAt(new \DateTime())
|
|
||||||
;
|
|
||||||
|
|
||||||
$om->persist($user);
|
$om->persist($user);
|
||||||
|
|
||||||
|
|
|
@ -68,17 +68,25 @@ class User
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var ArrayCollection|SubscriptionEvent[]
|
* @var ArrayCollection|SubscriptionEvent[]
|
||||||
|
*
|
||||||
* @ORM\OneToMany(targetEntity="SubscriptionEvent", mappedBy="author", fetch="EXTRA_LAZY")
|
* @ORM\OneToMany(targetEntity="SubscriptionEvent", mappedBy="author", fetch="EXTRA_LAZY")
|
||||||
*/
|
*/
|
||||||
private $newSubscriberEvents;
|
private $newSubscriberEvents;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var bool
|
||||||
|
*
|
||||||
|
* @ORM\Column(name="is_removed", type="boolean", options={"default": false})
|
||||||
|
*/
|
||||||
|
private $removed = false;
|
||||||
|
|
||||||
public function __construct(int $id, string $login = null, string $name = null)
|
|
||||||
|
public function __construct(int $id, \DateTime $createdAt = null, string $login = null, string $name = null)
|
||||||
{
|
{
|
||||||
$this->id = $id;
|
$this->id = $id;
|
||||||
$this->login = $login;
|
$this->login = $login;
|
||||||
$this->name = $name;
|
$this->name = $name;
|
||||||
$this->createdAt = new \DateTime();
|
$this->createdAt = $createdAt ?: new \DateTime();
|
||||||
|
|
||||||
$this->subscribers = new ArrayCollection();
|
$this->subscribers = new ArrayCollection();
|
||||||
$this->subscriptions = new ArrayCollection();
|
$this->subscriptions = new ArrayCollection();
|
||||||
|
@ -98,30 +106,25 @@ class User
|
||||||
return $this->id;
|
return $this->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setLogin(string $login): self
|
|
||||||
{
|
|
||||||
$this->login = $login;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getLogin(): string
|
public function getLogin(): string
|
||||||
{
|
{
|
||||||
return $this->login;
|
return $this->login;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setName(?string $name): self
|
|
||||||
{
|
|
||||||
$this->name = $name;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getName(): ?string
|
public function getName(): ?string
|
||||||
{
|
{
|
||||||
return $this->name;
|
return $this->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function updateLoginAndName(string $login, ?string $name): self
|
||||||
|
{
|
||||||
|
$this->login = $login;
|
||||||
|
$this->name = $name;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function addSubscriber(Subscription $subscribers): self
|
public function addSubscriber(Subscription $subscribers): self
|
||||||
{
|
{
|
||||||
$this->subscribers[] = $subscribers;
|
$this->subscribers[] = $subscribers;
|
||||||
|
@ -170,15 +173,18 @@ class User
|
||||||
return $this->createdAt;
|
return $this->createdAt;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setCreatedAt(\DateTime $createdAt): self
|
|
||||||
{
|
|
||||||
$this->createdAt = $createdAt;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getUpdatedAt(): ?\DateTime
|
public function getUpdatedAt(): ?\DateTime
|
||||||
{
|
{
|
||||||
return $this->updatedAt;
|
return $this->updatedAt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function isRemoved(): bool
|
||||||
|
{
|
||||||
|
return $this->isRemoved();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function markAsRemoved(): void
|
||||||
|
{
|
||||||
|
$this->removed = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,22 @@ class UserRepository extends EntityRepository
|
||||||
$this->getEntityManager()->persist($entity);
|
$this->getEntityManager()->persist($entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function findActiveUserWithSubscribers(int $id): ?User
|
||||||
|
{
|
||||||
|
$qb = $this->createQueryBuilder('u');
|
||||||
|
|
||||||
|
// May be optimize hydration procedure
|
||||||
|
return $qb
|
||||||
|
->select(['u', 's', 'us'])
|
||||||
|
->innerJoin('u.subscribers', 's')
|
||||||
|
->innerJoin('s.subscriber', 'us')
|
||||||
|
->where('u.id = :id')
|
||||||
|
->where('u.removed = FALSE')
|
||||||
|
->setParameter('id', $id)
|
||||||
|
->getQuery()->getOneOrNullResult()
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Case-insensitive user search
|
* Case-insensitive user search
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -51,22 +51,6 @@ class AbstractApi
|
||||||
$this->logger = $logger;
|
$this->logger = $logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Make GET request and return response body
|
|
||||||
*/
|
|
||||||
public function getGetResponseBody($path, array $parameters = []): StreamInterface
|
|
||||||
{
|
|
||||||
return $this->sendGetRequest($path, $parameters)->getBody();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Make POST request and return response body
|
|
||||||
*/
|
|
||||||
public function getPostResponseBody(string $path, array $parameters = []): StreamInterface
|
|
||||||
{
|
|
||||||
return $this->sendPostRequest($path, $parameters)->getBody();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make GET request and return DTO objects
|
* Make GET request and return DTO objects
|
||||||
*
|
*
|
||||||
|
@ -97,6 +81,22 @@ class AbstractApi
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make GET request and return response body
|
||||||
|
*/
|
||||||
|
public function getGetResponseBody($path, array $parameters = []): StreamInterface
|
||||||
|
{
|
||||||
|
return $this->sendGetRequest($path, $parameters)->getBody();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make POST request and return response body
|
||||||
|
*/
|
||||||
|
public function getPostResponseBody(string $path, array $parameters = []): StreamInterface
|
||||||
|
{
|
||||||
|
return $this->sendPostRequest($path, $parameters)->getBody();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $path Request path
|
* @param string $path Request path
|
||||||
* @param array $parameters Key => Value array of query parameters
|
* @param array $parameters Key => Value array of query parameters
|
||||||
|
@ -151,6 +151,12 @@ class AbstractApi
|
||||||
$code = $response->getStatusCode();
|
$code = $response->getStatusCode();
|
||||||
$reason = $response->getReasonPhrase();
|
$reason = $response->getReasonPhrase();
|
||||||
|
|
||||||
|
// @todo remove after fix
|
||||||
|
// Temporary fix until @arts fixes this bug
|
||||||
|
if ('{"error": "UserNotFound"}' === (string) $response->getBody()) {
|
||||||
|
throw new NotFoundException($reason, $code);
|
||||||
|
}
|
||||||
|
|
||||||
switch ($code) {
|
switch ($code) {
|
||||||
case SymfonyResponse::HTTP_UNAUTHORIZED:
|
case SymfonyResponse::HTTP_UNAUTHORIZED:
|
||||||
throw new UnauthorizedException($reason, $code);
|
throw new UnauthorizedException($reason, $code);
|
||||||
|
|
|
@ -39,16 +39,14 @@ class UserFactory extends AbstractFactory
|
||||||
|
|
||||||
/** @var User $user */
|
/** @var User $user */
|
||||||
if (null === ($user = $this->userRepository->find($userData->getId()))) {
|
if (null === ($user = $this->userRepository->find($userData->getId()))) {
|
||||||
// Creating new user
|
$user = new User(
|
||||||
$user = new User($userData->getId());
|
$userData->getId(),
|
||||||
|
\DateTime::createFromFormat('Y-m-d_H:i:s', $userData->getCreated()) ?: new \DateTime()
|
||||||
|
);
|
||||||
$this->userRepository->add($user);
|
$this->userRepository->add($user);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Updating data
|
$user->updateLoginAndName($userData->getLogin(), $userData->getName());
|
||||||
$user
|
|
||||||
->setLogin($userData->getLogin())
|
|
||||||
->setName($userData->getName())
|
|
||||||
;
|
|
||||||
|
|
||||||
return $user;
|
return $user;
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,6 +52,7 @@ class SubscriptionsManager
|
||||||
*/
|
*/
|
||||||
public function updateUserSubscribers(User $user, $newSubscribersList = []): void
|
public function updateUserSubscribers(User $user, $newSubscribersList = []): void
|
||||||
{
|
{
|
||||||
|
// @todo optimize
|
||||||
$tmpOldSubscribers = $user->getSubscribers();
|
$tmpOldSubscribers = $user->getSubscribers();
|
||||||
|
|
||||||
$oldSubscribersList = [];
|
$oldSubscribersList = [];
|
||||||
|
|
|
@ -14,15 +14,15 @@ class UserSubscribersUpdatedEventTest extends \PHPUnit_Framework_TestCase
|
||||||
|
|
||||||
public function testCreate()
|
public function testCreate()
|
||||||
{
|
{
|
||||||
$user = new User(99999, 'testuser', 'Test User 1');
|
$user = new User(99999, new \DateTime(), 'testuser', 'Test User 1');
|
||||||
|
|
||||||
$subscribed = [
|
$subscribed = [
|
||||||
new User(99998, 'testuser2', 'Test User 2'),
|
new User(99998, new \DateTime(), 'testuser2', 'Test User 2'),
|
||||||
];
|
];
|
||||||
|
|
||||||
$unsubscribed = [
|
$unsubscribed = [
|
||||||
new User(99997, 'testuser3', 'Test User 3'),
|
new User(99997, new \DateTime(), 'testuser3', 'Test User 3'),
|
||||||
new User(99996, 'testuser4', 'Test User 4'),
|
new User(99996, new \DateTime(), 'testuser4', 'Test User 4'),
|
||||||
];
|
];
|
||||||
|
|
||||||
return new UserSubscribersUpdatedEvent($user, $subscribed, $unsubscribed);
|
return new UserSubscribersUpdatedEvent($user, $subscribed, $unsubscribed);
|
||||||
|
|
|
@ -15,7 +15,7 @@ class UsersRenamedEventTest extends \PHPUnit_Framework_TestCase
|
||||||
|
|
||||||
public function testGetRenames()
|
public function testGetRenames()
|
||||||
{
|
{
|
||||||
$user = new User(99999, 'testuser', 'Test User 1');
|
$user = new User(99999, new \DateTime(), 'testuser', 'Test User 1');
|
||||||
$renameRecords = [
|
$renameRecords = [
|
||||||
new UserRenameEvent($user, 'testuser_old1'),
|
new UserRenameEvent($user, 'testuser_old1'),
|
||||||
new UserRenameEvent($user, 'testuser_old2'),
|
new UserRenameEvent($user, 'testuser_old2'),
|
||||||
|
|
Loading…
Reference in a new issue