<?php
namespace App\Service;
use App\Entity\Block;
use App\Entity\Stop;
use App\Repository\BlockRepository;
use App\Repository\StopRepository;
use App\Utils\StringUtils;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
use Symfony\Component\Routing\RouterInterface;
class BlockPathService
{
protected StopRepository $stopRepo;
protected BlockRepository $blockRepo;
private RouterInterface $router;
protected string $domainprefix;
public function __construct(EntityManagerInterface $entityManager, RouterInterface $router, string $domainprefix) {
$this->domainprefix = $domainprefix;
$this->router = $router;
$this->stopRepo = $entityManager->getRepository(Stop::class);
$this->blockRepo = $entityManager->getRepository(Block::class);
}
public function getBlock(Request $request): ?Block {
$path = $request->getPathInfo();
$host = $request->getHost();
$host = ltrim($host, $this->domainprefix);
return $this->blockRepo->findOneByPathIgnoreEndingSlash($path, $host);
}
/**
* Used in admin, to get informatin about the route
* From block.path, get intern route configuration and labels of ids
* @param $blockPath /fr/compagnie-de-bus/budgetbus or www.comparabus.com/fr/compagnie-de-bus/budgetbus (never starts with local- or test-)
*/
public function getRoute(string $blockPath) : ?array {
$blockPath = strtok($blockPath, "#"); //remove after #
try{
$backupHost = $this->router->getContext()->getHost();
[$host, $pathinfo] = self::extractDomainFromPath($blockPath); //to have stuff cleaner, will must probably always get the host set
if($host) $this->router->getContext()->setHost($this->domainprefix.$host);
$match = $this->router->match($pathinfo);
if($host) $this->router->getContext()->setHost($backupHost); //otherwise if done in a loop, will use last host when path starts with '/'
// in debug put ids label
$debug = '';
$debug .= isset($match['depStopId']) ? $this->stopRepo->find($match['depStopId'])->getName().' ' : '';
$debug .= isset($match['arrStopId']) ? $this->stopRepo->find($match['arrStopId'])->getName().' ' : '';
$debug .= isset($match['stopId']) ? $this->stopRepo->find($match['stopId'])->getName() : '';
$match['_cbdebug']=$debug;
return $match;
} catch (ResourceNotFoundException $e) {}
return null;
}
static public function extractDomainFromPath(string $url): array {
if (!StringUtils::startsWith($url, 'www')) return [null, $url];
if (!StringUtils::contains($url, '/')) return [$url, ''];
$host = StringUtils::substringBefore($url, '/');
$url = '/'.StringUtils::substringAfter($url, '/');
return [$host, $url];
}
public function decodeUrl(string $pathinfo): array {
$routeParam = $this->router->match($pathinfo);
if (!isset($routeParam['_route'])) throw new \Exception("_route missing for path: ".$pathinfo);
$route = $routeParam['_route'];
$conveyance = self::routeNameToConveyance($route);
if ($conveyance) {
return [
'depStopId' => $routeParam['depStopId'],
'arrStopId' => $routeParam['arrStopId'],
'conveyance' => $conveyance,
'locale' => $routeParam['_locale'],
'path' => null,
];
} else {
return ['path' => $pathinfo];
}
}
}