diff --git a/CRM/Core/Resources.php b/CRM/Core/Resources.php index f8c00772ae59..87cb3c79c92f 100644 --- a/CRM/Core/Resources.php +++ b/CRM/Core/Resources.php @@ -528,6 +528,9 @@ public function glob($ext, $patterns, $flags = NULL) { $patterns = (array) $patterns; $files = array(); foreach ($patterns as $pattern) { + if (preg_match(';^(assetBuilder|ext)://;', $pattern)) { + $files[] = $pattern; + } if (CRM_Utils_File::isAbsolute($pattern)) { // Absolute path. $files = array_merge($files, (array) glob($pattern, $flags)); diff --git a/CRM/Utils/Hook.php b/CRM/Utils/Hook.php index 4c1163493e95..4f0b0c371325 100644 --- a/CRM/Utils/Hook.php +++ b/CRM/Utils/Hook.php @@ -2110,8 +2110,8 @@ public static function alterResourceSettings(&$data) { * ); * $angularModules['myBigAngularModule'] = array( * 'ext' => 'org.example.mymod', - * 'js' => array('js/part1.js', 'js/part2.js'), - * 'css' => array('css/myAngularModule.css'), + * 'js' => array('js/part1.js', 'js/part2.js', 'ext://other.ext.name/file.js', 'assetBuilder://dynamicAsset.js'), + * 'css' => array('css/myAngularModule.css', 'ext://other.ext.name/file.css', 'assetBuilder://dynamicAsset.css'), * 'partials' => array('partials/myBigAngularModule'), * 'requires' => array('otherModuleA', 'otherModuleB'), * 'basePages' => array('civicrm/a'), diff --git a/Civi/Angular/Manager.php b/Civi/Angular/Manager.php index 3f4776205156..a10a8096f5f8 100644 --- a/Civi/Angular/Manager.php +++ b/Civi/Angular/Manager.php @@ -327,7 +327,12 @@ public function getResources($moduleNames, $resType, $refType) { $module = $this->getModule($moduleName); if (isset($module[$resType])) { foreach ($module[$resType] as $file) { - switch ($refType) { + $refTypeSuffix = ''; + if (is_string($file) && preg_match(';^(assetBuilder|ext)://;', $file)) { + $refTypeSuffix = '-' . parse_url($file, PHP_URL_SCHEME); + } + + switch ($refType . $refTypeSuffix) { case 'path': $result[] = $this->res->getPath($module['ext'], $file); break; @@ -340,6 +345,33 @@ public function getResources($moduleNames, $resType, $refType) { $result[] = $this->res->getUrl($module['ext'], $file, TRUE); break; + case 'path-assetBuilder': + $assetName = parse_url($file, PHP_URL_HOST) . parse_url($file, PHP_URL_PATH); + $assetParams = array(); + parse_str('' . parse_url($file, PHP_URL_QUERY), $assetParams); + $result[] = \Civi::service('asset_builder')->getPath($assetName, $assetParams); + break; + + case 'rawUrl-assetBuilder': + case 'cacheUrl-assetBuilder': + $assetName = parse_url($file, PHP_URL_HOST) . parse_url($file, PHP_URL_PATH); + $assetParams = array(); + parse_str('' . parse_url($file, PHP_URL_QUERY), $assetParams); + $result[] = \Civi::service('asset_builder')->getUrl($assetName, $assetParams); + break; + + case 'path-ext': + $result[] = $this->res->getPath(parse_url($file, PHP_URL_HOST), ltrim(parse_url($file, PHP_URL_PATH), '/')); + break; + + case 'rawUrl-ext': + $result[] = $this->res->getUrl(parse_url($file, PHP_URL_HOST), ltrim(parse_url($file, PHP_URL_PATH), '/')); + break; + + case 'cacheUrl-ext': + $result[] = $this->res->getUrl(parse_url($file, PHP_URL_HOST), ltrim(parse_url($file, PHP_URL_PATH), '/'), TRUE); + break; + case 'settings': case 'requires': if (!empty($module[$resType])) { diff --git a/Civi/Core/AssetBuilder.php b/Civi/Core/AssetBuilder.php index 5c3c8263b072..5f79555650c9 100644 --- a/Civi/Core/AssetBuilder.php +++ b/Civi/Core/AssetBuilder.php @@ -139,6 +139,23 @@ public function getUrl($name, $params = array()) { } } + /** + * @param string $name + * Ex: 'angular.json'. + * @param array $params + * @return string + * URL. + * Ex: '/var/www/files/civicrm/dyn/angular.abcd1234abcd1234.json'. + */ + public function getPath($name, $params = array()) { + if (!$this->isValidName($name)) { + throw new \RuntimeException("Invalid dynamic asset name"); + } + + $fileName = $this->build($name, $params); + return $this->getCachePath($fileName); + } + /** * Build the cached copy of an $asset. * diff --git a/tests/phpunit/Civi/Angular/ManagerTest.php b/tests/phpunit/Civi/Angular/ManagerTest.php index 3174a3518467..23572cc6736e 100644 --- a/tests/phpunit/Civi/Angular/ManagerTest.php +++ b/tests/phpunit/Civi/Angular/ManagerTest.php @@ -124,6 +124,17 @@ public function testGetPartials_Hooked() { // If crmMailing changes, feel free to use a different example. } + public function testGetJs_Asset() { + \CRM_Utils_Hook::singleton()->setHook('civicrm_angularModules', array($this, 'hook_civicrm_angularModules_fooBar')); + + $paths = $this->angular->getResources(array('fooBar'), 'js', 'path'); + $this->assertRegExp('/visual-bundle.[a-z0-9]+.js/', $paths[0]); + $this->assertRegExp('/crossfilter/', file_get_contents($paths[0])); + + $this->assertRegExp('/Common.js/', $paths[1]); + $this->assertRegExp('/console/', file_get_contents($paths[1])); + } + /** * Get a translatable string from an example module. */ @@ -209,4 +220,14 @@ public function hook_civicrm_alterAngular($angular) { ); } + public function hook_civicrm_angularModules_fooBar(&$angularModules) { + $angularModules['fooBar'] = array( + 'ext' => 'civicrm', + 'js' => array( + 'assetBuilder://visual-bundle.js', + 'ext://civicrm/js/Common.js', + ), + ); + } + }