<?php
namespace App\Service;
use App\Entity\Customer;
use App\Entity\FileData;
use App\Entity\FrontPage;
use App\Entity\HotelXmlPrice;
use App\Entity\MenuItemFront;
use App\Repository\AgencyRepository;
use App\Repository\CityRepository;
use App\Repository\CurrencyExchangerateRepository;
use App\Repository\CustomerRepository;
use App\Repository\ExtraTypeRepository;
use App\Repository\FileDataRepository;
use App\Repository\FrontPageRepository;
use App\Repository\FrontSectionRepository;
use App\Repository\FrontThemeRepository;
use App\Repository\FrontZoneRepository;
use App\Repository\HotelXmlPriceRepository;
use App\Repository\HotelXmlRepository;
use App\Repository\MenuItemFrontRepository;
use App\Repository\ProductFeeRepository;
use App\Repository\SocialNetworkRepository;
use App\Repository\HubLocationRepository;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
class FrontService
{
public function __construct(
private readonly MenuItemFrontRepository $menuItemFrontRepository,
private readonly FileDataRepository $fileDataRepository,
private readonly Helpers $helpers,
private readonly RequestStack $requestStack,
private readonly FrontZoneRepository $frontZoneRepository,
private readonly HotelXmlPriceRepository $hotelXmlPriceRepository,
private readonly CityRepository $cityRepository,
private readonly UrlGeneratorInterface $router,
private readonly CurrencyExchangerateRepository $currencyExchangerateRepository,
private readonly ParameterService $parameterService,
private readonly FrontPageRepository $frontPageRepository,
private readonly FrontSectionRepository $frontSectionRepository,
private readonly HotelXmlRepository $hotelXmlRepository,
private readonly SocialNetworkRepository $socialNetworkRepository,
private readonly AgencyRepository $agencyRepository,
private readonly CurrencyService $currencyService,
private readonly FrontThemeRepository $frontThemeRepository,
private readonly ProductFeeRepository $productFeeRepository,
private readonly HubLocationRepository $xmlApiDefaultRepository,
private readonly CustomerRepository $customerRepository,
private readonly ExtraTypeRepository $extraTypeRepository,
)
{
}
function getFrontMenu(): array
{
$session = $this->requestStack->getSession();
$menu_front_items = $this->menuItemFrontRepository->findBy(['active' => true], ['displayOrder' => 'ASC']);
$menu_front_items_array = $this->helpers->convert_ObjectArray_to_2DArray($menu_front_items);
foreach ($menu_front_items as $menu_front_item) {
switch ($menu_front_item->getId()) {
case str_starts_with($menu_front_item->getId(), MenuItemFront::HOTEL_CONTRY_CODE):
//if the country is null doesn't need to continue
if (is_null($menu_front_item->getCountry())) break;
$cities = $this->cityRepository->findBy(['country' => $menu_front_item->getCountry()]);
foreach ($cities as $key_city => $city) {
$path = $this->router->generate('app_front_hotel_city', ['name' => $city->getName()]);
$menu_city = [
'id' => 'HOTEL_' . strtoupper($city->getName()),
'title' => $city->getName(),
'route' => $path,
'displayOrder' => $key_city + 1,
'externalUrl' => null,
"parent" => $menu_front_item->getId()
];
$menu_front_items_array[] = $menu_city;
}
break;
}
}
//dd($menu_front_items_array);
$menu_as_tree = $this->helpers->buildTree($menu_front_items_array);
if (array_key_exists('FRONT', $menu_as_tree) && array_key_exists('children', $menu_as_tree['FRONT'])) {
$session->set('menu_front', $menu_as_tree['FRONT']['children']);
}
return $menu_as_tree;
}
public function getItemHotel(HotelXmlPrice $hotelXmlPrice): array
{
$currency_session = $this->currencyService->getSessionCurrency();
$hotel = $hotelXmlPrice->getHotelXml();
$promos = $hotel->getHotel() !== null ? $hotel->getHotel()->getPromos() : [];
$hotel_direct = $hotel->getHotel();
$badges = $hotel->getHotel() !== null ? $hotel->getHotel()->getBadges() : [];
return [
'type' => 'hotel',
'title' => ($hotel_direct != null) ? $hotel_direct->getName() : $hotel->getName(),
'link' => $this->router->generate('hotel_detail', [
'city_label' => $hotel->getCity(),
'country_label' => $hotel->getCountry(),
'hotel_label' => $hotel->getName(),
'id' => $hotel->getCode()
]),
'image' => ($hotel_direct != null) ? $hotel_direct->getPrimaryImageUrl() : $hotel->getImageUrl(),
'city' => $hotel->getCity(),
'country' => $hotel->getCountry(),
'stars' => ($hotel_direct != null) ? $hotel_direct->getStarRating() : $hotel->getStarRating(),
'promos' => $promos,
'badges' => $badges,
'price' => $this->currencyService->convert($hotelXmlPrice->getPrice(), $hotelXmlPrice->getCurrency(), $currency_session),
'currency' => $currency_session,
'board' => $hotelXmlPrice->getBoard(),
];
}
private function getItemCity(array $city_data): array
{
return [
'title' => $city_data['name'],
'type' => 'city',
'link' => $this->router->generate('app_front_hotel_city', [
'name' => $city_data['name']
]),
'image' => $this->getCityImage($city_data['name']),
'city' => $city_data['name'],
'badges' => [],
'country' => $city_data['country'],
'hotelsCount' => $city_data['hotelsCount'],
];
}
private function getItemTheme(array $theme_data): array
{
return [
'title' => $theme_data['name'],
'type' => 'theme',
'link' => $this->router->generate('app_front_hotel_theme', [
'name' => $theme_data['name']
]),
'image' => $this->getThemeImage($theme_data['name']),
'city' => "",
'country' => "",
'badges' => [],
'hotelsCount' => $theme_data['hotelsCount'],
];
}
public function getItemExtra(array $theme_data): array
{
return [
'title' => $theme_data['name'],
'type' => 'extra',
'link' => $this->router->generate('extra_detail', ['extra_label' => urlencode($theme_data['name']), 'id' => $theme_data['id']]),
'image' => $theme_data['image'],
'city' => "",
'badges' => [],
'country' => "",
'currency' =>$theme_data['currency'],
'price' => $theme_data['price'],
'hotelsCount' => "",
];
}
private function getItemExtraType(array $extra_type_data): array
{
return [
'title' => $extra_type_data['name'],
'type' => 'extra',
'link' => $this->router->generate('app_front_extra_by_type', ['id' => $extra_type_data['id'], 'name' => urlencode($extra_type_data['name'])]),
'image' => $extra_type_data['image'],
'city' => "",
'badges' => [],
'country' => "",
'price' => "",
'hotelsCount' => "",
];
}
public function getFrontZones(): array
{
$zones = $this->frontZoneRepository->findBy(['active' => true]);
//dd($zones);
$zones_data = [];
foreach ($zones as $zone) {
if (empty($zone->getQuery())) continue;
$zoneID = $zone->getId();
$zones_data[$zoneID] = [
'view' => $zone->getHtmlFileName(), # view 1, 2, 3, 4 ...
'title' => $zone->getTitle(),
'active' => $zone->isActive(),
'backgroundColor' => $zone->getbackgroundColor(),
'backgroundImage' => $zone->getBackgroundImage() ? $zone->getBackgroundImage()->getUrl() : null,
'itemsCount' => $zone->getNbElementsToDisplay(),
'query' => $zone->getQuery(),
'items' => [],
];
switch ($zone->getQuery()) {
case 'hotel' :
{
$criterias = [];
foreach ($zone->getFrontZoneParamValues() as $paramValue) {
if ($paramValue->getValue()) {
$criterias[$paramValue->getParameter()][] = $paramValue->getValue();
}
}
$hotelXmlPrices = $this->hotelXmlPriceRepository->getHotelXmlPriceByCriterias($criterias, $zone->getNbElementsToDisplay());
foreach ($hotelXmlPrices as $hotelXmlPrice) {
$zones_data[$zoneID]['items'][] = $this->getItemHotel($hotelXmlPrice);
}
break;
}
case 'cities' :
{
$cityNames = [];
$frontZoneParamValues = $zone->getFrontZoneParamValues();
foreach ($frontZoneParamValues as $frontZoneParamValue) {
$cityNames[] = $frontZoneParamValue->getValue();
}
$cities = $this->hotelXmlRepository->getCities($cityNames);
foreach ($cities as $city_data) {
$zones_data[$zoneID]['items'][] = $this->getItemCity($city_data);
}
break;
}
case 'themes':
{
$themeNames = [];
$frontZoneParamValues = $zone->getFrontZoneParamValues();
foreach ($frontZoneParamValues as $frontZoneParamValue) {
$themeNames[] = $frontZoneParamValue->getValue();
}
$themes = $this->frontThemeRepository->getSelectedFrontTheme($themeNames);
foreach ($themes as $theme) {
$hotelsCount = $this->hotelXmlRepository->getThemeCount($theme);
$theme_data = [
"name" => $theme->getName(),
"hotelsCount" => $hotelsCount
];
$zones_data[$zoneID]['items'][] = $this->getItemTheme($theme_data);
}
break;
}
case 'extras':
{
$types = [];
$frontZoneParamValues = $zone->getFrontZoneParamValues();
foreach ($frontZoneParamValues as $frontZoneParamValue) {
$types[] = $frontZoneParamValue->getValue();
}
$extraTypes = $this->extraTypeRepository->getSelectedFrontExtraType($types);
foreach ($extraTypes as $extraType_data) {
$extra_type_data = [
"id" => $extraType_data->getId(),
"name" => $extraType_data->getName(),
"image" => $extraType_data->getImage()?->getUrl(),
];
$zones_data[$zoneID]['items'][] = $this->getItemExtraType($extra_type_data);
}
break;
}
}
}
return $zones_data;
}
public function getCityImage($cityName): string
{
$city = $this->cityRepository->findOneBy(['name' => $cityName]);
if (is_null($city)) return FileData::IMAGE_NOT_AVAILABLE_PATH;
$image = $city->getImage();
return $image ? $image->getUrl() : FileData::IMAGE_NOT_AVAILABLE_PATH;
}
public function getThemeImage($themeName): string
{
$theme = $this->frontThemeRepository->findOneBy(['name' => $themeName]);
if (is_null($theme)) return FileData::IMAGE_NOT_AVAILABLE_PATH;
$image = $theme->getImage();
return $image ? $image->getUrl() : FileData::IMAGE_NOT_AVAILABLE_PATH;
}
public function getExtraImage($themeName): string
{
$extra = $this->extraTypeRepository->findOneBy(['name' => $themeName]);
if (is_null($extra)) return FileData::IMAGE_NOT_AVAILABLE_PATH;
$extra = $extra->getImage();
return $extra ? $extra->getUrl() : FileData::IMAGE_NOT_AVAILABLE_PATH;
}
public function getSliderImages($type): array
{
return $this->fileDataRepository->findBy(['type' => $type, 'active' => true]);
}
public function getSeoInfo(string $slug): array
{
$seoStaticPage = $this->frontPageRepository->findOneBy(['slug' => $slug]);
return [
'homeSeoTitle' => $seoStaticPage->getSeoTitle(),
'homeSeoDescription' => $seoStaticPage->getSeoDescription(),
'socialMedias' => $this->getSocialNetworks()
];
}
public function getSocialNetworks(): array
{
return $this->socialNetworkRepository->findBy(['active' => 'true']);
}
public function getCurrencies($fromExchangeRates = false): array
{
$currencies = [];
if ($fromExchangeRates) {
$currencies_exchanges = $this->currencyExchangerateRepository->findAll();
foreach ($currencies_exchanges as $currencies_exchange) {
$currencies[] = $currencies_exchange->getCurrencyTo();
}
} else {
$customers_default = $this->customerRepository->findBy(['isDefault' => true, 'active' => true]);
foreach ($customers_default as $customer) {
$currencies[] = $customer->getCurrency();
}
}
return array_unique($currencies);
}
public function getAgencies(): array
{
return $this->agencyRepository->findby(['isDefault' => false]);
}
public function getHomePage(): FrontPage
{
return $this->frontPageRepository->findOneBy(['slug' => FrontPage::HOME_PAGE]);
}
public function getProductFee(string $product, Customer $customer): float|int
{
$productFee = $this->productFeeRepository->findOneBy(['product' => $product]);
if ($productFee) {
$exchangeRate = $this->currencyService->calculateExchangeRate(
$this->parameterService->getReferenceCurrency(), // referenceCurrency
$customer->getCurrency()
);
if ($customer->getClass() == 'CustomerMoral') {
return $productFee->getB2bAmount() * $exchangeRate;
} else {
return $productFee->getAmount() * $exchangeRate;
}
}
return 0;
}
public function getSuggestions($cookieName, $xmlApiType): array
{
$suggestions = [];
$resultSuggestions = $this->xmlApiDefaultRepository->findBy(['productType' => $xmlApiType]);
foreach ($resultSuggestions as $resultSuggestion) {
$suggestions[] = json_decode($resultSuggestion->getDataJson());
}
return $suggestions;
}
public function getSections(): array
{
$sections = $this->frontSectionRepository->findAll();
return $sections;
}
public function getSessionCustomer(): ?Customer
{
$session = $this->requestStack->getSession();
$customer_in_session = $session->get('backend_customer');
$defaultCustomerId = $customer_in_session?->getId();
$defaultCustomer = null;
if ($defaultCustomerId) {
$defaultCustomer = $this->customerRepository->find($defaultCustomerId);
}
return $defaultCustomer;
}
public function getTrackingTools() : array
{
$twig_parameters ['META_PIXEL_ID'] = $this->parameterService->getTrackerMetaId();
$twig_parameters ['GOOGLE_ANALYTICS_ID'] = $this->parameterService->getTrackerGoogleAnalyticsID();
$twig_parameters ['GOOGLE_ADS_ID'] = $this->parameterService->getTrackerGoogleADsID();
$twig_parameters ['GOOGLE_TAG_MANAGER_ID'] = $this->parameterService->getTrackerGoogleTagManagerID();
$twig_parameters ['FACEBOOK_DOMAIN_VERIFICATION_CODE'] = $this->parameterService->getTrackerFacebookDomainVerification();
$twig_parameters ['GOOGLE_SEARCH_VERIFICATION'] = $this->parameterService->getTrackerGoogleSearchVerification();
return $twig_parameters;
}
}