public function testDefaults() { $route = new Route('/:foo'); $route->setDefaults(array('foo' => 'bar')); $this->assertEquals(array('foo' => 'bar'), $route->getDefaults(), '->setDefaults() sets the defaults'); $this->assertEquals($route, $route->setDefaults(array()), '->setDefaults() implements a fluent interface'); }
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); }
/** * @param string $controller * * @throws InvalidRouteException * @throws UnsupportedRouteFormatException */ private function validateRoute(Route $route) { if (!isset($route->getDefaults()['_controller'])) { throw new InvalidRouteException('_controller property is not set.'); } $controller = $route->getDefaults()['_controller']; if (substr_count($controller, ':') === 2 && strpos($controller, '::') !== false) { // Controller was in the `Bundle:Controller:Action` notation. // It will have been parsed to `Org\Bundle\XBundle\Controller\YController::somethingAction`. list($className, $methodName) = explode('::', $controller, 2); if (!class_exists($className)) { throw new InvalidRouteException(sprintf('Class "%s" does not exist.', $className)); } $this->validatePublicMethodExistsInClass($className, $methodName); } elseif (substr_count($controller, ':') === 2 && strpos($controller, '::') === false) { // Controller is in the `Bundle:Controller:Action` notation. try { $controller = $this->controllerNameParser->parse($controller); } catch (\InvalidArgumentException $e) { // The exception message if the bundle does not exist has changed after Symfony 2.5. // Use our own message for consistency. $isBundleDoesNotExistException = strpos($e->getMessage(), 'does not exist or it is not enabled') !== false || strpos($e->getMessage(), ' does not exist or is not enabled in your kernel') !== false; if ($isBundleDoesNotExistException) { $bundle = substr($controller, 0, strpos($controller, ':')); $message = sprintf('Bundle "%s" (from the _controller value "%s") does not exist, or is it not enabled', $bundle, $controller); throw new InvalidRouteException($message, null, $e); } throw new InvalidRouteException($e->getMessage(), null, $e); } // Controller will now have been parsed to // `Org\Bundle\XBundle\Controller\YController::somethingAction`. list($className, $methodName) = explode('::', $controller, 2); $this->validatePublicMethodExistsInClass($className, $methodName); } elseif (substr_count($controller, ':') === 1) { // Controller is in the `service:method` notation. list($service, $methodName) = explode(':', $controller, 2); try { $serviceInstance = $this->container->get($service); } catch (ServiceNotFoundException $e) { throw new InvalidRouteException($e->getMessage(), null, $e); } $this->validatePublicMethodExistsInClass(get_class($serviceInstance), $methodName); } else { throw new UnsupportedRouteFormatException(sprintf('Route format "%s" is not supported by this tool', $controller)); } }
/** * {@inheritdoc} */ protected function getAttributes(Route $route, $name, array $attributes) { if ($route instanceof RouteObjectInterface && is_string($route->getRouteKey())) { $name = $route->getRouteKey(); } $attributes[RouteObjectInterface::ROUTE_NAME] = $name; $attributes[RouteObjectInterface::ROUTE_OBJECT] = $route; return $this->mergeDefaults($attributes, $route->getDefaults()); }
/** * @covers Symfony\Component\Routing\Route::setDefaults * @covers Symfony\Component\Routing\Route::getDefaults * @covers Symfony\Component\Routing\Route::setDefault * @covers Symfony\Component\Routing\Route::getDefault */ public function testDefaults() { $route = new Route('/{foo}'); $route->setDefaults(array('foo' => 'bar')); $this->assertEquals(array('foo' => 'bar'), $route->getDefaults(), '->setDefaults() sets the defaults'); $this->assertEquals($route, $route->setDefaults(array()), '->setDefaults() implements a fluent interface'); $route->setDefault('foo', 'bar'); $this->assertEquals('bar', $route->getDefault('foo'), '->setDefault() sets a default value'); $route->setDefault('foo2', 'bar2'); $this->assertEquals('bar2', $route->getDefault('foo2'), '->getDefault() return the default value'); $this->assertNull($route->getDefault('not_defined'), '->getDefault() return null if default value is not setted'); }
/** * 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; }
/** * {@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.'); } }
public function testDefaults() { $route = new Route('/{foo}'); $route->setDefaults(array('foo' => 'bar')); $this->assertEquals(array('foo' => 'bar'), $route->getDefaults(), '->setDefaults() sets the defaults'); $this->assertEquals($route, $route->setDefaults(array()), '->setDefaults() implements a fluent interface'); $route->setDefault('foo', 'bar'); $this->assertEquals('bar', $route->getDefault('foo'), '->setDefault() sets a default value'); $route->setDefault('foo2', 'bar2'); $this->assertEquals('bar2', $route->getDefault('foo2'), '->getDefault() return the default value'); $this->assertNull($route->getDefault('not_defined'), '->getDefault() return null if default value is not set'); $route->setDefault('_controller', $closure = function () { return 'Hello'; }); $this->assertEquals($closure, $route->getDefault('_controller'), '->setDefault() sets a default value'); $route->setDefaults(array('foo' => 'foo')); $route->addDefaults(array('bar' => 'bar')); $this->assertEquals($route, $route->addDefaults(array()), '->addDefaults() implements a fluent interface'); $this->assertEquals(array('foo' => 'foo', 'bar' => 'bar'), $route->getDefaults(), '->addDefaults() keep previous defaults'); }
/** * {@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; }
/** * Returns the path of the route, without placeholders with a default value. * * When computing the path outline and fit, we want to skip default-value * placeholders. If we didn't, the path would never match. Note that this * only works for placeholders at the end of the path. Infix placeholders * with default values don't make sense anyway, so that should not be a * problem. * * @param \Symfony\Component\Routing\Route $route * The route to have the placeholders removed from. * * @return string * The path string, stripped of placeholders that have default values. */ public static function getPathWithoutDefaults(Route $route) { $path = $route->getPath(); $defaults = $route->getDefaults(); // Remove placeholders with default values from the outline, so that they // will still match. $remove = array_map(function ($a) { return '/{' . $a . '}'; }, array_keys($defaults)); $path = str_replace($remove, '', $path); return $path; }
/** * 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()); }
/** * 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; }
/** * Set the upcasting route objects. * * @param \Symfony\Component\Routing\Route $route * The route object to add the upcasting information onto. */ public function setRouteOptions(Route $route) { if ($controller = $this->getControllerClass($route->getDefaults())) { // Try to use reflection. if ($this->setParametersFromReflection($controller, $route)) { return; } } // Try to use _entity_* information on the route. $this->setParametersFromEntityInformation($route); }
/** * Tests setRouteOptions() with an _entity_form route for an add form. * * @covers ::setRouteOptions * @covers ::getControllerClass * @covers ::getEntityTypes * @covers ::setParametersFromReflection * @covers ::setParametersFromEntityInformation */ public function testSetRouteOptionsWithEntityAddFormRoute() { $this->setupEntityTypes(); $route = new Route('/example/add', array( '_entity_form' => 'entity_test.add', )); $defaults = $route->getDefaults(); $this->entityResolverManager->setRouteOptions($route); $this->assertEquals($defaults, $route->getDefaults()); $this->assertFalse($route->hasOption('parameters')); }
/** * 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); }
/** * Returns the defaults. * * @return array * The defaults. */ public function getDefaults() { return $this->route->getDefaults(); }
/** * Sets some Zikula-specific defaults for the routes. * * @param Route $route The route instance. * @param AbstractBundle $bundle The bundle. * @param string $bundleName The bundle's name. * @return array The legacy $type and $func parameters. */ private function setZikulaDefaults(Route $route, AbstractBundle $bundle, $bundleName) { $defaults = $route->getDefaults(); $defaults['_zkBundle'] = $bundleName; if ($bundle instanceof AbstractModule) { $defaults['_zkModule'] = $bundleName; } else { if ($bundle instanceof AbstractTheme) { $defaults['_zkTheme'] = $bundleName; } } $controller = $this->sanitizeController($bundleName, $defaults['_controller']); $controller = explode(':', $controller); $defaults['_zkType'] = $type = lcfirst($controller[1]); $defaults['_zkFunc'] = $func = $controller[2]; $defaults['_controller'] = $bundleName . ":" . $controller[1] . ":" . $func; $route->setDefaults($defaults); return [$type, $func]; }
/** * Tests setRouteOptions() with an _entity_form route. * * @covers ::setRouteOptions * @covers ::getControllerClass * @covers ::getEntityTypes * @covers ::setParametersFromReflection * @covers ::setParametersFromEntityInformation */ public function testSetRouteOptionsWithEntityFormRoute() { $this->setupEntityTypes(); $route = new Route('/example/{entity_test}', array('_entity_form' => 'entity_test.edit')); $defaults = $route->getDefaults(); $this->entityResolverManager->setRouteOptions($route); $this->assertEquals($defaults, $route->getDefaults()); $parameters = $route->getOption('parameters'); $this->assertEquals(array('entity_test' => array('type' => 'entity:entity_test')), $parameters); }
private function compileRoute(Route $route, $name, $supportsRedirections, $parentPrefix = null) { $code = array(); //substitute the default compiler class with the compredux compiler classes $route->setOption('compiler_class', 'NineThousand\\Bundle\\NineThousandCompreduxBundle\\Component\\Routing\\CompreduxRouteCompiler'); $compiledRoute = $route->compile(); $conditions = array(); $hasTrailingSlash = false; $matches = false; if (!count($compiledRoute->getVariables()) && false !== preg_match('#^(.)\^(?P<url>.*?)\1#', str_replace(array("\n", ' '), '', $compiledRoute->getRegex()), $m)) { if ($supportsRedirections && 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 = str_replace(array("\n", ' '), '', $compiledRoute->getRegex()); if ($supportsRedirections && $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; } $conditions = implode(' && ', $conditions); $gotoname = 'not_'.preg_replace('/[^A-Za-z0-9_]/', '', $name); $code[] = <<<EOF // $name if ($conditions) { EOF; 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'; } 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[] = sprintf(<<<EOF if (substr(\$pathinfo, -1) !== '/') { return \$this->redirect(\$pathinfo.'/', '%s'); } EOF , $name); } if ($scheme = $route->getRequirement('_scheme')) { if (!$supportsRedirections) { throw new \LogicException('The "_scheme" requirement is only supported for route dumper that implements RedirectableUrlMatcherInterface.'); } $code[] = sprintf(<<<EOF if (\$this->context->getScheme() !== '$scheme') { return \$this->redirect(\$pathinfo, '%s', '$scheme'); } EOF , $name); } // optimize parameters array if (true === $matches && $route->getDefaults()) { $code[] = sprintf(" return array_merge(\$this->mergeDefaults(\$matches, %s), array('_route' => '%s'));" , str_replace("\n", '', var_export($route->getDefaults(), true)), $name); } elseif (true === $matches) { $code[] = sprintf(" \$matches['_route'] = '%s';", $name); $code[] = sprintf(" return \$matches;", $name); } elseif ($route->getDefaults()) { $code[] = sprintf(' return %s;', str_replace("\n", '', var_export(array_merge($route->getDefaults(), array('_route' => $name)), true))); } else { $code[] = sprintf(" return array('_route' => '%s');", $name); } $code[] = " }"; if ($req) { $code[] = " $gotoname:"; } $code[] = ''; return $code; }
/** * Set the defaults * * @param array $defaults * @return Route */ public function setDefaults(array $defaults) { parent::setDefaults($defaults); $this->defaults = parent::getDefaults(); return $this; }
/** * Asserts that a route object has the expected properties. * * @param \Symfony\Component\Routing\Route $route * The route to test. * @param string $expected_path * The expected path for the route. * @param array $expected_defaults * The expected defaults for the route. * @param array $expected_requirements * The expected requirements for the route. * @param array $expected_options * The expected options for the route. */ protected function assertMatchingRoute(Route $route, $expected_path, $expected_defaults, $expected_requirements, $expected_options) { $this->assertSame($expected_path, $route->getPath()); $this->assertSame($expected_defaults, $route->getDefaults()); $this->assertSame($expected_requirements, $route->getRequirements()); $this->assertSame($expected_options, $route->getOptions()); }
/** * Makes a clone of the given Route object. * * @param Route $route * * @return Route */ public function cloneRoute(Route $route) { return new Route($route->getPath(), $route->getDefaults(), $route->getRequirements(), $route->getOptions(), $route->getHost(), $route->getSchemes(), $route->getMethods()); }
/** * @param Route $route route * * @return string */ private function extractFunctionFromRoute(Route $route) { $defaults = $route->getDefaults(); if (!isset($defaults['_controller'])) { return; } $controller = explode('::', $defaults['_controller']); return isset($controller[1]) ? $controller[1] : null; }
/** * 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; }
/** * Tests an _entity_form route where a non-entity parameter is first. * * The {argument} preceding {entity_test} in route path, is upcasting with a * custom param converter. * * @covers ::setRouteOptions * @covers ::getControllerClass * @covers ::getEntityTypes * @covers ::setParametersFromReflection * @covers ::setParametersFromEntityInformation */ public function testSetRouteOptionsWithEntityFormRouteAndArgument() { $this->setupEntityTypes(); $route = new Route('/example/{argument}/{entity_test}', ['_entity_form' => 'entity_test.edit']); // Add {argument} parameter configuration. In this case {argument} is // upcasted by a custom param converter 'argument_type'. $route->setOption('parameters', ['argument' => ['type' => 'argument_type']]); $defaults = $route->getDefaults(); $this->entityResolverManager->setRouteOptions($route); $this->assertEquals($defaults, $route->getDefaults()); $parameters = $route->getOption('parameters'); $expect = ['argument' => ['type' => 'argument_type'], 'entity_test' => ['type' => 'entity:entity_test']]; $this->assertEquals($expect, $parameters); }