From 2f0b9dc9bbf997624b77b7bb30187167bac33aeb Mon Sep 17 00:00:00 2001 From: Coleman Watts Date: Thu, 7 Apr 2022 15:40:30 -0400 Subject: [PATCH] Fix OptionValue BAO to call pre/post hooks to prevent force-reset of managed entities Managed entities rely on pre/post hooks being called in order to track whether an entity has been modified. Without those hooks OptionValues were being force-reverted by the managed system even when the 'update' mode was set to 'unmodified', which is supposed to defer to user modifications. --- CRM/Core/BAO/OptionValue.php | 5 +++++ .../api/v4/Entity/ManagedEntityTest.php | 19 ++++++++++++++++--- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/CRM/Core/BAO/OptionValue.php b/CRM/Core/BAO/OptionValue.php index 0214ca3072..bb49356d77 100644 --- a/CRM/Core/BAO/OptionValue.php +++ b/CRM/Core/BAO/OptionValue.php @@ -155,6 +155,9 @@ class CRM_Core_BAO_OptionValue extends CRM_Core_DAO_OptionValue { $params['option_group_id'], 'name', 'id' ); + $op = $id ? 'edit' : 'create'; + CRM_Utils_Hook::pre($op, 'OptionValue', $id, $params); + // action is taken depending upon the mode $optionValue = new CRM_Core_DAO_OptionValue(); $optionValue->copyValues($params); @@ -218,6 +221,8 @@ class CRM_Core_BAO_OptionValue extends CRM_Core_DAO_OptionValue { $optionValue->save(); CRM_Core_PseudoConstant::flush(); + CRM_Utils_Hook::post($op, 'OptionValue', $id, $optionValue); + // Create relationship for payment instrument options if (!empty($params['financial_account_id'])) { $optionName = civicrm_api3('OptionGroup', 'getvalue', [ diff --git a/tests/phpunit/api/v4/Entity/ManagedEntityTest.php b/tests/phpunit/api/v4/Entity/ManagedEntityTest.php index 13eb440498..ee238e7797 100644 --- a/tests/phpunit/api/v4/Entity/ManagedEntityTest.php +++ b/tests/phpunit/api/v4/Entity/ManagedEntityTest.php @@ -307,11 +307,21 @@ class ManagedEntityTest extends UnitTestCase implements TransactionalInterface, \CRM_Core_ManagedEntities::singleton(TRUE)->reconcile(); $values = OptionValue::get(FALSE) + ->addSelect('*', 'local_modified_date', 'has_base') ->addWhere('option_group_id.name', '=', 'testManagedOptionGroup') ->execute(); $this->assertCount(1, $values); $this->assertEquals('Option Value 1', $values[0]['label']); + $this->assertNull($values[0]['local_modified_date']); + $this->assertTrue($values[0]['has_base']); + + // Update option 1, now it should have a local_modified_date + // And the new label should persist after a reconcile + $result = OptionValue::update(FALSE) + ->addWhere('id', '=', $values[0]['id']) + ->addValue('label', '1 New Label') + ->execute(); $optionValue2 = [ 'module' => 'civicrm', @@ -333,8 +343,8 @@ class ManagedEntityTest extends UnitTestCase implements TransactionalInterface, ], ], ]; - $this->_managedEntities[] = $optionValue2; + \CRM_Core_ManagedEntities::singleton(TRUE)->reconcile(); $values = OptionValue::get(FALSE) @@ -344,9 +354,12 @@ class ManagedEntityTest extends UnitTestCase implements TransactionalInterface, ->execute(); $this->assertCount(2, $values); - $this->assertEquals('Option Value 2', $values[1]['label']); - $this->assertNull($values[0]['local_modified_date']); + $this->assertEquals('1 New Label', $values[0]['label']); + $this->assertNotNull($values[0]['local_modified_date']); $this->assertTrue($values[0]['has_base']); + $this->assertEquals('Option Value 2', $values[1]['label']); + $this->assertNull($values[1]['local_modified_date']); + $this->assertTrue($values[1]['has_base']); $this->_managedEntities = []; \CRM_Core_ManagedEntities::singleton(TRUE)->reconcile(); -- 2.25.1