From fcf926ad4ab1df90dd9d553a75f7385124420220 Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Sun, 23 Aug 2020 18:49:44 -0700 Subject: [PATCH] Add "Bundle" support - ie an unattached, mixable list of resources --- CRM/Core/Resources.php | 57 ++++++++++++++++++++++++++ CRM/Core/Resources/Bundle.php | 38 +++++++++++++++++ CRM/Core/Resources/CollectionTrait.php | 21 ++++++++++ 3 files changed, 116 insertions(+) create mode 100644 CRM/Core/Resources/Bundle.php diff --git a/CRM/Core/Resources.php b/CRM/Core/Resources.php index 9b694bb03a..4265fee1cf 100644 --- a/CRM/Core/Resources.php +++ b/CRM/Core/Resources.php @@ -45,6 +45,15 @@ class CRM_Core_Resources { */ private $strings = NULL; + /** + * Any bundles that have been added. + * + * Format is ($bundleName => bool). + * + * @var array + */ + protected $addedBundles = []; + /** * Added core resources. * @@ -139,6 +148,54 @@ class CRM_Core_Resources { $this->paths = Civi::paths(); } + /** + * Assimilate all the resources listed in a bundle. + * + * @param iterable|string|\CRM_Core_Resources_Bundle $bundle + * Either bundle object, or the symbolic name of a bundle, or a list of budnles. + * Note: For symbolic names, the bundle must be a container service ('bundle.FOO'). + * @return static + */ + public function addBundle($bundle) { + if (is_iterable($bundle)) { + foreach ($bundle as $b) { + $this->addBundle($b); + return $this; + } + } + + if (is_string($bundle)) { + $bundle = Civi::service('bundle.' . $bundle); + } + + if (isset($this->addedBundles[$bundle->name])) { + return $this; + } + $this->addedBundles[$bundle->name] = TRUE; + + // If an item is already assigned to a region, we'll respect that. + // Otherwise, we'll use defaults. + $pickRegion = function ($snippet) { + if (isset($snippet['settings'])) { + return $this->getSettingRegion($snippet['region'] ?? NULL)->_name; + } + else { + return $snippet['region'] ?? self::DEFAULT_REGION; + } + }; + + $byRegion = []; + foreach ($bundle->getAll() as $snippet) { + $snippet['region'] = $pickRegion($snippet); + $byRegion[$snippet['region']][$snippet['name']] = $snippet; + } + + foreach ($byRegion as $regionName => $snippets) { + CRM_Core_Region::instance($regionName)->merge($snippets); + } + return $this; + } + /** * Export permission data to the client to enable smarter GUIs. * diff --git a/CRM/Core/Resources/Bundle.php b/CRM/Core/Resources/Bundle.php new file mode 100644 index 0000000000..311dc2a05d --- /dev/null +++ b/CRM/Core/Resources/Bundle.php @@ -0,0 +1,38 @@ +name = $name; + $this->types = ['script', 'scriptFile', 'scriptUrl', 'settings', 'style', 'styleFile', 'styleUrl']; + } + +} diff --git a/CRM/Core/Resources/CollectionTrait.php b/CRM/Core/Resources/CollectionTrait.php index 38d259bc73..b402e61ea7 100644 --- a/CRM/Core/Resources/CollectionTrait.php +++ b/CRM/Core/Resources/CollectionTrait.php @@ -328,6 +328,27 @@ trait CRM_Core_Resources_CollectionTrait { // ----------------------------------------------- + /** + * Assimilate all the resources listed in a bundle. + * + * @param iterable|string|\CRM_Core_Resources_Bundle $bundle + * Either bundle object, or the symbolic name of a bundle. + * Note: For symbolic names, the bundle must be a container service ('bundle.FOO'). + * @return static + */ + public function addBundle($bundle) { + if (is_iterable($bundle)) { + foreach ($bundle as $b) { + $this->addBundle($b); + return $this; + } + } + if (is_string($bundle)) { + $bundle = Civi::service('bundle.' . $bundle); + } + return $this->merge($bundle->getAll()); + } + /** * Export permission data to the client to enable smarter GUIs. * -- 2.25.1