diff --git a/core/lib/Drupal/Core/Link.php b/core/lib/Drupal/Core/Link.php index e435d4427910..c4fbd0dfc358 100644 --- a/core/lib/Drupal/Core/Link.php +++ b/core/lib/Drupal/Core/Link.php @@ -3,7 +3,7 @@ namespace Drupal\Core; use Drupal\Core\Render\RenderableInterface; -use Drupal\Core\Routing\LinkGeneratorTrait; +use Drupal\Core\Utility\LinkGeneratorInterface; /** * Defines an object that holds information about a link. @@ -11,9 +11,11 @@ use Drupal\Core\Routing\LinkGeneratorTrait; class Link implements RenderableInterface { /** - * @deprecated in Drupal 8.0.x-dev, will be removed before Drupal 9.0.0. + * The link generator. + * + * @var \Drupal\Core\Utility\LinkGeneratorInterface */ - use LinkGeneratorTrait; + protected $linkGenerator; /** * The text of the link. @@ -147,4 +149,31 @@ class Link implements RenderableInterface { ]; } + /** + * Returns the link generator. + * + * @return \Drupal\Core\Utility\LinkGeneratorInterface + * The link generator + */ + protected function getLinkGenerator() { + if (!isset($this->linkGenerator)) { + $this->linkGenerator = \Drupal::service('link_generator'); + } + return $this->linkGenerator; + } + + /** + * Sets the link generator service. + * + * @param \Drupal\Core\Utility\LinkGeneratorInterface $generator + * The link generator service. + * + * @return $this + */ + public function setLinkGenerator(LinkGeneratorInterface $generator) { + $this->linkGenerator = $generator; + + return $this; + } + } diff --git a/core/lib/Drupal/Core/Logger/LoggerChannelInterface.php b/core/lib/Drupal/Core/Logger/LoggerChannelInterface.php index b7d350183b7f..8764535f71b9 100644 --- a/core/lib/Drupal/Core/Logger/LoggerChannelInterface.php +++ b/core/lib/Drupal/Core/Logger/LoggerChannelInterface.php @@ -29,7 +29,7 @@ use Symfony\Component\HttpFoundation\RequestStack; * @see \Psr\Log\LoggerInterface * @see \Drupal\Core\Logger\\LoggerChannelFactoryInterface * @see \Drupal\Core\Utility\LinkGeneratorInterface - * @see \Drupal\Core\Routing\LinkGeneratorTrait::l() + * @see \Drupal\Core\Link::fromTextAndUrl() * @see \Drupal\Core\Entity\EntityInterface::link() */ interface LoggerChannelInterface extends LoggerInterface { diff --git a/core/lib/Drupal/Core/Routing/LinkGeneratorTrait.php b/core/lib/Drupal/Core/Routing/LinkGeneratorTrait.php index 2cda6df9856c..4604058095d2 100644 --- a/core/lib/Drupal/Core/Routing/LinkGeneratorTrait.php +++ b/core/lib/Drupal/Core/Routing/LinkGeneratorTrait.php @@ -37,13 +37,14 @@ trait LinkGeneratorTrait { * A GeneratedLink object containing a link to the given route and * parameters and bubbleable metadata. * - * @deprecated in Drupal 8.0.0 and will be removed before Drupal 9.0.0. - * Use \Drupal\Core\Link instead. + * @deprecated in drupal:8.0.0 and is removed from drupal:9.0.0. Use + * \Drupal\Core\Link::fromTextAndUrl() instead. * * @see https://www.drupal.org/node/2614344 * @see \Drupal\Core\Utility\LinkGeneratorInterface::generate() */ protected function l($text, Url $url) { + @trigger_error(__NAMESPACE__ . "\LinkGeneratorTrait::l() is deprecated in drupal:8.0.0 and is removed from drupal:9.0.0. Use \Drupal\Core\Link::fromTextAndUrl() instead. See https://www.drupal.org/node/2614344", E_USER_DEPRECATED); return $this->getLinkGenerator()->generate($text, $url); } @@ -52,8 +53,14 @@ trait LinkGeneratorTrait { * * @return \Drupal\Core\Utility\LinkGeneratorInterface * The link generator + * + * @deprecated in drupal:8.0.0 and is removed from drupal:9.0.0. Inject the + * 'link_generator' service or use \Drupal\Core\Link instead + * + * @see https://www.drupal.org/node/2614344 */ protected function getLinkGenerator() { + @trigger_error(__NAMESPACE__ . "\LinkGeneratorTrait::getLinkGenerator() is deprecated in drupal:8.0.0 and is removed from drupal:9.0.0. Inject the 'link_generator' service or use \Drupal\Core\Link instead. See https://www.drupal.org/node/2614344", E_USER_DEPRECATED); if (!isset($this->linkGenerator)) { $this->linkGenerator = \Drupal::service('link_generator'); } @@ -67,8 +74,14 @@ trait LinkGeneratorTrait { * The link generator service. * * @return $this + * + * @deprecated in drupal:8.0.0 and is removed from drupal:9.0.0. Inject the + * 'link_generator' service or use \Drupal\Core\Link instead + * + * @see https://www.drupal.org/node/2614344 */ public function setLinkGenerator(LinkGeneratorInterface $generator) { + @trigger_error(__NAMESPACE__ . "\LinkGeneratorTrait::setLinkGenerator() is deprecated in drupal:8.0.0 and is removed from drupal:9.0.0. Inject the 'link_generator' service or use \Drupal\Core\Link instead. See https://www.drupal.org/node/2614344", E_USER_DEPRECATED); $this->linkGenerator = $generator; return $this; diff --git a/core/modules/aggregator/src/FeedForm.php b/core/modules/aggregator/src/FeedForm.php index 5077e7d8d53d..86978e346a08 100644 --- a/core/modules/aggregator/src/FeedForm.php +++ b/core/modules/aggregator/src/FeedForm.php @@ -4,6 +4,7 @@ namespace Drupal\aggregator; use Drupal\Core\Entity\ContentEntityForm; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Link; use Drupal\Core\Url; /** @@ -26,7 +27,7 @@ class FeedForm extends ContentEntityForm { $form_state->setRedirectUrl($feed->toUrl('canonical')); } else { - $this->logger('aggregator')->notice('Feed %feed added.', ['%feed' => $feed->label(), 'link' => $this->l($this->t('View'), new Url('aggregator.admin_overview'))]); + $this->logger('aggregator')->notice('Feed %feed added.', ['%feed' => $feed->label(), 'link' => Link::fromTextAndUrl($this->t('View'), new Url('aggregator.admin_overview'))->toString()]); $this->messenger()->addStatus($this->t('The feed %feed has been added.', ['%feed' => $view_link])); } } diff --git a/core/modules/book/src/Controller/BookController.php b/core/modules/book/src/Controller/BookController.php index 998fa16c5b41..bb09ae971966 100644 --- a/core/modules/book/src/Controller/BookController.php +++ b/core/modules/book/src/Controller/BookController.php @@ -5,6 +5,7 @@ namespace Drupal\book\Controller; use Drupal\book\BookExport; use Drupal\book\BookManagerInterface; use Drupal\Core\Controller\ControllerBase; +use Drupal\Core\Link; use Drupal\Core\Render\RendererInterface; use Drupal\Core\Url; use Drupal\node\NodeInterface; @@ -84,7 +85,7 @@ class BookController extends ControllerBase { $url->setOptions($book['options']); } $row = [ - $this->l($book['title'], $url), + Link::fromTextAndUrl($book['title'], $url), ]; $links = []; $links['edit'] = [ @@ -116,7 +117,7 @@ class BookController extends ControllerBase { public function bookRender() { $book_list = []; foreach ($this->bookManager->getAllBooks() as $book) { - $book_list[] = $this->l($book['title'], $book['url']); + $book_list[] = Link::fromTextAndUrl($book['title'], $book['url']); } return [ '#theme' => 'item_list', diff --git a/core/modules/comment/src/CommentForm.php b/core/modules/comment/src/CommentForm.php index 952c9d139b9d..f70bcff77ae8 100644 --- a/core/modules/comment/src/CommentForm.php +++ b/core/modules/comment/src/CommentForm.php @@ -13,6 +13,7 @@ use Drupal\Core\Entity\EntityFieldManagerInterface; use Drupal\Core\Entity\EntityRepositoryInterface; use Drupal\Core\Entity\EntityTypeBundleInfoInterface; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Link; use Drupal\Core\Render\RendererInterface; use Drupal\Core\Session\AccountInterface; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -379,7 +380,7 @@ class CommentForm extends ContentEntityForm { // Add a log entry. $logger->notice('Comment posted: %subject.', [ '%subject' => $comment->getSubject(), - 'link' => $this->l(t('View'), $comment->toUrl()->setOption('fragment', 'comment-' . $comment->id())), + 'link' => Link::fromTextAndUrl(t('View'), $comment->toUrl()->setOption('fragment', 'comment-' . $comment->id()))->toString(), ]); // Explain the approval queue if necessary. diff --git a/core/modules/content_translation/src/Controller/ContentTranslationController.php b/core/modules/content_translation/src/Controller/ContentTranslationController.php index 22c5a4098212..d7bdff90a95a 100644 --- a/core/modules/content_translation/src/Controller/ContentTranslationController.php +++ b/core/modules/content_translation/src/Controller/ContentTranslationController.php @@ -9,6 +9,7 @@ use Drupal\Core\Controller\ControllerBase; use Drupal\Core\Entity\ContentEntityInterface; use Drupal\Core\Entity\EntityFieldManagerInterface; use Drupal\Core\Language\LanguageInterface; +use Drupal\Core\Link; use Drupal\Core\Routing\RouteMatchInterface; use Drupal\Core\Url; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -189,7 +190,7 @@ class ContentTranslationController extends ControllerBase { $link = isset($links->links[$langcode]['url']) ? $links->links[$langcode] : ['url' => $entity->toUrl()]; if (!empty($link['url'])) { $link['url']->setOption('language', $language); - $row_title = $this->l($label, $link['url']); + $row_title = Link::fromTextAndUrl($label, $link['url'])->toString(); } if (empty($link['url'])) { diff --git a/core/modules/dblog/src/Controller/DbLogController.php b/core/modules/dblog/src/Controller/DbLogController.php index 54bc7ea6cabf..5b1ec80e478b 100644 --- a/core/modules/dblog/src/Controller/DbLogController.php +++ b/core/modules/dblog/src/Controller/DbLogController.php @@ -188,14 +188,14 @@ class DbLogController extends ControllerBase { $log_text = Unicode::truncate($title, 56, TRUE, TRUE); // The link generator will escape any unsafe HTML entities in the final // text. - $message = $this->l($log_text, new Url('dblog.event', ['event_id' => $dblog->wid], [ + $message = Link::fromTextAndUrl($log_text, new Url('dblog.event', ['event_id' => $dblog->wid], [ 'attributes' => [ // Provide a title for the link for useful hover hints. The // Attribute object will escape any unsafe HTML entities in the // final text. 'title' => $title, ], - ])); + ]))->toString(); } $username = [ '#theme' => 'username', diff --git a/core/modules/forum/src/Form/ForumForm.php b/core/modules/forum/src/Form/ForumForm.php index 73f5e8f1bfb3..75264cc4d578 100644 --- a/core/modules/forum/src/Form/ForumForm.php +++ b/core/modules/forum/src/Form/ForumForm.php @@ -3,6 +3,7 @@ namespace Drupal\forum\Form; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Link; use Drupal\Core\Url; use Drupal\taxonomy\TermForm; @@ -78,7 +79,7 @@ class ForumForm extends TermForm { $route_name = $this->urlStub == 'container' ? 'entity.taxonomy_term.forum_edit_container_form' : 'entity.taxonomy_term.forum_edit_form'; $route_parameters = ['taxonomy_term' => $term->id()]; - $link = $this->l($this->t('Edit'), new Url($route_name, $route_parameters)); + $link = Link::fromTextAndUrl($this->t('Edit'), new Url($route_name, $route_parameters))->toString(); $view_link = $term->toLink($term->getName())->toString(); switch ($status) { case SAVED_NEW: diff --git a/core/modules/node/src/Controller/NodeController.php b/core/modules/node/src/Controller/NodeController.php index 58712f37261e..e355d5e53ec6 100644 --- a/core/modules/node/src/Controller/NodeController.php +++ b/core/modules/node/src/Controller/NodeController.php @@ -7,6 +7,7 @@ use Drupal\Core\Controller\ControllerBase; use Drupal\Core\Datetime\DateFormatterInterface; use Drupal\Core\DependencyInjection\ContainerInjectionInterface; use Drupal\Core\Entity\EntityRepositoryInterface; +use Drupal\Core\Link; use Drupal\Core\Render\RendererInterface; use Drupal\Core\Url; use Drupal\node\NodeStorageInterface; @@ -211,7 +212,7 @@ class NodeController extends ControllerBase implements ContainerInjectionInterfa // this case. $is_current_revision = $vid == $default_revision || (!$current_revision_displayed && $revision->wasDefaultRevision()); if (!$is_current_revision) { - $link = $this->l($date, new Url('entity.node.revision', ['node' => $node->id(), 'node_revision' => $vid])); + $link = Link::fromTextAndUrl($date, new Url('entity.node.revision', ['node' => $node->id(), 'node_revision' => $vid]))->toString(); } else { $link = $node->toLink($date)->toString(); diff --git a/core/modules/path/src/Controller/PathController.php b/core/modules/path/src/Controller/PathController.php index 26fe851710c9..3577bc826909 100644 --- a/core/modules/path/src/Controller/PathController.php +++ b/core/modules/path/src/Controller/PathController.php @@ -4,6 +4,7 @@ namespace Drupal\path\Controller; use Drupal\Component\Utility\Unicode; use Drupal\Core\Controller\ControllerBase; +use Drupal\Core\Link; use Drupal\Core\Path\AliasStorageInterface; use Drupal\Core\Path\AliasManagerInterface; use Drupal\Core\Url; @@ -84,13 +85,13 @@ class PathController extends ControllerBase { $row = []; // @todo Should Path module store leading slashes? See // https://www.drupal.org/node/2430593. - $row['data']['alias'] = $this->l(Unicode::truncate($data->alias, 50, FALSE, TRUE), Url::fromUserInput($data->source, [ + $row['data']['alias'] = Link::fromTextAndUrl(Unicode::truncate($data->alias, 50, FALSE, TRUE), Url::fromUserInput($data->source, [ 'attributes' => ['title' => $data->alias], - ])); - $row['data']['source'] = $this->l(Unicode::truncate($data->source, 50, FALSE, TRUE), Url::fromUserInput($data->source, [ + ]))->toString(); + $row['data']['source'] = Link::fromTextAndUrl(Unicode::truncate($data->source, 50, FALSE, TRUE), Url::fromUserInput($data->source, [ 'alias' => TRUE, 'attributes' => ['title' => $data->source], - ])); + ]))->toString(); if ($multilanguage) { $row['data']['language_name'] = $this->languageManager()->getLanguageName($data->langcode); } diff --git a/core/modules/update/src/Form/UpdateManagerUpdate.php b/core/modules/update/src/Form/UpdateManagerUpdate.php index e17d214bb7d7..c42928e8d240 100644 --- a/core/modules/update/src/Form/UpdateManagerUpdate.php +++ b/core/modules/update/src/Form/UpdateManagerUpdate.php @@ -5,6 +5,7 @@ namespace Drupal\update\Form; use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Form\FormBase; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Link; use Drupal\Core\State\StateInterface; use Drupal\Core\Url; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -108,7 +109,7 @@ class UpdateManagerUpdate extends FormBase { // The project name to display can vary based on the info we have. if (!empty($project['title'])) { if (!empty($project['link'])) { - $project_name = $this->l($project['title'], Url::fromUri($project['link'])); + $project_name = Link::fromTextAndUrl($project['title'], Url::fromUri($project['link']))->toString(); } else { $project_name = $project['title']; diff --git a/core/modules/views_ui/src/Controller/ViewsUIController.php b/core/modules/views_ui/src/Controller/ViewsUIController.php index fe3d1595bc67..92a258558ba2 100644 --- a/core/modules/views_ui/src/Controller/ViewsUIController.php +++ b/core/modules/views_ui/src/Controller/ViewsUIController.php @@ -3,6 +3,7 @@ namespace Drupal\views_ui\Controller; use Drupal\Core\Controller\ControllerBase; +use Drupal\Core\Link; use Drupal\Core\Url; use Drupal\views\ViewExecutable; use Drupal\views\ViewEntityInterface; @@ -86,7 +87,7 @@ class ViewsUIController extends ControllerBase { foreach ($fields as $field_name => $views) { $rows[$field_name]['data'][0]['data']['#plain_text'] = $field_name; foreach ($views as $view) { - $rows[$field_name]['data'][1][] = $this->l($view, new Url('entity.view.edit_form', ['view' => $view])); + $rows[$field_name]['data'][1][] = Link::fromTextAndUrl($view, new Url('entity.view.edit_form', ['view' => $view]))->toString(); } $item_list = [ '#theme' => 'item_list', @@ -120,7 +121,7 @@ class ViewsUIController extends ControllerBase { $views = []; // Link each view name to the view itself. foreach ($row['views'] as $row_name => $view) { - $views[] = $this->l($view, new Url('entity.view.edit_form', ['view' => $view])); + $views[] = Link::fromTextAndUrl($view, new Url('entity.view.edit_form', ['view' => $view]))->toString(); } unset($row['views']); $row['views']['data'] = [ diff --git a/core/modules/views_ui/src/ViewEditForm.php b/core/modules/views_ui/src/ViewEditForm.php index 1d4434fe0d96..bc9a7caed082 100644 --- a/core/modules/views_ui/src/ViewEditForm.php +++ b/core/modules/views_ui/src/ViewEditForm.php @@ -9,6 +9,7 @@ use Drupal\Core\Ajax\HtmlCommand; use Drupal\Core\Ajax\ReplaceCommand; use Drupal\Core\Datetime\DateFormatterInterface; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Link; use Drupal\Core\Render\ElementInfoManagerInterface; use Drupal\Core\Url; use Drupal\Core\TempStore\SharedTempStoreFactory; @@ -1062,13 +1063,13 @@ class ViewEditForm extends ViewFormBase { if ($handler->broken()) { $build['fields'][$id]['#class'][] = 'broken'; $field_name = $handler->adminLabel(); - $build['fields'][$id]['#link'] = $this->l($field_name, new Url('views_ui.form_handler', [ + $build['fields'][$id]['#link'] = Link::fromTextAndUrl($field_name, new Url('views_ui.form_handler', [ 'js' => 'nojs', 'view' => $view->id(), 'display_id' => $display['id'], 'type' => $type, 'id' => $id, - ], ['attributes' => ['class' => ['views-ajax-link']]])); + ], ['attributes' => ['class' => ['views-ajax-link']]]))->toString(); continue; } @@ -1085,33 +1086,33 @@ class ViewEditForm extends ViewFormBase { // Add a [hidden] marker, if the field is excluded. $link_text .= ' [' . $this->t('hidden') . ']'; } - $build['fields'][$id]['#link'] = $this->l($link_text, new Url('views_ui.form_handler', [ + $build['fields'][$id]['#link'] = Link::fromTextAndUrl($link_text, new Url('views_ui.form_handler', [ 'js' => 'nojs', 'view' => $view->id(), 'display_id' => $display['id'], 'type' => $type, 'id' => $id, - ], ['attributes' => $link_attributes])); + ], ['attributes' => $link_attributes]))->toString(); $build['fields'][$id]['#class'][] = Html::cleanCssIdentifier($display['id'] . '-' . $type . '-' . $id); if ($executable->display_handler->useGroupBy() && $handler->usesGroupBy()) { - $build['fields'][$id]['#settings_links'][] = $this->l(new FormattableMarkup('@text', ['@text' => $this->t('Aggregation settings')]), new Url('views_ui.form_handler_group', [ + $build['fields'][$id]['#settings_links'][] = Link::fromTextAndUrl(new FormattableMarkup('@text', ['@text' => $this->t('Aggregation settings')]), new Url('views_ui.form_handler_group', [ 'js' => 'nojs', 'view' => $view->id(), 'display_id' => $display['id'], 'type' => $type, 'id' => $id, - ], ['attributes' => ['class' => ['views-button-configure', 'views-ajax-link'], 'title' => $this->t('Aggregation settings')]])); + ], ['attributes' => ['class' => ['views-button-configure', 'views-ajax-link'], 'title' => $this->t('Aggregation settings')]]))->toString(); } if ($handler->hasExtraOptions()) { - $build['fields'][$id]['#settings_links'][] = $this->l(new FormattableMarkup('@text', ['@text' => $this->t('Settings')]), new Url('views_ui.form_handler_extra', [ + $build['fields'][$id]['#settings_links'][] = Link::fromTextAndUrl(new FormattableMarkup('@text', ['@text' => $this->t('Settings')]), new Url('views_ui.form_handler_extra', [ 'js' => 'nojs', 'view' => $view->id(), 'display_id' => $display['id'], 'type' => $type, 'id' => $id, - ], ['attributes' => ['class' => ['views-button-configure', 'views-ajax-link'], 'title' => $this->t('Settings')]])); + ], ['attributes' => ['class' => ['views-button-configure', 'views-ajax-link'], 'title' => $this->t('Settings')]]))->toString(); } if ($grouping) {