function UrlGenerator::generateFromRoute

Same name and namespace in other branches
  1. 9 core/lib/Drupal/Core/Routing/UrlGenerator.php \Drupal\Core\Routing\UrlGenerator::generateFromRoute()
  2. 10 core/lib/Drupal/Core/Routing/UrlGenerator.php \Drupal\Core\Routing\UrlGenerator::generateFromRoute()
  3. 11.x core/lib/Drupal/Core/Routing/UrlGenerator.php \Drupal\Core\Routing\UrlGenerator::generateFromRoute()

Overrides UrlGeneratorInterface::generateFromRoute

1 call to UrlGenerator::generateFromRoute()
UrlGenerator::generate in core/lib/Drupal/Core/Routing/UrlGenerator.php

File

core/lib/Drupal/Core/Routing/UrlGenerator.php, line 265

Class

UrlGenerator
Generates URLs from route names and parameters.

Namespace

Drupal\Core\Routing

Code

public function generateFromRoute($name, $parameters = [], $options = [], $collect_bubbleable_metadata = FALSE) {
    $options += [
        'prefix' => '',
    ];
    if (!isset($options['query']) || !is_array($options['query'])) {
        $options['query'] = [];
    }
    $route = $this->getRoute($name);
    $generated_url = $collect_bubbleable_metadata ? new GeneratedUrl() : NULL;
    $fragment = '';
    if (isset($options['fragment'])) {
        if (($fragment = trim($options['fragment'])) != '') {
            $fragment = '#' . $fragment;
        }
    }
    // Generate a relative URL having no path, just query string and fragment.
    if ($route->getOption('_no_path')) {
        $query = $options['query'] ? '?' . UrlHelper::buildQuery($options['query']) : '';
        $url = $query . $fragment;
        return $collect_bubbleable_metadata ? $generated_url->setGeneratedUrl($url) : $url;
    }
    $options += $route->getOption('default_url_options') ?: [];
    $options += [
        'prefix' => '',
        'path_processing' => TRUE,
    ];
    $name = $this->getRouteDebugMessage($name);
    $this->processRoute($name, $route, $parameters, $generated_url);
    $path = $this->getInternalPathFromRoute($name, $route, $parameters, $options['query']);
    // Outbound path processors might need the route object for the path, e.g.
    // to get the path pattern.
    $options['route'] = $route;
    if ($options['path_processing']) {
        $path = $this->processPath($path, $options, $generated_url);
    }
    // Ensure the resulting path has at most one leading slash, to prevent it
    // becoming an external URL without a protocol like //example.com.
    if (strpos($path, '//') === 0) {
        $path = '/' . ltrim($path, '/');
    }
    // The contexts base URL is already encoded
    // (see Symfony\Component\HttpFoundation\Request).
    $path = str_replace($this->decodedChars[0], $this->decodedChars[1], rawurlencode($path));
    // Drupal paths rarely include dots, so skip this processing if possible.
    if (strpos($path, '/.') !== FALSE) {
        // the path segments "." and ".." are interpreted as relative reference when
        // resolving a URI; see http://tools.ietf.org/html/rfc3986#section-3.3
        // so we need to encode them as they are not used for this purpose here
        // otherwise we would generate a URI that, when followed by a user agent
        // (e.g. browser), does not match this route
        $path = strtr($path, [
            '/../' => '/%2E%2E/',
            '/./' => '/%2E/',
        ]);
        if ('/..' === substr($path, -3)) {
            $path = substr($path, 0, -2) . '%2E%2E';
        }
        elseif ('/.' === substr($path, -2)) {
            $path = substr($path, 0, -1) . '%2E';
        }
    }
    if (!empty($options['prefix'])) {
        $path = ltrim($path, '/');
        $prefix = empty($path) ? rtrim($options['prefix'], '/') : $options['prefix'];
        $path = '/' . str_replace('%2F', '/', rawurlencode($prefix)) . $path;
    }
    $query = $options['query'] ? '?' . UrlHelper::buildQuery($options['query']) : '';
    // The base_url might be rewritten from the language rewrite in domain mode.
    if (isset($options['base_url'])) {
        $base_url = $options['base_url'];
        if (isset($options['https'])) {
            if ($options['https'] === TRUE) {
                $base_url = str_replace('http://', 'https://', $base_url);
            }
            elseif ($options['https'] === FALSE) {
                $base_url = str_replace('https://', 'http://', $base_url);
            }
        }
        $url = $base_url . $path . $query . $fragment;
        return $collect_bubbleable_metadata ? $generated_url->setGeneratedUrl($url) : $url;
    }
    $base_url = $this->context
        ->getBaseUrl();
    $absolute = !empty($options['absolute']);
    if (!$absolute || !($host = $this->context
        ->getHost())) {
        $url = $base_url . $path . $query . $fragment;
        return $collect_bubbleable_metadata ? $generated_url->setGeneratedUrl($url) : $url;
    }
    // Prepare an absolute URL by getting the correct scheme, host and port from
    // the request context.
    if (isset($options['https'])) {
        $scheme = $options['https'] ? 'https' : 'http';
    }
    else {
        $scheme = $this->context
            ->getScheme();
    }
    $scheme_req = $route->getSchemes();
    if ($scheme_req && ($req = $scheme_req[0]) && $scheme !== $req) {
        $scheme = $req;
    }
    $port = '';
    if ('http' === $scheme && 80 != $this->context
        ->getHttpPort()) {
        $port = ':' . $this->context
            ->getHttpPort();
    }
    elseif ('https' === $scheme && 443 != $this->context
        ->getHttpsPort()) {
        $port = ':' . $this->context
            ->getHttpsPort();
    }
    if ($collect_bubbleable_metadata) {
        $generated_url->addCacheContexts([
            'url.site',
        ]);
    }
    $url = $scheme . '://' . $host . $port . $base_url . $path . $query . $fragment;
    return $collect_bubbleable_metadata ? $generated_url->setGeneratedUrl($url) : $url;
}

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