<?php
namespace App\Controller\Frontend;
use App\Entity\model\Conveyance;
use App\Entity\model\RouteSeo;
use App\Entity\Stop;
use App\Repository\RouteRepository;
use App\Service\Client\ClientRepository;
use App\Service\OdSeoService;
use App\Service\UrlRewrite;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Entity;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class OdController extends AbstractController {
// Check Router.js
//use in twig as const
public const REDIRECT_TAB = 'tab'; //autoload=0
public const REDIRECT_NONE = 'none'; //autoload=1
public const REDIRECT_FAKEURL = 'fakeurl'; //autoload=1
public const REDIRECT_URL = 'url'; //default, autoload=0
/** @required */
public UrlRewrite $rewriteService;
/** @required */
public ClientRepository $clientRepo;
/** @required */
public OdSeoService $seoService;
/** @required */
public RouteRepository $routeRepo;
/**
* @Route("/bus-{slug}-{depStopId}-{arrStopId}/{dateFrom}/{dateTo}", name="page_bus_od",
* requirements = {"depStopId" = "\d+", "arrStopId" = "\d+", "slug" = "[a-zA-Z1-9\-_\/]+"},
* defaults={"dateFrom" = null, "dateTo" = null, "transport" = "bus"})
*
* @Route("/train/{slug}-{depStopId}-{arrStopId}/{dateFrom}/{dateTo}", name="page_train_od",
* requirements = {"depStopId" = "\d+", "arrStopId" = "\d+", "slug" = "[a-zA-Z1-9\-_\/]+"},
* defaults={"dateFrom" = null, "dateTo" = null, "transport" = "train"}, options={"i18n_locales"={"fr", "es", "it", "en", "en_GB", "cs", "pl", "ru", "uk_UA"}})
*
* @Route("/covoiturage/{slug}-{depStopId}-{arrStopId}/{dateFrom}/{dateTo}", name="page_carpooling_od",
* requirements = {"depStopId" = "\d+", "arrStopId" = "\d+", "slug" = "[a-zA-Z1-9\-_\/]+"},
* defaults={"dateFrom" = null, "dateTo" = null, "transport" = "carpooling"}, options={"i18n_locales"={"fr"}})
*
* @Route("/avion/vol-{slug}-{depStopId}-{arrStopId}/{dateFrom}/{dateTo}", name="page_flight_od",
* requirements = {"depStopId" = "\d+", "arrStopId" = "\d+", "slug" = "[a-zA-Z1-9\-_\/]+"},
* defaults={"dateFrom" = null, "dateTo" = null, "transport" = "flight"}, options={"i18n_locales"={"fr"}})
* @Route("/avion/o-d-{depStopId}-{arrStopId}/{dateFrom}/{dateTo}", name="page_flight_od_fake",
* requirements = {"depStopId" = "\d+", "arrStopId" = "\d+"},
* defaults={"dateFrom" = null, "dateTo" = null, "transport" = "flight"}, options={"i18n_locales"={"fr"}})
*
* @Route("/billet/{slug}-{depStopId}-{arrStopId}/{dateFrom}/{dateTo}", name="page_ticket_od",
* requirements = {"depStopId" = "\d+", "arrStopId" = "\d+", "slug" = "[a-zA-Z1-9\-_\/]+"},
* defaults={"dateFrom" = null, "dateTo" = null, "transport"="all"}, options={"i18n_locales"={"en","fr","es","it","cs","ru","uk_UA","tr","pl"}})
* // that list of lang is in widget_doc.html.twig
*
* @Entity("depStop", expr="repository.findNotRemovedTranslated(depStopId, _locale)")
* @Entity("arrStop", expr="repository.findNotRemovedTranslated(arrStopId, _locale)")
*/
public function odAction(Request $r, UrlRewrite $rewrite, Stop $depStop, Stop $arrStop, ?string $dateFrom, ?string $dateTo, string $_locale, string $transport) {
$noIndex = $dateFrom !== null; // no index if has dates
$currentUriNoQueryString = self::getUriWithoutQueryString($r);
$expectedUri = $this->rewriteService->generateFromAtoBUrl($depStop, $arrStop, $dateFrom, $dateTo, false, $_locale, $transport);
if($currentUriNoQueryString !== $expectedUri) {
return $this->redirect($expectedUri);
}
$canonicalUrl = $this->rewriteService->generateFromAtoBUrlWithoutDate($depStop, $arrStop, false, null, $transport);
$seoOd = $this->seoService->getSeoOd($depStop, $arrStop, $transport, $noIndex, $_locale);
$popularRoutes = $noIndex ? [] : $this->getPopularRouteFrom($depStop, $transport, $_locale);
$infoStop = $noIndex ? null : $this->seoService->getInfoStop($arrStop->getId(), $transport, $_locale);
$response = $this->render('Default/odpage/odpage.html.twig', [
'depStop' => $depStop,
'arrStop' => $arrStop,
'search' => [
'depStopId' => $depStop->getId(),
'depStopName' => $depStop->getName(),
'arrStopId' => $arrStop->getId(),
'arrStopName' => $arrStop->getName(),
'dateFrom' => $dateFrom,
'dateTo' => $dateTo,
'type' => $transport
],
'redirect' => self::REDIRECT_FAKEURL, //only change url in js
'odpage' => $rewrite->generateODWebappLink($transport),
'noIndex' => $noIndex,
'canonical' => $canonicalUrl,
'transport' => $transport,
'cheapest' => $seoOd->cheapest,
//commun seo content (bus & train)
'seoOd' => $seoOd,
//bus related content
'infostop' => $infoStop,
'popularRoutes' => $popularRoutes,
]);
if(!$noIndex) self::setCache($response);
return $response;
}
//TODO use varnish : https://www.slideshare.net/lisachenko/handling-10k-requests-per-second-with-symfony-and-varnish
/**
* Do not use Cache annotation because cache only in some case
*/
protected static function setCache(Response $response) {
$date = new \DateTime();
$date->modify('+3600 seconds');
$response->setExpires($date);
//difference with $response->setSharedMaxAge(3600); ?
$response->setPublic();
}
public static function getUriWithoutQueryString(Request $r): string {
$currentUri = $r->getUri();
$pos = strpos($currentUri, '?');
return $pos ? substr($currentUri,0,$pos) : $currentUri;
}
protected function generateAlternate(Stop $depStop, Stop $arrStop): array {
$locales = ['fr', 'es', 'en'];
$alternates = [];
foreach($locales as $locale){
$url = $this->rewriteService->generateFromAtoBUrlWithoutDate($depStop, $arrStop, false, $locale);
$alternates[] = [
'hreflang' => $locale, //transform to locale
'href' => $url
];
}
return $alternates;
}
/**
* @return Link[]
*/
protected function getPopularRouteFrom(Stop $depStop, string $conveyance, string $_locale): array {
/** @var RouteSeo[] $routes */
$routes = [];
if ($_locale === 'fr' && $conveyance === Conveyance::BUS) { //FIXME use only full localell
$companyIds = $this->clientRepo->findIdsByType($conveyance);
$routes = $this->routeRepo->findTopFrenchByDepStopId($depStop->getId(), $companyIds);
} else {
$routes = $this->seoService->getPopularRoutesFromCsv($depStop, $conveyance, $_locale);
}
return $this->rewriteService->createRoutesLink($routes);
}
}