(REF) CRM_Core_Resources::addBundle() - Improve readability. Add test.
authorTim Otten <totten@civicrm.org>
Tue, 25 Aug 2020 23:53:47 +0000 (16:53 -0700)
committerSeamus Lee <seamuslee001@gmail.com>
Thu, 3 Sep 2020 22:02:17 +0000 (08:02 +1000)
CRM/Core/Resources.php
CRM/Core/Resources/Bundle.php
tests/phpunit/CRM/Core/ResourcesTest.php

index 6d73cccb00beb705465f34899db12fe2e0076cee..4a48798230c8ca38a716bd9c863eeb21dadb6bda 100644 (file)
@@ -219,23 +219,17 @@ class CRM_Core_Resources implements CRM_Core_Resources_CollectionAdderInterface
     }
     $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;
+    // Ensure that every asset has a region.
+    $bundle->filter(function($snippet) {
+      if (empty($snippet['region'])) {
+        $snippet['region'] = isset($snippet['settings'])
+          ? $this->getSettingRegion()->_name
+          : self::DEFAULT_REGION;
       }
-      else {
-        return $snippet['region'] ?? self::DEFAULT_REGION;
-      }
-    };
-
-    $byRegion = [];
-    foreach ($bundle->getAll() as $snippet) {
-      $snippet['region'] = $pickRegion($snippet);
-      $byRegion[$snippet['region']][$snippet['name']] = $snippet;
-    }
+      return $snippet;
+    });
 
+    $byRegion = CRM_Utils_Array::index(['region', 'name'], $bundle->getAll());
     foreach ($byRegion as $regionName => $snippets) {
       CRM_Core_Region::instance($regionName)->merge($snippets);
     }
index 311dc2a05d39127c9bff272e75b3af847e60bec2..62c1a04269589c1d920fea34b483eb8290e29f69 100644 (file)
@@ -29,10 +29,13 @@ class CRM_Core_Resources_Bundle implements CRM_Core_Resources_CollectionInterfac
   public $name;
 
   /**
+   * @param string|NULL $name
+   * @param string[]|NULL $types
+   *   List of resource-types to permit in this bundle. NULL for a default list.
    */
-  public function __construct($name = NULL) {
+  public function __construct($name = NULL, $types = NULL) {
     $this->name = $name;
-    $this->types = ['script', 'scriptFile', 'scriptUrl', 'settings', 'style', 'styleFile', 'styleUrl'];
+    $this->types = $types ?: ['script', 'scriptFile', 'scriptUrl', 'settings', 'style', 'styleFile', 'styleUrl'];
   }
 
 }
index e3e8627bd847a90e15c93252d422138aa8dd2285..2d726ab811c64d649e61500d5200eccdf72e3d12 100644 (file)
@@ -60,6 +60,51 @@ class CRM_Core_ResourcesTest extends CiviUnitTestCase {
     $_GET = $this->originalGet;
   }
 
+  /**
+   * Make two bundles (multi-regional). Add them to CRM_Core_Resources.
+   * Ensure that the resources land in the right regions.
+   */
+  public function testAddBundle() {
+    $foo = new CRM_Core_Resources_Bundle('foo', ['scriptUrl', 'styleUrl', 'markup']);
+    $bar = new CRM_Core_Resources_Bundle('bar', ['scriptUrl', 'styleUrl', 'markup']);
+
+    $foo->addScriptUrl('http://example.com/foo.js', 100, 'testAddBundle_foo');
+    $foo->add(['markup' => 'Hello, foo', 'region' => 'page-header']);
+    $bar->addScriptUrl('http://example.com/bar.js', 100, 'testAddBundle_bar');
+    $bar->add(['markup' => 'Hello, bar', 'region' => 'page-header']);
+    $foo->addStyleUrl('http://example.com/shoes.css');
+
+    $this->res->addBundle($foo);
+    $this->res->addBundle([$bar]);
+
+    $getPropsByRegion = function($region, $key) {
+      $props = [];
+      foreach (CRM_Core_Region::instance($region)->getAll() as $snippet) {
+        if (isset($snippet[$key])) {
+          $props[] = $snippet[$key];
+        }
+      }
+      return $props;
+    };
+
+    $this->assertEquals(
+      ['http://example.com/foo.js'],
+      $getPropsByRegion('testAddBundle_foo', 'scriptUrl')
+    );
+    $this->assertEquals(
+      ['http://example.com/bar.js'],
+      $getPropsByRegion('testAddBundle_bar', 'scriptUrl')
+    );
+    $this->assertEquals(
+      ['', 'Hello, foo', 'Hello, bar'],
+      $getPropsByRegion('page-header', 'markup')
+    );
+    $this->assertEquals(
+      ['http://example.com/shoes.css'],
+      $getPropsByRegion('page-footer', 'styleUrl')
+    );
+  }
+
   public function testAddScriptFile() {
     $this->res
       ->addScriptFile('com.example.ext', 'foo%20bar.js', 0, 'testAddScriptFile')