diff --git a/core/includes/menu.inc b/core/includes/menu.inc index be5171e7310320d01da45ef02fd51f34202cf1c4..c5aae17f36355518fd08ad7f079c98f4df025797 100644 --- a/core/includes/menu.inc +++ b/core/includes/menu.inc @@ -344,19 +344,9 @@ function template_preprocess_menu_local_task(&$variables) { $variables['link'] = array( '#type' => 'link', '#title' => $link_text, + '#url' => $link['url'], '#options' => $link['localized_options'], ); - - if (!empty($link['href'])) { - // @todo - Remove this once all pages are converted to routes. - $variables['link']['#href'] = $link['href']; - } - else { - $variables['link'] += array( - '#route_name' => $link['route_name'], - '#route_parameters' => $link['route_parameters'], - ); - } } /** @@ -373,9 +363,7 @@ function template_preprocess_menu_local_task(&$variables) { function template_preprocess_menu_local_action(&$variables) { $link = $variables['element']['#link']; $link += array( - 'href' => '', 'localized_options' => array(), - 'route_parameters' => array(), ); $link['localized_options']['attributes']['class'][] = 'button'; $link['localized_options']['attributes']['class'][] = 'button-action'; @@ -385,19 +373,8 @@ function template_preprocess_menu_local_action(&$variables) { '#type' => 'link', '#title' => $link['title'], '#options' => $link['localized_options'], + '#url' => $link['url'], ); - - // @todo Figure out how to support local actions without a href properly. - if ($link['href'] === '' && !empty($link['route_name'])) { - $variables['link'] += array( - '#route_name' => $link['route_name'], - '#route_parameters' => $link['route_parameters'], - ); - } - else { - // @todo - Remove this once all pages are converted to routes. - $variables['link']['#href'] = $link['href']; - } } /** diff --git a/core/includes/theme.inc b/core/includes/theme.inc index b84302918545ca104acd116e1d27c17643f5c0c6..47fda818a718389ea9754787452fa4f109f901cc 100644 --- a/core/includes/theme.inc +++ b/core/includes/theme.inc @@ -902,14 +902,8 @@ function template_preprocess_status_messages(&$variables) { * is used as its CSS class. Each link should be itself an array, with the * following elements: * - title: The link text. - * - route_name: (optional) The name of the route to link to. If omitted - * (and if 'href' is omitted as well), the 'title' is shown as - * a plain text item in the links list. - * - route_parameters: (optional) An array of route parameters for the link. - * - href: (optional) The link URL. It is preferred to use 'route_name' and - * 'route parameters' for internal links. Use 'href' for links to external - * URLs. If omitted (and if 'route_name' is omitted as well), the 'title' - * is shown as a plain text item in the links list. + * - url: (optional) The url object to link to. If omitted, no a tag is + * printed out. * - html: (optional) Whether or not 'title' is HTML. If set, the title * will not be passed through * \Drupal\Component\Utility\String::checkPlain(). @@ -986,30 +980,26 @@ function template_preprocess_links(&$variables) { foreach ($links as $key => $link) { $item = array(); $link += array( - 'href' => NULL, - 'route_name' => NULL, - 'route_parameters' => NULL, 'ajax' => NULL, + 'url' => NULL, ); $li_attributes = array('class' => array()); // Use the array key as class name. $li_attributes['class'][] = drupal_html_class($key); - $keys = array('title', 'href', 'route_name', 'route_parameters'); + $keys = ['title', 'url']; $link_element = array( '#type' => 'link', '#title' => $link['title'], '#options' => array_diff_key($link, array_combine($keys, $keys)), - '#href' => $link['href'], - '#route_name' => $link['route_name'], - '#route_parameters' => $link['route_parameters'], + '#url' => $link['url'], '#ajax' => $link['ajax'], ); // Handle links and ensure that the active class is added on the LIs, but // only if the 'set_active_class' option is not empty. - if (isset($link['href']) || isset($link['route_name'])) { + if (isset($link['url'])) { if (!empty($variables['set_active_class'])) { // Also enable set_active_class for the contained link. @@ -1027,16 +1017,16 @@ function template_preprocess_links(&$variables) { $li_attributes['data-drupal-link-query'] = Json::encode($query); } - if (isset($link['route_name'])) { - $path = \Drupal::service('url_generator')->getPathFromRoute($link['route_name'], $link['route_parameters']); + /** @var \Drupal\Core\Url $url */ + $url = $link['url']; + if ($url->isRouted()) { + // Add a "data-drupal-link-system-path" attribute to let the + // drupal.active-link library know the path in a standardized manner. + $system_path = $url->getInternalPath(); + // @todo System path is deprecated - use the route name and parameters. + // Special case for the front page. + $li_attributes['data-drupal-link-system-path'] = $system_path == '' ? '<front>' : $system_path; } - else { - $path = $link['href']; - } - - // Add a "data-drupal-link-system-path" attribute to let the - // drupal.active-link library know the path in a standardized manner. - $li_attributes['data-drupal-link-system-path'] = \Drupal::service('path.alias_manager')->getPathByAlias($path); } $item['link'] = $link_element; diff --git a/core/lib/Drupal/Core/Config/Entity/ConfigEntityListBuilder.php b/core/lib/Drupal/Core/Config/Entity/ConfigEntityListBuilder.php index 01fb7dd6b4ce9bd7098df77d59c1f46539ac126b..a0ecdcf30c3eb90f015b660a63d8360c5e5e7218 100644 --- a/core/lib/Drupal/Core/Config/Entity/ConfigEntityListBuilder.php +++ b/core/lib/Drupal/Core/Config/Entity/ConfigEntityListBuilder.php @@ -41,13 +41,15 @@ public function getDefaultOperations(EntityInterface $entity) { $operations['enable'] = array( 'title' => t('Enable'), 'weight' => -10, - ) + $entity->urlInfo('enable')->toArray(); + 'url' => $entity->urlInfo('enable'), + ); } elseif ($entity->hasLinkTemplate('disable')) { $operations['disable'] = array( 'title' => t('Disable'), 'weight' => 40, - ) + $entity->urlInfo('disable')->toArray(); + 'url' => $entity->urlInfo('disable'), + ); } } diff --git a/core/lib/Drupal/Core/Entity/EntityForm.php b/core/lib/Drupal/Core/Entity/EntityForm.php index 0a46a2ee21c41d791b366668a9766b22d6ccef23..25acfab241892c0cc12b8a4c2a33b4be9139b7c5 100644 --- a/core/lib/Drupal/Core/Entity/EntityForm.php +++ b/core/lib/Drupal/Core/Entity/EntityForm.php @@ -213,7 +213,7 @@ protected function actions(array $form, FormStateInterface $form_state) { 'class' => array('button', 'button--danger'), ), ); - $actions['delete'] += $route_info->toRenderArray(); + $actions['delete']['#url'] = $route_info; } return $actions; diff --git a/core/lib/Drupal/Core/Entity/EntityListBuilder.php b/core/lib/Drupal/Core/Entity/EntityListBuilder.php index eee643b5704852046629017414564a56c3e8d82f..9e41b08337330e6f62f954303bf0a20553e6d8bb 100644 --- a/core/lib/Drupal/Core/Entity/EntityListBuilder.php +++ b/core/lib/Drupal/Core/Entity/EntityListBuilder.php @@ -118,13 +118,15 @@ protected function getDefaultOperations(EntityInterface $entity) { $operations['edit'] = array( 'title' => $this->t('Edit'), 'weight' => 10, - ) + $entity->urlInfo('edit-form')->toArray(); + 'url' => $entity->urlInfo('edit-form'), + ); } if ($entity->access('delete') && $entity->hasLinkTemplate('delete-form')) { $operations['delete'] = array( 'title' => $this->t('Delete'), 'weight' => 100, - ) + $entity->urlInfo('delete-form')->toArray(); + 'url' => $entity->urlInfo('delete-form'), + ); } return $operations; diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/MailToFormatter.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/MailToFormatter.php index 58f6c6b300551f7b983b4835b18275a66b7ece29..19311b5695c213cd211e907f105d2e73da5e87fe 100644 --- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/MailToFormatter.php +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/MailToFormatter.php @@ -9,6 +9,7 @@ use Drupal\Core\Field\FormatterBase; use Drupal\Core\Field\FieldItemListInterface; +use Drupal\Core\Url; /** * Plugin implementation of the 'email_mailto' formatter. @@ -33,7 +34,7 @@ public function viewElements(FieldItemListInterface $items) { $elements[$delta] = array( '#type' => 'link', '#title' => $item->value, - '#href' => 'mailto:' . $item->value, + '#url' => Url::fromUri('mailto:' . $item->value), ); } diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/UriLinkFormatter.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/UriLinkFormatter.php index 762d5f38531b8d75799aed424117b713ae9ef80c..51e0c3bd30f2f6238c7489de1be2373735520b3e 100644 --- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/UriLinkFormatter.php +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/UriLinkFormatter.php @@ -9,6 +9,7 @@ use Drupal\Core\Field\FormatterBase; use Drupal\Core\Field\FieldItemListInterface; +use Drupal\Core\Url; /** * Plugin implementation of the 'uri_link' formatter. @@ -30,11 +31,13 @@ public function viewElements(FieldItemListInterface $items) { $elements = array(); foreach ($items as $delta => $item) { - $elements[$delta] = array( - '#type' => 'link', - '#href' => $item->value, - '#title' => $item->value, - ); + if (!$item->isEmpty()) { + $elements[$delta] = [ + '#type' => 'link', + '#url' => Url::fromUri($item->value), + '#title' => $item->value, + ]; + } } return $elements; diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/UriItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/UriItem.php index a823cac3ae054c0b2fa755f2dbcd0a115957d72b..a50696b2ee7608e4e80f4063eb1289b7c5f26166 100644 --- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/UriItem.php +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/UriItem.php @@ -61,4 +61,15 @@ public static function schema(FieldStorageDefinitionInterface $field_definition) ); } + /** + * {@inheritdoc} + */ + public function isEmpty() { + $value = $this->getValue(); + if (!isset($value['value']) || $value['value'] === '') { + return TRUE; + } + return parent::isEmpty(); + } + } diff --git a/core/lib/Drupal/Core/Form/ConfirmFormHelper.php b/core/lib/Drupal/Core/Form/ConfirmFormHelper.php index de98053d7ce1c3b61ba913770dd7521b878cd082..b58078d39e1633a7a5aa84e6661fc2754ba2e047 100644 --- a/core/lib/Drupal/Core/Form/ConfirmFormHelper.php +++ b/core/lib/Drupal/Core/Form/ConfirmFormHelper.php @@ -34,19 +34,20 @@ public static function buildCancelLink(ConfirmFormInterface $form, Request $requ // If a destination is specified, that serves as the cancel link. if ($query->has('destination')) { $options = UrlHelper::parse($query->get('destination')); - $link = array( - '#href' => $options['path'], - '#options' => $options, - ); + // @todo Use Url::fromPath() once https://www.drupal.org/node/2351379 is + // resolved. + $url = Url::fromUri('base://' . $options['path'], $options); } // Check for a route-based cancel link. - elseif ($url = $form->getCancelUrl()) { - $link = $url->toRenderArray(); + else { + $url = $form->getCancelUrl(); } - $link['#type'] = 'link'; - $link['#title'] = $form->getCancelText(); - return $link; + return [ + '#type' => 'link', + '#title' => $form->getCancelText(), + '#url' => $url, + ]; } } diff --git a/core/lib/Drupal/Core/Language/LanguageManager.php b/core/lib/Drupal/Core/Language/LanguageManager.php index 6fe99d6f7531020df20b7a18b2c47a632d5b11c8..ee8bd2acff961df86d0ad8b979acb90d4db597e4 100644 --- a/core/lib/Drupal/Core/Language/LanguageManager.php +++ b/core/lib/Drupal/Core/Language/LanguageManager.php @@ -11,6 +11,7 @@ use Drupal\Core\DependencyInjection\DependencySerializationTrait; use Drupal\Core\StringTranslation\TranslationInterface; use Drupal\Core\StringTranslation\TranslationWrapper; +use Drupal\Core\Url; /** * Class responsible for providing language support on language-unaware sites. @@ -239,7 +240,7 @@ public function getFallbackCandidates(array $context = array()) { /** * {@inheritdoc} */ - public function getLanguageSwitchLinks($type, $path) { + public function getLanguageSwitchLinks($type, Url $url) { return array(); } diff --git a/core/lib/Drupal/Core/Language/LanguageManagerInterface.php b/core/lib/Drupal/Core/Language/LanguageManagerInterface.php index e163c0cde97953d1eaa1e81c1659313fa918c821..783496c443c24e8f61973382f0060fcbe9c4fdad 100644 --- a/core/lib/Drupal/Core/Language/LanguageManagerInterface.php +++ b/core/lib/Drupal/Core/Language/LanguageManagerInterface.php @@ -8,6 +8,7 @@ namespace Drupal\Core\Language; use Drupal\Core\StringTranslation\TranslationInterface; +use Drupal\Core\Url; /** * Common interface for the language manager service. @@ -181,13 +182,13 @@ public function getFallbackCandidates(array $context = array()); * * @param string $type * The language type. - * @param string $path - * The internal path the switch links will be relative to. + * @param \Drupal\Core\Url $url + * The URL the switch links will be relative to. * * @return array * A keyed array of links ready to be themed. */ - public function getLanguageSwitchLinks($type, $path); + public function getLanguageSwitchLinks($type, Url $url); /** * Sets the configuration override language. diff --git a/core/lib/Drupal/Core/Menu/Form/MenuLinkDefaultForm.php b/core/lib/Drupal/Core/Menu/Form/MenuLinkDefaultForm.php index f6ee14bef183c99443b8c69bb225d7bda66c28ac..bf86365bb3459fa7773538b66087e5a2345d598f 100644 --- a/core/lib/Drupal/Core/Menu/Form/MenuLinkDefaultForm.php +++ b/core/lib/Drupal/Core/Menu/Form/MenuLinkDefaultForm.php @@ -113,7 +113,8 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta $link = array( '#type' => 'link', '#title' => $this->menuLink->getTitle(), - ) + $this->menuLink->getUrlObject()->toRenderArray(); + '#url' => $this->menuLink->getUrlObject(), + ); $form['path'] = array( 'link' => $link, '#type' => 'item', diff --git a/core/lib/Drupal/Core/Menu/LocalActionManager.php b/core/lib/Drupal/Core/Menu/LocalActionManager.php index 2e4eb9258a6063b0cbab2dde3e541fff395cb963..68550bc86992171ff8c4dfde0ab3ba9e319f00d9 100644 --- a/core/lib/Drupal/Core/Menu/LocalActionManager.php +++ b/core/lib/Drupal/Core/Menu/LocalActionManager.php @@ -16,6 +16,7 @@ use Drupal\Core\Plugin\Discovery\YamlDiscovery; use Drupal\Core\Plugin\Factory\ContainerFactory; use Drupal\Core\Routing\RouteProviderInterface; +use Drupal\Core\Url; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface; use Drupal\Core\Session\AccountInterface; @@ -166,8 +167,7 @@ public function getActionsForRoute($route_appears) { '#theme' => 'menu_local_action', '#link' => array( 'title' => $this->getTitle($plugin), - 'route_name' => $route_name, - 'route_parameters' => $route_parameters, + 'url' => Url::fromRoute($route_name, $route_parameters), 'localized_options' => $plugin->getOptions($request), ), '#access' => $this->accessManager->checkNamedRoute($route_name, $route_parameters, $this->account), diff --git a/core/lib/Drupal/Core/Menu/LocalTaskManager.php b/core/lib/Drupal/Core/Menu/LocalTaskManager.php index 3914d8edfc6995d3c96e4b960d70a87976d5c35b..5b85d7ff4dc38cc4bd61aedb23d5b6bd22066655 100644 --- a/core/lib/Drupal/Core/Menu/LocalTaskManager.php +++ b/core/lib/Drupal/Core/Menu/LocalTaskManager.php @@ -21,6 +21,7 @@ use Drupal\Core\Routing\RouteBuilderInterface; use Drupal\Core\Routing\RouteProviderInterface; use Drupal\Core\Session\AccountInterface; +use Drupal\Core\Url; use Symfony\Component\HttpFoundation\RequestStack; /** @@ -306,8 +307,7 @@ public function getTasksBuild($current_route_name) { $link = array( 'title' => $this->getTitle($child), - 'route_name' => $route_name, - 'route_parameters' => $route_parameters, + 'url' => Url::fromRoute($route_name, $route_parameters), 'localized_options' => $child->getOptions($request), ); $build[$level][$plugin_id] = array( diff --git a/core/lib/Drupal/Core/Menu/MenuLinkInterface.php b/core/lib/Drupal/Core/Menu/MenuLinkInterface.php index fdc61df666cfdb4505341d9db5f2389a3277c2fb..ffef25584510c62df165e408330516700fc9afbd 100644 --- a/core/lib/Drupal/Core/Menu/MenuLinkInterface.php +++ b/core/lib/Drupal/Core/Menu/MenuLinkInterface.php @@ -218,9 +218,9 @@ public function getFormClass(); /** * Returns route information for a route to delete the menu link. * - * @return array|null - * An array with keys route_name and route_parameters, or NULL if there is - * no route (e.g. when the link is not deletable). + * @return \Drupal\Core\Url|null + * A Url object, or NULL if there is no route (e.g. when the link is not + * deletable). */ public function getDeleteRoute(); @@ -231,18 +231,18 @@ public function getDeleteRoute(); * they need to define additional local tasks, local actions, etc. that are * visible from the edit form. * - * @return array|null - * An array with keys route_name and route_parameters, or NULL if there is - * no route because there is no custom edit route for this instance. + * @return \Drupal\Core\Url|null + * A Url object, or NULL if there is no route because there is no custom + * edit route for this instance. */ public function getEditRoute(); /** * Returns route information for a route to translate the menu link. * - * @return array - * An array with keys route_name and route_parameters, or NULL if there is - * no route (e.g. when the link is not translatable). + * @return \Drupal\Core\Url|null + * A Url object, or NULL if there is no route (e.g. when the link is not + * translatable). */ public function getTranslateRoute(); diff --git a/core/lib/Drupal/Core/Render/Element/Link.php b/core/lib/Drupal/Core/Render/Element/Link.php index 474e9f5531591ae9f5f4465264478f3f891e3a57..b785bd63af1e3b29279ed6cbf62b07d753bb9cb1 100644 --- a/core/lib/Drupal/Core/Render/Element/Link.php +++ b/core/lib/Drupal/Core/Render/Element/Link.php @@ -7,7 +7,7 @@ namespace Drupal\Core\Render\Element; -use Drupal\Core\Url as UrlObject; +use Drupal\Component\Utility\NestedArray; /** * Provides a link render element. @@ -36,11 +36,7 @@ public function getInfo() { * @param array $element * A structured array whose keys form the arguments to _l(): * - #title: The link text to pass as argument to _l(). - * - One of the following - * - #route_name and (optionally) a #route_parameters array; The route - * name and route parameters which will be passed into the link - * generator. - * - #href: The system path or URL to pass as argument to _l(). + * - #url: The URL info either pointing to a route or a non routed path. * - #options: (optional) An array of options to pass to _l() or the link * generator. * @@ -75,21 +71,12 @@ public static function preRenderLink($element) { if (!isset($element['#id'])) { $element['#id'] = $element['#options']['attributes']['id'] = drupal_html_id('ajax-link'); } - // If #ajax['path] was not specified, use the href as Ajax request URL. - if (!isset($element['#ajax']['path'])) { - $element['#ajax']['path'] = $element['#href']; - $element['#ajax']['options'] = $element['#options']; - } $element = static::preRenderAjaxForm($element); } - if (isset($element['#route_name'])) { - $element['#route_parameters'] = empty($element['#route_parameters']) ? array() : $element['#route_parameters']; - $element['#markup'] = \Drupal::l($element['#title'], new UrlObject($element['#route_name'], $element['#route_parameters'], $element['#options'])); - } - else { - // @todo Convert to \Drupal::l(): https://www.drupal.org/node/2347045. - $element['#markup'] = _l($element['#title'], $element['#href'], $element['#options']); + if (!empty($element['#url'])) { + $options = NestedArray::mergeDeep($element['#url']->getOptions(), $element['#options']); + $element['#markup'] = \Drupal::l($element['#title'], $element['#url']->setOptions($options)); } return $element; } diff --git a/core/lib/Drupal/Core/Render/Element/Table.php b/core/lib/Drupal/Core/Render/Element/Table.php index d82fda8d1c8206e18e149543791ccd192fb5fb6d..08c539a14791570f522e6b1b5a879b9296740f74 100644 --- a/core/lib/Drupal/Core/Render/Element/Table.php +++ b/core/lib/Drupal/Core/Render/Element/Table.php @@ -281,7 +281,7 @@ public static function validateTable(&$element, FormStateInterface $form_state, * $form['table'][$row]['edit'] = array( * '#type' => 'link', * '#title' => t('Edit'), - * '#href' => 'thing/' . $row . '/edit', + * '#url' => Url::fromRoute('entity.test_entity.edit_form', ['test_entity' => $row]), * ); * } * @endcode diff --git a/core/lib/Drupal/Core/Url.php b/core/lib/Drupal/Core/Url.php index a6f0220710fa2b6d0097dd874ed460bb8c7a1668..9f78645a238d7e431fe37cf3d4be8ef1551ae9eb 100644 --- a/core/lib/Drupal/Core/Url.php +++ b/core/lib/Drupal/Core/Url.php @@ -7,6 +7,7 @@ namespace Drupal\Core; +use Drupal\Component\Utility\String; use Drupal\Core\DependencyInjection\DependencySerializationTrait; use Drupal\Core\Routing\UrlGeneratorInterface; use Drupal\Core\Session\AccountInterface; @@ -203,7 +204,7 @@ public static function fromRoute($route_name, $route_parameters = array(), $opti */ public static function fromUri($uri, $options = array()) { if (!parse_url($uri, PHP_URL_SCHEME)) { - throw new \InvalidArgumentException('You must use a valid URI scheme. Use base:// for a path, e.g., to a Drupal file that needs the base path. Do not use this for internal paths controlled by Drupal.'); + throw new \InvalidArgumentException(String::format('The URI "@uri" is invalid. You must use a valid URI scheme. Use base:// for a path, e.g., to a Drupal file that needs the base path. Do not use this for internal paths controlled by Drupal.', ['@uri' => $uri])); } $url = new static($uri, array(), $options); @@ -455,22 +456,16 @@ public function toString() { * * @return array * An associative array containing all the properties of the route. + * + * @deprecated in Drupal 8.0.x-dev, will be removed before Drupal 9.0. + * Most usecases should use the URL object directly, like #type links. Other + * usecases should get the information from the URL object manually. */ public function toArray() { - if ($this->unrouted) { - return array( - // @todo Change 'path' to 'href': https://www.drupal.org/node/2347025. - 'path' => $this->getUri(), - 'options' => $this->getOptions(), - ); - } - else { - return array( - 'route_name' => $this->getRouteName(), - 'route_parameters' => $this->getRouteParameters(), - 'options' => $this->getOptions(), - ); - } + return [ + 'url' => $this, + 'options' => $this->getOptions(), + ]; } /** @@ -480,20 +475,14 @@ public function toArray() { * An associative array suitable for a render array. */ public function toRenderArray() { - if ($this->unrouted) { - return array( - '#href' => $this->getUri(), - '#options' => $this->getOptions(), - ); - } - else { - return array( - '#route_name' => $this->getRouteName(), - '#route_parameters' => $this->getRouteParameters(), - '#options' => $this->getOptions(), - '#access_callback' => array(get_class(), 'renderAccess'), - ); + $render_array = [ + '#url' => $this, + '#options' => $this->getOptions(), + ]; + if (!$this->unrouted) { + $render_array['#access_callback'] = [get_class(), 'renderAccess']; } + return $render_array; } /** @@ -543,7 +532,7 @@ public function access(AccountInterface $account = NULL) { * Returns TRUE if the current user has access to the url, otherwise FALSE. */ public static function renderAccess(array $element) { - return (new static($element['#route_name'], $element['#route_parameters'], $element['#options']))->access(); + return $element['#url']->access(); } /** diff --git a/core/lib/Drupal/Core/Utility/LinkGenerator.php b/core/lib/Drupal/Core/Utility/LinkGenerator.php index f56755819745ab4a76e72e89b6e02e055fbd142f..b029327a9935e447c24cd6c8eda6f480312b3ce4 100644 --- a/core/lib/Drupal/Core/Utility/LinkGenerator.php +++ b/core/lib/Drupal/Core/Utility/LinkGenerator.php @@ -109,7 +109,7 @@ public function generate($text, Url $url) { // Add a "data-drupal-link-system-path" attribute to let the // drupal.active-link library know the path in a standardized manner. - if (!isset($variables['options']['attributes']['data-drupal-link-system-path'])) { + if ($url->isRouted() && !isset($variables['options']['attributes']['data-drupal-link-system-path'])) { // @todo System path is deprecated - use the route name and parameters. $system_path = $url->getInternalPath(); // Special case for the front page. diff --git a/core/lib/Drupal/Core/Utility/UnroutedUrlAssembler.php b/core/lib/Drupal/Core/Utility/UnroutedUrlAssembler.php index 52d1d1397b50ce74ab8c8da7d667c299615fffb5..08d00834c67b951b575bdc324c0215d2a697f5dc 100644 --- a/core/lib/Drupal/Core/Utility/UnroutedUrlAssembler.php +++ b/core/lib/Drupal/Core/Utility/UnroutedUrlAssembler.php @@ -7,6 +7,7 @@ namespace Drupal\Core\Utility; +use Drupal\Component\Utility\String; use Drupal\Component\Utility\UrlHelper; use Drupal\Core\Config\ConfigFactoryInterface; use Symfony\Component\HttpFoundation\RequestStack; @@ -56,7 +57,7 @@ public function assemble($uri, array $options = []) { // UrlHelper::isExternal() only returns true for safe protocols. return $this->buildExternalUrl($uri, $options); } - throw new \InvalidArgumentException('You must use a valid URI scheme. Use base:// for a path e.g. to a Drupal file that needs the base path.'); + throw new \InvalidArgumentException(String::format('The URI "@uri" is invalid. You must use a valid URI scheme. Use base:// for a path, e.g., to a Drupal file that needs the base path. Do not use this for internal paths controlled by Drupal.', ['@uri' => $uri])); } /** diff --git a/core/modules/aggregator/src/Controller/AggregatorController.php b/core/modules/aggregator/src/Controller/AggregatorController.php index a37a81d29c986c4843b5b60205a509bd01e07517..a7e25fff804ae8abd3961d9660688c8e0d484129 100644 --- a/core/modules/aggregator/src/Controller/AggregatorController.php +++ b/core/modules/aggregator/src/Controller/AggregatorController.php @@ -11,6 +11,7 @@ use Drupal\Core\Controller\ControllerBase; use Drupal\Core\Datetime\DateFormatter; use Drupal\aggregator\FeedInterface; +use Drupal\Core\Url; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -128,25 +129,21 @@ public function adminOverview() { $refresh_rate = $feed->getRefreshRate(); $row[] = ($last_checked ? $this->t('@time ago', array('@time' => $this->dateFormatter->formatInterval(REQUEST_TIME - $last_checked))) : $this->t('never')); $row[] = ($last_checked && $refresh_rate ? $this->t('%time left', array('%time' => $this->dateFormatter->formatInterval($last_checked + $refresh_rate - REQUEST_TIME))) : $this->t('never')); - $links['edit'] = array( + $links['edit'] = [ 'title' => $this->t('Edit'), - 'route_name' => 'entity.aggregator_feed.edit_form', - 'route_parameters' => array('aggregator_feed' => $feed->id()), - ); + 'url' => Url::fromRoute('entity.aggregator_feed.edit_form', ['aggregator_feed' => $feed->id()]), + ]; $links['delete'] = array( 'title' => $this->t('Delete'), - 'route_name' => 'entity.aggregator_feed.delete_form', - 'route_parameters' => array('aggregator_feed' => $feed->id()), + 'url' => Url::fromRoute('entity.aggregator_feed.delete_form', ['aggregator_feed' => $feed->id()]), ); $links['delete_items'] = array( 'title' => $this->t('Delete items'), - 'route_name' => 'aggregator.feed_items_delete', - 'route_parameters' => array('aggregator_feed' => $feed->id()), + 'url' => Url::fromRoute('aggregator.feed_items_delete', ['aggregator_feed' => $feed->id()]), ); $links['update'] = array( 'title' => $this->t('Update items'), - 'route_name' => 'aggregator.feed_refresh', - 'route_parameters' => array('aggregator_feed' => $feed->id()), + 'url' => Url::fromRoute('aggregator.feed_refresh', ['aggregator_feed' => $feed->id()]) ); $row[] = array( 'data' => array( diff --git a/core/modules/aggregator/src/FeedViewBuilder.php b/core/modules/aggregator/src/FeedViewBuilder.php index 26523ab6c44e415cab125b859e35bac9ecf753b3..944d9a890269f0d1803ad0067914e8ebde826950 100644 --- a/core/modules/aggregator/src/FeedViewBuilder.php +++ b/core/modules/aggregator/src/FeedViewBuilder.php @@ -12,6 +12,7 @@ use Drupal\Core\Entity\EntityViewBuilder; use Drupal\Core\Config\Config; use Drupal\Core\Language\LanguageManagerInterface; +use Drupal\Core\Url; use Symfony\Component\DependencyInjection\ContainerInterface; /** @@ -99,7 +100,7 @@ public function buildComponents(array &$build, array $entities, array $displays, $image_link = array( '#type' => 'link', '#title' => $link_title, - '#href' => $link_href, + '#url' => Url::fromUri($link_href), '#options' => array( 'attributes' => array('class' => array('feed-image')), 'html' => TRUE, @@ -124,8 +125,7 @@ public function buildComponents(array &$build, array $entities, array $displays, '#title' => t('More<span class="visually-hidden"> posts about @title</span>', array( '@title' => $title_stripped, )), - '#route_name' => 'entity.aggregator_feed.canonical', - '#route_parameters' => array('aggregator_feed' => $entity->id()), + '#url' => Url::fromRoute('entity.aggregator_feed.canonical', ['aggregator_feed' => $entity->id()]), '#options' => array( 'html' => TRUE, 'attributes' => array( diff --git a/core/modules/aggregator/src/ItemsImporter.php b/core/modules/aggregator/src/ItemsImporter.php index af193253f39967444729b62d7eb1d673dae1c902..3098f085749db0c8dd7d02073bb8af6aafed61e4 100644 --- a/core/modules/aggregator/src/ItemsImporter.php +++ b/core/modules/aggregator/src/ItemsImporter.php @@ -120,7 +120,7 @@ public function refresh(FeedInterface $feed) { // Parse the feed. try { if ($this->parserManager->createInstance($this->config->get('parser'))->parse($feed)) { - if ($feed->getWebsiteUrl()) { + if (!$feed->getWebsiteUrl()) { $feed->setWebsiteUrl($feed->getUrl()); } $feed->setHash($hash); diff --git a/core/modules/aggregator/src/Plugin/Block/AggregatorFeedBlock.php b/core/modules/aggregator/src/Plugin/Block/AggregatorFeedBlock.php index f28ff0d0cfcdd3ada9ef770933e2bb66288e4de6..2710cedb86bb73f7255b184f1dfcfea0269591b5 100644 --- a/core/modules/aggregator/src/Plugin/Block/AggregatorFeedBlock.php +++ b/core/modules/aggregator/src/Plugin/Block/AggregatorFeedBlock.php @@ -164,7 +164,7 @@ public function build() { $more_link = array( '#type' => 'more_link', - '#href' => 'aggregator/sources/' . $feed->id(), + '#url' => $feed->urlInfo(), '#attributes' => array('title' => $this->t("View this feed's recent news.")), ); $read_more = drupal_render($more_link); diff --git a/core/modules/aggregator/src/Tests/AddFeedTest.php b/core/modules/aggregator/src/Tests/AddFeedTest.php index 5b15d02c9f6e4f61f073c6adc176424a592d4dcd..bbeae854fd581920e5133e2c8ac53f987b075756 100644 --- a/core/modules/aggregator/src/Tests/AddFeedTest.php +++ b/core/modules/aggregator/src/Tests/AddFeedTest.php @@ -18,6 +18,7 @@ class AddFeedTest extends AggregatorTestBase { */ function testAddFeed() { $feed = $this->createFeed(); + $feed->refreshItems(); // Check feed data. $this->assertUrl(\Drupal::url('aggregator.feed_add', [], ['absolute' => TRUE]), [], 'Directed to correct url.'); @@ -27,7 +28,7 @@ function testAddFeed() { $this->drupalGet('aggregator/sources/' . $feed->id()); $this->assertResponse(200, 'Feed source exists.'); $this->assertText($feed->label(), 'Page title'); - $this->assertText($feed->label()); + $this->assertRaw($feed->getWebsiteUrl()); // Delete feed. $this->deleteFeed($feed); @@ -40,11 +41,13 @@ function testAddLongFeed() { // Create a feed with a URL of > 255 characters. $long_url = "https://www.google.com/search?ix=heb&sourceid=chrome&ie=UTF-8&q=angie+byron#sclient=psy-ab&hl=en&safe=off&source=hp&q=angie+byron&pbx=1&oq=angie+byron&aq=f&aqi=&aql=&gs_sm=3&gs_upl=0l0l0l10534l0l0l0l0l0l0l0l0ll0l0&bav=on.2,or.r_gc.r_pw.r_cp.,cf.osb&fp=a70b6b1f0abe28d8&biw=1629&bih=889&ix=heb"; $feed = $this->createFeed($long_url); + $feed->refreshItems(); // Create a second feed of > 255 characters, where the only difference is // after the 255th character. $long_url_2 = "https://www.google.com/search?ix=heb&sourceid=chrome&ie=UTF-8&q=angie+byron#sclient=psy-ab&hl=en&safe=off&source=hp&q=angie+byron&pbx=1&oq=angie+byron&aq=f&aqi=&aql=&gs_sm=3&gs_upl=0l0l0l10534l0l0l0l0l0l0l0l0ll0l0&bav=on.2,or.r_gc.r_pw.r_cp.,cf.osb&fp=a70b6b1f0abe28d8&biw=1629&bih=889"; $feed_2 = $this->createFeed($long_url_2); + $feed->refreshItems(); // Check feed data. $this->assertTrue($this->uniqueFeed($feed->label(), $feed->getUrl()), 'The first long URL feed is unique.'); @@ -54,7 +57,6 @@ function testAddLongFeed() { $this->drupalGet('aggregator/sources/' . $feed->id()); $this->assertResponse(200, 'Long URL feed source exists.'); $this->assertText($feed->label(), 'Page title'); - $this->assertText($feed->label()); // Delete feeds. $this->deleteFeed($feed); diff --git a/core/modules/ban/src/Form/BanAdmin.php b/core/modules/ban/src/Form/BanAdmin.php index 94c1d4f0b77d6a5bd47df8e706fd3e696ae9635d..1690b91035a63f28726a42ed3b110ed7b75a28d8 100644 --- a/core/modules/ban/src/Form/BanAdmin.php +++ b/core/modules/ban/src/Form/BanAdmin.php @@ -10,6 +10,7 @@ use Drupal\Core\Form\FormBase; use Drupal\ban\BanIpManagerInterface; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Url; use Symfony\Component\DependencyInjection\ContainerInterface; /** @@ -65,8 +66,7 @@ public function buildForm(array $form, FormStateInterface $form_state, $default_ $links = array(); $links['delete'] = array( 'title' => $this->t('Delete'), - 'route_name' => 'ban.delete', - 'route_parameters' => array('ban_id' => $ip->iid), + 'url' => Url::fromRoute('ban.delete', ['ban_id' => $ip->iid]), ); $row[] = array( 'data' => array( diff --git a/core/modules/block/block.module b/core/modules/block/block.module index cbf56ab3b6b2c9e579daddd9b5bdfb1fe4cd150e..952bad2b97b7f9db822727bdfab4a9fea6928c16 100644 --- a/core/modules/block/block.module +++ b/core/modules/block/block.module @@ -93,10 +93,15 @@ function block_page_build(&$page) { $page['page_top']['backlink'] = array( '#type' => 'link', '#title' => t('Exit block region demonstration'), - '#href' => 'admin/structure/block' . (\Drupal::config('system.theme')->get('default') == $theme ? '' : '/list/' . $theme), '#options' => array('attributes' => array('class' => array('block-demo-backlink'))), '#weight' => -10, ); + if (\Drupal::config('system.theme')->get('default') == $theme) { + $page['page_top']['backlink']['#url'] = Url::fromRoute('block.admin_display'); + } + else { + $page['page_top']['backlink']['#url'] = Url::fromRoute('block.admin_display_theme', ['theme' => $theme]); + } } } diff --git a/core/modules/block/src/BlockListBuilder.php b/core/modules/block/src/BlockListBuilder.php index e5da65d1342c0fa97aaa262a8575d481d88d4075..1d11f9979a18e5b405ddcaf4c989c242d797905c 100644 --- a/core/modules/block/src/BlockListBuilder.php +++ b/core/modules/block/src/BlockListBuilder.php @@ -16,6 +16,7 @@ use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Form\FormInterface; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Url; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\Request; @@ -356,11 +357,10 @@ public function buildForm(array $form, FormStateInterface $form_state) { } $form['place_blocks']['list'][$category_key]['content']['#links'][$plugin_id] = array( 'title' => $plugin_definition['admin_label'], - 'route_name' => 'block.admin_add', - 'route_parameters' => array( + 'url' => Url::fromRoute('block.admin_add', [ 'plugin_id' => $plugin_id, 'theme' => $this->theme - ), + ]), 'attributes' => array( 'class' => array('use-ajax', 'block-filter-text-source'), 'data-accepts' => 'application/vnd.drupal-modal', diff --git a/core/modules/book/book.admin.inc b/core/modules/book/book.admin.inc index 469267c99dd8b844050fdffd1b4ed44a6d82f347..ced19d920ca09a3f20417786ea1ab8745e5401d6 100644 --- a/core/modules/book/book.admin.inc +++ b/core/modules/book/book.admin.inc @@ -8,6 +8,7 @@ use Drupal\Component\Utility\SafeMarkup; use Drupal\book\BookManager; use Drupal\Core\Render\Element; +use Drupal\Core\Url; /** * Returns HTML for a book administration form. @@ -45,19 +46,17 @@ function theme_book_admin_table($variables) { $links = array(); $links['view'] = array( 'title' => t('View'), - 'href' => $href, + 'url' => Url::fromRoute('entity.node.canonical', ['node' => $nid]), ); if ($access) { $links['edit'] = array( 'title' => t('Edit'), - 'route_name' => 'entity.node.edit_form', - 'route_parameters' => array('node' => $nid), + 'url' => Url::fromRoute('entity.node.edit_form', ['node' => $nid]), 'query' => $destination, ); $links['delete'] = array( 'title' => t('Delete'), - 'route_name' => 'entity.node.delete_form', - 'route_parameters' => array('node' => $nid), + 'url' => Url::fromRoute('entity.node.delete_form', ['node' => $nid]), 'query' => $destination, ); } diff --git a/core/modules/book/book.module b/core/modules/book/book.module index ee4410c7f73b830234c6bd7c013cb01f44c02fc0..a5cbb9cb67a18769f581a87d7c4da4c3c8f1229d 100644 --- a/core/modules/book/book.module +++ b/core/modules/book/book.module @@ -12,6 +12,7 @@ use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Render\Element; use Drupal\Core\Routing\RouteMatchInterface; +use Drupal\Core\Url; use Drupal\node\NodeInterface; use Drupal\node\NodeTypeInterface; use Drupal\node\Entity\Node; @@ -110,15 +111,17 @@ function book_node_links_alter(array &$node_links, NodeInterface $node, array &$ if (($account->hasPermission('add content to books') || $account->hasPermission('administer book outlines')) && $access_control_handler->createAccess($child_type) && $node->isPublished() && $node->book['depth'] < BookManager::BOOK_MAX_DEPTH) { $links['book_add_child'] = array( 'title' => t('Add child page'), - 'href' => 'node/add/' . $child_type, - 'query' => array('parent' => $node->id()), + 'url' => Url::fromRoute('node.add', ['node_type' => $child_type], ['query' => ['parent' => $node->id()]]), ); } if ($account->hasPermission('access printer-friendly version')) { $links['book_printer'] = array( 'title' => t('Printer-friendly version'), - 'href' => 'book/export/html/' . $node->id(), + 'url' => Url::fromRoute('book.export', [ + 'type' => 'html', + 'node' => $node->id(), + ]), 'attributes' => array('title' => t('Show a printer-friendly version of this book page and its sub-pages.')) ); } diff --git a/core/modules/book/src/Controller/BookController.php b/core/modules/book/src/Controller/BookController.php index 3079032223c3536c9f4bff0dd39798d4fee94d20..2f899371e7a034121b5850eb84886cbe862fac23 100644 --- a/core/modules/book/src/Controller/BookController.php +++ b/core/modules/book/src/Controller/BookController.php @@ -10,6 +10,7 @@ use Drupal\book\BookExport; use Drupal\book\BookManagerInterface; use Drupal\Core\Controller\ControllerBase; +use Drupal\Core\Url; use Drupal\node\Entity\Node; use Drupal\node\NodeInterface; use Symfony\Component\DependencyInjection\Container; @@ -83,8 +84,7 @@ public function adminOverview() { $links = array(); $links['edit'] = array( 'title' => t('Edit order and titles'), - 'route_name' => 'book.admin_edit', - 'route_parameters' => array('node' => $book['nid']), + 'url' => Url::fromRoute('book.admin_edit', ['node' => $book['nid']]), ); $row[] = array( 'data' => array( diff --git a/core/modules/comment/comment.api.php b/core/modules/comment/comment.api.php index 5430ee9f4acd90d4bdb212153d18632710cb789f..b460a7168b5e874bef59ddb62357bf383dc5a932 100644 --- a/core/modules/comment/comment.api.php +++ b/core/modules/comment/comment.api.php @@ -2,6 +2,7 @@ use Drupal\Core\Entity\EntityInterface; use Drupal\comment\CommentInterface; +use Drupal\Core\Url; /** * @file @@ -37,9 +38,8 @@ function hook_comment_links_alter(array &$links, CommentInterface $entity, array '#links' => array( 'comment-report' => array( 'title' => t('Report'), - 'href' => "comment/{$entity->id()}/report", + 'url' => Url::fromRoute('comment_test.report', ['comment' => $entity->id()], ['query' => ['token' => \Drupal::getContainer()->get('csrf_token')->get("comment/{$entity->id()}/report")]]), 'html' => TRUE, - 'query' => array('token' => \Drupal::getContainer()->get('csrf_token')->get("comment/{$entity->id()}/report")), ), ), ); diff --git a/core/modules/comment/src/CommentLinkBuilder.php b/core/modules/comment/src/CommentLinkBuilder.php index 972671269981f5b0151c5e98181647a7b55fd660..f689b1ab039ca577ecb0bd2786a69accbfeb4e6a 100644 --- a/core/modules/comment/src/CommentLinkBuilder.php +++ b/core/modules/comment/src/CommentLinkBuilder.php @@ -13,6 +13,7 @@ use Drupal\Core\Session\AccountInterface; use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\Core\StringTranslation\TranslationInterface; +use Drupal\Core\Url; /** * Defines a class for building markup for comment links on a commented entity. @@ -110,11 +111,12 @@ public function buildCommentedEntityLinks(FieldableEntityInterface $entity, arra 'title' => $this->formatPlural($entity->get($field_name)->comment_count, '1 comment', '@count comments'), 'attributes' => array('title' => $this->t('Jump to the first comment of this posting.')), 'fragment' => 'comments', - ) + $entity->urlInfo()->toArray(); + 'url' => $entity->urlInfo(), + ); if ($this->moduleHandler->moduleExists('history')) { $links['comment-new-comments'] = array( 'title' => '', - 'href' => '', + 'url' => Url::fromRoute('<current>'), 'attributes' => array( 'class' => 'hidden', 'title' => $this->t('Jump to the first new comment of this posting.'), @@ -136,15 +138,14 @@ public function buildCommentedEntityLinks(FieldableEntityInterface $entity, arra 'fragment' => 'comment-form', ); if ($comment_form_location == CommentItemInterface::FORM_SEPARATE_PAGE) { - $links['comment-add']['route_name'] = 'comment.reply'; - $links['comment-add']['route_parameters'] = array( + $links['comment-add']['url'] = Url::fromRoute('comment.reply', [ 'entity_type' => $entity->getEntityTypeId(), 'entity' => $entity->id(), 'field_name' => $field_name, - ); + ]); } else { - $links['comment-add'] += $entity->urlInfo()->toArray(); + $links['comment-add'] += ['url' => $entity->urlInfo()]; } } elseif ($this->currentUser->isAnonymous()) { @@ -171,15 +172,14 @@ public function buildCommentedEntityLinks(FieldableEntityInterface $entity, arra 'fragment' => 'comment-form', ); if ($comment_form_location == CommentItemInterface::FORM_SEPARATE_PAGE) { - $links['comment-add']['route_name'] = 'comment.reply'; - $links['comment-add']['route_parameters'] = array( + $links['comment-add']['url'] = Url::fromRoute('comment.reply', [ 'entity_type' => $entity->getEntityTypeId(), 'entity' => $entity->id(), 'field_name' => $field_name, - ); + ]); } else { - $links['comment-add'] += $entity->urlInfo()->toArray(); + $links['comment-add']['url'] = $entity->urlInfo(); } } } diff --git a/core/modules/comment/src/CommentViewBuilder.php b/core/modules/comment/src/CommentViewBuilder.php index 01856239f594c60867d6c01647a559597c02a66d..4314990033bb1180a6cd331ee70f216eccb9d730 100644 --- a/core/modules/comment/src/CommentViewBuilder.php +++ b/core/modules/comment/src/CommentViewBuilder.php @@ -17,6 +17,7 @@ use Drupal\Core\Entity\EntityViewBuilder; use Drupal\Core\Entity\Entity\EntityViewDisplay; use Drupal\Core\Language\LanguageManagerInterface; +use Drupal\Core\Url; use Symfony\Component\DependencyInjection\ContainerInterface; /** @@ -245,7 +246,7 @@ protected static function buildLinks(CommentInterface $entity, EntityInterface $ if ($entity->access('delete')) { $links['comment-delete'] = array( 'title' => t('Delete'), - 'href' => "comment/{$entity->id()}/delete", + 'url' => $entity->urlInfo('delete-form'), 'html' => TRUE, ); } @@ -253,22 +254,26 @@ protected static function buildLinks(CommentInterface $entity, EntityInterface $ if ($entity->access('update')) { $links['comment-edit'] = array( 'title' => t('Edit'), - 'href' => "comment/{$entity->id()}/edit", + 'url' => $entity->urlInfo('edit-form'), 'html' => TRUE, ); } if ($entity->access('create')) { $links['comment-reply'] = array( 'title' => t('Reply'), - 'href' => "comment/reply/{$entity->getCommentedEntityTypeId()}/{$entity->getCommentedEntityId()}/{$entity->getFieldName()}/{$entity->id()}", + 'url' => Url::fromRoute('comment.reply', [ + 'entity_type' => $entity->getCommentedEntityTypeId(), + 'entity' => $entity->getCommentedEntityId(), + 'field_name' => $entity->getFieldName(), + 'pid' => $entity->id(), + ]), 'html' => TRUE, ); } if (!$entity->isPublished() && $entity->access('approve')) { $links['comment-approve'] = array( 'title' => t('Approve'), - 'route_name' => 'comment.approve', - 'route_parameters' => array('comment' => $entity->id()), + 'url' => Url::fromRoute('comment.approve', ['comment' => $entity->id()]), 'html' => TRUE, ); } @@ -282,7 +287,7 @@ protected static function buildLinks(CommentInterface $entity, EntityInterface $ if (\Drupal::moduleHandler()->moduleExists('content_translation') && content_translation_translate_access($entity)->isAllowed()) { $links['comment-translations'] = array( 'title' => t('Translate'), - 'href' => 'comment/' . $entity->id() . '/translations', + 'url' => $entity->urlInfo('drupal:content-translation-overview'), 'html' => TRUE, ); } diff --git a/core/modules/comment/src/Form/CommentAdminOverview.php b/core/modules/comment/src/Form/CommentAdminOverview.php index 723241ad9b908e555eb312e11a9ebcf7de837fd9..4abff6820acdb1453e0f280ffc6ca17ab7898607 100644 --- a/core/modules/comment/src/Form/CommentAdminOverview.php +++ b/core/modules/comment/src/Form/CommentAdminOverview.php @@ -15,6 +15,7 @@ use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Form\FormBase; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Url; use Symfony\Component\DependencyInjection\ContainerInterface; /** @@ -200,7 +201,8 @@ public function buildForm(array $form, FormStateInterface $form_state, $type = ' 'data' => array( '#type' => 'link', '#title' => $comment->getSubject(), - ) + $comment_permalink->toRenderArray(), + '#url' => $comment_permalink, + ), ), 'author' => drupal_render($username), 'posted_in' => array( @@ -208,7 +210,8 @@ public function buildForm(array $form, FormStateInterface $form_state, $type = ' '#type' => 'link', '#title' => $commented_entity->label(), '#access' => $commented_entity->access('view'), - ) + $commented_entity->urlInfo()->toRenderArray(), + '#url' => $commented_entity->urlInfo(), + ), ), 'changed' => $this->dateFormatter->format($comment->getChangedTime(), 'short'), ); @@ -216,18 +219,12 @@ public function buildForm(array $form, FormStateInterface $form_state, $type = ' $links = array(); $links['edit'] = array( 'title' => $this->t('Edit'), - 'route_name' => 'entity.comment.edit_form', - 'route_parameters' => array('comment' => $comment->id()), - 'options' => $comment_uri_options, - 'query' => $destination, + 'url' => Url::fromRoute('entity.comment.edit_form', ['comment' => $comment->id()], $comment_uri_options + ['query' => $destination]), ); if ($this->moduleHandler->moduleExists('content_translation') && $this->moduleHandler->invoke('content_translation', 'translate_access', array($comment))->isAllowed()) { $links['translate'] = array( 'title' => $this->t('Translate'), - 'route_name' => 'content_translation.translation_overview_comment', - 'route_parameters' => array('comment' => $comment->id()), - 'options' => $comment_uri_options, - 'query' => $destination, + 'url' => Url::fromRoute('content_translation.translation_overview_comment', ['comment' => $comment->id()], $comment_uri_options + ['query' => $destination]), ); } $options[$comment->id()]['operations']['data'] = array( diff --git a/core/modules/comment/tests/modules/comment_test/comment_test.module b/core/modules/comment/tests/modules/comment_test/comment_test.module index 7ff9376b1a4bdc15dd46d4bdf5d9f4c41488ab33..9fb600f6414a4d5dd39bad117d12f6c45834d334 100644 --- a/core/modules/comment/tests/modules/comment_test/comment_test.module +++ b/core/modules/comment/tests/modules/comment_test/comment_test.module @@ -7,6 +7,7 @@ */ use Drupal\comment\CommentInterface; +use Drupal\Core\Url; /** * Implements hook_entity_type_alter(). @@ -36,9 +37,8 @@ function comment_test_comment_links_alter(array &$links, CommentInterface &$enti '#links' => array( 'comment-report' => array( 'title' => t('Report'), - 'href' => "comment/{$entity->id()}/report", + 'url' => Url::fromRoute('comment_test.report', ['comment' => $entity->id()], ['query' => ['token' => \Drupal::getContainer()->get('csrf_token')->get("comment/{$entity->id()}/report")]]), 'html' => TRUE, - 'query' => array('token' => \Drupal::getContainer()->get('csrf_token')->get("comment/{$entity->id()}/report")), ), ), ); diff --git a/core/modules/comment/tests/modules/comment_test/comment_test.routing.yml b/core/modules/comment/tests/modules/comment_test/comment_test.routing.yml new file mode 100644 index 0000000000000000000000000000000000000000..7841048caae9699c76e2eb1cbe404d6da83cab47 --- /dev/null +++ b/core/modules/comment/tests/modules/comment_test/comment_test.routing.yml @@ -0,0 +1,8 @@ +comment_test.report: + path: '/comment/{comment}/report' + defaults: + _title: 'Report' + _content: '\Drupal\comment_test\Controller\CommentTestController::commentReport' + requirements: + _access: 'TRUE' + _csrf_token: 'TRUE' diff --git a/core/modules/comment/tests/modules/comment_test/src/Controller/CommentTestController.php b/core/modules/comment/tests/modules/comment_test/src/Controller/CommentTestController.php new file mode 100644 index 0000000000000000000000000000000000000000..4f717552c3acc459c001faa079e519fb46f522a5 --- /dev/null +++ b/core/modules/comment/tests/modules/comment_test/src/Controller/CommentTestController.php @@ -0,0 +1,25 @@ +<?php + +/** + * @file + * Contains \Drupal\comment_test\Controller\CommentTestController. + */ + +namespace Drupal\comment_test\Controller; + +use Drupal\comment\CommentInterface; +use Drupal\Core\Controller\ControllerBase; + +/** + * Controller for the comment_test.module. + */ +class CommentTestController extends ControllerBase { + + /** + * Provides a comment report. + */ + public function commentReport(CommentInterface $comment) { + return ['#markup' => $this->t('Report for a comment')]; + } + +} diff --git a/core/modules/comment/tests/src/Unit/CommentLinkBuilderTest.php b/core/modules/comment/tests/src/Unit/CommentLinkBuilderTest.php index 2993f2830099074622b0c8beece8e676b8886fea..fdcb8f5eab9f680989f02a872f43b58891ba5ea3 100644 --- a/core/modules/comment/tests/src/Unit/CommentLinkBuilderTest.php +++ b/core/modules/comment/tests/src/Unit/CommentLinkBuilderTest.php @@ -9,6 +9,7 @@ use Drupal\comment\CommentLinkBuilder; use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface; +use Drupal\Core\Url; use Drupal\node\NodeInterface; use Drupal\simpletest\TestBase; use Drupal\Tests\UnitTestCase; @@ -129,12 +130,12 @@ public function testCommentLinkBuilder(NodeInterface $node, $context, $has_acces if (is_array($detail)) { // Array of link attributes. foreach ($detail as $key => $value) { - $this->assertEquals($links['comment__comment']['#links'][$link][$key], $value); + $this->assertEquals($value, $links['comment__comment']['#links'][$link][$key]); } } else { // Just the title. - $this->assertEquals($links['comment__comment']['#links'][$link]['title'], $detail); + $this->assertEquals($detail, $links['comment__comment']['#links'][$link]['title']); } } } @@ -236,11 +237,11 @@ public function getLinkCombinations() { $expected['comment-add'] = array('title' => 'Add new comment'); if ($combination['form_location'] == CommentItemInterface::FORM_BELOW) { // On the same page. - $expected['comment-add']['route_name'] = 'node.view'; + $expected['comment-add']['url'] = Url::fromRoute('node.view'); } else { // On a separate page. - $expected['comment-add']['route_name'] = 'comment.reply'; + $expected['comment-add']['url'] = Url::fromRoute('comment.reply', ['entity_type' => 'node', 'entity' => 1, 'field_name' => 'comment']); } } } @@ -314,12 +315,7 @@ protected function getMockNode($has_field, $comment_status, $form_location, $com ->method('id') ->willReturn(1); - $url = $this->getMockBuilder('\Drupal\Core\Url') - ->disableOriginalConstructor() - ->getMock(); - $url->expects($this->any()) - ->method('toArray') - ->willReturn(array('route_name' => 'node.view')); + $url = Url::fromRoute('node.view'); $node->expects($this->any()) ->method('urlInfo') ->willReturn($url); diff --git a/core/modules/config/src/Controller/ConfigController.php b/core/modules/config/src/Controller/ConfigController.php index 48b31df57d9ac04c9ba44cd8824899473e5e051a..8eb713f7784bac6801044aa5a9d4489048f64fb1 100644 --- a/core/modules/config/src/Controller/ConfigController.php +++ b/core/modules/config/src/Controller/ConfigController.php @@ -13,6 +13,7 @@ use Drupal\Core\Config\StorageInterface; use Drupal\Core\DependencyInjection\ContainerInjectionInterface; use Drupal\Core\Diff\DiffFormatter; +use Drupal\Core\Url; use Drupal\system\FileDownloadController; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\Request; @@ -156,7 +157,7 @@ public function diff($source_name, $target_name = NULL, $collection = NULL) { ), ), '#title' => "Back to 'Synchronize configuration' page.", - '#href' => 'admin/config/development/configuration', + '#url' => Url::fromRoute('config.sync'), ); return $build; diff --git a/core/modules/config/src/Form/ConfigSync.php b/core/modules/config/src/Form/ConfigSync.php index 9edfab6f59b4a3ba93b3f5915211c4a31efa5596..21840a5ce6334812a565b5a71f8431267c68e104 100644 --- a/core/modules/config/src/Form/ConfigSync.php +++ b/core/modules/config/src/Form/ConfigSync.php @@ -20,7 +20,7 @@ use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Lock\LockBackendInterface; use Drupal\Core\Config\StorageComparer; -use Drupal\Core\Routing\UrlGeneratorInterface; +use Drupal\Core\Url; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -71,13 +71,6 @@ class ConfigSync extends FormBase { */ protected $configManager; - /** - * URL generator service. - * - * @var \Drupal\Core\Routing\UrlGeneratorInterface - */ - protected $urlGenerator; - /** * The typed config manager. * @@ -114,8 +107,6 @@ class ConfigSync extends FormBase { * Event dispatcher. * @param \Drupal\Core\Config\ConfigManagerInterface $config_manager * Configuration manager. - * @param \Drupal\Core\Routing\UrlGeneratorInterface $url_generator - * The url generator service. * @param \Drupal\Core\Config\TypedConfigManagerInterface $typed_config * The typed configuration manager. * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler @@ -123,14 +114,13 @@ class ConfigSync extends FormBase { * @param \Drupal\Core\Extension\ThemeHandlerInterface $theme_handler * The theme handler */ - public function __construct(StorageInterface $staging_storage, StorageInterface $active_storage, StorageInterface $snapshot_storage, LockBackendInterface $lock, EventDispatcherInterface $event_dispatcher, ConfigManagerInterface $config_manager, UrlGeneratorInterface $url_generator, TypedConfigManagerInterface $typed_config, ModuleHandlerInterface $module_handler, ThemeHandlerInterface $theme_handler) { + public function __construct(StorageInterface $staging_storage, StorageInterface $active_storage, StorageInterface $snapshot_storage, LockBackendInterface $lock, EventDispatcherInterface $event_dispatcher, ConfigManagerInterface $config_manager, TypedConfigManagerInterface $typed_config, ModuleHandlerInterface $module_handler, ThemeHandlerInterface $theme_handler) { $this->stagingStorage = $staging_storage; $this->activeStorage = $active_storage; $this->snapshotStorage = $snapshot_storage; $this->lock = $lock; $this->eventDispatcher = $event_dispatcher; $this->configManager = $config_manager; - $this->urlGenerator = $url_generator; $this->typedConfigManager = $typed_config; $this->moduleHandler = $module_handler; $this->themeHandler = $theme_handler; @@ -147,7 +137,6 @@ public static function create(ContainerInterface $container) { $container->get('lock'), $container->get('event_dispatcher'), $container->get('config.manager'), - $container->get('url_generator'), $container->get('config.typed'), $container->get('module_handler'), $container->get('theme_handler') @@ -268,15 +257,15 @@ public function buildForm(array $form, FormStateInterface $form_state) { $route_options = array('source_name' => $config_name); } if ($collection != StorageInterface::DEFAULT_COLLECTION) { + $route_name = 'config.diff_collection'; $route_options['collection'] = $collection; - $href = $this->urlGenerator->getPathFromRoute('config.diff_collection', $route_options); } else { - $href = $this->urlGenerator->getPathFromRoute('config.diff', $route_options); + $route_name = 'config.diff'; } $links['view_diff'] = array( 'title' => $this->t('View differences'), - 'href' => $href, + 'url' => Url::fromRoute($route_name, $route_options), 'attributes' => array( 'class' => array('use-ajax'), 'data-accepts' => 'application/vnd.drupal-modal', diff --git a/core/modules/config/src/Tests/ConfigEntityListTest.php b/core/modules/config/src/Tests/ConfigEntityListTest.php index b0818b9ae419cec735018be6a65df0e3c5039e03..c578ff26028661d9260879bec8b101c66f01b743 100644 --- a/core/modules/config/src/Tests/ConfigEntityListTest.php +++ b/core/modules/config/src/Tests/ConfigEntityListTest.php @@ -48,21 +48,24 @@ function testList() { 'edit' => array ( 'title' => t('Edit'), 'weight' => 10, - ) + $entity->urlInfo()->toArray(), + 'url' => $entity->urlInfo(), + ), 'disable' => array( 'title' => t('Disable'), 'weight' => 40, - ) + $entity->urlInfo('disable')->toArray(), + 'url' => $entity->urlInfo('disable'), + ), 'delete' => array ( 'title' => t('Delete'), 'weight' => 100, - ) + $entity->urlInfo('delete-form')->toArray(), + 'url' => $entity->urlInfo('delete-form'), + ), ); $actual_operations = $controller->getOperations($entity); // Sort the operations to normalize link order. uasort($actual_operations, array('Drupal\Component\Utility\SortArray', 'sortByWeightElement')); - $this->assertIdentical($expected_operations, $actual_operations, 'The operations are identical.'); + $this->assertEqual($expected_operations, $actual_operations, 'The operations are identical.'); // Test buildHeader() method. $expected_items = array( @@ -71,7 +74,7 @@ function testList() { 'operations' => 'Operations', ); $actual_items = $controller->buildHeader(); - $this->assertIdentical($expected_items, $actual_items, 'Return value from buildHeader matches expected.'); + $this->assertEqual($expected_items, $actual_items, 'Return value from buildHeader matches expected.'); // Test buildRow() method. $build_operations = $controller->buildOperations($entity); @@ -83,7 +86,7 @@ function testList() { ), ); $actual_items = $controller->buildRow($entity); - $this->assertIdentical($expected_items, $actual_items, 'Return value from buildRow matches expected.'); + $this->assertEqual($expected_items, $actual_items, 'Return value from buildRow matches expected.'); // Test sorting. $storage = $controller->getStorage(); $entity = $storage->create(array( @@ -120,17 +123,19 @@ function testList() { 'edit' => array( 'title' => t('Edit'), 'weight' => 10, - ) + $entity->urlInfo()->toArray(), + 'url' => $entity->urlInfo(), + ), 'delete' => array( 'title' => t('Delete'), 'weight' => 100, - ) + $entity->urlInfo('delete-form')->toArray(), + 'url' => $entity->urlInfo('delete-form'), + ), ); $actual_operations = $controller->getOperations($entity); // Sort the operations to normalize link order. uasort($actual_operations, array('Drupal\Component\Utility\SortArray', 'sortByWeightElement')); - $this->assertIdentical($expected_operations, $actual_operations, 'The operations are identical.'); + $this->assertEqual($expected_operations, $actual_operations, 'The operations are identical.'); } /** diff --git a/core/modules/config_translation/config_translation.module b/core/modules/config_translation/config_translation.module index 29ea6eb8660df2cb23a4c6a321122555673e4e29..32b330743b88d7ab3b8d53df01838c06ceaee9fb 100644 --- a/core/modules/config_translation/config_translation.module +++ b/core/modules/config_translation/config_translation.module @@ -162,7 +162,8 @@ function config_translation_entity_operation(EntityInterface $entity) { $operations['translate'] = array( 'title' => t('Translate'), 'weight' => 50, - ) + $entity->urlInfo('drupal:config-translation-overview')->toArray(); + 'url' => $entity->urlInfo('drupal:config-translation-overview'), + ); } return $operations; diff --git a/core/modules/config_translation/src/ConfigEntityMapper.php b/core/modules/config_translation/src/ConfigEntityMapper.php index ce66ff670f7b3b2b7c228ba729561804285df0ae..2cbc78e38edc04ae305bd20216b50d1bb23a431b 100644 --- a/core/modules/config_translation/src/ConfigEntityMapper.php +++ b/core/modules/config_translation/src/ConfigEntityMapper.php @@ -13,6 +13,7 @@ use Drupal\Core\Entity\EntityManagerInterface; use Drupal\Core\Routing\RouteProviderInterface; use Drupal\Core\StringTranslation\TranslationInterface; +use Drupal\Core\Url; use Drupal\locale\LocaleConfigManager; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\Request; @@ -216,7 +217,9 @@ public function getOperations() { return array( 'list' => array( 'title' => $this->t('List'), - 'href' => 'admin/config/regional/config-translation/' . $this->getPluginId(), + 'url' => Url::fromRoute('config_translation.entity_list', [ + 'mapper_id' => $this->getPluginId(), + ]), ), ); } diff --git a/core/modules/config_translation/src/ConfigNamesMapper.php b/core/modules/config_translation/src/ConfigNamesMapper.php index 57811d915ef106abd1cb23423061c0deefff11cb..ed796af5a8dd3d2ca9ef76139f2f5bf2f4a3ac83 100644 --- a/core/modules/config_translation/src/ConfigNamesMapper.php +++ b/core/modules/config_translation/src/ConfigNamesMapper.php @@ -15,6 +15,7 @@ use Drupal\Core\Routing\RouteProviderInterface; use Drupal\Core\StringTranslation\TranslationInterface; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; +use Drupal\Core\Url; use Drupal\locale\LocaleConfigManager; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\Request; @@ -200,7 +201,7 @@ protected function processRoute(Route $route) { * {@inheritdoc} */ public function getBasePath() { - return $this->getPathFromRoute($this->getBaseRoute(), $this->getBaseRouteParameters()); + return Url::fromRoute($this->getBaseRouteName(), $this->getBaseRouteParameters())->getInternalPath(); } /** @@ -237,7 +238,7 @@ public function getOverviewRoute() { * {@inheritdoc} */ public function getOverviewPath() { - return $this->getPathFromRoute($this->getOverviewRoute(), $this->getOverviewRouteParameters()); + return Url::fromRoute($this->getOverviewRouteName(), $this->getOverviewRouteParameters())->getInternalPath(); } /** @@ -334,25 +335,6 @@ public function getDeleteRoute() { return $route; } - /** - * Gets the path for a certain route, given a set of route parameters. - * - * @param \Symfony\Component\Routing\Route $route - * The route object. - * @param array $parameters - * An array of route parameters. - * - * @return string - * Processed path with placeholders replaced. - */ - public function getPathFromRoute(Route $route, array $parameters) { - $path = $route->getPath(); - foreach ($parameters as $key => $value) { - $path = str_replace('{' . $key . '}', $value, $path); - } - return $path; - } - /** * {@inheritdoc} */ @@ -492,7 +474,7 @@ public function getOperations() { return array( 'translate' => array( 'title' => $this->t('Translate'), - 'href' => $this->getOverviewPath(), + 'url' => Url::fromRoute($this->getOverviewRouteName(), $this->getOverviewRouteParameters()), ), ); } diff --git a/core/modules/config_translation/src/Controller/ConfigTranslationController.php b/core/modules/config_translation/src/Controller/ConfigTranslationController.php index 646d3b8531b550614b4c2bb04ef8268447c40ef2..b6b016c9795be2164c340194654d02622f354974 100644 --- a/core/modules/config_translation/src/Controller/ConfigTranslationController.php +++ b/core/modules/config_translation/src/Controller/ConfigTranslationController.php @@ -15,6 +15,7 @@ use Drupal\Core\PathProcessor\InboundPathProcessorInterface; use Drupal\Core\Routing\RouteMatchInterface; use Drupal\Core\Session\AccountInterface; +use Drupal\Core\Url; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Routing\Matcher\RequestMatcherInterface; @@ -174,9 +175,7 @@ public function itemPage(Request $request, RouteMatchInterface $route_match, $pl if ($edit_access) { $operations['edit'] = array( 'title' => $this->t('Edit'), - 'route_name' => $mapper->getBaseRouteName(), - 'route_parameters' => $mapper->getBaseRouteParameters(), - 'query' => array('destination' => $mapper->getOverviewPath()), + 'url' => Url::fromRoute($mapper->getBaseRouteName(), $mapper->getBaseRouteParameters(), ['query' => ['destination' => $mapper->getOverviewPath()]]), ); } } @@ -188,22 +187,19 @@ public function itemPage(Request $request, RouteMatchInterface $route_match, $pl if (!$mapper->hasTranslation($language)) { $operations['add'] = array( 'title' => $this->t('Add'), - 'route_name' => $mapper->getAddRouteName(), - 'route_parameters' => $mapper->getAddRouteParameters(), + 'url' => Url::fromRoute($mapper->getAddRouteName(), $mapper->getAddRouteParameters()), ); } else { // Otherwise, link to edit the existing translation. $operations['edit'] = array( 'title' => $this->t('Edit'), - 'route_name' => $mapper->getEditRouteName(), - 'route_parameters' => $mapper->getEditRouteParameters(), + 'url' => Url::fromRoute($mapper->getEditRouteName(), $mapper->getEditRouteParameters()), ); $operations['delete'] = array( 'title' => $this->t('Delete'), - 'route_name' => $mapper->getDeleteRouteName(), - 'route_parameters' => $mapper->getDeleteRouteParameters(), + 'url' => Url::fromRoute($mapper->getDeleteRouteName(), $mapper->getDeleteRouteParameters()), ); } } diff --git a/core/modules/config_translation/tests/src/Unit/ConfigEntityMapperTest.php b/core/modules/config_translation/tests/src/Unit/ConfigEntityMapperTest.php index 69828f6be6f43582ae878f1264b41b36d83564ec..2b1c67e94d7ec38352b5f3c793399c9166266973 100644 --- a/core/modules/config_translation/tests/src/Unit/ConfigEntityMapperTest.php +++ b/core/modules/config_translation/tests/src/Unit/ConfigEntityMapperTest.php @@ -8,6 +8,7 @@ namespace Drupal\Tests\config_translation\Unit; use Drupal\config_translation\ConfigEntityMapper; +use Drupal\Core\Url; use Drupal\Tests\UnitTestCase; use Symfony\Component\Routing\Route; @@ -188,11 +189,11 @@ public function testGetOperations() { $expected = array( 'list' => array( 'title' => 'List', - 'href' => 'admin/config/regional/config-translation/configurable_language', - ) + 'url' => Url::fromRoute('config_translation.entity_list', ['mapper_id' => 'configurable_language']), + ), ); - $this->assertSame($expected, $result); + $this->assertEquals($expected, $result); } } diff --git a/core/modules/config_translation/tests/src/Unit/ConfigNamesMapperTest.php b/core/modules/config_translation/tests/src/Unit/ConfigNamesMapperTest.php index 5b19122555f9772fdc508d40ebe43828d07e721f..50e2712a917eca44555ffb1df08ca35dbe7131bf 100644 --- a/core/modules/config_translation/tests/src/Unit/ConfigNamesMapperTest.php +++ b/core/modules/config_translation/tests/src/Unit/ConfigNamesMapperTest.php @@ -9,7 +9,9 @@ use Drupal\config_translation\ConfigNamesMapper; use Drupal\Core\Config\ConfigFactoryInterface; +use Drupal\Core\DependencyInjection\ContainerBuilder; use Drupal\Core\Language\Language; +use Drupal\Core\Url; use Drupal\Tests\UnitTestCase; use Symfony\Component\Routing\Route; use Symfony\Component\HttpFoundation\Request; @@ -72,6 +74,13 @@ class ConfigNamesMapperTest extends UnitTestCase { */ protected $routeProvider; + /** + * The mocked URL generator. + * + * @var \Drupal\Core\Routing\UrlGeneratorInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $urlGenerator; + protected function setUp() { $this->routeProvider = $this->getMock('Drupal\Core\Routing\RouteProviderInterface'); @@ -91,6 +100,11 @@ protected function setUp() { $this->configMapperManager = $this->getMock('Drupal\config_translation\ConfigMapperManagerInterface'); + $this->urlGenerator = $this->getMock('Drupal\Core\Routing\UrlGeneratorInterface'); + $container = new ContainerBuilder(); + $container->set('url_generator', $this->urlGenerator); + \Drupal::setContainer($container); + $this->baseRoute = new Route('/admin/config/system/site-information'); $this->routeProvider @@ -147,6 +161,10 @@ public function testGetBaseRoute() { * Tests ConfigNamesMapper::getBasePath(). */ public function testGetBasePath() { + $this->urlGenerator->expects($this->once()) + ->method('getPathFromRoute') + ->with('system.site_information_settings', []) + ->willReturn('/admin/config/system/site-information'); $result = $this->configNamesMapper->getBasePath(); $this->assertSame('/admin/config/system/site-information', $result); } @@ -189,6 +207,11 @@ public function testGetOverviewRoute() { * Tests ConfigNamesMapper::getOverviewPath(). */ public function testGetOverviewPath() { + $this->urlGenerator->expects($this->once()) + ->method('getPathFromRoute') + ->with('config_translation.item.overview.system.site_information_settings', []) + ->willReturn('/admin/config/system/site-information/translate'); + $result = $this->configNamesMapper->getOverviewPath(); $this->assertSame('/admin/config/system/site-information/translate', $result); } @@ -605,7 +628,7 @@ public function testGetOperations() { $expected = array( 'translate' => array( 'title' => 'Translate', - 'href' => '/admin/config/system/site-information/translate', + 'url' => Url::fromRoute('config_translation.item.overview.system.site_information_settings'), ), ); $result = $this->configNamesMapper->getOperations(); diff --git a/core/modules/content_translation/content_translation.module b/core/modules/content_translation/content_translation.module index 102c67a6ecc225c41e99df7102a59b5eb2621381..4d3c794429b6c1da5dfaf865268cf0bbd22e2a6a 100644 --- a/core/modules/content_translation/content_translation.module +++ b/core/modules/content_translation/content_translation.module @@ -169,7 +169,8 @@ function content_translation_entity_operation_alter(array &$operations, \Drupal\ if ($entity instanceof NodeInterface && $entity->isTranslatable()) { $operations['translate'] = array( 'title' => t('Translate'), - ) + $entity->urlInfo('drupal:content-translation-overview')->toArray(); + 'url' => $entity->urlInfo('drupal:content-translation-overview'), + ); } } diff --git a/core/modules/content_translation/src/Controller/ContentTranslationController.php b/core/modules/content_translation/src/Controller/ContentTranslationController.php index b00a11fff78b0de04cc07df010aad439c9da9a5f..999a509fc0c46989b0d226220d8a30a8f405cd37 100644 --- a/core/modules/content_translation/src/Controller/ContentTranslationController.php +++ b/core/modules/content_translation/src/Controller/ContentTranslationController.php @@ -136,10 +136,11 @@ public function overview(Request $request, $entity_type_id = NULL) { // the entity form, otherwise if we are not dealing with the original // language we point the link to the translation form. if ($entity->access('update')) { - $links['edit'] = $entity->urlInfo('edit-form')->toArray() + ['language' => $language]; + $links['edit']['url'] = $entity->urlInfo('edit-form'); + $links['edit']['language'] = $language; } elseif (!$is_original && $handler->getTranslationAccess($entity, 'update')->isAllowed()) { - $links['edit'] = $edit_url->toArray(); + $links['edit']['url'] = $edit_url; } if (isset($links['edit'])) { @@ -164,7 +165,8 @@ public function overview(Request $request, $entity_type_id = NULL) { if ($handler->getTranslationAccess($entity, 'delete')->isAllowed()) { $links['delete'] = array( 'title' => $this->t('Delete'), - ) + $delete_url->toArray(); + 'url' => $delete_url, + ); } } } @@ -177,7 +179,8 @@ public function overview(Request $request, $entity_type_id = NULL) { if ($translatable) { $links['add'] = array( 'title' => $this->t('Add'), - ) + $add_url->toArray(); + 'url' => $add_url, + ); } elseif ($field_ui) { $url = new Url('language.content_settings_page'); @@ -186,7 +189,8 @@ public function overview(Request $request, $entity_type_id = NULL) { // setting to enable translation on fields. $links['nofields'] = array( 'title' => $this->t('No translatable fields'), - ) + $url->toArray(); + 'url' => $url, + ); } } diff --git a/core/modules/contextual/src/Element/ContextualLinks.php b/core/modules/contextual/src/Element/ContextualLinks.php index 180c01fb07fbb48852e5d09ebcd31081882b0e41..e2037c38e2e31f6956e1983878837ed3aaec7238 100644 --- a/core/modules/contextual/src/Element/ContextualLinks.php +++ b/core/modules/contextual/src/Element/ContextualLinks.php @@ -8,6 +8,7 @@ namespace Drupal\contextual\Element; use Drupal\Core\Render\Element\RenderElement; +use Drupal\Core\Url; /** * Provides a contextual_links element. @@ -81,8 +82,7 @@ public static function preRenderLinks(array $element) { $class = drupal_html_class($class); $links[$class] = array( 'title' => $item['title'], - 'route_name' => isset($item['route_name']) ? $item['route_name'] : '', - 'route_parameters' => isset($item['route_parameters']) ? $item['route_parameters'] : array(), + 'url' => Url::fromRoute(isset($item['route_name']) ? $item['route_name'] : '', isset($item['route_parameters']) ? $item['route_parameters'] : []), ); } $element['#links'] = $links; diff --git a/core/modules/entity_reference/src/Plugin/Field/FieldFormatter/EntityReferenceLabelFormatter.php b/core/modules/entity_reference/src/Plugin/Field/FieldFormatter/EntityReferenceLabelFormatter.php index a64a4c32017589e844fc4b61490395f31eb181c8..61abdb6818f2f6921cb9856f6e58e5fa355ed832 100644 --- a/core/modules/entity_reference/src/Plugin/Field/FieldFormatter/EntityReferenceLabelFormatter.php +++ b/core/modules/entity_reference/src/Plugin/Field/FieldFormatter/EntityReferenceLabelFormatter.php @@ -67,10 +67,12 @@ public function viewElements(FieldItemListInterface $items) { // If the link is to be displayed and the entity has a uri, display a // link. if ($this->getSetting('link') && $uri = $entity->urlInfo()) { - $elements[$delta] = array( + $elements[$delta] = [ '#type' => 'link', '#title' => $label, - ) + $uri->toRenderArray(); + '#url' => $uri, + '#options' => $uri->getOptions(), + ]; if (!empty($items[$delta]->_attributes)) { $elements[$delta]['#options'] += array('attributes' => array()); diff --git a/core/modules/field_ui/field_ui.module b/core/modules/field_ui/field_ui.module index b5f6f6ef2efbf1d44178a986e321651e920c30b0..19a8f8ec74a37495feeb8c35bc89d36edbcc3658 100644 --- a/core/modules/field_ui/field_ui.module +++ b/core/modules/field_ui/field_ui.module @@ -143,19 +143,22 @@ function field_ui_entity_operation(EntityInterface $entity) { $operations['manage-fields'] = array( 'title' => t('Manage fields'), 'weight' => 15, - ) + $entity->urlInfo('field_ui-fields')->toArray(); + 'url' => $entity->urlInfo('field_ui-fields'), + ); } if ($account->hasPermission('administer '. $bundle_of . ' form display')) { $operations['manage-form-display'] = array( 'title' => t('Manage form display'), 'weight' => 20, - ) + $entity->urlInfo('field_ui-form-display')->toArray(); + 'url' => $entity->urlInfo('field_ui-form-display'), + ); } if ($account->hasPermission('administer '. $bundle_of . ' display')) { $operations['manage-display'] = array( 'title' => t('Manage display'), 'weight' => 25, - ) + $entity->urlInfo('field_ui-display')->toArray(); + 'url' => $entity->urlInfo('field_ui-display'), + ); } } diff --git a/core/modules/field_ui/src/DisplayOverview.php b/core/modules/field_ui/src/DisplayOverview.php index 2bc07c15e180d5b5615c9b098b654776b34cb1fb..137449461934078bda65ac6a84f17c38f0351bc4 100644 --- a/core/modules/field_ui/src/DisplayOverview.php +++ b/core/modules/field_ui/src/DisplayOverview.php @@ -17,6 +17,7 @@ use Drupal\Core\Field\FormatterInterface; use Drupal\Core\Field\PluginSettingsInterface; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Url; use Symfony\Component\DependencyInjection\ContainerInterface; /** @@ -206,14 +207,10 @@ protected function getTableHeader() { * {@inheritdoc} */ protected function getOverviewRoute($mode) { - return array( - 'route_name' => 'field_ui.display_overview_view_mode_' . $this->entity_type, - 'route_parameters' => array( - $this->bundleEntityType => $this->bundle, - 'view_mode_name' => $mode, - ), - 'options' => array(), - ); + return Url::fromRoute('field_ui.display_overview_view_mode_' . $this->entity_type, [ + $this->bundleEntityType => $this->bundle, + 'view_mode_name' => $mode, + ]); } /** diff --git a/core/modules/field_ui/src/DisplayOverviewBase.php b/core/modules/field_ui/src/DisplayOverviewBase.php index 94db60a595c7686462e902282d69f612707a20f3..d41c7cb6a712f9440c2dc769d8a11dbb8ee0be22 100644 --- a/core/modules/field_ui/src/DisplayOverviewBase.php +++ b/core/modules/field_ui/src/DisplayOverviewBase.php @@ -595,8 +595,8 @@ public function submitForm(array &$form, FormStateInterface $form_state) { } $display_mode_label = $display_modes[$mode]['label']; - $route = $this->getOverviewRoute($mode); - drupal_set_message($this->t('The %display_mode mode now uses custom display settings. You might want to <a href="@url">configure them</a>.', array('%display_mode' => $display_mode_label, '@url' => $this->url($route['route_name'], $route['route_parameters'], $route['options'])))); + $url = $this->getOverviewRoute($mode); + drupal_set_message($this->t('The %display_mode mode now uses custom display settings. You might want to <a href="@url">configure them</a>.', ['%display_mode' => $display_mode_label, '@url' => $url->toString()])); } $statuses[$mode] = !empty($value); } @@ -872,14 +872,8 @@ abstract protected function getTableHeader(); * @param string $mode * The form or view mode. * - * @return array - * An associative array with the following keys: - * - route_name: The name of the route. - * - route_parameters: (optional) An associative array of parameter names - * and values. - * - options: (optional) An associative array of additional options. See - * \Drupal\Core\Routing\UrlGeneratorInterface::generateFromRoute() for - * comprehensive documentation. + * @return \Drupal\Core\Url + * A Url object for the overview route. */ abstract protected function getOverviewRoute($mode); diff --git a/core/modules/field_ui/src/EntityDisplayModeListBuilder.php b/core/modules/field_ui/src/EntityDisplayModeListBuilder.php index 2a73834dac6b1024c8fe884ed491bae34530239d..6056508ca467e41bf8031215e171098f7cf03715 100644 --- a/core/modules/field_ui/src/EntityDisplayModeListBuilder.php +++ b/core/modules/field_ui/src/EntityDisplayModeListBuilder.php @@ -11,6 +11,7 @@ use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Entity\EntityTypeInterface; +use Drupal\Core\Url; use Symfony\Component\DependencyInjection\ContainerInterface; /** @@ -118,7 +119,7 @@ public function render() { $table['#rows']['_add_new'][] = array( 'data' => array( '#type' => 'link', - '#href' => "admin/structure/display-modes/$short_type/add/$entity_type", + '#url' => Url::fromRoute($short_type == 'view' ? 'field_ui.entity_view_mode_add_type' : 'field_ui.entity_form_mode_add_type', ['entity_type_id' => $entity_type]), '#title' => t('Add new %label @entity-type', array('%label' => $this->entityTypes[$entity_type]->getLabel(), '@entity-type' => $this->entityType->getLowercaseLabel())), '#options' => array( 'html' => TRUE, diff --git a/core/modules/field_ui/src/FieldConfigListBuilder.php b/core/modules/field_ui/src/FieldConfigListBuilder.php index f4f76b59612160032d143a854f2b02f3871bc359..cae4250932ee4ce34917d2c1fed52e97bae5da49 100644 --- a/core/modules/field_ui/src/FieldConfigListBuilder.php +++ b/core/modules/field_ui/src/FieldConfigListBuilder.php @@ -66,7 +66,8 @@ public function getDefaultOperations(EntityInterface $entity) { 'title' => $this->t('Storage settings'), 'weight' => 20, 'attributes' => array('title' => $this->t('Edit storage settings.')), - ) + $entity->urlInfo('storage-edit-form')->toArray(); + 'url' => $entity->urlInfo('storage-edit-form'), + ); $operations['edit']['attributes']['title'] = $this->t('Edit field settings.'); $operations['delete']['attributes']['title'] = $this->t('Delete field.'); diff --git a/core/modules/field_ui/src/FieldOverview.php b/core/modules/field_ui/src/FieldOverview.php index 0e42fcd6f37a1351330354f2516b048882d4307b..838c116ea37a2af6513fd2b046c8152369f73a9c 100644 --- a/core/modules/field_ui/src/FieldOverview.php +++ b/core/modules/field_ui/src/FieldOverview.php @@ -14,6 +14,7 @@ use Drupal\Core\Field\FieldTypePluginManagerInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Render\Element; +use Drupal\Core\Url; use Drupal\field_ui\OverviewBase; use Symfony\Component\DependencyInjection\ContainerInterface; use Drupal\field\Entity\FieldStorageConfig; @@ -135,8 +136,7 @@ public function buildForm(array $form, FormStateInterface $form_state, $entity_t 'type' => array( '#type' => 'link', '#title' => $field_types[$field_storage->getType()]['label'], - '#route_name' => 'field_ui.storage_edit_' . $this->entity_type, - '#route_parameters' => $route_parameters, + '#url' => Url::fromRoute('field_ui.storage_edit_' . $this->entity_type, $route_parameters), '#options' => array('attributes' => array('title' => $this->t('Edit field settings.'))), ), ); diff --git a/core/modules/field_ui/src/FieldUI.php b/core/modules/field_ui/src/FieldUI.php index 7edb1c6d8311e2af2eb2537ac64dababa3323a7d..1658c797a5202433bfa20dffe12ccbf5596e0418 100644 --- a/core/modules/field_ui/src/FieldUI.php +++ b/core/modules/field_ui/src/FieldUI.php @@ -59,6 +59,8 @@ public static function getNextDestination(array $destinations) { $options['query']['destinations'] = $destinations; } // Redirect to any given path within the same domain. + // @todo Use Url::fromPath() once https://www.drupal.org/node/2351379 is + // resolved. $next_destination = Url::fromUri('base://' . $options['path']); } return $next_destination; diff --git a/core/modules/field_ui/src/FormDisplayOverview.php b/core/modules/field_ui/src/FormDisplayOverview.php index aacd42333e0137d7530c7cbceddb9d520f9575f4..c317fd55854faee6ab28130de611fb2c0e4c52b5 100644 --- a/core/modules/field_ui/src/FormDisplayOverview.php +++ b/core/modules/field_ui/src/FormDisplayOverview.php @@ -16,6 +16,7 @@ use Drupal\Core\Field\FieldTypePluginManager; use Drupal\Core\Field\PluginSettingsInterface; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Url; use Symfony\Component\DependencyInjection\ContainerInterface; /** @@ -171,14 +172,10 @@ protected function getTableHeader() { * {@inheritdoc} */ protected function getOverviewRoute($mode) { - return array( - 'route_name' => 'field_ui.form_display_overview_form_mode_' . $this->entity_type, - 'route_parameters' => array( - $this->bundleEntityType => $this->bundle, - 'form_mode_name' => $mode, - ), - 'options' => array(), - ); + return Url::fromRoute('field_ui.form_display_overview_form_mode_' . $this->entity_type, [ + $this->bundleEntityType => $this->bundle, + 'form_mode_name' => $mode, + ]); } /** diff --git a/core/modules/field_ui/src/Tests/ManageFieldsTest.php b/core/modules/field_ui/src/Tests/ManageFieldsTest.php index ff2139541a72d11b85d2f15c7f02c1742d4503c4..2379899165d02e30943b1f93322d10d4c4f8c26b 100644 --- a/core/modules/field_ui/src/Tests/ManageFieldsTest.php +++ b/core/modules/field_ui/src/Tests/ManageFieldsTest.php @@ -106,7 +106,7 @@ function manageFieldsPage($type = '') { $url = base_path() . "admin/structure/types/manage/$type/fields/node.$type.body"; $this->assertIdentical($url, (string) $result[0]['href']); $this->assertIdentical("$url/storage", (string) $result[1]['href']); - $this->assertIdentical("$url/delete", (string) $result[3]['href']); + $this->assertIdentical("$url/delete", (string) $result[2]['href']); } /** diff --git a/core/modules/forum/forum.module b/core/modules/forum/forum.module index 1b15b3e899b3a056d84c4b0d2a7f005fc21a768f..10b7366b9f900e2806295e3a88f9b32e0fa7dfce 100644 --- a/core/modules/forum/forum.module +++ b/core/modules/forum/forum.module @@ -52,8 +52,7 @@ function forum_help($route_name, RouteMatchInterface $route_match) { $output = '<p>' . t('Forums contain forum topics. Use containers to group related forums.') . '</p>'; $more_help_link = array( '#type' => 'link', - '#route_name' => 'help.page', - '#route_parameters' => array('name' => 'forum'), + '#url' => Url::fromRoute('help.page', ['name' => 'forum']), '#title' => t('More help'), ); $container = array( @@ -105,8 +104,6 @@ function forum_theme() { * Implements hook_menu_local_tasks(). */ function forum_menu_local_tasks(&$data, $route_name) { - $user = \Drupal::currentUser(); - // Add action link to 'node/add/forum' on 'forum' sub-pages. if (in_array($route_name, array('forum.index', 'forum.page'))) { $forum_term = \Drupal::routeMatch()->getParameter('taxonomy_term'); @@ -120,7 +117,7 @@ function forum_menu_local_tasks(&$data, $route_name) { '#theme' => 'menu_local_action', '#link' => array( 'title' => t('Add new @node_type', array('@node_type' => entity_load('node_type', $type)->label())), - 'href' => 'node/add/' . $type, + 'url' => Url::fromRoute('node.add', ['node_type' => $type]), ), ); if ($forum_term && $forum_term->bundle() == $vid) { @@ -130,31 +127,9 @@ function forum_menu_local_tasks(&$data, $route_name) { } } } - if (empty($links)) { - // Authenticated user does not have access to create new topics. - if ($user->isAuthenticated()) { - $links['disallowed'] = array( - '#theme' => 'menu_local_action', - '#link' => array( - 'title' => t('You are not allowed to post new content in the forum.'), - ), - ); - } - // Anonymous user does not have access to create new topics. - else { - $links['login'] = array( - '#theme' => 'menu_local_action', - '#link' => array( - 'title' => t('<a href="@login">Log in</a> to post new content in the forum.', array( - '@login' => \Drupal::url('user.login', [], array('query' => drupal_get_destination())), - )), - 'localized_options' => array('html' => TRUE), - ), - ); - } - } $data['actions'] += $links; } + // @todo Bring back functionality in https://www.drupal.org/node/1853072. } /** @@ -186,12 +161,7 @@ function forum_entity_bundle_info_alter(&$bundles) { * Entity URI callback used in forum_entity_bundle_info_alter(). */ function forum_uri($forum) { - return array( - 'route_name' => 'forum.page', - 'route_parameters' => array( - 'taxonomy_term' => $forum->id(), - ), - ); + return Url::fromRoute('forum.page', ['taxonomy_term' => $forum->id()]); } /** diff --git a/core/modules/forum/src/Form/ForumForm.php b/core/modules/forum/src/Form/ForumForm.php index 6a8131a115f889ce7bdd70535a8d68d08f12cfbf..fc51a32eb1b5f3fb03433dbdc14f5a935fb6e669 100644 --- a/core/modules/forum/src/Form/ForumForm.php +++ b/core/modules/forum/src/Form/ForumForm.php @@ -107,10 +107,7 @@ protected function actions(array $form, FormStateInterface $form_state) { $actions = parent::actions($form, $form_state); if (!$this->entity->isNew() && $this->entity->hasLinkTemplate('forum-delete-form')) { - $route_info = $this->entity->urlInfo('forum-delete-form'); - $actions['delete']['#options'] = $route_info->getOptions(); - $actions['delete']['#route_name'] = $route_info->getRouteName(); - $actions['delete']['#route_parameters'] = $route_info->getRouteParameters(); + $actions['delete']['#url'] = $this->entity->urlInfo('forum-delete-form'); } else { unset($actions['delete']); diff --git a/core/modules/forum/src/Form/Overview.php b/core/modules/forum/src/Form/Overview.php index eb05b3ac6df11bb4fb37f748bf377e7d30381a6d..8469f55a521f4c45e211676664cabfc8f3becc1e 100644 --- a/core/modules/forum/src/Form/Overview.php +++ b/core/modules/forum/src/Form/Overview.php @@ -10,6 +10,7 @@ use Drupal\Core\Entity\EntityManagerInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Render\Element; +use Drupal\Core\Url; use Drupal\taxonomy\Form\OverviewTerms; use Drupal\Core\Config\ConfigFactoryInterface; use Drupal\Core\Extension\ModuleHandlerInterface; @@ -65,22 +66,20 @@ public function buildForm(array $form, FormStateInterface $form_state) { foreach (Element::children($form['terms']) as $key) { if (isset($form['terms'][$key]['#term'])) { $term = $form['terms'][$key]['#term']; - $form['terms'][$key]['term']['#href'] = 'forum/' . $term->id(); + $form['terms'][$key]['term']['#url'] = Url::fromRoute('forum.page', ['taxonomy_term' => $term->id()]); unset($form['terms'][$key]['operations']['#links']['delete']); + $route_parameters = $form['terms'][$key]['operations']['#links']['edit']['url']->getRouteParameters(); if (!empty($term->forum_container->value)) { $form['terms'][$key]['operations']['#links']['edit']['title'] = $this->t('edit container'); - $form['terms'][$key]['operations']['#links']['edit']['route_name'] = 'forum.edit_container'; - // We don't want the redirect from the link so we can redirect the - // delete action. - unset($form['terms'][$key]['operations']['#links']['edit']['query']['destination']); + $form['terms'][$key]['operations']['#links']['edit']['url'] = Url::fromRoute('forum.edit_container', $route_parameters); } else { $form['terms'][$key]['operations']['#links']['edit']['title'] = $this->t('edit forum'); - $form['terms'][$key]['operations']['#links']['edit']['route_name'] = 'forum.edit_forum'; - // We don't want the redirect from the link so we can redirect the - // delete action. - unset($form['terms'][$key]['operations']['#links']['edit']['query']['destination']); + $form['terms'][$key]['operations']['#links']['edit']['url'] = Url::fromRoute('forum.edit_forum', $route_parameters); } + // We don't want the redirect from the link so we can redirect the + // delete action. + unset($form['terms'][$key]['operations']['#links']['edit']['query']['destination']); } } diff --git a/core/modules/forum/src/Plugin/Block/ForumBlockBase.php b/core/modules/forum/src/Plugin/Block/ForumBlockBase.php index f480892c53082a8e92b3a0e6bd8102a543806389..17c31470b32d0fb11b932813d6a74354e7bd5483 100644 --- a/core/modules/forum/src/Plugin/Block/ForumBlockBase.php +++ b/core/modules/forum/src/Plugin/Block/ForumBlockBase.php @@ -11,6 +11,7 @@ use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Session\AccountInterface; use Drupal\Core\Cache\Cache; +use Drupal\Core\Url; /** * Provides a base class for Forum blocks. @@ -27,7 +28,7 @@ public function build() { $elements['forum_list'] = $node_title_list; $elements['forum_more'] = array( '#type' => 'more_link', - '#href' => 'forum', + '#url' => Url::fromRoute('forum.index'), '#attributes' => array('title' => $this->t('Read the latest forum topics.')), ); } diff --git a/core/modules/forum/src/Tests/ForumTest.php b/core/modules/forum/src/Tests/ForumTest.php index ebda138ac36f9a1defd39bc668d64ea585ce851a..adbd2a4456df78cc3cf679a276cf8046883af275 100644 --- a/core/modules/forum/src/Tests/ForumTest.php +++ b/core/modules/forum/src/Tests/ForumTest.php @@ -121,7 +121,8 @@ function testForum() { $this->drupalLogin($this->web_user); // Verify that this user is shown a message that they may not post content. $this->drupalGet('forum/' . $this->forum['tid']); - $this->assertText(t('You are not allowed to post new content in the forum'), "Authenticated user without permission to post forum content is shown message in local tasks to that effect."); + // @todo Restore test coverage in https://www.drupal.org/node/1853072. + //$this->assertText(t('You are not allowed to post new content in the forum'), "Authenticated user without permission to post forum content is shown message in local tasks to that effect."); // Log in, and do basic tests for a user with permission to edit any forum diff --git a/core/modules/help/src/Controller/HelpController.php b/core/modules/help/src/Controller/HelpController.php index 80ae8f44565c85976b02d5335521bf3159b68cf0..2de0a53905c5c741d9cc53a83b17ecce6c4a9151 100644 --- a/core/modules/help/src/Controller/HelpController.php +++ b/core/modules/help/src/Controller/HelpController.php @@ -126,7 +126,7 @@ public function helpPage($name) { if (!empty($admin_tasks)) { $links = array(); foreach ($admin_tasks as $task) { - $link = $task['url']->toArray(); + $link['url'] = $task['url']; $link['title'] = $task['title']; $links[] = $link; } diff --git a/core/modules/image/src/Form/ImageEffectFormBase.php b/core/modules/image/src/Form/ImageEffectFormBase.php index 52d5b2c505ebccfe9de449a3e3c4f2d04ec233c8..addbcf6451e168f65967af270f7ea61a65739346 100644 --- a/core/modules/image/src/Form/ImageEffectFormBase.php +++ b/core/modules/image/src/Form/ImageEffectFormBase.php @@ -96,7 +96,8 @@ public function buildForm(array $form, FormStateInterface $form_state, ImageStyl $form['actions']['cancel'] = array( '#type' => 'link', '#title' => $this->t('Cancel'), - ) + $this->imageStyle->urlInfo('edit-form')->toRenderArray(); + '#url' => $this->imageStyle->urlInfo('edit-form'), + ); return $form; } diff --git a/core/modules/image/src/Form/ImageStyleEditForm.php b/core/modules/image/src/Form/ImageStyleEditForm.php index 8703ee6aa8209b0c96700bd82460600379c43004..4edd31c79457f0d40b7060a952dbd7d5324186cd 100644 --- a/core/modules/image/src/Form/ImageStyleEditForm.php +++ b/core/modules/image/src/Form/ImageStyleEditForm.php @@ -10,6 +10,7 @@ use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Url; use Drupal\image\ConfigurableImageEffectInterface; use Drupal\image\ImageEffectManager; use Drupal\Component\Utility\String; @@ -126,12 +127,18 @@ public function form(array $form, FormStateInterface $form_state) { if ($is_configurable) { $links['edit'] = array( 'title' => $this->t('Edit'), - 'href' => 'admin/config/media/image-styles/manage/' . $this->entity->id() . '/effects/' . $key, + 'url' => Url::fromRoute('image.effect_edit_form', [ + 'image_style' => $this->entity->id(), + 'image_effect' => $key, + ]), ); } $links['delete'] = array( 'title' => $this->t('Delete'), - 'href' => 'admin/config/media/image-styles/manage/' . $this->entity->id() . '/effects/' . $key . '/delete', + 'url' => Url::fromRoute('image.effect_delete', [ + 'image_style' => $this->entity->id(), + 'image_effect' => $key, + ]), ); $form['effects'][$key]['operations'] = array( '#type' => 'operations', diff --git a/core/modules/image/src/ImageStyleListBuilder.php b/core/modules/image/src/ImageStyleListBuilder.php index 73dfe6c80eabd82b1ec555d5d469ed932ed59ee7..b0ad2275714c9e2c2ab3a40b5240d91a48ad1e7e 100644 --- a/core/modules/image/src/ImageStyleListBuilder.php +++ b/core/modules/image/src/ImageStyleListBuilder.php @@ -78,7 +78,8 @@ public function getDefaultOperations(EntityInterface $entity) { $flush = array( 'title' => t('Flush'), 'weight' => 200, - ) + $entity->urlInfo('flush-form')->toArray(); + 'url' => $entity->urlInfo('flush-form'), + ); return parent::getDefaultOperations($entity) + array( 'flush' => $flush, diff --git a/core/modules/language/language.admin.inc b/core/modules/language/language.admin.inc index d5e5b7f7306d0e80b9a547c4a63fdc3e73800854..d7a041514c237e8479a9ad68c338ef0d3d095ea4 100644 --- a/core/modules/language/language.admin.inc +++ b/core/modules/language/language.admin.inc @@ -8,6 +8,7 @@ use Drupal\Component\Utility\String; use Drupal\Core\Render\Element; use Drupal\Core\Template\Attribute; +use Drupal\Core\Url; /** * Prepares variables for language negotiation configuration form. @@ -113,7 +114,7 @@ function theme_language_negotiation_configure_browser_form_table($variables) { $links = array(); $links['delete'] = array( 'title' => t('Delete'), - 'href' => "admin/config/regional/language/detection/browser/delete/$key", + 'url' => Url::fromRoute('language.negotiation_browser_delete', ['browser_langcode' => $key]), 'attributes' => array( 'class' => array('image-style-link'), ), diff --git a/core/modules/language/src/ConfigurableLanguageManager.php b/core/modules/language/src/ConfigurableLanguageManager.php index dbb68d21bbc53434ae6b1458db5ed843c8fbf81f..15c40ae95041bbc75e13a6aeda09cdc78bd914d1 100644 --- a/core/modules/language/src/ConfigurableLanguageManager.php +++ b/core/modules/language/src/ConfigurableLanguageManager.php @@ -14,6 +14,7 @@ use Drupal\Core\Language\Language; use Drupal\Core\Language\LanguageDefault; use Drupal\Core\Language\LanguageManager; +use Drupal\Core\Url; use Drupal\language\Config\LanguageConfigFactoryOverrideInterface; use Drupal\language\Entity\ConfigurableLanguage; use Symfony\Component\HttpFoundation\Request; @@ -395,7 +396,7 @@ public function getFallbackCandidates(array $context = array()) { /** * {@inheritdoc} */ - public function getLanguageSwitchLinks($type, $path) { + public function getLanguageSwitchLinks($type, Url $url) { $links = FALSE; if ($this->negotiator) { @@ -403,7 +404,7 @@ public function getLanguageSwitchLinks($type, $path) { $reflector = new \ReflectionClass($method['class']); if ($reflector->implementsInterface('\Drupal\language\LanguageSwitcherInterface')) { - $result = $this->negotiator->getNegotiationMethodInstance($method_id)->getLanguageSwitchLinks($this->requestStack->getCurrentRequest(), $type, $path); + $result = $this->negotiator->getNegotiationMethodInstance($method_id)->getLanguageSwitchLinks($this->requestStack->getCurrentRequest(), $type, $url); if (!empty($result)) { // Allow modules to provide translations for specific links. diff --git a/core/modules/language/src/Form/NegotiationConfigureForm.php b/core/modules/language/src/Form/NegotiationConfigureForm.php index 83eb5670ebcf9d2096183fc10ec2a8dc1c5978bc..c7495e9bf8a20a9af0583895f9154847f0719589 100644 --- a/core/modules/language/src/Form/NegotiationConfigureForm.php +++ b/core/modules/language/src/Form/NegotiationConfigureForm.php @@ -16,6 +16,7 @@ use Drupal\Core\Extension\ThemeHandlerInterface; use Drupal\Core\Form\FormBase; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Url; use Drupal\language\ConfigurableLanguageManagerInterface; use Drupal\language\LanguageNegotiatorInterface; use Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationSelected; @@ -295,10 +296,10 @@ protected function configureFormTable(array &$form, $type) { $table_form['description'][$method_id] = array('#markup' => Xss::filterAdmin($method['description'])); $config_op = array(); - if (isset($method['config_path'])) { + if (isset($method['config_route_name'])) { $config_op['configure'] = array( 'title' => $this->t('Configure'), - 'href' => $method['config_path'], + 'url' => Url::fromRoute($method['config_route_name']), ); // If there is at least one operation enabled show the operation // column. diff --git a/core/modules/language/src/LanguageSwitcherInterface.php b/core/modules/language/src/LanguageSwitcherInterface.php index d6edd5b2e6c3b67be417c21ea5cfa8466db8f53f..0550dd47f6acc379c3584fdea10854f8f4cb08ec 100644 --- a/core/modules/language/src/LanguageSwitcherInterface.php +++ b/core/modules/language/src/LanguageSwitcherInterface.php @@ -7,6 +7,7 @@ namespace Drupal\language; +use Drupal\Core\Url; use Symfony\Component\HttpFoundation\Request; /** @@ -21,12 +22,12 @@ interface LanguageSwitcherInterface { * The current request. * @param string $type * The language type. - * @param string $path - * The path links should point to. + * @param \Drupal\Core\Url $url + * The URL the switch links will be relative to. * * @return array * An array of link arrays keyed by language code. */ - public function getLanguageSwitchLinks(Request $request, $type, $path); + public function getLanguageSwitchLinks(Request $request, $type, Url $url); } diff --git a/core/modules/language/src/Plugin/Block/LanguageBlock.php b/core/modules/language/src/Plugin/Block/LanguageBlock.php index a3aba84ef2c1e30ea077ff016b48534658ea9c7f..0502d2d610cc19165e5c7c3b03ba89f81679ea95 100644 --- a/core/modules/language/src/Plugin/Block/LanguageBlock.php +++ b/core/modules/language/src/Plugin/Block/LanguageBlock.php @@ -11,6 +11,7 @@ use Drupal\Core\Session\AccountInterface; use Drupal\Core\Language\LanguageManagerInterface; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; +use Drupal\Core\Url; use Symfony\Component\DependencyInjection\ContainerInterface; /** @@ -75,9 +76,9 @@ protected function blockAccess(AccountInterface $account) { */ public function build() { $build = array(); - $path = drupal_is_front_page() ? '<front>' : current_path(); + $route_name = drupal_is_front_page() ? '<front>' : '<current>'; $type = $this->getDerivativeId(); - $links = $this->languageManager->getLanguageSwitchLinks($type, $path); + $links = $this->languageManager->getLanguageSwitchLinks($type, Url::fromRoute($route_name)); if (isset($links->links)) { $build = array( diff --git a/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationBrowser.php b/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationBrowser.php index 0ce2c86c69457b3e7b8f3d0b6cd300de0261725b..e9fc38e00e8eee69e440a911c8c19a61cd9d6bea 100644 --- a/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationBrowser.php +++ b/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationBrowser.php @@ -20,7 +20,7 @@ * cache = 0, * name = @Translation("Browser"), * description = @Translation("Language from the browser's language settings."), - * config_path = "admin/config/regional/language/detection/browser" + * config_route_name = "language.negotiation_browser" * ) */ class LanguageNegotiationBrowser extends LanguageNegotiationMethodBase { diff --git a/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationSelected.php b/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationSelected.php index 4819abfd865016913800528fc3856d6aaac610f2..c4cd150b3b413de31a3b5231756be2a3182a2eea 100644 --- a/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationSelected.php +++ b/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationSelected.php @@ -18,7 +18,7 @@ * weight = 12, * name = @Translation("Selected language"), * description = @Translation("Language based on a selected language."), - * config_path = "admin/config/regional/language/detection/selected" + * config_route_name = "language.negotiation_selected" * ) */ class LanguageNegotiationSelected extends LanguageNegotiationMethodBase { diff --git a/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationSession.php b/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationSession.php index dc5617d20bf59aafb8230ff749857c1eba8abe67..7f0085d93172133fa2e45ede54c877f89ca6458e 100644 --- a/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationSession.php +++ b/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationSession.php @@ -9,6 +9,7 @@ use Drupal\Core\Language\LanguageInterface; use Drupal\Core\PathProcessor\OutboundPathProcessorInterface; +use Drupal\Core\Url; use Drupal\language\LanguageNegotiationMethodBase; use Drupal\language\LanguageSwitcherInterface; use Symfony\Component\HttpFoundation\Request; @@ -21,7 +22,7 @@ * weight = -6, * name = @Translation("Session"), * description = @Translation("Language from a request/session parameter."), - * config_path = "admin/config/regional/language/detection/session" + * config_route_name = "language.negotiation_session" * ) */ class LanguageNegotiationSession extends LanguageNegotiationMethodBase implements OutboundPathProcessorInterface, LanguageSwitcherInterface { @@ -121,7 +122,7 @@ public function processOutbound($path, &$options = array(), Request $request = N /** * {@inheritdoc} */ - function getLanguageSwitchLinks(Request $request, $type, $path) { + public function getLanguageSwitchLinks(Request $request, $type, Url $url) { $links = array(); $config = $this->config->get('language.negotiation')->get('session'); $param = $config['parameter']; @@ -132,7 +133,7 @@ function getLanguageSwitchLinks(Request $request, $type, $path) { foreach ($this->languageManager->getNativeLanguages() as $language) { $langcode = $language->id; $links[$langcode] = array( - 'href' => $path, + 'url' => $url, 'title' => $language->getName(), 'attributes' => array('class' => array('language-link')), 'query' => $query, diff --git a/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationUrl.php b/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationUrl.php index be9f91561b9820f3a4b12cc74203c39bf8f3a78b..0b46727008ddc5c666b825e7bbe2d24800872e08 100644 --- a/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationUrl.php +++ b/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationUrl.php @@ -10,6 +10,7 @@ use Drupal\Core\Language\LanguageInterface; use Drupal\Core\PathProcessor\InboundPathProcessorInterface; use Drupal\Core\PathProcessor\OutboundPathProcessorInterface; +use Drupal\Core\Url; use Drupal\language\LanguageNegotiationMethodBase; use Drupal\language\LanguageSwitcherInterface; use Symfony\Component\HttpFoundation\Request; @@ -25,7 +26,7 @@ * weight = -8, * name = @Translation("URL"), * description = @Translation("Language from the URL (Path prefix or domain)."), - * config_path = "admin/config/regional/language/detection/url" + * config_route_name = "language.negotiation_url" * ) */ class LanguageNegotiationUrl extends LanguageNegotiationMethodBase implements InboundPathProcessorInterface, OutboundPathProcessorInterface, LanguageSwitcherInterface { @@ -187,12 +188,12 @@ public function processOutbound($path, &$options = array(), Request $request = N /** * {@inheritdoc} */ - function getLanguageSwitchLinks(Request $request, $type, $path) { + public function getLanguageSwitchLinks(Request $request, $type, Url $url) { $links = array(); foreach ($this->languageManager->getNativeLanguages() as $language) { $links[$language->id] = array( - 'href' => $path, + 'url' => $url, 'title' => $language->getName(), 'language' => $language, 'attributes' => array('class' => array('language-link')), diff --git a/core/modules/language/tests/language_test/src/Controller/LanguageTestController.php b/core/modules/language/tests/language_test/src/Controller/LanguageTestController.php index a5cb033a3bec00ca463b3e15bcc7fefe2d580401..6766d4a7634c688b9e40e3f86adf107f92877a5f 100644 --- a/core/modules/language/tests/language_test/src/Controller/LanguageTestController.php +++ b/core/modules/language/tests/language_test/src/Controller/LanguageTestController.php @@ -9,6 +9,7 @@ use Drupal\Core\DependencyInjection\ContainerInjectionInterface; use Drupal\Core\Language\LanguageManagerInterface; +use Drupal\Core\Url; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\HttpKernelInterface; @@ -62,7 +63,7 @@ public function typeLinkActiveClass() { 'no_language' => array( '#type' => 'link', '#title' => t('Link to the current path with no langcode provided.'), - '#route_name' => '<current>', + '#url' => Url::fromRoute('<current>'), '#options' => array( 'attributes' => array( 'id' => 'no_lang_link', @@ -73,7 +74,7 @@ public function typeLinkActiveClass() { 'fr' => array( '#type' => 'link', '#title' => t('Link to a French version of the current path.'), - '#route_name' => '<current>', + '#url' => Url::fromRoute('<current>'), '#options' => array( 'language' => $languages['fr'], 'attributes' => array( @@ -85,7 +86,7 @@ public function typeLinkActiveClass() { 'en' => array( '#type' => 'link', '#title' => t('Link to an English version of the current path.'), - '#route_name' => '<current>', + '#url' => Url::fromRoute('<current>'), '#options' => array( 'language' => $languages['en'], 'attributes' => array( diff --git a/core/modules/link/src/Plugin/Field/FieldFormatter/LinkFormatter.php b/core/modules/link/src/Plugin/Field/FieldFormatter/LinkFormatter.php index ca753f8827b09d2e5b5f28fbf68e2c376a807bd5..3aabb67a10e8a96a343fc3364038a6a5664ccbf1 100644 --- a/core/modules/link/src/Plugin/Field/FieldFormatter/LinkFormatter.php +++ b/core/modules/link/src/Plugin/Field/FieldFormatter/LinkFormatter.php @@ -163,13 +163,7 @@ public function viewElements(FieldItemListInterface $items) { '#title' => $link_title, '#options' => $url->getOptions(), ); - if ($url->isExternal()) { - $element[$delta]['#href'] = $url->getUri(); - } - else { - $element[$delta]['#route_name'] = $url->getRouteName(); - $element[$delta]['#route_parameters'] = $url->getRouteParameters(); - } + $element[$delta]['#url'] = $url; if (!empty($item->_attributes)) { $element[$delta]['#options'] += array ('attributes' => array()); diff --git a/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php b/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php index 21e078f12bac69362f7fbc7e20951f0a206ea175..e0666d90d30529591a53f81eef0afc4dfa108a9e 100644 --- a/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php +++ b/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php @@ -205,6 +205,8 @@ public function massageFormValues(array $values, array $form, FormStateInterface return $values; } + // @todo Don't use the toArray method here. Removed once it is + // deprecated. $value += $url->toArray(); // Reset the URL value to contain only the path. diff --git a/core/modules/menu_link_content/src/Plugin/Menu/MenuLinkContent.php b/core/modules/menu_link_content/src/Plugin/Menu/MenuLinkContent.php index ea47019859ada0d15ffe211a6916e86d90cb7a13..8e3433bc0e1b7c3e05adb06dd2d7f23b6468dcba 100644 --- a/core/modules/menu_link_content/src/Plugin/Menu/MenuLinkContent.php +++ b/core/modules/menu_link_content/src/Plugin/Menu/MenuLinkContent.php @@ -180,31 +180,21 @@ public function getDescription() { * {@inheritdoc} */ public function getDeleteRoute() { - return array( - 'route_name' => 'entity.menu_link_content.delete_form', - 'route_parameters' => array('menu_link_content' => $this->getEntity()->id()), - ); + return $this->getEntity()->urlInfo('delete-form'); } /** * {@inheritdoc} */ public function getEditRoute() { - return array( - 'route_name' => 'entity.menu_link_content.canonical', - 'route_parameters' => array('menu_link_content' => $this->getEntity()->id()), - ); + return $this->getEntity()->urlInfo(); } /** * {@inheritdoc} */ public function getTranslateRoute() { - $entity_type = 'menu_link_content'; - return array( - 'route_name' => 'content_translation.translation_overview_' . $entity_type, - 'route_parameters' => array( $entity_type => $this->getEntity()->id()), - ); + return $this->getEntity()->urlInfo('drupal:content-translation-overview'); } /** diff --git a/core/modules/menu_ui/src/MenuForm.php b/core/modules/menu_ui/src/MenuForm.php index 720aa2b2908028a36d91f87109824d6f02ad3f1e..d0b904edfe53d289de012ccb8e9ea081b3ed613d 100644 --- a/core/modules/menu_ui/src/MenuForm.php +++ b/core/modules/menu_ui/src/MenuForm.php @@ -18,6 +18,7 @@ use Drupal\Core\Menu\MenuTreeParameters; use Drupal\Core\Render\Element; use Drupal\Core\Routing\UrlGeneratorTrait; +use Drupal\Core\Url; use Drupal\Core\Utility\LinkGeneratorInterface; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -306,23 +307,21 @@ protected function buildOverviewTreeForm($tree, $delta) { // Allow for a custom edit link per plugin. $edit_route = $link->getEditRoute(); if ($edit_route) { - $operations['edit'] += $edit_route; + $operations['edit']['url'] = $edit_route; // Bring the user back to the menu overview. $operations['edit']['query']['destination'] = $this->entity->url(); } else { // Fall back to the standard edit link. $operations['edit'] += array( - 'route_name' => 'menu_ui.link_edit', - 'route_parameters' => array('menu_link_plugin' => $link->getPluginId()), + 'url' => Url::fromRoute('menu_ui.link_edit', ['menu_link_plugin' => $link->getPluginId()]), ); } // Links can either be reset or deleted, not both. if ($link->isResettable()) { $operations['reset'] = array( 'title' => $this->t('Reset'), - 'route_name' => 'menu_ui.link_reset', - 'route_parameters' => array('menu_link_plugin' => $link->getPluginId()), + 'url' => Url::fromRoute('menu_ui.link_reset', ['menu_link_plugin' => $link->getPluginId()]), ); } elseif ($delete_link = $link->getDeleteRoute()) { @@ -333,7 +332,8 @@ protected function buildOverviewTreeForm($tree, $delta) { if ($link->isTranslatable()) { $operations['translate'] = array( 'title' => $this->t('Translate'), - ) + (array) $link->getTranslateRoute(); + 'url' => $link->getTranslateRoute(), + ); } $form[$id]['operations'] = array( '#type' => 'operations', diff --git a/core/modules/menu_ui/src/MenuListBuilder.php b/core/modules/menu_ui/src/MenuListBuilder.php index 4fdb29841c8cd538cd7e03ec823149a2dd17d654..7e987f1e0a23f4e6babd77e815ac0f4c15e5b2dd 100644 --- a/core/modules/menu_ui/src/MenuListBuilder.php +++ b/core/modules/menu_ui/src/MenuListBuilder.php @@ -54,7 +54,8 @@ public function getDefaultOperations(EntityInterface $entity) { $operations['add'] = array( 'title' => t('Add link'), 'weight' => 20, - ) + $entity->urlInfo('add-link-form')->toArray(); + 'url' => $entity->urlInfo('add-link-form'), + ); } if (isset($operations['delete'])) { $operations['delete']['title'] = t('Delete menu'); diff --git a/core/modules/node/src/Controller/NodeController.php b/core/modules/node/src/Controller/NodeController.php index 64fc4f6ce65cb749d67cad9f2e92b0ba6704367f..33c5989751bbcfab704ed97c904c26eca6ac86c5 100644 --- a/core/modules/node/src/Controller/NodeController.php +++ b/core/modules/node/src/Controller/NodeController.php @@ -184,16 +184,14 @@ public function revisionOverview(NodeInterface $node) { if ($revert_permission) { $links['revert'] = array( 'title' => $this->t('Revert'), - 'route_name' => 'node.revision_revert_confirm', - 'route_parameters' => array('node' => $node->id(), 'node_revision' => $vid), + 'url' => Url::fromRoute('node.revision_revert_confirm', ['node' => $node->id(), 'node_revision' => $vid]), ); } if ($delete_permission) { $links['delete'] = array( 'title' => $this->t('Delete'), - 'route_name' => 'node.revision_delete_confirm', - 'route_parameters' => array('node' => $node->id(), 'node_revision' => $vid), + 'url' => Url::fromRoute('node.revision_delete_confirm', ['node' => $node->id(), 'node_revision' => $vid]), ); } diff --git a/core/modules/node/src/Form/NodePreviewForm.php b/core/modules/node/src/Form/NodePreviewForm.php index 81fd61c206e6732c6b52b347ac378bff54ffbed7..52f0267d3000cd962005cf8ed3a5e0c54c4223e2 100644 --- a/core/modules/node/src/Form/NodePreviewForm.php +++ b/core/modules/node/src/Form/NodePreviewForm.php @@ -13,6 +13,7 @@ use Drupal\Core\Entity\EntityManagerInterface; use Drupal\Core\Form\FormBase; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Url; use Symfony\Component\DependencyInjection\ContainerInterface; /** @@ -81,7 +82,7 @@ public function buildForm(array $form, FormStateInterface $form_state, EntityInt $form['backlink'] = array( '#type' => 'link', '#title' => $this->t('Back to content editing'), - '#href' => $node->isNew() ? 'node/add/' . $node->bundle() : 'node/' . $node->id() . '/edit', + '#url' => $node->isNew() ? Url::fromRoute('node.add', ['node_type' => $node->bundle()]) : $node->urlInfo('edit-form'), '#options' => array('attributes' => array('class' => array('node-preview-backlink'))) + $query_options, ); diff --git a/core/modules/node/src/NodeListBuilder.php b/core/modules/node/src/NodeListBuilder.php index c78915d66660e399b10952045f1360d19ff1fba9..606da79b6a1ed1f2153824411d8eecfe8fbe86cd 100644 --- a/core/modules/node/src/NodeListBuilder.php +++ b/core/modules/node/src/NodeListBuilder.php @@ -105,7 +105,8 @@ public function buildRow(EntityInterface $entity) { '#type' => 'link', '#title' => $entity->label(), '#suffix' => ' ' . drupal_render($mark), - ) + $uri->toRenderArray(); + '#url' => $uri, + ); $row['type'] = String::checkPlain(node_get_type_label($entity)); $row['author']['data'] = array( '#theme' => 'username', diff --git a/core/modules/node/src/NodeViewBuilder.php b/core/modules/node/src/NodeViewBuilder.php index 8cf1c040f4349a5bbaaef4a565f5aca8f847b8e4..11364282e0eaacfa1a82442cdbe5e3af464aea9c 100644 --- a/core/modules/node/src/NodeViewBuilder.php +++ b/core/modules/node/src/NodeViewBuilder.php @@ -146,7 +146,7 @@ protected static function buildLinks(NodeInterface $entity, $view_mode) { 'title' => t('Read more<span class="visually-hidden"> about @title</span>', array( '@title' => $node_title_stripped, )), - 'href' => 'node/' . $entity->id(), + 'url' => $entity->urlInfo(), 'language' => $entity->language(), 'html' => TRUE, 'attributes' => array( diff --git a/core/modules/node/src/Plugin/views/area/ListingEmpty.php b/core/modules/node/src/Plugin/views/area/ListingEmpty.php index cba41c288c7f1ec9322fef70e991bdf65e5b922a..8804f2e9a708be4ecdc4aab61e90938757e83d57 100644 --- a/core/modules/node/src/Plugin/views/area/ListingEmpty.php +++ b/core/modules/node/src/Plugin/views/area/ListingEmpty.php @@ -8,6 +8,7 @@ namespace Drupal\node\Plugin\views\area; use Drupal\Core\Access\AccessManagerInterface; +use Drupal\Core\Url; use Drupal\views\Plugin\views\area\AreaPluginBase; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -67,7 +68,7 @@ public function render($empty = FALSE) { '#theme' => 'links', '#links' => array( array( - 'href' => 'node/add', + 'url' => Url::fromRoute('node.add_page'), 'title' => $this->t('Add content'), ), ), diff --git a/core/modules/path/src/Controller/PathController.php b/core/modules/path/src/Controller/PathController.php index 96dd34b7bdc49d1a9fd4992a91adbf1903cb4836..5f6f3c6bf9d6e07b8c636b88697d356a2f95ff9a 100644 --- a/core/modules/path/src/Controller/PathController.php +++ b/core/modules/path/src/Controller/PathController.php @@ -10,6 +10,7 @@ use Drupal\Core\Controller\ControllerBase; use Drupal\Core\Path\AliasStorageInterface; use Drupal\Core\Path\AliasManagerInterface; +use Drupal\Core\Url; use Symfony\Component\DependencyInjection\ContainerInterface; /** @@ -87,19 +88,11 @@ public function adminOverview($keys) { $operations = array(); $operations['edit'] = array( 'title' => $this->t('Edit'), - 'route_name' => 'path.admin_edit', - 'route_parameters' => array( - 'pid' => $data->pid, - ), - 'query' => $destination, + 'url' => Url::fromRoute('path.admin_edit', ['pid' => $data->pid], ['query' => $destination]), ); $operations['delete'] = array( 'title' => $this->t('Delete'), - 'route_name' => 'path.delete', - 'route_parameters' => array( - 'pid' => $data->pid, - ), - 'query' => $destination, + 'url' => Url::fromRoute('path.delete', ['pid' => $data->pid], ['query' => $destination]), ); $row['data']['operations'] = array( 'data' => array( diff --git a/core/modules/responsive_image/src/ResponsiveImageMappingListBuilder.php b/core/modules/responsive_image/src/ResponsiveImageMappingListBuilder.php index b12fb61f8eee9310d828288c940146736eb6aa17..6032b7c12d53c92409adc43666a03d83cb72c1c4 100644 --- a/core/modules/responsive_image/src/ResponsiveImageMappingListBuilder.php +++ b/core/modules/responsive_image/src/ResponsiveImageMappingListBuilder.php @@ -41,7 +41,8 @@ public function getDefaultOperations(EntityInterface $entity) { $operations['duplicate'] = array( 'title' => t('Duplicate'), 'weight' => 15, - ) + $entity->urlInfo('duplicate-form')->toArray(); + 'url' => $entity->urlInfo('duplicate-form'), + ); return $operations; } diff --git a/core/modules/search/src/SearchPageListBuilder.php b/core/modules/search/src/SearchPageListBuilder.php index 5714f0a3545b6a63ea7ec493647bd5347b97d1eb..93b87ef3f3ca5d1d2eb1442818fa54e89efb7800 100644 --- a/core/modules/search/src/SearchPageListBuilder.php +++ b/core/modules/search/src/SearchPageListBuilder.php @@ -14,6 +14,7 @@ use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Form\FormInterface; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Url; use Symfony\Component\DependencyInjection\ContainerInterface; /** @@ -118,7 +119,7 @@ public function buildRow(EntityInterface $entity) { $row['url'] = array( '#type' => 'link', '#title' => $row['url'], - '#route_name' => 'search.view_' . $entity->id(), + '#url' => Url::fromRoute('search.view_' . $entity->id()), ); } @@ -305,10 +306,9 @@ public function getDefaultOperations(EntityInterface $entity) { else { $operations['default'] = array( 'title' => $this->t('Set as default'), - 'route_name' => 'entity.search_page.set_default', - 'route_parameters' => array( + 'url' => Url::fromRoute('entity.search_page.set_default', [ 'search_page' => $entity->id(), - ), + ]), 'weight' => 50, ); } diff --git a/core/modules/shortcut/shortcut.module b/core/modules/shortcut/shortcut.module index 2575128894ac2a7fef492d5b933fa50f27e5391e..f21d00fa9365d2ef0eebaed3ed8aa8753bf2611f 100644 --- a/core/modules/shortcut/shortcut.module +++ b/core/modules/shortcut/shortcut.module @@ -258,7 +258,7 @@ function shortcut_renderable_links($shortcut_set = NULL) { $shortcut = \Drupal::entityManager()->getTranslationFromContext($shortcut); $links[] = array( 'title' => $shortcut->label(), - 'href' => $shortcut->path->value, + 'url' => Url::fromRoute($shortcut->getRouteName(), $shortcut->getRouteParams()), ); $cache_tags = Cache::mergeTags($cache_tags, $shortcut->getCacheTag()); } @@ -343,8 +343,7 @@ function shortcut_preprocess_page(&$variables) { '#prefix' => '<div class="add-or-remove-shortcuts ' . $link_mode . '-shortcut">', '#type' => 'link', '#title' => '<span class="icon"></span><span class="text">'. $link_text .'</span>', - '#route_name' => $route_name, - '#route_parameters' => $route_parameters, + '#url' => Url::fromRoute($route_name, $route_parameters), '#options' => array('query' => $query, 'html' => TRUE), '#suffix' => '</div>', ); @@ -367,8 +366,7 @@ function shortcut_toolbar() { $configure_link = array( '#type' => 'link', '#title' => t('Edit shortcuts'), - '#route_name' => 'entity.shortcut_set.customize_form', - '#route_parameters' => array('shortcut_set' => $shortcut_set->id()), + '#url' => Url::fromRoute('entity.shortcut_set.customize_form', ['shortcut_set' => $shortcut_set->id()]), '#options' => array('attributes' => array('class' => array('edit-shortcuts'))), ); } @@ -378,7 +376,7 @@ function shortcut_toolbar() { 'tab' => array( '#type' => 'link', '#title' => t('Shortcuts'), - '#href' => 'admin/config/user-interface/shortcut', + '#url' => Url::fromRoute('shortcut.set_admin'), '#attributes' => array( 'title' => t('Shortcuts'), 'class' => array('toolbar-icon', 'toolbar-icon-shortcut'), diff --git a/core/modules/shortcut/src/Entity/Shortcut.php b/core/modules/shortcut/src/Entity/Shortcut.php index 75d5b2283d51a45cb6e9ec1c9017a607c944e325..9734109fcd368cbdfb74fefcd1f5e911bdb9933f 100644 --- a/core/modules/shortcut/src/Entity/Shortcut.php +++ b/core/modules/shortcut/src/Entity/Shortcut.php @@ -115,7 +115,7 @@ public function getRouteParams() { * {@inheritdoc} */ public function setRouteParams($route_parameters) { - $this->set('route_parameters', array($route_parameters)); + $this->set('route_parameters', $route_parameters); return $this; } diff --git a/core/modules/shortcut/src/Form/SetCustomize.php b/core/modules/shortcut/src/Form/SetCustomize.php index e778d8c769e15d7b76a0220ed5cfcdc3d03a027e..2d026b560963d27a2b2013a93d382e5f34193931 100644 --- a/core/modules/shortcut/src/Form/SetCustomize.php +++ b/core/modules/shortcut/src/Form/SetCustomize.php @@ -64,11 +64,11 @@ public function form(array $form, FormStateInterface $form_state) { $links['edit'] = array( 'title' => t('Edit'), - 'href' => "admin/config/user-interface/shortcut/link/$id", + 'url' => $shortcut->urlInfo(), ); $links['delete'] = array( 'title' => t('Delete'), - 'href' => "admin/config/user-interface/shortcut/link/$id/delete", + 'url' => $shortcut->urlInfo('delete-form'), ); $form['shortcuts']['links'][$id]['operations'] = array( '#type' => 'operations', diff --git a/core/modules/shortcut/src/ShortcutSetListBuilder.php b/core/modules/shortcut/src/ShortcutSetListBuilder.php index 907f470c65f0de89919925e7143167d1db7de237..9de658d668f5f8673d748317d99986fa10e6921f 100644 --- a/core/modules/shortcut/src/ShortcutSetListBuilder.php +++ b/core/modules/shortcut/src/ShortcutSetListBuilder.php @@ -37,7 +37,8 @@ public function getDefaultOperations(EntityInterface $entity) { $operations['list'] = array( 'title' => t('List links'), - ) + $entity->urlInfo('customize-form')->toArray(); + 'url' => $entity->urlInfo('customize-form'), + ); return $operations; } diff --git a/core/modules/simpletest/src/AssertContentTrait.php b/core/modules/simpletest/src/AssertContentTrait.php index 7c28b042c562196b639889cf5caebe884c9b2a45..0836987bf0b08274447bc8000cb3d248b3ed9f5f 100644 --- a/core/modules/simpletest/src/AssertContentTrait.php +++ b/core/modules/simpletest/src/AssertContentTrait.php @@ -742,8 +742,8 @@ protected function assertNoTitle($title, $message = '', $group = 'Other') { */ protected function assertThemeOutput($callback, array $variables = array(), $expected = '', $message = '', $group = 'Other') { $output = \Drupal::theme()->render($callback, $variables); - $this->verbose('Variables:' . '<pre>' . String::checkPlain(var_export($variables, TRUE)) . '</pre>' - . '<hr />' . 'Result:' . '<pre>' . String::checkPlain(var_export($output, TRUE)) . '</pre>' + $this->verbose( + '<hr />' . 'Result:' . '<pre>' . String::checkPlain(var_export($output, TRUE)) . '</pre>' . '<hr />' . 'Expected:' . '<pre>' . String::checkPlain(var_export($expected, TRUE)) . '</pre>' . '<hr />' . $output ); diff --git a/core/modules/simpletest/src/Form/SimpletestResultsForm.php b/core/modules/simpletest/src/Form/SimpletestResultsForm.php index 56d4f59a2bd19a877b59624270d6a71f470ff096..7d39496a13fcea6b9505c1e221d15c4ba5ffdcd3 100644 --- a/core/modules/simpletest/src/Form/SimpletestResultsForm.php +++ b/core/modules/simpletest/src/Form/SimpletestResultsForm.php @@ -12,6 +12,7 @@ use Drupal\Core\Form\FormBase; use Drupal\Core\Form\FormState; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Url; use Drupal\simpletest\TestDiscovery; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\RedirectResponse; @@ -238,7 +239,7 @@ public function buildForm(array $form, FormStateInterface $form_state, $test_id $form['action']['return'] = array( '#type' => 'link', '#title' => $this->t('Return to list'), - '#href' => 'admin/config/development/testing', + '#url' => Url::fromRoute('simpletest.test_form'), ); if (is_numeric($test_id)) { diff --git a/core/modules/system/src/Controller/DbUpdateController.php b/core/modules/system/src/Controller/DbUpdateController.php index 2f987720acd8d1bdd772553a9bb7610825ebece9..7dff04a586ae97b46903b9fe6954aa5af2e4b100 100644 --- a/core/modules/system/src/Controller/DbUpdateController.php +++ b/core/modules/system/src/Controller/DbUpdateController.php @@ -216,7 +216,8 @@ protected function info() { '#type' => 'link', '#title' => $this->t('Continue'), '#attributes' => array('class' => array('button', 'button--primary')), - ) + $url->toRenderArray(); + '#url' => $url, + ); return $build; } @@ -347,7 +348,8 @@ protected function selection() { '#title' => $this->t('Apply pending updates'), '#attributes' => array('class' => array('button', 'button--primary')), '#weight' => 5, - ) + $url->toRenderArray(); + '#url' => $url, + ); } return $build; @@ -620,12 +622,12 @@ public static function batchFinished($success, $results, $operations) { protected function helpfulLinks() { $links['front'] = array( 'title' => $this->t('Front page'), - 'href' => '<front>', + 'url' => Url::fromRoute('<front>'), ); if ($this->account->hasPermission('access administration pages')) { $links['admin-pages'] = array( 'title' => $this->t('Administration pages'), - 'href' => 'admin', + 'url' => Url::fromRoute('system.admin'), ); } return $links; diff --git a/core/modules/system/src/Controller/SystemController.php b/core/modules/system/src/Controller/SystemController.php index 5f2ca3f70e63493eb7b049bf0352f5d5f59496d0..0980b0a3f6a6c815078e61e243a8ae7095dd2612 100644 --- a/core/modules/system/src/Controller/SystemController.php +++ b/core/modules/system/src/Controller/SystemController.php @@ -15,6 +15,7 @@ use Drupal\Core\Menu\MenuLinkTreeInterface; use Drupal\Core\Menu\MenuTreeParameters; use Drupal\Core\Theme\ThemeAccessCheck; +use Drupal\Core\Url; use Drupal\system\SystemManager; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -243,8 +244,7 @@ public function themesPage() { if ($this->themeAccess->checkAccess($theme->getName())) { $theme->operations[] = array( 'title' => $this->t('Settings'), - 'route_name' => 'system.theme_settings_theme', - 'route_parameters' => array('theme' => $theme->getName()), + 'url' => Url::fromRoute('system.theme_settings_theme', ['theme' => $theme->getName()]), 'attributes' => array('title' => $this->t('Settings for !theme theme', array('!theme' => $theme->info['name']))), ); } @@ -253,14 +253,14 @@ public function themesPage() { if ($theme->getName() != $admin_theme) { $theme->operations[] = array( 'title' => $this->t('Uninstall'), - 'route_name' => 'system.theme_uninstall', + 'url' => Url::fromRoute('system.theme_uninstall'), 'query' => $query, 'attributes' => array('title' => $this->t('Uninstall !theme theme', array('!theme' => $theme->info['name']))), ); } $theme->operations[] = array( 'title' => $this->t('Set as default'), - 'route_name' => 'system.theme_set_default', + 'url' => Url::fromRoute('system.theme_set_default'), 'query' => $query, 'attributes' => array('title' => $this->t('Set !theme as default theme', array('!theme' => $theme->info['name']))), ); @@ -270,13 +270,13 @@ public function themesPage() { else { $theme->operations[] = array( 'title' => $this->t('Install'), - 'route_name' => 'system.theme_install', + 'url' => Url::fromRoute('system.theme_install'), 'query' => $query, 'attributes' => array('title' => $this->t('Install !theme theme', array('!theme' => $theme->info['name']))), ); $theme->operations[] = array( 'title' => $this->t('Install and set as default'), - 'route_name' => 'system.theme_set_default', + 'url' => Url::fromRoute('system.theme_set_default'), 'query' => $query, 'attributes' => array('title' => $this->t('Install !theme as default theme', array('!theme' => $theme->info['name']))), ); diff --git a/core/modules/system/src/Form/ModulesListForm.php b/core/modules/system/src/Form/ModulesListForm.php index 23505fa39dd64522edf53be85e73bff3e5385e80..5f85624ffb76254df3f5c67dc82eace255e5ae08 100644 --- a/core/modules/system/src/Form/ModulesListForm.php +++ b/core/modules/system/src/Form/ModulesListForm.php @@ -22,6 +22,7 @@ use Drupal\Core\Routing\RouteMatchInterface; use Drupal\Core\Routing\RouteProviderInterface; use Drupal\Core\Session\AccountInterface; +use Drupal\Core\Url; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\Request; @@ -258,7 +259,7 @@ protected function buildRow(array $modules, Extension $module, $distribution) { $row['links']['help'] = array( '#type' => 'link', '#title' => $this->t('Help'), - '#href' => 'admin/help/' . $module->getName(), + '#url' => Url::fromRoute('help.page', ['name' => $module->getName()]), '#options' => array('attributes' => array('class' => array('module-link', 'module-link-help'), 'title' => $this->t('Help'))), ); } @@ -270,7 +271,7 @@ protected function buildRow(array $modules, Extension $module, $distribution) { $row['links']['permissions'] = array( '#type' => 'link', '#title' => $this->t('Permissions'), - '#href' => 'admin/people/permissions', + '#url' => Url::fromRoute('user.admin_permissions'), '#options' => array('fragment' => 'module-' . $module->getName(), 'attributes' => array('class' => array('module-link', 'module-link-permissions'), 'title' => $this->t('Configure permissions'))), ); } @@ -301,8 +302,7 @@ protected function buildRow(array $modules, Extension $module, $distribution) { $row['links']['configure'] = array( '#type' => 'link', '#title' => $this->t('Configure'), - '#route_name' => $module->info['configure'], - '#route_parameters' => $route_parameters, + '#url' => Url::fromRoute($module->info['configure'], $route_parameters), '#options' => array( 'attributes' => array( 'class' => array('module-link', 'module-link-configure'), diff --git a/core/modules/system/src/Tests/Common/RenderElementTypesTest.php b/core/modules/system/src/Tests/Common/RenderElementTypesTest.php index 9757a2b67a58256f46c1f904fd8d7358f87f7a2e..f3f27abd4e8e8d10f3bf78b085cf3d9d980fcad4 100644 --- a/core/modules/system/src/Tests/Common/RenderElementTypesTest.php +++ b/core/modules/system/src/Tests/Common/RenderElementTypesTest.php @@ -8,6 +8,7 @@ namespace Drupal\system\Tests\Common; use Drupal\Component\Utility\String; +use Drupal\Core\Url; use Drupal\simpletest\DrupalUnitTestBase; /** @@ -112,7 +113,7 @@ function testMoreLink() { 'name' => "#type 'more_link' anchor tag generation without extra classes", 'value' => array( '#type' => 'more_link', - '#href' => 'http://drupal.org', + '#url' => Url::fromUri('http://drupal.org'), ), 'expected' => '//div[@class="more-link"]/a[@href="http://drupal.org" and text()="More"]', ), @@ -120,7 +121,7 @@ function testMoreLink() { 'name' => "#type 'more_link' anchor tag generation with different link text", 'value' => array( '#type' => 'more_link', - '#href' => 'http://drupal.org', + '#url' => Url::fromUri('http://drupal.org'), '#title' => 'More Titles', ), 'expected' => '//div[@class="more-link"]/a[@href="http://drupal.org" and text()="More Titles"]', @@ -129,7 +130,7 @@ function testMoreLink() { 'name' => "#type 'more_link' anchor tag generation with attributes on wrapper", 'value' => array( '#type' => 'more_link', - '#href' => 'http://drupal.org', + '#url' => Url::fromUri('http://drupal.org'), '#theme_wrappers' => array( 'container' => array( '#attributes' => array( @@ -145,16 +146,15 @@ function testMoreLink() { 'name' => "#type 'more_link' anchor tag with a relative path", 'value' => array( '#type' => 'more_link', - '#href' => 'a/link', + '#url' => Url::fromRoute('router_test.1'), ), - 'expected' => '//div[@class="more-link"]/a[@href="' . _url('a/link') . '" and text()="More"]', + 'expected' => '//div[@class="more-link"]/a[@href="' . _url('router_test/test1') . '" and text()="More"]', ), array( 'name' => "#type 'more_link' anchor tag with a route", 'value' => array( '#type' => 'more_link', - '#route_name' => 'router_test.1', - '#route_parameters' => array(), + '#url' => Url::fromRoute('router_test.1'), ), 'expected' => '//div[@class="more-link"]/a[@href="' . \Drupal::urlGenerator()->generate('router_test.1') . '" and text()="More"]', ), @@ -162,7 +162,7 @@ function testMoreLink() { 'name' => "#type 'more_link' anchor tag with an absolute path", 'value' => array( '#type' => 'more_link', - '#href' => 'admin/content', + '#url' => Url::fromRoute('system.admin_content'), '#options' => array('absolute' => TRUE), ), 'expected' => '//div[@class="more-link"]/a[@href="' . _url('admin/content', array('absolute' => TRUE)) . '" and text()="More"]', @@ -171,7 +171,7 @@ function testMoreLink() { 'name' => "#type 'more_link' anchor tag to the front page", 'value' => array( '#type' => 'more_link', - '#href' => '<front>', + '#url' => Url::fromRoute('<front>'), ), 'expected' => '//div[@class="more-link"]/a[@href="' . _url('<front>') . '" and text()="More"]', ), diff --git a/core/modules/system/src/Tests/Common/RenderTest.php b/core/modules/system/src/Tests/Common/RenderTest.php index 6c286cab01630b7017394a9317bed80db12ef08c..56c2f3909b187473a5ab86dd34cdd19fc023dcc8 100644 --- a/core/modules/system/src/Tests/Common/RenderTest.php +++ b/core/modules/system/src/Tests/Common/RenderTest.php @@ -10,6 +10,7 @@ use Drupal\Component\Serialization\Json; use Drupal\Component\Utility\Html; use Drupal\Core\Render\Element; +use Drupal\Core\Url; use Drupal\simpletest\DrupalUnitTestBase; /** @@ -120,7 +121,7 @@ function testDrupalRenderBasics() { ), ), '#attributes' => array('id' => 'foo'), - '#href' => 'http://drupal.org', + '#url' => Url::fromUri('http://drupal.org'), '#title' => 'bar', ), 'expected' => '<div class="baz"><a href="http://drupal.org" id="foo">bar</a></div>' . "\n", @@ -131,7 +132,7 @@ function testDrupalRenderBasics() { 'name' => '#theme_wrappers attribute disambiguation with undefined #theme attribute', 'value' => array( '#type' => 'link', - '#href' => 'http://drupal.org', + '#url' => Url::fromUri('http://drupal.org'), '#title' => 'foo', '#theme_wrappers' => array( 'container' => array( diff --git a/core/modules/system/src/Tests/Common/RenderWebTest.php b/core/modules/system/src/Tests/Common/RenderWebTest.php index 3e58fb0e849466b384abe30856292793416f8c5b..05a9cbe754333f0cfe3eef7eaa5800f31a4d49b8 100644 --- a/core/modules/system/src/Tests/Common/RenderWebTest.php +++ b/core/modules/system/src/Tests/Common/RenderWebTest.php @@ -8,6 +8,7 @@ namespace Drupal\system\Tests\Common; use Drupal\Component\Utility\String; +use Drupal\Core\Url; use Drupal\simpletest\WebTestBase; /** @@ -105,13 +106,13 @@ function testDrupalRenderFormElements() { $element = array( '#type' => 'link', '#title' => $this->randomMachineName(), - '#href' => $this->randomMachineName(), + '#url' => Url::fromRoute('common_test.destination'), '#options' => array( 'absolute' => TRUE, ), ); $this->assertRenderedElement($element, '//a[@href=:href and contains(., :title)]', array( - ':href' => _url($element['#href'], array('absolute' => TRUE)), + ':href' => \Drupal::urlGenerator()->generateFromPath('common-test/destination', ['absolute' => TRUE]), ':title' => $element['#title'], )); @@ -148,10 +149,7 @@ function testDrupalRenderFormElements() { protected function assertRenderedElement(array $element, $xpath, array $xpath_args = array()) { $original_element = $element; $this->drupalSetContent(drupal_render($element)); - $this->verbose('<pre>' . String::checkPlain(var_export($original_element, TRUE)) . '</pre>' - . '<pre>' . String::checkPlain(var_export($element, TRUE)) . '</pre>' - . '<hr />' . $this->drupalGetContent() - ); + $this->verbose('<hr />' . $this->drupalGetContent()); // @see \Drupal\simpletest\WebTestBase::xpath() $xpath = $this->buildXPathQuery($xpath, $xpath_args); diff --git a/core/modules/system/src/Tests/Common/UrlTest.php b/core/modules/system/src/Tests/Common/UrlTest.php index 3ac4bc4ebca624466b173c2afd5c7d0da4adcd08..e316eaa6fbc86a7debd6653aa69ccba22d680e7b 100644 --- a/core/modules/system/src/Tests/Common/UrlTest.php +++ b/core/modules/system/src/Tests/Common/UrlTest.php @@ -39,15 +39,10 @@ function testLinkXSS() { $sanitized_path = check_url(_url($path)); $this->assertTrue(strpos($link, $sanitized_path) !== FALSE, format_string('XSS attack @path was filtered by _l().', array('@path' => $path))); - // Test #type 'link'. - $link_array = array( - '#type' => 'link', - '#title' => $this->randomMachineName(), - '#href' => $path, - ); - $type_link = drupal_render($link_array); + // Test _url(). + $link = _url($path); $sanitized_path = check_url(_url($path)); - $this->assertTrue(strpos($type_link, $sanitized_path) !== FALSE, format_string('XSS attack @path was filtered by #theme', array('@path' => $path))); + $this->assertTrue(strpos($link, $sanitized_path) !== FALSE, format_string('XSS attack @path was filtered by #theme', ['@path' => $path])); } /** @@ -61,7 +56,7 @@ function testLinkAttributes() { '#options' => array( 'language' => $language, ), - '#href' => 'http://drupal.org', + '#url' => Url::fromUri('http://drupal.org'), '#title' => 'bar', ); $langcode = $language->id; @@ -123,7 +118,7 @@ function testLinkAttributes() { $type_link = array( '#type' => 'link', '#title' => $this->randomMachineName(), - '#route_name' => '<current>', + '#url' => Url::fromRoute('<current>'), '#options' => array( 'attributes' => array( 'class' => array($class_theme), @@ -150,7 +145,7 @@ function testLinkRenderArrayText() { $type_link_plain_array = array( '#type' => 'link', '#title' => 'foo', - '#href' => 'http://drupal.org', + '#url' => Url::fromUri('http://drupal.org'), ); $type_link_plain = drupal_render($type_link_plain_array); $this->assertEqual($type_link_plain, $l); @@ -159,7 +154,7 @@ function testLinkRenderArrayText() { $type_link_nested_array = array( '#type' => 'link', '#title' => array('#markup' => 'foo'), - '#href' => 'http://drupal.org', + '#url' => Url::fromUri('http://drupal.org'), ); $type_link_nested = drupal_render($type_link_nested_array); $this->assertEqual($type_link_nested, $l); diff --git a/core/modules/system/src/Tests/Theme/FunctionsTest.php b/core/modules/system/src/Tests/Theme/FunctionsTest.php index c8d068cb747d71348a805993aba324ba58c90179..6433a6495a2d1782d021ceb3966aafbfc9e23418 100644 --- a/core/modules/system/src/Tests/Theme/FunctionsTest.php +++ b/core/modules/system/src/Tests/Theme/FunctionsTest.php @@ -10,6 +10,7 @@ use Drupal\Component\Serialization\Json; use Drupal\Component\Utility\String; use Drupal\Core\Session\UserSession; +use Drupal\Core\Url; use Drupal\simpletest\WebTestBase; /** @@ -190,24 +191,22 @@ function testLinks() { $variables['links'] = array( 'a link' => array( 'title' => 'A <link>', - 'href' => 'a/link', + 'url' => Url::fromUri('base://a/link'), ), 'plain text' => array( 'title' => 'Plain "text"', ), 'front page' => array( 'title' => 'Front page', - 'href' => '<front>', + 'url' => Url::fromRoute('<front>'), ), 'router-test' => array( 'title' => 'Test route', - 'route_name' => 'router_test.1', - 'route_parameters' => array(), + 'url' => Url::fromRoute('router_test.1'), ), 'query-test' => array( 'title' => 'Query test route', - 'route_name' => 'router_test.1', - 'route_parameters' => array(), + 'url' => Url::fromRoute('router_test.1'), 'query' => array( 'key' => 'value', ) @@ -216,7 +215,7 @@ function testLinks() { $expected_links = ''; $expected_links .= '<ul id="somelinks">'; - $expected_links .= '<li class="a-link"><a href="' . _url('a/link') . '">' . String::checkPlain('A <link>') . '</a></li>'; + $expected_links .= '<li class="a-link"><a href="' . Url::fromUri('base://a/link')->toString() . '">' . String::checkPlain('A <link>') . '</a></li>'; $expected_links .= '<li class="plain-text">' . String::checkPlain('Plain "text"') . '</li>'; $expected_links .= '<li class="front-page"><a href="' . _url('<front>') . '">' . String::checkPlain('Front page') . '</a></li>'; $expected_links .= '<li class="router-test"><a href="' . \Drupal::urlGenerator()->generate('router_test.1') . '">' . String::checkPlain('Test route') . '</a></li>'; @@ -250,15 +249,12 @@ function testLinks() { $this->assertThemeOutput('links', $variables, $expected); // Verify that passing attributes for the links work. - $variables['links']['a link']['attributes'] = array( - 'class' => array('a/class'), - ); $variables['links']['plain text']['attributes'] = array( 'class' => array('a/class'), ); $expected_links = ''; $expected_links .= '<ul id="somelinks">'; - $expected_links .= '<li class="a-link"><a href="' . _url('a/link') . '" class="a/class">' . String::checkPlain('A <link>') . '</a></li>'; + $expected_links .= '<li class="a-link"><a href="' . Url::fromUri('base://a/link')->toString() . '">' . String::checkPlain('A <link>') . '</a></li>'; $expected_links .= '<li class="plain-text"><span class="a/class">' . String::checkPlain('Plain "text"') . '</span></li>'; $expected_links .= '<li class="front-page"><a href="' . _url('<front>') . '">' . String::checkPlain('Front page') . '</a></li>'; $expected_links .= '<li class="router-test"><a href="' . \Drupal::urlGenerator()->generate('router_test.1') . '">' . String::checkPlain('Test route') . '</a></li>'; @@ -273,7 +269,7 @@ function testLinks() { $variables['set_active_class'] = TRUE; $expected_links = ''; $expected_links .= '<ul id="somelinks">'; - $expected_links .= '<li class="a-link" data-drupal-link-system-path="a/link"><a href="' . _url('a/link') . '" class="a/class" data-drupal-link-system-path="a/link">' . String::checkPlain('A <link>') . '</a></li>'; + $expected_links .= '<li class="a-link"><a href="' . Url::fromUri('base://a/link')->toString() . '">' . String::checkPlain('A <link>') . '</a></li>'; $expected_links .= '<li class="plain-text"><span class="a/class">' . String::checkPlain('Plain "text"') . '</span></li>'; $expected_links .= '<li class="front-page" data-drupal-link-system-path="<front>"><a href="' . _url('<front>') . '" data-drupal-link-system-path="<front>">' . String::checkPlain('Front page') . '</a></li>'; $expected_links .= '<li class="router-test" data-drupal-link-system-path="router_test/test1"><a href="' . \Drupal::urlGenerator()->generate('router_test.1') . '" data-drupal-link-system-path="router_test/test1">' . String::checkPlain('Test route') . '</a></li>'; @@ -297,7 +293,7 @@ function testDrupalPreRenderLinks() { '#links' => array( 'parent_link' => array( 'title' => 'Parent link original', - 'href' => 'parent-link-original', + 'url' => Url::fromRoute('router_test.1'), ), ), 'first_child' => array( @@ -308,12 +304,12 @@ function testDrupalPreRenderLinks() { // one of the parent's links). 'parent_link' => array( 'title' => 'Parent link copy', - 'href' => 'parent-link-copy', + 'url' => Url::fromRoute('router_test.6'), ), // This should always be rendered. 'first_child_link' => array( 'title' => 'First child link', - 'href' => 'first-child-link', + 'url' => Url::fromRoute('router_test.7'), ), ), ), @@ -323,7 +319,7 @@ function testDrupalPreRenderLinks() { '#links' => array( 'second_child_link' => array( 'title' => 'Second child link', - 'href' => 'second-child-link', + 'url' => Url::fromRoute('router_test.8'), ), ), ), @@ -334,7 +330,7 @@ function testDrupalPreRenderLinks() { '#links' => array( 'third_child_link' => array( 'title' => 'Third child link', - 'href' => 'third-child-link', + 'url' => Url::fromRoute('router_test.9'), ), ), '#access' => FALSE, diff --git a/core/modules/system/system.api.php b/core/modules/system/system.api.php index a0ee2947f2f642525e4f508435fac84007d43d2a..417f6f062084b44d7151f9160476d9ca1cff9af4 100644 --- a/core/modules/system/system.api.php +++ b/core/modules/system/system.api.php @@ -412,7 +412,7 @@ function hook_menu_local_tasks(&$data, $route_name) { '#theme' => 'menu_local_action', '#link' => array( 'title' => t('Add content'), - 'href' => 'node/add', + 'url' => Url::fromRoute('node.add_page'), 'localized_options' => array( 'attributes' => array( 'title' => t('Add content'), @@ -426,7 +426,7 @@ function hook_menu_local_tasks(&$data, $route_name) { '#theme' => 'menu_local_task', '#link' => array( 'title' => t('Example tab'), - 'href' => 'node/add', + 'url' => Url::fromRoute('node.add_page'), 'localized_options' => array( 'attributes' => array( 'title' => t('Add content'), @@ -2277,7 +2277,7 @@ function hook_system_themes_page_alter(&$theme_groups) { // Add a foo link to each list of theme operations. $theme->operations[] = array( 'title' => t('Foo'), - 'href' => 'admin/appearance/foo', + 'url' => Url::fromRoute('system.themes_page'), 'query' => array('theme' => $theme->getName()) ); } diff --git a/core/modules/system/tests/modules/ajax_test/ajax_test.module b/core/modules/system/tests/modules/ajax_test/ajax_test.module index 6127b2e60a8b56ba9da4864596fe3e50a5211837..870a1577b7493261234475bad91c1020c0c1688d 100644 --- a/core/modules/system/tests/modules/ajax_test/ajax_test.module +++ b/core/modules/system/tests/modules/ajax_test/ajax_test.module @@ -11,6 +11,7 @@ use Drupal\Core\Ajax\OpenModalDialogCommand; use Drupal\Core\Ajax\CloseDialogCommand; use Drupal\Core\Ajax\HtmlCommand; +use Drupal\Core\Url; /** * Menu callback: Returns an element suitable for use by @@ -108,7 +109,7 @@ function ajax_test_dialog_contents() { 'cancel' => array( '#type' => 'link', '#title' => 'Cancel', - '#href' => '', + '#url' => Url::fromRoute('<front>'), '#attributes' => array( // This is a special class to which JavaScript assigns dialog closing // behavior. diff --git a/core/modules/system/tests/modules/ajax_test/src/Controller/AjaxTestController.php b/core/modules/system/tests/modules/ajax_test/src/Controller/AjaxTestController.php index ac0399f67b59d285d2036d9a116ff549352db3dd..ab25fdee277ecd3bb0035be248fd7992119fd584 100644 --- a/core/modules/system/tests/modules/ajax_test/src/Controller/AjaxTestController.php +++ b/core/modules/system/tests/modules/ajax_test/src/Controller/AjaxTestController.php @@ -7,6 +7,8 @@ namespace Drupal\ajax_test\Controller; +use Drupal\Core\Url; + /** * Provides content for dialog tests. */ @@ -56,7 +58,7 @@ public function dialog() { $build['link'] = array( '#type' => 'link', '#title' => 'Link 1 (modal)', - '#href' => 'ajax-test/dialog-contents', + '#url' => Url::fromRoute('ajax_test.dialog_contents'), '#attributes' => array( 'class' => array('use-ajax'), 'data-accepts' => 'application/vnd.drupal-modal', @@ -69,7 +71,7 @@ public function dialog() { '#links' => array( 'link2' => array( 'title' => 'Link 2 (modal)', - 'href' => 'ajax-test/dialog-contents', + 'url' => Url::fromRoute('ajax_test.dialog_contents'), 'attributes' => array( 'class' => array('use-ajax'), 'data-accepts' => 'application/vnd.drupal-modal', @@ -80,7 +82,7 @@ public function dialog() { ), 'link3' => array( 'title' => 'Link 3 (non-modal)', - 'href' => 'ajax-test/dialog-contents', + 'url' => Url::fromRoute('ajax_test.dialog_contents'), 'attributes' => array( 'class' => array('use-ajax'), 'data-accepts' => 'application/vnd.drupal-dialog', @@ -92,14 +94,14 @@ public function dialog() { ), 'link4' => array( 'title' => 'Link 4 (close non-modal if open)', - 'href' => 'ajax-test/dialog-close', + 'url' => Url::fromRoute('ajax_test.dialog_close'), 'attributes' => array( 'class' => array('use-ajax'), ), ), 'link5' => array( 'title' => 'Link 5 (form)', - 'href' => 'ajax-test/dialog-form', + 'url' => Url::fromRoute('ajax_test.dialog_form'), 'attributes' => array( 'class' => array('use-ajax'), 'data-accepts' => 'application/vnd.drupal-modal', @@ -107,7 +109,7 @@ public function dialog() { ), 'link6' => array( 'title' => 'Link 6 (entity form)', - 'href' => 'admin/structure/contact/add', + 'url' => Url::fromRoute('contact.form_add'), 'attributes' => array( 'class' => array('use-ajax'), 'data-accepts' => 'application/vnd.drupal-modal', @@ -119,7 +121,7 @@ public function dialog() { ), 'link7' => array( 'title' => 'Link 7 (non-modal, no target)', - 'href' => 'ajax-test/dialog-contents', + 'url' => Url::fromRoute('ajax_test.dialog_contents'), 'attributes' => array( 'class' => array('use-ajax'), 'data-accepts' => 'application/vnd.drupal-dialog', diff --git a/core/modules/system/tests/modules/common_test/src/Controller/CommonTestController.php b/core/modules/system/tests/modules/common_test/src/Controller/CommonTestController.php index 161aabe32e265936a400205ab062bfef356eea1a..cf82dba1f716120f645a6152f9ababc131875fad 100644 --- a/core/modules/system/tests/modules/common_test/src/Controller/CommonTestController.php +++ b/core/modules/system/tests/modules/common_test/src/Controller/CommonTestController.php @@ -8,6 +8,7 @@ namespace Drupal\common_test\Controller; use Drupal\Component\Utility\String; +use Drupal\Core\Url; use Symfony\Component\HttpFoundation\Response; /** @@ -25,7 +26,7 @@ public function typeLinkActiveClass() { 'no_query' => array( '#type' => 'link', '#title' => t('Link with no query string'), - '#route_name' => '<current>', + '#url' => Url::fromRoute('<current>'), '#options' => array( 'set_active_class' => TRUE, ), @@ -33,7 +34,7 @@ public function typeLinkActiveClass() { 'with_query' => array( '#type' => 'link', '#title' => t('Link with a query string'), - '#route_name' => '<current>', + '#url' => Url::fromRoute('<current>'), '#options' => array( 'query' => array( 'foo' => 'bar', @@ -45,7 +46,7 @@ public function typeLinkActiveClass() { 'with_query_reversed' => array( '#type' => 'link', '#title' => t('Link with the same query string in reverse order'), - '#route_name' => '<current>', + '#url' => Url::fromRoute('<current>'), '#options' => array( 'query' => array( 'one' => 'two', diff --git a/core/modules/system/tests/modules/entity_test/entity_test.module b/core/modules/system/tests/modules/entity_test/entity_test.module index e17eb0175dc1e81e04ab8772a9f5c252878149e8..41906a18b64689258e3df61e90f120490c17f316 100644 --- a/core/modules/system/tests/modules/entity_test/entity_test.module +++ b/core/modules/system/tests/modules/entity_test/entity_test.module @@ -14,6 +14,7 @@ use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Session\AccountInterface; use Drupal\Core\Entity\Entity\EntityFormDisplay; +use Drupal\Core\Url; /** * Filter that limits test entity list to revisable ones. @@ -384,11 +385,19 @@ function entity_test_entity_predelete(EntityInterface $entity) { * Implements hook_entity_operation_alter(). */ function entity_test_entity_operation_alter(array &$operations, EntityInterface $entity) { - $operations['test_operation'] = array( - 'title' => format_string('Test Operation: @label', array('@label' => $entity->label())), - 'href' => $entity->url() . '/test_operation', - 'weight' => 50, - ); + $valid_entity_type_ids = [ + 'user_role', + 'block', + ]; + if (in_array($entity->getEntityTypeId(), $valid_entity_type_ids)) { + if (\Drupal::service('router.route_provider')->getRouteByName("entity.{$entity->getEntityTypeId()}.test_operation")) { + $operations['test_operation'] = [ + 'title' => format_string('Test Operation: @label', ['@label' => $entity->label()]), + 'url' => Url::fromRoute("entity.{$entity->getEntityTypeId()}.test_operation", [$entity->getEntityTypeId() => $entity->id()]), + 'weight' => 50, + ]; + } + } } /** diff --git a/core/modules/system/tests/modules/entity_test/entity_test.routing.yml b/core/modules/system/tests/modules/entity_test/entity_test.routing.yml index e3d0adca2faa6bf908b8ed3227d31c3885bd1df5..34cbc5692e8c8af038504219beeaac3085ca754f 100644 --- a/core/modules/system/tests/modules/entity_test/entity_test.routing.yml +++ b/core/modules/system/tests/modules/entity_test/entity_test.routing.yml @@ -76,6 +76,19 @@ entity.entity_test.list_empty: requirements: _access: 'TRUE' +entity.block.test_operation: + path: '/admin/structure/block/manage/{block}/test_operation' + defaults: + _entity_view: 'entity_test' + requirements: + _access: 'TRUE' + +entity.user_role.test_operation: + path: '/admin/people/roles/manage/{user_role}/test_operation' + defaults: + _entity_view: 'entity_test' + requirements: + _access: 'TRUE' route_callbacks: - '\Drupal\entity_test\Routing\EntityTestRoutes::routes' diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestRedirectForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestRedirectForm.php index f7c0d4a671867a5f4477a5da9aa3b078d3d8d6bb..925c84e32d4f37b2a9068a5e2bcd0bfe24d0e173 100644 --- a/core/modules/system/tests/modules/form_test/src/Form/FormTestRedirectForm.php +++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestRedirectForm.php @@ -54,6 +54,8 @@ public function buildForm(array $form, FormStateInterface $form_state) { public function submitForm(array &$form, FormStateInterface $form_state) { if (!$form_state->isValueEmpty('redirection')) { if (!$form_state->isValueEmpty('destination')) { + // @todo Use Url::fromPath() once https://www.drupal.org/node/2351379 is + // resolved. $form_state->setRedirectUrl(Url::fromUri('base://' . $form_state->getValue('destination'))); } } diff --git a/core/modules/system/tests/modules/theme_test/src/EventSubscriber/ThemeTestSubscriber.php b/core/modules/system/tests/modules/theme_test/src/EventSubscriber/ThemeTestSubscriber.php index a02be18db03e384e946081c402a0ad67e92991d4..b4e4393a8b0185db49c84f45e3ff62e632bb1f56 100644 --- a/core/modules/system/tests/modules/theme_test/src/EventSubscriber/ThemeTestSubscriber.php +++ b/core/modules/system/tests/modules/theme_test/src/EventSubscriber/ThemeTestSubscriber.php @@ -7,6 +7,7 @@ namespace Drupal\theme_test\EventSubscriber; +use Drupal\Core\Url; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\HttpKernel\Event\GetResponseEvent; use Symfony\Component\EventDispatcher\EventSubscriberInterface; @@ -44,7 +45,7 @@ public function onRequest(GetResponseEvent $event) { // returning output and theming the page as a whole. $more_link = array( '#type' => 'more_link', - '#href' => 'user', + '#url' => Url::fromRoute('user.page'), '#attributes' => array('title' => 'Themed output generated in a KernelEvents::REQUEST listener'), ); $GLOBALS['theme_test_output'] = drupal_render($more_link); diff --git a/core/modules/taxonomy/src/Form/OverviewTerms.php b/core/modules/taxonomy/src/Form/OverviewTerms.php index 95e6178253f4e6b7e397622982aa4621737911cc..65ed68ac7db0190e0fd4d22afb4c7fd63d493479 100644 --- a/core/modules/taxonomy/src/Form/OverviewTerms.php +++ b/core/modules/taxonomy/src/Form/OverviewTerms.php @@ -225,7 +225,8 @@ public function buildForm(array $form, FormStateInterface $form_state, Vocabular '#prefix' => !empty($indentation) ? drupal_render($indentation) : '', '#type' => 'link', '#title' => $term->getName(), - ) + $term->urlInfo()->toRenderArray(); + '#url' => $term->urlInfo(), + ); if ($taxonomy_vocabulary->hierarchy != TAXONOMY_HIERARCHY_MULTIPLE && count($tree) > 1) { $parent_fields = TRUE; $form['terms'][$key]['term']['tid'] = array( @@ -268,17 +269,20 @@ public function buildForm(array $form, FormStateInterface $form_state, Vocabular 'edit' => array( 'title' => $this->t('Edit'), 'query' => $destination, - ) + $term->urlInfo('edit-form')->toArray(), + 'url' => $term->urlInfo('edit-form'), + ), 'delete' => array( 'title' => $this->t('Delete'), 'query' => $destination, - ) + $term->urlInfo('delete-form')->toArray(), + 'url' => $term->urlInfo('delete-form'), + ), ); if ($this->moduleHandler->moduleExists('content_translation') && content_translation_translate_access($term)->isAllowed()) { $operations['translate'] = array( 'title' => $this->t('Translate'), 'query' => $destination, - ) + $term->urlInfo('drupal:content-translation-overview')->toArray(); + 'url' => $term->urlInfo('drupal:content-translation-overview'), + ); } $form['terms'][$key]['operations'] = array( '#type' => 'operations', diff --git a/core/modules/taxonomy/src/Plugin/Field/FieldFormatter/LinkFormatter.php b/core/modules/taxonomy/src/Plugin/Field/FieldFormatter/LinkFormatter.php index 856b73e0ad0b9933917d15477cb3df2cb561b886..ec1f86283f80eb70b0baabf8058c91dbb2b7e234 100644 --- a/core/modules/taxonomy/src/Plugin/Field/FieldFormatter/LinkFormatter.php +++ b/core/modules/taxonomy/src/Plugin/Field/FieldFormatter/LinkFormatter.php @@ -42,11 +42,14 @@ public function viewElements(FieldItemListInterface $items) { $elements[$delta] = array( '#type' => 'link', '#title' => $term->getName(), - ) + $term->urlInfo()->toRenderArray(); + '#url' => $term->urlInfo(), + ); if (!empty($item->_attributes)) { - $elements[$delta]['#options'] += array('attributes' => array()); - $elements[$delta]['#options']['attributes'] += $item->_attributes; + $options = $elements[$delta]['#url']->getOptions(); + $options += ['attributes' => []]; + $options['attributes'] += $item->_attributes; + $elements[$delta]['#url']->setOptions($options); // Unset field item attributes since they have been included in the // formatter output and should not be rendered in the field template. unset($item->_attributes); diff --git a/core/modules/taxonomy/src/VocabularyListBuilder.php b/core/modules/taxonomy/src/VocabularyListBuilder.php index a5a02fc0f792c5179bcc7c7bdf753fb174267a8b..bb385df487ea7457e725d442cbc9e2b80e4221c9 100644 --- a/core/modules/taxonomy/src/VocabularyListBuilder.php +++ b/core/modules/taxonomy/src/VocabularyListBuilder.php @@ -43,11 +43,13 @@ public function getDefaultOperations(EntityInterface $entity) { $operations['list'] = array( 'title' => t('List terms'), 'weight' => 0, - ) + $entity->urlInfo('overview-form')->toArray(); + 'url' => $entity->urlInfo('overview-form'), + ); $operations['add'] = array( 'title' => t('Add terms'), 'weight' => 10, - ) + $entity->urlInfo('add-form')->toArray(); + 'url' => $entity->urlInfo('add-form'), + ); unset($operations['delete']); return $operations; diff --git a/core/modules/telephone/src/Plugin/Field/FieldFormatter/TelephoneLinkFormatter.php b/core/modules/telephone/src/Plugin/Field/FieldFormatter/TelephoneLinkFormatter.php index ef45d4efcac643ed3ac106616ddd0419a5b9a944..5d83b7c6020243078b44a12920e4c044567dc127 100644 --- a/core/modules/telephone/src/Plugin/Field/FieldFormatter/TelephoneLinkFormatter.php +++ b/core/modules/telephone/src/Plugin/Field/FieldFormatter/TelephoneLinkFormatter.php @@ -10,6 +10,7 @@ use Drupal\Core\Field\FormatterBase; use Drupal\Core\Field\FieldItemListInterface; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Url; /** * Plugin implementation of the 'telephone_link' formatter. @@ -78,7 +79,7 @@ public function viewElements(FieldItemListInterface $items) { // itself as title. '#title' => $title_setting ?: $item->value, // Prepend 'tel:' to the telephone number. - '#href' => 'tel:' . rawurlencode(preg_replace('/\s+/', '', $item->value)), + '#url' => Url::fromUri('tel:' . rawurlencode(preg_replace('/\s+/', '', $item->value))), '#options' => array('external' => TRUE), ); diff --git a/core/modules/toolbar/src/Element/ToolbarItem.php b/core/modules/toolbar/src/Element/ToolbarItem.php index 0eeb5c4b4db7058aa27869ea02cce165485df418..5926a37804eef051882aafde34c88971537f1205 100644 --- a/core/modules/toolbar/src/Element/ToolbarItem.php +++ b/core/modules/toolbar/src/Element/ToolbarItem.php @@ -9,6 +9,7 @@ use Drupal\Component\Utility\Html; use Drupal\Core\Render\Element\RenderElement; +use Drupal\Core\Url; /** * Provides a toolbar item that is wrapped in markup for common styling. @@ -32,7 +33,7 @@ public function getInfo() { 'tab' => array( '#type' => 'link', '#title' => NULL, - '#href' => '', + '#url' => Url::fromRoute('<front>'), ), ); } diff --git a/core/modules/toolbar/tests/modules/toolbar_test/toolbar_test.module b/core/modules/toolbar/tests/modules/toolbar_test/toolbar_test.module index 69dac7ab176ed1bcb56e75ded62ffd24621ff361..9d4e89f6370bb14965e7d3882cf2daa70a218e3b 100644 --- a/core/modules/toolbar/tests/modules/toolbar_test/toolbar_test.module +++ b/core/modules/toolbar/tests/modules/toolbar_test/toolbar_test.module @@ -17,7 +17,7 @@ function toolbar_test_toolbar() { 'tab' => array( '#type' => 'link', '#title' => t('Test tab'), - '#href' => '', + '#url' => Url::fromRoute('<front>'), '#options' => array( 'html' => FALSE, 'attributes' => array( diff --git a/core/modules/toolbar/toolbar.api.php b/core/modules/toolbar/toolbar.api.php index ab9b75a758b44e1393b31a1445d33e844c5a38e8..bce69aeae66a847fcb78c839f0e4409ce05a2bcd 100644 --- a/core/modules/toolbar/toolbar.api.php +++ b/core/modules/toolbar/toolbar.api.php @@ -4,6 +4,7 @@ * @file * Hooks provided by the toolbar module. */ +use Drupal\Core\Url; /** * @addtogroup hooks @@ -72,7 +73,7 @@ function hook_toolbar() { 'tab' => array( '#type' => 'link', '#title' => t('Home'), - '#href' => '<front>', + '#url' => Url::fromRoute('<front>'), '#options' => array( 'attributes' => array( 'title' => t('Home page'), @@ -96,7 +97,7 @@ function hook_toolbar() { 'tab' => array( '#type' => 'link', '#title' => t('Shopping cart'), - '#href' => '/cart', + '#url' => Url::fromRoute('cart'), '#options' => array( 'html' => FALSE, 'attributes' => array( @@ -131,7 +132,7 @@ function hook_toolbar() { '#theme' => 'user_message_toolbar_tab', '#theme_wrappers' => array(), '#title' => t('Messages'), - '#href' => '/user/messages', + '#url' => Url::fromRoute('user.message'), '#options' => array( 'attributes' => array( 'title' => t('Messages'), diff --git a/core/modules/toolbar/toolbar.module b/core/modules/toolbar/toolbar.module index 3d960a8b5f61e27ca4324bb6cc985211470cabd3..ab0eb01b3be2a59a967fab16f52d4ce27cc0a2bd 100644 --- a/core/modules/toolbar/toolbar.module +++ b/core/modules/toolbar/toolbar.module @@ -14,6 +14,7 @@ use Drupal\Component\Utility\Crypt; use Drupal\Component\Utility\String; use Drupal\user\Entity\Role; +use Drupal\Core\Url; /** * Implements hook_help(). @@ -125,7 +126,7 @@ function toolbar_toolbar() { 'tab' => array( '#type' => 'link', '#title' => t('Back to site'), - '#href' => '<front>', + '#url' => Url::fromRoute('<front>'), '#attributes' => array( 'title' => t('Return to site content'), 'class' => array('toolbar-icon', 'toolbar-icon-escape-admin'), @@ -164,7 +165,7 @@ function toolbar_toolbar() { 'tab' => array( '#type' => 'link', '#title' => t('Manage'), - '#href' => 'admin', + '#url' => Url::fromRoute('system.admin'), '#attributes' => array( 'title' => t('Admin menu'), 'class' => array('toolbar-icon', 'toolbar-icon-menu'), diff --git a/core/modules/user/src/RoleListBuilder.php b/core/modules/user/src/RoleListBuilder.php index 8e7feecb08e9c819ac05bdfa4bc44460ed92e72f..4e0dd7398b0cee6ee76b68640fdacf9a7680c94a 100644 --- a/core/modules/user/src/RoleListBuilder.php +++ b/core/modules/user/src/RoleListBuilder.php @@ -51,7 +51,8 @@ public function getDefaultOperations(EntityInterface $entity) { $operations['permissions'] = array( 'title' => t('Edit permissions'), 'weight' => 20, - ) + $entity->urlInfo('edit-permissions-form')->toArray(); + 'url' => $entity->urlInfo('edit-permissions-form'), + ); } return $operations; } diff --git a/core/modules/user/user.module b/core/modules/user/user.module index 92bebb0079f3547457215b931d40f2ad08081125..3e4efe6c38d3e5df358a057b9aed159012d081ec 100644 --- a/core/modules/user/user.module +++ b/core/modules/user/user.module @@ -1455,7 +1455,7 @@ function user_toolbar() { $links = array( 'account' => array( 'title' => t('View profile'), - 'href' => 'user', + 'url' => Url::fromRoute('user.page'), 'html' => TRUE, 'attributes' => array( 'title' => t('User account'), @@ -1463,7 +1463,7 @@ function user_toolbar() { ), 'account_edit' => array( 'title' => t('Edit profile'), - 'href' => 'user/' . $user->id() . '/edit', + 'url' => Url::fromRoute('entity.user.edit_form', ['user' => $user->id()]), 'html' => TRUE, 'attributes' => array( 'title' => t('Edit user account'), @@ -1471,7 +1471,7 @@ function user_toolbar() { ), 'logout' => array( 'title' => t('Log out'), - 'href' => 'user/logout', + 'url' => Url::fromRoute('user.logout'), ), ); } @@ -1479,7 +1479,7 @@ function user_toolbar() { $links = array( 'login' => array( 'title' => t('Log in'), - 'href' => 'user', + 'url' => Url::fromRoute('user.page'), ), ); } @@ -1489,7 +1489,7 @@ function user_toolbar() { 'tab' => array( '#type' => 'link', '#title' => $user->getUsername(), - '#href' => 'user', + '#url' => Url::fromRoute('user.page'), '#attributes' => array( 'title' => t('My account'), 'class' => array('toolbar-icon', 'toolbar-icon-user'), diff --git a/core/modules/views/src/Plugin/views/field/Links.php b/core/modules/views/src/Plugin/views/field/Links.php index 5bb0ab765d5d83e8845277e83e938aa36e5cbde4..591266437d39e642d2cf4e3aa308acba413bde23 100644 --- a/core/modules/views/src/Plugin/views/field/Links.php +++ b/core/modules/views/src/Plugin/views/field/Links.php @@ -8,6 +8,7 @@ namespace Drupal\views\Plugin\views\field; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Url as UrlObject; /** * A abstract handler which provides a collection of links. @@ -79,7 +80,7 @@ protected function getLinks() { $path = strip_tags(decode_entities(strtr($path, $tokens))); $links[$field] = array( - 'href' => $path, + 'url' => UrlObject::fromUri('base://' . $path), 'title' => $title, ); if (!empty($this->options['destination'])) { diff --git a/core/modules/views/views.theme.inc b/core/modules/views/views.theme.inc index 02f017569b10601cfff42bdaa94f27083b918a2e..f089f565501a7b46ea053ea5313801439a4f9bae 100644 --- a/core/modules/views/views.theme.inc +++ b/core/modules/views/views.theme.inc @@ -1049,7 +1049,7 @@ function template_preprocess_views_mini_pager(&$variables) { $li_previous = array( '#type' => 'link', '#title' => $tags[1], - '#route_name' => '<current>', + '#url' => Url::fromRoute('<current>'), '#options' => array( 'query' => pager_query_add_page($parameters, $element, $pager_page_array[$element] - 1), 'attributes' => array( @@ -1072,7 +1072,7 @@ function template_preprocess_views_mini_pager(&$variables) { $li_next = array( '#type' => 'link', '#title' => $tags[3], - '#route_name' => '<current>', + '#url' => Url::fromRoute('<current>'), '#options' => array( 'query' => pager_query_add_page($parameters, $element, $pager_page_array[$element] + 1), 'attributes' => array( diff --git a/core/modules/views_ui/src/Form/Ajax/ReorderDisplays.php b/core/modules/views_ui/src/Form/Ajax/ReorderDisplays.php index c6e24db0ae64ead09193ee0baa451b61033f1f9d..72dae7c308a8e314faa9cffa7d8848e3307002d4 100644 --- a/core/modules/views_ui/src/Form/Ajax/ReorderDisplays.php +++ b/core/modules/views_ui/src/Form/Ajax/ReorderDisplays.php @@ -8,6 +8,7 @@ namespace Drupal\views_ui\Form\Ajax; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Url; use Drupal\views_ui\ViewUI; /** @@ -120,7 +121,7 @@ public function buildForm(array $form, FormStateInterface $form_state) { 'link' => array( '#type' => 'link', '#title' => '<span>' . $this->t('Remove') . '</span>', - '#href' => 'javascript:void()', + '#url' => Url::fromRoute('<none>'), '#options' => array( 'html' => TRUE, ), diff --git a/core/modules/views_ui/src/Tests/DisplayPathTest.php b/core/modules/views_ui/src/Tests/DisplayPathTest.php index 7e553e3807ee26a804e538116fb6bee66a088f12..3f79d64fa4cfb539373641fc9130ac4045911a48 100644 --- a/core/modules/views_ui/src/Tests/DisplayPathTest.php +++ b/core/modules/views_ui/src/Tests/DisplayPathTest.php @@ -48,6 +48,10 @@ protected function doBasicPathUITest() { // Save a path and make sure the summary appears as expected. $random_path = $this->randomMachineName(); + // @todo Once https://www.drupal.org/node/2351379 is resolved, Views will no + // longer use Url::fromUri(), and this path will be able to contain ':'. + $random_path = str_replace(':', '', $random_path); + $this->drupalPostForm('admin/structure/views/nojs/display/test_view/page_1/path', array('path' => $random_path), t('Apply')); $this->assertText('/' . $random_path, 'The custom path appears in the summary.'); $this->assertLink(t('View @display', array('@display' => 'Page')), 0, 'view page link found on the page.'); diff --git a/core/modules/views_ui/src/ViewEditForm.php b/core/modules/views_ui/src/ViewEditForm.php index dcd81c2f321159789e835544cd54d89c756ec05e..ea3ba889aaa3a4ffe7f49e90c18e1c21039971d5 100644 --- a/core/modules/views_ui/src/ViewEditForm.php +++ b/core/modules/views_ui/src/ViewEditForm.php @@ -320,6 +320,8 @@ public function save(array $form, FormStateInterface $form_state) { $query->remove('destination'); } } + // @todo Use Url::fromPath() once https://www.drupal.org/node/2351379 is + // resolved. $form_state->setRedirectUrl(Url::fromUri("base://$destination")); } @@ -424,7 +426,9 @@ public function getDisplayDetails($view, $display) { '#type' => 'link', '#title' => $this->t('View !display_title', array('!display_title' => $display_title)), '#options' => array('alt' => array($this->t("Go to the real page for this display"))), - '#href' => $path, + // @todo Use Url::fromPath() once + // https://www.drupal.org/node/2351379 is resolved. + '#url' => Url::fromUri("base://$path"), '#prefix' => '<li class="view">', "#suffix" => '</li>', ); @@ -692,20 +696,21 @@ public function renderDisplayTop(ViewUI $view) { '#links' => array( 'edit-details' => array( 'title' => $this->t('Edit view name/description'), - 'href' => "admin/structure/views/nojs/edit-details/{$view->id()}/$display_id", + 'url' => Url::fromRoute('views_ui.form_edit_details', ['js' => 'nojs', 'view' => $view->id(), 'display_id' => $display_id]), 'attributes' => array('class' => array('views-ajax-link')), ), 'analyze' => array( 'title' => $this->t('Analyze view'), - 'href' => "admin/structure/views/nojs/analyze/{$view->id()}/$display_id", + 'url' => Url::fromRoute('views_ui.form_analyze', ['js' => 'nojs', 'view' => $view->id(), 'display_id' => $display_id]), 'attributes' => array('class' => array('views-ajax-link')), ), 'duplicate' => array( 'title' => $this->t('Duplicate view'), - ) + $view->urlInfo('duplicate-form')->toArray(), + 'url' => $view->urlInfo('duplicate-form'), + ), 'reorder' => array( 'title' => $this->t('Reorder displays'), - 'href' => "admin/structure/views/nojs/reorder-displays/{$view->id()}/$display_id", + 'url' => Url::fromRoute('views_ui.form_reorder_displays', ['js' => 'nojs', 'view' => $view->id(), 'display_id' => $display_id]), 'attributes' => array('class' => array('views-ajax-link')), ), ), @@ -714,7 +719,8 @@ public function renderDisplayTop(ViewUI $view) { if ($view->access('delete')) { $element['extra_actions']['#links']['delete'] = array( 'title' => $this->t('Delete view'), - ) + $view->urlInfo('delete-form')->toArray(); + 'url' => $view->urlInfo('delete-form'), + ); } // Let other modules add additional links here. @@ -731,7 +737,7 @@ public function renderDisplayTop(ViewUI $view) { else { $element['extra_actions']['#links']['delete'] = array( 'title' => $this->t('Delete view'), - 'href' => "admin/structure/views/view/{$view->id()}/delete", + 'url' => $view->urlInfo('delete-form'), ); } } @@ -941,7 +947,7 @@ public function getFormBucket(ViewUI $view, $type, $display) { $build['#name'] = $build['#title'] = $types[$type]['title']; - $rearrange_url = "admin/structure/views/nojs/rearrange/{$view->id()}/{$display['id']}/$type"; + $rearrange_url = Url::fromRoute('views_ui.form_rearrange', ['js' => 'nojs', 'view' => $view->id(), 'display_id' => $display['id'], 'type' => $type]); $class = 'icon compact rearrange'; // Different types now have different rearrange forms, so we use this switch @@ -950,7 +956,7 @@ public function getFormBucket(ViewUI $view, $type, $display) { case 'filter': // The rearrange form for filters contains the and/or UI, so override // the used path. - $rearrange_url = "admin/structure/views/nojs/rearrange-filter/{$view->id()}/{$display['id']}"; + $rearrange_url = Url::fromRoute('views_ui.form_rearrange_filter', ['js' => 'nojs', 'view' => $view->id(), 'display_id' => $display['id']]); // TODO: Add another class to have another symbol for filter rearrange. $class = 'icon compact rearrange'; break; @@ -990,7 +996,7 @@ public function getFormBucket(ViewUI $view, $type, $display) { $actions['add'] = array( 'title' => $add_text, - 'href' => "admin/structure/views/nojs/add-handler/{$view->id()}/{$display['id']}/$type", + 'url' => Url::fromRoute('views_ui.form_add_handler', ['js' => 'nojs', 'view' => $view->id(), 'display_id' => $display['id'], 'type' => $type]), 'attributes' => array('class' => array('icon compact add', 'views-ajax-link'), 'id' => 'views-add-' . $type), 'html' => TRUE, ); @@ -1000,7 +1006,7 @@ public function getFormBucket(ViewUI $view, $type, $display) { $actions['rearrange'] = array( 'title' => $rearrange_text, - 'href' => $rearrange_url, + 'url' => $rearrange_url, 'attributes' => array('class' => array($class, 'views-ajax-link'), 'id' => 'views-rearrange-' . $type), 'html' => TRUE, ); diff --git a/core/modules/views_ui/src/ViewFormBase.php b/core/modules/views_ui/src/ViewFormBase.php index 9544040eff35fa5db4f5efcf987c02f3c735cacb..39f1a0dce01c4c4d78ac8aaee65e6ad8b4f63481 100644 --- a/core/modules/views_ui/src/ViewFormBase.php +++ b/core/modules/views_ui/src/ViewFormBase.php @@ -122,9 +122,9 @@ public function getDisplayTabs(ViewUI $view) { '#link' => array( 'title' => $this->getDisplayLabel($view, $id), 'localized_options' => array(), - ) + $view->urlInfo('edit-display-form')->toArray(), + 'url' => $view->urlInfo('edit-display-form')->setRouteParameter('display_id', $id), + ), ); - $tabs[$id]['#link']['route_parameters']['display_id'] = $id; if (!empty($display['deleted'])) { $tabs[$id]['#link']['localized_options']['attributes']['class'][] = 'views-display-deleted-link'; } diff --git a/core/modules/views_ui/src/ViewListBuilder.php b/core/modules/views_ui/src/ViewListBuilder.php index 9d12e5a3dc79b168690e948e8e13ceca5625c74b..c8dcbe105df947a902ec4cca0b31a0edbacce247 100644 --- a/core/modules/views_ui/src/ViewListBuilder.php +++ b/core/modules/views_ui/src/ViewListBuilder.php @@ -149,15 +149,14 @@ public function getDefaultOperations(EntityInterface $entity) { $operations['duplicate'] = array( 'title' => $this->t('Duplicate'), 'weight' => 15, - ) + $entity->urlInfo('duplicate-form')->toArray(); + 'url' => $entity->urlInfo('duplicate-form'), + ); } // Add AJAX functionality to enable/disable operations. foreach (array('enable', 'disable') as $op) { if (isset($operations[$op])) { - $operations[$op]['route_name'] = "entity.view.{$op}"; - $operations[$op]['route_parameters'] = array('view' => $entity->id()); - + $operations[$op]['url'] = $entity->urlInfo($op); // Enable and disable operations should use AJAX. $operations[$op]['attributes']['class'][] = 'use-ajax'; } diff --git a/core/modules/views_ui/views_ui.module b/core/modules/views_ui/views_ui.module index 46adb0f1ef9e184b26003777958ed8c0c77c21a3..a2beebac43ae5d0c342bb9854802d272d53d0700 100644 --- a/core/modules/views_ui/views_ui.module +++ b/core/modules/views_ui/views_ui.module @@ -6,6 +6,7 @@ */ use Drupal\Core\Routing\RouteMatchInterface; +use Drupal\Core\Url; use Drupal\views\Views; use Drupal\views\ViewExecutable; use Drupal\views\ViewStorageInterface; @@ -181,13 +182,13 @@ function views_ui_view_preview_section_handler_links(ViewExecutable $view, $type $field_name = $handler->adminLabel(TRUE); $links[$type . '-edit-' . $id] = array( 'title' => t('Edit @section', array('@section' => $field_name)), - 'href' => "admin/structure/views/nojs/handler/{$view->storage->id()}/{$display['id']}/$type/$id", + 'url' => Url::fromRoute('views_ui.form_handler', ['js' => 'nojs', 'view' => $view->storage->id(), 'display_id' => $display['id'], 'type' => $type, 'id' => $id]), 'attributes' => array('class' => array('views-ajax-link')), ); } $links[$type . '-add'] = array( 'title' => t('Add new'), - 'href' => "admin/structure/views/nojs/add-handler/{$view->storage->id()}/{$display['id']}/$type", + 'url' => Url::fromRoute('views_ui.form_add_handler', ['js' => 'nojs', 'view' => $view->storage->id(), 'display_id' => $display['id'], 'type' => $type]), 'attributes' => array('class' => array('views-ajax-link')), ); @@ -202,7 +203,7 @@ function views_ui_view_preview_section_display_category_links(ViewExecutable $vi $links = array( $type . '-edit' => array( 'title' => t('Edit @section', array('@section' => $title)), - 'href' => "admin/structure/views/nojs/display/{$view->storage->id()}/{$display['id']}/$type", + 'url' => Url::fromRoute('views_ui.form_display', ['js' => 'nojs', 'view' => $view->storage->id(), 'display_id' => $display['id'], 'type' => $type]), 'attributes' => array('class' => array('views-ajax-link')), ), ); @@ -253,8 +254,8 @@ function views_ui_contextual_links_view_alter(&$element, $items) { // screen. elseif (!empty($element['#links']['entityviewedit-form'])) { $display_id = $items['entity.view.edit_form']['metadata']['display_id']; - $element['#links']['entityviewedit-form']['route_parameters']['display_id'] = $display_id; - $element['#links']['entityviewedit-form']['route_name'] = 'entity.view.edit_display_form'; + $route_parameters = $element['#links']['entityviewedit-form']['url']->getRouteParameters() + ['display_id' => $display_id]; + $element['#links']['entityviewedit-form']['url'] = Url::fromRoute('entity.view.edit_display_form', $route_parameters); } } diff --git a/core/modules/views_ui/views_ui.theme.inc b/core/modules/views_ui/views_ui.theme.inc index 80f2f45c863f2eedf5cb5647e09fea50f5315a4e..4528490a10395a94b53a3dddbd05a17d8602cdda 100644 --- a/core/modules/views_ui/views_ui.theme.inc +++ b/core/modules/views_ui/views_ui.theme.inc @@ -9,6 +9,7 @@ use Drupal\Core\Form\FormState; use Drupal\Core\Render\Element; use Drupal\Core\Template\Attribute; +use Drupal\Core\Url; /** * Prepares variables for Views UI display tab setting templates. @@ -283,7 +284,7 @@ function template_preprocess_views_ui_rearrange_filter_form(&$variables) { $remove_link = array( '#type' => 'link', - '#href' => '', + '#url' => Url::fromRoute('<none>'), '#title' => '<span>' . t('Remove') . '</span>', '#weight' => '1', '#options' => array( diff --git a/core/tests/Drupal/Tests/Core/Form/ConfirmFormHelperTest.php b/core/tests/Drupal/Tests/Core/Form/ConfirmFormHelperTest.php index 176d5b475f3ca534a0a24693bd92bd275006b563..b80567fff508db4c7e09ddfddaac062c7aa6f629 100644 --- a/core/tests/Drupal/Tests/Core/Form/ConfirmFormHelperTest.php +++ b/core/tests/Drupal/Tests/Core/Form/ConfirmFormHelperTest.php @@ -47,7 +47,7 @@ public function testCancelLinkRoute() { ->method('getCancelUrl') ->will($this->returnValue($cancel_route)); $link = ConfirmFormHelper::buildCancelLink($form, new Request()); - $this->assertSame($route_name, $link['#route_name']); + $this->assertEquals(Url::fromRoute($route_name), $link['#url']); } /** @@ -56,23 +56,13 @@ public function testCancelLinkRoute() { * Tests a cancel link route with parameters. */ public function testCancelLinkRouteWithParams() { - $cancel_route = array( - 'route_name' => 'foo_bar.baz', - 'route_parameters' => array( - 'baz' => 'banana', - ), - 'options' => array( - 'absolute' => TRUE, - ), - ); + $expected = Url::fromRoute('foo_bar.baz', ['baz' => 'banana'], ['absolute' => TRUE]); $form = $this->getMock('Drupal\Core\Form\ConfirmFormInterface'); $form->expects($this->any()) ->method('getCancelUrl') - ->will($this->returnValue(new Url($cancel_route['route_name'], $cancel_route['route_parameters'], $cancel_route['options']))); + ->will($this->returnValue($expected)); $link = ConfirmFormHelper::buildCancelLink($form, new Request()); - $this->assertSame($cancel_route['route_name'], $link['#route_name']); - $this->assertSame($cancel_route['route_parameters'], $link['#route_parameters']); - $this->assertSame($cancel_route['options'], $link['#options']); + $this->assertEquals($expected, $link['#url']); } /** @@ -94,9 +84,7 @@ public function testCancelLinkRouteWithUrl() { ->method('getCancelUrl') ->will($this->returnValue($cancel_route)); $link = ConfirmFormHelper::buildCancelLink($form, new Request()); - $this->assertSame($cancel_route->getRouteName(), $link['#route_name']); - $this->assertSame($cancel_route->getRouteParameters(), $link['#route_parameters']); - $this->assertSame($cancel_route->getOptions(), $link['#options']); + $this->assertSame($cancel_route, $link['#url']); } /** @@ -108,7 +96,7 @@ public function testCancelLinkDestination() { $query = array('destination' => 'baz'); $form = $this->getMock('Drupal\Core\Form\ConfirmFormInterface'); $link = ConfirmFormHelper::buildCancelLink($form, new Request($query)); - $this->assertSame($query['destination'], $link['#href']); + $this->assertSame('base://' . $query['destination'], $link['#url']->getUri()); } } diff --git a/core/tests/Drupal/Tests/Core/Menu/LocalActionManagerTest.php b/core/tests/Drupal/Tests/Core/Menu/LocalActionManagerTest.php index 1942fc37648b7cf15b34c2b7c6a59ae7acb6e41b..219ef0399489a58526e4705d863f5c4061e23f6b 100644 --- a/core/tests/Drupal/Tests/Core/Menu/LocalActionManagerTest.php +++ b/core/tests/Drupal/Tests/Core/Menu/LocalActionManagerTest.php @@ -16,6 +16,7 @@ use Drupal\Core\Menu\LocalActionManager; use Drupal\Core\Routing\RouteProviderInterface; use Drupal\Core\Session\AccountInterface; +use Drupal\Core\Url; use Drupal\Tests\UnitTestCase; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RequestStack; @@ -196,8 +197,7 @@ public function getActionsForRouteProvider() { '#theme' => 'menu_local_action', '#link' => array( 'title' => 'Plugin ID 1', - 'route_name' => 'test_route_2', - 'route_parameters' => array(), + 'url' => Url::fromRoute('test_route_2'), 'localized_options' => '', ), '#access' => FALSE, @@ -231,8 +231,7 @@ public function getActionsForRouteProvider() { '#theme' => 'menu_local_action', '#link' => array( 'title' => 'Plugin ID 1', - 'route_name' => 'test_route_2', - 'route_parameters' => array(), + 'url' => Url::fromRoute('test_route_2'), 'localized_options' => '', ), '#access' => FALSE, @@ -267,8 +266,7 @@ public function getActionsForRouteProvider() { '#theme' => 'menu_local_action', '#link' => array( 'title' => 'Plugin ID 1', - 'route_name' => 'test_route_2', - 'route_parameters' => array(), + 'url' => Url::fromRoute('test_route_2'), 'localized_options' => '', ), '#access' => FALSE, @@ -278,8 +276,7 @@ public function getActionsForRouteProvider() { '#theme' => 'menu_local_action', '#link' => array( 'title' => 'Plugin ID 2', - 'route_name' => 'test_route_3', - 'route_parameters' => array(), + 'url' => Url::fromRoute('test_route_3'), 'localized_options' => '', ), '#access' => FALSE, @@ -316,8 +313,7 @@ public function getActionsForRouteProvider() { '#theme' => 'menu_local_action', '#link' => array( 'title' => 'Plugin ID 1', - 'route_name' => 'test_route_2', - 'route_parameters' => array('test1'), + 'url' => Url::fromRoute('test_route_2', ['test1']), 'localized_options' => '', ), '#access' => FALSE, @@ -327,8 +323,7 @@ public function getActionsForRouteProvider() { '#theme' => 'menu_local_action', '#link' => array( 'title' => 'Plugin ID 2', - 'route_name' => 'test_route_2', - 'route_parameters' => array('test2'), + 'url' => Url::fromRoute('test_route_2', ['test2']), 'localized_options' => '', ), '#access' => FALSE, diff --git a/core/tests/Drupal/Tests/Core/UnroutedUrlTest.php b/core/tests/Drupal/Tests/Core/UnroutedUrlTest.php index 9d6ea001331f3a6f1657335d7254171975910b40..6de1785bf1863bc0286c55b6465ba8b20499cecf 100644 --- a/core/tests/Drupal/Tests/Core/UnroutedUrlTest.php +++ b/core/tests/Drupal/Tests/Core/UnroutedUrlTest.php @@ -146,17 +146,13 @@ public function testToString(array $urls) { * @covers ::toArray */ public function testToArray(array $urls) { - $expected = array( - 'path' => $this->unroutedExternal, - 'options' => array('external' => TRUE), - ); - $this->assertSame($expected, $urls[0]->toArray()); - - $expected = array( - 'path' => $this->unroutedInternal, - 'options' => array(), - ); - $this->assertSame($expected, $urls[1]->toArray()); + $expected = Url::fromUri($this->unroutedExternal, ['external' => TRUE]); + $expected->setUnroutedUrlAssembler(\Drupal::service('unrouted_url_assembler')); + $this->assertEquals($expected, $urls[0]); + + $expected = Url::fromUri($this->unroutedInternal); + $expected->setUnroutedUrlAssembler(\Drupal::service('unrouted_url_assembler')); + $this->assertEquals($expected, $urls[1]); } /** diff --git a/core/tests/Drupal/Tests/Core/UrlTest.php b/core/tests/Drupal/Tests/Core/UrlTest.php index cf0496f694f39bdf6fad662010c87bc84cf9f058..404702e2a55f2496f5a848e19d6c3a00f6663741 100644 --- a/core/tests/Drupal/Tests/Core/UrlTest.php +++ b/core/tests/Drupal/Tests/Core/UrlTest.php @@ -102,7 +102,8 @@ public function testUrlFromRequest() { foreach ($this->map as $index => $values) { $path = array_pop($values); $url = Url::createFromRequest(Request::create("$path")); - $this->assertSame($values, array_values($url->toArray())); + $expected = Url::fromRoute($values[0], $values[1], $values[2]); + $this->assertEquals($expected, $url); $urls[$index] = $url; } return $urls; @@ -245,12 +246,9 @@ public function testToString($urls) { */ public function testToArray($urls) { foreach ($urls as $index => $url) { - $expected = array( - 'route_name' => $this->map[$index][0], - 'route_parameters' => $this->map[$index][1], - 'options' => $this->map[$index][2], - ); - $this->assertSame($expected, $url->toArray()); + $expected = Url::fromRoute($this->map[$index][0], $this->map[$index][1], $this->map[$index][2]); + $expected->setUrlGenerator(\Drupal::urlGenerator()); + $this->assertEquals($expected, $url); } } @@ -350,9 +348,7 @@ public function testAccess($access) { */ public function testRenderAccess($access) { $element = array( - '#route_name' => 'entity.node.canonical', - '#route_parameters' => ['node' => 3], - '#options' => [], + '#url' => Url::fromRoute('entity.node.canonical', ['node' => 3]), ); $this->container->set('current_user', $this->getMock('Drupal\Core\Session\AccountInterface')); $this->container->set('access_manager', $this->getMockAccessManager($access));