Civi::url() - Allow environments to change default scheme and format
authorTim Otten <totten@civicrm.org>
Fri, 21 Jul 2023 01:43:09 +0000 (18:43 -0700)
committerTim Otten <totten@civicrm.org>
Mon, 24 Jul 2023 08:12:30 +0000 (01:12 -0700)
CRM/Core/Invoke.php
Civi/Core/Url.php

index 51b2d0cb1502b7e20284efead33defff7fddfc7d..f326d3835ef8719b4a3ec86ca2b0878621e956e8 100644 (file)
@@ -207,6 +207,9 @@ class CRM_Core_Invoke {
     self::registerPharHandler();
 
     $config = CRM_Core_Config::singleton();
+
+    // WISHLIST: if $item is a web-service route, swap prepend to $civicrm_url_defaults
+
     if ($config->userFramework == 'Joomla' && $item) {
       $config->userFrameworkURLVar = 'task';
 
index 009c94eac8821aba21104826b39a6ebcb2757b2e..5bcb72dc5f188589a113321d86a28e960d2ac41b 100644 (file)
@@ -9,7 +9,7 @@ namespace Civi\Core;
  *
  * As output, it provides a *concrete URL* that can be used by a web-browser to make requests.
  */
-class Url {
+final class Url {
 
   /**
    * @var string
@@ -286,24 +286,16 @@ class Url {
    */
   public function __toString(): string {
     $userSystem = \CRM_Core_Config::singleton()->userSystem;
+    $preferFormat = $this->getPreferFormat() ?: static::detectFormat();
     $scheme = $this->getScheme();
-    $preferFormat = $this->getPreferFormat();
 
-    // Translate subjective values to real values.
-    switch ($scheme) {
-      case 'current':
-        $preferFormat = $preferFormat ?: 'relative';
-        $scheme = $userSystem->isFrontEndPage() ? 'frontend' : 'backend';
-        // The current call could actually be a 'service' request, but we treat those as equivalent to 'frontend', so maybe it doesn't matter.
-        break;
-
-      case 'default':
-        // $preferFormat = $preferFormat ?: 'absolute';
-        // TODO pick $scheme = 'frontend' or 'backend' or 'service';
-        throw new \RuntimeException("FIXME: Implement lookup for default ");
+    if ($scheme === NULL || $scheme === 'current') {
+      $scheme = static::detectScheme();
+    }
 
-      default:
-        $preferFormat = $preferFormat ?: 'absolute';
+    if ($scheme === 'default') {
+      // TODO Use metadata to pick $scheme = 'frontend' or 'backend' or 'service';
+      throw new \RuntimeException("FIXME: Implement lookup for default ");
     }
 
     switch ($scheme) {
@@ -350,4 +342,32 @@ class Url {
     return $this->htmlEscape ? htmlentities($result) : $result;
   }
 
+  private static function detectFormat(): string {
+    // Some environments may override default - e.g. cv-cli prefers absolute URLs
+    // WISHLIST: If handling `Job.*`, then 'absolute'
+    // WISHLIST: If active route is a web-service/web-hook/IPN, then 'absolute'
+    foreach ($GLOBALS['civicrm_url_defaults'] ?? [] as $default) {
+      if (isset($default['format'])) {
+        return $default['format'];
+      }
+    }
+
+    // Web UI: Most CiviCRM routes (`CRM_Core_Invoke::invoke()`) and CMS blocks
+    return 'relative';
+  }
+
+  private static function detectScheme(): string {
+    // Some environments may override default - e.g. cv-cli prefers 'default://'.
+    // WISHLIST: If handling `Job.*`, then `default://'
+    // WISHLIST: If active route is a web-service/web-hook/IPN, then 'default://'
+    foreach ($GLOBALS['civicrm_url_defaults'] ?? [] as $default) {
+      if (isset($default['scheme'])) {
+        return $default['scheme'];
+      }
+    }
+
+    // Web UI: Most CiviCRM routes (`CRM_Core_Invoke::invoke()`) and CMS blocks
+    return \CRM_Core_Config::singleton()->userSystem->isFrontEndPage() ? 'frontend' : 'backend';
+  }
+
 }