Example #1
0
 /**
  * {@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");
 }
Example #3
0
 /**
  * {@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);
 }
Example #5
0
    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;
     }
 }
Example #7
0
 /**
  * @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);
 }
Example #9
0
 /**
  * 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;
 }
Example #11
0
 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();
 }
Example #12
0
 /**
  * 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];
 }
Example #13
0
 /**
  * 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;
 }
Example #15
0
 /**
  * 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;
 }
Example #16
0
 /**
  * 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;
 }
Example #20
0
 /**
  * {@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();
 }
Example #21
0
 /**
  * @dataProvider getNumericVariableNames
  * @expectedException \DomainException
  */
 public function testRouteWithNumericVariableName($name)
 {
     $route = new Route('/{' . $name . '}');
     $route->compile();
 }
Example #22
0
    /**
     * 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;
    }
Example #23
0
 /**
  * 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);
 }
Example #24
0
 /**
  * @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']);
             }
         }
     }
 }
Example #26
0
 /**
  * @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();
 }
Example #29
0
 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');
 }
Example #30
0
 /**
  * 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);
 }