From 4f5b44bd3bd490309eb2ba7b44df4769816ba729 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20L=C5=93uillet?= Date: Sat, 3 Aug 2013 19:26:54 +0200 Subject: twig implementation --- .../Component/Routing/Matcher/UrlMatcher.php | 208 +++++++++++++++++++++ 1 file changed, 208 insertions(+) create mode 100644 vendor/symfony/routing/Symfony/Component/Routing/Matcher/UrlMatcher.php (limited to 'vendor/symfony/routing/Symfony/Component/Routing/Matcher/UrlMatcher.php') diff --git a/vendor/symfony/routing/Symfony/Component/Routing/Matcher/UrlMatcher.php b/vendor/symfony/routing/Symfony/Component/Routing/Matcher/UrlMatcher.php new file mode 100644 index 00000000..db18ec4e --- /dev/null +++ b/vendor/symfony/routing/Symfony/Component/Routing/Matcher/UrlMatcher.php @@ -0,0 +1,208 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Matcher; + +use Symfony\Component\Routing\Exception\MethodNotAllowedException; +use Symfony\Component\Routing\Exception\ResourceNotFoundException; +use Symfony\Component\Routing\RouteCollection; +use Symfony\Component\Routing\RequestContext; +use Symfony\Component\Routing\Route; + +/** + * UrlMatcher matches URL based on a set of routes. + * + * @author Fabien Potencier + * + * @api + */ +class UrlMatcher implements UrlMatcherInterface +{ + const REQUIREMENT_MATCH = 0; + const REQUIREMENT_MISMATCH = 1; + const ROUTE_MATCH = 2; + + /** + * @var RequestContext + */ + protected $context; + + /** + * @var array + */ + protected $allow = array(); + + /** + * @var RouteCollection + */ + protected $routes; + + /** + * Constructor. + * + * @param RouteCollection $routes A RouteCollection instance + * @param RequestContext $context The context + * + * @api + */ + public function __construct(RouteCollection $routes, RequestContext $context) + { + $this->routes = $routes; + $this->context = $context; + } + + /** + * {@inheritdoc} + */ + public function setContext(RequestContext $context) + { + $this->context = $context; + } + + /** + * {@inheritdoc} + */ + public function getContext() + { + return $this->context; + } + + /** + * {@inheritdoc} + */ + public function match($pathinfo) + { + $this->allow = array(); + + if ($ret = $this->matchCollection(rawurldecode($pathinfo), $this->routes)) { + return $ret; + } + + throw 0 < count($this->allow) + ? new MethodNotAllowedException(array_unique(array_map('strtoupper', $this->allow))) + : new ResourceNotFoundException(); + } + + /** + * Tries to match a URL with a set of routes. + * + * @param string $pathinfo The path info to be parsed + * @param RouteCollection $routes The set of routes + * + * @return array An array of parameters + * + * @throws ResourceNotFoundException If the resource could not be found + * @throws MethodNotAllowedException If the resource was found but the request method is not allowed + */ + protected function matchCollection($pathinfo, RouteCollection $routes) + { + foreach ($routes as $name => $route) { + $compiledRoute = $route->compile(); + + // check the static prefix of the URL first. Only use the more expensive preg_match when it matches + if ('' !== $compiledRoute->getStaticPrefix() && 0 !== strpos($pathinfo, $compiledRoute->getStaticPrefix())) { + continue; + } + + if (!preg_match($compiledRoute->getRegex(), $pathinfo, $matches)) { + continue; + } + + $hostMatches = array(); + if ($compiledRoute->getHostRegex() && !preg_match($compiledRoute->getHostRegex(), $this->context->getHost(), $hostMatches)) { + continue; + } + + // check HTTP method requirement + if ($req = $route->getRequirement('_method')) { + // HEAD and GET are equivalent as per RFC + if ('HEAD' === $method = $this->context->getMethod()) { + $method = 'GET'; + } + + if (!in_array($method, $req = explode('|', strtoupper($req)))) { + $this->allow = array_merge($this->allow, $req); + + continue; + } + } + + $status = $this->handleRouteRequirements($pathinfo, $name, $route); + + if (self::ROUTE_MATCH === $status[0]) { + return $status[1]; + } + + if (self::REQUIREMENT_MISMATCH === $status[0]) { + continue; + } + + return $this->getAttributes($route, $name, array_replace($matches, $hostMatches)); + } + } + + /** + * Returns an array of values to use as request attributes. + * + * As this method requires the Route object, it is not available + * in matchers that do not have access to the matched Route instance + * (like the PHP and Apache matcher dumpers). + * + * @param Route $route The route we are matching against + * @param string $name The name of the route + * @param array $attributes An array of attributes from the matcher + * + * @return array An array of parameters + */ + protected function getAttributes(Route $route, $name, array $attributes) + { + $attributes['_route'] = $name; + + return $this->mergeDefaults($attributes, $route->getDefaults()); + } + + /** + * Handles specific route requirements. + * + * @param string $pathinfo The path + * @param string $name The route name + * @param Route $route The route + * + * @return array The first element represents the status, the second contains additional information + */ + protected function handleRouteRequirements($pathinfo, $name, Route $route) + { + // check HTTP scheme requirement + $scheme = $route->getRequirement('_scheme'); + $status = $scheme && $scheme !== $this->context->getScheme() ? self::REQUIREMENT_MISMATCH : self::REQUIREMENT_MATCH; + + return array($status, null); + } + + /** + * Get merged default parameters. + * + * @param array $params The parameters + * @param array $defaults The defaults + * + * @return array Merged default parameters + */ + protected function mergeDefaults($params, $defaults) + { + foreach ($params as $key => $value) { + if (!is_int($key)) { + $defaults[$key] = $value; + } + } + + return $defaults; + } +} -- cgit v1.2.3