->register('civicrm.packages', function () {
return [
'path' => \Civi::paths()->getPath('[civicrm.root]/packages/'),
- 'url' => \Civi::paths()->getUrl('[civicrm.root]/packages/'),
+ 'url' => \Civi::paths()->getUrl('[civicrm.root]/packages/', 'absolute'),
];
})
->register('civicrm.vendor', function () {
return [
'path' => \Civi::paths()->getPath('[civicrm.root]/vendor/'),
- 'url' => \Civi::paths()->getUrl('[civicrm.root]/vendor/'),
+ 'url' => \Civi::paths()->getUrl('[civicrm.root]/vendor/', 'absolute'),
];
})
->register('civicrm.bower', function () {
return [
'path' => \Civi::paths()->getPath('[civicrm.root]/bower_components/'),
- 'url' => \Civi::paths()->getUrl('[civicrm.root]/bower_components/'),
+ 'url' => \Civi::paths()->getUrl('[civicrm.root]/bower_components/', 'absolute'),
];
})
->register('civicrm.files', function () {
$this->assertEquals("$cmsRoot/foo", $p->getUrl('foo'));
}
+ /**
+ * This test demonstrates how to (and how not to) compute a derivative path variable.
+ */
+ public function testAbsoluteRelativeConversions() {
+ $gstack = \CRM_Utils_GlobalStack::singleton();
+ $gstack->push(['_SERVER' => ['HTTP_HOST' => 'example.com']]);
+ $cleanup = \CRM_Utils_AutoClean::with([$gstack, 'pop']);
+
+ $paths = new Paths();
+ $paths->register('test.base', function () {
+ return [
+ 'path' => '/var/foo/',
+ 'url' => 'http://example.com/foo/',
+ ];
+ });
+ $paths->register('test.goodsub', function () use ($paths) {
+ return [
+ 'path' => $paths->getPath('[test.base]/good/'),
+ 'url' => $paths->getUrl('[test.base]/good/', 'absolute'),
+ ];
+ });
+ $paths->register('test.badsub', function () use ($paths) {
+ return [
+ 'path' => $paths->getPath('[test.base]/bad/'),
+ // This *looks* OK, but `getUrl()` by default uses `$preferFormat==relative`.
+ // The problem is that `$civicrm_paths['...']['url']` is interpreted as relative to CMS root,
+ // and `getUrl(..., 'relative')` is interpreted as relative to HTTP root.
+ // So this definition misbehaves on sites where the CMS root and HTTP root are different.
+ 'url' => $paths->getUrl('[test.base]/bad/'),
+ ];
+ });
+
+ // The test.base works as explicitly defined...
+ $this->assertEquals('/var/foo', $paths->getPath('[test.base]/.'));
+ $this->assertEquals('http://example.com/foo', $paths->getUrl('[test.base]/.', 'absolute'));
+ $this->assertEquals('/foo', $paths->getUrl('[test.base]/.', 'relative'));
+
+ // The test.goodsub works as expected...
+ $this->assertEquals('/var/foo/good', $paths->getPath('[test.goodsub]/.'));
+ $this->assertEquals('http://example.com/foo/good', $paths->getUrl('[test.goodsub]/.', 'absolute'));
+ $this->assertEquals('/foo/good', $paths->getUrl('[test.goodsub]/.', 'relative'));
+
+ // The test.badsub doesn't work as expected.
+ $this->assertEquals('/var/foo/bad', $paths->getPath('[test.badsub]/.'));
+ $this->assertNotEquals('http://example.com/foo/bad', $paths->getUrl('[test.badsub]/.', 'absolute'));
+ $this->assertNotEquals('/foo/bad', $paths->getUrl('[test.badsub]/.', 'relative'));
+ }
+
}