From 052cd546449a6271e69024e8d47a019500e155f1 Mon Sep 17 00:00:00 2001 From: Coleman Watts Date: Fri, 12 Nov 2021 22:03:16 -0500 Subject: [PATCH] APIv4 - Opt-in more ManagedEntity types Adds the ManagedEntity trait to a number of entities that are commonly used for configuration. --- CRM/Core/DAO.php | 2 +- CRM/Core/Reference/Interface.php | 2 +- Civi/Api4/ContactType.php | 1 + Civi/Api4/CustomField.php | 1 + Civi/Api4/CustomGroup.php | 1 + Civi/Api4/Membership.php | 1 - Civi/Api4/MembershipStatus.php | 1 + Civi/Api4/MembershipType.php | 1 + Civi/Api4/OptionGroup.php | 1 + Civi/Api4/OptionValue.php | 1 + Civi/Api4/PaymentProcessorType.php | 1 + Civi/Api4/RelationshipType.php | 1 + .../api/v4/Entity/ManagedEntityTest.php | 118 ++++++++++++++++-- 13 files changed, 121 insertions(+), 11 deletions(-) diff --git a/CRM/Core/DAO.php b/CRM/Core/DAO.php index 1c6e774dbb..906c3aeb9f 100644 --- a/CRM/Core/DAO.php +++ b/CRM/Core/DAO.php @@ -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; } } diff --git a/CRM/Core/Reference/Interface.php b/CRM/Core/Reference/Interface.php index f1bcaff6d2..c5ee1fff58 100644 --- a/CRM/Core/Reference/Interface.php +++ b/CRM/Core/Reference/Interface.php @@ -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 diff --git a/Civi/Api4/ContactType.php b/Civi/Api4/ContactType.php index e78beb2cc1..74eeccd9d8 100644 --- a/Civi/Api4/ContactType.php +++ b/Civi/Api4/ContactType.php @@ -27,5 +27,6 @@ namespace Civi\Api4; */ class ContactType extends Generic\DAOEntity { use Generic\Traits\OptionList; + use Generic\Traits\ManagedEntity; } diff --git a/Civi/Api4/CustomField.php b/Civi/Api4/CustomField.php index c308738a96..533644f548 100644 --- a/Civi/Api4/CustomField.php +++ b/Civi/Api4/CustomField.php @@ -19,5 +19,6 @@ namespace Civi\Api4; * @package Civi\Api4 */ class CustomField extends Generic\DAOEntity { + use Generic\Traits\ManagedEntity; } diff --git a/Civi/Api4/CustomGroup.php b/Civi/Api4/CustomGroup.php index 26125a102d..11473bdaaf 100644 --- a/Civi/Api4/CustomGroup.php +++ b/Civi/Api4/CustomGroup.php @@ -19,5 +19,6 @@ namespace Civi\Api4; * @package Civi\Api4 */ class CustomGroup extends Generic\DAOEntity { + use Generic\Traits\ManagedEntity; } diff --git a/Civi/Api4/Membership.php b/Civi/Api4/Membership.php index 3906edd802..751cd65e32 100644 --- a/Civi/Api4/Membership.php +++ b/Civi/Api4/Membership.php @@ -18,6 +18,5 @@ namespace Civi\Api4; * @package Civi\Api4 */ class Membership extends Generic\DAOEntity { - use Generic\Traits\OptionList; } diff --git a/Civi/Api4/MembershipStatus.php b/Civi/Api4/MembershipStatus.php index e94c6c237e..7b36fa90b8 100644 --- a/Civi/Api4/MembershipStatus.php +++ b/Civi/Api4/MembershipStatus.php @@ -19,5 +19,6 @@ namespace Civi\Api4; */ class MembershipStatus extends Generic\DAOEntity { use Generic\Traits\OptionList; + use Generic\Traits\ManagedEntity; } diff --git a/Civi/Api4/MembershipType.php b/Civi/Api4/MembershipType.php index 7b1d891c23..6be44a5f92 100644 --- a/Civi/Api4/MembershipType.php +++ b/Civi/Api4/MembershipType.php @@ -19,5 +19,6 @@ namespace Civi\Api4; */ class MembershipType extends Generic\DAOEntity { use Generic\Traits\OptionList; + use Generic\Traits\ManagedEntity; } diff --git a/Civi/Api4/OptionGroup.php b/Civi/Api4/OptionGroup.php index 0f909bd6b0..fa4f11c66f 100644 --- a/Civi/Api4/OptionGroup.php +++ b/Civi/Api4/OptionGroup.php @@ -20,5 +20,6 @@ namespace Civi\Api4; */ class OptionGroup extends Generic\DAOEntity { use Generic\Traits\OptionList; + use Generic\Traits\ManagedEntity; } diff --git a/Civi/Api4/OptionValue.php b/Civi/Api4/OptionValue.php index cccb88f6be..8c42cbf046 100644 --- a/Civi/Api4/OptionValue.php +++ b/Civi/Api4/OptionValue.php @@ -20,5 +20,6 @@ namespace Civi\Api4; */ class OptionValue extends Generic\DAOEntity { use Generic\Traits\OptionList; + use Generic\Traits\ManagedEntity; } diff --git a/Civi/Api4/PaymentProcessorType.php b/Civi/Api4/PaymentProcessorType.php index bc60c6180d..1cdcdd7c20 100644 --- a/Civi/Api4/PaymentProcessorType.php +++ b/Civi/Api4/PaymentProcessorType.php @@ -21,5 +21,6 @@ namespace Civi\Api4; */ class PaymentProcessorType extends Generic\DAOEntity { use Generic\Traits\OptionList; + use Generic\Traits\ManagedEntity; } diff --git a/Civi/Api4/RelationshipType.php b/Civi/Api4/RelationshipType.php index a46723a051..113b44b724 100644 --- a/Civi/Api4/RelationshipType.php +++ b/Civi/Api4/RelationshipType.php @@ -21,5 +21,6 @@ namespace Civi\Api4; */ class RelationshipType extends Generic\DAOEntity { use Generic\Traits\OptionList; + use Generic\Traits\ManagedEntity; } diff --git a/tests/phpunit/api/v4/Entity/ManagedEntityTest.php b/tests/phpunit/api/v4/Entity/ManagedEntityTest.php index fb3d8ee35d..5cdd5e12d4 100644 --- a/tests/phpunit/api/v4/Entity/ManagedEntityTest.php +++ b/tests/phpunit/api/v4/Entity/ManagedEntityTest.php @@ -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() { -- 2.25.1