$scheme = \CRM_Core_Menu::isPublicRoute($this->getPath()) ? 'frontend' : 'backend';
}
+ // Goal: After this switch(), we should have the $scheme, $path, and $query combined.
switch ($scheme) {
case 'assetBuilder':
$assetName = $this->getPath();
case 'asset':
if (preg_match(';^\[([\w\.]+)\](.*)$;', $this->getPath(), $m)) {
[, $var, $rest] = $m;
- $result = rtrim(\Civi::paths()->getVariable($var, 'url'), '/');
- if ($preferFormat === 'relative') {
- $result = \CRM_Utils_Url::toRelative($result);
- }
- $result .= $rest . $this->composeSuffix();
+ $varValue = rtrim(\Civi::paths()->getVariable($var, 'url'), '/');
+ $result = $varValue . $rest . $this->composeQuery();
}
else {
throw new \RuntimeException("Malformed asset path: {$this->getPath()}");
case 'ext':
$parts = explode('/', $this->getPath(), 2);
- $result = \Civi::resources()->getUrl($parts[0], $parts[1] ?? NULL, FALSE) . $this->composeSuffix();
+ $result = \Civi::resources()->getUrl($parts[0], $parts[1] ?? NULL, FALSE) . $this->composeQuery();
break;
// Handle 'frontend', 'backend', 'service', and any extras.
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;
}
$result = \Civi::resources()->addCacheCode($result);
}
+ $result .= $this->composeFragment();
+
+ if ($preferFormat === 'relative') {
+ $result = \CRM_Utils_Url::toRelative($result);
+ }
+
// TODO decide if the current default is good enough for future
$ssl = $this->getSsl() ?: \CRM_Utils_System::isSSL();
if ($ssl && str_starts_with($result, 'http:')) {
return $this->__toString();
}
- private function composeSuffix(): string {
- $result = '';
+ /**
+ * @return string
+ * '' or '?foo=bar'
+ */
+ private function composeQuery(): string {
if ($this->query !== NULL && $this->query !== '') {
- $result .= '?' . $this->query;
+ return '?' . $this->query;
}
- $fragment = $this->composeFragment();
- if ($fragment !== NULL && $fragment !== '') {
- $result .= '#' . $fragment;
+ else {
+ return '';
}
- return $result;
}
- private function composeFragment(): ?string {
- $fragment = $this->fragment;
+ /**
+ * @return string
+ * '' or '#foobar'
+ */
+ private function composeFragment(): string {
+ $fragment = $this->fragment ?: '';
if ($this->fragmentQuery !== NULL && $this->fragmentQuery !== '') {
- $fragment = ($fragment ?: '') . '?' . $this->fragmentQuery;
+ $fragment .= '?' . $this->fragmentQuery;
}
- return $fragment;
+ return ($fragment === '') ? '' : "#$fragment";
}
private static function detectFormat(): string {
$absolutes = [];
$absolutes['flag'] = Civi::url('backend://civicrm/admin', 'a');
$absolutes['method'] = Civi::url('backend://civicrm/admin')->setPreferFormat('absolute');
+ $absolutes['ext'] = Civi::url('ext://org.civicrm.search_kit/js/foobar.js', 'a');
+ $absolutes['asset'] = Civi::url('asset://[civicrm.packages]/js/foobar.js', 'a');
$relatives = [];
$relatives['default'] = Civi::url('backend://civicrm/admin');
$relatives['flag'] = Civi::url('backend://civicrm/admin', 'r');
$relatives['method'] = Civi::url('backend://civicrm/admin')->setPreferFormat('relative');
+ $relatives['ext'] = Civi::url('ext://org.civicrm.search_kit/js/foobar.js', 'r');
+ $relatives['asset'] = Civi::url('asset://[civicrm.packages]/js/foobar.js', 'r');
foreach ($absolutes as $key => $url) {
$this->assertRegExp(';^https?://;', (string) $url, "absolutes[$key] should be absolute URL");
$urlPats[] = [';^https?://.*civicrm;', \Civi::url('frontend://civicrm/event/info?reset=1', 'a')];
$urlPats[] = [';^https://.*civicrm;', \Civi::url('frontend://civicrm/event/info?reset=1', 'as')];
+ $urlPats[] = [';civicrm(/|%2F)a(/|%2F).*#/mailing/new\?angularDebug=1;', \Civi::url('backend://civicrm/a/#/mailing/new?angularDebug=1')];
+ $urlPats[] = [';/jquery.timeentry.js\?r=.*#foo;', \Civi::url('asset://[civicrm.packages]/jquery/plugins/jquery.timeentry.js', 'c')->addFragment('foo')];
+ $urlPats[] = [';/stuff.js\?r=.*#foo;', \Civi::url('ext://org.civicrm.search_kit/stuff.js', 'c')->addFragment('foo')];
+ $urlPats[] = [';#foo;', \Civi::url('assetBuilder://crm-l10n.js?locale=en_US')->addFragment('foo')];
// Some test-harnesses have HTTP_HOST. Some don't. It's pre-req for truly relative URLs.
if (!empty($_SERVER['HTTP_HOST'])) {