- <?php
- namespace DcSiteBundle\Controller;
- use CoreBundle\Component\CoreFormFactory;
- use CoreBundle\Component\FormManager;
- use CoreBundle\Controller\ViDiController;
- use CoreBundle\Entity\Dealer;
- use CoreBundle\Entity\Model;
- use CoreBundle\Factory\Vehicle as VehicleFactory;
- use CoreBundle\Model\Api\OnlineService\ApiServer1C;
- use CoreBundle\Model\Vehicles\AbstractVehicle;
- use CoreBundle\Model\Vehicles\InStockVehicle;
- use CoreBundle\Model\Vehicles\Repository;
- use CoreBundle\Model\Vehicles\Vehicle;
- use CoreBundle\Services\MediaExtensionVidi;
- use DateTime;
- use Doctrine\ORM\EntityManagerInterface;
- use Exception;
- use MyBundle\Entity\Basket;
- use PortalBundle\Model\SeoMetaTag;
- use Symfony\Component\Filesystem\Filesystem;
- use Symfony\Component\HttpFoundation\JsonResponse;
- use Symfony\Component\HttpFoundation\Request;
- use Symfony\Component\HttpFoundation\RequestStack;
- use Symfony\Component\HttpFoundation\Response;
- use Symfony\Component\HttpFoundation\Session\SessionInterface;
- use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
- use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
- use Symfony\Component\Routing\RouterInterface;
- use Symfony\Component\String\UnicodeString;
- use Twig\Environment;
- class BaseDcController extends ViDiController
- {
-     protected SeoMetaTag $seoMetaTag;
-     protected RequestStack $requestStack;
-     protected RouterInterface $router;
-     protected FormManager $formManager;
-     protected EntityManagerInterface $em;
-     protected ApiServer1C $apiServer1C;
-     protected SessionInterface $session;
-     protected Filesystem $filesystem;
-     protected MediaExtensionVidi $mediaExtensionVidi;
-     protected Repository $vehicleRepository;
-     protected VehicleFactory $vehicleFactory;
-     protected Environment $twig;
-     public function __construct(CoreFormFactory    $coreFormFactory, SeoMetaTag $seoMetaTag, RequestStack $requestStack,
-                                 RouterInterface    $router, FormManager $formManager, EntityManagerInterface $em,
-                                 ApiServer1C        $apiServer1C, SessionInterface $session, Filesystem $filesystem,
-                                 MediaExtensionVidi $mediaExtensionVidi, Repository $vehicleRepository,
-                                 VehicleFactory     $vehicleFactory, Environment $twig)
-     {
-         parent::__construct($coreFormFactory);
-         $this->seoMetaTag = $seoMetaTag;
-         $this->router = $router;
-         $this->formManager = $formManager;
-         $this->em = $em;
-         $this->apiServer1C = $apiServer1C;
-         $this->session = $session;
-         $this->filesystem = $filesystem;
-         $this->mediaExtensionVidi = $mediaExtensionVidi;
-         $this->vehicleRepository = $vehicleRepository;
-         $this->vehicleFactory = $vehicleFactory;
-         $this->twig = $twig;
-         $this->requestStack = $requestStack;
-     }
-     const DEALER_CITY_ID = 3;
-     /**
-      * @var array
-      */
-     private static $dealers = [];
-     private $js = [];
-     private $baseJs = [];
-     private $jsParams = [];
-     protected function sendSmsLead(Request $request): JsonResponse
-     {
-         $formName = '';
-         $formPhone = '';
-         $formData = [
-             'vin' => '', 'visit_date' => '', 'model' => '', 'brand' => '', 'year' => '', 'data' => []
-         ];
-         try {
-             if (empty($request->get('vin'))) {
-                 throw new Exception("Не вказано 'vin'");
-             }
-             if (empty($request->get('visitDate'))) {
-                 throw new Exception("Не вказано 'visitDate'");
-             }
-             $formData['vin'] = $request->get('vin');
-             $formData['visit_date'] = str_replace('%', '-', $request->get('visitDate'));
-             $arr = $this->apiServer1C->getHistory($formData['vin']);
-             if (empty($arr)) {
-                 throw new Exception("Не знайдено '{$formData['vin']}'");
-             }
-             if (!empty($arr['ModelID'])) {
-                 /**
-                  * @var $model Model
-                  */
-                 $model = $this->em
-                     ->getRepository(Model::class)
-                     ->findOneBy(['uid_1c' => $arr['ModelID']]);
-                 if (!empty($model)) {
-                     $formData['model'] = $model->getTitle();
-                     $formData['brand'] = $model->getBrand()->getName();
-                 }
-             }
-             if (!empty($arr['LastOwner'])) {
-                 $formName = $arr['LastOwner'];
-             }
-             if (!empty($arr['Phone'])) {
-                 $formPhone = $arr['Phone'];
-             }
-             if (!empty($arr['Year'])) {
-                 $formData['year'] = $arr['Year'];
-             }
-             if (!empty($arr['data'])) {
-                 $formData['data'] = $arr['data'];
-             }
-             $this->formManager->saveSmsLeadForm(
-                 $request,
-                 $this->getDealer(),
-                 $formName,
-                 $formPhone,
-                 $formData
-             );
-             return $this->success();
-         } catch (Exception $e) {
-             return $this->error($e);
-         }
-     }
-     protected function checkSend(Request $request): bool
-     {
-         $vin = $request->get('vin');
-         $visitDate = str_replace('%', '-', $request->get('visitDate'));
-         $toCheck = md5($vin . $visitDate);
-         $inSes = $this->session->get('nselectcheck');
-         $inSes = is_array($inSes) ? $inSes : [];
-         if (!in_array($toCheck, $inSes)) {
-             $inSes[] = $toCheck;
-             $this->session->set('nselectcheck', $inSes);
-             return false;
-         } else {
-             return true;
-         }
-     }
-     public function getDealer(): Dealer
-     {
-         $request = $this->requestStack->getCurrentRequest();
-         $host = $request->getHost();
-         if (!isset(self::$dealers[md5($host)])) {
-             $dealerId = $request->get('dealerId');
-             if ($host == 'vidi.ua' && !is_null($dealerId)) {
-                 $findDealer = ['id' => $request->get('dealerId')];
-             } else {
-                 $host = $this->isDealerShop($host);
-                 $findDealer = ['domain' => $host];
-             }
-             $Dealer = $this->em->getRepository(Dealer::class)->findOneBy($findDealer);
-             if (!$Dealer) {
-                 throw new NotFoundHttpException();
-             }
-             self::$dealers[md5($host)] = $Dealer;
-         }
-         return self::$dealers[md5($host)];
-     }
-     private function isDealerShop($host)
-     {
-         return str_replace("shop.", "", $host);
-     }
-     protected function webpUpdate(Request $request, $url, $manager)
-     {
-         $userAgent = $request->server->get('HTTP_USER_AGENT');
-         preg_match("/(MSIE|Opera|Firefox|Chrome|Version)(?:\/| )([0-9.]+)/", $userAgent, $browser_info);
-         $browser = $browser_info[1] ?? false;
-         if (!$browser) {
-             return $url;
-         }
-         if ($browser == 'Version' || $browser == 'MSIE') {
-             return $url;
-         }
-         $basePath = $this->getParameter('kernel.project_dir') . '/public';
-         $path = $basePath . $url . '.webp';
-         if (file_exists($path)) {
-             return $manager->getUrl($url . '.webp');
-         }
-         $im = @imagecreatefrompng($basePath . $url);
-         if (!$im) {
-             $im = @imagecreatefromjpeg($basePath . $url);
-         }
-         if ($im) {
-             $newUrl = $url . '.webp';
-             if (imagewebp($im, $path)) {
-                 imagedestroy($im);
-                 return $manager->getUrl($newUrl);
-             } else {
-                 imagedestroy($im);
-                 return $manager->getUrl($url);
-             }
-         }
-         return $url;
-     }
-     protected function baseDcRender($view, array $parameters = [], Response $response = null): ?Response
-     {
-         $request = $this->requestStack->getCurrentRequest();
-         $dealer = $this->getDealer();
-         $seoMeta = $this->seoMetaTag->getSeoMeta($request);
-         $subdomain = explode('.', $request->server->get('HTTP_HOST'))[0];
-         $basketCount = [];
-         if ($this->getUser()) {
-             $basketCount = $this->em->getRepository(Basket::class)->getBasketCountByDealerUser($this->getDealer(), $this->getUser());
-         } else {
-             $guestBasket = $this->session->get('guest_basket', []);
-             if ($guestBasket && isset($guestBasket[$this->getDealer()->getId()])) {
-                 $basketCount['count'] = count($guestBasket[$this->getDealer()->getId()]);
-             }
-         }
-         $basketCount = ($basketCount) ? $basketCount['count'] : 0;
-         $isSubdomainShop = $subdomain === "shop";
-         $utmData = $this->getUtmData();
-         $parameters = array_merge($parameters, [
-             'dealer' => $this->getDealer(),
-             'basketCount' => $basketCount,
-             'dealerCityNihgtBooking' => self::DEALER_CITY_ID,
-             'backLoginUrl' => $request->getUri(),
-             'seoMeta' => $seoMeta,
-             'isSubdomainShop' => $isSubdomainShop,
-             'currentYear' => (new DateTime('now'))->format('Y'),
-             'utmData' => $utmData,
-         ]);
-         $helpCrunchParams = $this->getParameter('help_crunch_params')[$dealer->getUniqueId()] ?? null;
-         if ($helpCrunchParams) {
-             $parameters = array_merge($parameters, ['helpCrunch' => $helpCrunchParams]);
-         }
-         $content = $this->twig->render($view, $parameters);
-         if (null === $response) {
-             $response = new Response();
-         }
-         return $response->setContent($content);
-     }
-     protected function getMpdfTempDir(): string
-     {
-         $newTempDir = $this->getParameter('file_directory_mpdf');
-         if (!$this->filesystem->exists($newTempDir)) {
-             $this->filesystem-- > mkdir($newTempDir, 0777);
-         }
-         return $newTempDir;
-     }
-     public function getCarStructuredDataCarInStock(Request $request, InStockVehicle $item): bool|string
-     {
-         $twig = $this->mediaExtensionVidi;
-         $router = $this->router;
-         $routerCurrent = $router->getMatcher()->match($router->getContext()->getPathInfo())['_route'];
-         $routerCurrentParams = [
-             'car' => $item->getUrl(),
-             'url' => $item->getUrl(),
-             'category' => $item->getCategory()->getUrl()
-         ];
-         if ($routerCurrent == 'suzuki_card_moto') {
-             $routerCurrentParams = [
-                 'moto' => $item->getUrl()
-             ];
-         }
-         $images = [];
-         $gallery = $item->getGallery();
-         if (!empty($gallery)) {
-             $gallery = $gallery->getGalleryItems();
-             if (!empty($gallery)) {
-                 $images = $gallery->toArray();
-             }
-         }
-         $images = array_reduce($images, function ($rows, $row) use ($request, $twig) {
-             $rows[] = $request->getSchemeAndHttpHost() . $twig->getPath($row->getMedia(), 'reference');
-             return $rows;
-         }, [$request->getSchemeAndHttpHost() . $twig->getPath($item->getPreview(), 'reference')]);
-         $characteristics = $item->getCharacterisaticsByGroup($request->getLocale());
-         $characteristicsSize = $characteristics[1] ?? [];
-         $characteristicsSizeNumberOfDoors = array_filter($characteristicsSize['characteristics'], fn($row) => $row['id'] === 15);
-         $characteristicsSizeNumberOfDoors = array_values($characteristicsSizeNumberOfDoors);
-         $characteristicsSizeVehicleSeatingCapacity = array_filter($characteristicsSize['characteristics'], fn($row) => $row['id'] === 20);
-         $characteristicsSizeVehicleSeatingCapacity = array_values($characteristicsSizeVehicleSeatingCapacity);
-         switch ($item->getDriveUnitType()->getId()) {
-             case 13:
-                 $driveWheelConfiguration = 'AllWheelDriveConfiguration'; // Повний
-                 break;
-             case 3:
-                 $driveWheelConfiguration = 'FrontWheelDriveConfiguration'; // Передній
-                 break;
-             case 11:
-                 $driveWheelConfiguration = 'RearWheelDriveConfiguration'; // Задній
-                 break;
-             case 27:
-                 $driveWheelConfiguration = 'FourWheelDriveConfiguration'; // AWD
-                 break;
-             default:
-                 $driveWheelConfiguration = 'undefined';
-                 break;
-         }
-         return json_encode([
-             "@context" => "http://schema.org",
-             "@type" => "Car",
-             "name" => $item->getFullName(),
-             "vehicleIdentificationNumber" => $item->getVin() ?? '00000000000000000',
-             "image" => $images,
-             "url" => $router->generate($routerCurrent, $routerCurrentParams, UrlGeneratorInterface::ABSOLUTE_URL),
-             "offers" => [
-                 "@type" => "Offer",
-                 "availability" => "http://schema.org/InStock",
-                 "price" => $item->price(),
-                 "priceCurrency" => "UAH"
-             ],
-             "itemCondition" => "https://schema.org/NewCondition",
-             "brand" => [
-                 "@type" => "Brand",
-                 "name" => $item->getBrand()->getName()
-             ],
-             "model" => $item->getModelName(),
-             "vehicleConfiguration" => $item->getEquipment()->getTitle(),
-             "vehicleModelDate" => $item->getYear(),
-             "mileageFromOdometer" => [
-                 "@type" => "QuantitativeValue",
-                 "value" => 0,
-                 "unitCode" => 'KMT'
-             ],
-             "color" => $item->getColor(),
-             "vehicleInteriorColor" => $item->getColor(),
-             "vehicleInteriorType" => 'Standard',
-             "bodyType" => $item->getBodyTypeName($request->getLocale()),
-             "driveWheelConfiguration" => $driveWheelConfiguration,
-             "vehicleEngine" => [
-                 "@type" => "EngineSpecification",
-                 "engineType" => $item->getFuelTypeName($request->getLocale()),
-             ],
-             "vehicleTransmission" => $item->getTransmissionTypeName($request->getLocale()),
-             "numberOfDoors" => $characteristicsSizeNumberOfDoors[0]['value'] ?? null,
-             "vehicleSeatingCapacity" => $characteristicsSizeVehicleSeatingCapacity[0]['value'] ?? null
-         ], JSON_UNESCAPED_SLASHES);
-     }
-     public function getCarStructuredDataCarUsed(Request $request, AbstractVehicle $item): bool|string
-     {
-         $twig = $this->mediaExtensionVidi;
-         $router = $this->router;
-         $routerCurrent = $router->getMatcher()->match($router->getContext()->getPathInfo())['_route'];
-         $routerCurrentParams = [
-             'id' => $item->getVehicleId(),
-             'url' => $item->getUrl()
-         ];
-         if ($routerCurrent == 'suzuki_card_moto') {
-             $routerCurrentParams = [
-                 'moto' => $item->getUrl()
-             ];
-         }
-         $images = array_reduce(($item->getGallery()) ? $item->getGallery()->getGalleryItems()->toArray() : [], function ($rows, $row) use ($request, $twig) {
-             $rows[] = $request->getSchemeAndHttpHost() . $twig->getPath($row->getMedia(), 'reference');
-             return $rows;
-         }, [$request->getSchemeAndHttpHost() . $twig->getPath($item->getPreview(), 'reference')]);
-         $characteristics = $item->getCharacterisaticsWithGroup($request->getLocale());
-         $characteristicsSize = $characteristics[1] ?? [];
-         $characteristicsSizeNumberOfDoors = array_filter($characteristicsSize['characteristics'], fn($row) => $row['id'] === 15);
-         $characteristicsSizeNumberOfDoors = array_values($characteristicsSizeNumberOfDoors);
-         $characteristicsSizeVehicleSeatingCapacity = array_filter($characteristicsSize['characteristics'], fn($row) => $row['id'] === 20);
-         $characteristicsSizeVehicleSeatingCapacity = array_values($characteristicsSizeVehicleSeatingCapacity);
-         return json_encode([
-             "@context" => "http://schema.org",
-             "@type" => "Car",
-             "name" => $item->getFullName(),
-             "vehicleIdentificationNumber" => $item->getVIN() ?? '00000000000000000',
-             "image" => $images,
-             "url" => $router->generate($routerCurrent, $routerCurrentParams, UrlGeneratorInterface::ABSOLUTE_URL),
-             "offers" => [
-                 "@type" => "Offer",
-                 "availability" => "http://schema.org/InStock",
-                 "price" => $item->price(),
-                 "priceCurrency" => "UAH"
-             ],
-             "itemCondition" => "https://schema.org/UsedCondition",
-             "brand" => [
-                 "@type" => "Brand",
-                 "name" => $item->getBrand()->getName()
-             ],
-             "model" => $item->getModelName(),
-             "vehicleConfiguration" => $item->getEquipment()->getTitle(),
-             "vehicleModelDate" => $item->getYear(),
-             "mileageFromOdometer" => [
-                 "@type" => "QuantitativeValue",
-                 "value" => $item->getMileage(),
-                 "unitCode" => 'KMT'
-             ],
-             "color" => $item->getBodyColor($request->getLocale()),
-             "vehicleInteriorColor" => $item->getBodyColor($request->getLocale()),
-             "vehicleInteriorType" => 'Standard',
-             "bodyType" => $item->getBodyTypeName($request->getLocale()),
-             "driveWheelConfiguration" => $item->getDriveUnitTypeName($request->getLocale()),
-             "vehicleEngine" => [
-                 "@type" => "EngineSpecification",
-                 "engineType" => $item->getFuelTypeName($request->getLocale()),
-             ],
-             "vehicleTransmission" => $item->getTransmissionTypeName($request->getLocale()),
-             "numberOfDoors" => $characteristicsSizeNumberOfDoors[0]['value'] ?? null,
-             "vehicleSeatingCapacity" => $characteristicsSizeVehicleSeatingCapacity[0]['value'] ?? null
-         ], JSON_UNESCAPED_SLASHES);
-     }
-     public function getCarPageStructuredData(Request $request, Vehicle $vehicle): string
-     {
-         $twig = $this->mediaExtensionVidi;
-         $router = $this->router;
-         $currentRoute = $router->getMatcher()->match($router->getContext()->getPathInfo())['_route'];
-         if ($vehicle->getDealer()->getUrl() !== 'land-rover') {
-             $homepageRoute = $router->generate(
-                 preg_replace('([^a-zA-Z])', '_', $vehicle->getDealer()->getUrl()) . '_homepage', [], UrlGeneratorInterface::ABSOLUTE_URL
-             );
-         } else {
-             $homepageRoute = $router->generate(
-                 preg_replace('([^a-zA-Z])', '', $vehicle->getDealer()->getUrl()) . '_homepage', [], UrlGeneratorInterface::ABSOLUTE_URL
-             );
-         }
-         $params = [
-             'car' => $vehicle->getUrl(),
-             'url' => $vehicle->getUrl(),
-             'category' => $vehicle->getCategory() ? $vehicle->getCategory()->getUrl() : '',
-         ];
-         if ($currentRoute == 'suzuki_card_moto') {
-             $params = ['moto' => $vehicle->getUrl()];
-         }
-         $images = [
-             $request->getSchemeAndHttpHost() . $twig->getPath($vehicle->getPreview(), 'reference'),
-         ];
-         $gallery = $vehicle->getGallery();
-         if ($gallery) {
-             foreach ($gallery->getGalleryItems() as $galleryItem) {
-                 $images[] = $request->getSchemeAndHttpHost() . $twig->getPath($galleryItem->getMedia(), 'reference');
-             }
-         }
-         return json_encode([
-             "@context" => "http://schema.org",
-             "@type" => "Product",
-             "image" => $images,
-             "brand" => [
-                 "@type" => "Brand",
-                 "name" => $vehicle->getBrand()->getName(),
-             ],
-             "manufacturer" => [
-                 "@type" => "Corporation",
-                 "name" => $vehicle->getBrand()->getName()
-             ],
-             "description" => $vehicle->seoDescription($request->getLocale()),
-             "sku" => $vehicle->getVehicleId(),
-             "name" => $vehicle->getFullName(),
-             "offers" => [
-                 "@type" => "AggregateOffer",
-                 "availability" => "http://schema.org/InStock",
-                 "priceCurrency" => "UAH",
-                 "price" => $vehicle->price(),
-                 "lowPrice" => $vehicle->minPrice(),
-                 "highPrice" => $vehicle->maxPrice(),
-             ],
-             "itemCondition" => "http://schema.org/NewCondition",
-             "url" => $router->generate($currentRoute, $params, UrlGeneratorInterface::ABSOLUTE_URL)
-         ], JSON_UNESCAPED_SLASHES);
-     }
-     public function getModelMenuItems($locale, $format = null, $categId = false): array
-     {
-         $cars = $this->vehicleRepository->getNewByDealer($this->getDealer());
-         $categories = [];
-         /** @var \CoreBundle\Entity\Vehicles\Vehicle $car */
-         foreach ($cars as $car) {
-             $vehicleModel = $this->vehicleFactory->createByEntity($car);
-             if (!$vehicleModel) {
-                 continue;
-             }
-             $categoryId = $car->getCategory() ? $car->getCategory()->getId() : null;
-             if ($categId && $categoryId != $categId) continue;
-             $key = array_search($categoryId, array_column($categories, 'id'));
-             $format = $format ?: 'menu';
-             $oneCar = [
-                 'id' => $vehicleModel->getVehicleId(),
-                 'title' => $vehicleModel->getModelName(),
-                 'customTitle' => $vehicleModel->getCustomName($locale),
-                 'isNew' => $vehicleModel->isNew(),
-                 'isPreOrder' => $vehicleModel->isPreOrder(),
-                 'onTestDrive' => $vehicleModel->getTestDrive(),
-                 'position' => $vehicleModel->getPosition(),
-                 'url' => $vehicleModel->getUrl(),
-                 'hasHybrid' => $vehicleModel->hasHybrid(),
-                 'price' => round($vehicleModel->price()),
-                 'image' => $vehicleModel->getPreviewPath($format),
-                 'image_webp' => $vehicleModel->getPreviewPathWebp($format),
-                 'modelId' => $vehicleModel->getModel()->getId(),
-                 'preorderPrice' => $vehicleModel->getPreorderPrice(),
-             ];
-             if ($key === false && $car->getCategory()) {
-                 $category = [
-                     'id' => $categoryId,
-                     'title' => $vehicleModel->getCategory()->getTitle($locale),
-                     'position' => $vehicleModel->getCategory()->getPosition(),
-                     'url' => $vehicleModel->getCategory()->getUrl(),
-                     'cars' => []
-                 ];
-                 $category['cars'][] = $oneCar;
-                 $categories[] = $category;
-             } else {
-                 $categories[$key]['cars'][] = $oneCar;
-             }
-         }
-         $positionC = [];
-         foreach ($categories as $k => &$row) {
-             $position = [];
-             foreach ($row['cars'] as $key => $car) {
-                 $position[$key] = $car['position'];
-             }
-             $positionC[$k] = $row['position'];
-             array_multisort($position, SORT_ASC, $row['cars']);
-         }
-         array_multisort($positionC, SORT_ASC, $categories);
-         return $categories;
-     }
-     protected function removeBOM($str = ""): bool|string
-     {
-         if (substr($str, 0, 3) == pack('CCC', 0xef, 0xbb, 0xbf)) {
-             $str = substr($str, 3);
-         }
-         return $str;
-     }
-     public function getUtmData(): string
-     {
-         $request = $this->requestStack->getCurrentRequest();
-         if (!$request) {
-             return json_encode([], JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT);
-         }
-         $utmData = [];
-         $utmTags = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content'];
-         foreach ($utmTags as $tag) {
-             $pascalCaseTag = (new UnicodeString($tag))->camel()->title()->toString();
-             $utmData[$pascalCaseTag] = $request->query->get($tag, '');
-         }
-         $utmData['BpmRef'] = $request->headers->get('referer', '');
-         $utmData['BpmHref'] = $request->getUri();
-         return json_encode($utmData,  JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT);
-     }
- }
-