8889841cImportConfigurator.php000064400000003674150536261440011132 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Symfony\Component\Routing\Loader\Configurator; use Symfony\Component\Routing\RouteCollection; /** * @author Nicolas Grekas */ class ImportConfigurator { use Traits\HostTrait; use Traits\PrefixTrait; use Traits\RouteTrait; private $parent; public function __construct(RouteCollection $parent, RouteCollection $route) { $this->parent = $parent; $this->route = $route; } /** * @return array */ public function __sleep() { throw new \BadMethodCallException('Cannot serialize '.__CLASS__); } public function __wakeup() { throw new \BadMethodCallException('Cannot unserialize '.__CLASS__); } public function __destruct() { $this->parent->addCollection($this->route); } /** * Sets the prefix to add to the path of all child routes. * * @param string|array $prefix the prefix, or the localized prefixes * * @return $this */ final public function prefix($prefix, bool $trailingSlashOnRoot = true): self { $this->addPrefix($this->route, $prefix, $trailingSlashOnRoot); return $this; } /** * Sets the prefix to add to the name of all child routes. * * @return $this */ final public function namePrefix(string $namePrefix): self { $this->route->addNamePrefix($namePrefix); return $this; } /** * Sets the host to use for all child routes. * * @param string|array $host the host, or the localized hosts * * @return $this */ final public function host($host): self { $this->addHost($this->route, $host); return $this; } } RouteConfigurator.php000064400000002321150536261440010742 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Symfony\Component\Routing\Loader\Configurator; use Symfony\Component\Routing\RouteCollection; /** * @author Nicolas Grekas */ class RouteConfigurator { use Traits\AddTrait; use Traits\HostTrait; use Traits\RouteTrait; protected $parentConfigurator; public function __construct(RouteCollection $collection, RouteCollection $route, string $name = '', CollectionConfigurator $parentConfigurator = null, array $prefixes = null) { $this->collection = $collection; $this->route = $route; $this->name = $name; $this->parentConfigurator = $parentConfigurator; // for GC control $this->prefixes = $prefixes; } /** * Sets the host to use for all child routes. * * @param string|array $host the host, or the localized hosts * * @return $this */ final public function host($host): self { $this->addHost($this->route, $host); return $this; } } Traits/AddTrait.php000064400000003362150536261440010231 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Symfony\Component\Routing\Loader\Configurator\Traits; use Symfony\Component\Routing\Loader\Configurator\AliasConfigurator; use Symfony\Component\Routing\Loader\Configurator\CollectionConfigurator; use Symfony\Component\Routing\Loader\Configurator\RouteConfigurator; use Symfony\Component\Routing\RouteCollection; /** * @author Nicolas Grekas */ trait AddTrait { use LocalizedRouteTrait; /** * @var RouteCollection */ protected $collection; protected $name = ''; protected $prefixes; /** * Adds a route. * * @param string|array $path the path, or the localized paths of the route */ public function add(string $name, $path): RouteConfigurator { $parentConfigurator = $this instanceof CollectionConfigurator ? $this : ($this instanceof RouteConfigurator ? $this->parentConfigurator : null); $route = $this->createLocalizedRoute($this->collection, $name, $path, $this->name, $this->prefixes); return new RouteConfigurator($this->collection, $route, $this->name, $parentConfigurator, $this->prefixes); } public function alias(string $name, string $alias): AliasConfigurator { return new AliasConfigurator($this->collection->addAlias($name, $alias)); } /** * Adds a route. * * @param string|array $path the path, or the localized paths of the route */ public function __invoke(string $name, $path): RouteConfigurator { return $this->add($name, $path); } } Traits/RouteTrait.php000064400000006752150536261440010645 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Symfony\Component\Routing\Loader\Configurator\Traits; use Symfony\Component\Routing\Route; use Symfony\Component\Routing\RouteCollection; trait RouteTrait { /** * @var RouteCollection|Route */ protected $route; /** * Adds defaults. * * @return $this */ final public function defaults(array $defaults): self { $this->route->addDefaults($defaults); return $this; } /** * Adds requirements. * * @return $this */ final public function requirements(array $requirements): self { $this->route->addRequirements($requirements); return $this; } /** * Adds options. * * @return $this */ final public function options(array $options): self { $this->route->addOptions($options); return $this; } /** * Whether paths should accept utf8 encoding. * * @return $this */ final public function utf8(bool $utf8 = true): self { $this->route->addOptions(['utf8' => $utf8]); return $this; } /** * Sets the condition. * * @return $this */ final public function condition(string $condition): self { $this->route->setCondition($condition); return $this; } /** * Sets the pattern for the host. * * @return $this */ final public function host(string $pattern): self { $this->route->setHost($pattern); return $this; } /** * Sets the schemes (e.g. 'https') this route is restricted to. * So an empty array means that any scheme is allowed. * * @param string[] $schemes * * @return $this */ final public function schemes(array $schemes): self { $this->route->setSchemes($schemes); return $this; } /** * Sets the HTTP methods (e.g. 'POST') this route is restricted to. * So an empty array means that any method is allowed. * * @param string[] $methods * * @return $this */ final public function methods(array $methods): self { $this->route->setMethods($methods); return $this; } /** * Adds the "_controller" entry to defaults. * * @param callable|string|array $controller a callable or parseable pseudo-callable * * @return $this */ final public function controller($controller): self { $this->route->addDefaults(['_controller' => $controller]); return $this; } /** * Adds the "_locale" entry to defaults. * * @return $this */ final public function locale(string $locale): self { $this->route->addDefaults(['_locale' => $locale]); return $this; } /** * Adds the "_format" entry to defaults. * * @return $this */ final public function format(string $format): self { $this->route->addDefaults(['_format' => $format]); return $this; } /** * Adds the "_stateless" entry to defaults. * * @return $this */ final public function stateless(bool $stateless = true): self { $this->route->addDefaults(['_stateless' => $stateless]); return $this; } } Traits/LocalizedRouteTrait.php000064400000004745150536261440012474 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Symfony\Component\Routing\Loader\Configurator\Traits; use Symfony\Component\Routing\Route; use Symfony\Component\Routing\RouteCollection; /** * @internal * * @author Nicolas Grekas * @author Jules Pietri */ trait LocalizedRouteTrait { /** * Creates one or many routes. * * @param string|array $path the path, or the localized paths of the route */ final protected function createLocalizedRoute(RouteCollection $collection, string $name, $path, string $namePrefix = '', array $prefixes = null): RouteCollection { $paths = []; $routes = new RouteCollection(); if (\is_array($path)) { if (null === $prefixes) { $paths = $path; } elseif ($missing = array_diff_key($prefixes, $path)) { throw new \LogicException(sprintf('Route "%s" is missing routes for locale(s) "%s".', $name, implode('", "', array_keys($missing)))); } else { foreach ($path as $locale => $localePath) { if (!isset($prefixes[$locale])) { throw new \LogicException(sprintf('Route "%s" with locale "%s" is missing a corresponding prefix in its parent collection.', $name, $locale)); } $paths[$locale] = $prefixes[$locale].$localePath; } } } elseif (null !== $prefixes) { foreach ($prefixes as $locale => $prefix) { $paths[$locale] = $prefix.$path; } } else { $routes->add($namePrefix.$name, $route = $this->createRoute($path)); $collection->add($namePrefix.$name, $route); return $routes; } foreach ($paths as $locale => $path) { $routes->add($name.'.'.$locale, $route = $this->createRoute($path)); $collection->add($namePrefix.$name.'.'.$locale, $route); $route->setDefault('_locale', $locale); $route->setRequirement('_locale', preg_quote($locale)); $route->setDefault('_canonical_route', $namePrefix.$name); } return $routes; } private function createRoute(string $path): Route { return new Route($path); } } Traits/HostTrait.php000064400000003177150536261440010462 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Symfony\Component\Routing\Loader\Configurator\Traits; use Symfony\Component\Routing\RouteCollection; /** * @internal */ trait HostTrait { final protected function addHost(RouteCollection $routes, $hosts) { if (!$hosts || !\is_array($hosts)) { $routes->setHost($hosts ?: ''); return; } foreach ($routes->all() as $name => $route) { if (null === $locale = $route->getDefault('_locale')) { $routes->remove($name); foreach ($hosts as $locale => $host) { $localizedRoute = clone $route; $localizedRoute->setDefault('_locale', $locale); $localizedRoute->setRequirement('_locale', preg_quote($locale)); $localizedRoute->setDefault('_canonical_route', $name); $localizedRoute->setHost($host); $routes->add($name.'.'.$locale, $localizedRoute); } } elseif (!isset($hosts[$locale])) { throw new \InvalidArgumentException(sprintf('Route "%s" with locale "%s" is missing a corresponding host in its parent collection.', $name, $locale)); } else { $route->setHost($hosts[$locale]); $route->setRequirement('_locale', preg_quote($locale)); $routes->add($name, $route); } } } } Traits/PrefixTrait.php000064400000004536150536261440011002 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Symfony\Component\Routing\Loader\Configurator\Traits; use Symfony\Component\Routing\Route; use Symfony\Component\Routing\RouteCollection; /** * @internal * * @author Nicolas Grekas */ trait PrefixTrait { final protected function addPrefix(RouteCollection $routes, $prefix, bool $trailingSlashOnRoot) { if (\is_array($prefix)) { foreach ($prefix as $locale => $localePrefix) { $prefix[$locale] = trim(trim($localePrefix), '/'); } foreach ($routes->all() as $name => $route) { if (null === $locale = $route->getDefault('_locale')) { $routes->remove($name); foreach ($prefix as $locale => $localePrefix) { $localizedRoute = clone $route; $localizedRoute->setDefault('_locale', $locale); $localizedRoute->setRequirement('_locale', preg_quote($locale)); $localizedRoute->setDefault('_canonical_route', $name); $localizedRoute->setPath($localePrefix.(!$trailingSlashOnRoot && '/' === $route->getPath() ? '' : $route->getPath())); $routes->add($name.'.'.$locale, $localizedRoute); } } elseif (!isset($prefix[$locale])) { throw new \InvalidArgumentException(sprintf('Route "%s" with locale "%s" is missing a corresponding prefix in its parent collection.', $name, $locale)); } else { $route->setPath($prefix[$locale].(!$trailingSlashOnRoot && '/' === $route->getPath() ? '' : $route->getPath())); $routes->add($name, $route); } } return; } $routes->addPrefix($prefix); if (!$trailingSlashOnRoot) { $rootPath = (new Route(trim(trim($prefix), '/').'/'))->getPath(); foreach ($routes->all() as $route) { if ($route->getPath() === $rootPath) { $route->setPath(rtrim($rootPath, '/')); } } } } } RoutingConfigurator.php000064400000004242150536261440011277 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Symfony\Component\Routing\Loader\Configurator; use Symfony\Component\Routing\Loader\PhpFileLoader; use Symfony\Component\Routing\RouteCollection; /** * @author Nicolas Grekas */ class RoutingConfigurator { use Traits\AddTrait; private $loader; private $path; private $file; private $env; public function __construct(RouteCollection $collection, PhpFileLoader $loader, string $path, string $file, string $env = null) { $this->collection = $collection; $this->loader = $loader; $this->path = $path; $this->file = $file; $this->env = $env; } /** * @param string|string[]|null $exclude Glob patterns to exclude from the import */ final public function import($resource, string $type = null, bool $ignoreErrors = false, $exclude = null): ImportConfigurator { $this->loader->setCurrentDir(\dirname($this->path)); $imported = $this->loader->import($resource, $type, $ignoreErrors, $this->file, $exclude) ?: []; if (!\is_array($imported)) { return new ImportConfigurator($this->collection, $imported); } $mergedCollection = new RouteCollection(); foreach ($imported as $subCollection) { $mergedCollection->addCollection($subCollection); } return new ImportConfigurator($this->collection, $mergedCollection); } final public function collection(string $name = ''): CollectionConfigurator { return new CollectionConfigurator($this->collection, $name); } /** * Get the current environment to be able to write conditional configuration. */ final public function env(): ?string { return $this->env; } /** * @return static */ final public function withPath(string $path): self { $clone = clone $this; $clone->path = $clone->file = $path; return $clone; } } AliasConfigurator.php000064400000002270150536261440010700 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Symfony\Component\Routing\Loader\Configurator; use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; use Symfony\Component\Routing\Alias; class AliasConfigurator { private $alias; public function __construct(Alias $alias) { $this->alias = $alias; } /** * Whether this alias is deprecated, that means it should not be called anymore. * * @param string $package The name of the composer package that is triggering the deprecation * @param string $version The version of the package that introduced the deprecation * @param string $message The deprecation message to use * * @return $this * * @throws InvalidArgumentException when the message template is invalid */ public function deprecate(string $package, string $version, string $message): self { $this->alias->setDeprecated($package, $version, $message); return $this; } } CollectionConfigurator.php000064400000006744150536261440011754 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Symfony\Component\Routing\Loader\Configurator; use Symfony\Component\Routing\Route; use Symfony\Component\Routing\RouteCollection; /** * @author Nicolas Grekas */ class CollectionConfigurator { use Traits\AddTrait; use Traits\HostTrait; use Traits\RouteTrait; private $parent; private $parentConfigurator; private $parentPrefixes; private $host; public function __construct(RouteCollection $parent, string $name, self $parentConfigurator = null, array $parentPrefixes = null) { $this->parent = $parent; $this->name = $name; $this->collection = new RouteCollection(); $this->route = new Route(''); $this->parentConfigurator = $parentConfigurator; // for GC control $this->parentPrefixes = $parentPrefixes; } /** * @return array */ public function __sleep() { throw new \BadMethodCallException('Cannot serialize '.__CLASS__); } public function __wakeup() { throw new \BadMethodCallException('Cannot unserialize '.__CLASS__); } public function __destruct() { if (null === $this->prefixes) { $this->collection->addPrefix($this->route->getPath()); } if (null !== $this->host) { $this->addHost($this->collection, $this->host); } $this->parent->addCollection($this->collection); } /** * Creates a sub-collection. */ final public function collection(string $name = ''): self { return new self($this->collection, $this->name.$name, $this, $this->prefixes); } /** * Sets the prefix to add to the path of all child routes. * * @param string|array $prefix the prefix, or the localized prefixes * * @return $this */ final public function prefix($prefix): self { if (\is_array($prefix)) { if (null === $this->parentPrefixes) { // no-op } elseif ($missing = array_diff_key($this->parentPrefixes, $prefix)) { throw new \LogicException(sprintf('Collection "%s" is missing prefixes for locale(s) "%s".', $this->name, implode('", "', array_keys($missing)))); } else { foreach ($prefix as $locale => $localePrefix) { if (!isset($this->parentPrefixes[$locale])) { throw new \LogicException(sprintf('Collection "%s" with locale "%s" is missing a corresponding prefix in its parent collection.', $this->name, $locale)); } $prefix[$locale] = $this->parentPrefixes[$locale].$localePrefix; } } $this->prefixes = $prefix; $this->route->setPath('/'); } else { $this->prefixes = null; $this->route->setPath($prefix); } return $this; } /** * Sets the host to use for all child routes. * * @param string|array $host the host, or the localized hosts * * @return $this */ final public function host($host): self { $this->host = $host; return $this; } private function createRoute(string $path): Route { return (clone $this->route)->setPath($path); } }