Follow-up to #2343661: Rename l() to _l() and url() to _url(), and document replacements

Problem/Motivation

_l() and _url() circumvent the routing system, and their replacements are not backward-compatible, so they should be removed before release.

Proposed resolution

Remove _l() and _url() before release.

Remaining tasks

Contributor tasks needed
Task Novice task? Contributor instructions Complete?
Find the change records that will need to be updated. List links to them in the summary.
Update change records for the API changes Instructions for drafting a change record might be helpful, but note this is *updating* existing records.

User interface changes

None.

API changes

_l() and _url() are removed

Postponed until

#2343661: Rename l() to _l() and url() to _url(), and document replacements
#2345725: Query parameters are not decoded the same as the path portion of a URL
#2344487: Provide special route names for <current> and <none>
#2364157: Replace most existing _url calls with Url objects
#2368323: Replace _l() in PathController::adminOverview()
#2368653: Replace _l in all places (3) besides one.
#2280961: (Views)FieldPluginBase::advancedRender() calls SafeMarkup::set() on a string that it doesn't know to be safe
#2404041: Replace _l() calls in file module
#2409209: Replace all _url() calls beside the one in _l()
#2410499: Remove remaining _l() calls in Views

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

xjm’s picture

Issue tags: -Pre-AMS beta sprint
xjm’s picture

Issue summary: View changes
xjm’s picture

We'll need to finalize https://www.drupal.org/node/2346779 once this lands.

dawehner’s picture

geerlingguy’s picture

Also, FYI to anyone who might be burned by not being able to make arbitrary links (e.g. in .install files) to drupal paths, You can do so by using base://. This will work for any internal path that may not yet be in the routing system. You shouldn't normally do this... but it might be necessary in some circumstances:

$config_url = Url::fromUri('base://local/path/in/drupal');
catch’s picture

Title: Remove _l() and _url() » [PP-1] Remove _l() and _url()
dawehner’s picture

Title: [PP-1] Remove _l() and _url() » [PP-2] Remove _l() and _url()
Related issues: +#2368323: Replace _l() in PathController::adminOverview()
xjm’s picture

Issue tags: +Triaged D8 critical
YesCT’s picture

Issue summary: View changes

updated summary with the issues blocking this, and a remaining task. but might need more details added to the summary for when this is unpostponed.

Wim Leers’s picture

Title: [PP-2] Remove _l() and _url() » [PP-1] Remove _l() and _url()
Wim Leers’s picture

pcambra’s picture

rpayanm’s picture

Hello someone can tell me what mean [PP-1] on the issue title? Thank.

cilefen’s picture

Postponed, one level deep.

YesCT’s picture

Title: [PP-1] Remove _l() and _url() » [PP-4] Remove _l() and _url()
Issue summary: View changes
Related issues: +#2280961: (Views)FieldPluginBase::advancedRender() calls SafeMarkup::set() on a string that it doesn't know to be safe

I think it is postponed on 4 issues now, adding them to the list.

webchick’s picture

Title: [PP-4] Remove _l() and _url() » [PP-7] Remove _l() and _url()
Issue summary: View changes

Adding a few more dependent sub-issues I found via #2364157: Replace most existing _url calls with Url objects.

mpdonadio’s picture

Title: [PP-7] Remove _l() and _url() » [PP-6] Remove _l() and _url()
Issue summary: View changes

Removed issue that no longer blocks this.

webchick’s picture

Title: [PP-6] Remove _l() and _url() » [PP-5] Remove _l() and _url()
webchick’s picture

Title: [PP-5] Remove _l() and _url() » [PP-3] Remove _l() and _url()
Issue summary: View changes

Actually, for giggles and grins I did a "whole word" grep for _url( and _l(. Here's where we're currently at:

_url(): 17 usages.

Syss-MacBook-Air:8.x webchick$ grep -wr '_url(' .
./core/includes/common.inc:function _url($path = NULL, array $options = array()) {
./core/includes/common.inc: * @see _url()
./core/includes/common.inc:  $url = String::checkPlain(_url($variables['path'], $variables['options']));
./core/lib/Drupal/Core/Routing/UrlGeneratorInterface.php:   *   - 'entity_type': The entity type of the object that called _url(). Only
./core/lib/Drupal/Core/Routing/UrlGeneratorInterface.php:   *     set if _url() is invoked by Drupal\Core\Entity\Entity::uri().
./core/lib/Drupal/Core/Routing/UrlGeneratorInterface.php:   *     generated. Only set if _url() is invoked by Drupal\Core\Entity\Entity::uri().
./core/modules/views/src/Form/ViewsExposedForm.php:    $form['#action'] = _url($view->display_handler->getUrl());
./core/modules/views/src/Plugin/views/display/DisplayPluginBase.php:        $path = check_url(_url($path, $url_options));
./core/modules/views/src/Plugin/views/field/FieldPluginBase.php:        // Make sure that paths which were run through _url() work as well.
./core/modules/views/src/Plugin/views/row/RssFields.php:    $item->link = _url($this->getField($row_index, $this->options['link_field']), array('absolute' => TRUE));
./core/modules/views/src/Plugin/views/row/RssFields.php:      $item_guid = _url($item_guid, array('absolute' => TRUE));
./core/modules/views/src/Plugin/views/style/Opml.php:    $url = _url($this->view->getUrl(NULL, $path), $url_options);
./core/modules/views/src/Plugin/views/style/Rss.php:    $url = _url($this->view->getUrl(NULL, $path), $url_options);
./core/modules/views/views.theme.inc:    $variables['rows'][$id]->url = _url($view->getUrl($args, $base_path), $url_options);
./core/modules/views/views.theme.inc:    $variables['rows'][$id]->url = _url($view->getUrl($args, $base_path), $url_options);
./core/modules/views/views.theme.inc:    $variables['link'] = check_url(_url($path, $url_options));
./core/modules/views/views.tokens.inc:            $replacements[$original] = _url($path, $url_options);

_l(): 41 usages.

Syss-MacBook-Air:8.x webchick$ grep -wr '_l(' .
./core/includes/common.inc:function _l($text, $path, array $options = array()) {
./core/lib/Drupal/Core/Menu/LocalTaskManager.php:            // Normally, _l() compares the href of every link with the current
./core/lib/Drupal/Core/Render/Element/Link.php:   *   A structured array whose keys form the arguments to _l():
./core/lib/Drupal/Core/Render/Element/Link.php:   *   - #title: The link text to pass as argument to _l().
./core/lib/Drupal/Core/Render/Element/Link.php:   *   - #options: (optional) An array of options to pass to _l() or the link
./core/lib/Drupal/Core/Render/Element/Link.php:    // By default, link options to pass to _l() are normally set in #options.
./core/modules/language/src/Tests/LanguageSwitchingTest.php:    // Test links generated by _l() on an English page.
./core/modules/language/src/Tests/LanguageSwitchingTest.php:    // Test links generated by _l() on a French page.
./core/modules/language/src/Tests/LanguageSwitchingTest.php:    // Test links generated by _l() on an English page.
./core/modules/language/src/Tests/LanguageSwitchingTest.php:    // Test links generated by _l() on a French page.
./core/modules/language/tests/language_test/src/Controller/LanguageTestController.php:   * Using #type 'link' causes these links to be rendered with _l().
./core/modules/link/src/Plugin/Field/FieldFormatter/LinkFormatter.php:        // by default in _l().
./core/modules/link/src/Plugin/Field/FieldFormatter/LinkSeparateFormatter.php:        // by default in _l().
./core/modules/link/src/Tests/LinkFieldTest.php:    // _l() and options/attributes. Only 'url_plain' has a dependency on
./core/modules/simpletest/src/TestBase.php:      // Not using _l() to avoid invoking the theme system, so that unit tests
./core/modules/system/language.api.php: * translated link text before going through _l(), which will just handle the
./core/modules/system/menu.api.php: *   - options: (optional) An array of options to be passed to _l() when
./core/modules/system/menu.api.php: *   - localized_options: An array of options to pass to _l().
./core/modules/system/src/Tests/Common/UrlTest.php: * \Drupal\Component\Utility\UrlHelper::buildQuery(), and _l() work correctly
./core/modules/system/src/Tests/Common/UrlTest.php:    // Test _l().
./core/modules/system/src/Tests/Common/UrlTest.php:    $link = _l($text, $path);
./core/modules/system/src/Tests/Common/UrlTest.php:    $this->assertTrue(strpos($link, $sanitized_path) !== FALSE, format_string('XSS attack @path was filtered by _l().', array('@path' => $path)));
./core/modules/system/src/Tests/Common/UrlTest.php:    // Test the active class in links produced by _l() and #type 'link'.
./core/modules/system/src/Tests/Common/UrlTest.php:    $this->assertTrue(isset($links[0]), 'A link generated by _l() to the current page is marked active.');
./core/modules/system/src/Tests/Common/UrlTest.php:    $this->assertTrue(isset($links[0]), 'A link generated by _l() to the current page with a query string when the current page has no query string is not marked active.');
./core/modules/system/src/Tests/Common/UrlTest.php:    $this->assertTrue(isset($links[0]), 'A link generated by _l() to the current page with a query string that matches the current query string is marked active.');
./core/modules/system/src/Tests/Common/UrlTest.php:    $this->assertTrue(isset($links[0]), 'A link generated by _l() to the current page with a query string that has matching parameters to the current query string but in a different order is marked active.');
./core/modules/system/src/Tests/Common/UrlTest.php:    $this->assertTrue(isset($links[0]), 'A link generated by _l() to the current page without a query string when the current page has a query string is not marked active.');
./core/modules/system/src/Tests/Common/UrlTest.php:    // Test adding a custom class in links produced by _l() and #type 'link'.
./core/modules/system/src/Tests/Common/UrlTest.php:    // Test _l().
./core/modules/system/src/Tests/Common/UrlTest.php:    // Build a link with _l() for reference.
./core/modules/system/src/Tests/Common/UrlTest.php:    // Test a renderable array passed to _l().
./core/modules/system/src/Tests/Theme/FunctionsTest.php:    // Turn off the query for the _l() function to compare the active
./core/modules/system/system.api.php: *   exposed as the 'link_generator' service or a link generated by _l(). If the
./core/modules/system/tests/modules/common_test/src/Controller/CommonTestController.php:   * Using #type 'link' causes these links to be rendered with _l().
./core/modules/views/src/Plugin/views/field/FieldPluginBase.php:        $more_link = _l($more_link_text, $more_link_path, array('attributes' => array('class' => array('views-more-link'))));
./core/modules/views/src/Plugin/views/field/FieldPluginBase.php:    // $path will be run through check_url() by _l() so we do not need to
./core/modules/views/src/Plugin/views/field/FieldPluginBase.php:      // convert back to an array form for _l().
./core/modules/views/src/Plugin/views/field/FieldPluginBase.php:      $value .= _l($text, $path, $options);
./core/modules/views/src/Plugin/views/field/Url.php:      return _l($this->sanitizeValue($value), $value, array('html' => TRUE));
./core/modules/views/src/Tests/ViewStorageTest.php:    // Enable the system module so _l() can work using url_alias table.

AFAICS all of these are covered by the following:

So by my count, we're now down to PP-3. Updated the issue summary with remaining tasks.

webchick’s picture

Title: [PP-3] Remove _l() and _url() » [PP-2] Remove _l() and _url()
webchick’s picture

Title: [PP-2] Remove _l() and _url() » [PP-1] Remove _l() and _url()
mpdonadio’s picture

#2404603: Add proper support for Url objects in FieldPluginBase::renderAsLink(), so we can remove EntityInterface::getSystemPath() will be getting a patch tonight that should address all concerns. I just need to post it and explain a bit.

mpdonadio’s picture

Issue summary: View changes

So, I got antsy, and took the latest patch from #2404603: Add proper support for Url objects in FieldPluginBase::renderAsLink(), so we can remove EntityInterface::getSystemPath() and made a test branch from it. PhpStorm reported no uses of _url() or _l(), other than themselves. As a test, I removed both from common.inc, made a patch, and it comes up green.

Probably need to do a few greps/searches to catch uses in comments (but IS says that shouldn't hold up this issue), so this is looking good.

Updated IS since one of the Remaining Tasks was covered by an issue that has been done for a while now.

mpdonadio’s picture

Title: [PP-1] Remove _l() and _url() » Remove _l() and _url()
Status: Postponed » Needs review
FileSize
56.62 KB

I think all blockers are gone now.

dawehner’s picture

Too bad, I'd like to RTBC this already.

dawehner’s picture

@mpdonadio
Can you roll a small patch, please?

mpdonadio’s picture

FileSize
9.33 KB

Reroll b/c git a git problem.

dawehner’s picture

Status: Needs review » Reviewed & tested by the community

Perfect, the documentation is reflected in another issue.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 28: remove_l_and_url-2343669-28.patch, failed testing.

Status: Needs work » Needs review
star-szr’s picture

Status: Needs review » Reviewed & tested by the community

Back to #29's RTBC because it came back green.

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Bye, bye, old friends.

Committed a7e819e and pushed to 8.0.x. Thanks!

  • alexpott committed a7e819e on 8.0.x
    Issue #2343669 by mpdonadio: Remove _l() and _url()
    
hussainweb’s picture

Opened #2424525: Remove references to _l() and _url() for a followup to remove references to _l() and _url() from comments and doxygen.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.