function Url::fromInternalUri

Same name and namespace in other branches
  1. 9 core/lib/Drupal/Core/Url.php \Drupal\Core\Url::fromInternalUri()
  2. 8.9.x core/lib/Drupal/Core/Url.php \Drupal\Core\Url::fromInternalUri()
  3. 10 core/lib/Drupal/Core/Url.php \Drupal\Core\Url::fromInternalUri()

Creates a new Url object for 'internal:' URIs.

Important note: the URI minus the scheme can NOT simply be validated by a \Drupal\Core\Path\PathValidatorInterface implementation. The semantics of the 'internal:' URI scheme are different:

  • PathValidatorInterface accepts paths without a leading slash (e.g. 'node/add') as well as 2 special paths: '<front>' and '<none>', which are mapped to the correspondingly named routes.
  • 'internal:' URIs store paths with a leading slash that represents the root — i.e. the front page — (e.g. 'internal:/node/add'), and doesn't have any exceptions.

To clarify, a few examples of path plus corresponding 'internal:' URI:

  • 'node/add' -> 'internal:/node/add'
  • 'node/add?foo=bar' -> 'internal:/node/add?foo=bar'
  • 'node/add#kitten' -> 'internal:/node/add#kitten'
  • '<front>' -> 'internal:/'
  • '<front>foo=bar' -> 'internal:/?foo=bar'
  • '<front>#kitten' -> 'internal:/#kitten'
  • '<none>' -> 'internal:'
  • '<none>foo=bar' -> 'internal:?foo=bar'
  • '<none>#kitten' -> 'internal:#kitten'

Therefore, when using a PathValidatorInterface to validate 'internal:' URIs, we must map:

  • 'internal:' (path component is '') to the special '<none>' path
  • 'internal:/' (path component is '/') to the special '<front>' path
  • 'internal:/some-path' (path component is '/some-path') to 'some-path'

Parameters

array $uri_parts: Parts from a URI of the form internal:{path} as from parse_url().

array $options: An array of options, see \Drupal\Core\Url::fromUri() for details.

Return value

static A new Url object for an 'internal:' URI.

Throws

\InvalidArgumentException Thrown when the URI's path component doesn't have a leading slash.

1 call to Url::fromInternalUri()
Url::fromUri in core/lib/Drupal/Core/Url.php
Creates a new Url object from a URI.

File

core/lib/Drupal/Core/Url.php, line 403

Class

Url
Defines an object that holds information about a URL.

Namespace

Drupal\Core

Code

protected static function fromInternalUri(array $uri_parts, array $options) {
    // Both PathValidator::getUrlIfValidWithoutAccessCheck() and 'base:' URIs
    // only accept/contain paths without a leading slash, unlike 'internal:'
    // URIs, for which the leading slash means "relative to Drupal root" and
    // "relative to Symfony app root" (just like in Symfony/Drupal 8 routes).
    if (empty($uri_parts['path'])) {
        $uri_parts['path'] = '<none>';
    }
    elseif ($uri_parts['path'] === '/') {
        $uri_parts['path'] = '<front>';
    }
    else {
        if ($uri_parts['path'][0] !== '/') {
            throw new \InvalidArgumentException("The internal path component '{$uri_parts['path']}' is invalid. Its path component must have a leading slash, e.g. internal:/foo.");
        }
        // Remove the leading slash.
        $uri_parts['path'] = substr($uri_parts['path'], 1);
        if (UrlHelper::isExternal($uri_parts['path'])) {
            throw new \InvalidArgumentException("The internal path component '{$uri_parts['path']}' is external. You are not allowed to specify an external URL together with internal:/.");
        }
    }
    $url = \Drupal::pathValidator()->getUrlIfValidWithoutAccessCheck($uri_parts['path']) ?: static::fromUri('base:' . $uri_parts['path'], $options);
    // Allow specifying additional options.
    $url->setOptions($options + $url->getOptions());
    return $url;
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.