Telegram notifications on user subscribers list changes. Some refactoring of SubscriptionsManager and event system.
This commit is contained in:
parent
9488eddd9f
commit
88be9e99ae
|
@ -0,0 +1,66 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Skobkin\Bundle\PointToolsBundle\Event;
|
||||||
|
|
||||||
|
use Skobkin\Bundle\PointToolsBundle\Entity\User;
|
||||||
|
use Symfony\Component\EventDispatcher\Event;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispatched when user subscribers list was changed
|
||||||
|
*/
|
||||||
|
class UserSubscribersUpdatedEvent extends Event
|
||||||
|
{
|
||||||
|
const NAME = 'app.user.subscribers_updated';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var User
|
||||||
|
*/
|
||||||
|
private $user;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var User[]
|
||||||
|
*/
|
||||||
|
private $subscribed;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var User[]
|
||||||
|
*/
|
||||||
|
private $unsubscribed;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UserSubscribersUpdatedEvent constructor.
|
||||||
|
*
|
||||||
|
* @param User[] $subscribed
|
||||||
|
* @param User[] $unsubscribed
|
||||||
|
*/
|
||||||
|
public function __construct(User $user, array $subscribed, array $unsubscribed)
|
||||||
|
{
|
||||||
|
$this->user = $user;
|
||||||
|
$this->subscribed = $subscribed;
|
||||||
|
$this->unsubscribed = $unsubscribed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return User
|
||||||
|
*/
|
||||||
|
public function getUser(): User
|
||||||
|
{
|
||||||
|
return $this->user;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return User[]
|
||||||
|
*/
|
||||||
|
public function getSubscribedUsers(): array
|
||||||
|
{
|
||||||
|
return $this->subscribed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return User[]
|
||||||
|
*/
|
||||||
|
public function getUnsubscribedUsers(): array
|
||||||
|
{
|
||||||
|
return $this->unsubscribed;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Skobkin\Bundle\PointToolsBundle\EventListener;
|
||||||
|
|
||||||
|
use Skobkin\Bundle\PointToolsBundle\Event\UserSubscribersUpdatedEvent;
|
||||||
|
use Skobkin\Bundle\PointToolsBundle\Service\Telegram\Notifier;
|
||||||
|
|
||||||
|
class UserSubscribersUpdatedListener
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var Notifier
|
||||||
|
*/
|
||||||
|
private $notifier;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UsersRenameNotifierListener constructor.
|
||||||
|
*
|
||||||
|
* @param Notifier $notifier
|
||||||
|
*/
|
||||||
|
public function __construct(Notifier $notifier)
|
||||||
|
{
|
||||||
|
$this->notifier = $notifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onAppUserSubscribersUpdated(UserSubscribersUpdatedEvent $event)
|
||||||
|
{
|
||||||
|
$this->notifier->sendUserSubscribersUpdatedNotification($event->getUser(), $event->getSubscribedUsers(), $event->getUnsubscribedUsers());
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,7 +5,7 @@ namespace Skobkin\Bundle\PointToolsBundle\EventListener;
|
||||||
use Skobkin\Bundle\PointToolsBundle\Event\UsersRenamedEvent;
|
use Skobkin\Bundle\PointToolsBundle\Event\UsersRenamedEvent;
|
||||||
use Skobkin\Bundle\PointToolsBundle\Service\Telegram\Notifier;
|
use Skobkin\Bundle\PointToolsBundle\Service\Telegram\Notifier;
|
||||||
|
|
||||||
class UsersRenamedNotifierListener
|
class UsersRenamedListener
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var Notifier
|
* @var Notifier
|
|
@ -3,14 +3,16 @@
|
||||||
namespace Skobkin\Bundle\PointToolsBundle\Repository;
|
namespace Skobkin\Bundle\PointToolsBundle\Repository;
|
||||||
|
|
||||||
use Doctrine\ORM\EntityRepository;
|
use Doctrine\ORM\EntityRepository;
|
||||||
|
use Skobkin\Bundle\PointToolsBundle\Entity\User;
|
||||||
|
|
||||||
class SubscriptionRepository extends EntityRepository
|
class SubscriptionRepository extends EntityRepository
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @param integer $id
|
* @param int $id
|
||||||
* @return integer
|
*
|
||||||
|
* @return int
|
||||||
*/
|
*/
|
||||||
public function getUserSubscribersCountById($id)
|
public function getUserSubscribersCountById($id): int
|
||||||
{
|
{
|
||||||
if (!is_int($id)) {
|
if (!is_int($id)) {
|
||||||
throw new \InvalidArgumentException('$id must be an integer');
|
throw new \InvalidArgumentException('$id must be an integer');
|
||||||
|
@ -25,4 +27,21 @@ class SubscriptionRepository extends EntityRepository
|
||||||
->getQuery()->getSingleScalarResult()
|
->getQuery()->getSingleScalarResult()
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param User $user
|
||||||
|
* @param User[] $subscribers
|
||||||
|
*/
|
||||||
|
public function removeSubscribers(User $user, array $subscribers)
|
||||||
|
{
|
||||||
|
$qb = $this->createQueryBuilder('s');
|
||||||
|
$qb
|
||||||
|
->delete()
|
||||||
|
->where('s.author = :author')
|
||||||
|
->andWhere('s.subscriber IN (:subscribers)')
|
||||||
|
->setParameter('author', $user->getId())
|
||||||
|
->setParameter('subscribers', $subscribers)
|
||||||
|
->getQuery()->execute();
|
||||||
|
;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -35,7 +35,7 @@ services:
|
||||||
|
|
||||||
skobkin_point_tools.subscriptions_manager:
|
skobkin_point_tools.subscriptions_manager:
|
||||||
class: Skobkin\Bundle\PointToolsBundle\Service\SubscriptionsManager
|
class: Skobkin\Bundle\PointToolsBundle\Service\SubscriptionsManager
|
||||||
arguments: [ @doctrine.orm.entity_manager ]
|
arguments: [ @doctrine.orm.entity_manager, @event_dispatcher ]
|
||||||
|
|
||||||
|
|
||||||
# Factories
|
# Factories
|
||||||
|
@ -92,11 +92,17 @@ services:
|
||||||
- { name: doctrine.event_subscriber, connection: default }
|
- { name: doctrine.event_subscriber, connection: default }
|
||||||
|
|
||||||
point_tools.event_listener.users_renamed_notifier:
|
point_tools.event_listener.users_renamed_notifier:
|
||||||
class: Skobkin\Bundle\PointToolsBundle\EventListener\UsersRenamedNotifierListener
|
class: Skobkin\Bundle\PointToolsBundle\EventListener\UsersRenamedListener
|
||||||
arguments: [@point_tools.telegram.notifier]
|
arguments: [@point_tools.telegram.notifier]
|
||||||
tags:
|
tags:
|
||||||
- { name: kernel.event_listener, event: app.users.renamed }
|
- { name: kernel.event_listener, event: app.users.renamed }
|
||||||
|
|
||||||
|
point_tools.event_listener.user_subscribers_updated:
|
||||||
|
class: Skobkin\Bundle\PointToolsBundle\EventListener\UserSubscribersUpdatedListener
|
||||||
|
arguments: [@point_tools.telegram.notifier]
|
||||||
|
tags:
|
||||||
|
- { name: kernel.event_listener, event: app.user.subscribers_updated }
|
||||||
|
|
||||||
|
|
||||||
# Twig extensions
|
# Twig extensions
|
||||||
point_tools.twig.point_avatar_extension:
|
point_tools.twig.point_avatar_extension:
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
{# @var subscribed \Skobkin\Bundle\PointToolsBundle\Entity\User[] #}
|
||||||
|
{# @var unsubscribed \Skobkin\Bundle\PointToolsBundle\Entity\User[] #}
|
||||||
|
*Subscribers list changed:*
|
||||||
|
|
||||||
|
{% if subscribed|length > 0 %}
|
||||||
|
New subscribers:
|
||||||
|
{% for subscriber in subscribed %}
|
||||||
|
[@{{ subscriber.login }}]({{ subscriber.login|point_user_url(true) }})
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{% if unsubscribed|length > 0 %}
|
||||||
|
|
||||||
|
Lost subscribers:
|
||||||
|
{% for subscriber in unsubscribed %}
|
||||||
|
[@{{ subscriber.login }}]({{ subscriber.login|point_user_url(true) }})
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{# @todo remove hardcoded URL #}
|
||||||
|
See full subscribers history on [Point Tools](https://point.skobk.in{{ path('user_show', {'login': user.login}) }}) site.
|
|
@ -3,28 +3,34 @@
|
||||||
namespace Skobkin\Bundle\PointToolsBundle\Service;
|
namespace Skobkin\Bundle\PointToolsBundle\Service;
|
||||||
|
|
||||||
use Doctrine\ORM\EntityManager;
|
use Doctrine\ORM\EntityManager;
|
||||||
use Doctrine\ORM\QueryBuilder;
|
|
||||||
use Skobkin\Bundle\PointToolsBundle\Entity\Subscription;
|
use Skobkin\Bundle\PointToolsBundle\Entity\Subscription;
|
||||||
use Skobkin\Bundle\PointToolsBundle\Entity\SubscriptionEvent;
|
use Skobkin\Bundle\PointToolsBundle\Entity\SubscriptionEvent;
|
||||||
use Skobkin\Bundle\PointToolsBundle\Entity\User;
|
use Skobkin\Bundle\PointToolsBundle\Entity\User;
|
||||||
|
use Skobkin\Bundle\PointToolsBundle\Event\UserSubscribersUpdatedEvent;
|
||||||
|
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||||
|
|
||||||
class SubscriptionsManager
|
class SubscriptionsManager
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var EntityManager
|
* @var EntityManager
|
||||||
*/
|
*/
|
||||||
protected $em;
|
private $em;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var EventDispatcherInterface
|
||||||
|
*/
|
||||||
|
private $eventDispatcher;
|
||||||
|
|
||||||
|
|
||||||
// @todo Add logger
|
public function __construct(EntityManager $entityManager, EventDispatcherInterface $eventDispatcher)
|
||||||
public function __construct(EntityManager $entityManager)
|
|
||||||
{
|
{
|
||||||
$this->em = $entityManager;
|
$this->em = $entityManager;
|
||||||
|
$this->eventDispatcher = $eventDispatcher;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param User $user
|
* @param User $user
|
||||||
* @param User[]|array $newSubscribersList
|
* @param User[] $newSubscribersList
|
||||||
*/
|
*/
|
||||||
public function updateUserSubscribers(User $user, $newSubscribersList = [])
|
public function updateUserSubscribers(User $user, $newSubscribersList = [])
|
||||||
{
|
{
|
||||||
|
@ -37,6 +43,7 @@ class SubscriptionsManager
|
||||||
$oldSubscribersList[] = $subscription->getSubscriber();
|
$oldSubscribersList[] = $subscription->getSubscriber();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @todo remove
|
||||||
$isFirstTime = false;
|
$isFirstTime = false;
|
||||||
|
|
||||||
// Preventing to add garbage subscriptions for first processing
|
// Preventing to add garbage subscriptions for first processing
|
||||||
|
@ -66,16 +73,6 @@ class SubscriptionsManager
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unset($subscribedList);
|
|
||||||
|
|
||||||
/** @var QueryBuilder $unsubscribedQuery */
|
|
||||||
$unsubscribedQuery = $this->em->getRepository('SkobkinPointToolsBundle:Subscription')->createQueryBuilder('s');
|
|
||||||
$unsubscribedQuery
|
|
||||||
->delete()
|
|
||||||
->where('s.author = :author')
|
|
||||||
->andWhere('s.subscriber IN (:subscribers)')
|
|
||||||
;
|
|
||||||
|
|
||||||
/** @var User $unsubscribedUser */
|
/** @var User $unsubscribedUser */
|
||||||
foreach ($unsubscribedList as $unsubscribedUser) {
|
foreach ($unsubscribedList as $unsubscribedUser) {
|
||||||
$logEvent = new SubscriptionEvent($user, $unsubscribedUser, SubscriptionEvent::ACTION_UNSUBSCRIBE);
|
$logEvent = new SubscriptionEvent($user, $unsubscribedUser, SubscriptionEvent::ACTION_UNSUBSCRIBE);
|
||||||
|
@ -84,13 +81,12 @@ class SubscriptionsManager
|
||||||
$user->addNewSubscriberEvent($logEvent);
|
$user->addNewSubscriberEvent($logEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
$unsubscribedQuery
|
// Removing users from database
|
||||||
->setParameter('author', $user->getId())
|
$this->em->getRepository('SkobkinPointToolsBundle:Subscription')->removeSubscribers($user, $unsubscribedList);
|
||||||
->setParameter('subscribers', $unsubscribedList)
|
|
||||||
->getQuery()->execute();
|
|
||||||
;
|
|
||||||
|
|
||||||
unset($unsubscribedList);
|
// Dispatching event
|
||||||
|
$subscribersUpdatedEvent = new UserSubscribersUpdatedEvent($user, $subscribedList, $unsubscribedList);
|
||||||
|
$this->eventDispatcher->dispatch(UserSubscribersUpdatedEvent::NAME, $subscribersUpdatedEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -4,6 +4,7 @@ namespace Skobkin\Bundle\PointToolsBundle\Service\Telegram;
|
||||||
|
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Doctrine\ORM\EntityRepository;
|
use Doctrine\ORM\EntityRepository;
|
||||||
|
use Skobkin\Bundle\PointToolsBundle\Entity\User;
|
||||||
use Skobkin\Bundle\PointToolsBundle\Entity\UserRenameEvent;
|
use Skobkin\Bundle\PointToolsBundle\Entity\UserRenameEvent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -50,4 +51,35 @@ class Notifier
|
||||||
|
|
||||||
$this->messenger->sendMassTemplatedMessage($accounts, '@SkobkinPointTools/Telegram/users_renamed_notification.md.twig', ['events' => $userRenameEvents]);
|
$this->messenger->sendMassTemplatedMessage($accounts, '@SkobkinPointTools/Telegram/users_renamed_notification.md.twig', ['events' => $userRenameEvents]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send notification about changes in user's subscribers list
|
||||||
|
*
|
||||||
|
* @param User $user
|
||||||
|
* @param array $subscribed
|
||||||
|
* @param array $unsubscribed
|
||||||
|
*/
|
||||||
|
public function sendUserSubscribersUpdatedNotification(User $user, array $subscribed, array $unsubscribed)
|
||||||
|
{
|
||||||
|
$account = $this->accountsRepo->findOneBy(
|
||||||
|
[
|
||||||
|
'user' => $user,
|
||||||
|
'subscriberNotification' => true,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
if (null === $account) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->messenger->sendTemplatedMessage(
|
||||||
|
$account,
|
||||||
|
'@SkobkinPointTools/Telegram/user_subscribers_updated_notification.md.twig',
|
||||||
|
[
|
||||||
|
'user' => $user,
|
||||||
|
'subscribed' => $subscribed,
|
||||||
|
'unsubscribed' => $unsubscribed,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue