/** * {@inheritdoc} */ protected function handleRouteRequirements($pathinfo, $name, Route $route) { // expression condition if ($route->getCondition() && !$this->getExpressionLanguage()->evaluate($route->getCondition(), array('context' => $this->context, 'request' => $this->request))) { return array(self::REQUIREMENT_MISMATCH, null); } // check HTTP scheme requirement $scheme = $route->getRequirement('_scheme'); if ($scheme && $this->context->getScheme() !== $scheme) { return array(self::ROUTE_MATCH, $this->redirect($pathinfo, $name, $scheme)); } return array(self::REQUIREMENT_MATCH, null); }
protected function handleRouteRequirements($pathinfo, $name, Route $route) { if ($route->getCondition() && !$this->getExpressionLanguage()->evaluate($route->getCondition(), array('context' => $this->context, 'request' => $this->request))) { return array(self::REQUIREMENT_MISMATCH, null); } $scheme = $this->context->getScheme(); $schemes = $route->getSchemes(); if ($schemes && !$route->hasScheme($scheme)) { return array(self::ROUTE_MATCH, $this->redirect($pathinfo, $name, current($schemes))); } return array(self::REQUIREMENT_MATCH, null); }
public function testCondition() { $route = new Route('/'); $this->assertEquals(null, $route->getCondition()); $route->setCondition('context.getMethod() == "GET"'); $this->assertEquals('context.getMethod() == "GET"', $route->getCondition()); }
/** * 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) { // expression condition if ($route->getCondition() && !$this->getExpressionLanguage()->evaluate($route->getCondition(), array('context' => $this->context, 'request' => $this->request))) { return array(self::REQUIREMENT_MISMATCH, null); } // check HTTP scheme requirement $scheme = $this->context->getScheme(); $status = $route->getSchemes() && !$route->hasScheme($scheme) ? self::REQUIREMENT_MISMATCH : self::REQUIREMENT_MATCH; return array($status, null); }
/** * Compiles a single Route to PHP code used to match it against the path info. * * @param Route $route A Route instance * @param string $name The name of the Route * @param bool $supportsRedirections Whether redirections are supported by the base class * @param string|null $parentPrefix The prefix of the parent collection used to optimize the code * * @return string PHP code * * @throws \LogicException */ private function compileRoute(Route $route, $name, $supportsRedirections, $parentPrefix = null) { $code = ''; $compiledRoute = $route->compile(); $conditions = array(); $hasTrailingSlash = false; $matches = false; $hostMatches = false; $methods = $route->getMethods(); // GET and HEAD are equivalent if (in_array('GET', $methods) && !in_array('HEAD', $methods)) { $methods[] = 'HEAD'; } $supportsTrailingSlash = $supportsRedirections && (!$methods || in_array('HEAD', $methods)); if (!count($compiledRoute->getPathVariables()) && false !== preg_match('#^(.)\\^(?P<url>.*?)\\$\\1#', $compiledRoute->getRegex(), $m)) { if ($supportsTrailingSlash && substr($m['url'], -1) === '/') { $conditions[] = sprintf("rtrim(\$pathinfo, '/') === %s", var_export(rtrim(str_replace('\\', '', $m['url']), '/'), true)); $hasTrailingSlash = true; } else { $conditions[] = sprintf("\$pathinfo === %s", var_export(str_replace('\\', '', $m['url']), true)); } } else { if ($compiledRoute->getStaticPrefix() && $compiledRoute->getStaticPrefix() !== $parentPrefix) { $conditions[] = sprintf("0 === strpos(\$pathinfo, %s)", var_export($compiledRoute->getStaticPrefix(), true)); } $regex = $compiledRoute->getRegex(); if ($supportsTrailingSlash && ($pos = strpos($regex, '/$'))) { $regex = substr($regex, 0, $pos) . '/?$' . substr($regex, $pos + 2); $hasTrailingSlash = true; } $conditions[] = sprintf("preg_match(%s, \$pathinfo, \$matches)", var_export($regex, true)); $matches = true; } if ($compiledRoute->getHostVariables()) { $hostMatches = true; } if ($route->getCondition()) { $conditions[] = $this->getExpressionLanguage()->compile($route->getCondition(), array('context', 'request')); } $conditions = implode(' && ', $conditions); $code .= <<<EOF // {$name} if ({$conditions}) { EOF; $gotoname = 'not_' . preg_replace('/[^A-Za-z0-9_]/', '', $name); if ($methods) { if (1 === count($methods)) { $code .= <<<EOF if (\$this->context->getMethod() != '{$methods['0']}') { \$allow[] = '{$methods['0']}'; goto {$gotoname}; } EOF; } else { $methods = implode("', '", $methods); $code .= <<<EOF if (!in_array(\$this->context->getMethod(), array('{$methods}'))) { \$allow = array_merge(\$allow, array('{$methods}')); goto {$gotoname}; } EOF; } } if ($hasTrailingSlash) { $code .= <<<EOF if (substr(\$pathinfo, -1) !== '/') { return \$this->redirect(\$pathinfo.'/', '{$name}'); } EOF; } if ($schemes = $route->getSchemes()) { if (!$supportsRedirections) { throw new \LogicException('The "schemes" requirement is only supported for URL matchers that implement RedirectableUrlMatcherInterface.'); } $schemes = str_replace("\n", '', var_export(array_flip($schemes), true)); $code .= <<<EOF \$requiredSchemes = {$schemes}; if (!isset(\$requiredSchemes[\$this->context->getScheme()])) { return \$this->redirect(\$pathinfo, '{$name}', key(\$requiredSchemes)); } EOF; } // optimize parameters array if ($matches || $hostMatches) { $vars = array(); if ($hostMatches) { $vars[] = '$hostMatches'; } if ($matches) { $vars[] = '$matches'; } $vars[] = "array('_route' => '{$name}')"; $code .= sprintf(" return \$this->mergeDefaults(array_replace(%s), %s);\n", implode(', ', $vars), str_replace("\n", '', var_export($route->getDefaults(), true))); } elseif ($route->getDefaults()) { $code .= sprintf(" return %s;\n", str_replace("\n", '', var_export(array_replace($route->getDefaults(), array('_route' => $name)), true))); } else { $code .= sprintf(" return array('_route' => '%s');\n", $name); } $code .= " }\n"; if ($methods) { $code .= " {$gotoname}:\n"; } return $code; }