APIv4 - Opt-in more ManagedEntity types
authorColeman Watts <coleman@civicrm.org>
Sat, 13 Nov 2021 03:03:16 +0000 (22:03 -0500)
committerColeman Watts <coleman@civicrm.org>
Sat, 13 Nov 2021 19:48:57 +0000 (14:48 -0500)
Adds the ManagedEntity trait to a number of entities that are commonly
used for configuration.

13 files changed:
CRM/Core/DAO.php
CRM/Core/Reference/Interface.php
Civi/Api4/ContactType.php
Civi/Api4/CustomField.php
Civi/Api4/CustomGroup.php
Civi/Api4/Membership.php
Civi/Api4/MembershipStatus.php
Civi/Api4/MembershipType.php
Civi/Api4/OptionGroup.php
Civi/Api4/OptionValue.php
Civi/Api4/PaymentProcessorType.php
Civi/Api4/RelationshipType.php
tests/phpunit/api/v4/Entity/ManagedEntityTest.php

index 1c6e774dbb69469ed2d274dba835d98308faa65d..906c3aeb9f484ad2fd6ece08f2bf0a476a81e659 100644 (file)
@@ -2562,7 +2562,7 @@ SELECT contact_id
     foreach ($links as $refSpec) {
       /** @var $refSpec CRM_Core_Reference_Interface */
       $count = $refSpec->getReferenceCount($this);
-      if ($count['count'] != 0) {
+      if (!empty($count['count'])) {
         $counts[] = $count;
       }
     }
index f1bcaff6d26e0d4d18c6630a876b14247b309f82..c5ee1fff58af78c20059bda123d78def2743f01c 100644 (file)
@@ -31,7 +31,7 @@ interface CRM_Core_Reference_Interface {
    *
    * @param CRM_Core_DAO $targetDao
    *   The instance for which we want references.
-   * @return array
+   * @return array{type: string, count: int}|NULL
    *   a record describing the reference; must include the keys:
    *   - 'type': string (not necessarily unique)
    *   - 'count': int
index e78beb2cc169c0e0997302d37b5a673d02763137..74eeccd9d82524e1d98988c76188bc532e2e9a75 100644 (file)
@@ -27,5 +27,6 @@ namespace Civi\Api4;
  */
 class ContactType extends Generic\DAOEntity {
   use Generic\Traits\OptionList;
+  use Generic\Traits\ManagedEntity;
 
 }
index c308738a962e909f5df5a2f717294150e49757a4..533644f548d24eac1c435ea7fc10790056fd1062 100644 (file)
@@ -19,5 +19,6 @@ namespace Civi\Api4;
  * @package Civi\Api4
  */
 class CustomField extends Generic\DAOEntity {
+  use Generic\Traits\ManagedEntity;
 
 }
index 26125a102dc070161921ccb7b7b4d5b89ee12ad5..11473bdaaf12ff53ca1d52c026db75705fa32f71 100644 (file)
@@ -19,5 +19,6 @@ namespace Civi\Api4;
  * @package Civi\Api4
  */
 class CustomGroup extends Generic\DAOEntity {
+  use Generic\Traits\ManagedEntity;
 
 }
index 3906edd80232b5e437099ff6b09e783adca299e3..751cd65e32a8a1a1ec7a02019f67001ea00d3676 100644 (file)
@@ -18,6 +18,5 @@ namespace Civi\Api4;
  * @package Civi\Api4
  */
 class Membership extends Generic\DAOEntity {
-  use Generic\Traits\OptionList;
 
 }
index e94c6c237ed395c42df98902dc466c9d87d7f531..7b36fa90b814d75cd70a3331230cb1c8cdd02ca4 100644 (file)
@@ -19,5 +19,6 @@ namespace Civi\Api4;
  */
 class MembershipStatus extends Generic\DAOEntity {
   use Generic\Traits\OptionList;
+  use Generic\Traits\ManagedEntity;
 
 }
index 7b1d891c23d275798b49d58e013b6030f59d8914..6be44a5f927c656829492ce1708a87013dbfadc8 100644 (file)
@@ -19,5 +19,6 @@ namespace Civi\Api4;
  */
 class MembershipType extends Generic\DAOEntity {
   use Generic\Traits\OptionList;
+  use Generic\Traits\ManagedEntity;
 
 }
index 0f909bd6b0b77f4fa13f04da106b08c9be0478b2..fa4f11c66f60f00dded2c829ebe5a15b9bc6c1f1 100644 (file)
@@ -20,5 +20,6 @@ namespace Civi\Api4;
  */
 class OptionGroup extends Generic\DAOEntity {
   use Generic\Traits\OptionList;
+  use Generic\Traits\ManagedEntity;
 
 }
index cccb88f6be551ee5f7ae36a2fb59a7b2c16d129e..8c42cbf04662974fe3e0eaa19a99293fe025082b 100644 (file)
@@ -20,5 +20,6 @@ namespace Civi\Api4;
  */
 class OptionValue extends Generic\DAOEntity {
   use Generic\Traits\OptionList;
+  use Generic\Traits\ManagedEntity;
 
 }
index bc60c6180d95a55318c4068f56e63dd9e354a09b..1cdcdd7c20fd368db8f25067f88e3557e4c79282 100644 (file)
@@ -21,5 +21,6 @@ namespace Civi\Api4;
  */
 class PaymentProcessorType extends Generic\DAOEntity {
   use Generic\Traits\OptionList;
+  use Generic\Traits\ManagedEntity;
 
 }
index a46723a051b3170aaabf3bd279b455840551bb53..113b44b72444bc904d41132553d0f950f9091d28 100644 (file)
@@ -21,5 +21,6 @@ namespace Civi\Api4;
  */
 class RelationshipType extends Generic\DAOEntity {
   use Generic\Traits\OptionList;
+  use Generic\Traits\ManagedEntity;
 
 }
index fb3d8ee35d98ab0e032cce99d3566c03c74d468e..5cdd5e12d4317a235cb5b20f94f0c331b235afb9 100644 (file)
@@ -19,6 +19,8 @@
 namespace api\v4\Entity;
 
 use api\v4\UnitTestCase;
+use Civi\Api4\OptionGroup;
+use Civi\Api4\OptionValue;
 use Civi\Api4\SavedSearch;
 use Civi\Test\HookInterface;
 use Civi\Test\TransactionalInterface;
@@ -257,6 +259,97 @@ class ManagedEntityTest extends UnitTestCase implements TransactionalInterface,
     $this->assertNull($search['local_modified_date']);
   }
 
+  public function testOptionGroupAndValues() {
+    $optionGroup = [
+      'module' => 'civicrm',
+      'name' => 'testManagedOptionGroup',
+      'entity' => 'OptionGroup',
+      'cleanup' => 'unused',
+      'update' => 'unmodified',
+      'params' => [
+        'version' => 4,
+        'values' => [
+          'name' => 'testManagedOptionGroup',
+          'title' => 'Test Managed Option Group',
+          'description' => 'Original state',
+          'is_active' => TRUE,
+          'is_locked' => FALSE,
+        ],
+      ],
+    ];
+    $optionValue1 = [
+      'module' => 'civicrm',
+      'name' => 'testManagedOptionValue1',
+      'entity' => 'OptionValue',
+      'cleanup' => 'unused',
+      'update' => 'unmodified',
+      'params' => [
+        'version' => 4,
+        'values' => [
+          'option_group_id.name' => 'testManagedOptionGroup',
+          'value' => 1,
+          'label' => 'Option Value 1',
+          'description' => 'Original state',
+          'is_active' => TRUE,
+          'is_reserved' => FALSE,
+          'weight' => 1,
+          'icon' => 'fa-test',
+        ],
+      ],
+    ];
+    $this->_managedEntities[] = $optionGroup;
+    $this->_managedEntities[] = $optionValue1;
+    \CRM_Core_ManagedEntities::singleton(TRUE)->reconcile();
+
+    $values = OptionValue::get(FALSE)
+      ->addWhere('option_group_id.name', '=', 'testManagedOptionGroup')
+      ->execute();
+
+    $this->assertCount(1, $values);
+    $this->assertEquals('Option Value 1', $values[0]['label']);
+
+    $optionValue2 = [
+      'module' => 'civicrm',
+      'name' => 'testManagedOptionValue2',
+      'entity' => 'OptionValue',
+      'cleanup' => 'unused',
+      'update' => 'unmodified',
+      'params' => [
+        'version' => 4,
+        'values' => [
+          'option_group_id.name' => 'testManagedOptionGroup',
+          'value' => 2,
+          'label' => 'Option Value 2',
+          'description' => 'Original state',
+          'is_active' => TRUE,
+          'is_reserved' => FALSE,
+          'weight' => 2,
+          'icon' => 'fa-test',
+        ],
+      ],
+    ];
+
+    $this->_managedEntities[] = $optionValue2;
+    \CRM_Core_ManagedEntities::singleton(TRUE)->reconcile();
+
+    $values = OptionValue::get(FALSE)
+      ->addWhere('option_group_id.name', '=', 'testManagedOptionGroup')
+      ->addSelect('*', 'local_modified_date', 'has_base')
+      ->addOrderBy('weight')
+      ->execute();
+
+    $this->assertCount(2, $values);
+    $this->assertEquals('Option Value 2', $values[1]['label']);
+    $this->assertNull($values[0]['local_modified_date']);
+    $this->assertTrue($values[0]['has_base']);
+
+    $this->_managedEntities = [];
+    \CRM_Core_ManagedEntities::singleton(TRUE)->reconcile();
+
+    $this->assertCount(0, OptionValue::get(FALSE)->addWhere('id', 'IN', $values->column('id'))->execute());
+    $this->assertCount(0, OptionGroup::get(FALSE)->addWhere('name', '=', 'testManagedOptionGroup')->execute());
+  }
+
   /**
    * @dataProvider sampleEntityTypes
    * @param string $entityName
@@ -267,18 +360,27 @@ class ManagedEntityTest extends UnitTestCase implements TransactionalInterface,
   }
 
   public function sampleEntityTypes() {
-    return [
+    $entityTypes = [
       // v3 pseudo-entity
-      'ActivityType' => ['ActivityType', FALSE],
+      'ActivityType' => FALSE,
       // v3 pseudo-entity
-      'CustomSearch' => ['CustomSearch', FALSE],
-      // Not a dao entity, can't be managed
-      'Entity' => ['Entity', FALSE],
+      'CustomSearch' => FALSE,
+      // Non-dao entities can't be managed
+      'Entity' => FALSE,
+      'Afform' => FALSE,
+      'Settings' => FALSE,
       // v4 entity not using ManagedEntity trait
-      'UFJoin' => ['UFJoin', FALSE],
-      // v4 entity using ManagedEntity trait
-      'SavedSearch' => ['SavedSearch', TRUE],
+      'UFJoin' => FALSE,
+      // v4 entities using ManagedEntity trait
+      'ContactType' => TRUE,
+      'CustomField' => TRUE,
+      'CustomGroup' => TRUE,
+      'MembershipType' => TRUE,
+      'OptionGroup' => TRUE,
+      'OptionValue' => TRUE,
+      'SavedSearch' => TRUE,
     ];
+    return array_combine(array_keys($entityTypes), \CRM_Utils_Array::makeNonAssociative($entityTypes, 0, 1));
   }
 
   private function getCurrentTimestamp() {