<?php
namespace App\EventSubscriber;
use App\Entity\User;
use App\Entity\JobQueue;
use App\Entity\Newsfeed;
use App\Service\EsCache;
use App\Entity\Container;
use App\Service\EsSocket;
use App\Service\EsJobQueue;
use App\Event\NewsfeedPostUpdateEvent;
use App\Event\NewsfeedPrePersistEvent;
use App\Event\NewsfeedPostPersistEvent;
use Doctrine\ORM\EntityManagerInterface;
use App\Entity\Interfaces\NewsfeedAssetCreatorInterface;
use App\Service\JobQueueAction\SendUserAssignEmailAction;
use App\Service\JobQueueAction\SendCompanyFeedEmailAction;
use App\Service\JobQueueAction\NewsfeedSubscriptionEmailAction;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class NewsfeedSubscriber implements EventSubscriberInterface
{
public function __construct(
private EsCache $esCache,
private EsJobQueue $esJobQueue,
private EntityManagerInterface $_em,
private EsSocket $esSocket
) {
}
public static function getSubscribedEvents(): array
{
return [
NewsfeedPrePersistEvent::NAME => 'preCreate',
NewsfeedPostPersistEvent::NAME => 'onCreate',
// NewsfeedPostUpdateEvent::NAME => 'onUpdate',
];
}
public function preCreate(NewsfeedPrePersistEvent $event)
{
$object = $event->getObject();
$this->addVoteExpiry($object);
$this->addAssetDetails($object);
// $this->addCompanyDetails($object);
}
public function onCreate(NewsfeedPostPersistEvent $event)
{
$object = $event->getObject();
if ($object->getPostType() === Newsfeed::POSTTYPE_COMPANY && $object->getCompany()) {
$container = $this->esCache->getContainer();
$payload = ['newsfeedId' => $object->getId()];
$this->esJobQueue->create(
SendCompanyFeedEmailAction::NAME,
json_encode($payload),
JobQueue::PRIORITY_MEDIUM,
$container
);
}
$this->createNotificationMailQueue($event);
$this->createSubscriptionMailQueue($event);
$this->esSocket->emit(
'backend-command',
[
'type' => 'newsfeed_update',
'payload' => ['newsfeedId' => $object->getId(), 'newsfeedPostType' => Newsfeed::POSTTYPE_TEXT, 'containerId' => $object->getContainer()->getId(), 'userId' => $object->getUser()->getId()]
]
);
}
public function onUpdate(NewsfeedPostUpdateEvent $event)
{
// $this->createNotificationMailQueue($event);
}
private function createSubscriptionMailQueue($event)
{
$object = $event->getObject();
$newsfeedCategory = $object->getNewsfeedCategory();
if ($newsfeedCategory) {
$sharingContainerIds = $this->_em->getRepository(Container::class)
->getSharingContainerIds($object->getContainer()->getId());
$sharingContainerIds[] = $object->getContainer()->getId();
$userIds = $this->_em->getRepository(User::class)
->getNewsfeedSubscribedUsers($newsfeedCategory, $sharingContainerIds, $object->getUserGroups());
if ($userIds) {
$payload = [
'userIds' => $userIds,
'newsfeedId' => $object->getId()
];
$this->esJobQueue->create(
NewsfeedSubscriptionEmailAction::NAME,
json_encode($payload),
JobQueue::PRIORITY_MEDIUM
);
}
}
}
private function createNotificationMailQueue($event)
{
$object = $event->getObject();
$userIds = $object->getAssignUsers();
if (is_array($userIds) && count($userIds) > 0) {
$container = $this->esCache->getContainer();
$container = $this->_em->getRepository(Container::class)
->find($container->getId());
$uIds = $ugIds = [];
foreach ($userIds as $d) {
if (isset($d['type']) && $d['type'] === 'group') {
$ugIds[] = $d['id'];
} else {
$uIds[] = $d['id'];
}
}
if (count($uIds) > 0) {
$payload = [
'userIds' => $uIds,
'type' => 'Newsfeed',
'objId' => $object->getId()
];
$this->esJobQueue->create(
SendUserAssignEmailAction::NAME,
json_encode($payload),
JobQueue::PRIORITY_MEDIUM,
$container
);
}
if (count($ugIds) > 0) {
$offset = 0;
$limit = 100;
$found = true;
do {
$objs = $this->_em->getRepository(User::class)
->findByUserGroupIds($ugIds, $limit, $offset);
if (!$objs) {
$found = false;
break;
}
$uIds = [];
foreach ($objs as $o) {
$uIds[] = $o->getId();
}
if (count($uIds) > 0) {
$payload = [
'userIds' => $uIds,
'type' => 'Newsfeed',
'objId' => $object->getId()
];
$this->esJobQueue->create(
SendUserAssignEmailAction::NAME,
json_encode($payload),
JobQueue::PRIORITY_MEDIUM,
$container
);
}
$offset += $limit;
} while($found);
}
}
}
private function addAssetDetails(Newsfeed $newsfeed)
{
$typeId = $newsfeed->getTypeId();
$entityClass = $newsfeed->getPostSubTypeEntity();
if (!$entityClass) {
return;
}
$sourceElement = $this->_em->getRepository($entityClass)
->find($typeId);
if (!$sourceElement || !($sourceElement instanceof NewsfeedAssetCreatorInterface)) {
return;
}
$newsfeed
->setPostMetadata($sourceElement->getPostMetadata())
->setUserGroups($sourceElement->getPostUserGroups())
->setMediaFileNames([$sourceElement->getPostPoster()])
->setIsPublished(true)
;
}
private function addVoteExpiry(Newsfeed $newsfeed)
{
if ($newsfeed->getPostType() === Newsfeed::POSTTYPE_TEXT && $newsfeed->getMediaFileType() === Newsfeed::MEDIAFILETYPE_VOTE) {
$meta = $newsfeed->getPostMetadata();
if (isset($meta['vote']['duration'])) {
$hours = $this->getHoursFromDuration($meta['vote']['duration']);
$expiry = new \DateTime();
$expiry->add(new \DateInterval('PT'.$hours.'H'));
$newsfeed->setVoteExpiry($expiry);
}
}
}
private function addCompanyDetails(Newsfeed $newsfeed)
{
if ($newsfeed->getPostType() === Newsfeed::POSTTYPE_COMPANY && $newsfeed->getCompany()) {
$postMeta = [];
if (is_array($newsfeed->getPostMetadata())) {
$postMeta = $newsfeed->getPostMetadata();
}
$companyMeta = $newsfeed->getCompany()->getMetadata();
$postMeta['company'] = $companyMeta['company'];
$newsfeed->setPostMetadata($postMeta);
}
}
private function getHoursFromDuration($duration)
{
$hours = 0;
switch($duration) {
case 'd3':
$hours = 72;
break;
case 'w1':
$hours = 168;
break;
case 'w2':
$hours = 336;
break;
case 'w4':
$hours = 672;
break;
default:
$hours = 24;
}
return $hours;
}
}