Extract CRM_Utils_System_Base::getRouteUrl()
authorTim Otten <totten@civicrm.org>
Tue, 25 Jul 2023 22:15:10 +0000 (15:15 -0700)
committerTim Otten <totten@civicrm.org>
Tue, 25 Jul 2023 23:02:35 +0000 (16:02 -0700)
CRM/Utils/System/Base.php
Civi/Core/Url.php

index c78f72c0c97fcde50673db8c264b21a6a3d71e3e..c6c0220e79be99e31dbaa18be290b4d3dcaf380e 100644 (file)
@@ -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.
    *
index 9f6fd45d24231b1dc843da9dbab5a8d952ccadd0..9ae35d2891c516420f78306641a87c9e19896298 100644 (file)
@@ -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) {