Skip to content

Commit dec2c2c

Browse files
committed
minor #200 Add UserManager::findUserByUsername() (phansys)
This PR was merged into the 3.x branch. Discussion ---------- |Q |A | |--- |---| |Branch |3.x| |Bug fix? |no | |New feature? |yes| |BC breaks? |no | |Deprecations?|no | |Tests pass? |yes| |Fixed tickets|n/a| |License |MIT| |Doc PR |n/a| Commits ------- 5fd2771 Add `UserManager::findUserByUsername()`
2 parents 947b764 + 5fd2771 commit dec2c2c

File tree

10 files changed

+159
-34
lines changed

10 files changed

+159
-34
lines changed

Command/AutoClosingCommand.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
*/
2525
class AutoClosingCommand extends ContainerAwareCommand
2626
{
27-
use UserManagerTrait;
27+
use UserManagerAwareTrait;
2828

2929
protected static $defaultName = 'ticket:autoclosing';
3030

Command/TicketManagerCommand.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
*/
2424
class TicketManagerCommand extends ContainerAwareCommand
2525
{
26-
use UserManagerTrait;
26+
use UserManagerAwareTrait;
2727

2828
protected static $defaultName = 'ticket:create';
2929

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,29 +11,28 @@
1111

1212
namespace Hackzilla\Bundle\TicketBundle\Command;
1313

14-
use Doctrine\Persistence\ObjectRepository;
14+
use Hackzilla\Bundle\TicketBundle\Manager\UserManagerInterface;
1515
use Hackzilla\Bundle\TicketBundle\Model\UserInterface;
1616

1717
/**
18-
* NEXT_MAJOR: Inject the object repository and the user class directly in the command
19-
* classes and remove this trait.
18+
* NEXT_MAJOR: Inject the user manager directly in the command classes and remove this trait.
2019
*
2120
* @author Javier Spagnoletti <[email protected]>
2221
*/
23-
trait UserManagerTrait
22+
trait UserManagerAwareTrait
2423
{
2524
/**
26-
* @var ObjectRepository
25+
* @var UserManagerInterface
2726
*/
28-
private $userRepository;
27+
private $userManager;
2928

30-
public function __construct(string $name = null, ?ObjectRepository $userRepository = null)
29+
public function __construct(string $name = null, ?UserManagerInterface $userManager = null)
3130
{
3231
parent::__construct($name);
3332

34-
$this->userRepository = $userRepository;
33+
$this->userManager = $userManager;
3534

36-
if (null === $userRepository) {
35+
if (null === $userManager) {
3736
@trigger_error(sprintf(
3837
'Omitting or passing null as argument 2 for "%s()" is deprecated since hackzilla/ticket-bundle 3.x.',
3938
__METHOD__
@@ -43,8 +42,8 @@ public function __construct(string $name = null, ?ObjectRepository $userReposito
4342

4443
private function findUser(string $username): ?UserInterface
4544
{
46-
if (null !== $this->userRepository) {
47-
return $this->userRepository->findBy(['username' => $username]);
45+
if (null !== $this->userManager) {
46+
return $this->userManager->findUserByUsername($username);
4847
}
4948

5049
if (!$this->getContainer()->has('fos_user.user_manager')) {

EventListener/UserLoad.php

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Hackzilla\Bundle\TicketBundle\EventListener;
1313

1414
use Doctrine\ORM\Event\LifecycleEventArgs;
15+
use Hackzilla\Bundle\TicketBundle\Manager\UserManagerInterface;
1516
use Hackzilla\Bundle\TicketBundle\Model\TicketInterface;
1617
use Hackzilla\Bundle\TicketBundle\Model\TicketMessageInterface;
1718

@@ -20,11 +21,14 @@
2021
*/
2122
class UserLoad
2223
{
23-
protected $userRepository;
24+
/**
25+
* @var UserManagerInterface
26+
*/
27+
protected $userManager;
2428

25-
public function __construct($userRepository)
29+
public function __construct(UserManagerInterface $userManager)
2630
{
27-
$this->userRepository = $userRepository;
31+
$this->userManager = $userManager;
2832
}
2933

3034
public function getSubscribedEvents()
@@ -38,23 +42,21 @@ public function postLoad(LifecycleEventArgs $args)
3842
{
3943
$entity = $args->getEntity();
4044

41-
// Ignore any entity lifecycle events not relating to this bundles entities.
45+
// Ignore any entity lifecycle events not related to this bundle's entities.
4246
if (!$entity instanceof TicketInterface && !$entity instanceof TicketMessageInterface) {
4347
return;
4448
}
4549

46-
$userRepository = $args->getEntityManager()->getRepository($this->userRepository);
47-
4850
if ($entity instanceof TicketInterface) {
4951
if (null === $entity->getUserCreatedObject()) {
50-
$entity->setUserCreated($userRepository->find($entity->getUserCreated()));
52+
$entity->setUserCreated($this->userManager->getUserById($entity->getUserCreated()));
5153
}
5254
if (null === $entity->getLastUserObject()) {
53-
$entity->setLastUser($userRepository->find($entity->getLastUser()));
55+
$entity->setLastUser($this->userManager->getUserById($entity->getLastUser()));
5456
}
5557
} elseif ($entity instanceof TicketMessageInterface) {
5658
if (null === $entity->getUserObject()) {
57-
$entity->setUser($userRepository->find($entity->getUser()));
59+
$entity->setUser($this->userManager->getUserById($entity->getUser()));
5860
}
5961
}
6062
}

Manager/UserManager.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,15 @@ public function __construct(
4545
AuthorizationCheckerInterface $authorizationChecker
4646
) {
4747
$this->tokenStorage = $tokenStorage;
48+
49+
if (!is_subclass_of($userRepository->getClassName(), UserInterface::class)) {
50+
throw new \InvalidArgumentException(sprintf(
51+
'Argument 2 passed to "%s()" MUST be an object repository for a class implementing "%s".',
52+
__METHOD__,
53+
UserInterface::class
54+
));
55+
}
56+
4857
$this->userRepository = $userRepository;
4958
$this->authorizationChecker = $authorizationChecker;
5059
}
@@ -58,6 +67,11 @@ public function getCurrentUser()
5867

5968
if ('anon.' === $user) {
6069
$user = 0;
70+
} elseif (!$user instanceof UserInterface) {
71+
throw new \LogicException(sprintf(
72+
'The object representing the authenticated user MUST implement "%s".',
73+
UserInterface::class
74+
));
6175
}
6276

6377
return $user;
@@ -100,4 +114,9 @@ public function hasPermission($user, TicketInterface $ticket)
100114
throw new AccessDeniedHttpException();
101115
}
102116
}
117+
118+
public function findUserByUsername(string $username): ?UserInterface
119+
{
120+
return $this->userRepository->findOneBy(['username' => $username]);
121+
}
103122
}

Manager/UserManagerInterface.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414
use Hackzilla\Bundle\TicketBundle\Model\TicketInterface;
1515
use Hackzilla\Bundle\TicketBundle\Model\UserInterface;
1616

17+
/**
18+
* @method ?UserInterface findUserByUsername(string $username)
19+
*/
1720
interface UserManagerInterface
1821
{
1922
public function getCurrentUser();
@@ -26,4 +29,7 @@ public function hasRole(UserInterface $user, $role);
2629
* @param \Hackzilla\Bundle\TicketBundle\Model\UserInterface|string $user
2730
*/
2831
public function hasPermission($user, TicketInterface $ticket);
32+
33+
// NEXT_MAJOR: Uncomment this method.
34+
// public function findUserByUsername(string $username): ?UserInterface;
2935
}

Resources/config/services.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,14 +75,14 @@ services:
7575
class: Hackzilla\Bundle\TicketBundle\Command\AutoClosingCommand
7676
arguments:
7777
- null
78-
- '@hackzilla_ticket.user_repository'
78+
- '@hackzilla_ticket.user_manager'
7979
tags:
8080
- { name: console.command, command: 'ticket:autoclosing' }
8181

8282
hackzilla_ticket.command.create:
8383
class: Hackzilla\Bundle\TicketBundle\Command\TicketManagerCommand
8484
arguments:
8585
- null
86-
- '@hackzilla_ticket.user_repository'
86+
- '@hackzilla_ticket.user_manager'
8787
tags:
8888
- { name: console.command, command: 'ticket:create' }

Tests/EventListener/UserLoadTest.php

Lines changed: 100 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,33 +11,126 @@
1111

1212
namespace Hackzilla\Bundle\TicketBundle\Tests\EventListener;
1313

14+
use Doctrine\ORM\Event\LifecycleEventArgs;
15+
use Doctrine\Persistence\ObjectManager;
16+
use Hackzilla\Bundle\TicketBundle\Entity\Ticket;
17+
use Hackzilla\Bundle\TicketBundle\Entity\TicketMessage;
1418
use Hackzilla\Bundle\TicketBundle\EventListener\UserLoad;
1519
use Hackzilla\Bundle\TicketBundle\Manager\UserManager;
20+
use Hackzilla\Bundle\TicketBundle\Model\UserInterface;
21+
use Hackzilla\Bundle\TicketBundle\Tests\Functional\Entity\User;
22+
use PHPUnit\Framework\MockObject\MockObject;
1623
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
1724

1825
final class UserLoadTest extends WebTestCase
1926
{
20-
private $object;
27+
private const USER_CREATED_ID = 42;
28+
private const LAST_USER_ID = 43;
29+
private const USER_MESSAGE_ID = 44;
30+
31+
/**
32+
* @var UserLoad
33+
*/
34+
private $userLoad;
35+
36+
/**
37+
* @var UserInterface
38+
*/
39+
private $userCreated;
40+
41+
/**
42+
* @var UserInterface
43+
*/
44+
private $lastUser;
45+
46+
/**
47+
* @var UserInterface
48+
*/
49+
private $userMessage;
2150

2251
protected function setUp(): void
2352
{
53+
$this->userCreated = new User();
54+
$this->lastUser = new User();
55+
$this->userMessage = new User();
56+
57+
(\Closure::bind(function ($id): void {
58+
$this->id = $id;
59+
}, $this->userCreated, User::class))(self::USER_CREATED_ID);
60+
61+
(\Closure::bind(function ($id): void {
62+
$this->id = $id;
63+
}, $this->lastUser, User::class))(self::LAST_USER_ID);
64+
65+
(\Closure::bind(function ($id): void {
66+
$this->id = $id;
67+
}, $this->userMessage, User::class))(self::USER_MESSAGE_ID);
68+
2469
$userManager = $this->getUserManagerMock();
2570

26-
$this->object = new UserLoad($userManager);
71+
$this->userLoad = new UserLoad($userManager);
2772
}
2873

2974
protected function tearDown(): void
3075
{
31-
$this->object = null;
76+
$this->userCreated = null;
77+
$this->lastUser = null;
78+
$this->userMessage = null;
79+
$this->userLoad = null;
3280
}
3381

34-
public function getUserManagerMock()
82+
public function testObjectCreated(): void
3583
{
36-
return $this->createMock(UserManager::class);
84+
$this->assertInstanceOf(UserLoad::class, $this->userLoad);
3785
}
3886

39-
public function testObjectCreated()
87+
public function testPostLoad(): void
4088
{
41-
$this->assertInstanceOf(UserLoad::class, $this->object);
89+
$objectManager = $this->createStub(ObjectManager::class);
90+
91+
$ticket = new Ticket();
92+
$ticket->setUserCreated(self::USER_CREATED_ID);
93+
$ticket->setLastUser(self::LAST_USER_ID);
94+
95+
$this->assertNull($ticket->getUserCreatedObject());
96+
$this->assertNull($ticket->getLastUserObject());
97+
98+
$this->userLoad->postLoad(new LifecycleEventArgs($ticket, $objectManager));
99+
100+
$this->assertSame($this->userCreated, $ticket->getUserCreatedObject());
101+
$this->assertSame($this->lastUser, $ticket->getLastUserObject());
102+
103+
$message = new TicketMessage();
104+
$message->setUser(self::USER_MESSAGE_ID);
105+
106+
$this->assertNull($message->getUserObject());
107+
108+
$this->userLoad->postLoad(new LifecycleEventArgs($message, $objectManager));
109+
110+
$this->assertSame($this->userMessage, $message->getUserObject());
111+
}
112+
113+
private function getUserManagerMock(): MockObject
114+
{
115+
$userManager = $this->createMock(UserManager::class);
116+
$userManager
117+
->method('getUserById')
118+
->willReturnCallback(function ($userId): ?UserInterface {
119+
if ($userId === $this->userCreated->getId()) {
120+
return $this->userCreated;
121+
}
122+
123+
if ($userId === $this->lastUser->getId()) {
124+
return $this->lastUser;
125+
}
126+
127+
if ($userId === $this->userMessage->getId()) {
128+
return $this->userMessage;
129+
}
130+
131+
return null;
132+
});
133+
134+
return $userManager;
42135
}
43136
}

Tests/Manager/TicketManagerTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
* file that was distributed with this source code.
1010
*/
1111

12-
namespace Hackzilla\Bundle\TicketBundle\Tests\User;
12+
namespace Hackzilla\Bundle\TicketBundle\Tests\Manager;
1313

1414
use Doctrine\ORM\EntityRepository;
1515
use Doctrine\ORM\QueryBuilder;

Tests/Manager/UserManagerTest.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,11 @@
99
* file that was distributed with this source code.
1010
*/
1111

12-
namespace Hackzilla\Bundle\TicketBundle\Tests\User;
12+
namespace Hackzilla\Bundle\TicketBundle\Tests\Manager;
1313

1414
use Doctrine\ORM\EntityRepository;
1515
use Hackzilla\Bundle\TicketBundle\Manager\UserManager;
16+
use Hackzilla\Bundle\TicketBundle\Tests\Functional\Entity\User;
1617
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
1718
use Symfony\Component\Security\Core\Authentication\AuthenticationProviderManager;
1819
use Symfony\Component\Security\Core\Authentication\Provider\AnonymousAuthenticationProvider;
@@ -54,6 +55,11 @@ public function testObjectCreated()
5455

5556
private function getMockUserRepository()
5657
{
57-
return $this->createMock(EntityRepository::class);
58+
$userRepository = $this->createMock(EntityRepository::class);
59+
$userRepository
60+
->method('getClassName')
61+
->willReturn(User::class);
62+
63+
return $userRepository;
5864
}
5965
}

0 commit comments

Comments
 (0)