Civi\Core\Url - Allow dynamic variables
authorTim Otten <totten@civicrm.org>
Tue, 25 Jul 2023 05:01:23 +0000 (22:01 -0700)
committerTim Otten <totten@civicrm.org>
Tue, 25 Jul 2023 05:29:36 +0000 (22:29 -0700)
Civi/Core/Url.php

index c521998975051880b96faa44ffbfa9a8a46afc46..6bd147f29f71d732e82d3ae8e57c14eb47a8914b 100644 (file)
@@ -108,6 +108,13 @@ final class Url implements \JsonSerializable {
    */
   private $vars;
 
+  /**
+   * Define a dynamic lookup for variables.
+   *
+   * @var callable|null
+   */
+  private $varsCallback;
+
   /**
    * @param string $logicalUri
    * @param string|null $flags
@@ -430,6 +437,27 @@ final class Url implements \JsonSerializable {
     return $this;
   }
 
+  /**
+   * @return callable|null
+   */
+  public function getVarsCallback(): ?callable {
+    return $this->varsCallback;
+  }
+
+  /**
+   * Configure dynamic lookup for variables.
+   *
+   * @param callable|null $varsCallback
+   *   Function(string $varName): ?string
+   *   Determine the string-value of the variable. (May be ''.)
+   *   If the variable is unavailable, return NULL.
+   * @return $this
+   */
+  public function setVarsCallback(?callable $varsCallback) {
+    $this->varsCallback = $varsCallback;
+    return $this;
+  }
+
   /**
    * Apply a series of flags using short-hand notation.
    *
@@ -553,7 +581,16 @@ final class Url implements \JsonSerializable {
       // Replace variables
       $result = preg_replace_callback('/\[(\w+)\]/', function($m) {
         $var = $m[1];
-        return isset($this->vars[$var]) ? urlencode($this->vars[$var]) : "[$var]";
+        if (isset($this->vars[$var])) {
+          return urlencode($this->vars[$var]);
+        }
+        if ($this->varsCallback !== NULL) {
+          $value = call_user_func($this->varsCallback, $var);
+          if ($value !== NULL) {
+            return urlencode($value);
+          }
+        }
+        return "[$var]";
       }, $result);
     }