Skip to content

Custom base URL support in UrlGenerator for absolute URLs #60187

Open
@speller

Description

@speller

Description

The proposal is to allow passing a custom base URL for absolute URLs, not just the current/preconfigured context one.

Use case:
My website is working on multiple domains. It is not possible to preconfigure a single one. I need to be able to read the base URL from some config (in yaml or in database) and pass it to the URL builder to make an absolute URL for a specific domain. For example - email generation for different users having sites on different domains where links to their websites must use a specific base URL.

Example

Here is how I solved it in my project with a patch:

--- a/Generator/UrlGenerator.php
+++ b/Generator/UrlGenerator.php
@@ -199,8 +199,10 @@
         }

         $schemeAuthority = '';
-        $host = $this->context->getHost();
-        $scheme = $this->context->getScheme();
+        $host = $parameters['_host'] ?? $this->context->getHost();
+        $port = $parameters['_port'] ?? '';
+        $scheme = $parameters['_scheme'] ?? $this->context->getScheme();
+        unset($parameters['_scheme'], $parameters['_host'], $parameters['_port']);

         if ($requiredSchemes) {
             if (!\in_array($scheme, $requiredSchemes, true)) {
@@ -240,11 +242,10 @@

         if (self::ABSOLUTE_URL === $referenceType || self::NETWORK_PATH === $referenceType) {
             if ('' !== $host || ('' !== $scheme && 'http' !== $scheme && 'https' !== $scheme)) {
-                $port = '';
-                if ('http' === $scheme && 80 !== $this->context->getHttpPort()) {
-                    $port = ':'.$this->context->getHttpPort();
-                } elseif ('https' === $scheme && 443 !== $this->context->getHttpsPort()) {
-                    $port = ':'.$this->context->getHttpsPort();
+                if ('http' === $scheme && 80 !== ($port ?: $this->context->getHttpPort())) {
+                    $port = ':'.($port ?: $this->context->getHttpPort());
+                } elseif ('https' === $scheme && 443 !== ($port ?: $this->context->getHttpsPort())) {
+                    $port = ':'.($port ?: $this->context->getHttpsPort());
                 }

                 $schemeAuthority = self::NETWORK_PATH === $referenceType || '' === $scheme ? '//' : "$scheme://";

Example usage:

        return $this->urlGenerator->generate(
            'public_order_tracking',
            [
                ...
                '_scheme' => $base['scheme'] ?? null,
                '_host' => $base['host'] ?? null,
                '_port' => $base['port'] ?? null,
            ],
            UrlGeneratorInterface::ABSOLUTE_URL,
        );

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions