src/Bundle/Routing/CompoundRouter.php line 87

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Bundle\Routing;
  4. use InvalidArgumentException;
  5. use Psr\Log\LoggerInterface;
  6. use RuntimeException;
  7. use Symfony\Bundle\FrameworkBundle\Routing\Router;
  8. use Symfony\Component\HttpFoundation\Request;
  9. use Symfony\Component\HttpKernel\CacheWarmer\WarmableInterface;
  10. use Symfony\Component\Routing\Exception\MethodNotAllowedException;
  11. use Symfony\Component\Routing\Exception\ResourceNotFoundException;
  12. use Symfony\Component\Routing\Exception\RouteNotFoundException;
  13. use Symfony\Component\Routing\Matcher\RequestMatcherInterface;
  14. use Symfony\Component\Routing\RequestContext;
  15. use Symfony\Component\Routing\RouteCollection;
  16. use Symfony\Component\Routing\RouterInterface;
  17. class CompoundRouter implements CompoundRouterInterfaceWarmableInterface
  18. {
  19.     /**
  20.      * Array of routers sorted by priority.
  21.      *
  22.      * @var RouterInterface[]
  23.      */
  24.     protected $sortedRouters = [];
  25.     /**
  26.      * Array of routers grouped by priority.
  27.      *
  28.      * @var RouterInterface[]
  29.      */
  30.     protected $routers = [];
  31.     /**
  32.      * @var RouteCollection|null
  33.      */
  34.     protected $routeCollection;
  35.     /**
  36.      * @var RequestContext|null
  37.      */
  38.     protected $context;
  39.     /**
  40.      * @var LoggerInterface|null
  41.      */
  42.     protected $logger;
  43.     public function __construct(LoggerInterface $logger null)
  44.     {
  45.         $this->logger $logger;
  46.     }
  47.     /**
  48.      * {@inheritDoc}
  49.      */
  50.     public function matchRequest(Request $request): array
  51.     {
  52.         $this->logger->debug("REQUEST PATH:" $request->getPathInfo());
  53.         $exc null;
  54.         foreach ($this->all() as $router) {
  55.             try {
  56.                 $ret $router->matchRequest($request);
  57.                 $this->logger->debug(
  58.                     sprintf('Router %s matched the route'get_class($router))
  59.                 );
  60.                 return $ret;
  61.             } catch (ResourceNotFoundException $e) {
  62.                 if ($this->logger) {
  63.                     $this->logger->debug(
  64.                         sprintf('Router %s was not able to match, message "%s"'get_class($router), $e->getMessage())
  65.                     );
  66.                 }
  67.             } catch (MethodNotAllowedException $e) {
  68.                 if ($this->logger) {
  69.                     $this->logger->debug(
  70.                         sprintf('Router %s do not allow this method, message "%s"'get_class($router), $e->getMessage())
  71.                     );
  72.                     $exc $e;
  73.                 }
  74.             }
  75.         }
  76.         throw $exc ?: new ResourceNotFoundException('None of the routers could matched the request: ' $request);
  77.     }
  78.     /**
  79.      * {@inheritDoc}
  80.      */
  81.     public function match($pathinfo): array
  82.     {
  83.         throw new RuntimeException('The match method is unsupported, adjust Router to use matchRequest method.');
  84.     }
  85.     /**
  86.      * {@inheritDoc}
  87.      */
  88.     public function generate($name$parameters = [], $referenceType self::ABSOLUTE_PATH): string
  89.     {
  90.         foreach ($this->all() as $router) {
  91.             try {
  92.                 return $router->generate($name$parameters$referenceType);
  93.             } catch (RouteNotFoundException $e) {
  94.                 if ($this->logger) {
  95.                     $this->logger->debug(
  96.                         sprintf(
  97.                             'Router %s cannot generate route "%s". Reason: "%s"',
  98.                             get_class($router),
  99.                             $name,
  100.                             $e->getMessage()
  101.                         )
  102.                     );
  103.                 }
  104.             }
  105.         }
  106.         throw new RouteNotFoundException("None of the routers were able to generate route \"$name\"");
  107.     }
  108.     /**
  109.      * {@inheritDoc}
  110.      */
  111.     public function all(): array
  112.     {
  113.         if (!$this->sortedRouters) {
  114.             $this->sortedRouters $this->sortRouters();
  115.             // Context setting must be done here in order to prevent cache issues
  116.             if (null !== $ctx $this->context) {
  117.                 foreach ($this->sortedRouters as $router)
  118.                     $router->setContext($ctx);
  119.             }
  120.         }
  121.         return $this->sortedRouters;
  122.     }
  123.     public function attach(RouterInterface $routerint $priority 0): CompoundRouterInterface
  124.     {
  125.         if (!$router instanceof RequestMatcherInterface)
  126.             throw new InvalidArgumentException(
  127.                 sprintf('%s must implement %s'get_class($router), RequestMatcherInterface::class)
  128.             );
  129.         if (!isset($this->routers[$priority]))
  130.             $this->routers[$priority] = [];
  131.         $this->routers[$priority][] = $router;
  132.         $this->sortedRouters = [];
  133.         return $this;
  134.     }
  135.     /**
  136.      * {@inheritDoc}
  137.      */
  138.     public function getRouteCollection(): RouteCollection
  139.     {
  140.         if (!$this->routeCollection) {
  141.             $this->routeCollection = new CompoundRouteCollection();
  142.             foreach ($this->all() as $router)
  143.                 $this->routeCollection->addCollection($router->getRouteCollection());
  144.         }
  145.         return $this->routeCollection;
  146.     }
  147.     /**
  148.      * {@inheritDoc}
  149.      */
  150.     public function setContext(RequestContext $context)
  151.     {
  152.         $this->context $context;
  153.         foreach ($this->all() as $router)
  154.             $router->setContext($context);
  155.         return $this;
  156.     }
  157.     /**
  158.      * {@inheritDoc}
  159.      */
  160.     public function getContext(): RequestContext
  161.     {
  162.         return $this->context;
  163.     }
  164.     /**
  165.      * {@inheritDoc}
  166.      */
  167.     public function warmUp($cacheDir): array
  168.     {
  169.         foreach ($this->all() as $router)
  170.             if ($router instanceof WarmableInterface)
  171.                 $router->warmUp($cacheDir);
  172.         return [];
  173.     }
  174.     /**
  175.      * @return RouterInterface[]
  176.      */
  177.     protected function sortRouters(): array
  178.     {
  179.         $output = [];
  180.         krsort($this->routers);
  181.         foreach ($this->routers as $routers)
  182.             $output array_merge($output$routers);
  183.         return $output;
  184.     }
  185. }