Skip to content
Snippets Groups Projects
Commit e46fba18 authored by colemanw's avatar colemanw
Browse files

Merge pull request #1691 from eileenmcnaughton/CRM-13234

CRM-13234 fixes on profile api required due to added tests (caching issue, field mapping issue)
parents 27f0b7e5 29fbb90a
Branches
Tags
No related merge requests found
......@@ -47,17 +47,16 @@
* {getfields MembershipType_get}
*/
function civicrm_api3_membership_type_create($params) {
$values = $params;
civicrm_api3_verify_mandatory($values, 'CRM_Member_DAO_MembershipType');
$ids['membershipType'] = CRM_Utils_Array::value('id', $params);
$ids['memberOfContact'] = CRM_Utils_Array::value('member_of_contact_id', $params);
$ids['contributionType'] = CRM_Utils_Array::value('financial_type_id', $params);
$ids['membershipType'] = CRM_Utils_Array::value('id', $values);
$ids['memberOfContact'] = CRM_Utils_Array::value('member_of_contact_id', $values);
$ids['contributionType'] = CRM_Utils_Array::value('financial_type_id', $values);
$membershipTypeBAO = CRM_Member_BAO_MembershipType::add($values, $ids);
$membershipTypeBAO = CRM_Member_BAO_MembershipType::add($params, $ids);
$membershipType = array();
_civicrm_api3_object_to_array($membershipTypeBAO, $membershipType[$membershipTypeBAO->id]);
CRM_Member_PseudoConstant::membershipType(NULL, TRUE);
civicrm_api3('membership', 'getfields', array('cache_clear' => 1, 'fieldname' => 'membership_type_id'));
civicrm_api3('profile', 'getfields', array('action' => 'submit', 'cache_clear' => 1));
return civicrm_api3_create_success($membershipType, $params, 'membership_type', 'create', $membershipTypeBAO);
}
......
......@@ -295,7 +295,10 @@ function _civicrm_api3_profile_submit_spec(&$params, $apirequest) {
// we don't resolve state, country & county for performance reasons
$resolveOptions = CRM_Utils_Array::value('get_options',$apirequest['params']) == 'all' ? True : False;
$profileID = _civicrm_api3_profile_getProfileID($apirequest['params']['profile_id']);
$params = _civicrm_api3_buildprofile_submitfields($profileID, $resolveOptions);
$params = _civicrm_api3_buildprofile_submitfields($profileID, $resolveOptions, CRM_Utils_Array::value('cache_clear', $params));
}
elseif (isset($apirequest['params']['cache_clear'])) {
_civicrm_api3_buildprofile_submitfields(FALSE, FALSE, True);
}
$params['profile_id']['api.required'] = TRUE;
}
......@@ -451,10 +454,21 @@ function _civicrm_api3_profile_getbillingpseudoprofile(&$params) {
*
* @param integer $profileID
* @param integer $optionsBehaviour 0 = don't resolve, 1 = resolve non-aggressively, 2 = resolve aggressively - ie include country & state
* @param $is_flush
*
* @internal param $params
*
* @return
*/
function _civicrm_api3_buildprofile_submitfields($profileID, $optionsBehaviour = 1) {
function _civicrm_api3_buildprofile_submitfields($profileID, $optionsBehaviour = 1, $is_flush) {
static $profileFields = array();
if($is_flush) {
$profileFields = array();
if(empty($profileID)) {
return;
}
}
if(isset($profileFields[$profileID])) {
return $profileFields[$profileID];
}
......@@ -504,20 +518,38 @@ function _civicrm_api3_buildprofile_submitfields($profileID, $optionsBehaviour =
$result = civicrm_api3($entity, 'getfields', array('action' => 'create'));
$entityGetFieldsResult = _civicrm_api3_profile_appendaliases($result['values'], $entity);
foreach ($entityFields as $entityfield => $realName) {
$profileFields[$profileID][strtolower($entityfield)] = array_merge($profileFields[$profileID][$entityfield], $entityGetFieldsResult[$realName]);
$fieldName = strtolower($entityfield);
if(!strstr($fieldName, '-')) {
if(strtolower($realName) != $fieldName) {
// we want to keep the '-' pattern for locations but otherwise
// we are going to make the api-standard field the main / preferred name but support the db name
// in future naming the fields in the DB to reflect the way the rest of the api / BAO / metadata works would
// reduce code
$fieldName = strtolower($realName);
}
if(isset($entityGetFieldsResult[$realName]['uniqueName'])) {
// we won't alias the field name on here are we are using uniqueNames for the possibility of needing to differentiate
// which entity 'status_id' belongs to
$fieldName = $entityGetFieldsResult[$realName]['uniqueName'];
}
}
$profileFields[$profileID][$fieldName] = array_merge($profileFields[$profileID][$entityfield], $entityGetFieldsResult[$realName]);
if(!isset($profileFields[$profileID][$fieldName]['api.aliases'])) {
$profileFields[$profileID][$fieldName]['api.aliases'] = array();
}
if($optionsBehaviour && !empty($entityGetFieldsResult[$realName]['pseudoconstant'])) {
if($optionsBehaviour > 1 || !in_array($realName, array('state_province_id', 'county_id', 'country_id'))) {
$options = civicrm_api3($entity, 'getoptions', array('field' => $realName));
$profileFields[$profileID][$entityfield]['options'] = $options['values'];
$profileFields[$profileID][$fieldName]['options'] = $options['values'];
}
}
if($entityfield != strtolower($entityfield)) {
// we will make the mixed case version (e.g. of 'Primary') an aliase
if(!isset($profileFields[$profileID][strtolower($entityfield)])) {
$profileFields[$profileID][strtolower($entityfield)]['api.aliases'] = array();
if($entityfield != $fieldName) {
if(isset($profileFields[$profileID][$entityfield])) {
unset($profileFields[$profileID][$entityfield]);
}
$profileFields[$profileID][strtolower($entityfield)]['api.aliases'][] = $entityfield;
// we will make the mixed case version (e.g. of 'Primary') an alias
$profileFields[$profileID][$fieldName]['api.aliases'][] = $entityfield;
}
/**
* putting this on hold -this would cause the api to set the default - but could have unexpected behaviour
......@@ -539,27 +571,28 @@ function _civicrm_api3_buildprofile_submitfields($profileID, $optionsBehaviour =
function _civicrm_api3_map_profile_fields_to_entity(&$field) {
$entity = $field['field_type'];
$contactTypes = civicrm_api3('contact', 'getoptions', array('field' => 'contact_type'));
$locationFields = array('email' => 'Email');
if(in_array($entity, $contactTypes['values'])) {
$entity = 'Contact';
$entity = 'contact';
}
$entity = _civicrm_api_get_entity_name_from_camel($entity);
$locationFields = array('email' => 'email');
$fieldName = $field['field_name'];
if(!empty($field['location_type_id'])) {
if($fieldName == 'email') {
$entity = 'Email';
$entity = 'email';
}
else{
$entity = 'Address';
$entity = 'address';
}
$fieldName .= '-' . $field['location_type_id'];
}
elseif(array_key_exists($fieldName, $locationFields)) {
$fieldName .= '-Primary';
$entity = 'Email';
$entity = 'email';
}
if(!empty($field['phone_type_id'])) {
$fieldName .= '-' . $field['location_type_id'];
$entity = 'Phone';
$entity = 'phone';
}
// @todo - sort this out!
......@@ -568,29 +601,29 @@ function _civicrm_api3_map_profile_fields_to_entity(&$field) {
// in a perfect world the uf_field table would hold the correct entity for each item
// & only the relationships between entities would need to be coded
$hardCodedEntityMappings = array(
'street_address' => 'Address',
'street_number' => 'Address',
'supplemental_address_1' => 'Address',
'supplemental_address_2' => 'Address',
'supplemental_address_3' => 'Address',
'postal_code' => 'Address',
'city' => 'Address',
'email' => 'Email',
'state_province' => 'Address',
'country' => 'Address',
'county' => 'Address',
'street_address' => 'address',
'street_number' => 'address',
'supplemental_address_1' => 'address',
'supplemental_address_2' => 'address',
'supplemental_address_3' => 'address',
'postal_code' => 'address',
'city' => 'address',
'email' => 'email',
'state_province' => 'address',
'country' => 'address',
'county' => 'address',
//note that in discussions about how to restructure the api we discussed making these membership
// fields into 'membership_payment' fields - which would entail declaring them in getfields
// & renaming them in existing profiles
'financial_type' => 'Contribution',
'total_amount' => 'Contribution',
'receive_date' => 'Contribution',
'payment_instrument' => 'Contribution',
'check_number' => 'Contribution',
'contribution_status_id' => 'Contribution',
'soft_credit' => 'Contribution',
'group' => 'GroupContact',
'tag' => 'EntityTag',
'financial_type' => 'contribution',
'total_amount' => 'contribution',
'receive_date' => 'contribution',
'payment_instrument' => 'contribution',
'check_number' => 'contribution',
'contribution_status_id' => 'contribution',
'soft_credit' => 'contribution',
'group' => 'group_contact',
'tag' => 'entity_tag',
);
if(array_key_exists($fieldName, $hardCodedEntityMappings)) {
$entity = $hardCodedEntityMappings[$fieldName];
......@@ -633,7 +666,7 @@ function _civicrm_api3_profile_appendaliases($values, $entity) {
}
}
//special case on membership & contribution - can't see how to handle in a generic way
if(in_array($entity, array('Membership', 'Contribution'))) {
if(in_array($entity, array('membership', 'contribution'))) {
$values['send_receipt'] = array('title' => 'Send Receipt', 'type' => (int) 16);
}
return $values;
......
......@@ -38,7 +38,7 @@ function profile_getfields_expectedresult(){
'title' => 'First Name',
'help_pre' => '',
'help_post' => '',
'entity' => 'Contact',
'entity' => 'contact',
'name' => 'first_name',
'type' => 2,
'maxlength' => 64,
......@@ -48,13 +48,14 @@ function profile_getfields_expectedresult(){
'headerPattern' => '/^first|(f(irst\s)?name)$/i',
'dataPattern' => '/^\w+$/',
'export' => true,
'api.aliases' => array(),
),
'last_name' => array(
'api.required' => '1',
'title' => 'Last Name',
'help_pre' => '',
'help_post' => '',
'entity' => 'Contact',
'entity' => 'contact',
'name' => 'last_name',
'type' => 2,
'maxlength' => 64,
......@@ -64,13 +65,14 @@ function profile_getfields_expectedresult(){
'headerPattern' => '/^last|(l(ast\s)?name)$/i',
'dataPattern' => '/^\w+(\s\w+)?+$/',
'export' => true,
'api.aliases' => array(),
),
'email-primary' => array(
'api.required' => 1,
'title' => 'Email',
'help_pre' => '',
'help_post' => '',
'entity' => 'Email',
'entity' => 'email',
'api.aliases' => array(
'0' => 'email-Primary',
),
......@@ -90,7 +92,7 @@ function profile_getfields_expectedresult(){
'title' => 'Phone',
'help_pre' => '',
'help_post' => '',
'entity' => 'Phone',
'entity' => 'phone',
'name' => 'phone',
'type' => 2,
'maxlength' => 32,
......@@ -100,13 +102,14 @@ function profile_getfields_expectedresult(){
'headerPattern' => '/phone/i',
'dataPattern' => '/^[\d\(\)\-\.\s]+$/',
'export' => true,
'api.aliases' => array(),
),
'country-1' => array(
'api.required' => '1',
'title' => 'Country',
'help_pre' => '',
'help_post' => '',
'entity' => 'Address',
'entity' => 'address',
'name' => 'country_id',
'type' => 1,
'FKClassName' => 'CRM_Core_DAO_Country',
......@@ -116,13 +119,14 @@ function profile_getfields_expectedresult(){
'labelColumn' => 'name',
'nameColumn' => 'iso_code',
),
'api.aliases' => array(),
),
'state_province-1' => array(
'api.required' => '1',
'title' => 'State',
'help_pre' => '',
'help_post' => '',
'entity' => 'Address',
'entity' => 'address',
'name' => 'state_province_id',
'type' => 1,
'FKClassName' => 'CRM_Core_DAO_StateProvince',
......@@ -131,13 +135,14 @@ function profile_getfields_expectedresult(){
'keyColumn' => 'id',
'labelColumn' => 'name',
),
'api.aliases' => array(),
),
'postal_code-1' => array(
'api.required' => 0,
'title' => 'Postal Code',
'help_pre' => '',
'help_post' => '',
'entity' => 'Address',
'entity' => 'address',
'name' => 'postal_code',
'type' => 2,
'maxlength' => 12,
......@@ -147,13 +152,14 @@ function profile_getfields_expectedresult(){
'headerPattern' => '/postal|zip/i',
'dataPattern' => '/\d?\d{4}(-\d{4})?/',
'export' => true,
'api.aliases' => array(),
),
'custom_1' => array(
'api.required' => '1',
'title' => 'first_name',
'help_pre' => '',
'help_post' => '',
'entity' => 'Contact',
'entity' => 'contact',
'label' => '_addCustomFieldToProfile',
'groupTitle' => '_addCustomFie',
'data_type' => 'String',
......@@ -173,6 +179,7 @@ function profile_getfields_expectedresult(){
'time_format' => '',
'name' => 'custom_1',
'type' => 2,
'api.aliases' => array(),
),
'profile_id' => array(
'api.required' => true,
......
......@@ -65,6 +65,7 @@ function profile_submit_expectedresult(){
'first_name' => 'abc2',
'middle_name' => 'J.',
'last_name' => 'xyz2',
'prefix_id' => '3',
'suffix_id' => '3',
'email_greeting_id' => '1',
'email_greeting_custom' => '',
......
......@@ -39,6 +39,8 @@ require_once 'tests/phpunit/CiviTest/CiviUnitTestCase.php';
class api_v3_ProfileTest extends CiviUnitTestCase {
protected $_apiversion;
protected $_profileID = 0;
protected $_membershipTypeID;
protected $_contactID;
function get_info() {
return array(
'name' => 'Profile Test',
......@@ -54,6 +56,7 @@ class api_v3_ProfileTest extends CiviUnitTestCase {
$config->countryLimit[1] = 1013;
$config->stateLimit[1] = 1013;
$this->createLoggedInUser();
$this->_membershipTypeID = $this->membershipTypeCreate();
}
function tearDown() {
......@@ -62,7 +65,10 @@ class api_v3_ProfileTest extends CiviUnitTestCase {
'civicrm_contact',
'civicrm_phone',
'civicrm_address',
'civicrm_membership',
'civicrm_contribution',
), TRUE);
$this->callAPISuccess('membership_type', 'delete', array('id' => $this->_membershipTypeID));
// ok can't be bothered wring an api to do this & truncating is crazy
CRM_Core_DAO::executeQuery(" DELETE FROM civicrm_uf_group WHERE id IN ($this->_profileID, 26)");
}
......@@ -318,8 +324,9 @@ class api_v3_ProfileTest extends CiviUnitTestCase {
'profile_id' => 'participant_status',
'get_options' => 'all')
);
$this->assertTrue(array_key_exists('participant_status', $result['values']));
$this->assertEquals('Attended', $result['values']['participant_status']['options'][2]);
$this->assertTrue(array_key_exists('participant_status_id', $result['values']));
$this->assertEquals('Attended', $result['values']['participant_status_id']['options'][2]);
$this->assertEquals(array('participant_status'), $result['values']['participant_status_id']['api.aliases']);
}
/**
......@@ -333,6 +340,9 @@ class api_v3_ProfileTest extends CiviUnitTestCase {
'get_options' => 'all')
);
$this->assertTrue(array_key_exists('total_amount', $result['values']));
$this->assertTrue(array_key_exists('financial_type_id', $result['values']));
$this->assertEquals(array('contribution_type_id', 'contribution_type', 'financial_type'), $result['values']['financial_type_id']['api.aliases']);
$this->assertTrue(!array_key_exists('financial_type', $result['values']));
$this->assertEquals(12, $result['values']['receive_date']['type']);
}
......@@ -441,6 +451,37 @@ class api_v3_ProfileTest extends CiviUnitTestCase {
$this->assertEquals('my@mail.com', $profileDetails['values']['email-Primary']);
}
/**
* Ensure caches are being cleared so we don't get into a debugging trap because of cached metadata
* First we delete & create to increment the version & then check for caching probs
*/
function testProfileSubmitCheckCaching() {
$this->callAPISuccess('membership_type', 'delete', array('id' => $this->_membershipTypeID));
$this->_membershipTypeID = $this->membershipTypeCreate();
$membershipTypes = $this->callAPISuccess('membership_type', 'get', array());
$profileFields = $this->callAPISuccess('profile', 'getfields', array('get_options' => 'all', 'action' => 'submit', 'profile_id' => 'membership_batch_entry'));
$getoptions = $this->callAPISuccess('membership', 'getoptions', array('field' => 'membership_type', 'context' => 'validate'));
$this->assertEquals(array_keys($membershipTypes['values']), array_keys($getoptions['values']));
$this->assertEquals(array_keys($membershipTypes['values']), array_keys($profileFields['values']['membership_type']['options']));
}
/**
* Check we can submit membership batch profiles (create mode)
*/
function testProfileSubmitMembershipBatch() {
$this->_contactID = $this->individualCreate();
$this->callAPISuccess('profile', 'submit', array(
'profile_id' => 'membership_batch_entry',
'financial_type_id' => 1,
'membership_type' => $this->_membershipTypeID,
'join_date' => 'now',
'total_amount' => 10,
'contribution_status_id' => 1,
'receive_date' => 'now',
'contact_id' => $this->_contactID,
));
}
/**
* set is deprecated but we need to ensure it still works
*/
......@@ -672,10 +713,10 @@ class api_v3_ProfileTest extends CiviUnitTestCase {
), $params
);
$contactID = $this->individualCreate($contactParams);
$this->_contactID = $this->individualCreate($contactParams);
$this->_createIndividualProfile();
// expected result of above created profile with contact Id $contactId
$profileData[$contactID] = array(
$profileData[$this->_contactID] = array(
'first_name' => 'abc1',
'last_name' => 'xyz1',
'email-primary' => 'abc1.xyz1@yahoo.com',
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment