From baccd59ede074668d6d676de0dbf2e263f06fb98 Mon Sep 17 00:00:00 2001 From: Coleman Watts Date: Sat, 8 Aug 2015 15:52:06 -0400 Subject: [PATCH] CRM-13160 - Fix deleting relationshipType from MembershipType --- CRM/Contact/BAO/RelationshipType.php | 27 ++--- CRM/Member/Form/MembershipType.php | 5 +- api/v3/MembershipType.php | 19 ++- tests/phpunit/api/v3/MembershipTypeTest.php | 122 ++++++-------------- 4 files changed, 71 insertions(+), 102 deletions(-) diff --git a/CRM/Contact/BAO/RelationshipType.php b/CRM/Contact/BAO/RelationshipType.php index 131e47e3e7..b0b1caa1fd 100644 --- a/CRM/Contact/BAO/RelationshipType.php +++ b/CRM/Contact/BAO/RelationshipType.php @@ -154,19 +154,20 @@ class CRM_Contact_BAO_RelationshipType extends CRM_Contact_DAO_RelationshipType $relationship->relationship_type_id = $relationshipTypeId; $relationship->delete(); - // set all membership_type to null - $query = " -UPDATE civicrm_membership_type - SET relationship_type_id = NULL - WHERE relationship_type_id = %1 -"; - $params = array( - 1 => array( - CRM_Core_DAO::VALUE_SEPARATOR . $relationshipTypeId . CRM_Core_DAO::VALUE_SEPARATOR, - 'String', - ), - ); - CRM_Core_DAO::executeQuery($query, $params); + // remove this relationship type from membership types + $mems = civicrm_api3('MembershipType', 'get', array( + 'relationship_type_id' => array('LIKE' => "%{$relationshipTypeId}%"), + 'return' => array('id', 'relationship_type_id', 'relationship_direction'), + )); + foreach ($mems['values'] as $membershipTypeId => $membershipType) { + $pos = array_search($relationshipTypeId, $membershipType['relationship_type_id']); + // Api call may have returned false positives but currently the relationship_type_id uses + // nonstandard serialization which makes anything more accurate impossible. + if ($pos !== FALSE) { + unset($membershipType['relationship_type_id'][$pos], $membershipType['relationship_direction'][$pos]); + civicrm_api3('MembershipType', 'create', $membershipType); + } + } //fixed for CRM-3323 $mappingField = new CRM_Core_DAO_MappingField(); diff --git a/CRM/Member/Form/MembershipType.php b/CRM/Member/Form/MembershipType.php index 41ad6152f3..6605c487a2 100644 --- a/CRM/Member/Form/MembershipType.php +++ b/CRM/Member/Form/MembershipType.php @@ -176,9 +176,8 @@ class CRM_Member_Form_MembershipType extends CRM_Member_Form_MembershipConfig { if (is_array($relTypeInd)) { asort($relTypeInd); } - $memberRel = &$this->add('select', 'relationship_type_id', ts('Relationship Type'), - array('' => ts('- select -')) + $relTypeInd); - $memberRel->setMultiple(TRUE); + $memberRel = $this->add('select', 'relationship_type_id', ts('Relationship Type'), + $relTypeInd, FALSE, array('class' => 'crm-select2 huge', 'multiple' => 1)); $this->addSelect('visibility', array('placeholder' => NULL, 'option_url' => NULL)); diff --git a/api/v3/MembershipType.php b/api/v3/MembershipType.php index ea36118b2e..5d3f378f74 100644 --- a/api/v3/MembershipType.php +++ b/api/v3/MembershipType.php @@ -41,6 +41,12 @@ * API result array. */ function civicrm_api3_membership_type_create($params) { + // Workaround for fields using nonstandard serialization + foreach (array('relationship_type_id', 'relationship_direction') as $field) { + if (isset($params[$field]) && is_array($params[$field])) { + $params[$field] = implode(CRM_Core_DAO::VALUE_SEPARATOR, $params[$field]); + } + } return _civicrm_api3_basic_create(_civicrm_api3_get_BAO(__FUNCTION__), $params, 'Membership_type'); } @@ -74,7 +80,18 @@ function _civicrm_api3_membership_type_create_spec(&$params) { * API result array. */ function civicrm_api3_membership_type_get($params) { - return _civicrm_api3_basic_get(_civicrm_api3_get_BAO(__FUNCTION__), $params); + $results = _civicrm_api3_basic_get(_civicrm_api3_get_BAO(__FUNCTION__), $params); + if (!empty($results['values'])) { + foreach ($results['values'] as &$item) { + // Workaround for fields using nonstandard serialization + foreach (array('relationship_type_id', 'relationship_direction') as $field) { + if (isset($item[$field]) && !is_array($item[$field])) { + $item[$field] = (array) $item[$field]; + } + } + } + } + return $results; } /** diff --git a/tests/phpunit/api/v3/MembershipTypeTest.php b/tests/phpunit/api/v3/MembershipTypeTest.php index 39b0b10436..d2c43c7c38 100644 --- a/tests/phpunit/api/v3/MembershipTypeTest.php +++ b/tests/phpunit/api/v3/MembershipTypeTest.php @@ -40,7 +40,7 @@ class api_v3_MembershipTypeTest extends CiviUnitTestCase { parent::setUp(); $this->useTransaction(TRUE); $this->_apiversion = 3; - $this->_contactID = $this->organizationCreate(NULL); + $this->_contactID = $this->organizationCreate(); } public function testGetWithoutId() { @@ -74,16 +74,6 @@ class api_v3_MembershipTypeTest extends CiviUnitTestCase { $this->membershipTypeDelete($params); } - /** - * Civicrm_membership_type_create methods. - */ - public function testCreateWithEmptyParams() { - $membershiptype = $this->callAPIFailure('membership_type', 'create', array()); - $this->assertEquals($membershiptype['error_message'], - 'Mandatory key(s) missing from params array: domain_id, member_of_contact_id, financial_type_id, duration_unit, duration_interval, name' - ); - } - public function testCreateWithoutMemberOfContactId() { $params = array( 'name' => '60+ Membership', @@ -102,59 +92,6 @@ class api_v3_MembershipTypeTest extends CiviUnitTestCase { ); } - public function testCreateWithoutContributionTypeId() { - $params = array( - 'name' => '70+ Membership', - 'description' => 'people above 70 are given health instructions', - 'member_of_contact_id' => $this->_contactID, - 'domain_id' => '1', - 'minimum_fee' => '200', - 'duration_unit' => 'month', - 'duration_interval' => '10', - 'period_type' => 'rolling', - 'visibility' => 'public', - ); - $membershiptype = $this->callAPIFailure('membership_type', 'create', $params); - $this->assertEquals($membershiptype['error_message'], - 'Mandatory key(s) missing from params array: financial_type_id' - ); - } - - public function testCreateWithoutDurationUnit() { - $params = array( - 'name' => '80+ Membership', - 'description' => 'people above 80 are given health instructions', - 'member_of_contact_id' => $this->_contactID, - 'financial_type_id' => 1, - 'domain_id' => '1', - 'minimum_fee' => '200', - 'duration_interval' => '10', - 'visibility' => 'public', - ); - - $membershiptype = $this->callAPIFailure('membership_type', 'create', $params); - $this->assertEquals($membershiptype['error_message'], - 'Mandatory key(s) missing from params array: duration_unit' - ); - } - - public function testCreateWithoutDurationInterval() { - $params = array( - 'name' => '70+ Membership', - 'description' => 'people above 70 are given health instructions', - 'member_of_contact_id' => $this->_contactID, - 'domain_id' => '1', - 'minimum_fee' => '200', - 'duration_unit' => 'month', - 'period_type' => 'rolling', - 'visibility' => 'public', - ); - $membershiptype = $this->callAPIFailure('membership_type', 'create', $params); - $this->assertEquals($membershiptype['error_message'], - 'Mandatory key(s) missing from params array: financial_type_id, duration_interval' - ); - } - public function testCreateWithoutNameandDomainIDandDurationUnit() { $params = array( 'description' => 'people above 50 are given health instructions', @@ -208,14 +145,6 @@ class api_v3_MembershipTypeTest extends CiviUnitTestCase { $this->membershipTypeDelete(array('id' => $membershipType['id'])); } - - /** - * Test mandatory parameter check. - */ - public function testUpdateWithEmptyParams() { - $this->callAPIFailure('membership_type', 'create', array()); - } - /** * Test update fails with no ID. */ @@ -262,20 +191,8 @@ class api_v3_MembershipTypeTest extends CiviUnitTestCase { $this->getAndCheck($params, $id, $this->_entity); } - /** - * Test for failure when id is not valid. - */ - public function testDeleteNotExists() { - $params = array( - 'id' => 'doesNotExist', - ); - $this->callAPIFailure('membership_type', 'delete', $params, - 'Error while deleting membership type. id : ' . $params['id'] - ); - } - public function testDelete() { - $orgID = $this->organizationCreate(NULL); + $orgID = $this->organizationCreate(); $membershipTypeID = $this->membershipTypeCreate(array('member_of_contact_id' => $orgID)); $params = array( 'id' => $membershipTypeID, @@ -284,4 +201,39 @@ class api_v3_MembershipTypeTest extends CiviUnitTestCase { $this->callAPIAndDocument('membership_type', 'delete', $params, __FUNCTION__, __FILE__); } + public function testDeleteRelationshipTypesUsedByMembershipType() { + $rel1 = $this->relationshipTypeCreate(array( + 'name_a_b' => 'abcde', + 'name_b_a' => 'abcde', + )); + $rel2 = $this->relationshipTypeCreate(array( + 'name_a_b' => 'fghij', + 'name_b_a' => 'fghij', + )); + $rel3 = $this->relationshipTypeCreate(array( + 'name_a_b' => 'lkmno', + 'name_b_a' => 'lkmno', + )); + $id = $this->membershipTypeCreate(array( + 'member_of_contact_id' => $this->_contactID, + 'relationship_type_id' => array($rel1, $rel2, $rel3), + 'relationship_direction' => array('a_b', 'a_b', 'b_a'), + )); + + $this->callAPISuccess('RelationshipType', 'delete', array('id' => $rel2)); + $newValues = $this->callAPISuccess('MembershipType', 'getsingle', array('id' => $id)); + $this->assertEquals(array($rel1, $rel3), $newValues['relationship_type_id']); + $this->assertEquals(array('a_b', 'b_a'), $newValues['relationship_direction']); + + $this->callAPISuccess('RelationshipType', 'delete', array('id' => $rel1)); + $newValues = $this->callAPISuccess('MembershipType', 'getsingle', array('id' => $id)); + $this->assertEquals(array($rel3), $newValues['relationship_type_id']); + $this->assertEquals(array('b_a'), $newValues['relationship_direction']); + + $this->callAPISuccess('RelationshipType', 'delete', array('id' => $rel3)); + $newValues = $this->callAPISuccess('MembershipType', 'getsingle', array('id' => $id)); + $this->assertTrue(empty($newValues['relationship_type_id'])); + $this->assertTrue(empty($newValues['relationship_direction'])); + } + } -- 2.25.1