From 59af62f8b3d280cf3080d78be3d9a86c28ab2749 Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Tue, 25 Jul 2023 15:15:10 -0700 Subject: [PATCH] Extract CRM_Utils_System_Base::getRouteUrl() --- CRM/Utils/System/Base.php | 36 ++++++++++++++++++++++++++++++++++++ Civi/Core/Url.php | 22 ++++++++++++---------- 2 files changed, 48 insertions(+), 10 deletions(-) diff --git a/CRM/Utils/System/Base.php b/CRM/Utils/System/Base.php index c78f72c0c9..c6c0220e79 100644 --- a/CRM/Utils/System/Base.php +++ b/CRM/Utils/System/Base.php @@ -136,6 +136,42 @@ abstract class CRM_Utils_System_Base { $forceBackend = FALSE ); + /** + * Compose the URL for a page/route. + * + * @internal + * @see \Civi\Core\Url::__toString + * @param string $scheme + * Ex: 'frontend', 'backend', 'service' + * @param string $path + * Ex: 'civicrm/event/info' + * @param string|null $query + * Ex: 'id=100&msg=Hello+world' + * @return string|null + * Absolute URL, or NULL if scheme is unsupported. + * Ex: 'https://subdomain.example.com/index.php?q=civicrm/event/info&id=100&msg=Hello+world' + */ + public function getRouteUrl(string $scheme, string $path, ?string $query): ?string { + switch ($scheme) { + case 'frontend': + return $this->url($path, $query, TRUE, NULL, TRUE, FALSE, FALSE); + + case 'service': + // The original `url()` didn't have an analog for "service://". But "frontend" is probably the closer bet? + // Or maybe getNotifyUrl() makes sense? + return $this->url($path, $query, TRUE, NULL, TRUE, FALSE, FALSE); + + case 'backend': + return $this->url($path, $query, TRUE, NULL, FALSE, TRUE, FALSE); + + // If the UF defines other major UI/URL conventions, then you might hypothetically handle + // additional schemes. + + default: + return NULL; + } + } + /** * Return the Notification URL for Payments. * diff --git a/Civi/Core/Url.php b/Civi/Core/Url.php index 9f6fd45d24..9ae35d2891 100644 --- a/Civi/Core/Url.php +++ b/Civi/Core/Url.php @@ -524,15 +524,6 @@ final class Url implements \JsonSerializable { } switch ($scheme) { - case 'frontend': - case 'service': - $result = $userSystem->url($this->getPath(), $this->getQuery(), $preferFormat === 'absolute', $this->composeFragment(), TRUE, FALSE, FALSE); - break; - - case 'backend': - $result = $userSystem->url($this->getPath(), $this->getQuery(), $preferFormat === 'absolute', $this->composeFragment(), FALSE, TRUE, FALSE); - break; - case 'assetBuilder': $assetName = $this->getPath(); $assetParams = []; @@ -559,8 +550,19 @@ final class Url implements \JsonSerializable { $result = \Civi::resources()->getUrl($parts[0], $parts[1] ?? NULL, FALSE) . $this->composeSuffix(); break; + // Handle 'frontend', 'backend', 'service', and any extras. default: - throw new \RuntimeException("Unknown URL scheme: {$this->getScheme()}"); + $result = $userSystem->getRouteUrl($scheme, $this->getPath(), $this->getQuery()); + if ($result === NULL) { + throw new \RuntimeException("Unknown URL scheme: $scheme"); + } + if ($preferFormat === 'relative') { + $result = \CRM_Utils_Url::toRelative($result); + } + if ($fragment = $this->composeFragment()) { + $result .= '#' . $fragment; + } + break; } if ($this->cacheCode) { -- 2.25.1