From: Tim Otten Date: Tue, 18 Aug 2020 02:54:08 +0000 (-0700) Subject: CollectionTrait - Support merge() X-Git-Url: https://vcs.fsf.org/?a=commitdiff_plain;h=5dddc6e037ef38639f363a3a7d9ee83d63026f81;p=civicrm-core.git CollectionTrait - Support merge() --- diff --git a/CRM/Core/Resources/CollectionTrait.php b/CRM/Core/Resources/CollectionTrait.php index eca138278d..35147c48b7 100644 --- a/CRM/Core/Resources/CollectionTrait.php +++ b/CRM/Core/Resources/CollectionTrait.php @@ -105,7 +105,12 @@ trait CRM_Core_Resources_CollectionTrait { elseif (!in_array($snippet['type'], $this->types)) { throw new \RuntimeException("Unsupported snippet type: " . $snippet['type']); } - if (!isset($snippet['name'])) { + // Traditional behavior: sort by (1) weight and (2) either name or natural position. This second thing is called 'sortId'. + if (isset($snippet['name'])) { + $snippet['sortId'] = $snippet['name']; + } + else { + $snippet['sortId'] = $this->nextId(); switch ($snippet['type']) { case 'scriptUrl': case 'styleUrl': @@ -113,7 +118,7 @@ trait CRM_Core_Resources_CollectionTrait { break; default: - $snippet['name'] = count($this->snippets); + $snippet['name'] = $snippet['sortId']; break; } } @@ -123,6 +128,17 @@ trait CRM_Core_Resources_CollectionTrait { return $snippet; } + protected function nextId() { + if (!isset(Civi::$statics['CRM_Core_Resource_Count'])) { + $resId = Civi::$statics['CRM_Core_Resource_Count'] = 1; + } + else { + $resId = ++Civi::$statics['CRM_Core_Resource_Count']; + } + + return $resId; + } + /** * @param string $name * @param $snippet @@ -214,6 +230,38 @@ trait CRM_Core_Resources_CollectionTrait { return $r; } + /** + * Assimilate a list of resources into this list. + * + * @param iterable $snippets + * List of snippets to add. + * @return static + * @see CRM_Core_Resources_CollectionInterface::merge() + */ + public function merge(iterable $snippets) { + foreach ($snippets as $next) { + $name = $next['name']; + $current = $this->snippets[$name] ?? NULL; + if ($current === NULL) { + $this->add($next); + } + elseif ($current['type'] === 'settings' && $next['type'] === 'settings') { + $this->addSetting($next['settings']); + foreach ($next['settingsFactories'] as $factory) { + $this->addSettingsFactory($factory); + } + $this->isSorted = FALSE; + } + elseif ($current['type'] === 'settings' || $next['type'] === 'settings') { + throw new \RuntimeException(sprintf("Cannot merge snippets of types [%s] and [%s]" . $current['type'], $next['type'])); + } + else { + $this->add($next); + } + } + return $this; + } + /** * Ensure that the collection is sorted. * @@ -241,10 +289,10 @@ trait CRM_Core_Resources_CollectionTrait { return 1; } // fallback to name sort; don't really want to do this, but it makes results more stable - if ($a['name'] < $b['name']) { + if ($a['sortId'] < $b['sortId']) { return -1; } - if ($a['name'] > $b['name']) { + if ($a['sortId'] > $b['sortId']) { return 1; } return 0;