<?php
namespace Aqarmap\Bundle\ListingBundle\Service;
use Aqarmap\Bundle\ListingBundle\Constant\Campaign;
use Aqarmap\Bundle\ListingBundle\Constant\InteractionTypes;
use Aqarmap\Bundle\ListingBundle\Entity\Interaction;
use Aqarmap\Bundle\ListingBundle\Entity\Listing;
use Aqarmap\Bundle\ListingBundle\Repository\InteractionRepository;
use Aqarmap\Bundle\MainBundle\Constant\ProducerQueues;
use Aqarmap\Bundle\MainBundle\Contract\ProducerFactoryInterface;
use Aqarmap\Bundle\UserBundle\Entity\User;
use Aqarmap\Bundle\UserBundle\Services\UserInterestManager;
use Aqarmap\Bundle\UserBundle\Services\UserManager;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
class InteractionService
{
private $em;
/** @var RequestStack */
private $request;
/** @var ListingManager */
private $listingManager;
/**
* @var EventDispatcherInterface
*/
protected $dispatcher;
/**
* @var Storage
*/
protected $tokenStorage;
/**
* @var ProducerFactoryInterface
*/
protected $buyerAlertProducer;
/**
* @var UserInterestManager
*/
protected $interestManager;
protected UserManager $userManager;
/** @var InteractionRepository */
protected $interactionRepository;
/** @var ListingContactRateService */
protected $listingContactRateService;
public function __construct(
ContainerInterface $container,
EntityManagerInterface $em,
RequestStack $request,
EventDispatcherInterface $dispatcher,
ProducerFactoryInterface $pokeProducerFactory,
UserInterestManager $interestManager,
UserManager $userManager,
InteractionRepository $interactionRepository,
ListingContactRateService $listingContactRateService
) {
$this->em = $em;
$this->request = $request->getCurrentRequest();
$this->dispatcher = $dispatcher;
$this->pokeProducerFactory = $pokeProducerFactory->create(ProducerQueues::POKE_CLICKED_LISTING);
$this->interestManager = $interestManager;
$this->userManager = $userManager;
$this->interactionRepository = $interactionRepository;
$this->listingContactRateService = $listingContactRateService;
}
/**
* @param int $type
* @param User $user
* @param string|null $source
* @param bool $flush
* @param null $campaign
*/
public function addInteraction($type, Listing $listing, $user = null, $source = null, $flush = true, $campaign = null): ?Interaction
{
$isValid = true;
$interaction = new Interaction();
$interaction
->setUser($user)
->setListing($listing)
->setType($type)
->setUserIp($this->request->getClientIp())
->setSource($source)
->setCampaign($campaign)
;
// Check if the campaign exists in the cookie add it to listing
$cookies = $this->request->cookies;
if ($cookies->has('campaign')) {
$interaction->setCampaign($cookies->get('campaign'));
}
if (\in_array($type, [InteractionTypes::LISTING_VIEWS])) {
$isValid = $this->validateInteractionsDuplications($interaction);
}
if (true == $isValid) {
$this->em->persist($interaction);
if ($flush) {
$this->em->flush([$interaction]);
}
$this->listingManager->incrementViewsCounters($listing);
return $interaction;
}
return null;
}
/**
* @return bool
*/
private function validateInteractionsDuplications(Interaction $interaction)
{
$duplicates = $this->interactionRepository->checkDuplicateInteraction($interaction);
return $duplicates ? false : true;
}
/**
* @param User $user
*/
public function increaseViews(Listing $listing, $user = null): void
{
$response = new Response();
$views = [];
if ($this->request->cookies->has('viewed_listings')) {
$views = unserialize($this->request->cookies->get('viewed_listings'));
if (\count($views) > 100) {
array_pop($views);
}
}
if (!\in_array($listing->getId(), $views)) {
$views[] = $listing->getId();
$response->headers->setCookie(new Cookie('viewed_listings', serialize($views), time() + (86400 * 7)));
$response->sendHeaders();
$this->addInteraction(InteractionTypes::LISTING_VIEWS, $listing, $user, 'interaction-service');
}
}
/**
* @required
*/
public function setListingManager(ListingManager $listingManager): void
{
$this->listingManager = $listingManager;
}
}