/** * {@inheritDoc} */ public function generateI18nPatterns($routeName, Route $route) { $patterns = array(); foreach ($route->getOption('i18n_locales') ?: $this->locales as $locale) { // Check if translation exists in the translation catalogue to avoid errors being logged by // the new LoggingTranslator of Symfony 2.6. However, the LoggingTranslator did not implement // the interface until Symfony 2.6.5, so an extra check is needed. if ($this->translator instanceof TranslatorBagInterface || $this->translator instanceof LoggingTranslator) { // Check if route is translated. if (!$this->translator->getCatalogue($locale)->has($routeName, $this->translationDomain)) { // No translation found. $i18nPattern = $route->getPath(); } else { // Get translation. $i18nPattern = $this->translator->trans($routeName, array(), $this->translationDomain, $locale); } } else { // if no translation exists, we use the current pattern if ($routeName === ($i18nPattern = $this->translator->trans($routeName, array(), $this->translationDomain, $locale))) { $i18nPattern = $route->getPath(); } } // prefix with locale if requested if (self::STRATEGY_PREFIX === $this->strategy || self::STRATEGY_PREFIX_EXCEPT_DEFAULT === $this->strategy && $this->defaultLocale !== $locale) { $i18nPattern = '/' . $locale . $i18nPattern; if (null !== $route->getOption('i18n_prefix')) { $i18nPattern = $route->getOption('i18n_prefix') . $i18nPattern; } } $patterns[$i18nPattern][] = $locale; } return $patterns; }
public function testPath() { $route = new Route('/{foo}'); $route->setPath('/{bar}'); $this->assertEquals('/{bar}', $route->getPath(), '->setPath() sets the path'); $route->setPath(''); $this->assertEquals('/', $route->getPath(), '->setPath() adds a / at the beginning of the path if needed'); $route->setPath('bar'); $this->assertEquals('/bar', $route->getPath(), '->setPath() adds a / at the beginning of the path if needed'); $this->assertEquals($route, $route->setPath(''), '->setPath() implements a fluent interface'); $route->setPath('//path'); $this->assertEquals('/path', $route->getPath(), '->setPath() does not allow two slahes "//" at the beginning of the path as it would be confused with a network path when generating the path from the route'); }
/** * {@inheritDoc} */ public function generateI18nPatterns($routeName, Route $route) { $patterns = array(); foreach ($route->getOption('i18n_locales') ?: $this->locales as $locale) { // Check if translation exists in the translation catalogue to avoid errors being logged by // the new LoggingTranslator of Symfony 2.6. However, the LoggingTranslator did not implement // the interface until Symfony 2.6.5, so an extra check is needed. if ($this->translator instanceof TranslatorBagInterface || $this->translator instanceof LoggingTranslator) { // Check if route is translated. if (!$this->translator->getCatalogue($locale)->has($routeName, $this->translationDomain)) { // No translation found. $i18nPattern = $route->getPath(); } else { // Get translation. $i18nPattern = $this->translator->trans($routeName, array(), $this->translationDomain, $locale); } } else { // if no translation exists, we use the current pattern if ($routeName === ($i18nPattern = $this->translator->trans($routeName, array(), $this->translationDomain, $locale))) { $i18nPattern = $route->getPath(); } } /////////////////////////////////////// // Begin customizations // prefix with zikula module url if requested if ($route->hasDefault('_zkModule')) { $module = $route->getDefault('_zkModule'); $zkNoBundlePrefix = $route->getOption('zkNoBundlePrefix'); if (!isset($zkNoBundlePrefix) || !$zkNoBundlePrefix) { $untranslatedPrefix = $this->getModUrlString($module); if ($this->translator->getCatalogue($locale)->has($untranslatedPrefix, strtolower($module))) { $prefix = $this->translator->trans($untranslatedPrefix, [], strtolower($module), $locale); } else { $prefix = $untranslatedPrefix; } $i18nPattern = "/" . $prefix . $i18nPattern; } } // End customizations /////////////////////////////////////// // prefix with locale if requested if (self::STRATEGY_PREFIX === $this->strategy || self::STRATEGY_PREFIX_EXCEPT_DEFAULT === $this->strategy && $this->defaultLocale !== $locale) { $i18nPattern = '/' . $locale . $i18nPattern; if (null !== $route->getOption('i18n_prefix')) { $i18nPattern = $route->getOption('i18n_prefix') . $i18nPattern; } } $patterns[$i18nPattern][] = $locale; } return $patterns; }
/** * Constructs a Route object. */ public function __construct($name, Route $route, RouteProviderInterface $route_provider) { $this->name = $name; $this->route = $route; $this->routeProvider = $route_provider ? $route_provider : \Drupal::service('router.route_provider'); $this->path = new PathUtility($route->getPath()); }
/** * {@inheritdoc} */ protected function describeRoute(Route $route, array $options = array()) { $requirements = $route->getRequirements(); unset($requirements['_scheme'], $requirements['_method']); // fixme: values were originally written as raw $description = array( '<comment>Path</comment> '.$route->getPath(), '<comment>Host</comment> '.('' !== $route->getHost() ? $route->getHost() : 'ANY'), '<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> '.$this->formatRouterConfig($requirements) ?: 'NO CUSTOM', '<comment>Options</comment> '.$this->formatRouterConfig($route->getOptions()), '<comment>Path-Regex</comment> '.$route->compile()->getRegex(), ); if (isset($options['name'])) { array_unshift($description, '<comment>Name</comment> '.$options['name']); array_unshift($description, $this->formatSection('router', sprintf('Route "%s"', $options['name']))); } if (null !== $route->compile()->getHostRegex()) { $description[] = '<comment>Host-Regex</comment> '.$route->compile()->getHostRegex(); } $this->writeText(implode("\n", $description)."\n", $options); }
/** * {@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" . '- Host: ' . ('' !== $route->getHost() ? $route->getHost() : 'ANY') . "\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: ' . $this->formatRouterConfig($requirements) ?: 'NONE' . "\n" . '- Options: ' . $this->formatRouterConfig($route->getOptions()) . "\n" . '- Path-Regex: ' . $route->compile()->getRegex(); $this->write(isset($options['name']) ? $options['name'] . "\n" . str_repeat('-', strlen($options['name'])) . "\n\n" . $output : $output); $this->write("\n"); }
public function getPath() { if ($path = parent::getPath()) { return $path; } $defaults = $this->getDefaults(); return $defaults['path']; }
/** * @param Route $route * @return Action */ public function getActionForRoute(Route $route) { foreach ($this->actions as $action) { // TODO this should be improved to be more precise (route prefix) $sameSchema = strpos($route->getPath(), $action->getUrlSchema()) >= 0; $sameMethods = $action->getMethods() == $route->getMethods(); if ($sameMethods && $sameSchema) { return $action; } } }
/** * @param Route $route * @param array $params * @return array */ public function matchParams(Route $route, $params) { $ret = []; preg_match_all('/{(.*?)}/', $route->getPath(), $routeParams); foreach ($routeParams[1] as $param) { if (isset($params[$param])) { $ret[$param] = $this->entityAccessor->fetchIdentifier($params[$param]); } } return $ret; }
/** * @param Route $route * * @return string */ protected function getEntryPath(Route $route) { $result = $route->getPath(); if (false !== ($pos = strpos($result, '{version}'))) { $result = substr($result, $pos + 10); } if (false !== ($pos = strpos($result, '.{'))) { $result = substr($result, 0, $pos); } return $result; }
public function generateI18nPatterns($routeName, Route $route) { $patterns = array(); $config = $route->getOption('i18n'); foreach ($this->locales as $locale) { // if no translation exists, we use the current pattern $i18nPattern = array_key_exists($locale, $config) ? $config[$locale] : $route->getPath(); $i18nPattern = '/' . $locale . $i18nPattern; $patterns[$i18nPattern][] = $locale; } return $patterns; }
/** * {@inheritdoc} */ public function processOutbound(Route $route, array &$parameters) { if ($route->hasRequirement('_csrf_token')) { $path = ltrim($route->getPath(), '/'); // Replace the path parameters with values from the parameters array. foreach ($parameters as $param => $value) { $path = str_replace("{{$param}}", $value, $path); } // Adding this to the parameters means it will get merged into the query // string when the route is compiled. $parameters['token'] = $this->csrfToken->get($path); } }
public function generateI18nPatterns($routeName, Route $route) { $patterns = array(); foreach ($route->getOption('i18n_locales') ?: $this->locales as $locale) { // if no translation exists, we use the current pattern if ($routeName === ($i18nPattern = $this->translator->trans($routeName, array(), $this->translationDomain, $locale))) { $i18nPattern = $route->getPath(); } $i18nPattern = '/' . $locale . $i18nPattern; $patterns[$i18nPattern][] = $locale; } return $patterns; }
/** * Checks access based on a CSRF token for the request. * * @param \Symfony\Component\Routing\Route $route * The route to check against. * @param \Symfony\Component\HttpFoundation\Request $request * The request object. * @param \Drupal\Core\Routing\RouteMatchInterface $route_match * The route match object. * * @return \Drupal\Core\Access\AccessResultInterface * The access result. */ public function access(Route $route, Request $request, RouteMatchInterface $route_match) { $parameters = $route_match->getRawParameters(); $path = ltrim($route->getPath(), '/'); // Replace the path parameters with values from the parameters array. foreach ($parameters as $param => $value) { $path = str_replace("{{$param}}", $value, $path); } if ($this->csrfToken->validate($request->query->get('token'), $path)) { $result = AccessResult::allowed(); } else { $result = AccessResult::forbidden(); } // Not cacheable because the CSRF token is highly dynamic. return $result->setCacheable(FALSE); }
/** * {@inheritdoc} */ public function processOutbound($route_name, Route $route, array &$parameters, CacheableMetadata $cacheable_metadata = NULL) { if ($route->hasRequirement('_csrf_token')) { $path = ltrim($route->getPath(), '/'); // Replace the path parameters with values from the parameters array. foreach ($parameters as $param => $value) { $path = str_replace("{{$param}}", $value, $path); } // Adding this to the parameters means it will get merged into the query // string when the route is compiled. $parameters['token'] = $this->csrfToken->get($path); if ($cacheable_metadata) { // Tokens are per user and per session, so not cacheable. // @todo Improve in https://www.drupal.org/node/2351015. $cacheable_metadata->setCacheMaxAge(0); } } }
/** * Generates the i18n paths for the given route. * * @param string $routeName The route name * @param Route $route A Route instance */ public function generateI18nPaths($routeName, Route $route) { // @todo Explicar el motivo para que haya traducción de routes // $fallbackLocales = ['es', 'en']; //$this->translator->getFallbackLocales(); // $this->translator->setFallbackLocales([]); $paths = []; foreach ($route->getOption('i18n_locales') ?: $this->locales as $locale) { // If no translation exists, we use the current pattern if ($routeName === ($i18nPath = $this->translator->trans($routeName, [], 'routes', $locale))) { $i18nPath = $route->getPath(); } if (self::STRATEGY_PREFIX === $this->strategy || self::STRATEGY_PREFIX_EXCEPT_DEFAULT === $this->strategy && $this->defaultLocale !== $locale) { $i18nPath = preg_replace('/\\/\\//', '/', sprintf('/{_locale}/%s', $i18nPath)); } $paths[$i18nPath][] = $locale; } // $this->translator->setFallbackLocales($fallbackLocales); return $paths; }
public function generateI18nPatterns($routeName, Route $route) { $patterns = []; /** @var FrozenParameterBag $parameterBag */ $parameterBag = $this->container->getParameterBag(); if (empty($this->offices)) { $this->offices = $this->container->get('doctrine')->getRepository('OctavaMuiBundle:Office')->getRoutingOffices(); } $translation = null; if ($structureId = $route->getDefault(Structure::ROUTING_ID_NAME)) { $structureRepository = $this->container->get('doctrine.orm.entity_manager')->getRepository('OctavaStructureBundle:Structure'); $translation = $structureRepository->getTranslations($structureRepository->getById($structureId)); } foreach (array_keys($this->offices) as $locale) { if ($translation !== null && empty($translation[$locale]['state'])) { // отключенная страница continue; } $office = $this->offices[$locale]; $i18nPattern = $route->getPath(); $paths = $route->getOption('translatable_path'); if (!empty($paths[$locale])) { $i18nPattern = $paths[$locale]; } if ($office->getIncludeLangInUrl()) { $i18nPattern = '/{_locale}' . $i18nPattern; } if (null !== ($prefix = $route->getOption('i18n_prefix'))) { $prefix = $parameterBag->resolveValue($prefix); $i18nPattern = $prefix . $i18nPattern; } $host = $office->getHost(); if (empty($patterns[$i18nPattern][$host])) { $patterns[$i18nPattern][$host] = []; } $patterns[$i18nPattern][$host][] = $locale; } return $patterns; }
public function generateI18nPatterns($routeName, Route $route) { $patterns = []; /** @var \Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag $parameterBag */ $parameterBag = $this->container->getParameterBag(); $locales = $route->getOption('i18n_locales') ?: $this->locales; $locales = $parameterBag->resolveValue($locales); foreach ($locales as $locale) { $i18nPattern = $route->getPath(); // prefix with locale if requested if (DefaultPatternGenerationStrategy::STRATEGY_PREFIX === $this->strategy || DefaultPatternGenerationStrategy::STRATEGY_PREFIX === $route->getOption('i18n_strategy') || DefaultPatternGenerationStrategy::STRATEGY_PREFIX_EXCEPT_DEFAULT === $this->strategy && $this->defaultLocale !== $locale) { $i18nPattern = '/{_locale}' . $i18nPattern; if (null !== $route->getOption('i18n_prefix')) { $prefix = $route->getOption('i18n_prefix'); $prefix = $parameterBag->resolveValue($prefix); $i18nPattern = $prefix . $i18nPattern; } } $patterns[$i18nPattern][] = $locale; } return $patterns; }
/** * {@inheritDoc} */ public function generateI18nPatterns($routeName, Route $route) { $locales = $route->getOption('i18n_locales') ?: $this->locales; $patterns = array(); // "routes" option which store all translations for a given route (TODO: required after refacto) if (null !== ($routes = $route->getOption('routes')) && !isset($routes[$this->defaultLocale])) { throw new \InvalidArgumentException(sprintf('The "path" option for the route "%s" must have at least the %s translation.', $routeName, $this->defaultLocale)); } foreach ($locales as $locale) { // if no translation exists, we use the current pattern $i18nPattern = $this->translator->trans($routeName, array(), $this->translationDomain, $locale); // overload the routes' translations from translations' files by the routes' translations from route' files if (null !== $routes) { $i18nPattern = isset($routes[$locale]) ? $routes[$locale] : $routes[$this->defaultLocale]; } if ($routeName === $i18nPattern) { $i18nPattern = $route->getPath(); } $patterns[$i18nPattern][] = $locale; } return $patterns; }
public function generateI18nPatterns($routeName, Route $route) { $patterns = []; foreach ($route->getOption('i18n_locales') ?: $this->locales as $locale) { // if no translation exists, we use the current pattern if ($routeName === ($i18nPattern = $this->translator->trans($routeName, [], $this->translationDomain, $locale))) { $i18nPattern = $route->getPath(); } // prefix with locale if requested if (self::STRATEGY_PREFIX === $this->strategy || self::STRATEGY_PREFIX === $route->getOption('i18n_strategy') || self::STRATEGY_PREFIX_EXCEPT_DEFAULT === $this->strategy && $this->defaultLocale !== $locale) { $i18nPattern = '/' . $locale . $i18nPattern; if (null !== $route->getOption('i18n_prefix')) { $prefix = $route->getOption('i18n_prefix'); /** @var FrozenParameterBag $parameterBag */ $parameterBag = $this->container->getParameterBag(); $prefix = $parameterBag->resolveValue($prefix); $i18nPattern = $prefix . $i18nPattern; } } $patterns[$i18nPattern][] = $locale; } return $patterns; }
/** * @param Route $route the route we're tried to add * @param int $name the name given to the route we tried to add * @param Route $routeWithSameName the existing route with the same name */ public function __construct(Route $route, $name, Route $routeWithSameName) { // host to string if (!($host = $route->getHost())) { $host = 'any'; } if (!($hostRouteWithSameName = $routeWithSameName->getHost())) { $hostRouteWithSameName = 'any'; } // methods to string if ($methods = $route->getMethods()) { $methods = implode($methods, ', '); } else { $methods = 'any'; } if ($methodsRouteWithSameName = $routeWithSameName->getMethods()) { $methodsRouteWithSameName = implode($methodsRouteWithSameName, ', '); } else { $methodsRouteWithSameName = 'any'; } $message = sprintf("Cannot add the route [path: %s, host: %s, methods: %s] with the name '%s'\n as it is already used by the route [path: %s, host: %s, methods: %s].", $route->getPath(), $host, $methods, $name, $routeWithSameName->getPath(), $hostRouteWithSameName, $methodsRouteWithSameName); parent::__construct($message); }
/** * {@inheritdoc} */ public function processOutbound($route_name, Route $route, array &$parameters, BubbleableMetadata $bubbleable_metadata = NULL) { if ($route->hasRequirement('_csrf_token')) { $path = ltrim($route->getPath(), '/'); // Replace the path parameters with values from the parameters array. foreach ($parameters as $param => $value) { $path = str_replace("{{$param}}", $value, $path); } // Adding this to the parameters means it will get merged into the query // string when the route is compiled. if (!$bubbleable_metadata) { $parameters['token'] = $this->csrfToken->get($path); } else { // Generate a placeholder and a render array to replace it. $placeholder = hash('sha1', $path); $placeholder_render_array = ['#lazy_builder' => ['route_processor_csrf:renderPlaceholderCsrfToken', [$path]]]; // Instead of setting an actual CSRF token as the query string, we set // the placeholder, which will be replaced at the very last moment. This // ensures links with CSRF tokens don't break cacheability. $parameters['token'] = $placeholder; $bubbleable_metadata->addAttachments(['placeholders' => [$placeholder => $placeholder_render_array]]); } } }
/** * {@inheritdoc} */ protected function getInternalPathFromRoute(Route $route, $parameters = array()) { return $route->getPath(); }
/** * 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; }
/** * Checks if a route has the given attribute * * @param Route $route * @param string $placeholder * * @return bool */ protected function hasAttribute(Route $route, $placeholder) { return false !== strpos($route->getPath(), $placeholder); }
/** * @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()); }
/** * {@inheritdoc} */ protected function getInternalPathFromRoute($name, Route $route, $parameters = array(), $query_params = array()) { return $route->getPath(); }
/** * Gets the add-form route. * * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type * The entity type. * * @return \Symfony\Component\Routing\Route|null * The generated route, if available. */ protected function getAddFormRoute(EntityTypeInterface $entity_type) { if ($entity_type->hasLinkTemplate('add-form')) { $entity_type_id = $entity_type->id(); $route = new Route($entity_type->getLinkTemplate('add-form')); // Use the add form handler, if available, otherwise default. $operation = 'default'; if ($entity_type->getFormClass('add')) { $operation = 'add'; } $route->setDefaults(['_entity_form' => "{$entity_type_id}.{$operation}", 'entity_type_id' => $entity_type_id]); // If the entity has bundles, we can provide a bundle-specific title // and access requirements. $expected_parameter = $entity_type->getBundleEntityType() ?: $entity_type->getKey('bundle'); // @todo: We have to check if a route contains a bundle in its path as // test entities have inconsistent usage of "add-form" link templates. // Fix it in https://www.drupal.org/node/2699959. if (($bundle_key = $entity_type->getKey('bundle')) && strpos($route->getPath(), '{' . $expected_parameter . '}') !== FALSE) { $route->setDefault('_title_callback', EntityController::class . '::addBundleTitle'); // If the bundles are entities themselves, we can add parameter // information to the route options. if ($bundle_entity_type_id = $entity_type->getBundleEntityType()) { $bundle_entity_type = $this->entityTypeManager->getDefinition($bundle_entity_type_id); $route->setDefault('bundle_parameter', $bundle_entity_type_id)->setRequirement('_entity_create_access', $entity_type_id . ':{' . $bundle_entity_type_id . '}'); // Entity types with serial IDs can specify this in their route // requirements, improving the matching process. if ($this->getEntityTypeIdKeyType($bundle_entity_type) === 'integer') { $route->setRequirement($entity_type_id, '\\d+'); } $bundle_entity_parameter = ['type' => 'entity:' . $bundle_entity_type_id]; if ($bundle_entity_type instanceof ConfigEntityTypeInterface) { // The add page might be displayed on an admin path. Even then, we // need to load configuration overrides so that, for example, the // bundle label gets translated correctly. // @see \Drupal\Core\ParamConverter\AdminPathConfigEntityConverter $bundle_entity_parameter['with_config_overrides'] = TRUE; } $route->setOption('parameters', [$bundle_entity_type_id => $bundle_entity_parameter]); } else { // If the bundles are not entities, the bundle key is used as the // route parameter name directly. $route->setDefault('bundle_parameter', $bundle_key)->setRequirement('_entity_create_access', $entity_type_id . ':{' . $bundle_key . '}'); } } else { $route->setDefault('_title_callback', EntityController::class . '::addTitle')->setRequirement('_entity_create_access', $entity_type_id); } return $route; } }
/** * Get the route information for a given route. * * @param string $name * @param \Symfony\Component\Routing\Route $route * @return array */ protected function getRouteInformation($name, Route $route) { $uri = head($route->getMethods()) . ' ' . $route->getPath(); $action = $route->getAction() ?: 'Closure'; return array('host' => $route->getHost(), 'uri' => $uri, 'name' => $this->getRouteName($name), 'action' => $action, 'before' => $this->getBeforeFilters($route), 'after' => $this->getAfterFilters($route)); }