vendor/friendsofsymfony/jsrouting-bundle/Extractor/ExposedRoutesExtractor.php line 79

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of the FOSJsRoutingBundle package.
  4.  *
  5.  * (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
  6.  *
  7.  * For the full copyright and license information, please view the LICENSE
  8.  * file that was distributed with this source code.
  9.  */
  10. namespace FOS\JsRoutingBundle\Extractor;
  11. use Symfony\Component\Routing\Route;
  12. use Symfony\Component\Routing\RouteCollection;
  13. use Symfony\Component\Routing\RouterInterface;
  14. use JMS\I18nRoutingBundle\Router\I18nLoader;
  15. /**
  16.  * @author      William DURAND <william.durand1@gmail.com>
  17.  */
  18. class ExposedRoutesExtractor implements ExposedRoutesExtractorInterface
  19. {
  20.     /**
  21.      * @var RouterInterface
  22.      */
  23.     protected $router;
  24.     /**
  25.      * Base cache directory
  26.      *
  27.      * @var string
  28.      */
  29.     protected $cacheDir;
  30.     /**
  31.      * @var array
  32.      */
  33.     protected $bundles;
  34.     /**
  35.      * @var string
  36.      */
  37.     protected $pattern;
  38.     /**
  39.      * @var array
  40.      */
  41.     protected $availableDomains;
  42.     /**
  43.      * Default constructor.
  44.      *
  45.      * @param RouterInterface $router The router.
  46.      * @param array $routesToExpose Some route names to expose.
  47.      * @param string $cacheDir
  48.      * @param array $bundles list of loaded bundles to check when generating the prefix
  49.      *
  50.      * @throws \Exception
  51.      */
  52.     public function __construct(RouterInterface $router, array $routesToExpose$cacheDir$bundles = array())
  53.     {
  54.         $this->router         $router;
  55.         $this->cacheDir       $cacheDir;
  56.         $this->bundles        $bundles;
  57.         $domainPatterns $this->extractDomainPatterns($routesToExpose);
  58.         $this->availableDomains array_keys($domainPatterns);
  59.         $this->pattern $this->buildPattern($domainPatterns);
  60.     }
  61.     /**
  62.      * {@inheritDoc}
  63.      */
  64.     public function getRoutes()
  65.     {
  66.         $collection $this->router->getRouteCollection();
  67.         $routes     = new RouteCollection();
  68.         /** @var Route $route */
  69.         foreach ($collection->all() as $name => $route) {
  70.             if ($route->hasOption('expose')) {
  71.                 $expose $route->getOption('expose');
  72.                 if ($expose !== false && $expose !== 'false') {
  73.                     $routes->add($name$route);
  74.                 }
  75.                 continue;
  76.             }
  77.             preg_match('#^' $this->pattern '$#'$name$matches);
  78.             if (count($matches) === 0) {
  79.                 continue;
  80.             }
  81.             $domain $this->getDomainByRouteMatches($matches$name);
  82.             if (is_null($domain)) {
  83.                 continue;
  84.             }
  85.             $route = clone $route;
  86.             $route->setOption('expose'$domain);
  87.             $routes->add($name$route);
  88.         }
  89.         return $routes;
  90.     }
  91.     /**
  92.      * {@inheritDoc}
  93.      */
  94.     public function getBaseUrl()
  95.     {
  96.         return $this->router->getContext()->getBaseUrl() ?: '';
  97.     }
  98.     /**
  99.      * {@inheritDoc}
  100.      */
  101.     public function getPrefix($locale)
  102.     {
  103.         if (isset($this->bundles['JMSI18nRoutingBundle'])) {
  104.             return $locale I18nLoader::ROUTING_PREFIX;
  105.         }
  106.         return '';
  107.     }
  108.     /**
  109.      * {@inheritDoc}
  110.      */
  111.     public function getHost()
  112.     {
  113.         $requestContext $this->router->getContext();
  114.         $host $requestContext->getHost() .
  115.             ('' === $this->getPort() ? $this->getPort() : ':' $this->getPort());
  116.         return $host;
  117.     }
  118.     /**
  119.      * {@inheritDoc}
  120.      */
  121.     public function getPort()
  122.     {
  123.         $requestContext $this->router->getContext();
  124.         $port="";
  125.         if ($this->usesNonStandardPort()) {
  126.             $method sprintf('get%sPort'ucfirst($requestContext->getScheme()));
  127.             $port $requestContext->$method();
  128.         }
  129.         return $port;
  130.     }
  131.     /**
  132.      * {@inheritDoc}
  133.      */
  134.     public function getScheme()
  135.     {
  136.         return $this->router->getContext()->getScheme();
  137.     }
  138.     /**
  139.      * {@inheritDoc}
  140.      */
  141.     public function getCachePath($locale)
  142.     {
  143.         $cachePath $this->cacheDir DIRECTORY_SEPARATOR 'fosJsRouting';
  144.         if (!file_exists($cachePath)) {
  145.             mkdir($cachePath);
  146.         }
  147.         if (isset($this->bundles['JMSI18nRoutingBundle'])) {
  148.             $cachePath $cachePath DIRECTORY_SEPARATOR 'data.' $locale '.json';
  149.         } else {
  150.             $cachePath $cachePath DIRECTORY_SEPARATOR 'data.json';
  151.         }
  152.         return $cachePath;
  153.     }
  154.     /**
  155.      * {@inheritDoc}
  156.      */
  157.     public function getResources()
  158.     {
  159.         return $this->router->getRouteCollection()->getResources();
  160.     }
  161.     /**
  162.      * {@inheritDoc}
  163.      */
  164.     public function isRouteExposed(Route $route$name)
  165.     {
  166.         if (false === $route->hasOption('expose')) {
  167.             return ('' !== $this->pattern && preg_match('#^' $this->pattern '$#'$name));
  168.         }
  169.         $status $route->getOption('expose');
  170.         return ($status !== false && $status !== 'false');
  171.     }
  172.     protected function getDomainByRouteMatches($matches$name)
  173.     {
  174.         $matches array_filter($matches, function($match) {
  175.             return !empty($match);
  176.         });
  177.         $matches array_flip(array_intersect_key($matchesarray_flip($this->availableDomains)));
  178.         return isset($matches[$name]) ? $matches[$name] : null;
  179.     }
  180.     protected function extractDomainPatterns($routesToExpose)
  181.     {
  182.         $domainPatterns = array();
  183.         foreach ($routesToExpose as $item) {
  184.             if (is_string($item)) {
  185.                 $domainPatterns['default'][] = $item;
  186.                 continue;
  187.             }
  188.             if (is_array($item) && is_string($item['pattern'])) {
  189.                 if (!isset($item['domain'])) {
  190.                     $domainPatterns['default'][] = $item['pattern'];
  191.                     continue;
  192.                 } elseif (is_string($item['domain'])) {
  193.                     $domainPatterns[$item['domain']][] = $item['pattern'];
  194.                     continue;
  195.                 }
  196.             }
  197.             throw new \Exception('routes_to_expose definition is invalid');
  198.         }
  199.         return $domainPatterns;
  200.     }
  201.     /**
  202.      * Convert the routesToExpose array in a regular expression pattern
  203.      *
  204.      * @param $domainPatterns
  205.      * @return string
  206.      * @throws \Exception
  207.      */
  208.     protected function buildPattern($domainPatterns)
  209.     {
  210.         $patterns = array();
  211.         foreach ($domainPatterns as $domain => $items) {
  212.             $patterns[] =  '(?P<' $domain '>' implode('|'$items) . ')';
  213.         }
  214.         return implode('|'$patterns);
  215.     }
  216.     /**
  217.      * Check whether server is serving this request from a non-standard port
  218.      *
  219.      * @return bool
  220.      */
  221.     private function usesNonStandardPort()
  222.     {
  223.         return $this->usesNonStandardHttpPort() || $this->usesNonStandardHttpsPort();
  224.     }
  225.     /**
  226.      * Check whether server is serving HTTP over a non-standard port
  227.      *
  228.      * @return bool
  229.      */
  230.     private function usesNonStandardHttpPort()
  231.     {
  232.         return 'http' === $this->getScheme() && '80' != $this->router->getContext()->getHttpPort();
  233.     }
  234.     /**
  235.      * Check whether server is serving HTTPS over a non-standard port
  236.      *
  237.      * @return bool
  238.      */
  239.     private function usesNonStandardHttpsPort()
  240.     {
  241.         return 'https' === $this->getScheme() && '443' != $this->router->getContext()->getHttpsPort();
  242.     }
  243. }