From 195d49998ab2726e35dda7834ee69ab9f5209b17 Mon Sep 17 00:00:00 2001 From: Alex Pott Date: Thu, 9 Oct 2014 07:39:37 +0100 Subject: [PATCH] Issue #2347465 by tim.plunkett, dawehner, cilefen: Convert all instances of #type link/links to convert to use routes. --- core/includes/menu.inc | 27 +---------- core/includes/theme.inc | 40 ++++++---------- .../Config/Entity/ConfigEntityListBuilder.php | 6 ++- core/lib/Drupal/Core/Entity/EntityForm.php | 2 +- .../Drupal/Core/Entity/EntityListBuilder.php | 6 ++- .../Field/FieldFormatter/MailToFormatter.php | 3 +- .../Field/FieldFormatter/UriLinkFormatter.php | 13 +++-- .../Field/Plugin/Field/FieldType/UriItem.php | 11 +++++ .../Drupal/Core/Form/ConfirmFormHelper.php | 19 ++++---- .../Drupal/Core/Language/LanguageManager.php | 3 +- .../Language/LanguageManagerInterface.php | 7 +-- .../Core/Menu/Form/MenuLinkDefaultForm.php | 3 +- .../Drupal/Core/Menu/LocalActionManager.php | 4 +- .../lib/Drupal/Core/Menu/LocalTaskManager.php | 4 +- .../Drupal/Core/Menu/MenuLinkInterface.php | 18 +++---- core/lib/Drupal/Core/Render/Element/Link.php | 23 ++------- core/lib/Drupal/Core/Render/Element/Table.php | 2 +- core/lib/Drupal/Core/Url.php | 47 +++++++------------ .../lib/Drupal/Core/Utility/LinkGenerator.php | 2 +- .../Core/Utility/UnroutedUrlAssembler.php | 3 +- .../src/Controller/AggregatorController.php | 17 +++---- .../aggregator/src/FeedViewBuilder.php | 6 +-- core/modules/aggregator/src/ItemsImporter.php | 2 +- .../src/Plugin/Block/AggregatorFeedBlock.php | 2 +- .../aggregator/src/Tests/AddFeedTest.php | 6 ++- core/modules/ban/src/Form/BanAdmin.php | 4 +- core/modules/block/block.module | 7 ++- core/modules/block/src/BlockListBuilder.php | 6 +-- core/modules/book/book.admin.inc | 9 ++-- core/modules/book/book.module | 9 ++-- .../book/src/Controller/BookController.php | 4 +- core/modules/comment/comment.api.php | 4 +- .../comment/src/CommentLinkBuilder.php | 20 ++++---- .../comment/src/CommentViewBuilder.php | 17 ++++--- .../comment/src/Form/CommentAdminOverview.php | 17 +++---- .../modules/comment_test/comment_test.module | 4 +- .../comment_test/comment_test.routing.yml | 8 ++++ .../src/Controller/CommentTestController.php | 25 ++++++++++ .../tests/src/Unit/CommentLinkBuilderTest.php | 16 +++---- .../src/Controller/ConfigController.php | 3 +- core/modules/config/src/Form/ConfigSync.php | 21 ++------- .../config/src/Tests/ConfigEntityListTest.php | 23 +++++---- .../config_translation.module | 3 +- .../src/ConfigEntityMapper.php | 5 +- .../src/ConfigNamesMapper.php | 26 ++-------- .../ConfigTranslationController.php | 14 ++---- .../tests/src/Unit/ConfigEntityMapperTest.php | 7 +-- .../tests/src/Unit/ConfigNamesMapperTest.php | 25 +++++++++- .../content_translation.module | 3 +- .../ContentTranslationController.php | 14 ++++-- .../src/Element/ContextualLinks.php | 4 +- .../EntityReferenceLabelFormatter.php | 6 ++- core/modules/field_ui/field_ui.module | 9 ++-- core/modules/field_ui/src/DisplayOverview.php | 13 ++--- .../field_ui/src/DisplayOverviewBase.php | 14 ++---- .../src/EntityDisplayModeListBuilder.php | 3 +- .../field_ui/src/FieldConfigListBuilder.php | 3 +- core/modules/field_ui/src/FieldOverview.php | 4 +- core/modules/field_ui/src/FieldUI.php | 2 + .../field_ui/src/FormDisplayOverview.php | 13 ++--- .../field_ui/src/Tests/ManageFieldsTest.php | 2 +- core/modules/forum/forum.module | 38 ++------------- core/modules/forum/src/Form/ForumForm.php | 5 +- core/modules/forum/src/Form/Overview.php | 17 ++++--- .../forum/src/Plugin/Block/ForumBlockBase.php | 3 +- core/modules/forum/src/Tests/ForumTest.php | 3 +- .../help/src/Controller/HelpController.php | 2 +- .../image/src/Form/ImageEffectFormBase.php | 3 +- .../image/src/Form/ImageStyleEditForm.php | 11 ++++- .../image/src/ImageStyleListBuilder.php | 3 +- core/modules/language/language.admin.inc | 3 +- .../src/ConfigurableLanguageManager.php | 5 +- .../src/Form/NegotiationConfigureForm.php | 5 +- .../src/LanguageSwitcherInterface.php | 7 +-- .../src/Plugin/Block/LanguageBlock.php | 5 +- .../LanguageNegotiationBrowser.php | 2 +- .../LanguageNegotiationSelected.php | 2 +- .../LanguageNegotiationSession.php | 7 +-- .../LanguageNegotiationUrl.php | 7 +-- .../src/Controller/LanguageTestController.php | 7 +-- .../Field/FieldFormatter/LinkFormatter.php | 8 +--- .../Plugin/Field/FieldWidget/LinkWidget.php | 2 + .../src/Plugin/Menu/MenuLinkContent.php | 16 ++----- core/modules/menu_ui/src/MenuForm.php | 12 ++--- core/modules/menu_ui/src/MenuListBuilder.php | 3 +- .../node/src/Controller/NodeController.php | 6 +-- .../modules/node/src/Form/NodePreviewForm.php | 3 +- core/modules/node/src/NodeListBuilder.php | 3 +- core/modules/node/src/NodeViewBuilder.php | 2 +- .../src/Plugin/views/area/ListingEmpty.php | 3 +- .../path/src/Controller/PathController.php | 13 ++--- .../src/ResponsiveImageMappingListBuilder.php | 3 +- .../search/src/SearchPageListBuilder.php | 8 ++-- core/modules/shortcut/shortcut.module | 10 ++-- core/modules/shortcut/src/Entity/Shortcut.php | 2 +- .../shortcut/src/Form/SetCustomize.php | 4 +- .../shortcut/src/ShortcutSetListBuilder.php | 3 +- .../simpletest/src/AssertContentTrait.php | 4 +- .../src/Form/SimpletestResultsForm.php | 3 +- .../src/Controller/DbUpdateController.php | 10 ++-- .../src/Controller/SystemController.php | 12 ++--- .../system/src/Form/ModulesListForm.php | 8 ++-- .../Tests/Common/RenderElementTypesTest.php | 18 +++---- .../system/src/Tests/Common/RenderTest.php | 5 +- .../system/src/Tests/Common/RenderWebTest.php | 10 ++-- .../system/src/Tests/Common/UrlTest.php | 19 +++----- .../system/src/Tests/Theme/FunctionsTest.php | 30 +++++------- core/modules/system/system.api.php | 6 +-- .../tests/modules/ajax_test/ajax_test.module | 3 +- .../src/Controller/AjaxTestController.php | 16 ++++--- .../src/Controller/CommonTestController.php | 7 +-- .../modules/entity_test/entity_test.module | 19 ++++++-- .../entity_test/entity_test.routing.yml | 13 +++++ .../src/Form/FormTestRedirectForm.php | 2 + .../EventSubscriber/ThemeTestSubscriber.php | 3 +- .../taxonomy/src/Form/OverviewTerms.php | 12 +++-- .../Field/FieldFormatter/LinkFormatter.php | 9 ++-- .../taxonomy/src/VocabularyListBuilder.php | 6 ++- .../FieldFormatter/TelephoneLinkFormatter.php | 3 +- .../toolbar/src/Element/ToolbarItem.php | 3 +- .../modules/toolbar_test/toolbar_test.module | 2 +- core/modules/toolbar/toolbar.api.php | 7 +-- core/modules/toolbar/toolbar.module | 5 +- core/modules/user/src/RoleListBuilder.php | 3 +- core/modules/user/user.module | 10 ++-- .../views/src/Plugin/views/field/Links.php | 3 +- core/modules/views/views.theme.inc | 4 +- .../src/Form/Ajax/ReorderDisplays.php | 3 +- .../views_ui/src/Tests/DisplayPathTest.php | 4 ++ core/modules/views_ui/src/ViewEditForm.php | 28 ++++++----- core/modules/views_ui/src/ViewFormBase.php | 4 +- core/modules/views_ui/src/ViewListBuilder.php | 7 ++- core/modules/views_ui/views_ui.module | 11 +++-- core/modules/views_ui/views_ui.theme.inc | 3 +- .../Tests/Core/Form/ConfirmFormHelperTest.php | 24 +++------- .../Core/Menu/LocalActionManagerTest.php | 19 +++----- .../Drupal/Tests/Core/UnroutedUrlTest.php | 16 +++---- core/tests/Drupal/Tests/Core/UrlTest.php | 16 +++---- 138 files changed, 633 insertions(+), 636 deletions(-) create mode 100644 core/modules/comment/tests/modules/comment_test/comment_test.routing.yml create mode 100644 core/modules/comment/tests/modules/comment_test/src/Controller/CommentTestController.php diff --git a/core/includes/menu.inc b/core/includes/menu.inc index be5171e7310..c5aae17f363 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 b8430291854..47fda818a71 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 == '' ? '' : $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 01fb7dd6b4c..a0ecdcf30c3 100644 --- a/core/lib/Drupal/Core/Config/Entity/ConfigEntityListBuilder.php +++ b/core/lib/Drupal/Core/Config/Entity/ConfigEntityListBuilder.php @@ -41,13 +41,15 @@ class ConfigEntityListBuilder extends EntityListBuilder { $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 0a46a2ee21c..25acfab2418 100644 --- a/core/lib/Drupal/Core/Entity/EntityForm.php +++ b/core/lib/Drupal/Core/Entity/EntityForm.php @@ -213,7 +213,7 @@ class EntityForm extends FormBase implements EntityFormInterface { '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 eee643b5704..9e41b083373 100644 --- a/core/lib/Drupal/Core/Entity/EntityListBuilder.php +++ b/core/lib/Drupal/Core/Entity/EntityListBuilder.php @@ -118,13 +118,15 @@ class EntityListBuilder extends EntityHandlerBase implements EntityListBuilderIn $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 58f6c6b3005..19311b5695c 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 @@ namespace Drupal\Core\Field\Plugin\Field\FieldFormatter; 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 @@ class MailToFormatter extends FormatterBase { $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 762d5f38531..51e0c3bd30f 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 @@ namespace Drupal\Core\Field\Plugin\Field\FieldFormatter; 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 @@ class UriLinkFormatter extends FormatterBase { $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 a823cac3ae0..a50696b2ee7 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 @@ class UriItem extends StringItem { ); } + /** + * {@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 de98053d7ce..b58078d39e1 100644 --- a/core/lib/Drupal/Core/Form/ConfirmFormHelper.php +++ b/core/lib/Drupal/Core/Form/ConfirmFormHelper.php @@ -34,19 +34,20 @@ class ConfirmFormHelper { // 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 6fe99d6f753..ee8bd2acff9 100644 --- a/core/lib/Drupal/Core/Language/LanguageManager.php +++ b/core/lib/Drupal/Core/Language/LanguageManager.php @@ -11,6 +11,7 @@ use Drupal\Component\Utility\String; 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 @@ class LanguageManager implements LanguageManagerInterface { /** * {@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 e163c0cde97..783496c443c 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 @@ interface LanguageManagerInterface { * * @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 f6ee14bef18..bf86365bb34 100644 --- a/core/lib/Drupal/Core/Menu/Form/MenuLinkDefaultForm.php +++ b/core/lib/Drupal/Core/Menu/Form/MenuLinkDefaultForm.php @@ -113,7 +113,8 @@ class MenuLinkDefaultForm implements MenuLinkFormInterface, ContainerInjectionIn $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 2e4eb9258a6..68550bc8699 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\ContainerDerivativeDiscoveryDecorator; 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 @@ class LocalActionManager extends DefaultPluginManager implements LocalActionMana '#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 3914d8edfc6..5b85d7ff4dc 100644 --- a/core/lib/Drupal/Core/Menu/LocalTaskManager.php +++ b/core/lib/Drupal/Core/Menu/LocalTaskManager.php @@ -21,6 +21,7 @@ use Drupal\Core\Plugin\Factory\ContainerFactory; 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 @@ class LocalTaskManager extends DefaultPluginManager implements LocalTaskManagerI $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 fdc61df666c..ffef2558451 100644 --- a/core/lib/Drupal/Core/Menu/MenuLinkInterface.php +++ b/core/lib/Drupal/Core/Menu/MenuLinkInterface.php @@ -218,9 +218,9 @@ interface MenuLinkInterface extends PluginInspectionInterface, DerivativeInspect /** * 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 @@ interface MenuLinkInterface extends PluginInspectionInterface, DerivativeInspect * 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 474e9f55315..b785bd63af1 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 @@ class Link extends RenderElement { * @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 @@ class Link extends RenderElement { 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 d82fda8d1c8..08c539a1479 100644 --- a/core/lib/Drupal/Core/Render/Element/Table.php +++ b/core/lib/Drupal/Core/Render/Element/Table.php @@ -281,7 +281,7 @@ class Table extends FormElement { * $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 a6f0220710f..9f78645a238 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 @@ class Url { */ 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 @@ class Url { * * @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 @@ class Url { * 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 @@ class Url { * 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 f5675581974..b029327a993 100644 --- a/core/lib/Drupal/Core/Utility/LinkGenerator.php +++ b/core/lib/Drupal/Core/Utility/LinkGenerator.php @@ -109,7 +109,7 @@ class LinkGenerator implements LinkGeneratorInterface { // 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 52d1d1397b5..08d00834c67 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 @@ class UnroutedUrlAssembler implements UnroutedUrlAssemblerInterface { // 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 a37a81d29c9..a7e25fff804 100644 --- a/core/modules/aggregator/src/Controller/AggregatorController.php +++ b/core/modules/aggregator/src/Controller/AggregatorController.php @@ -11,6 +11,7 @@ use Drupal\Component\Utility\Xss; 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 @@ class AggregatorController extends ControllerBase { $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 26523ab6c44..944d9a89026 100644 --- a/core/modules/aggregator/src/FeedViewBuilder.php +++ b/core/modules/aggregator/src/FeedViewBuilder.php @@ -12,6 +12,7 @@ use Drupal\Core\Entity\EntityTypeInterface; 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 @@ class FeedViewBuilder extends EntityViewBuilder { $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 @@ class FeedViewBuilder extends EntityViewBuilder { '#title' => t('More posts about @title', 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 af193253f39..3098f085749 100644 --- a/core/modules/aggregator/src/ItemsImporter.php +++ b/core/modules/aggregator/src/ItemsImporter.php @@ -120,7 +120,7 @@ class ItemsImporter implements ItemsImporterInterface { // 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 f28ff0d0cfc..2710cedb86b 100644 --- a/core/modules/aggregator/src/Plugin/Block/AggregatorFeedBlock.php +++ b/core/modules/aggregator/src/Plugin/Block/AggregatorFeedBlock.php @@ -164,7 +164,7 @@ class AggregatorFeedBlock extends BlockBase implements ContainerFactoryPluginInt $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 5b15d02c9f6..bbeae854fd5 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 @@ class AddFeedTest extends AggregatorTestBase { $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 @@ class AddFeedTest extends AggregatorTestBase { // 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 @@ class AddFeedTest extends AggregatorTestBase { $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 94c1d4f0b77..1690b91035a 100644 --- a/core/modules/ban/src/Form/BanAdmin.php +++ b/core/modules/ban/src/Form/BanAdmin.php @@ -10,6 +10,7 @@ namespace Drupal\ban\Form; 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 @@ class BanAdmin extends FormBase { $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 cbf56ab3b6b..952bad2b97b 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 e5da65d1342..1d11f9979a1 100644 --- a/core/modules/block/src/BlockListBuilder.php +++ b/core/modules/block/src/BlockListBuilder.php @@ -16,6 +16,7 @@ use Drupal\Core\Entity\EntityStorageInterface; 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 @@ class BlockListBuilder extends ConfigEntityListBuilder implements FormInterface } $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 469267c99dd..ced19d920ca 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 ee4410c7f73..a5cbb9cb67a 100644 --- a/core/modules/book/book.module +++ b/core/modules/book/book.module @@ -12,6 +12,7 @@ use Drupal\Core\Entity\EntityInterface; 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 3079032223c..2f899371e7a 100644 --- a/core/modules/book/src/Controller/BookController.php +++ b/core/modules/book/src/Controller/BookController.php @@ -10,6 +10,7 @@ namespace Drupal\book\Controller; 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 @@ class BookController extends ControllerBase { $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 5430ee9f4ac..b460a7168b5 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 97267126998..f689b1ab039 100644 --- a/core/modules/comment/src/CommentLinkBuilder.php +++ b/core/modules/comment/src/CommentLinkBuilder.php @@ -13,6 +13,7 @@ use Drupal\Core\Extension\ModuleHandlerInterface; 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 @@ class CommentLinkBuilder implements CommentLinkBuilderInterface { '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(''), 'attributes' => array( 'class' => 'hidden', 'title' => $this->t('Jump to the first new comment of this posting.'), @@ -136,15 +138,14 @@ class CommentLinkBuilder implements CommentLinkBuilderInterface { '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 @@ class CommentLinkBuilder implements CommentLinkBuilderInterface { '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 01856239f59..4314990033b 100644 --- a/core/modules/comment/src/CommentViewBuilder.php +++ b/core/modules/comment/src/CommentViewBuilder.php @@ -17,6 +17,7 @@ use Drupal\Core\Entity\EntityTypeInterface; 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 @@ class CommentViewBuilder extends EntityViewBuilder { 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 @@ class CommentViewBuilder extends EntityViewBuilder { 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 @@ class CommentViewBuilder extends EntityViewBuilder { 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 723241ad9b9..4abff6820ac 100644 --- a/core/modules/comment/src/Form/CommentAdminOverview.php +++ b/core/modules/comment/src/Form/CommentAdminOverview.php @@ -15,6 +15,7 @@ use Drupal\Core\Entity\EntityManagerInterface; 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 @@ class CommentAdminOverview extends FormBase { 'data' => array( '#type' => 'link', '#title' => $comment->getSubject(), - ) + $comment_permalink->toRenderArray(), + '#url' => $comment_permalink, + ), ), 'author' => drupal_render($username), 'posted_in' => array( @@ -208,7 +210,8 @@ class CommentAdminOverview extends FormBase { '#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 @@ class CommentAdminOverview extends FormBase { $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 7ff9376b1a4..9fb600f6414 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 00000000000..7841048caae --- /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 00000000000..4f717552c3a --- /dev/null +++ b/core/modules/comment/tests/modules/comment_test/src/Controller/CommentTestController.php @@ -0,0 +1,25 @@ + $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 2993f283009..fdcb8f5eab9 100644 --- a/core/modules/comment/tests/src/Unit/CommentLinkBuilderTest.php +++ b/core/modules/comment/tests/src/Unit/CommentLinkBuilderTest.php @@ -9,6 +9,7 @@ namespace Drupal\Tests\comment\Unit; 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 @@ class CommentLinkBuilderTest extends UnitTestCase { 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 @@ class CommentLinkBuilderTest extends UnitTestCase { $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 @@ class CommentLinkBuilderTest extends UnitTestCase { ->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 48b31df57d9..8eb713f7784 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\ConfigManagerInterface; 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 @@ class ConfigController implements ContainerInjectionInterface { ), ), '#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 9edfab6f59b..21840a5ce63 100644 --- a/core/modules/config/src/Form/ConfigSync.php +++ b/core/modules/config/src/Form/ConfigSync.php @@ -20,7 +20,7 @@ use Drupal\Core\Config\StorageInterface; 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 @@ class ConfigSync extends FormBase { $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 @@ class ConfigSync extends FormBase { $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 b0818b9ae41..c578ff26028 100644 --- a/core/modules/config/src/Tests/ConfigEntityListTest.php +++ b/core/modules/config/src/Tests/ConfigEntityListTest.php @@ -48,21 +48,24 @@ class ConfigEntityListTest extends WebTestBase { '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 @@ class ConfigEntityListTest extends WebTestBase { '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 @@ class ConfigEntityListTest extends WebTestBase { ), ); $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 @@ class ConfigEntityListTest extends WebTestBase { '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 29ea6eb8660..32b330743b8 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 ce66ff670f7..2cbc78e38ed 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\EntityInterface; 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 @@ class ConfigEntityMapper extends ConfigNamesMapper { 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 57811d915ef..ed796af5a8d 100644 --- a/core/modules/config_translation/src/ConfigNamesMapper.php +++ b/core/modules/config_translation/src/ConfigNamesMapper.php @@ -15,6 +15,7 @@ use Drupal\Core\Plugin\PluginBase; 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 @@ class ConfigNamesMapper extends PluginBase implements ConfigMapperInterface, Con * {@inheritdoc} */ public function getBasePath() { - return $this->getPathFromRoute($this->getBaseRoute(), $this->getBaseRouteParameters()); + return Url::fromRoute($this->getBaseRouteName(), $this->getBaseRouteParameters())->getInternalPath(); } /** @@ -237,7 +238,7 @@ class ConfigNamesMapper extends PluginBase implements ConfigMapperInterface, Con * {@inheritdoc} */ public function getOverviewPath() { - return $this->getPathFromRoute($this->getOverviewRoute(), $this->getOverviewRouteParameters()); + return Url::fromRoute($this->getOverviewRouteName(), $this->getOverviewRouteParameters())->getInternalPath(); } /** @@ -334,25 +335,6 @@ class ConfigNamesMapper extends PluginBase implements ConfigMapperInterface, Con 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 @@ class ConfigNamesMapper extends PluginBase implements ConfigMapperInterface, Con 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 646d3b8531b..b6b016c9795 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\Language\LanguageManagerInterface; 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 @@ class ConfigTranslationController extends ControllerBase { 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 @@ class ConfigTranslationController extends ControllerBase { 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 69828f6be6f..2b1c67e94d7 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 @@ class ConfigEntityMapperTest extends UnitTestCase { $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 5b19122555f..50e2712a917 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 @@ namespace Drupal\Tests\config_translation\Unit; 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 @@ class ConfigNamesMapperTest extends UnitTestCase { $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 @@ class ConfigNamesMapperTest extends UnitTestCase { * 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 @@ class ConfigNamesMapperTest extends UnitTestCase { * 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 @@ class ConfigNamesMapperTest extends UnitTestCase { $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 102c67a6ecc..4d3c794429b 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 b00a11fff78..999a509fc0c 100644 --- a/core/modules/content_translation/src/Controller/ContentTranslationController.php +++ b/core/modules/content_translation/src/Controller/ContentTranslationController.php @@ -136,10 +136,11 @@ class ContentTranslationController extends ControllerBase { // 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 @@ class ContentTranslationController extends ControllerBase { if ($handler->getTranslationAccess($entity, 'delete')->isAllowed()) { $links['delete'] = array( 'title' => $this->t('Delete'), - ) + $delete_url->toArray(); + 'url' => $delete_url, + ); } } } @@ -177,7 +179,8 @@ class ContentTranslationController extends ControllerBase { 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 @@ class ContentTranslationController extends ControllerBase { // 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 180c01fb07f..e2037c38e2e 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 @@ class ContextualLinks extends RenderElement { $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 a64a4c32017..61abdb6818f 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 @@ class EntityReferenceLabelFormatter extends EntityReferenceFormatterBase { // 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 b5f6f6ef2ef..19a8f8ec74a 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 2bc07c15e18..13744946193 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\FieldTypePluginManager; 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 @@ class DisplayOverview extends DisplayOverviewBase { * {@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 94db60a595c..d41c7cb6a71 100644 --- a/core/modules/field_ui/src/DisplayOverviewBase.php +++ b/core/modules/field_ui/src/DisplayOverviewBase.php @@ -595,8 +595,8 @@ abstract class DisplayOverviewBase extends OverviewBase { } $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 configure them.', 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 configure them.', ['%display_mode' => $display_mode_label, '@url' => $url->toString()])); } $statuses[$mode] = !empty($value); } @@ -872,14 +872,8 @@ abstract class DisplayOverviewBase extends OverviewBase { * @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 2a73834dac6..6056508ca46 100644 --- a/core/modules/field_ui/src/EntityDisplayModeListBuilder.php +++ b/core/modules/field_ui/src/EntityDisplayModeListBuilder.php @@ -11,6 +11,7 @@ use Drupal\Core\Config\Entity\ConfigEntityListBuilder; 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 @@ class EntityDisplayModeListBuilder extends ConfigEntityListBuilder { $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 f4f76b59612..cae4250932e 100644 --- a/core/modules/field_ui/src/FieldConfigListBuilder.php +++ b/core/modules/field_ui/src/FieldConfigListBuilder.php @@ -66,7 +66,8 @@ class FieldConfigListBuilder extends ConfigEntityListBuilder { '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 0e42fcd6f37..838c116ea37 100644 --- a/core/modules/field_ui/src/FieldOverview.php +++ b/core/modules/field_ui/src/FieldOverview.php @@ -14,6 +14,7 @@ use Drupal\Core\Extension\ModuleHandlerInterface; 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 @@ class FieldOverview extends OverviewBase { '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 7edb1c6d831..1658c797a52 100644 --- a/core/modules/field_ui/src/FieldUI.php +++ b/core/modules/field_ui/src/FieldUI.php @@ -59,6 +59,8 @@ class FieldUI { $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 aacd42333e0..c317fd55854 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\FieldDefinitionInterface; 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 @@ class FormDisplayOverview extends DisplayOverviewBase { * {@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 ff2139541a7..2379899165d 100644 --- a/core/modules/field_ui/src/Tests/ManageFieldsTest.php +++ b/core/modules/field_ui/src/Tests/ManageFieldsTest.php @@ -106,7 +106,7 @@ class ManageFieldsTest extends FieldUiTestBase { $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 1b15b3e899b..10b7366b9f9 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 = '

' . t('Forums contain forum topics. Use containers to group related forums.') . '

'; $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('Log in 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 6a8131a115f..fc51a32eb1b 100644 --- a/core/modules/forum/src/Form/ForumForm.php +++ b/core/modules/forum/src/Form/ForumForm.php @@ -107,10 +107,7 @@ class ForumForm extends TermForm { $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 eb05b3ac6df..8469f55a521 100644 --- a/core/modules/forum/src/Form/Overview.php +++ b/core/modules/forum/src/Form/Overview.php @@ -10,6 +10,7 @@ namespace Drupal\forum\Form; 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 @@ class Overview extends OverviewTerms { 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 f480892c530..17c31470b32 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\Block\BlockBase; 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 @@ abstract class ForumBlockBase extends BlockBase { $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 ebda138ac36..adbd2a4456d 100644 --- a/core/modules/forum/src/Tests/ForumTest.php +++ b/core/modules/forum/src/Tests/ForumTest.php @@ -121,7 +121,8 @@ class ForumTest extends WebTestBase { $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 80ae8f44565..2de0a53905c 100644 --- a/core/modules/help/src/Controller/HelpController.php +++ b/core/modules/help/src/Controller/HelpController.php @@ -126,7 +126,7 @@ class HelpController extends ControllerBase { 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 52d5b2c505e..addbcf6451e 100644 --- a/core/modules/image/src/Form/ImageEffectFormBase.php +++ b/core/modules/image/src/Form/ImageEffectFormBase.php @@ -96,7 +96,8 @@ abstract class ImageEffectFormBase extends FormBase { $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 8703ee6aa82..4edd31c7945 100644 --- a/core/modules/image/src/Form/ImageStyleEditForm.php +++ b/core/modules/image/src/Form/ImageStyleEditForm.php @@ -10,6 +10,7 @@ namespace Drupal\image\Form; 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 @@ class ImageStyleEditForm extends ImageStyleFormBase { 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 73dfe6c80ea..b0ad2275714 100644 --- a/core/modules/image/src/ImageStyleListBuilder.php +++ b/core/modules/image/src/ImageStyleListBuilder.php @@ -78,7 +78,8 @@ class ImageStyleListBuilder extends ConfigEntityListBuilder { $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 d5e5b7f7306..d7a041514c2 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 dbb68d21bbc..15c40ae9504 100644 --- a/core/modules/language/src/ConfigurableLanguageManager.php +++ b/core/modules/language/src/ConfigurableLanguageManager.php @@ -14,6 +14,7 @@ use Drupal\Core\Extension\ModuleHandlerInterface; 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 @@ class ConfigurableLanguageManager extends LanguageManager implements Configurabl /** * {@inheritdoc} */ - public function getLanguageSwitchLinks($type, $path) { + public function getLanguageSwitchLinks($type, Url $url) { $links = FALSE; if ($this->negotiator) { @@ -403,7 +404,7 @@ class ConfigurableLanguageManager extends LanguageManager implements Configurabl $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 83eb5670ebc..c7495e9bf8a 100644 --- a/core/modules/language/src/Form/NegotiationConfigureForm.php +++ b/core/modules/language/src/Form/NegotiationConfigureForm.php @@ -16,6 +16,7 @@ use Drupal\Core\Entity\EntityStorageInterface; 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 @@ class NegotiationConfigureForm extends FormBase { $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 d6edd5b2e6c..0550dd47f6a 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 a3aba84ef2c..0502d2d610c 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\Block\BlockBase; 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 @@ class LanguageBlock extends BlockBase implements ContainerFactoryPluginInterface */ public function build() { $build = array(); - $path = drupal_is_front_page() ? '' : current_path(); + $route_name = drupal_is_front_page() ? '' : ''; $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 0ce2c86c694..e9fc38e00e8 100644 --- a/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationBrowser.php +++ b/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationBrowser.php @@ -20,7 +20,7 @@ use Symfony\Component\HttpFoundation\Request; * 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 4819abfd865..c4cd150b3b4 100644 --- a/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationSelected.php +++ b/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationSelected.php @@ -18,7 +18,7 @@ use Symfony\Component\HttpFoundation\Request; * 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 dc5617d20bf..7f0085d9317 100644 --- a/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationSession.php +++ b/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationSession.php @@ -9,6 +9,7 @@ namespace Drupal\language\Plugin\LanguageNegotiation; 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 @@ use Symfony\Component\HttpFoundation\Request; * 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 @@ class LanguageNegotiationSession extends LanguageNegotiationMethodBase implement /** * {@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 @@ class LanguageNegotiationSession extends LanguageNegotiationMethodBase implement 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 be9f91561b9..0b46727008d 100644 --- a/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationUrl.php +++ b/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationUrl.php @@ -10,6 +10,7 @@ namespace Drupal\language\Plugin\LanguageNegotiation; 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 @@ use Symfony\Component\HttpFoundation\Request; * 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 @@ class LanguageNegotiationUrl extends LanguageNegotiationMethodBase implements In /** * {@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 a5cb033a3be..6766d4a7634 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 @@ namespace Drupal\language_test\Controller; 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 @@ class LanguageTestController implements ContainerInjectionInterface { 'no_language' => array( '#type' => 'link', '#title' => t('Link to the current path with no langcode provided.'), - '#route_name' => '', + '#url' => Url::fromRoute(''), '#options' => array( 'attributes' => array( 'id' => 'no_lang_link', @@ -73,7 +74,7 @@ class LanguageTestController implements ContainerInjectionInterface { 'fr' => array( '#type' => 'link', '#title' => t('Link to a French version of the current path.'), - '#route_name' => '', + '#url' => Url::fromRoute(''), '#options' => array( 'language' => $languages['fr'], 'attributes' => array( @@ -85,7 +86,7 @@ class LanguageTestController implements ContainerInjectionInterface { 'en' => array( '#type' => 'link', '#title' => t('Link to an English version of the current path.'), - '#route_name' => '', + '#url' => Url::fromRoute(''), '#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 ca753f8827b..3aabb67a10e 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 @@ class LinkFormatter extends FormatterBase { '#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 21e078f12ba..e0666d90d30 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 @@ class LinkWidget extends WidgetBase { 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 ea47019859a..8e3433bc0e1 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 @@ class MenuLinkContent extends MenuLinkBase implements ContainerFactoryPluginInte * {@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 720aa2b2908..d0b904edfe5 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\MenuLinkTreeInterface; 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 @@ class MenuForm extends EntityForm { // 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 @@ class MenuForm extends EntityForm { 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 4fdb29841c8..7e987f1e0a2 100644 --- a/core/modules/menu_ui/src/MenuListBuilder.php +++ b/core/modules/menu_ui/src/MenuListBuilder.php @@ -54,7 +54,8 @@ class MenuListBuilder extends ConfigEntityListBuilder { $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 64fc4f6ce65..33c5989751b 100644 --- a/core/modules/node/src/Controller/NodeController.php +++ b/core/modules/node/src/Controller/NodeController.php @@ -184,16 +184,14 @@ class NodeController extends ControllerBase implements ContainerInjectionInterfa 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 81fd61c206e..52f0267d300 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\EntityInterface; 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 @@ class NodePreviewForm extends FormBase implements ContainerInjectionInterface { $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 c78915d6666..606da79b6a1 100644 --- a/core/modules/node/src/NodeListBuilder.php +++ b/core/modules/node/src/NodeListBuilder.php @@ -105,7 +105,8 @@ class NodeListBuilder extends EntityListBuilder { '#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 8cf1c040f43..11364282e0e 100644 --- a/core/modules/node/src/NodeViewBuilder.php +++ b/core/modules/node/src/NodeViewBuilder.php @@ -146,7 +146,7 @@ class NodeViewBuilder extends EntityViewBuilder { 'title' => t('Read more about @title', 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 cba41c288c7..8804f2e9a70 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 @@ class ListingEmpty extends AreaPluginBase { '#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 96dd34b7bdc..5f6f3c6bf9d 100644 --- a/core/modules/path/src/Controller/PathController.php +++ b/core/modules/path/src/Controller/PathController.php @@ -10,6 +10,7 @@ namespace Drupal\path\Controller; 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 @@ class PathController extends ControllerBase { $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 b12fb61f8ee..6032b7c12d5 100644 --- a/core/modules/responsive_image/src/ResponsiveImageMappingListBuilder.php +++ b/core/modules/responsive_image/src/ResponsiveImageMappingListBuilder.php @@ -41,7 +41,8 @@ class ResponsiveImageMappingListBuilder extends ConfigEntityListBuilder { $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 5714f0a3545..93b87ef3f3c 100644 --- a/core/modules/search/src/SearchPageListBuilder.php +++ b/core/modules/search/src/SearchPageListBuilder.php @@ -14,6 +14,7 @@ use Drupal\Core\Entity\EntityStorageInterface; 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 @@ class SearchPageListBuilder extends DraggableListBuilder implements FormInterfac $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 @@ class SearchPageListBuilder extends DraggableListBuilder implements FormInterfac 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 2575128894a..f21d00fa936 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' => '', ); @@ -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 75d5b2283d5..9734109fcd3 100644 --- a/core/modules/shortcut/src/Entity/Shortcut.php +++ b/core/modules/shortcut/src/Entity/Shortcut.php @@ -115,7 +115,7 @@ class Shortcut extends ContentEntityBase implements ShortcutInterface { * {@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 e778d8c769e..2d026b56096 100644 --- a/core/modules/shortcut/src/Form/SetCustomize.php +++ b/core/modules/shortcut/src/Form/SetCustomize.php @@ -64,11 +64,11 @@ class SetCustomize extends EntityForm { $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 907f470c65f..9de658d668f 100644 --- a/core/modules/shortcut/src/ShortcutSetListBuilder.php +++ b/core/modules/shortcut/src/ShortcutSetListBuilder.php @@ -37,7 +37,8 @@ class ShortcutSetListBuilder extends ConfigEntityListBuilder { $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 7c28b042c56..0836987bf0b 100644 --- a/core/modules/simpletest/src/AssertContentTrait.php +++ b/core/modules/simpletest/src/AssertContentTrait.php @@ -742,8 +742,8 @@ trait AssertContentTrait { */ protected function assertThemeOutput($callback, array $variables = array(), $expected = '', $message = '', $group = 'Other') { $output = \Drupal::theme()->render($callback, $variables); - $this->verbose('Variables:' . '
' . String::checkPlain(var_export($variables, TRUE)) . '
' - . '
' . 'Result:' . '
' . String::checkPlain(var_export($output, TRUE)) . '
' + $this->verbose( + '
' . 'Result:' . '
' . String::checkPlain(var_export($output, TRUE)) . '
' . '
' . 'Expected:' . '
' . String::checkPlain(var_export($expected, TRUE)) . '
' . '
' . $output ); diff --git a/core/modules/simpletest/src/Form/SimpletestResultsForm.php b/core/modules/simpletest/src/Form/SimpletestResultsForm.php index 56d4f59a2bd..7d39496a13f 100644 --- a/core/modules/simpletest/src/Form/SimpletestResultsForm.php +++ b/core/modules/simpletest/src/Form/SimpletestResultsForm.php @@ -12,6 +12,7 @@ use Drupal\Core\Database\Connection; 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 @@ class SimpletestResultsForm extends FormBase { $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 2f987720acd..7dff04a586a 100644 --- a/core/modules/system/src/Controller/DbUpdateController.php +++ b/core/modules/system/src/Controller/DbUpdateController.php @@ -216,7 +216,8 @@ class DbUpdateController extends ControllerBase { '#type' => 'link', '#title' => $this->t('Continue'), '#attributes' => array('class' => array('button', 'button--primary')), - ) + $url->toRenderArray(); + '#url' => $url, + ); return $build; } @@ -347,7 +348,8 @@ class DbUpdateController extends ControllerBase { '#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 @@ class DbUpdateController extends ControllerBase { protected function helpfulLinks() { $links['front'] = array( 'title' => $this->t('Front page'), - 'href' => '', + 'url' => Url::fromRoute(''), ); 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 5f2ca3f70e6..0980b0a3f6a 100644 --- a/core/modules/system/src/Controller/SystemController.php +++ b/core/modules/system/src/Controller/SystemController.php @@ -15,6 +15,7 @@ use Drupal\Core\Form\FormBuilderInterface; 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 @@ class SystemController extends ControllerBase { 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 @@ class SystemController extends ControllerBase { 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 @@ class SystemController extends ControllerBase { 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 23505fa39dd..5f85624ffb7 100644 --- a/core/modules/system/src/Form/ModulesListForm.php +++ b/core/modules/system/src/Form/ModulesListForm.php @@ -22,6 +22,7 @@ use Drupal\Core\Render\Element; 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 @@ class ModulesListForm extends FormBase { $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 @@ class ModulesListForm extends FormBase { $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 @@ class ModulesListForm extends FormBase { $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 9757a2b67a5..f3f27abd4e8 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 @@ class RenderElementTypesTest extends DrupalUnitTestBase { '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 @@ class RenderElementTypesTest extends DrupalUnitTestBase { '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 @@ class RenderElementTypesTest extends DrupalUnitTestBase { '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 @@ class RenderElementTypesTest extends DrupalUnitTestBase { '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 @@ class RenderElementTypesTest extends DrupalUnitTestBase { '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 @@ class RenderElementTypesTest extends DrupalUnitTestBase { 'name' => "#type 'more_link' anchor tag to the front page", 'value' => array( '#type' => 'more_link', - '#href' => '', + '#url' => Url::fromRoute(''), ), 'expected' => '//div[@class="more-link"]/a[@href="' . _url('') . '" and text()="More"]', ), diff --git a/core/modules/system/src/Tests/Common/RenderTest.php b/core/modules/system/src/Tests/Common/RenderTest.php index 6c286cab016..56c2f3909b1 100644 --- a/core/modules/system/src/Tests/Common/RenderTest.php +++ b/core/modules/system/src/Tests/Common/RenderTest.php @@ -10,6 +10,7 @@ namespace Drupal\system\Tests\Common; 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 @@ class RenderTest extends DrupalUnitTestBase { ), ), '#attributes' => array('id' => 'foo'), - '#href' => 'http://drupal.org', + '#url' => Url::fromUri('http://drupal.org'), '#title' => 'bar', ), 'expected' => '' . "\n", @@ -131,7 +132,7 @@ class RenderTest extends DrupalUnitTestBase { '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 3e58fb0e849..05a9cbe7543 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 @@ class RenderWebTest extends WebTestBase { $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 @@ class RenderWebTest extends WebTestBase { protected function assertRenderedElement(array $element, $xpath, array $xpath_args = array()) { $original_element = $element; $this->drupalSetContent(drupal_render($element)); - $this->verbose('
' .  String::checkPlain(var_export($original_element, TRUE)) . '
' - . '
' .  String::checkPlain(var_export($element, TRUE)) . '
' - . '
' . $this->drupalGetContent() - ); + $this->verbose('
' . $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 3ac4bc4ebca..e316eaa6fbc 100644 --- a/core/modules/system/src/Tests/Common/UrlTest.php +++ b/core/modules/system/src/Tests/Common/UrlTest.php @@ -39,15 +39,10 @@ class UrlTest extends WebTestBase { $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 @@ class UrlTest extends WebTestBase { '#options' => array( 'language' => $language, ), - '#href' => 'http://drupal.org', + '#url' => Url::fromUri('http://drupal.org'), '#title' => 'bar', ); $langcode = $language->id; @@ -123,7 +118,7 @@ class UrlTest extends WebTestBase { $type_link = array( '#type' => 'link', '#title' => $this->randomMachineName(), - '#route_name' => '', + '#url' => Url::fromRoute(''), '#options' => array( 'attributes' => array( 'class' => array($class_theme), @@ -150,7 +145,7 @@ class UrlTest extends WebTestBase { $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 @@ class UrlTest extends WebTestBase { $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 c8d068cb747..6433a6495a2 100644 --- a/core/modules/system/src/Tests/Theme/FunctionsTest.php +++ b/core/modules/system/src/Tests/Theme/FunctionsTest.php @@ -10,6 +10,7 @@ namespace Drupal\system\Tests\Theme; 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 @@ class FunctionsTest extends WebTestBase { $variables['links'] = array( 'a link' => array( 'title' => 'A ', - 'href' => 'a/link', + 'url' => Url::fromUri('base://a/link'), ), 'plain text' => array( 'title' => 'Plain "text"', ), 'front page' => array( 'title' => 'Front page', - 'href' => '', + 'url' => Url::fromRoute(''), ), '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 @@ class FunctionsTest extends WebTestBase { $expected_links = ''; $expected_links .= '