/** * {@inheritdoc} */ protected function describeRoute(Route $route, array $options = array()) { $tableHeaders = array('Property', 'Value'); $tableRows = array(array('Route Name', $options['name']), array('Path', $route->getPath()), array('Path Regex', $route->compile()->getRegex()), array('Host', '' !== $route->getHost() ? $route->getHost() : 'ANY'), array('Host Regex', '' !== $route->getHost() ? $route->compile()->getHostRegex() : ''), array('Scheme', $route->getSchemes() ? implode('|', $route->getSchemes()) : 'ANY'), array('Method', $route->getMethods() ? implode('|', $route->getMethods()) : 'ANY'), array('Requirements', $route->getRequirements() ? $this->formatRouterConfig($route->getRequirements()) : 'NO CUSTOM'), array('Class', get_class($route)), array('Defaults', $this->formatRouterConfig($route->getDefaults())), array('Options', $this->formatRouterConfig($route->getOptions()))); $table = new Table($this->getOutput()); $table->setHeaders($tableHeaders)->setRows($tableRows); $table->render(); }
/** * {@inheritdoc} */ protected function describeRoute(Route $route, array $options = array()) { $requirements = $route->getRequirements(); unset($requirements['_scheme'], $requirements['_method']); $output = '- Path: ' . $route->getPath() . "\n" . '- Path Regex: ' . $route->compile()->getRegex() . "\n" . '- Host: ' . ('' !== $route->getHost() ? $route->getHost() : 'ANY') . "\n" . '- Host Regex: ' . ('' !== $route->getHost() ? $route->compile()->getHostRegex() : '') . "\n" . '- Scheme: ' . ($route->getSchemes() ? implode('|', $route->getSchemes()) : 'ANY') . "\n" . '- Method: ' . ($route->getMethods() ? implode('|', $route->getMethods()) : 'ANY') . "\n" . '- Class: ' . get_class($route) . "\n" . '- Defaults: ' . $this->formatRouterConfig($route->getDefaults()) . "\n" . '- Requirements: ' . ($requirements ? $this->formatRouterConfig($requirements) : 'NO CUSTOM') . "\n" . '- Options: ' . $this->formatRouterConfig($route->getOptions()); $this->write(isset($options['name']) ? $options['name'] . "\n" . str_repeat('-', strlen($options['name'])) . "\n\n" . $output : $output); $this->write("\n"); }
/** * {@inheritdoc} */ protected function describeRoute(Route $route, array $options = array()) { // fixme: values were originally written as raw $description = array('<comment>Path</comment> ' . $route->getPath(), '<comment>Path Regex</comment> ' . $route->compile()->getRegex(), '<comment>Host</comment> ' . ('' !== $route->getHost() ? $route->getHost() : 'ANY'), '<comment>Host Regex</comment> ' . ('' !== $route->getHost() ? $route->compile()->getHostRegex() : ''), '<comment>Scheme</comment> ' . ($route->getSchemes() ? implode('|', $route->getSchemes()) : 'ANY'), '<comment>Method</comment> ' . ($route->getMethods() ? implode('|', $route->getMethods()) : 'ANY'), '<comment>Class</comment> ' . get_class($route), '<comment>Defaults</comment> ' . $this->formatRouterConfig($route->getDefaults()), '<comment>Requirements</comment> ' . ($route->getRequirements() ? $this->formatRouterConfig($route->getRequirements()) : 'NO CUSTOM'), '<comment>Options</comment> ' . $this->formatRouterConfig($route->getOptions())); if (isset($options['name'])) { array_unshift($description, '<comment>Name</comment> ' . $options['name']); array_unshift($description, $this->formatSection('router', sprintf('Route "%s"', $options['name']))); } $this->writeText(implode("\n", $description) . "\n", $options); }
public function createFromRoute(Route $route) { $compiledRoute = $route->compile(); $defaults = array_intersect_key($route->getDefaults(), array_fill_keys($compiledRoute->getVariables(), null)); $tokens = $compiledRoute->getTokens(); return new ExtractedRoute($tokens, $defaults); }
protected function matchCollection($pathinfo, RouteCollection $routes) { foreach ($routes as $name => $route) { $compiledRoute = $route->compile(); if (!preg_match($compiledRoute->getRegex(), $pathinfo, $matches)) { // does it match without any requirements? $r = new Route($route->getPath(), $route->getDefaults(), array(), $route->getOptions()); $cr = $r->compile(); if (!preg_match($cr->getRegex(), $pathinfo)) { $this->addTrace(sprintf('Path "%s" does not match', $route->getPath()), self::ROUTE_DOES_NOT_MATCH, $name, $route); continue; } foreach ($route->getRequirements() as $n => $regex) { $r = new Route($route->getPath(), $route->getDefaults(), array($n => $regex), $route->getOptions()); $cr = $r->compile(); if (in_array($n, $cr->getVariables()) && !preg_match($cr->getRegex(), $pathinfo)) { $this->addTrace(sprintf('Requirement for "%s" does not match (%s)', $n, $regex), self::ROUTE_ALMOST_MATCHES, $name, $route); continue 2; } } 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); $this->addTrace(sprintf('Method "%s" does not match the requirement ("%s")', $this->context->getMethod(), implode(', ', $req)), self::ROUTE_ALMOST_MATCHES, $name, $route); continue; } } // check HTTP scheme requirement if ($scheme = $route->getRequirement('_scheme')) { if ($this->context->getScheme() !== $scheme) { $this->addTrace(sprintf('Scheme "%s" does not match the requirement ("%s"); the user will be redirected', $this->context->getScheme(), $scheme), self::ROUTE_ALMOST_MATCHES, $name, $route); return true; } } $this->addTrace('Route matches!', self::ROUTE_MATCHES, $name, $route); return true; } }
protected function matchCollection($pathinfo, RouteCollection $routes) { foreach ($routes as $name => $route) { $compiledRoute = $route->compile(); if (!preg_match($compiledRoute->getRegex(), $pathinfo, $matches)) { // does it match without any requirements? $r = new Route($route->getPath(), $route->getDefaults(), array(), $route->getOptions()); $cr = $r->compile(); if (!preg_match($cr->getRegex(), $pathinfo)) { $this->addTrace(sprintf('Path "%s" does not match', $route->getPath()), self::ROUTE_DOES_NOT_MATCH, $name, $route); continue; } foreach ($route->getRequirements() as $n => $regex) { $r = new Route($route->getPath(), $route->getDefaults(), array($n => $regex), $route->getOptions()); $cr = $r->compile(); if (in_array($n, $cr->getVariables()) && !preg_match($cr->getRegex(), $pathinfo)) { $this->addTrace(sprintf('Requirement for "%s" does not match (%s)', $n, $regex), self::ROUTE_ALMOST_MATCHES, $name, $route); continue 2; } } continue; } // check host requirement $hostMatches = array(); if ($compiledRoute->getHostRegex() && !preg_match($compiledRoute->getHostRegex(), $this->context->getHost(), $hostMatches)) { $this->addTrace(sprintf('Host "%s" does not match the requirement ("%s")', $this->context->getHost(), $route->getHost()), self::ROUTE_ALMOST_MATCHES, $name, $route); 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); $this->addTrace(sprintf('Method "%s" does not match the requirement ("%s")', $this->context->getMethod(), implode(', ', $req)), self::ROUTE_ALMOST_MATCHES, $name, $route); continue; } } // check condition if ($condition = $route->getCondition()) { if (!$this->getExpressionLanguage()->evaluate($condition, array('context' => $this->context, 'request' => $this->request))) { $this->addTrace(sprintf('Condition "%s" does not evaluate to "true"', $condition), self::ROUTE_ALMOST_MATCHES, $name, $route); continue; } } // check HTTP scheme requirement if ($requiredSchemes = $route->getSchemes()) { $scheme = $this->context->getScheme(); if (!$route->hasScheme($scheme)) { $this->addTrace(sprintf('Scheme "%s" does not match any of the required schemes ("%s"); the user will be redirected to first required scheme', $scheme, implode(', ', $requiredSchemes)), self::ROUTE_ALMOST_MATCHES, $name, $route); return true; } } $this->addTrace('Route matches!', self::ROUTE_MATCHES, $name, $route); return true; } }
/** * @param Route $route * @return Generator */ private function getParameters(Route $route) : Generator { /** @var CompiledRoute $compiled */ $compiled = $route->compile(); foreach ($compiled->getVariables() as $name) { (yield ['name' => $name, 'type' => 'string', 'required' => true, 'in' => 'path']); } }
public function handle(ApiDoc $annotation, array $annotations, Route $route, \ReflectionMethod $method) { // description if (null === $annotation->getDescription()) { $comments = explode("\n", $annotation->getDocumentation()); // just set the first line $comment = trim($comments[0]); $comment = preg_replace("#\n+#", ' ', $comment); $comment = preg_replace('#\\s+#', ' ', $comment); $comment = preg_replace('#[_`*]+#', '', $comment); if ('@' !== substr($comment, 0, 1)) { $annotation->setDescription($comment); } } // requirements $requirements = $annotation->getRequirements(); foreach ($route->getRequirements() as $name => $value) { if (!isset($requirements[$name]) && '_method' !== $name) { $requirements[$name] = array('requirement' => $value, 'dataType' => '', 'description' => ''); } if ('_scheme' == $name) { $https = 'https' == $value; $annotation->setHttps($https); } } $paramDocs = array(); foreach (explode("\n", $this->commentExtractor->getDocComment($method)) as $line) { if (preg_match('{^@param (.+)}', trim($line), $matches)) { $paramDocs[] = $matches[1]; } if (preg_match('{^@deprecated\\b(.*)}', trim($line), $matches)) { $annotation->setDeprecated(true); } if (preg_match('{^@link\\b(.*)}', trim($line), $matches)) { $annotation->setLink($matches[1]); } } $regexp = '{(\\w*) *\\$%s\\b *(.*)}i'; foreach ($route->compile()->getVariables() as $var) { $found = false; foreach ($paramDocs as $paramDoc) { if (preg_match(sprintf($regexp, preg_quote($var)), $paramDoc, $matches)) { $requirements[$var]['dataType'] = isset($matches[1]) ? $matches[1] : ''; $requirements[$var]['description'] = $matches[2]; if (!isset($requirements[$var]['requirement'])) { $requirements[$var]['requirement'] = ''; } $found = true; break; } } if (!isset($requirements[$var]) && false === $found) { $requirements[$var] = array('requirement' => '', 'dataType' => '', 'description' => ''); } } $annotation->setRequirements($requirements); }
/** * Confirms that a compiled route with default values has the correct outline. */ public function testCompilationDefaultValue() { // Because "here" has a default value, it should not factor into the outline // or the fitness. $route = new Route('/test/{something}/more/{here}', array('here' => 'there')); $route->setOption('compiler_class', 'Drupal\\Core\\Routing\\RouteCompiler'); $compiled = $route->compile(); $this->assertEquals($compiled->getFit(), 5, 'The fit was not correct.'); $this->assertEquals($compiled->getPatternOutline(), '/test/%/more', 'The pattern outline was not correct.'); }
/** * {@inheritdoc} */ public function applies($definition, $name, Route $route) { if (!empty($definition['type']) && strpos($definition['type'], 'entity_revision:') === 0) { $entity_type_id = substr($definition['type'], strlen('entity:')); if (strpos($definition['type'], '{') !== FALSE) { $entity_type_slug = substr($entity_type_id, 1, -1); return $name != $entity_type_slug && in_array($entity_type_slug, $route->compile()->getVariables(), TRUE); } return $this->entityManager->hasDefinition($entity_type_id); } return FALSE; }
public function compile() { $defaults = $this->getDefaults(); if (array_key_exists('_formats', $defaults)) { $path = $this->getPath(); // add format to the path $this->setPath($path . ".{_format}"); // add a requirement $this->addRequirements(['_format' => implode('|', $defaults['_formats'])]); } return parent::compile(); }
/** * get collection and id from route * * @param Route $route route to look at * @param string $value value of reference as URI * * @return array */ private function getDataFromRoute(Route $route, $value) { if ($route->getRequirement('id') !== null && $route->getMethods() === ['GET'] && preg_match($route->compile()->getRegex(), $value, $matches)) { $id = $matches['id']; list($routeService) = explode(':', $route->getDefault('_controller')); list($core, $bundle, , $name) = explode('.', $routeService); $serviceName = implode('.', [$core, $bundle, 'rest', $name]); $collection = array_search($serviceName, $this->mapping); return [$collection, $id]; } return [null, null]; }
/** * Dumps a single route * * @param string $name Route name * @param Route $route The route * @param array $options Options * @param bool $hostRegexUnique Unique identifier for the host regex * * @return string The compiled route */ private function dumpRoute($name, $route, array $options, $hostRegexUnique) { $compiledRoute = $route->compile(); // prepare the apache regex $regex = $this->regexToApacheRegex($compiledRoute->getRegex()); $regex = '^' . self::escape(preg_quote($options['base_uri']) . substr($regex, 1), ' ', '\\'); $methods = $this->getRouteMethods($route); $hasTrailingSlash = (!$methods || in_array('HEAD', $methods)) && '/$' === substr($regex, -2) && '^/$' !== $regex; $variables = array('E=_ROUTING_route:' . $name); foreach ($compiledRoute->getHostVariables() as $variable) { $variables[] = sprintf('E=_ROUTING_param_%s:%%{ENV:__ROUTING_host_%s_%s}', $variable, $hostRegexUnique, $variable); } foreach ($compiledRoute->getPathVariables() as $i => $variable) { $variables[] = 'E=_ROUTING_param_' . $variable . ':%' . ($i + 1); } foreach ($this->normalizeValues($route->getDefaults()) as $key => $value) { $variables[] = 'E=_ROUTING_default_' . $key . ':' . strtr($value, array(':' => '\\:', '=' => '\\=', '\\' => '\\\\', ' ' => '\\ ')); } $variables = implode(',', $variables); $rule = array("# {$name}"); // method mismatch if (0 < count($methods)) { $allow = array(); foreach ($methods as $method) { $allow[] = 'E=_ROUTING_allow_' . $method . ':1'; } if ($compiledRoute->getHostRegex()) { $rule[] = sprintf("RewriteCond %%{ENV:__ROUTING_host_%s} =1", $hostRegexUnique); } $rule[] = "RewriteCond %{REQUEST_URI} {$regex}"; $rule[] = sprintf("RewriteCond %%{REQUEST_METHOD} !^(%s)\$ [NC]", implode('|', $methods)); $rule[] = sprintf('RewriteRule .* - [S=%d,%s]', $hasTrailingSlash ? 2 : 1, implode(',', $allow)); } // redirect with trailing slash appended if ($hasTrailingSlash) { if ($compiledRoute->getHostRegex()) { $rule[] = sprintf("RewriteCond %%{ENV:__ROUTING_host_%s} =1", $hostRegexUnique); } $rule[] = 'RewriteCond %{REQUEST_URI} ' . substr($regex, 0, -2) . '$'; $rule[] = 'RewriteRule .* $0/ [QSA,L,R=301]'; } // the main rule if ($compiledRoute->getHostRegex()) { $rule[] = sprintf("RewriteCond %%{ENV:__ROUTING_host_%s} =1", $hostRegexUnique); } $rule[] = "RewriteCond %{REQUEST_URI} {$regex}"; $rule[] = "RewriteRule .* {$options['script_name']} [QSA,L,{$variables}]"; return implode("\n", $rule); }
/** * {@inheritdoc} */ public function applies($definition, $name, Route $route) { if (!empty($definition['type']) && strpos($definition['type'], 'entity:') === 0) { $entity_type_id = substr($definition['type'], strlen('entity:')); if (strpos($definition['type'], '{') !== FALSE) { $entity_type_slug = substr($entity_type_id, 1, -1); return $name != $entity_type_slug && in_array($entity_type_slug, $route->compile()->getVariables(), TRUE); } // This converter only applies rdf entities. $entity_storage = $this->entityManager->getStorage($entity_type_id); if ($entity_storage instanceof RdfEntitySparqlStorage) { return $this->entityManager->hasDefinition($entity_type_id); } } return FALSE; }
/** * Extracts all of the raw attributes from a path for a given route. * * @param \Symfony\Component\Routing\Route $route * The route object. * @param string $name * The route name. * @param string $path * A path. * * @return array * An array of raw attributes for this path and route. */ public static function extractRawAttributes(Route $route, $name, $path) { // See \Symfony\Component\Routing\Matcher\UrlMatcher::matchCollection(). preg_match($route->compile()->getRegex(), $path, $matches); // See \Symfony\Component\Routing\Matcher\UrlMatcher::mergeDefaults(). $attributes = $route->getDefaults(); foreach ($matches as $key => $value) { if (!is_int($key)) { $attributes[$key] = $value; } } // See \Symfony\Cmf\Component\Routing\NestedMatcher\UrlMatcher::getAttributes(). $attributes[RouteObjectInterface::ROUTE_OBJECT] = $route; $attributes[RouteObjectInterface::ROUTE_NAME] = $name; return $attributes; }
/** * Tries to match a URL with an individual route. * * @param $pathinfo * @param $name * @param BaseRoute $route * @return array|null */ protected function matchRoute($pathinfo, $name, BaseRoute $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())) { return null; } if (!preg_match($compiledRoute->getRegex(), $pathinfo, $matches)) { return null; } $hostMatches = array(); if ($compiledRoute->getHostRegex() && !preg_match($compiledRoute->getHostRegex(), $this->context->getHost(), $hostMatches)) { return null; } // 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); return null; } } $status = $this->handleRouteRequirements($pathinfo, $name, $route); if (self::ROUTE_MATCH === $status[0]) { return $status[1]; } if (self::REQUIREMENT_MISMATCH === $status[0]) { return null; } $attrs = $this->getAttributes($route, $name, array_replace($matches, $hostMatches)); if ($route instanceof Route) { foreach ($route->getMatchCallbacks() as $callback) { $ret = call_user_func($callback, $attrs); if ($ret === false) { return null; } if (is_array($ret)) { $attrs = $ret; } } } return $attrs; }
/** * {@inheritdoc} */ public function generate($name, $parameters = array(), $referenceType = self::ABSOLUTE_PATH) { try { if ($name instanceof SeoAwareInterface) { $documentUrl = $name->getUrl(); } else { throw new RouteNotFoundException(); } $type = $this->collector->getDocumentType(get_class($name)); $route = new Route($documentUrl, ['_controller' => $this->routeMap[$type], 'document' => $name, 'type' => $type]); // the Route has a cache of its own and is not recompiled as long as it does not get modified $compiledRoute = $route->compile(); $hostTokens = $compiledRoute->getHostTokens(); return $this->doGenerate($compiledRoute->getVariables(), $route->getDefaults(), $route->getRequirements(), $compiledRoute->getTokens(), $parameters, 'ongr_route', $referenceType, $hostTokens); } catch (\Exception $e) { throw new RouteNotFoundException('Document is not correct or route cannot be generated.'); } }
/** * {@inheritdoc} */ public function generate($name, $parameters = array(), $referenceType = self::ABSOLUTE_PATH) { try { $document = $parameters['document']; if (is_object($document)) { $documentUrl = $document->url; } else { $documentUrl = $document['url']; } $type = $this->collector->getDocumentType(get_class($document)); $route = new Route($documentUrl, ['_controller' => $this->routeMap[$type], 'document' => $document, 'type' => $type]); // the Route has a cache of its own and is not recompiled as long as it does not get modified $compiledRoute = $route->compile(); $hostTokens = $compiledRoute->getHostTokens(); $debug_message = $this->getRouteDebugMessage($name); return $this->doGenerate($compiledRoute->getVariables(), $route->getDefaults(), $route->getRequirements(), $compiledRoute->getTokens(), $parameters, $debug_message, $referenceType, $hostTokens); } catch (\Exception $e) { throw new RouteNotFoundException('Document is not correct or route cannot be generated.'); } }
private function isAccessedAnonymously($routeName, Route $route) { if (!in_array('GET', $route->getMethods()) && $route->getMethods()) { return false; // GET method must be allowed } if (strpos($routeName, '_') === 0) { return false; // internal|private routes } $compiled = $route->compile(); $params = []; foreach ($compiled->getPathVariables() as $key) { $params[$key] = 'any'; // we do not care about it } foreach ($route->getRequirements() as $key => $regex) { $params[$key] = 'any'; // we do not care about it } foreach ($route->getDefaults() as $key => $default) { $params[$key] = $default; } if (!array_key_exists('_controller', $params)) { return false; // route is dynamic, should not be index by robots } $uri = $this->get('router')->generate($routeName, $params); // mock the request $request = Request::create('http://mock.com' . $uri); $request->setSession(new Session(new MockFileSessionStorage())); // run the request through security firewall $event = new GetResponseEvent($this->getApplication()->getKernel(), $request, HttpKernelInterface::MASTER_REQUEST); try { $this->get('security.firewall')->onKernelRequest($event); } catch (AccessDeniedException $e) { return false; // access is denied } return !$event->getResponse() instanceof RedirectResponse; }
/** * {@inheritDoc} * * Overwritten to make sure the route is recompiled if the pattern was changed */ public function compile() { if ($this->needRecompile) { // calling parent::setPath just to let it set compiled=null. the parent $path field is never used parent::setPath($this->getPath()); } return parent::compile(); }
/** * @dataProvider getNumericVariableNames * @expectedException \DomainException */ public function testRouteWithNumericVariableName($name) { $route = new Route('/{' . $name . '}'); $route->compile(); }
/** * 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 = array(); if ($req = $route->getRequirement('_method')) { $methods = explode('|', strtoupper($req)); // 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; } $conditions = implode(' && ', $conditions); $code .= <<<EOF // {$name} if ({$conditions}) { EOF; if ($methods) { $gotoname = 'not_' . preg_replace('/[^A-Za-z0-9_]/', '', $name); 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 ($scheme = $route->getRequirement('_scheme')) { if (!$supportsRedirections) { throw new \LogicException('The "_scheme" requirement is only supported for URL matchers that implement RedirectableUrlMatcherInterface.'); } $code .= <<<EOF if (\$this->context->getScheme() !== '{$scheme}') { return \$this->redirect(\$pathinfo, '{$name}', '{$scheme}'); } 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; }
/** * Tests that the serialized representation of a route in one symfony version * also works in later symfony versions, i.e. the unserialized route is in the * same state as another, semantically equivalent, route. */ public function testSerializedRepresentationKeepsWorking() { $serialized = 'C:31:"Symfony\\Component\\Routing\\Route":934:{a:8:{s:4:"path";s:13:"/prefix/{foo}";s:4:"host";s:20:"{locale}.example.net";s:8:"defaults";a:1:{s:3:"foo";s:7:"default";}s:12:"requirements";a:1:{s:3:"foo";s:3:"\\d+";}s:7:"options";a:1:{s:14:"compiler_class";s:39:"Symfony\\Component\\Routing\\RouteCompiler";}s:7:"schemes";a:0:{}s:7:"methods";a:0:{}s:8:"compiled";C:39:"Symfony\\Component\\Routing\\CompiledRoute":569:{a:8:{s:4:"vars";a:2:{i:0;s:6:"locale";i:1;s:3:"foo";}s:11:"path_prefix";s:7:"/prefix";s:10:"path_regex";s:30:"#^/prefix(?:/(?P<foo>\\d+))?$#s";s:11:"path_tokens";a:2:{i:0;a:4:{i:0;s:8:"variable";i:1;s:1:"/";i:2;s:3:"\\d+";i:3;s:3:"foo";}i:1;a:2:{i:0;s:4:"text";i:1;s:7:"/prefix";}}s:9:"path_vars";a:1:{i:0;s:3:"foo";}s:10:"host_regex";s:39:"#^(?P<locale>[^\\.]++)\\.example\\.net$#si";s:11:"host_tokens";a:2:{i:0;a:2:{i:0;s:4:"text";i:1;s:12:".example.net";}i:1;a:4:{i:0;s:8:"variable";i:1;s:0:"";i:2;s:7:"[^\\.]++";i:3;s:6:"locale";}}s:9:"host_vars";a:1:{i:0;s:6:"locale";}}}}}'; $unserialized = unserialize($serialized); $route = new Route('/prefix/{foo}', array('foo' => 'default'), array('foo' => '\\d+')); $route->setHost('{locale}.example.net'); $route->compile(); $this->assertEquals($route, $unserialized); $this->assertNotSame($route, $unserialized); }
/** * @param Route $route * * @return array */ protected function getRouteData(Route $route) { return array('path' => $route->getPath(), 'pathRegex' => $route->compile()->getRegex(), 'host' => '' !== $route->getHost() ? $route->getHost() : 'ANY', 'hostRegex' => '' !== $route->getHost() ? $route->compile()->getHostRegex() : '', 'scheme' => $route->getSchemes() ? implode('|', $route->getSchemes()) : 'ANY', 'method' => $route->getMethods() ? implode('|', $route->getMethods()) : 'ANY', 'class' => get_class($route), 'defaults' => $route->getDefaults(), 'requirements' => $route->getRequirements() ?: 'NO CUSTOM', 'options' => $route->getOptions()); }
/** * If the _locale parameter is allowed by the requirements of the route * and it is the default locale, remove it from the parameters so that we * do not get an unneeded ?_locale= query string. * * @param SymfonyRoute $route The route being generated. * @param array $parameters The parameters used, will be modified to * remove the _locale field if needed. */ protected function unsetLocaleIfNotNeeded(SymfonyRoute $route, array &$parameters) { $locale = $this->getLocale($parameters); if (null !== $locale) { if (preg_match('/' . $route->getRequirement('_locale') . '/', $locale) && $locale == $route->getDefault('_locale')) { $compiledRoute = $route->compile(); if (!in_array('_locale', $compiledRoute->getVariables())) { unset($parameters['_locale']); } } } }
/** * @expectedException \LogicException */ public function testRouteWithSameVariableTwice() { $route = new Route('/{name}/{name}'); $compiled = $route->compile(); }
/** * Gets the path of a route. * * @param \Symfony\Component\Routing\Route $route * The route object. * @param array $parameters * An array of parameters as passed to * \Symfony\Component\Routing\Generator\UrlGeneratorInterface::generate(). * * @return string * The url path corresponding to the route, without the base path. */ protected function getInternalPathFromRoute(SymfonyRoute $route, $parameters = array()) { // The Route has a cache of its own and is not recompiled as long as it does // not get modified. $compiledRoute = $route->compile(); $hostTokens = $compiledRoute->getHostTokens(); $route_requirements = $route->getRequirements(); // We need to bypass the doGenerate() method's handling of absolute URLs as // we handle that ourselves after processing the path. if (isset($route_requirements['_scheme'])) { unset($route_requirements['_scheme']); } $path = $this->doGenerate($compiledRoute->getVariables(), $route->getDefaults(), $route_requirements, $compiledRoute->getTokens(), $parameters, $route->getPath(), FALSE, $hostTokens); // The URL returned from doGenerate() will include the base path if there is // one (i.e., if running in a subdirectory) so we need to strip that off // before processing the path. $base_url = $this->context->getBaseUrl(); if (!empty($base_url) && strpos($path, $base_url) === 0) { $path = substr($path, strlen($base_url)); } return $path; }
/** * {@inheritDoc} * * Overwritten to make sure the route is recompiled if the pattern was changed */ public function compile() { if ($this->needRecompile) { // calling parent::setPath just to let it set compiled=null. the parent $path field is never used // TODO: drop setPattern when we drop symfony 2.1 support // TODO: for now we need to check the method as setPattern on 2.2. triggers our setPath instead of parent setPath if (method_exists('Symfony\\Component\\Routing\\Route', 'setPath')) { parent::setPath($this->getPath()); } else { parent::setPattern($this->getPath()); } } return parent::compile(); }
public function testCompile() { $route = new Route('/{foo}'); $this->assertInstanceOf('Symfony\\Component\\Routing\\CompiledRoute', $compiled = $route->compile(), '->compile() returns a compiled route'); $this->assertSame($compiled, $route->compile(), '->compile() only compiled the route once if unchanged'); $route->setRequirement('foo', '.*'); $this->assertNotSame($compiled, $route->compile(), '->compile() recompiles if the route was modified'); }
/** * Gets the path of a route. * * @param $name * The route name or other debug message. * @param \Symfony\Component\Routing\Route $route * The route object. * @param array $parameters * An array of parameters as passed to * \Symfony\Component\Routing\Generator\UrlGeneratorInterface::generate(). * @param array $query_params * An array of query string parameter, which will get any extra values from * $parameters merged in. * * @return string * The url path corresponding to the route, without the base path. */ protected function getInternalPathFromRoute($name, SymfonyRoute $route, $parameters = array(), $query_params = array()) { // The Route has a cache of its own and is not recompiled as long as it does // not get modified. $compiledRoute = $route->compile(); return $this->doGenerate($compiledRoute->getVariables(), $route->getDefaults(), $compiledRoute->getTokens(), $parameters, $query_params, $name); }