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

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 = array(), $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.                 $routes->add($name$route);
  72.                 continue;
  73.             }
  74.             preg_match('#^' $this->pattern '$#'$name$matches);
  75.             if (count($matches) === 0) {
  76.                 continue;
  77.             }
  78.             $domain $this->getDomainByRouteMatches($matches$name);
  79.             if (is_null($domain)) {
  80.                 continue;
  81.             }
  82.             $route = clone $route;
  83.             $route->setOption('expose'$domain);
  84.             $routes->add($name$route);
  85.         }
  86.         return $routes;
  87.     }
  88.     /**
  89.      * {@inheritDoc}
  90.      */
  91.     public function getBaseUrl()
  92.     {
  93.         return $this->router->getContext()->getBaseUrl() ?: '';
  94.     }
  95.     /**
  96.      * {@inheritDoc}
  97.      */
  98.     public function getPrefix($locale)
  99.     {
  100.         if (isset($this->bundles['JMSI18nRoutingBundle'])) {
  101.             return $locale I18nLoader::ROUTING_PREFIX;
  102.         }
  103.         return '';
  104.     }
  105.     /**
  106.      * {@inheritDoc}
  107.      */
  108.     public function getHost()
  109.     {
  110.         $requestContext $this->router->getContext();
  111.         $host $requestContext->getHost() .
  112.             ('' === $this->getPort() ? $this->getPort() : ':' $this->getPort());
  113.         return $host;
  114.     }
  115.     /**
  116.      * {@inheritDoc}
  117.      */
  118.     public function getPort()
  119.     {
  120.         $requestContext $this->router->getContext();
  121.         $port="";
  122.         if ($this->usesNonStandardPort()) {
  123.             $method sprintf('get%sPort'ucfirst($requestContext->getScheme()));
  124.             $port $requestContext->$method();
  125.         }
  126.         return $port;
  127.     }
  128.     /**
  129.      * {@inheritDoc}
  130.      */
  131.     public function getScheme()
  132.     {
  133.         return $this->router->getContext()->getScheme();
  134.     }
  135.     /**
  136.      * {@inheritDoc}
  137.      */
  138.     public function getCachePath($locale)
  139.     {
  140.         $cachePath $this->cacheDir DIRECTORY_SEPARATOR 'fosJsRouting';
  141.         if (!file_exists($cachePath)) {
  142.             mkdir($cachePath);
  143.         }
  144.         if (isset($this->bundles['JMSI18nRoutingBundle'])) {
  145.             $cachePath $cachePath DIRECTORY_SEPARATOR 'data.' $locale '.json';
  146.         } else {
  147.             $cachePath $cachePath DIRECTORY_SEPARATOR 'data.json';
  148.         }
  149.         return $cachePath;
  150.     }
  151.     /**
  152.      * {@inheritDoc}
  153.      */
  154.     public function getResources()
  155.     {
  156.         return $this->router->getRouteCollection()->getResources();
  157.     }
  158.     /**
  159.      * {@inheritDoc}
  160.      */
  161.     public function isRouteExposed(Route $route$name)
  162.     {
  163.         return true === $route->hasOption('expose') ||
  164.             ('' !== $this->pattern && preg_match('#^' $this->pattern '$#'$name));
  165.     }
  166.     protected function getDomainByRouteMatches($matches$name)
  167.     {
  168.         $matches array_filter($matches, function($match) {
  169.             return !empty($match);
  170.         });
  171.         $matches array_flip(array_intersect_key($matchesarray_flip($this->availableDomains)));
  172.         return isset($matches[$name]) ? $matches[$name] : null;
  173.     }
  174.     protected function extractDomainPatterns($routesToExpose)
  175.     {
  176.         $domainPatterns = array();
  177.         foreach ($routesToExpose as $item) {
  178.             if (is_string($item)) {
  179.                 $domainPatterns['default'][] = $item;
  180.                 continue;
  181.             }
  182.             if (is_array($item) && is_string($item['pattern'])) {
  183.                 if (!isset($item['domain'])) {
  184.                     $domainPatterns['default'][] = $item['pattern'];
  185.                     continue;
  186.                 } elseif (is_string($item['domain'])) {
  187.                     $domainPatterns[$item['domain']][] = $item['pattern'];
  188.                     continue;
  189.                 }
  190.             }
  191.             throw new \Exception('routes_to_expose definition is invalid');
  192.         }
  193.         return $domainPatterns;
  194.     }
  195.     /**
  196.      * Convert the routesToExpose array in a regular expression pattern
  197.      *
  198.      * @param $domainPatterns
  199.      * @return string
  200.      * @throws \Exception
  201.      */
  202.     protected function buildPattern($domainPatterns)
  203.     {
  204.         $patterns = array();
  205.         foreach ($domainPatterns as $domain => $items) {
  206.             $patterns[] =  '(?P<' $domain '>' implode('|'$items) . ')';
  207.         }
  208.         return implode('|'$patterns);
  209.     }
  210.     /**
  211.      * Check whether server is serving this request from a non-standard port
  212.      *
  213.      * @return bool
  214.      */
  215.     private function usesNonStandardPort()
  216.     {
  217.         return $this->usesNonStandardHttpPort() || $this->usesNonStandardHttpsPort();
  218.     }
  219.     /**
  220.      * Check whether server is serving HTTP over a non-standard port
  221.      *
  222.      * @return bool
  223.      */
  224.     private function usesNonStandardHttpPort()
  225.     {
  226.         return 'http' === $this->getScheme() && '80' != $this->router->getContext()->getHttpPort();
  227.     }
  228.     /**
  229.      * Check whether server is serving HTTPS over a non-standard port
  230.      *
  231.      * @return bool
  232.      */
  233.     private function usesNonStandardHttpsPort()
  234.     {
  235.         return 'https' === $this->getScheme() && '443' != $this->router->getContext()->getHttpsPort();
  236.     }
  237. }