<?php
namespace Aqarmap\Bundle\ListingBundle\EventListener;
use Aqarmap\Bundle\FinancialAidsBundle\Service\FinancialAidService;
use Aqarmap\Bundle\ListingBundle\Constant\EligibleForMortgageData;
use Aqarmap\Bundle\ListingBundle\Constant\ListingCustomFields;
use Aqarmap\Bundle\ListingBundle\Constant\PropertyRegistrationStatusOption;
use Aqarmap\Bundle\ListingBundle\Entity\Listing;
use Aqarmap\Bundle\ListingBundle\Entity\Photo;
use Aqarmap\Bundle\ListingBundle\Service\ListingManager;
use Aqarmap\Bundle\ListingBundle\Service\V4\CompoundDetailService;
use Aqarmap\Bundle\ListingBundle\Service\V4\CostPerLeadService;
use Aqarmap\Bundle\MainBundle\Service\ThumbURL;
use Doctrine\ORM\EntityManagerInterface;
use Gedmo\Translatable\TranslatableListener;
use JMS\Serializer\EventDispatcher\Events;
use JMS\Serializer\EventDispatcher\EventSubscriberInterface;
use JMS\Serializer\EventDispatcher\PreSerializeEvent;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Contracts\Translation\TranslatorInterface;
use Vich\UploaderBundle\Templating\Helper\UploaderHelper;
/**
* Add thumbs url pre serialization.
*/
class ListingPreSerializerListener implements EventSubscriberInterface
{
public const SIMILAR_LISTINGS_LIMIT = 10;
private $uploaderHelper;
private $thumbURL;
private $translator;
private $request;
private $locales;
private $entityManager;
private $translatableListener;
/** @var CompoundDetailService */
private $compoundDetailService;
/** @var FinancialAidService */
private $financialAidService;
/** @var CostPerLeadService */
private $costPerLeadService;
public function __construct(
ThumbURL $thumbURL,
UploaderHelper $uploaderHelper,
TranslatorInterface $translator,
RequestStack $request,
array $locales,
EntityManagerInterface $entityManager,
TranslatableListener $translatableListener,
CompoundDetailService $compoundDetailService,
FinancialAidService $financialAidService,
ListingManager $listingManager,
CostPerLeadService $costPerLeadService
) {
$this->thumbURL = $thumbURL;
$this->uploaderHelper = $uploaderHelper;
$this->translator = $translator;
$this->request = $request->getCurrentRequest();
if ($this->request) {
$this->translator->setLocale($this->request->getLocale());
}
$this->locales = $locales;
$this->entityManager = $entityManager;
$this->translatableListener = $translatableListener;
$this->compoundDetailService = $compoundDetailService;
$this->financialAidService = $financialAidService;
$this->costPerLeadService = $costPerLeadService;
}
public static function getSubscribedEvents()
{
return [
[
'event' => Events::PRE_SERIALIZE,
'class' => Listing::class,
'method' => 'setLogos',
],
[
'event' => Events::PRE_SERIALIZE,
'class' => Listing::class,
'method' => 'translateLabels',
],
[
'event' => Events::PRE_SERIALIZE,
'class' => Listing::class,
'method' => 'translateListingV4',
],
[
'event' => Events::PRE_SERIALIZE,
'class' => Listing::class,
'method' => 'setPropertyTypChildren',
],
[
'event' => Events::PRE_SERIALIZE,
'class' => Listing::class,
'method' => 'setCostPerLead',
],
];
}
public function setLogos(PreSerializeEvent $event): void
{
// if not in group serialization, skip
foreach (['ProjectSearchV4', 'ProjectDetailsV4', 'locationListingV2'] as $group) {
if ($this->hasGroup($event, $group)) {
break;
}
return;
}
/** @var Listing $listing */
$listing = $event->getObject();
if ($listing->getLogo()) {
$listing->setListingLogo($this->thumbURL->generateURL($this->uploaderHelper->asset($listing->getLogo()->getFile(), 'file'), 'logo'));
}
if ($listing->getValidUserLogo()) {
$listing->setUserLogo($this->thumbURL->generateURL($this->uploaderHelper->asset($listing->getValidUserLogo(), 'file'), 'logo'));
}
}
/**
* Set PropertyTypeChildren (listings) of compounds.
*/
public function setPropertyTypChildren(PreSerializeEvent $event): void
{
/** @var Listing $listing */
$listing = $event->getObject();
if ($this->hasGroup($event, 'ProjectDetailsV4')) {
$this->compoundDetailService->getPropertyTypeChildrens($listing, $this->request->getLocale());
}
}
public function translateLabels(PreSerializeEvent $event): void
{
/** @var Listing $listing */
$listing = $event->getObject();
if ($listing->hasPropertyRegistrationStatusOptions()) {
$listing->setPropertyRegistrationStatusOptions($this->getPropertyRegistrationStatusTranslatedOptions());
} else {
$listing->setPropertyRegistrationStatusOptions([]);
}
if (!empty($listing->getEligibleForMortgage())) {
$listing->setEligibleForMortgageData($this->getEligibleForMortgageTranslated($listing));
} else {
$listing->setEligibleForMortgageData([]);
}
$attributesList = $listing->getListingAttributesList() ?: [];
$translatedAttributesList = [];
foreach ($attributesList as $key => $value) {
if (ListingCustomFields::FINISH_TYPE_LABEL_VALUE == $key) {
$translatedAttributesList[$key] = $this->translator->trans($value);
continue;
}
$translatedAttributesList[$key] = $value;
}
$listing->setListingAttributesList($translatedAttributesList);
$mappedPhotos = $listing->getMappedPhotos() ?: [];
foreach ($mappedPhotos as $key => $value) {
if (isset($mappedPhotos[$key]['photo']) && $mappedPhotos[$key]['photo'] instanceof Photo) {
$mappedPhotos[$key]['thumbnails'] = [
'large' => $this->thumbURL->generateURL($this->uploaderHelper->asset($mappedPhotos[$key]['photo'], 'file'), 'large'),
'small' => $this->thumbURL->generateURL($this->uploaderHelper->asset($mappedPhotos[$key]['photo'], 'file'), 'small'),
'thumb' => $this->thumbURL->generateURL($this->uploaderHelper->asset($mappedPhotos[$key]['photo'], 'file'), 'search-thumb-webp'),
];
unset($mappedPhotos[$key]['photo']);
}
}
$listing->setMappedPhotos($mappedPhotos);
$mainPhoto = $listing->getMappedMainPhoto() ?: null;
if (!empty($mainPhoto) && isset($mainPhoto['photo']) && $mainPhoto['photo'] instanceof Photo) {
$mainPhoto['thumbnails'] = [
'large' => $this->thumbURL->generateURL($this->uploaderHelper->asset($mainPhoto['photo'], 'file'), 'large'),
'small' => $this->thumbURL->generateURL($this->uploaderHelper->asset($mainPhoto['photo'], 'file'), 'small'),
'thumb' => $this->thumbURL->generateURL($this->uploaderHelper->asset($mainPhoto['photo'], 'file'), 'search-thumb-webp'),
];
unset($mainPhoto['photo']);
}
$listing->setMappedMainPhoto($mainPhoto);
}
public function translateListingV4(PreSerializeEvent $event): void
{
if ($this->hasGroup($event, 'DefaultV4') || $this->hasGroup($event, 'SearchV4') || $this->hasGroup($event, 'MyListing')) {
/** @var Listing $listing */
$listing = $event->getObject();
$translations = $listing->getV4Translations() ?: [];
$index = 0;
if ($listing->getTranslations()->count() || $listing->getTitle() || $listing->getDescription()) {
$this->translatableListener->setTranslationFallback(false);
foreach ($this->locales as $locale) {
$listing->setTranslatableLocale($locale);
$this->entityManager->refresh($listing);
if ($listing->getTitle()) {
$translations[$index]['locale'] = $locale;
$translations[$index]['title'] = $listing->getTitle();
}
if ($listing->getDescription()) {
$translations[$index]['locale'] = $locale;
$translations[$index]['description'] = $listing->getDescription();
}
++$index;
}
}
$this->translatableListener->setTranslationFallback(true);
if ($this->request) {
$listing->setTranslatableLocale($this->request->getLocale());
}
$this->entityManager->refresh($listing);
$listing->setV4Translations($translations);
}
}
/**
* Set cost per lead to listing.
*/
public function setCostPerLead(PreSerializeEvent $event): void
{
/** @var Listing $listing */
$listing = $event->getObject();
$costPerLead = $this->costPerLeadService->getCostPerLeadByListing($listing);
$listing->setCostPerLead($costPerLead);
}
private function hasGroup(PreSerializeEvent $event, string $group): bool
{
try {
$groups = $event->getContext()->getAttribute('groups');
} catch (\Exception $exception) {
return false;
}
return $groups && \in_array($group, $groups);
}
/**
* Get Mortgage Translated Options.
*
* @return array
*/
private function getPropertyRegistrationStatusTranslatedOptions()
{
foreach (PropertyRegistrationStatusOption::getChoices() as $key => $status) {
$statusOptions[] = [
'id' => $key,
'title' => $this->translator->trans($status),
];
}
return $statusOptions;
}
/**
* Get Eligible For Mortgage Translated.
*
* @return array
*/
private function getEligibleForMortgageTranslated(Listing $listing)
{
foreach ($listing->getEligibleForMortgage() as $mortgage) {
$eligibleForMortgageTranslated[] = [
'id' => $mortgage,
'title' => $this->translator->trans(EligibleForMortgageData::getLabel($mortgage)),
];
}
return $eligibleForMortgageTranslated;
}
/**
* set FinancialAid in listing for sale.
*
* @throws \Doctrine\ORM\NonUniqueResultException
*/
private function setFinancialAid(Listing $listing): void
{
$this->financialAidService->setFinancialAidInListing($listing);
}
}