<?php
/**
* Router
*
* @author Vincent van Waasbergen <v.vanwaasbergen@visualmedia.nl>
*/
namespace VisualMedia\RoutingBundle\Service;
use Exception;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpKernel\CacheWarmer\WarmableInterface;
use Symfony\Component\Routing\RequestContext;
use Symfony\Component\Routing\Router as SymfonyRouter;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Routing\RouteCollection;
use VisualMedia\LisaBundle\Component\ManagerData;
use VisualMedia\RoutingBundle\Controller\RedirectController;
use VisualMedia\RoutingBundle\Entity\BaseRedirect;
use VisualMedia\RoutingBundle\Entity\BaseRoute;
use VisualMedia\TranslationBundle\Service\ChannelProvider;
/**
* Router
*/
class Router implements RouterInterface, WarmableInterface
{
/**
* @var RequestStack
*/
protected $requestStack;
/**
* @var RouterInterface
*/
protected $router;
/**
* @var EntityManagerInterface
*/
protected $manager;
/**
* @var ChannelProvider
*/
protected $channelProvider;
/**
* {@inheritdoc}
*/
public function __construct(RequestStack $requestStack, RouterInterface $router, EntityManagerInterface $manager)
{
$this->requestStack = $requestStack;
$this->router = $router;
$this->manager = $manager;
}
/**
* {@inheritdoc}
*/
public function initialize(ChannelProvider $channelProvider)
{
$this->channelProvider = $channelProvider;
}
/**
* {@inheritdoc}
*/
public function warmup(string $cacheDir)
{
// ...
}
/**
* {@inheritdoc}
*/
public function getRouteCollection()
{
return $this->router->getRouteCollection();
}
/**
* {@inheritdoc}
*/
public function getContext()
{
return $this->router->getContext();
}
/**
* {@inheritdoc}
*/
public function setContext(RequestContext $context)
{
$this->router->setContext($context);
}
/**
* {@inheritdoc}
*/
public function generate(string $name, array $parameters = [], int $referenceType = self::ABSOLUTE_PATH)
{
try {
return $this->router->generate($name, $parameters, $referenceType);
}
catch (Exception $exception) {
return '#';
}
}
/**
* {@inheritdoc}
*/
public function match($pathinfo)
{
// Match non-fallback system routes.
try {
if (is_array($match = $this->router->match($pathinfo))) {
$collection = $this->router->getRouteCollection();
if (null !== $route = $collection->get($match['_route'])) {
if (!$route->getOption('fallback')) {
return $match;
}
}
}
} catch (Exception $exception) {}
// Match database routes.
$locales = [];
if (null !== $domain = $this->channelProvider->getCurrentDomain()) {
foreach ($domain->locales as $locale) {
$locales[] = $locale->code;
}
if (!empty($locales)) {
$request = $this->requestStack->getMasterRequest();
$manager = $this->manager->getRepository(BaseRoute::class);
$route = $manager->getFirst(new ManagerData([
'url' => $pathinfo,
'locales' => $locales,
'active' => true,
]));
if ($route) {
if ($request->getLocale() !== $locale = $route->locale->code) {
$request->setLocale($locale);
}
$data = array_merge([
'_route' => $route->name,
'_controller' => $route->getController(),
], $route->getParameters());
return $data;
}
}
}
// Match redirects.
$manager = $this->manager->getRepository(BaseRedirect::class);
$redirect = $manager->getFirst(new ManagerData([
'urlFrom' => $pathinfo,
'active' => true,
]));
if ($redirect) {
return [
'_route' => 'redirect',
'_controller' => sprintf('%s::%s', RedirectController::class, 'redirectAction'),
'url' => $redirect->urlTo,
'code' => $redirect->type,
];
}
// Match fallback system routes.
return $this->router->match($pathinfo);
}
/**
* {@inheritdoc}
*/
public function getOption($option)
{
return $this->router->getOption($option);
}
}