/** * {@inheritdoc} */ public function processOutbound($route_name, Route $route, array &$parameters, BubbleableMetadata $bubbleable_metadata = NULL) { if ($route_name === '<current>') { if ($current_route = $this->routeMatch->getRouteObject()) { $requirements = $current_route->getRequirements(); // Setting _method and _schema is deprecated since 2.7. Using // setMethods() and setSchemes() are now the recommended ways. unset($requirements['_method']); unset($requirements['_schema']); $route->setRequirements($requirements); $route->setPath($current_route->getPath()); $route->setSchemes($current_route->getSchemes()); $route->setMethods($current_route->getMethods()); $route->setOptions($current_route->getOptions()); $route->setDefaults($current_route->getDefaults()); $parameters = array_merge($parameters, $this->routeMatch->getRawParameters()->all()); if ($bubbleable_metadata) { $bubbleable_metadata->addCacheContexts(['route']); } } else { // If we have no current route match available, point to the frontpage. $route->setPath('/'); } } }
/** * {@inheritdoc} */ public function processOutbound($route_name, Route $route, array &$parameters) { if ($route_name === '<current>' && ($current_route = $this->routeMatch->getRouteObject())) { $route->setPath($current_route->getPath()); $route->setRequirements($current_route->getRequirements()); $route->setOptions($current_route->getOptions()); $route->setDefaults($current_route->getDefaults()); $parameters = array_merge($parameters, $this->routeMatch->getRawParameters()->all()); } }
/** * {@inheritdoc} */ public function processOutbound($route_name, Route $route, array &$parameters) { if ($route_name === '<current>') { if ($current_route = $this->routeMatch->getRouteObject()) { $route->setPath($current_route->getPath()); $route->setRequirements($current_route->getRequirements()); $route->setOptions($current_route->getOptions()); $route->setDefaults($current_route->getDefaults()); $parameters = array_merge($parameters, $this->routeMatch->getRawParameters()->all()); } else { // If we have no current route match available, point to the frontpage. $route->setPath('/'); } } }
/** * {@inheritdoc} */ public function getRouteParameters(RouteMatchInterface $route_match) { $parameters = isset($this->pluginDefinition['route_parameters']) ? $this->pluginDefinition['route_parameters'] : array(); $route = $this->routeProvider()->getRouteByName($this->getRouteName()); $variables = $route->compile()->getVariables(); // Normally the \Drupal\Core\ParamConverter\ParamConverterManager has // processed the Request attributes, and in that case the _raw_variables // attribute holds the original path strings keyed to the corresponding // slugs in the path patterns. For example, if the route's path pattern is // /filter/tips/{filter_format} and the path is /filter/tips/plain_text then // $raw_variables->get('filter_format') == 'plain_text'. $raw_variables = $route_match->getRawParameters(); foreach ($variables as $name) { if (isset($parameters[$name])) { continue; } if ($raw_variables && $raw_variables->has($name)) { $parameters[$name] = $raw_variables->get($name); } elseif ($value = $route_match->getRawParameter($name)) { $parameters[$name] = $value; } } // The UrlGenerator will throw an exception if expected parameters are // missing. This method should be overridden if that is possible. return $parameters; }
/** * {@inheritdoc} */ public function getActiveLink($menu_name = NULL) { // Note: this is a very simple implementation. If you need more control // over the return value, such as matching a prioritized list of menu names, // you should substitute your own implementation for the 'menu.active_trail' // service in the container. // The menu links coming from the storage are already sorted by depth, // weight and ID. $found = NULL; $route_name = $this->routeMatch->getRouteName(); // On a default (not custom) 403 page the route name is NULL. On a custom // 403 page we will get the route name for that page, so we can consider // it a feature that a relevant menu tree may be displayed. if ($route_name) { $route_parameters = $this->routeMatch->getRawParameters()->all(); // Load links matching this route. $links = $this->menuLinkManager->loadLinksByRoute($route_name, $route_parameters, $menu_name); // Select the first matching link. if ($links) { $found = reset($links); } } return $found; }
/** * 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); }
/** * Determines whether the route of a certain local task is currently active. * * @param string $current_route_name * The route name of the current main request. * @param string $route_name * The route name of the local task to determine the active status. * @param array $route_parameters * * @return bool * Returns TRUE if the passed route_name and route_parameters is considered * as the same as the one from the request, otherwise FALSE. */ protected function isRouteActive($current_route_name, $route_name, $route_parameters) { // Flag the list element as active if this tab's route and parameters match // the current request's route and route variables. $active = $current_route_name == $route_name; if ($active) { // The request is injected, so we need to verify that we have the expected // _raw_variables attribute. $raw_variables_bag = $this->routeMatch->getRawParameters(); // If we don't have _raw_variables, we assume the attributes are still the // original values. $raw_variables = $raw_variables_bag ? $raw_variables_bag->all() : $this->routeMatch->getParameters()->all(); $active = array_intersect_assoc($route_parameters, $raw_variables) == $route_parameters; } return $active; }
/** * Checks access to create the entity type and bundle for the given route. * * @param \Symfony\Component\Routing\Route $route * The route to check against. * @param \Drupal\Core\Routing\RouteMatchInterface $route_match * The parametrized route. * @param \Drupal\Core\Session\AccountInterface $account * The currently logged in account. * * @return \Drupal\Core\Access\AccessResultInterface * The access result. */ public function access(Route $route, RouteMatchInterface $route_match, AccountInterface $account) { list($entity_type, $bundle) = explode(':', $route->getRequirement($this->requirementsKey) . ':'); // The bundle argument can contain request argument placeholders like // {name}, loop over the raw variables and attempt to replace them in the // bundle name. If a placeholder does not exist, it won't get replaced. if ($bundle && strpos($bundle, '{') !== FALSE) { foreach ($route_match->getRawParameters()->all() as $name => $value) { $bundle = str_replace('{' . $name . '}', $value, $bundle); } // If we were unable to replace all placeholders, deny access. if (strpos($bundle, '{') !== FALSE) { return AccessResult::neutral(); } } return $this->entityManager->getAccessControlHandler($entity_type)->createAccess($bundle, $account, [], TRUE); }
/** * {@inheritdoc} */ public function getArgumentsResolver(RouteMatchInterface $route_match, AccountInterface $account, Request $request = NULL) { $route = $route_match->getRouteObject(); // Defaults for the parameters defined on the route object need to be added // to the raw arguments. $raw_route_arguments = $route_match->getRawParameters()->all() + $route->getDefaults(); $upcasted_route_arguments = $route_match->getParameters()->all(); // Parameters which are not defined on the route object, but still are // essential for access checking are passed as wildcards to the argument // resolver. An access-check method with a parameter of type Route, // RouteMatchInterface, AccountInterface or Request will receive those // arguments regardless of the parameter name. $wildcard_arguments = [$route, $route_match, $account]; if (isset($request)) { $wildcard_arguments[] = $request; } return new ArgumentsResolver($raw_route_arguments, $upcasted_route_arguments, $wildcard_arguments); }
/** * {@inheritdoc} */ public function getCurrentRouteMenuTreeParameters($menu_name) { $route_parameters = $this->routeMatch->getRawParameters()->all(); ksort($route_parameters); $cid = 'current-route-parameters:' . $menu_name . ':route:' . $this->routeMatch->getRouteName() . ':route_parameters:' . serialize($route_parameters); if (!isset($this->cachedCurrentRouteParameters[$menu_name])) { $cache = $this->cache->get($cid); if ($cache && $cache->data) { $parameters = $cache->data; } else { $active_trail = $this->menuActiveTrail->getActiveTrailIds($menu_name); $parameters = new MenuTreeParameters(); $parameters->setActiveTrail($active_trail)->addExpandedParents($active_trail)->addExpandedParents($this->treeStorage->getExpanded($menu_name, $active_trail)); $this->cache->set($cid, $parameters, CacheBackendInterface::CACHE_PERMANENT, array('menu' => $menu_name)); } $this->cachedCurrentRouteParameters[$menu_name] = $parameters; } return $this->cachedCurrentRouteParameters[$menu_name]; }
/** * Creates a new URL object from a route match. * * @param \Drupal\Core\Routing\RouteMatchInterface $route_match * The route match. * * @return $this */ public static function fromRouteMatch(RouteMatchInterface $route_match) { if ($route_match->getRouteObject()) { return new static($route_match->getRouteName(), $route_match->getRawParameters()->all()); } else { throw new \InvalidArgumentException('Route required'); } }
/** * {@inheritdoc} */ public function getContext() { return $this->routeMatch->getRouteName() . hash('sha256', serialize($this->routeMatch->getRawParameters()->all())); }
/** * Language translations overview page for a configuration name. * * @param \Symfony\Component\HttpFoundation\Request $request * Page request object. * @param \Drupal\Core\Routing\RouteMatchInterface $route_match * The route match. * @param string $plugin_id * The plugin ID of the mapper. * * @return array * Page render array. */ public function itemPage(Request $request, RouteMatchInterface $route_match, $plugin_id) { /** @var \Drupal\config_translation\ConfigMapperInterface $mapper */ $mapper = $this->configMapperManager->createInstance($plugin_id); $mapper->populateFromRequest($request); $page = array(); $page['#title'] = $this->t('Translations for %label', array('%label' => $mapper->getTitle())); // It is possible the original language this configuration was saved with is // not on the system. For example, the configuration shipped in English but // the site has no English configured. Represent the original language in // the table even if it is not currently configured. $languages = $this->languageManager->getLanguages(); $original_langcode = $mapper->getLangcode(); if (!isset($languages[$original_langcode])) { $language_name = $this->languageManager->getLanguageName($original_langcode); if ($original_langcode == 'en') { $language_name = $this->t('Built-in English'); } // Create a dummy language object for this listing only. $languages[$original_langcode] = new Language(array('id' => $original_langcode, 'name' => $language_name)); } // We create a fake request object to pass into // ConfigMapperInterface::populateFromRequest() for the different languages. // Creating a separate request for each language and route is neither easily // possible nor performant. $fake_request = $request->duplicate(); $page['languages'] = array('#type' => 'table', '#header' => array($this->t('Language'), $this->t('Operations'))); foreach ($languages as $language) { $langcode = $language->getId(); // This is needed because // ConfigMapperInterface::getAddRouteParameters(), for example, // needs to return the correct language code for each table row. $fake_request->attributes->set('langcode', $langcode); $mapper->populateFromRequest($fake_request); // Prepare the language name and the operations depending on whether this // is the original language or not. if ($langcode == $original_langcode) { $language_name = '<strong>' . $this->t('@language (original)', array('@language' => $language->getName())) . '</strong>'; // Check access for the path/route for editing, so we can decide to // include a link to edit or not. $edit_access = $this->accessManager->checkNamedRoute($mapper->getBaseRouteName(), $route_match->getRawParameters()->all(), $this->account); // Build list of operations. $operations = array(); if ($edit_access) { $operations['edit'] = array('title' => $this->t('Edit'), 'url' => Url::fromRoute($mapper->getBaseRouteName(), $mapper->getBaseRouteParameters(), ['query' => ['destination' => $mapper->getOverviewPath()]])); } } else { $language_name = $language->getName(); $operations = array(); // If no translation exists for this language, link to add one. if (!$mapper->hasTranslation($language)) { $operations['add'] = array('title' => $this->t('Add'), 'url' => Url::fromRoute($mapper->getAddRouteName(), $mapper->getAddRouteParameters())); } else { // Otherwise, link to edit the existing translation. $operations['edit'] = array('title' => $this->t('Edit'), 'url' => Url::fromRoute($mapper->getEditRouteName(), $mapper->getEditRouteParameters())); $operations['delete'] = array('title' => $this->t('Delete'), 'url' => Url::fromRoute($mapper->getDeleteRouteName(), $mapper->getDeleteRouteParameters())); } } $page['languages'][$langcode]['language'] = array('#markup' => $language_name); $page['languages'][$langcode]['operations'] = array('#type' => 'operations', '#links' => $operations); } return $page; }
/** * @covers ::getRawParameters * @covers \Drupal\Core\Routing\RouteMatch::getParameterNames * @dataProvider routeMatchProvider */ public function testGetRawParameters(RouteMatchInterface $route_match, Route $route, $parameters, $expected_filtered_parameters) { $this->assertSame($expected_filtered_parameters, $route_match->getRawParameters()->all()); }
/** * {@inheritdoc} */ public function getUrlFromRoute($route_suffix, array $route_parameters, array $options = []) { // See Url::fromRouteMatch() return Url::fromRoute($this->pluginDefinition->base_route . '.' . $route_suffix, $route_parameters + $this->currentRouteMatch->getRawParameters()->all(), $options); }