|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
namespace Skobkin\Bundle\PointToolsBundle\Service; |
|
4
|
|
|
|
|
5
|
|
|
use Doctrine\ORM\EntityManager; |
|
6
|
|
|
use Skobkin\Bundle\PointToolsBundle\Entity\Subscription; |
|
7
|
|
|
use Skobkin\Bundle\PointToolsBundle\Entity\SubscriptionEvent; |
|
8
|
|
|
use Skobkin\Bundle\PointToolsBundle\Entity\User; |
|
9
|
|
|
use Skobkin\Bundle\PointToolsBundle\Event\UserSubscribersUpdatedEvent; |
|
10
|
|
|
use Symfony\Component\EventDispatcher\EventDispatcherInterface; |
|
11
|
|
|
|
|
12
|
|
|
class SubscriptionsManager |
|
13
|
|
|
{ |
|
14
|
|
|
/** |
|
15
|
|
|
* @var EntityManager |
|
16
|
|
|
*/ |
|
17
|
|
|
private $em; |
|
18
|
|
|
|
|
19
|
|
|
/** |
|
20
|
|
|
* @var EventDispatcherInterface |
|
21
|
|
|
*/ |
|
22
|
|
|
private $eventDispatcher; |
|
23
|
|
|
|
|
24
|
|
|
|
|
25
|
|
|
public function __construct(EntityManager $entityManager, EventDispatcherInterface $eventDispatcher) |
|
|
|
|
|
|
26
|
|
|
{ |
|
27
|
|
|
$this->em = $entityManager; |
|
28
|
|
|
$this->eventDispatcher = $eventDispatcher; |
|
29
|
|
|
} |
|
30
|
|
|
|
|
31
|
|
|
/** |
|
32
|
|
|
* @param User $user |
|
33
|
|
|
* @param User[] $newSubscribersList |
|
34
|
|
|
*/ |
|
35
|
|
|
public function updateUserSubscribers(User $user, $newSubscribersList = []) |
|
36
|
|
|
{ |
|
37
|
|
|
/** @var Subscription[] $tmpOldSubscribers */ |
|
38
|
|
|
$tmpOldSubscribers = $user->getSubscribers(); |
|
39
|
|
|
|
|
40
|
|
|
$oldSubscribersList = []; |
|
41
|
|
|
|
|
42
|
|
|
foreach ($tmpOldSubscribers as $subscription) { |
|
43
|
|
|
$oldSubscribersList[] = $subscription->getSubscriber(); |
|
44
|
|
|
} |
|
45
|
|
|
|
|
46
|
|
|
// @todo remove |
|
47
|
|
|
$isFirstTime = false; |
|
48
|
|
|
|
|
49
|
|
|
// Preventing to add garbage subscriptions for first processing |
|
50
|
|
|
// @todo improve algorithm |
|
51
|
|
|
if ((count($oldSubscribersList) === 0) && (count($newSubscribersList) > 1)) { |
|
52
|
|
|
$isFirstTime = true; |
|
53
|
|
|
} |
|
54
|
|
|
|
|
55
|
|
|
unset($tmpOldSubscribers); |
|
56
|
|
|
|
|
57
|
|
|
$subscribedList = $this->getUsersListsDiff($newSubscribersList, $oldSubscribersList); |
|
58
|
|
|
$unsubscribedList = $this->getUsersListsDiff($oldSubscribersList, $newSubscribersList); |
|
59
|
|
|
|
|
60
|
|
|
/** @var User $subscribedUser */ |
|
61
|
|
|
foreach ($subscribedList as $subscribedUser) { |
|
62
|
|
|
$subscription = new Subscription($user, $subscribedUser); |
|
63
|
|
|
|
|
64
|
|
|
$user->addSubscriber($subscription); |
|
65
|
|
|
$this->em->persist($subscription); |
|
66
|
|
|
|
|
67
|
|
|
// If it's not first processing |
|
68
|
|
|
if (!$isFirstTime) { |
|
69
|
|
|
$logEvent = new SubscriptionEvent($user, $subscribedUser, SubscriptionEvent::ACTION_SUBSCRIBE); |
|
70
|
|
|
$this->em->persist($logEvent); |
|
71
|
|
|
|
|
72
|
|
|
$user->addNewSubscriberEvent($logEvent); |
|
73
|
|
|
} |
|
74
|
|
|
} |
|
75
|
|
|
|
|
76
|
|
|
/** @var User $unsubscribedUser */ |
|
77
|
|
|
foreach ($unsubscribedList as $unsubscribedUser) { |
|
78
|
|
|
$logEvent = new SubscriptionEvent($user, $unsubscribedUser, SubscriptionEvent::ACTION_UNSUBSCRIBE); |
|
79
|
|
|
$this->em->persist($logEvent); |
|
80
|
|
|
|
|
81
|
|
|
$user->addNewSubscriberEvent($logEvent); |
|
82
|
|
|
} |
|
83
|
|
|
|
|
84
|
|
|
// Removing users from database |
|
85
|
|
|
$this->em->getRepository('SkobkinPointToolsBundle:Subscription')->removeSubscribers($user, $unsubscribedList); |
|
86
|
|
|
|
|
87
|
|
|
if (0 !== count($subscribedList) || 0 !== count($unsubscribedList)) { |
|
88
|
|
|
// Dispatching event |
|
89
|
|
|
$subscribersUpdatedEvent = new UserSubscribersUpdatedEvent($user, $subscribedList, $unsubscribedList); |
|
90
|
|
|
$this->eventDispatcher->dispatch(UserSubscribersUpdatedEvent::NAME, $subscribersUpdatedEvent); |
|
91
|
|
|
} |
|
92
|
|
|
} |
|
93
|
|
|
|
|
94
|
|
|
/** |
|
95
|
|
|
* Compares $list1 against $list2 and returns the values in $list1 that are not present in $list2. |
|
96
|
|
|
* |
|
97
|
|
|
* @param User[] $list1 |
|
98
|
|
|
* @param User[] $list2 |
|
99
|
|
|
* |
|
100
|
|
|
* @return User[] Diff |
|
101
|
|
|
*/ |
|
102
|
|
|
public function getUsersListsDiff(array $list1 = [], array $list2 = []) |
|
103
|
|
|
{ |
|
104
|
|
|
$hash1 = []; |
|
105
|
|
|
$hash2 = []; |
|
106
|
|
|
|
|
107
|
|
|
foreach ($list1 as $user) { |
|
108
|
|
|
$hash1[$user->getId()] = $user; |
|
109
|
|
|
} |
|
110
|
|
|
foreach ($list2 as $user) { |
|
111
|
|
|
$hash2[$user->getId()] = $user; |
|
112
|
|
|
} |
|
113
|
|
|
|
|
114
|
|
|
return array_diff_key($hash1, $hash2); |
|
115
|
|
|
} |
|
116
|
|
|
} |
The
EntityManagermight become unusable for example if a transaction is rolled back and it gets closed. Let’s assume that somewhere in your application, or in a third-party library, there is code such as the following:If that code throws an exception and the
EntityManageris closed. Any other code which depends on the same instance of theEntityManagerduring this request will fail.On the other hand, if you instead inject the
ManagerRegistry, thegetManager()method guarantees that you will always get a usable manager instance.