src/Aqarmap/Bundle/ListingBundle/Controller/ListingController.php line 393

Open in your IDE?
  1. <?php
  2. namespace Aqarmap\Bundle\ListingBundle\Controller;
  3. use App\Exception\LogicHttpException;
  4. use Aqarmap\Bundle\CreditBundle\Constant\CreditStatus;
  5. use Aqarmap\Bundle\CreditBundle\Entity\Credit;
  6. use Aqarmap\Bundle\CreditBundle\Services\CreditManager;
  7. use Aqarmap\Bundle\FeatureToggleBundle\Service\FeatureToggleManager;
  8. use Aqarmap\Bundle\FinancialAidsBundle\Service\FinancialAidService;
  9. use Aqarmap\Bundle\ListingBundle\Constant\LeadTypes;
  10. use Aqarmap\Bundle\ListingBundle\Constant\ListingCategories;
  11. use Aqarmap\Bundle\ListingBundle\Constant\ListingFeaturedTypes;
  12. use Aqarmap\Bundle\ListingBundle\Constant\ListingFeatures;
  13. use Aqarmap\Bundle\ListingBundle\Constant\ListingSections;
  14. use Aqarmap\Bundle\ListingBundle\Constant\ListingSellerRoles;
  15. use Aqarmap\Bundle\ListingBundle\Constant\ListingSource;
  16. use Aqarmap\Bundle\ListingBundle\Constant\ListingStatus;
  17. use Aqarmap\Bundle\ListingBundle\Constant\PropertyRegistrationStatusOption;
  18. use Aqarmap\Bundle\ListingBundle\Constant\ResaleListingsConstant;
  19. use Aqarmap\Bundle\ListingBundle\Contracts\PhoneManagerInterface;
  20. use Aqarmap\Bundle\ListingBundle\Contracts\RelatedResultServiceInterface;
  21. use Aqarmap\Bundle\ListingBundle\Entity\CallRequest;
  22. use Aqarmap\Bundle\ListingBundle\Entity\Listing;
  23. use Aqarmap\Bundle\ListingBundle\Entity\ListingPhone;
  24. use Aqarmap\Bundle\ListingBundle\Entity\Phone;
  25. use Aqarmap\Bundle\ListingBundle\Entity\Section;
  26. use Aqarmap\Bundle\ListingBundle\Event\ListingEvent;
  27. use Aqarmap\Bundle\ListingBundle\Exception\CanListInLocationException;
  28. use Aqarmap\Bundle\ListingBundle\Exception\InvalidLeadValidationHttpException;
  29. use Aqarmap\Bundle\ListingBundle\Form\AdvancedFilterType;
  30. use Aqarmap\Bundle\ListingBundle\Form\AdvancedSearchType;
  31. use Aqarmap\Bundle\ListingBundle\Form\CallRequestFormType;
  32. use Aqarmap\Bundle\ListingBundle\Form\ContactSellerFormType;
  33. use Aqarmap\Bundle\ListingBundle\Form\ContactSellerWideFormType;
  34. use Aqarmap\Bundle\ListingBundle\Form\LandingPageFormType;
  35. use Aqarmap\Bundle\ListingBundle\Form\ListingInitializeType;
  36. use Aqarmap\Bundle\ListingBundle\Form\ListingType;
  37. use Aqarmap\Bundle\ListingBundle\Form\LiteListingType;
  38. use Aqarmap\Bundle\ListingBundle\Form\Model\LandingPage;
  39. use Aqarmap\Bundle\ListingBundle\Form\MultipleSearchFormType;
  40. use Aqarmap\Bundle\ListingBundle\Form\PhotoType;
  41. use Aqarmap\Bundle\ListingBundle\Form\QuickLeadType;
  42. use Aqarmap\Bundle\ListingBundle\Service\AdvancedFilterFormTypeManager;
  43. use Aqarmap\Bundle\ListingBundle\Service\AdvancedSearchFormTypeManager;
  44. use Aqarmap\Bundle\ListingBundle\Service\CallRequestManager;
  45. use Aqarmap\Bundle\ListingBundle\Service\Contracts\ListingLeadManagerInterface;
  46. use Aqarmap\Bundle\ListingBundle\Service\Contracts\LocationManagerInterface;
  47. use Aqarmap\Bundle\ListingBundle\Service\FreeListingService;
  48. use Aqarmap\Bundle\ListingBundle\Service\InteractionService;
  49. use Aqarmap\Bundle\ListingBundle\Service\ListingFeatureService;
  50. use Aqarmap\Bundle\ListingBundle\Service\ListingManager;
  51. use Aqarmap\Bundle\ListingBundle\Service\ListingRuleMatcher;
  52. use Aqarmap\Bundle\ListingBundle\Service\Mortgage\MortgageService;
  53. use Aqarmap\Bundle\ListingBundle\Service\SpecialAddListingService;
  54. use Aqarmap\Bundle\ListingBundle\Service\SpecialListingFeatureDecorator;
  55. use Aqarmap\Bundle\ListingBundle\Service\V4\CompoundDetailService;
  56. use Aqarmap\Bundle\MainBundle\Form\ConfirmFeaturedFormType;
  57. use Aqarmap\Bundle\MainBundle\Form\ConfirmFormType;
  58. use Aqarmap\Bundle\MainBundle\Service\MobileDetectionService;
  59. use Aqarmap\Bundle\MainBundle\Service\Setting;
  60. use Aqarmap\Bundle\MessageBundle\Service\Composer;
  61. use Aqarmap\Bundle\NeighborhoodBundle\Service\NeighborhoodManager;
  62. use Aqarmap\Bundle\NotificationBundle\DatabaseNotification;
  63. use Aqarmap\Bundle\NotifierBundle\Event\NotifierEvent;
  64. use Aqarmap\Bundle\OTPBundle\Contract\OtpServiceInterface;
  65. use Aqarmap\Bundle\SearchBundle\Services\CompoundFaqsService;
  66. use Aqarmap\Bundle\SearchBundle\Services\ElasticListingSearch\DefaultListingSearch;
  67. use Aqarmap\Bundle\TopSellerBundle\Model\TopSeller;
  68. use Aqarmap\Bundle\TopSellerBundle\Service\TopSellerRetrievalService;
  69. use Aqarmap\Bundle\UserBundle\Constant\UserServicesType;
  70. use Aqarmap\Bundle\UserBundle\Constant\UserTypes;
  71. use Aqarmap\Bundle\UserBundle\Entity\User;
  72. use Aqarmap\Bundle\UserBundle\Entity\UserServices;
  73. use Aqarmap\Bundle\UserBundle\Form\QuickRegistrationFormType;
  74. use Aqarmap\Bundle\UserBundle\Repository\UserPackagesRepository;
  75. use Aqarmap\Bundle\UserBundle\Services\UserActivityService;
  76. use Aqarmap\Bundle\UserBundle\Services\UserManager;
  77. use Aqarmap\Bundle\UserBundle\Services\UserPackagesService;
  78. use Aqarmap\Bundle\UserBundle\Services\UserServicesManager;
  79. use Doctrine\ORM\EntityManager;
  80. use Doctrine\ORM\EntityManagerInterface;
  81. use FOS\RestBundle\Controller\Annotations as Rest;
  82. use FOS\RestBundle\View\View;
  83. use FOS\UserBundle\Model\UserManagerInterface;
  84. use Gedmo\Translatable\TranslatableListener;
  85. use Knp\Component\Pager\PaginatorInterface;
  86. use Liip\ImagineBundle\Imagine\Cache\CacheManager;
  87. use Predis\ClientInterface as RedisClient;
  88. use Psr\Log\LoggerInterface;
  89. use Psr\Log\LogLevel;
  90. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
  91. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  92. use Symfony\Component\EventDispatcher\EventDispatcherInterface;
  93. use Symfony\Component\Form\FormInterface;
  94. use Symfony\Component\HttpFoundation\JsonResponse;
  95. use Symfony\Component\HttpFoundation\RedirectResponse;
  96. use Symfony\Component\HttpFoundation\Request;
  97. use Symfony\Component\HttpFoundation\Response;
  98. use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
  99. use Symfony\Component\Routing\Annotation\Route;
  100. use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
  101. use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
  102. use Symfony\Contracts\Translation\TranslatorInterface;
  103. use Vich\UploaderBundle\Templating\Helper\UploaderHelper;
  104. /**
  105.  * Listing controller.
  106.  */
  107. class ListingController extends AbstractController
  108. {
  109.     /**
  110.      * @var Composer
  111.      */
  112.     private $messageComposer;
  113.     /**
  114.      * @var DatabaseNotification
  115.      */
  116.     private $databaseNotification;
  117.     /**
  118.      * @var LoggerInterface
  119.      */
  120.     private $logger;
  121.     /**
  122.      * @var TranslatorInterface
  123.      */
  124.     private $translator;
  125.     /**
  126.      * @var FeatureToggleManager
  127.      */
  128.     private $featureToggleManager;
  129.     /**
  130.      * @var Setting
  131.      */
  132.     private $setting;
  133.     /**
  134.      * @var ListingManager
  135.      */
  136.     private $listingManager;
  137.     /**
  138.      * @var EventDispatcherInterface
  139.      */
  140.     private $dispatcher;
  141.     /**
  142.      * @var InteractionService
  143.      */
  144.     private $interactionService;
  145.     /**
  146.      * @var NeighborhoodManager
  147.      */
  148.     private $neighborhoodManager;
  149.     /**
  150.      * @var DefaultListingSearch
  151.      */
  152.     private $defaultListingSearch;
  153.     /**
  154.      * @var RelatedResultServiceInterface
  155.      */
  156.     private $relatedResultService;
  157.     /**
  158.      * @var TopSellerRetrievalService
  159.      */
  160.     private $topSellerRetrievalService;
  161.     /**
  162.      * @var FinancialAidService
  163.      */
  164.     private $financialAidService;
  165.     /**
  166.      * @var ListingLeadManagerInterface
  167.      */
  168.     private $listingLeadManager;
  169.     /**
  170.      * @var CompoundFaqsService
  171.      */
  172.     private $compoundFaqsService;
  173.     /**
  174.      * @var PaginatorInterface
  175.      */
  176.     private $paginator;
  177.     /**
  178.      * @var UserActivityService
  179.      */
  180.     private $userActivityService;
  181.     /**
  182.      * @var MobileDetectionService
  183.      */
  184.     private $mobileDetectionService;
  185.     /**
  186.      * @var RedisClient
  187.      */
  188.     private $redis;
  189.     /**
  190.      * @var CacheManager
  191.      */
  192.     private $imagine;
  193.     /**
  194.      * @var UploaderHelper
  195.      */
  196.     private $uploaderHelper;
  197.     /**
  198.      * @var CallRequestManager
  199.      */
  200.     private $callRequestManager;
  201.     /**
  202.      * @var AuthorizationCheckerInterface
  203.      */
  204.     private $authorizationChecker;
  205.     /**
  206.      * @var TokenStorage
  207.      */
  208.     private $tokenStorage;
  209.     /**
  210.      * @var MortgageService
  211.      */
  212.     private $mortgageService;
  213.     /**
  214.      * @var ListingRuleMatcher
  215.      */
  216.     private $listingRuleMatcher;
  217.     /**
  218.      * @var CreditManager
  219.      */
  220.     private $creditManager;
  221.     /**
  222.      * @var UserServicesManager
  223.      */
  224.     private $userServicesManager;
  225.     /**
  226.      * @var UserManagerInterface
  227.      */
  228.     private $FOSUserManager;
  229.     /**
  230.      * @var PhoneManagerInterface
  231.      */
  232.     private $phoneManager;
  233.     /**
  234.      * @var ListingFeatureService
  235.      */
  236.     private $listingFeatureService;
  237.     private UserManager $userManager;
  238.     /**
  239.      * @var AdvancedSearchFormTypeManager
  240.      */
  241.     private $advancedSearchFormTypeManager;
  242.     /**
  243.      * @var AdvancedFilterFormTypeManager
  244.      */
  245.     private $advancedFilterFormTypeManager;
  246.     /** @var CompoundDetailService */
  247.     private $compoundDetailService;
  248.     /** @var TranslatableListener */
  249.     private $translatableListener;
  250.     /** @var EntityManagerInterface */
  251.     private $entityManager;
  252.     /** @var UserPackagesRepository */
  253.     private $userPackagesRepository;
  254.     public function __construct(
  255.         Composer $messageComposer,
  256.         OtpServiceInterface $otpService,
  257.         DatabaseNotification $databaseNotification,
  258.         LoggerInterface $logger,
  259.         TranslatorInterface $translator,
  260.         FeatureToggleManager $featureToggleManager,
  261.         Setting $setting,
  262.         ListingManager $listingManager,
  263.         EventDispatcherInterface $dispatcher,
  264.         InteractionService $interactionService,
  265.         NeighborhoodManager $neighborhoodManager,
  266.         DefaultListingSearch $defaultListingSearch,
  267.         RelatedResultServiceInterface $relatedResultService,
  268.         LocationManagerInterface $locationManager,
  269.         TopSellerRetrievalService $topSellerRetrievalService,
  270.         FinancialAidService $financialAidService,
  271.         ListingLeadManagerInterface $listingLeadManager,
  272.         CompoundFaqsService $compoundFaqsService,
  273.         PaginatorInterface $paginator,
  274.         UserActivityService $userActivityService,
  275.         MobileDetectionService $mobileDetectionService,
  276.         RedisClient $redis,
  277.         CacheManager $imagine,
  278.         UploaderHelper $uploaderHelper,
  279.         CallRequestManager $callRequestManager,
  280.         AuthorizationCheckerInterface $authorizationChecker,
  281.         TokenStorageInterface $tokenStorage,
  282.         MortgageService $mortgageService,
  283.         ListingRuleMatcher $listingRuleMatcher,
  284.         CreditManager $creditManager,
  285.         UserServicesManager $userServicesManager,
  286.         UserManagerInterface $FOSUserManager,
  287.         PhoneManagerInterface $phoneManager,
  288.         FreeListingService $freeListingService,
  289.         ListingFeatureService $listingFeatureService,
  290.         UserManager $userManager,
  291.         AdvancedSearchFormTypeManager $advancedSearchFormTypeManager,
  292.         AdvancedFilterFormTypeManager $advancedFilterFormTypeManager,
  293.         SpecialAddListingService $specialAddListingService,
  294.         CompoundDetailService $compoundDetailService,
  295.         SpecialListingFeatureDecorator $specialListingFeatureDecorator,
  296.         TranslatableListener $translatableListener,
  297.         EntityManagerInterface $entityManager,
  298.         UserPackagesRepository $userPackagesRepository
  299.     ) {
  300.         $this->messageComposer $messageComposer;
  301.         $this->databaseNotification $databaseNotification;
  302.         $this->logger $logger;
  303.         $this->translator $translator;
  304.         $this->featureToggleManager $featureToggleManager;
  305.         $this->setting $setting;
  306.         $this->listingManager $listingManager;
  307.         $this->dispatcher $dispatcher;
  308.         $this->interactionService $interactionService;
  309.         $this->neighborhoodManager $neighborhoodManager;
  310.         $this->defaultListingSearch $defaultListingSearch;
  311.         $this->relatedResultService $relatedResultService;
  312.         $this->topSellerRetrievalService $topSellerRetrievalService;
  313.         $this->financialAidService $financialAidService;
  314.         $this->listingLeadManager $listingLeadManager;
  315.         $this->compoundFaqsService $compoundFaqsService;
  316.         $this->paginator $paginator;
  317.         $this->userActivityService $userActivityService;
  318.         $this->mobileDetectionService $mobileDetectionService;
  319.         $this->redis $redis;
  320.         $this->imagine $imagine;
  321.         $this->uploaderHelper $uploaderHelper;
  322.         $this->callRequestManager $callRequestManager;
  323.         $this->authorizationChecker $authorizationChecker;
  324.         $this->tokenStorage $tokenStorage;
  325.         $this->mortgageService $mortgageService;
  326.         $this->listingRuleMatcher $listingRuleMatcher;
  327.         $this->creditManager $creditManager;
  328.         $this->userServicesManager $userServicesManager;
  329.         $this->FOSUserManager $FOSUserManager;
  330.         $this->phoneManager $phoneManager;
  331.         $this->listingFeatureService $listingFeatureService;
  332.         $this->userManager $userManager;
  333.         $this->advancedSearchFormTypeManager $advancedSearchFormTypeManager;
  334.         $this->advancedFilterFormTypeManager $advancedFilterFormTypeManager;
  335.         $this->specialAddListingService $specialAddListingService;
  336.         $this->specialListingFeatureDecorator $specialListingFeatureDecorator;
  337.         $this->compoundDetailService $compoundDetailService;
  338.         $this->translatableListener $translatableListener;
  339.         $this->entityManager $entityManager;
  340.         $this->userPackagesRepository $userPackagesRepository;
  341.     }
  342.     /**
  343.      * Listing Details Action.
  344.      *
  345.      * @Route("/{id}/{notification}", defaults={"notification"=0}, requirements={"id" = "\d+"}, options={"i18n" = false, "expose" = true}, name="listing_view", methods={"GET"})
  346.      * @Route("/listing/{id}/notification/{notification}", defaults={"notification"=0}, name="listing_view_notification", methods={"GET"})
  347.      * @Route("/listing/{id}", requirements={"id" = "\d+"} , options={"expose" = true} , name="listing_details", methods={"GET"})
  348.      * @Route("/listing/{id}-{slug}", requirements={"id" = "\d+", "slug" = ".+"}, name="listing_slug", methods={"GET"})
  349.      */
  350.     public function read(Request $requestListing $listingEntityManagerInterface $em)
  351.     {
  352.         if ($request->get('notification')) {
  353.             try {
  354.                 $this->databaseNotification->markOneAsRead($request->get('notification'));
  355.             } catch (\Exception $exception) {
  356.                 $this->logger->log(LogLevel::ERROR$exception->getMessage());
  357.             }
  358.         }
  359.         // Redirect to the right URL if the URL is short-URL or the listing slug is incorrect
  360.         if (('listing_slug' != $request->get('_route')
  361.                 || $request->attributes->get('slug') != $listing->getSlug())
  362.             && !empty($listing->getSlug())
  363.         ) {
  364.             return $this->redirect($this->generateUrl('listing_slug'array_merge($request->query->all(), [
  365.                 'id' => $listing->getId(),
  366.                 'slug' => $listing->getSlug(),
  367.             ])), Response::HTTP_MOVED_PERMANENTLY);
  368.         }
  369.         $listingStatus = !\in_array($listing->getStatus(), [ListingStatus::LIVEListingStatus::PENDING]);
  370.         if ($listingStatus && !$request->query->get('noredirect') && $listing->getUser() != $this->getUser()) {
  371.             if (!$listing->getSection()->getSearchable()) {
  372.                 return $this->redirect($this->generateUrl('compound_search'), Response::HTTP_FOUND);
  373.             }
  374.             try {
  375.                 $searchableLocation $listing->getLocation()->getNearestSearchable();
  376.             } catch (\Exception $exception) {
  377.                 $this->addFlash(
  378.                     'danger',
  379.                     $this->translator->trans('listing.not_available')
  380.                 );
  381.                 return $this->redirect($this->generateUrl('homepage'), Response::HTTP_FOUND);
  382.             }
  383.             return $this->redirect($this->generateUrl('search', [
  384.                 'section_slug' => $listing->getSection()->getSlug(),
  385.                 'property_type_slug' => $listing->getPropertyType()->getSlug(),
  386.                 'location_slug' => $searchableLocation->getSlug(),
  387.             ]), Response::HTTP_MOVED_PERMANENTLY);
  388.         }
  389.         $listingRepo $em->getRepository(Listing::class);
  390.         if ($notifierId $request->query->get('notifier')) {
  391.             if (null !== $notifier $em->getRepository('AqarmapNotifierBundle:Notifier')->find($notifierId)) {
  392.                 $this->dispatcher->dispatch(new NotifierEvent($notifier), 'aqarmap.notifier.interaction');
  393.             } else {
  394.                 $this->logger->warning('Notifier with id: '.$notifierId.' was not found!');
  395.             }
  396.         }
  397.         $this->interactionService->increaseViews($listing$this->getUser());
  398.         $relatedListingCriteriaMapper $this->relatedResultService->getRelatedListingCriteriaMapper($listing);
  399.         $relatedListings $this->defaultListingSearch->search($relatedListingCriteriaMapper)['searchResults'];
  400.         $topSeller $this->createTopSeller($listing);
  401.         $topSearchableCompanies $this->topSellerRetrievalService->getTopSellerPersonalData($topSeller$request->getLocale());
  402.         $searchableLocation $listing->getLocation()->getNearestSearchable();
  403.         $isPlaceHoldered false;
  404.         $userProfilePhoto $listing->getUser()->isValidPersonalPhoto() ? $listing->getUser()->getPersonalPhoto() : null;
  405.         if ($listing->getLogo() || ($listing->getParent() && $listing->getParent()->getLogo())) {
  406.             if ($listing->getParent() && $listing->getParent()->getLogo()) {
  407.             }
  408.         } elseif (!empty($listing->getPhotosForSlider()) && $listing->getUser()->getIsValidLogo()) {
  409.             $isPlaceHoldered true;
  410.         }
  411.         $this->financialAidService->setFinancialAidInListing($listing);
  412.         $activeListingsCount $listing->getUser()->getActiveListingsCount();
  413.         $leadsCount 0;
  414.         if ($this->featureToggleManager->isEnabled('web.client.served.count')) {
  415.             $leadsCount $listing->getUser()->getClientServedCount();
  416.         }
  417.         $listing current(
  418.             $this->listingManager->setUserActivities(
  419.                 [$listing],
  420.                 [$listing->getId()]
  421.             )
  422.         );
  423.         $hasUserMadeLead false;
  424.         if ($user $this->getUser()) {
  425.             $hasUserMadeLead $this->listingLeadManager->hasUserMadeLead($listing$user);
  426.         }
  427.         $compoundFaqs = [];
  428.         $listingDetails $listing;
  429.         if ($listing->isProject()) {
  430.             $compoundFaqs $this->compoundFaqsService->generateFaqData($listing);
  431.             $resaleRegularListingsPaginated $this->paginator->paginate(
  432.                 $listingRepo->getSectionListings($listingnullListingSections::FOR_SALE),
  433.                 $request->query->get('page'ResaleListingsConstant::PAGE),
  434.                 ResaleListingsConstant::LIMIT
  435.             );
  436.             $this->compoundDetailService->getPropertyTypeChildrens($listing$request->getLocale());
  437.             $liveUnitsPaginated $listing->getPropertyTypeChildren();
  438.             $this->compoundDetailService->getPropertyTypeUnitsChildrens($listingListingSections::FOR_SALE$request->getLocale());
  439.             $resaleUnitsPaginated $listing->getPropertyTypeChildren();
  440.             $this->compoundDetailService->getPropertyTypeUnitsChildrens($listingListingSections::FOR_RENT$request->getLocale());
  441.             $rentUnitsPaginated $listing->getPropertyTypeChildren();
  442.         }
  443.         $request->cookies->get('user-agent');
  444.         $mobileDetection $this->mobileDetectionService->mobileDetection($request$return);
  445.         $return = [
  446.             'listing' => $listingDetails,
  447.             'searchableLocation' => $searchableLocation,
  448.             'contact_seller_form' => $this->contactSellerForm($listing)->createView(),
  449.             'quick_registration_form' => $this->quickRegistrationForm()->createView(),
  450.             'call_request' => $this->callRequestForm($listing)->createView(),
  451.             'related_listings' => $relatedListings,
  452.             'relatedListingsCount' => (null != $relatedListings) ? $relatedListings->getTotalItemCount() : 0,
  453.             'location_statistics' => $this->neighborhoodManager->getStatistics(
  454.                 $listing->getLocation()->getNearestNeighborhood(),
  455.                 $listing->getPropertyType()
  456.             ),
  457.             'topSearchableCompanies' => $topSearchableCompanies,
  458.             'topSearchableCompaniesCount' => \count($topSearchableCompanies),
  459.             'isPlaceHoldered' => $isPlaceHoldered,
  460.             'userProfilePhoto' => $userProfilePhoto,
  461.             'activeListingsCount' => $activeListingsCount,
  462.             'leadsCount' => $leadsCount,
  463.             'featureToggle' => $this->userActivityService->getFeatureToggles(),
  464.             'leadAnalytics' => $this->listingManager->getLeadAnalytics($listing),
  465.             'otherUnits' => $this->listingManager->getOtherUnits($listing$request->getLocale()),
  466.             'hasUserMadeLead' => $hasUserMadeLead,
  467.             'resaleRegularListings' => $resaleRegularListingsPaginated ?? null,
  468.             'resaleUnitsPaginated' => $resaleUnitsPaginated ?? null,
  469.             'liveUnitsPaginated' => $liveUnitsPaginated ?? null,
  470.             'rentUnitsPaginated' => $rentUnitsPaginated ?? null,
  471.             'compoundFaqs' => $compoundFaqs,
  472.             'isMobile' => $mobileDetection['isMobile'],
  473.         ];
  474.         if ($mobileDetection['isMobile']) {
  475.             $nearestLocations $em
  476.                 ->getRepository(\Aqarmap\Bundle\ListingBundle\Entity\Location::class)
  477.                 ->getNearestLocations([$listing->getLocation()])
  478.             ;
  479.             $return['nearestLocations'] = $nearestLocations;
  480.             foreach ($mobileDetection as $key => $val) {
  481.                 $return[$key] = $val;
  482.             }
  483.             return $this->render('@AqarmapListing/Listing/read-mob.html.twig'$return);
  484.         }
  485.         $return['discussions'] = $em
  486.             ->getRepository('AqarmapDiscussionBundle:Discussion')
  487.             ->getTrendingWithLocation($listing->getLocation()->getId(), 3)
  488.         ;
  489.         return $this->render('@AqarmapListing/Listing/read.html.twig'$return);
  490.     }
  491.     /**
  492.      * TopSeller Attributes from listing data.
  493.      *
  494.      * @param  Listing
  495.      *
  496.      * @return TopSeller
  497.      */
  498.     private function createTopSeller($listing)
  499.     {
  500.         $topSeller = new TopSeller();
  501.         $topSeller->setLocation($listing->getLocation()->getId());
  502.         $topSeller->setSection($listing->getSection()->getId());
  503.         $topSeller->setPropertyType($listing->getPropertyType()->getId());
  504.         return $topSeller;
  505.     }
  506.     /**
  507.      * Advanced Search Form.
  508.      */
  509.     protected function createAdvancedSearchForm(): FormInterface
  510.     {
  511.         return $this->advancedSearchFormTypeManager
  512.             ->setAction($this->generateUrl('listing_advanced_search'))
  513.             ->setFormType(AdvancedSearchType::class)
  514.             ->setMethodType('Post')
  515.             ->setSettings($this->setting)
  516.             ->applyOptions()
  517.             ->createForm();
  518.     }
  519.     /**
  520.      * Advanced Search Form.
  521.      */
  522.     protected function createAdvancedFilterForm(): FormInterface
  523.     {
  524.         $customFields $this->redis->get('customFields');
  525.         return $this->advancedFilterFormTypeManager
  526.             ->setAction($this->generateUrl('listing_filter_search'))
  527.             ->setFormType(AdvancedFilterType::class)
  528.             ->setMethodType('Post')
  529.             ->setSettings($this->setting)
  530.             ->setCustomFields($customFields unserialize($customFields) : [])
  531.             ->applyOptions()
  532.             ->createForm();
  533.     }
  534.     /**
  535.      * Multiple Search Form.
  536.      */
  537.     protected function createMultipleSearchForm(): FormInterface
  538.     {
  539.         return $this->advancedSearchFormTypeManager
  540.             ->setAction($this->generateUrl('listing_multiple_search'))
  541.             ->setFormType(MultipleSearchFormType::class)
  542.             ->setMethodType('Post')
  543.             ->setSettings($this->setting)
  544.             ->applyOptions()
  545.             ->createForm();
  546.     }
  547.     /**
  548.      * Latest Listings Action.
  549.      *
  550.      * @Route("/listing/latest", name="listing_latest", methods={"GET"})
  551.      */
  552.     public function latest(Request $request): Response
  553.     {
  554.         /** @var $em \Doctrine\ORM\EntityManager */
  555.         $em $this->getDoctrine()->getManager();
  556.         $pagination $this->paginator->paginate(
  557.             $em->getRepository(Listing::class)->getLatestListings(),
  558.             $request->query->get('page'1)
  559.         );
  560.         return $this->render('@AqarmapListing/Listing/latest.html.twig', [
  561.             'listings' => $pagination,
  562.         ]);
  563.     }
  564.     /**
  565.      * @Route("/listing/latest/{section}.{_format}")
  566.      *
  567.      * @return Response
  568.      */
  569.     public function CSVLatestListings(Request $requestSection $section)
  570.     {
  571.         /** @var EntityManager $em */
  572.         $em $this->getDoctrine()->getManager();
  573.         $listings $em->getRepository(Listing::class)->findBy([
  574.             'section' => $section,
  575.             'status' => ListingStatus::LIVE,
  576.         ], ['id' => 'desc'], 100);
  577.         $handle fopen('php://memory''r+');
  578.         fputcsv($handle, [
  579.             $request->query->get('id''id'),
  580.             $request->query->get('section''section'),
  581.             $request->query->get('description''description'),
  582.             $request->query->get('image''image'),
  583.             $request->query->get('link''link'),
  584.             $request->query->get('title''title'),
  585.             $request->query->get('price''price'),
  586.             $request->query->get('formatted_price''formatted_price'),
  587.             $request->query->get('price_currency''price_currency'),
  588.             $request->query->get('location''location'),
  589.             $request->query->get('address''address'),
  590.             $request->query->get('property_type''property_type'),
  591.             $request->query->get('availability''availability'),
  592.             $request->query->get('condition''condition'),
  593.         ]);
  594.         foreach ($listings as $listing) {
  595.             $thumb null;
  596.             if ($listing->getMainPhoto()) {
  597.                 $thumb $this->imagine->generateUrl(
  598.                     $this->uploaderHelper->asset($listing->getMainPhoto()->getFile(), 'file'),
  599.                     'large'
  600.                 );
  601.             }
  602.             $description preg_split('/\n/'mb_substr($listing->getDescription(), 0200), \PREG_SPLIT_DELIM_CAPTURE);
  603.             fputcsv($handle, [
  604.                 $listing->getId(),
  605.                 $section->getTitle(),
  606.                 $description[0],
  607.                 $thumb,
  608.                 $this->generateUrl('listing_view', ['id' => $listing->getId()], true),
  609.                 $listing->getTitle(),
  610.                 $listing->getPrice(),
  611.                 number_format($listing->getPrice()),
  612.                 sprintf('%s %s'number_format($listing->getPrice()), 'EGP'),
  613.                 $listing->getLocation()->getTitle(),
  614.                 $listing->getAddress(),
  615.                 $listing->getPropertyType()->getTitle(),
  616.                 'in stock',
  617.                 'new',
  618.             ]);
  619.         }
  620.         rewind($handle);
  621.         $content stream_get_contents($handle);
  622.         fclose($handle);
  623.         return new Response($contentResponse::HTTP_OK, [
  624.             'Content-Type' => 'application/force-download',
  625.             'Content-Disposition' => sprintf(
  626.                 'attachment; filename="latest-listings - %s - %s.csv"',
  627.                 $section->getTitle(),
  628.                 date('Y-m-d H-i-s')
  629.             ),
  630.         ]);
  631.     }
  632.     /**
  633.      * @deprecated
  634.      *
  635.      * @Route("/listing/{id}/one", name="landing_page", methods={"GET", "POST"})
  636.      *
  637.      * @Rest\View()
  638.      *
  639.      * @return array
  640.      */
  641.     public function landingPage(Request $requestListing $listing)
  642.     {
  643.         $form $this->createForm(LandingPageFormType::class, $landingPage = new LandingPage(), [
  644.             'action' => $this->generateUrl('landing_page', ['id' => $listing->getId()]),
  645.         ]);
  646.         $form->handleRequest($request);
  647.         if ($form->isSubmitted() && $form->isValid()) {
  648.             if (!($user $this->FOSUserManager->findUserByEmail($landingPage->getUser()->getEmail()))) {
  649.                 $user $this->userManager
  650.                     ->createUserWithoutPassword($form->get('user')->getData(), $form->get('user'), $request)
  651.                 ;
  652.             }
  653.             if (!$form->get('message')->getData()) {
  654.                 $callRequest = new CallRequest();
  655.                 $callRequest->setListing($listing);
  656.                 $callRequest->setUser($user);
  657.                 $this->callRequestManager->submitCallRequest($callRequest);
  658.             } else {
  659.                 // Compose a message
  660.                 $composer $this->messageComposer;
  661.                 $composer->setSender($user);
  662.                 $composer->compose($form->get('message')->getData(), $listing);
  663.             }
  664.         }
  665.         return [
  666.             'form' => $form->createView(),
  667.             'listing' => $listing,
  668.         ];
  669.     }
  670.     /**
  671.      * Add Listing First Step Action.
  672.      *
  673.      * @Route("/listing/initialize", name="listing_initialize", options={"expose"=true})
  674.      */
  675.     public function initialize(Request $request)
  676.     {
  677.         $user $this->getUser();
  678.         if (false === $this->authorizationChecker->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
  679.             return $this->redirect($this->generateUrl('aqarmap_add_listing'));
  680.         }
  681.         $hasRentalPackage $this->userPackagesRepository->hasRentalPackage($user);
  682.         $initializeOptions = [
  683.             'action' => $this->generateUrl('listing_initialize'),
  684.             'method' => 'POST',
  685.             'em' => $this->getDoctrine()->getManager(),
  686.             'is_admin' => $this->authorizationChecker->isGranted('ROLE_ADMIN'),
  687.             'has_rental_package' => $hasRentalPackage,
  688.             'parentUser' => $user,
  689.         ];
  690.         $form $this->createForm(ListingInitializeType::class, $listing = new Listing(), $initializeOptions);
  691.         $listingEvent = new ListingEvent($listing);
  692.         $this->dispatcher->dispatch($listingEvent'aqarmap.listing.pre_submitted');
  693.         $form->handleRequest($request);
  694.         if ($form->isSubmitted() && $form->isValid()) {
  695.             try {
  696.                 $this->dispatcher->dispatch(new ListingEvent($listing), 'aqarmap.listing.can_list_in_location');
  697.             } catch (CanListInLocationException $exception) {
  698.                 $this->addFlash('danger'$this->translator->trans('credit.can_not_list_in_location'));
  699.                 return $this->redirect($this->generateUrl('listing_initialize'), Response::HTTP_FOUND);
  700.             }
  701.             $listing $this->listingManager->createDraft($listing);
  702.             // Add user phone number to the listing
  703.             if ($listing->getUser()->getPhoneNumber()) {
  704.                 // link user phone with this listing
  705.                 // TODO: Suggest only the main number for now, later on we will suggest the main + last 2 numbers.
  706.                 $this->listingManager->suggestListingPhoneNumbers(
  707.                     [$listing->getUser()->getPhoneNumber()],
  708.                     $listing
  709.                 );
  710.             }
  711.             return $this->redirect($this->generateUrl('listing_edit', [
  712.                 'id' => $listing->getId(),
  713.             ]));
  714.         }
  715.         return $this->render('@AqarmapListing/Listing/initialize.html.twig', [
  716.             'form' => $form->createView(),
  717.         ]);
  718.     }
  719.     /**
  720.      * Add Listing V2.
  721.      *
  722.      * @Route("/listing/initialize/{step}", name="add_listing", options={"expose"=true})
  723.      * @Route("/listing/initialize/{id}/{step}", name="edit_listing", options={"expose"=true})
  724.      *
  725.      * @Security("is_granted('IS_AUTHENTICATED_REMEMBERED')")
  726.      *
  727.      * @throws \Doctrine\ORM\NonUniqueResultException
  728.      */
  729.     public function addListing(): Response
  730.     {
  731.         return $this->render('@AqarmapListing/Listing/add.html.twig', [
  732.             'title' => $this->translator->trans('listing.add_your_listing'),
  733.             'featureToggle' => [
  734.                 'accept_adding_phones' => $this->featureToggleManager->isEnabled('web.addlisting.accept_adding_phones'),
  735.                 'google_maps_location' => $this->featureToggleManager->isEnabled('web.addlisting.google_maps_location'),
  736.             ],
  737.         ]);
  738.     }
  739.     /**
  740.      * Add Listing groups.
  741.      *
  742.      * @Route("/listing/add/", name="add_listing_steps", options={"expose"=true})
  743.      * @Route("/listing/{id}/edit/steps", name="edit_listing_steps", options={"expose"=true})
  744.      *
  745.      * @Security("is_granted('IS_AUTHENTICATED_REMEMBERED')")
  746.      *
  747.      * @throws \Doctrine\ORM\NonUniqueResultException
  748.      */
  749.     public function addListingSteps(): Response
  750.     {
  751.         return $this->render('@AqarmapListing/Listing/addSteps.html.twig', [
  752.             'title' => $this->translator->trans('listing.add_your_listing'),
  753.             'featureToggle' => [
  754.                 'accept_adding_phones' => $this->featureToggleManager->isEnabled('web.addlisting.accept_adding_phones'),
  755.                 'google_maps_location' => $this->featureToggleManager->isEnabled('web.addlisting.google_maps_location'),
  756.             ],
  757.         ]);
  758.     }
  759.     /**
  760.      * Listing Post Action
  761.      * This action manage adding & editing listings.
  762.      *
  763.      * @Route("/listing/{id}/edit/", name="listing_edit", requirements={"id" = "\d+"}, options={"expose"=true})
  764.      *
  765.      * @Security(
  766.      *     "(is_granted('IS_AUTHENTICATED_REMEMBERED') and is_granted('ROLE_OWNER', listing)) or is_granted('ROLE_ADMIN')"
  767.      * )
  768.      */
  769.     public function post(Request $requestListing $listing): Response
  770.     {
  771.         $form $this->createForm(ListingType::class, $listing, [
  772.             'action' => $this->generateUrl('listing_edit', ['id' => $listing->getId()]),
  773.             'method' => 'POST',
  774.             'listingIsLiveFor5Days' => $this->listingManager->checkListingLiveDays($listing),
  775.             'is_admin' => $this->authorizationChecker->isGranted('ROLE_ADMIN'),
  776.             'user_country' => $this->setting->getSetting('general''country'),
  777.             'user_type' => $listing->getUser() ? $listing->getUser()->getUserType() : null,
  778.             'isMortgageOptionsEnabled' => $this->featureToggleManager->isEnabled('web.mortgage.options'),
  779.             'isListingMarketPropertyTypesEnabled' => $this->featureToggleManager->isEnabled('web.listing.market.property.types'),
  780.         ]);
  781.         $form->handleRequest($request);
  782.         if ($request->isMethod('POST')) {
  783.             if ($form->isSubmitted() && $form->isValid()) {
  784.                 $this->updateWhatsAppPhones($listing->getUser()->getId(), (array) $request->request->get('phoneIds', []), (array) $request->request->get('hasWhatsApp', []));
  785.                 $listing $this->handleListingPhones($listing$request->request->all()['listing']['phones']);
  786.                 $this->handleUserPhones($listing->getUser(), $request->request->all()['listing']['phones']);
  787.                 $this->listingManager->saveListing($listing);
  788.                 if ($this->featureToggleManager->isEnabled('web.add.listing.translations')) {
  789.                     if ('en' == $request->getLocale()) {
  790.                         $criteria = [
  791.                             'reversedLocale' => 'ar',
  792.                             'title-ar' => $request->request->get('title-ar'),
  793.                             'description-ar' => $request->request->get('description-ar'),
  794.                         ];
  795.                     } else {
  796.                         $criteria = [
  797.                             'reversedLocale' => 'en',
  798.                             'title-en' => $request->request->get('title-en'),
  799.                             'description-en' => $request->request->get('description-en'),
  800.                         ];
  801.                     }
  802.                     $this->listingManager->updateListingTranslationsFields($listing$criteria);
  803.                 } else {
  804.                     $this->listingManager->updateListingTranslations($listing);
  805.                 }
  806.                 if ($this->featureToggleManager->isEnabled('web.mortgage.options')) {
  807.                     $propertyRegistrationStatus $form->has('propertyRegistrationStatus') ? $form->get('propertyRegistrationStatus')->getData() : null;
  808.                     if (\in_array($propertyRegistrationStatusPropertyRegistrationStatusOption::getValidMorgageOptions())) {
  809.                         $this->mortgageService->addEligibleMortgageTypes($listing);
  810.                     } else {
  811.                         $this->listingManager->setELigibleMortgageToNull($listing);
  812.                     }
  813.                     $listing $this->mortgageService->addMortgageApproval($listing$form);
  814.                 }
  815.                 $listingEvent = new ListingEvent($listing);
  816.                 $this->dispatcher->dispatch($listingEvent'aqarmap.listing.submitted');
  817.                 if (ListingSource::SCRAPPING == $listing->getSource()
  818.                     || ListingSource::LITE == $listing->getSource()
  819.                 ) {
  820.                     return $this->redirect($this->generateUrl('listing_view', ['id' => $listing->getId()]));
  821.                 }
  822.                 return $this
  823.                     ->redirect(
  824.                         $this->generateUrl(
  825.                             'listing_upload',
  826.                             ['id' => $listing->getId(), '_locale' => $request->get('_locale')]
  827.                         )
  828.                     )
  829.                 ;
  830.             }
  831.             $this->addFlash('danger'$this->translator->trans('static.problem_error_message'));
  832.         }
  833.         $translatedLocale 'en' == $request->getLocale() ? 'ar' 'en';
  834.         return $this->render('@AqarmapListing/Listing/post.html.twig', [
  835.             'form' => $form->createView(),
  836.             'listing' => $listing,
  837.             'title_translation' => $this->listingTitleTranslations($listing$translatedLocale),
  838.             'description_translation' => $this->listingDescriptionTranslations($listing$translatedLocale),
  839.             'brokerChoices' => UserTypes::getBrokerChoices(),
  840.         ]);
  841.     }
  842.     /**
  843.      * @return array|mixed
  844.      */
  845.     private function listingTitleTranslations(Listing $listingstring $locale)
  846.     {
  847.         $this->translatableListener->setTranslatableLocale($locale);
  848.         $listing->setTranslatableLocale($locale);
  849.         $this->entityManager->refresh($listing);
  850.         return $listing->getTitle() ?? $this->listingManager->listingTitleTranslations($listing$locale);
  851.     }
  852.     private function listingDescriptionTranslations(Listing $listingstring $locale)
  853.     {
  854.         $this->translatableListener->setTranslatableLocale($locale);
  855.         $listing->setTranslatableLocale($locale);
  856.         $this->entityManager->refresh($listing);
  857.         return $listing->getDescription() ?? $this->listingManager->listingTitleTranslations($listing$locale);
  858.     }
  859.     private function handleListingPhones(Listing $listing, array $phones): Listing
  860.     {
  861.         $listing->clearPhones();
  862.         foreach ($phones as $phone) {
  863.             $phoneNumber $phone['number'];
  864.             $countryCode $phone['countryCode'];
  865.             $phone = new Phone($countryCode.$phoneNumber$countryCode);
  866.             $listing->addPhone(new ListingPhone($phoneNumber$listing$countryCode$phone));
  867.         }
  868.         return $listing;
  869.     }
  870.     private function handleUserPhones(User $user, array $phones): void
  871.     {
  872.         foreach ($phones as $phone) {
  873.             $originalPhoneNumber $phone['number'];
  874.             $countryCode $phone['countryCode'];
  875.             $phoneNumber $this->phoneManager->trimZero($originalPhoneNumber$countryCode);
  876.             $this->phoneManager->addNewUserPhone($phoneNumber$countryCode$usertruefalsenull$originalPhoneNumber);
  877.         }
  878.     }
  879.     /**
  880.      * Listing Post Action
  881.      * This action manage adding & editing listings.
  882.      *
  883.      * @Route("/listing/{id}/preview/", name="listing_preview", requirements={"id" = "\d+"}, options={"expose"=true})
  884.      *
  885.      * @Security(
  886.      *     "(is_granted('IS_AUTHENTICATED_REMEMBERED') and is_granted('ROLE_OWNER', listing)) or is_granted('ROLE_ADMIN')"
  887.      * )
  888.      *
  889.      * @return array|RedirectResponse
  890.      */
  891.     public function preview(Listing $listing): Response
  892.     {
  893.         return $this->render('@AqarmapListing/Listing/preview.html.twig', [
  894.             'listing' => $listing,
  895.         ]);
  896.     }
  897.     /**
  898.      * Listing Post Action
  899.      * This action manage adding & editing listings.
  900.      *
  901.      * @Route("/listing/lite", name="listing_lite_add",  options={"expose"=true})
  902.      */
  903.     public function postLite(Request $request)
  904.     {
  905.         /** @var $em \Doctrine\ORM\EntityManager */
  906.         $em $this->getDoctrine()->getManager();
  907.         $form $this->createForm(
  908.             LiteListingType::class,
  909.             null,
  910.             ['em' => $em,
  911.                 'action' => $this->generateUrl('listing_lite_add'),
  912.                 'method' => 'post', ]
  913.         );
  914.         if ($request->isMethod('POST')) {
  915.             $form->handleRequest($request);
  916.             if ($form->isSubmitted() && $form->isValid()) {
  917.                 $listing $form->getData();
  918.                 $listing->setSellerRole(ListingSellerRoles::OWNER);
  919.                 $this->listingManager->saveListing($listing);
  920.                 // add listing phone to new phones table ;
  921.                 $this->phoneManager->addListingPhonesList($listing->getPhones(), ''$listing);
  922.                 $this->listingManager->addLiteListingTitleAndDescriptionTranslation($listing);
  923.                 $listingEvent = new ListingEvent($listing);
  924.                 $this->dispatcher->dispatch($listingEvent'aqarmap.listing.submitted');
  925.                 $this->addFlash(
  926.                     'success',
  927.                     $this->translator->trans('add_listing_page.success_messages.padding_review')
  928.                 );
  929.                 if ($this->featureToggleManager->isEnabled('web.delayed.review.eid.info.message')) {
  930.                     $this->addFlash(
  931.                         'info',
  932.                         $this->translator->trans('add_listing_page.info_messages.eid_delayed_review')
  933.                     );
  934.                 }
  935.                 return $this->redirect($this->generateUrl('homepage'));
  936.             }
  937.             $this->addFlash('danger'$this->translator->trans('static.problem_error_message'));
  938.         }
  939.         return $this->render('@AqarmapListing/Listing/postLite.html.twig', [
  940.             'form' => $form->createView(),
  941.         ]);
  942.     }
  943.     /**
  944.      * Add Listing First Step Action.
  945.      *
  946.      * @Route("/listing/{id}/edit/photos", name="listing_upload", requirements={"id" = "\d+"}, options={"expose"=true})
  947.      *
  948.      * @Security("is_granted('ROLE_ADMIN') or is_granted('ROLE_OWNER', listing)")
  949.      */
  950.     public function upload(Request $requestListing $listing)
  951.     {
  952.         $form $this->createForm(PhotoType::class, null, [
  953.             'method' => 'POST',
  954.         ]);
  955.         $form->handleRequest($request);
  956.         $listingRules $this->listingRuleMatcher->match($listing);
  957.         if ($form->isSubmitted() && $form->isValid() && $request->isMethod('POST')) {
  958.             $listingPhotos = [];
  959.             try {
  960.                 $listingPhotos $this->listingManager->addListingPhotos($listing$form->get('file')->getData());
  961.                 $listingEvent = new ListingEvent($listing);
  962.                 $this->dispatcher->dispatch($listingEvent'aqarmap.listing.submitted');
  963.                 $this->listingManager->saveListing($listing);
  964.                 // If not Ajax request
  965.                 if (!$request->isXmlHttpRequest()) {
  966.                     $this->logger->error('Not AJAX');
  967.                     return $this->redirect($request->headers->get('referer') ?: $this->generateUrl('homepage'));
  968.                 }
  969.             } catch (\Exception $exception) {
  970.                 $this->logger->error($exception->getMessage());
  971.             }
  972.             return View::create(['files' => $listingPhotos], Response::HTTP_OK);
  973.         }
  974.         return $this->render('@AqarmapListing/Listing/upload.html.twig', [
  975.             'requiredPhotosCount' => $listingRules['required_photos'] ?? 0,
  976.             'listing' => $listing,
  977.             'form' => $form->createView(),
  978.         ]);
  979.     }
  980.     /**
  981.      * Should be called after photos are uploaded.
  982.      *
  983.      * @Route("/listing/{id}/finish", requirements={"id" = "\d+"}, name="listing_finish")
  984.      *
  985.      * @return RedirectResponse|Response
  986.      */
  987.     public function finish(Listing $listing)
  988.     {
  989.         $listingEvent = new ListingEvent($listing);
  990.         $this->dispatcher->dispatch($listingEvent'aqarmap.listing.submitted');
  991.         $response $listingEvent->getResponse();
  992.         if (null === $response) {
  993.             if (ListingStatus::PENDING === $listing->getStatus()) {
  994.                 $this->addFlash(
  995.                     'success',
  996.                     $this->translator->trans('add_listing_page.success_messages.padding_review')
  997.                 );
  998.                 if ($this->featureToggleManager->isEnabled('web.delayed.review.eid.info.message')) {
  999.                     $this->addFlash(
  1000.                         'info',
  1001.                         $this->translator->trans('add_listing_page.info_messages.eid_delayed_review')
  1002.                     );
  1003.                 }
  1004.             }
  1005.             $response = new RedirectResponse(
  1006.                 $this->generateUrl(
  1007.                     'listing_slug',
  1008.                     ['id' => $listing->getId(), 'slug' => $listing->getSlug()]
  1009.                 )
  1010.             );
  1011.         }
  1012.         return $response;
  1013.     }
  1014.     /**
  1015.      * SWAT special add listing feature page.
  1016.      *
  1017.      * @Route("/listing/{id}/feature", requirements={"id" = "\d+"}, name="special_add_listing_feature")
  1018.      *
  1019.      * @Security("is_granted('ROLE_OWNER', listing)")
  1020.      */
  1021.     public function specialAddListingFeature(Listing $listing): RedirectResponse
  1022.     {
  1023.         return $this->redirectToRoute('listing_finish', ['id' => $listing->getId()]);
  1024.     }
  1025.     /**
  1026.      * @Route("/listing/{id}/make_it_featured",
  1027.      * requirements={"id" = "\d+"}, name="listing_confirm_featured_credit", methods={"GET"})
  1028.      *
  1029.      * @Security("is_granted('ROLE_OWNER', listing)")
  1030.      *
  1031.      * @return RedirectResponse|Response
  1032.      */
  1033.     public function confirmFeaturedPublishing(Listing $listing)
  1034.     {
  1035.         if (!\in_array($listing->getStatus(), [ListingStatus::PENDINGListingStatus::LIVE])) {
  1036.             $this->addFlash(
  1037.                 'danger',
  1038.                 $this->translator->trans('listing.featured_failure_statement.not_live_or_pending')
  1039.             );
  1040.             return $this->redirect($this->generateUrl('aqarmap_listing_default_mylistings'));
  1041.         }
  1042.         if (UserTypes::INDIVIDUAL == $listing->getUser()->getUserType()) {
  1043.             $listingRules $this->listingFeatureService->getFeaturedListingRules($listing, ['sold_by_owner''sold_by_owner_sponsored']);
  1044.         } else {
  1045.             $listingRules $this->listingFeatureService->getFeaturedListingRules($listing, ['featured''premium''sponsored''spotlight']);
  1046.         }
  1047.         /** @var User $user */
  1048.         $user $this->getUser();
  1049.         return $this->render(
  1050.             '@AqarmapListing/Listing/featuredListingCheckout.html.twig',
  1051.             [
  1052.                 'listingRules' => $listingRules,
  1053.                 'listingId' => $listing->getId(),
  1054.                 'haveFeesToFeature' => $this->listingManager->userHasFeesToFeature($user$listing),
  1055.             ]
  1056.         );
  1057.     }
  1058.     /**
  1059.      * @Route("/listing/{id}/make_it_featured",  options={"expose"=true} ,requirements={"id" = "\d+"},
  1060.      * name="listing_confirm_publish_featured_credit_post", methods={"POST"})
  1061.      *
  1062.      * @Security("is_granted('ROLE_OWNER', listing)")
  1063.      */
  1064.     public function prepareFeaturedListingPayment(Listing $listingRequest $request): RedirectResponse
  1065.     {
  1066.         $listingRules $this->listingManager->getListingRules($listing);
  1067.         $fees $request->query->get('fees'$listingRules['featured_fees']);
  1068.         $duration $request->query->get('duration'$listingRules['featured_duration']);
  1069.         $listingFeaturedType $request->query->get('listingFeaturedType'ListingFeaturedTypes::FEATURED);
  1070.         $listingFeature $request->query->get('listingFeature'ListingFeatures::FEATURED);
  1071.         $listingStatus $listing->getStatus();
  1072.         /** @var User $user */
  1073.         $user $this->getUser();
  1074.         if (!$this->listingManager->isAffordable($user$fees)) {
  1075.             $this->addFlash('danger'$this->translator->trans('credit.not_enough_featuring_credit', [
  1076.                 'link' => $this->generateUrl('aqarmap_buy_credit', ['listing_id' => $listing->getId()]),
  1077.             ]));
  1078.             return $this->redirect($this->generateUrl('listing_confirm_featured_credit', [
  1079.                 'id' => $listing->getId(),
  1080.             ]), Response::HTTP_FOUND);
  1081.         }
  1082.         $featuredText $this->translator->trans(ListingFeaturedTypes::getFeaturedText($listingFeaturedType));
  1083.         $rules = [
  1084.             'featuredFees' => $fees,
  1085.             'featuredDuration' => $duration,
  1086.             'listingFeaturedType' => $listingFeaturedType,
  1087.             'listingFeature' => $listingFeature,
  1088.             'featuredText' => $featuredText,
  1089.         ];
  1090.         if ($this->listingManager->requiresFeaturingReview($listingFeaturedType)) {
  1091.             try {
  1092.                 $this->listingManager->makeItFeatured($listing$rules);
  1093.                 if (ListingStatus::LIVE == $listingStatus) {
  1094.                     $this->addFlash(
  1095.                         'success',
  1096.                         $this->translator->trans('add_listing_page.success_messages.pending_featuring', [':featured_type:' => $featuredText])
  1097.                     );
  1098.                 } else {
  1099.                     $this->addFlash(
  1100.                         'success',
  1101.                         $this->translator->trans('add_listing_page.success_messages.padding_review')
  1102.                     );
  1103.                     if ($this->featureToggleManager->isEnabled('web.delayed.review.eid.info.message')) {
  1104.                         $this->addFlash(
  1105.                             'info',
  1106.                             $this->translator->trans('add_listing_page.info_messages.eid_delayed_review')
  1107.                         );
  1108.                     }
  1109.                 }
  1110.             } catch (\Exception $exception) {
  1111.                 $this->addFlash('danger'$this->translator->trans($exception->getMessage()));
  1112.             }
  1113.             if (ListingStatus::LIVE == $listingStatus) {
  1114.                 return $this->redirect($this->generateUrl('aqarmap_listing_default_mylistings'));
  1115.             }
  1116.             return $this->redirect($this->generateUrl('listing_finish', [
  1117.                 'id' => $listing->getId(),
  1118.             ]));
  1119.         }
  1120.         try {
  1121.             $this->listingManager->makeItFeatured($listing$rules);
  1122.             if (ListingStatus::LIVE == $listing->getStatus()) {
  1123.                 $this->addFlash(
  1124.                     'success',
  1125.                     $this->translator->trans(
  1126.                         'add_listing_page.success_messages.featured',
  1127.                         [':listing_title:' => $listing->getTitle(), ':featured_type:' => $featuredText]
  1128.                     )
  1129.                 );
  1130.                 return $this->redirectToRoute('aqarmap_listing_default_mylistings');
  1131.             }
  1132.             $this->addFlash(
  1133.                 'success',
  1134.                 $this->translator->trans('add_listing_page.success_messages.padding_review')
  1135.             );
  1136.             if ($this->featureToggleManager->isEnabled('web.delayed.review.eid.info.message')) {
  1137.                 $this->addFlash(
  1138.                     'info',
  1139.                     $this->translator->trans('add_listing_page.info_messages.eid_delayed_review')
  1140.                 );
  1141.             }
  1142.             return $this->redirectToRoute('listing_finish', [
  1143.                 'id' => $listing->getId(),
  1144.             ]);
  1145.         } catch (\Exception $e) {
  1146.             $buyCreditLink $this->generateUrl('page_view', ['slug' => 'buy-credit'], true);
  1147.             if ($this->setting->getSetting('features''payments')) {
  1148.                 $buyCreditLink $this->generateUrl('aqarmap_buy_credit');
  1149.             }
  1150.             $this->addFlash('danger'$this->translator->trans(
  1151.                 $e->getMessage(),
  1152.                 ['%link%' => $buyCreditLink],
  1153.                 'exceptions'
  1154.             ));
  1155.         }
  1156.         return $this->redirect($this->generateUrl('listing_confirm_featured_credit', [
  1157.             'id' => $listing->getId(),
  1158.         ]), Response::HTTP_FOUND);
  1159.     }
  1160.     /**
  1161.      * @Route(
  1162.      *     "/listing/{id}/payment_confirmation",
  1163.      *     requirements={"id" = "\d+"}, name="listing_confirm_publish_credit", methods={"GET"}
  1164.      * )
  1165.      *
  1166.      * @Security("is_granted('ROLE_ADMIN') or is_granted('ROLE_OWNER', listing)")
  1167.      *
  1168.      * @return array|RedirectResponse
  1169.      */
  1170.     public function confirmPublishing(Listing $listing)
  1171.     {
  1172.         $listingRule $this->listingRuleMatcher->match($listing);
  1173.         /** @var $em \Doctrine\ORM\EntityManager */
  1174.         $em $this->getDoctrine()->getManager();
  1175.         // User Balance
  1176.         $userDetails $listing->getUser();
  1177.         $available_balance $this->userPackagesRepository->getTotalCreditsByUser($userDetails);
  1178.         $userId $userDetails->getId();
  1179.         $em->getRepository(User::class)->findOneBy(['id' => $userId]);
  1180.         $listingManger $this->listingManager;
  1181.         try {
  1182.             $this->dispatcher->dispatch(new ListingEvent($listing), 'aqarmap.listing.can_list_in_location');
  1183.         } catch (CanListInLocationException $exception) {
  1184.             $this->addFlash('danger'$this->translator->trans('credit.can_not_list_in_location'));
  1185.             return $this->redirect($this->generateUrl('aqarmap_listing_default_mylistings'), Response::HTTP_FOUND);
  1186.         }
  1187.         $userServiceRepository $em->getRepository(UserServices::class);
  1188.         if ($this->userServicesManager->hasActiveService(UserServicesType::UNLIMITED_LISTINGS$userId)
  1189.             && ListingCategories::UNLIMITED != $listing->getCategory()
  1190.             && ListingStatus::DRAFT != $listing->getStatus()
  1191.         ) {
  1192.             if ($userServiceRepository
  1193.                     ->passUnlimitedListing($listing$this->creditManager$listingManger) || $listing->getPublicationCredit()
  1194.             ) {
  1195.                 if ($this->listingFeatureService->isFeaturedOffersAvailable($listing)) {
  1196.                     return $this->redirect($this->generateUrl('listing_confirm_featured_credit', [
  1197.                         'id' => $listing->getId(),
  1198.                     ]));
  1199.                 }
  1200.                 return $this->redirect($this->generateUrl('listing_finish', [
  1201.                     'id' => $listing->getId(),
  1202.                 ]));
  1203.             }
  1204.         }
  1205.         $isUserInSpecialAddListingGroup $this->specialAddListingService->hasSpecialAddListingGroup($userDetails);
  1206.         $userUnlimitedListings $this->userServicesManager->hasActiveService(UserServicesType::UNLIMITED_LISTINGS$userId);
  1207.         $userHasNoFreeListingService = !$userUnlimitedListings;
  1208.         $userHasNoFreeListingQuote = ($userUnlimitedListings && == $userUnlimitedListings['remainingQuota']);
  1209.         if ($isUserInSpecialAddListingGroup) {
  1210.             if ($userHasNoFreeListingService || $userHasNoFreeListingQuote) {
  1211.                 return $this->redirectToRoute('special_add_listing_feature', ['id' => $listing->getId()]);
  1212.             }
  1213.         }
  1214.         $form $this->ConfirmPaymentForm($listing);
  1215.         return $this->render(
  1216.             '@AqarmapListing/Listing/confirmPublishing.html.twig',
  1217.             [
  1218.                 'listing' => $listing,
  1219.                 'fees' => $listingRule['publication_fees'],
  1220.                 'duration' => $listingRule['duration'],
  1221.                 'available_balance' => $available_balance,
  1222.                 'form' => $form->createView(),
  1223.             ]
  1224.         );
  1225.     }
  1226.     /**
  1227.      * @Route(
  1228.      *     "/listing/{id}/list_rejections",
  1229.      *     requirements={"id" = "\d+"},
  1230.      *     name="listing_list_rejections", methods={"GET"}
  1231.      * )
  1232.      *
  1233.      * @Security("is_granted('ROLE_OWNER', listing)")
  1234.      *
  1235.      * @return array
  1236.      */
  1237.     public function listRejections(Listing $listingRequest $request): Response
  1238.     {
  1239.         if ($request->get('notification')) {
  1240.             try {
  1241.                 $this->databaseNotification->markOneAsRead($request->get('notification'));
  1242.             } catch (\Exception $exception) {
  1243.                 $this->logger->log(LogLevel::ERROR$exception->getMessage());
  1244.             }
  1245.         }
  1246.         return $this->render(
  1247.             '@AqarmapListing/Listing/confirmPublishing.html.twig',
  1248.             [
  1249.                 'listing' => $listing,
  1250.             ]
  1251.         );
  1252.     }
  1253.     /**
  1254.      * @Route(
  1255.      *     "/listing/{id}/payment_confirmation",
  1256.      *     requirements={"id" = "\d+"}, name="listing_confirm_publish_credit_post", methods={"POST"}
  1257.      * )
  1258.      *
  1259.      * @Security("is_granted('ROLE_ADMIN') or is_granted('ROLE_OWNER', listing)")
  1260.      *
  1261.      * @return array|RedirectResponse
  1262.      */
  1263.     public function prepareListingPayment(Listing $listingRequest $requestUserPackagesService $userPackagesService): RedirectResponse
  1264.     {
  1265.         $listingRule $this->listingRuleMatcher->match($listing);
  1266.         /** @var EntityManager $em */
  1267.         $em $this->getDoctrine()->getManager();
  1268.         // User Balance
  1269.         $available_balance $this->userPackagesRepository->getTotalCreditsByUser($listing->getUser());
  1270.         $userId $listing->getUser()->getId();
  1271.         $listingManger $this->listingManager;
  1272.         try {
  1273.             $this->dispatcher->dispatch(new ListingEvent($listing), 'aqarmap.listing.can_list_in_location');
  1274.         } catch (CanListInLocationException $exception) {
  1275.             $this->addFlash('danger'$this->translator->trans('credit.can_not_list_in_location'));
  1276.             return $this->redirect($this->generateUrl('listing_confirm_publish_credit', [
  1277.                 'id' => $listing->getId(),
  1278.             ]), Response::HTTP_FOUND);
  1279.         }
  1280.         $userServiceRepository $em->getRepository(UserServices::class);
  1281.         if ($this->userServicesManager->hasActiveService(UserServicesType::UNLIMITED_LISTINGS$userId)) {
  1282.             if ($userServiceRepository->passUnlimitedListing($listing$this->creditManager$listingManger)
  1283.             ) {
  1284.                 if (!$this->listingFeatureService->isFeaturedOffersAvailable($listing)) {
  1285.                     return $this->redirect($this->generateUrl('listing_finish', [
  1286.                         'id' => $listing->getId(),
  1287.                     ]));
  1288.                 }
  1289.                 return $this->redirect($this->generateUrl('listing_confirm_featured_credit', [
  1290.                     'id' => $listing->getId(),
  1291.                 ]));
  1292.             }
  1293.         }
  1294.         $form $this->ConfirmPaymentForm($listing);
  1295.         $form->handleRequest($request);
  1296.         if ($form->isSubmitted() && $form->isValid()) {
  1297.             // Payment Confirmed?
  1298.             // If user cancel payment redirect him to his listing,
  1299.             if (!$form->get('confirm')->isClicked()) {
  1300.                 return $this->redirect($this->generateUrl('listing_view', [
  1301.                     'id' => $listing->getId(),
  1302.                 ]), Response::HTTP_FOUND);
  1303.             }
  1304.             // If user credit expired, complain.
  1305.             $enforceCredit $this->setting->getSetting('features''enforce_credits_expiration');
  1306.             /** @var User $user */
  1307.             $user $this->getUser();
  1308.             if ($enforceCredit && === $user->getAbsoluteCreditExpiryDays()) {
  1309.                 $this->addFlash('danger'$this->translator->trans('credit.credit_can_not_use', [
  1310.                     'link' => $this->generateUrl('aqarmap_buy_credit', ['listing_id' => $listing->getId()]),
  1311.                 ]));
  1312.                 return $this->redirect($this->generateUrl('listing_confirm_publish_credit', [
  1313.                     'id' => $listing->getId(),
  1314.                 ]), Response::HTTP_FOUND);
  1315.             }
  1316.             // User already paid
  1317.             if ($listing->getPublicationCredit()) {
  1318.                 $this->addFlash('info'$this->translator->trans('credit.already_paid'));
  1319.             } else {
  1320.                 // User don't have enough credits
  1321.                 if ($listingRule['publication_fees'] > $available_balance) {
  1322.                     $this->addFlash('danger'$this->translator->trans('credit.not_enough_credits'));
  1323.                 } else {
  1324.                     // Subtract publication fees
  1325.                     $credits $this->creditManager->deduction(
  1326.                         $listing->getUser(),
  1327.                         $listingRule['publication_fees'],
  1328.                         'Listing Fees'
  1329.                     );
  1330.                     foreach ($credits as $credit) {
  1331.                         if ($credit instanceof Credit) {
  1332.                             $credit->setStatus(CreditStatus::SUCCESS);
  1333.                             $this->listingManager->addFeature($listingListingFeatures::PAIDnull$credit);
  1334.                             if (!$this->listingFeatureService->isFeaturedOffersAvailable($listing)) {
  1335.                                 return $this->redirect($this->generateUrl('listing_finish', [
  1336.                                     'id' => $listing->getId(),
  1337.                                 ]));
  1338.                             }
  1339.                         }
  1340.                     }
  1341.                     return $this->redirect($this->generateUrl('listing_confirm_featured_credit', [
  1342.                         'id' => $listing->getId(),
  1343.                         'ref' => 'add_listing',
  1344.                     ]));
  1345.                 }
  1346.             }
  1347.         }
  1348.         $this->addFlash('danger''Unexpected error occurred.');
  1349.         return $this->redirect($this->generateUrl('listing_confirm_publish_credit', [
  1350.             'id' => $listing->getId(),
  1351.         ]));
  1352.     }
  1353.     private function ConfirmPaymentForm(Listing $listing)
  1354.     {
  1355.         return $this->createForm(ConfirmFormType::class, null, [
  1356.             'method' => 'POST',
  1357.             'action' => $this->generateUrl('listing_confirm_publish_credit_post', ['id' => $listing->getId()]),
  1358.         ]);
  1359.     }
  1360.     /**
  1361.      * @return \Symfony\Component\Form\Form
  1362.      */
  1363.     private function confirmFeaturedPaymentForm(Listing $listing)
  1364.     {
  1365.         return $this->createForm(ConfirmFeaturedFormType::class, null, [
  1366.             'method' => 'POST',
  1367.             'action' => $this
  1368.                 ->generateUrl(
  1369.                     'listing_confirm_publish_featured_credit_post',
  1370.                     ['id' => $listing->getId()]
  1371.                 ),
  1372.         ]);
  1373.     }
  1374.     /**
  1375.      * Delete Listing entity.
  1376.      *
  1377.      * @Route("/listing/{id}/delete", requirements={"id" = "\d+"}, name="listing_delete", options={"expose"=true})
  1378.      *
  1379.      * @Security("is_granted('ROLE_ADMIN') or is_granted('ROLE_OWNER', listing)")
  1380.      */
  1381.     public function delete(Listing $listingRequest $request): RedirectResponse
  1382.     {
  1383.         if (\in_array('ROLE_PREVENT_DELETE_LISTING'$this->getUser()->getRoles())) {
  1384.             throw new AccessDeniedHttpException("Forbidden, user don't have this permession.");
  1385.         }
  1386.         if (ListingStatus::EXPIRED == $listing->getStatus()) {
  1387.             throw $this->createNotFoundException('Listing is expired.');
  1388.         }
  1389.         $this->listingManager->remove($listingListingStatus::USER_DELETED);
  1390.         $this->addFlash(
  1391.             'success',
  1392.             $this->translator->trans('add_listing_page.success_messages.deleted')
  1393.         );
  1394.         return $this->redirect($request->headers->get('referer') ?: $this->generateUrl('homepage'));
  1395.     }
  1396.     /**
  1397.      * unDelete Listing entity.
  1398.      *
  1399.      * @Route("/listing/{id}/undelete", requirements={"id" = "\d+"}, name="listing_undelete")
  1400.      *
  1401.      * @Security("is_granted('ROLE_ADMIN') or is_granted('ROLE_OWNER', listing)")
  1402.      *
  1403.      * @return RedirectResponse|Response|null
  1404.      */
  1405.     public function undelete(Listing $listing)
  1406.     {
  1407.         if (ListingStatus::USER_DELETED != $listing->getStatus()) {
  1408.             throw $this->createNotFoundException('Unable to find this listing.');
  1409.         }
  1410.         $this->getDoctrine()->getManager();
  1411.         $this->listingManager->changeStatus($listingListingStatus::PENDING);
  1412.         $listingEvent = new ListingEvent($listing);
  1413.         $this->dispatcher->dispatch($listingEvent'aqarmap.listing.submitted');
  1414.         $response $listingEvent->getResponse();
  1415.         if (null === $response) {
  1416.             if (ListingStatus::PENDING === $listing->getStatus()) {
  1417.                 $this->addFlash(
  1418.                     'success',
  1419.                     $this->translator->trans('add_listing_page.success_messages.padding_review')
  1420.                 );
  1421.                 if ($this->featureToggleManager->isEnabled('web.delayed.review.eid.info.message')) {
  1422.                     $this->addFlash(
  1423.                         'info',
  1424.                         $this->translator->trans('add_listing_page.info_messages.eid_delayed_review')
  1425.                     );
  1426.                 }
  1427.             }
  1428.             $response = new RedirectResponse(
  1429.                 $this->generateUrl(
  1430.                     'listing_slug',
  1431.                     ['id' => $listing->getId(), 'slug' => $listing->getSlug()]
  1432.                 )
  1433.             );
  1434.         }
  1435.         return $response;
  1436.     }
  1437.     /**
  1438.      * Creates "Request a Call" button.
  1439.      *
  1440.      * @return \Symfony\Component\Form\Form
  1441.      */
  1442.     public function callRequestForm(Listing $listing)
  1443.     {
  1444.         return $this->createForm(CallRequestFormType::class, null, [
  1445.             'method' => 'POST',
  1446.             'action' => $this->generateUrl('aqarmap_listing_call_request', ['id' => $listing->getId()]),
  1447.         ]);
  1448.     }
  1449.     /**
  1450.      * Creates contact seller form.
  1451.      *
  1452.      * @param Listing $listing The listing entity
  1453.      *
  1454.      * @return \Symfony\Component\Form\Form The form
  1455.      */
  1456.     public function contactSellerForm(Listing $listing)
  1457.     {
  1458.         return $this->createForm(ContactSellerFormType::class, null, [
  1459.             'method' => 'POST',
  1460.             'action' => $this->generateUrl('aqarmap_listing_contact_seller', ['id' => $listing->getId()]),
  1461.         ]);
  1462.     }
  1463.     /**
  1464.      * Creates contact seller form.
  1465.      *
  1466.      * @param Listing $listing The listing entity
  1467.      *
  1468.      * @return \Symfony\Component\Form\Form The form
  1469.      */
  1470.     public function contactSellerWideForm(Listing $listing)
  1471.     {
  1472.         return $this->createForm(ContactSellerWideFormType::class, null, [
  1473.             'method' => 'POST',
  1474.             'action' => $this->generateUrl('aqarmap_listing_contact_seller', ['id' => $listing->getId()]),
  1475.         ]);
  1476.     }
  1477.     /**
  1478.      * Creates quick registration form.
  1479.      *
  1480.      * @return \Symfony\Component\Form\Form The form
  1481.      */
  1482.     public function quickRegistrationForm()
  1483.     {
  1484.         return $this->createForm(QuickRegistrationFormType::class, null, [
  1485.             'method' => 'POST',
  1486.             'action' => $this->generateUrl('aqarmap_user_quick_registration'),
  1487.         ]);
  1488.     }
  1489.     /**
  1490.      * Contact Seller Action.
  1491.      *
  1492.      * @Route("/listing/{id}/contact_seller", requirements={"id" = "\d+"}, name="aqarmap_listing_contact_seller", options={"expose"=true}, defaults={"_format": "json"}, methods={"POST"})
  1493.      *
  1494.      * @Rest\View()
  1495.      *
  1496.      * @return array|\Symfony\Component\Form\Form
  1497.      */
  1498.     public function contactSeller(Listing $listingRequest $request)
  1499.     {
  1500.         $form $this->contactSellerForm($listing);
  1501.         if ($request->request->has('contact_seller_wide')) {
  1502.             $form $this->contactSellerWideForm($listing);
  1503.         }
  1504.         $lead $request->get('lead');
  1505.         $originalPhoneNumber $lead['phone'];
  1506.         $phoneNumber $lead $this->phoneManager->trimZero($lead['phone'], $request->get('countryCode')) : null;
  1507.         $message json_decode((string) $request->get('message'), true);
  1508.         $hasEmail = !$request->get('isAutoGeneratedEmail'0);
  1509.         $user $this->getUser();
  1510.         $form->handleRequest($request);
  1511.         if ($lead) {
  1512.             $form $this->createForm(QuickLeadType::class, null, [
  1513.                 'method' => 'POST',
  1514.                 'csrf_protection' => false,
  1515.             ]);
  1516.             /** @var User $user */
  1517.             $user $this->FOSUserManager->findUserByEmail($lead['email']);
  1518.             if (!$user && !$hasEmail) {
  1519.                 $user $this->userManager->findLatestByPhone($phoneNumber$request->get('countryCode'));
  1520.             }
  1521.             if (!$user && $hasEmail) {
  1522.                 $user $this->userManager->findAndReplaceUserAndEmail($phoneNumber$lead['email'], $request->get('countryCode'));
  1523.             }
  1524.             $phone $this->phoneManager->findOrSavePhoneNumber($phoneNumber$request->get('countryCode'), null$originalPhoneNumber);
  1525.             if (!$user) {
  1526.                 $user $this->FOSUserManager->createUser();
  1527.                 $user
  1528.                     ->setFullName($lead['name'])
  1529.                     ->setPhoneNumber($lead['phone'])
  1530.                     ->setTempOriginalPhoneNumber($originalPhoneNumber)
  1531.                     ->setEmail($lead['email'])
  1532.                     ->setHasEmail($hasEmail)
  1533.                     ->setIsQucikRegistered(true)
  1534.                 ;
  1535.                 $this->userManager->quickRegister($user$form$requesttruefalsefalse);
  1536.                 $registerMessage $this->translator->trans('popup_form.success');
  1537.             }
  1538.             $this->phoneManager->addNewUserPhone($phoneNumber$request->get('countryCode'), $usertruefalsenull$originalPhoneNumber);
  1539.         }
  1540.         if ($request->isMethod('POST')) {
  1541.             // Get current logged in user
  1542.             $user ??= $this->getUser();
  1543.             $composer $this->messageComposer;
  1544.             $composer
  1545.                 ->setSender($user)
  1546.                 ->compose($message['content'], $listingnull$message['type'] ?? LeadTypes::SEND_MESSAGE)
  1547.             ;
  1548.             $this->addFlash(
  1549.                 'success',
  1550.                 $this->translator->trans('add_listing_page.success_messages.message_sent')
  1551.             );
  1552.             return [
  1553.                 'status' => 'ok',
  1554.                 'message' => $this->translator->trans('listing.success_message_seller'),
  1555.             ];
  1556.         }
  1557.         return $form;
  1558.     }
  1559.     /**
  1560.      * Contact Seller Action.
  1561.      *
  1562.      * @Route("/listing/{id}/call_request", requirements={"id" = "\d+", "_format" = "json"},
  1563.      *      name="aqarmap_listing_call_request",
  1564.      *      options={"expose"=true},
  1565.      *      defaults={"_format": "json"},
  1566.      *      methods={"POST"}
  1567.      * )
  1568.      *
  1569.      * @Rest\View()
  1570.      */
  1571.     public function callRequest(Request $requestListing $listing)
  1572.     {
  1573.         $lead $request->get('lead');
  1574.         $countryCode $request->get('countryCode'$lead['countryCode'] ?? '+20');
  1575.         $originalPhoneNumber $lead['phone'];
  1576.         $phoneNumber $lead $this->phoneManager->trimZero($lead['phone'], $countryCode) : null;
  1577.         $user $this->getUser();
  1578.         $registerMessage '';
  1579.         $callRequest = new CallRequest();
  1580.         if ($lead) {
  1581.             $form $this->createForm(QuickLeadType::class, null, [
  1582.                 'method' => 'POST',
  1583.                 'csrf_protection' => false,
  1584.             ]);
  1585.             $form->handleRequest($request);
  1586.             $hasEmail = !$request->get('isAutoGeneratedEmail'0);
  1587.             /** @var User $user */
  1588.             $user $this->FOSUserManager->findUserByEmail($lead['email']);
  1589.             if (!$user && !$hasEmail) {
  1590.                 $user $this->userManager->findLatestByPhone($phoneNumber$countryCode);
  1591.             }
  1592.             if (!$user && $hasEmail) {
  1593.                 $user $this->userManager->findAndReplaceUserAndEmail($phoneNumber$lead['email'], $request->get('countryCode'));
  1594.             }
  1595.             $phone $this->phoneManager->findOrSavePhoneNumber($phoneNumber$countryCodenull$originalPhoneNumber);
  1596.             if (!$user) {
  1597.                 $user $this->FOSUserManager->createUser();
  1598.                 $user
  1599.                     ->setFullName($lead['name'])
  1600.                     ->setPhoneNumber($lead['phone'])
  1601.                     ->setTempCountryCode($countryCode)
  1602.                     ->setTempOriginalPhoneNumber($originalPhoneNumber)
  1603.                     ->setEmail($lead['email'])
  1604.                     ->setHasEmail($hasEmail)
  1605.                     ->setIsQucikRegistered(true)
  1606.                 ;
  1607.                 $this->userManager->quickRegister($user$form$requesttruefalsefalse);
  1608.                 $registerMessage $this->translator->trans('popup_form.success');
  1609.             }
  1610.             $callRequest->setPhone($phone);
  1611.             $callRequest->setLeadEmail($lead['email']);
  1612.             $callRequest->setLeadFullName($lead['name']);
  1613.             $this->phoneManager->addNewUserPhone($phoneNumber$countryCode$usertruefalsenull$originalPhoneNumber);
  1614.         }
  1615.         // Create Call Request
  1616.         $callRequest->setUser($user);
  1617.         $callRequest->setListing($listing);
  1618.         $form $this->callRequestForm($listing);
  1619.         $form->handleRequest($request);
  1620.         $isPostRequestAndValidForm $request->isMethod('POST') && ($form->isSubmitted() && $form->isValid());
  1621.         $isNotCheckForm = (false == $request->get('check_form'));
  1622.         if ($isPostRequestAndValidForm || $isNotCheckForm) {
  1623.             try {
  1624.                 $this->callRequestManager->submitCallRequest($callRequestnull$request->query->get('sourceRoute'''));
  1625.                 return [
  1626.                     'status' => 'ok',
  1627.                     'message' => $this->translator->trans('listing.success_call_request'),
  1628.                     'registerMessage' => $registerMessage,
  1629.                 ];
  1630.             } catch (InvalidLeadValidationHttpException $exception) {
  1631.                 return [
  1632.                     'status' => $exception->getStatusCode(),
  1633.                     'message' => $exception->getMessage(),
  1634.                 ];
  1635.             }
  1636.         }
  1637.         return $form;
  1638.     }
  1639.     /**
  1640.      * Show how to add a listing for new users.
  1641.      *
  1642.      * @Route("/add_listing", name="aqarmap_add_listing")
  1643.      */
  1644.     public function addListingRoles(): Response
  1645.     {
  1646.         return $this->render(
  1647.             '@AqarmapListing/Listing/addListingRoles.html.twig',
  1648.             [
  1649.             ]
  1650.         );
  1651.     }
  1652.     /**
  1653.      * @Route("/listing/{id}/relist", requirements={"id" = "\d+"}, name="aqarmap_listing_relist", options={"expose"=true} )
  1654.      *
  1655.      * @Security("is_granted('ROLE_ADMIN') or is_granted('ROLE_OWNER', listing)")
  1656.      *
  1657.      * @return RedirectResponse|Response
  1658.      */
  1659.     public function relist(Listing $listing)
  1660.     {
  1661.         if (!\in_array($listing->getStatus(), [ListingStatus::EXPIREDListingStatus::USER_DELETED])) {
  1662.             throw new LogicHttpException('Whoops! Looks like the listing you are trying to relist in not expired!');
  1663.         }
  1664.         $em $this->getDoctrine()->getManager();
  1665.         $listingRepo $em->getRepository(Listing::class);
  1666.         $relistChild $listingRepo->getRelistChild($listing);
  1667.         if ($relistChild) {
  1668.             $this->addFlash(
  1669.                 'success',
  1670.                 $this->translator->trans('add_listing_page.success_messages.relist')
  1671.             );
  1672.             return new RedirectResponse(
  1673.                 $this
  1674.                     ->generateUrl(
  1675.                         'listing_slug',
  1676.                         ['id' => $relistChild->getId(),
  1677.                             'slug' => $relistChild->getSlug(), ]
  1678.                     )
  1679.             )
  1680.             ;
  1681.         }
  1682.         $listing $this->listingManager->relist($listing);
  1683.         // Check if the listing require more photos or require repayment, and redirection.
  1684.         $listingEvent = new ListingEvent($listing);
  1685.         $this->dispatcher->dispatch($listingEvent'aqarmap.listing.resubmitted');
  1686.         $response $listingEvent->getResponse();
  1687.         if (null === $response) {
  1688.             if (\in_array($listing->getStatus(), [ListingStatus::PENDINGListingStatus::LIVE])) {
  1689.                 $this->addFlash(
  1690.                     'success',
  1691.                     $this->translator->trans('add_listing_page.success_messages.relist')
  1692.                 );
  1693.             }
  1694.             $response = new RedirectResponse(
  1695.                 $this
  1696.                     ->generateUrl(
  1697.                         'listing_slug',
  1698.                         [
  1699.                             'id' => $listing->getId(),
  1700.                             'slug' => $listing->getSlug(),
  1701.                         ]
  1702.                     )
  1703.             );
  1704.         }
  1705.         return $response;
  1706.     }
  1707.     /**
  1708.      * @Route(
  1709.      *     "/listing/transfer/scraped/{id}",
  1710.      *     requirements={"id" = "\d+"},
  1711.      *     name="aqarmap_listing_transfer_ownership",
  1712.      *     options={"expose"=true},
  1713.      *     methods={"POST"},
  1714.      * )
  1715.      */
  1716.     public function transferScrapedListingOwnership(Listing $listing)
  1717.     {
  1718.         /** @var User $user */
  1719.         $user $this->getUser();
  1720.         /** @var EntityManager $em */
  1721.         $em $this->getDoctrine()->getManager();
  1722.         if (!$listing->canChangeScrapedListing()) {
  1723.             throw new LogicHttpException();
  1724.         }
  1725.         $listing->setUser($user);
  1726.         $em->persist($listing);
  1727.         $em->flush($listing);
  1728.         return new JsonResponse();
  1729.     }
  1730.     /**
  1731.      * @Route("/listing/{id}/pump_up",
  1732.      * requirements={"id" = "\d+"}, name="confirm_listing_pump_up", methods={"POST"})
  1733.      *
  1734.      * @Security("is_granted('ROLE_OWNER', listing)")
  1735.      */
  1736.     public function confirmPumpUpListing(Listing $listingRequest $request): RedirectResponse
  1737.     {
  1738.         $pumpUpForm $this->confirmFeaturedPaymentForm($listing);
  1739.         $pumpUpForm->handleRequest($request);
  1740.         if ($request->isMethod('POST') && $pumpUpForm->isValid()) {
  1741.             if (!$pumpUpForm->get('confirm')->isClicked()) {
  1742.                 return $this->redirect($this->generateUrl('aqarmap_listing_default_mylistings'), Response::HTTP_FOUND);
  1743.             }
  1744.             try {
  1745.                 $this->listingManager->pumpUp($listing);
  1746.                 $this->addFlash(
  1747.                     'success',
  1748.                     $this->translator->trans('credit.pump_up_success', [':listing_title:' => $listing->getTitle()])
  1749.                 );
  1750.             } catch (\Exception $e) {
  1751.                 $this->addFlash('danger'$e->getMessage());
  1752.             }
  1753.         }
  1754.         return $this->redirect($this->generateUrl('aqarmap_listing_default_mylistings'));
  1755.     }
  1756.     /**
  1757.      * @Route("/listing/{id}/pump_up",
  1758.      * requirements={"id" = "\d+"}, name="listing_pump_up", methods={"GET"})
  1759.      *
  1760.      * @Security("is_granted('ROLE_OWNER', listing)")
  1761.      *
  1762.      * @return array|RedirectResponse
  1763.      */
  1764.     public function pumpUpListing(Listing $listing)
  1765.     {
  1766.         $listingRules $this->listingManager->getListingRules($listing);
  1767.         $listingOwner $listing->getUser();
  1768.         $pumpUpFees $listingRules['pump_up_fees'];
  1769.         $pumpUpOccurrence $listingRules['pump_up_occurrence'];
  1770.         $pumpUpDuration $listingRules['pump_up_duration'];
  1771.         if (!$this->listingManager->isPumpUpAvailable($listingRules)) {
  1772.             $this->addFlash(
  1773.                 'danger',
  1774.                 $this->translator->trans('credit.pump_up_not_available')
  1775.             );
  1776.             return $this->redirect($this->generateUrl('aqarmap_listing_default_mylistings'));
  1777.         }
  1778.         if (!$this->listingManager->isAffordable($listingOwner$pumpUpFees)) {
  1779.             $this->addFlash(
  1780.                 'danger',
  1781.                 $this->translator->trans('credit.pump_up_can_not_use')
  1782.             );
  1783.             return $this->redirect($this->generateUrl('aqarmap_listing_default_mylistings'));
  1784.         }
  1785.         /** @var $em \Doctrine\ORM\EntityManager */
  1786.         $em $this->getDoctrine()->getManager();
  1787.         $em->getRepository(Credit::class);
  1788.         $pumpUpForm $this->createForm(ConfirmFeaturedFormType::class, null, [
  1789.             'method' => 'POST',
  1790.             'action' => $this
  1791.                 ->generateUrl(
  1792.                     'listing_pump_up',
  1793.                     ['id' => $listing->getId()]
  1794.                 ),
  1795.             'confirm_message' => $this->translator->trans('listing.pump_up.confirm'),
  1796.             'cancel_message' => $this->translator->trans('listing.pump_up.cancel'),
  1797.         ]);
  1798.         return $this->render(
  1799.             '@AqarmapListing/Listing/pumpUpListing.html.twig',
  1800.             [
  1801.                 'fees' => $pumpUpFees,
  1802.                 'duration' => $pumpUpDuration,
  1803.                 'occurrence' => $pumpUpOccurrence,
  1804.                 'form' => $pumpUpForm->createView(),
  1805.             ]
  1806.         );
  1807.     }
  1808.     /**
  1809.      * Listing Details Single Page App.
  1810.      *
  1811.      * @Route("/listingApp/{id}", requirements={"id" = "\d+"} , options={"expose" = true} , name="listing_details_app", methods={"GET"})
  1812.      */
  1813.     public function listingDetailsApp(Listing $listing): Response
  1814.     {
  1815.         return $this->render(
  1816.             '@AqarmapListing/Listing/listingDetailsApp.html.twig',
  1817.             [
  1818.                 'listingId' => $listing->getReferenceId(),
  1819.             ]
  1820.         );
  1821.     }
  1822.     /**
  1823.      * Update WhatsApp Phones.
  1824.      */
  1825.     private function updateWhatsAppPhones(int $userId, array $phones = [], array $whatsApp = []): void
  1826.     {
  1827.         foreach ($phones as $index => $phone) {
  1828.             $whatsApp[$index] = isset($whatsApp[$index]) && 'true' === $whatsApp[$index];
  1829.             $this->phoneManager->updateWhatsApp($userId, (int) $phone$whatsApp[$index], true);
  1830.         }
  1831.     }
  1832. }