<?php
namespace App\Service\Internal;
use App\Event\ModeEvent;
use App\Manager\AccountManager;
use App\Security\KasUserAuthenticator;
use App\Service\Internal\User\PreferenceService;
use App\Service\Internal\Schedule\FavoriteService;
use App\Manager\BookingSecureBikeParkManager;
use App\Manager\InteractiveMapManager;
use App\Manager\DisruptionManager;
use App\Normalizer\DisruptionNormalizer;
use App\Normalizer\LineNormalizer;
use App\Normalizer\UserPreferencesNormalizer;
use App\Normalizer\Schedule\FavoriteNormalizer as ScheduleFavoriteNormalizer;
use App\Normalizer\Line\FavoriteNormalizer as LineFavoriteNormalizer;
use App\Utils\DeviceInfo;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Security\Core\Security;
class HomePageService
{
public const TRANSITPASS_KEY = 'TRANSITPASS';
protected string $networkId;
protected array $network;
protected string $ticketingModule;
protected string $geoserverUrl;
protected PreferenceService $preferenceService;
protected UserPreferencesNormalizer $userPreferencesNormalizer;
protected NetworkService $networkService;
protected UserService $userService;
protected DisruptionService $disruptionService;
protected DisruptionNormalizer $disruptionNormalizer;
protected FavoriteService $favoriteService;
protected CmsService $cmsService;
protected ScheduleFavoriteNormalizer $scheduleFavoriteNormalizer;
protected LineFavoriteNormalizer $lineFavoriteNormalizer;
protected MetaService$metaService;
protected LocalizationService $localizationService;
protected RequestStack $requestStack;
protected Security $security;
protected LineNormalizer $lineNormalizer;
protected BookingSecureBikeParkManager $bookingSecureBikeParkManager;
protected EventDispatcherInterface $eventDispatcher;
protected InteractiveMapManager $interactiveMapManager;
protected ParameterBagInterface $params;
protected DisruptionManager $disruptionManager;
protected Line\FavoriteService $lineFavoriteService;
protected AccountManager $accountManager;
public function __construct(
string $networkId,
string $ticketingModule,
string $geoserverUrl,
PreferenceService $preferenceService,
UserPreferencesNormalizer $userPreferencesNormalizer,
NetworkService $networkService,
UserService $userService,
DisruptionService $disruptionService,
DisruptionNormalizer $disruptionNormalizer,
Schedule\FavoriteService $favoriteService,
Line\FavoriteService $lineFavoriteService,
ScheduleFavoriteNormalizer $scheduleFavoriteNormalizer,
LineFavoriteNormalizer $lineFavoriteNormalizer,
CmsService $cmsService,
MetaService $metaService,
LocalizationService $localizationService,
RequestStack $requestStack,
Security $security,
LineNormalizer $lineNormalizer,
BookingSecureBikeParkManager $bookingSecureBikeParkManager,
EventDispatcherInterface $eventDispatcher,
InteractiveMapManager $interactiveMapManager,
AccountManager $accountManager,
ParameterBagInterface $parameterBag,
DisruptionManager $disruptionManager
) {
$this->networkId = $networkId;
$this->ticketingModule = $ticketingModule;
$this->geoserverUrl = $geoserverUrl;
$this->preferenceService = $preferenceService;
$this->userPreferencesNormalizer = $userPreferencesNormalizer;
$this->disruptionNormalizer = $disruptionNormalizer;
$this->networkService = $networkService;
$this->userService = $userService;
$this->disruptionService = $disruptionService;
$this->favoriteService = $favoriteService;
$this->lineFavoriteService = $lineFavoriteService;
$this->scheduleFavoriteNormalizer = $scheduleFavoriteNormalizer;
$this->lineFavoriteNormalizer = $lineFavoriteNormalizer;
$this->cmsService = $cmsService;
$this->metaService = $metaService;
$this->localizationService = $localizationService;
$this->requestStack = $requestStack;
$this->security = $security;
$this->lineNormalizer = $lineNormalizer;
$this->bookingSecureBikeParkManager = $bookingSecureBikeParkManager;
$this->eventDispatcher = $eventDispatcher;
$this->interactiveMapManager = $interactiveMapManager;
$this->accountManager = $accountManager;
$this->params = $parameterBag;
$this->disruptionManager = $disruptionManager;
$this->network = $this->networkService->getNetwork();
}
/**
* @return array
* @throws \Exception
*/
public function getRenderParameters(array $get = [], array $parameters = [])
{
//TODO: Temporaire, à supprimer quand la conf par réseau et environnement sera externalisée
$parameters['baseUrl'] = 'https://' . $_SERVER['SERVER_NAME'];
$parameters = DeviceInfo::addDeviceParameters($parameters);
$session = $this->requestStack->getSession();
$body = $get;
$nbDayFuture = $this->networkService->getNbDayFuture();
$maxDate = new \DateTime('now');
$maxDate = $maxDate->add(new \DateInterval('P'.$nbDayFuture.'D'));
$parameters['maxDate'] = $maxDate->format('Y-d-m');
$parameters['networkId'] = isset($this->networkId) ? $this->networkId : '';
$parameters['default_latlon'] = $this->networkService->getLatLon();
$parameters['network_lat'] = $this->networkService->getLat();
$parameters['network_lon'] = $this->networkService->getLon();
$parameters['external'] = $this->networkService->isExternalNetwork();
$parameters['operators'] = json_encode($this->networkService->getOperatorInfos());
$parameters['geoserverUrl'] = isset($this->geoserverUrl) ? $this->geoserverUrl : '';
$parameters['journeys'] = isset($parameters['journeys']) ? $parameters['journeys'] : [];
$parameters['directions'] = isset($parameters['directions']) ? $parameters['directions'] : [];
$parameters['stopPoints'] = isset($parameters['stopPoints']) ? $parameters['stopPoints'] : [];
$parameters['languages'] = $this->localizationService->getLanguages();
$parameters['bookingIsEnabled'] = $this->bookingSecureBikeParkManager->isEnabled($this->network);
$parameters['fromSEO'] = preg_match('/(google|yahoo|bing|qwant)/i', isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '') === 1;
$parameters['fromWidget'] = $session->get('context', null) === 'WIDGET';
$parameters['referer'] = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '';
if($parameters['fromWidget']){
$request = $this->requestStack->getCurrentRequest();
$url = $request->headers->get('referer') ?? $request->getSchemeAndHttpHost();
$parameters['isAuthorizedDomainForBookingSbp'] = $this->bookingSecureBikeParkManager->isAuthorizedDomain($url);
}
$layoutScheduleLine = $this->networkService->getLayoutScheduleLine();
$session->set('layoutScheduleLine', $layoutScheduleLine);
if (empty($parameters['activeTab'])) {
$parameters['activeTab'] = 'journey';
}
if (!isset($parameters['displayDisruptionWithAjax']) || false === $parameters['displayDisruptionWithAjax'] || $parameters['activeTab'] == 'traffic') {
$this->getDisruption($parameters);
}
if ($parameters['activeTab'] == 'interactiveMap') {
$poi = $this->requestStack->getCurrentRequest()->get('poi');
$parameters['poi'] = explode(',', $poi);
$interactiveMapData = $this->interactiveMapManager->interactiveMapData();
$parameters = array_merge($parameters, $interactiveMapData);
}
$userPreferences = [];
if ($this->security->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
$userPreferences = $this->preferenceService->getUserPreferences();
$parameters = $this->accountManager->getRenderParameters($parameters);
}
$context['itineraryOptions'] = $this->networkService->getItineraryOptions();
if ($this->params->get('global.login_mode') === KasUserAuthenticator::LOGIN_MODE
&& $this->security->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
$settings = $this->accountManager->getItineraryPreferences();
$parameters['preferences']['tripPlanner'] = $settings->body;
$parameters['preferences'] = $this->userPreferencesNormalizer->normalize(json_decode(json_encode($parameters['preferences'] ?? []), true), $context);
} else {
$parameters['preferences'] = $this->userPreferencesNormalizer->normalize($userPreferences, $context, true);
}
$parameters['isTransitPassEnabled'] = in_array(self::TRANSITPASS_KEY, $context['itineraryOptions'], true);
$includedModes = $body['modes'] ?? null;
$excludedModesPreferences = !empty($parameters['preferences']['tripPlanner']['excludedModes']) ? $parameters['preferences']['tripPlanner']['excludedModes'] : [];
$modeEvent = new ModeEvent($includedModes, $excludedModesPreferences);
$this->eventDispatcher->dispatch($modeEvent, ModeEvent::NAME);
$parameters['modes'] = $modeEvent->getDefaultModes();
$parameters['modesLayout'] = $modeEvent->getLayoutModes();
$scheduleFavorites = [];
$parameters['lineFavorites'] = [];
if ($this->security->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
$scheduleFavorites = $this->favoriteService->getScheduleFavorites();
$scheduleFavorites = $this->scheduleFavoriteNormalizer->normalize($scheduleFavorites);
$userResponse = $this->userService->myAccount();
if (isset($userResponse->body) && isset($userResponse->status) && $userResponse->status === 200) {
$parameters['userData'] = $userResponse->body;
}
$parameters['lineFavorites'] = $this->lineFavoriteService->getFavoriteLines([]);
$parameters['lineFavorites'] = $this
->lineFavoriteNormalizer
->normalize($parameters['lineFavorites'], $parameters['linesDisruptions'] ?? []);
}
$parameters['scheduleFavorites'] = isset($scheduleFavorites) ? $scheduleFavorites : [];
$parameters['activeWidgets'] = [
'journey' => 1,
'schedule' => 1,
'traffic' => 1,
'linesAndPoi' => 1
];
if (!isset($parameters['departurePlace'])) {
$parameters['departurePlace']['id'] = '';
$parameters['departurePlace']['value'] = '';
$parameters['departurePlace']['latlon'] = '';
$parameters['departurePlace']['latitude'] = '';
$parameters['departurePlace']['longitude'] = '';
}
if (!isset($parameters['arrivalPlace'])) {
$parameters['arrivalPlace']['id'] = '';
$parameters['arrivalPlace']['value'] = '';
$parameters['arrivalPlace']['latlon'] = '';
$parameters['arrivalPlace']['latitude'] = '';
$parameters['arrivalPlace']['longitude'] = '';
}
$menu = $this->cmsService->getMenu();
$parameters['menuPages'] = $menu['menuPages'];
$parameters['footerPages'] = $menu['footerPages'];
$parameters['items'] = $menu['items'];
$banners = $this->cmsService->getBanners();
foreach($banners as $banner) {
$banner->id = str_replace(':', '-', $banner->id);
}
$launchNews = $this->cmsService->getLaunchNews();
$parameters['banners'] = $banners;
$parameters['launchNews'] = $launchNews;
$ids = [];
foreach ($launchNews as $popupPost) {
$ids[] = $popupPost->id;
}
$parameters['launchNewsId'] = isset($launchNews[0]->id) ? $launchNews[0]->id : '';
$parameters['ticketingModule'] = $this->ticketingModule;
$posts = $this->cmsService->getPosts();
$parameters['posts'] = $posts;
// Preferences
$speedProfiles = [0 => 'SLOW', 1 => 'NORMAL', 2 => 'FAST', 3 => 'VTT', 4 => 'VAE'];
$parameters['preferences']['tripPlanner']['excludedModes'] = $modeEvent->getExcludedModes();
$parameters['preferences']['tripPlanner']['showAccessibility'] = isset($body['showAccessibility']) ? filter_var($body['showAccessibility'], FILTER_VALIDATE_BOOLEAN) : $parameters['preferences']['tripPlanner']['showAccessibility'];
$parameters['preferences']['tripPlanner']['wheelchairAccessible'] = isset($body['accessible']) ? filter_var($body['accessible'], FILTER_VALIDATE_BOOLEAN) : $parameters['preferences']['tripPlanner']['wheelchairAccessible'];
$parameters['preferences']['tripPlanner']['walkProfile'] = isset($body['walk']['speed']) ? $speedProfiles[$body['walk']['speed']] : $parameters['preferences']['tripPlanner']['walkProfile'];
$parameters['preferences']['tripPlanner']['bikeProfile'] = isset($body['bike']['speed']) ? $speedProfiles[$body['bike']['speed']] : $parameters['preferences']['tripPlanner']['bikeProfile'];
$this->generateMetas($parameters);
return $parameters;
}
/**
* @param array $parameters
* @throws \Exception
*/
public function getDisruption(array &$parameters = [])
{
$currentSubNetworksDisruptions = 0;
$futureSubNetworksDisruptions = 0;
$disruptionLayout = $this->networkService->getDisruptionLayout();
$subNetworks = $this->networkService->getSubNetworks();
$isSubNetworks = $parameters['issubnetworks'] ?? '';
$currentDisruptions = $this->disruptionService->getDisruptions($isSubNetworks, DisruptionNormalizer::STATUS_ONGOING);
$futureDisruptions = $this->disruptionService->getDisruptions($isSubNetworks, DisruptionNormalizer::STATUS_COMING);
$parameters['nbSubNetworks'] = count($subNetworks) ?? 0;
$parameters['currentDisruptions'] = $currentDisruptions['disruptions'] ?? [];
$parameters['futureDisruptions'] = $futureDisruptions['disruptions'] ?? [];
$withDisruptionOnly = null;
if (in_array("FAV_WITH_DISRUPTIONS_BOARDS_LINES", $disruptionLayout)) {
$withDisruptionOnly = 0;
} elseif (in_array("FAV_WITH_DISRUPTIONS_BOARDS_LINES_WITHDISRUPTIONSONLY", $disruptionLayout)) {
$withDisruptionOnly = 1;
}
if ($withDisruptionOnly !== null) {
$parameters['currentDisruptions']['subNetworks'] = [];
$parameters['futureDisruptions']['subNetworks'] = [];
} else {
$parameters['currentDisruptions']['subNetworks'] = $this->disruptionManager->getSubNetworksDisruptions($currentDisruptions, 'currents',$isSubNetworks);
$parameters['futureDisruptions']['subNetworks'] = $this->disruptionManager->getSubNetworksDisruptions($futureDisruptions, 'futures', $isSubNetworks);
$currentSubNetworksDisruptions = $this->getDisruptionsCountForSubNetworkOrLine($parameters['currentDisruptions']['subNetworks'], 'currents');
$futureSubNetworksDisruptions = $this->getDisruptionsCountForSubNetworkOrLine($parameters['futureDisruptions']['subNetworks'], 'futures');
}
$parameters['currentDisruptions']['lines'] = $this->disruptionManager->getLinesDisruptions($currentDisruptions, 'currents');
$parameters['futureDisruptions']['lines'] = $this->disruptionManager->getLinesDisruptions($futureDisruptions, 'futures');
$parameters['currentDisruptions']['stopPoints'] = $this->disruptionManager->getStopPointsDisruptions($currentDisruptions, 'currents');
$parameters['futureDisruptions']['stopPoints'] = $this->disruptionManager->getStopPointsDisruptions($futureDisruptions, 'futures');
$parameters['currentDisruptions']['general'] = $this->disruptionManager->getGeneralDisruptions($currentDisruptions, 'currents');
$parameters['futureDisruptions']['general'] = $this->disruptionManager->getGeneralDisruptions($futureDisruptions, 'futures');
if ($this->security->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
$parameters['lineFavorites'] = $this->lineFavoriteService->getFavoriteLines([]);
$parameters['lineFavorites'] = $this
->lineFavoriteNormalizer
->normalize($parameters['lineFavorites'], $parameters['linesDisruptions'] ?? []);
}
$parameters['withDisruptionOnly'] = $withDisruptionOnly;
$parameters['currentSubNetworksDisruptions'] = $currentSubNetworksDisruptions;
$parameters['futureSubNetworksDisruptions'] = $futureSubNetworksDisruptions;
}
/**
* @param array $subNetworks
* @return int Number of disruptions on a subnetwork
*/
protected function getDisruptionsCountForSubNetworkOrLine(array $subNetworks, string $status) {
return array_reduce($subNetworks, function ($disruptionsCount, $subNetwork) use ($status) {
if ($this->hasDisruptionsForSubnetworkOrLine($subNetwork, $status)) {
return $disruptionsCount + 1;
}
return $disruptionsCount;
}, 0);
}
/**
* @param array $subNetworkData
* @return bool true if the subnetwork or one of its lines has disruptions
*/
protected function hasDisruptionsForSubnetworkOrLine(array $subNetworkData, string $status): bool
{
$hasSubnetworkDisruption = !empty($subNetworkData['disruptions'][$status]);
$hasLineDisruption = !empty($subNetworkData['disruptions']['lines'][$status]);
return $hasSubnetworkDisruption || $hasLineDisruption;
}
protected function generateMetas(array &$params)
{
$params['page_title'] = $this->metaService->getPageTitle($params);
$params['enable_no_index'] = $this->metaService->enableNoIndex();
$params['page_keywords'] = $this->metaService->getPageKeywords($params);
$params['page_description'] = $this->metaService->getPageDescription($params);
}
}