From 2930d67a5c56ea97900118838c955258d822acd6 Mon Sep 17 00:00:00 2001 From: atif-shaikh Date: Mon, 23 Feb 2015 19:37:45 +0530 Subject: [PATCH] CRM-15792 fix along with api test ---------------------------------------- * CRM-15792: Loss of data when creating / updating custom datetime fields through the API https://issues.civicrm.org/jira/browse/CRM-15792 --- CRM/Core/BAO/CustomField.php | 3 +- api/v3/utils.php | 33 ++++++++++--- tests/phpunit/api/v3/ContactTest.php | 71 ++++++++++++++++++++++++++++ 3 files changed, 100 insertions(+), 7 deletions(-) diff --git a/CRM/Core/BAO/CustomField.php b/CRM/Core/BAO/CustomField.php index bf96c1cb1a..17b461639c 100644 --- a/CRM/Core/BAO/CustomField.php +++ b/CRM/Core/BAO/CustomField.php @@ -278,7 +278,8 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField { $customField->is_searchable = CRM_Utils_Array::value('is_searchable', $params, FALSE); $customField->in_selector = CRM_Utils_Array::value('in_selector', $params, FALSE); $customField->is_search_range = CRM_Utils_Array::value('is_search_range', $params, FALSE); - $customField->is_active = CRM_Utils_Array::value('is_active', $params, FALSE); + //CRM-15792 - Custom field gets disabled if is_active not set + $customField->is_active = CRM_Utils_Array::value('is_active', $params, TRUE); $customField->is_view = CRM_Utils_Array::value('is_view', $params, FALSE); $customField->save(); diff --git a/api/v3/utils.php b/api/v3/utils.php index 6333488201..863c85503c 100644 --- a/api/v3/utils.php +++ b/api/v3/utils.php @@ -1457,7 +1457,20 @@ function _civicrm_api3_custom_data_get(&$returnArray, $entity, $entity_id, $grou * @throws Exception */ function _civicrm_api3_validate_fields($entity, $action, &$params, $fields, $errorMode = FALSE) { + //CRM-15792 handle datetime for custom fields below code handles chain api call + $chainApikeys = array_flip(preg_grep("/^api./", array_keys($params))); + if (!empty($chainApikeys) && is_array($chainApikeys)) { + foreach ($chainApikeys as $key => $value) { + if (is_array($params[$key])) { + $chainApiParams = array_intersect_key($fields, $params[$key]); + $customFields = array_fill_keys(array_keys($params[$key]), $key); + } + } + } $fields = array_intersect_key($fields, $params); + if (!empty($chainApiParams)) { + $fields = array_merge($fields, $chainApiParams); + } foreach ($fields as $fieldName => $fieldInfo) { switch (CRM_Utils_Array::value('type', $fieldInfo)) { case CRM_Utils_Type::T_INT: @@ -1465,11 +1478,17 @@ function _civicrm_api3_validate_fields($entity, $action, &$params, $fields, $err _civicrm_api3_validate_integer($params, $fieldName, $fieldInfo, $entity); break; - case 4: - case 12: + case CRM_Utils_Type::T_DATE: + case CRM_Utils_Type::T_DATE + CRM_Utils_Type::T_TIME: case CRM_Utils_Type::T_TIMESTAMP: //field is of type date or datetime - _civicrm_api3_validate_date($params, $fieldName, $fieldInfo); + if (!empty($customFields) && array_key_exists($fieldName, $customFields)) { + $dateParams = &$params[$customFields[$fieldName]]; + } + else { + $dateParams = &$params; + } + _civicrm_api3_validate_date($dateParams, $fieldName, $fieldInfo); break; case 32: @@ -1815,7 +1834,7 @@ function _civicrm_api_get_custom_fields($entity, &$params) { // Regular fields have a 'name' property $value['name'] = 'custom_' . $key; $value['title'] = $value['label']; - $value['type'] = _getStandardTypeFromCustomDataType($value['data_type'], $value); + $value['type'] = _getStandardTypeFromCustomDataType($value); $ret['custom_' . $key] = $value; } return $ret; @@ -1828,8 +1847,10 @@ function _civicrm_api_get_custom_fields($entity, &$params) { * * @return int */ -function _getStandardTypeFromCustomDataType($dataType, $value) { - if ($dataType == 'Date' && isset($value['time_format']) && $value['time_format'] > 0) { +function _getStandardTypeFromCustomDataType($value) { + $dataType = $value['data_type']; + //CRM-15792 - If date custom field contains timeformat change type to DateTime + if ($value['data_type'] == 'Date' && isset($value['time_format']) && $value['time_format'] > 0) { $dataType = 'DateTime'; } $mapping = array( diff --git a/tests/phpunit/api/v3/ContactTest.php b/tests/phpunit/api/v3/ContactTest.php index f9d97e9394..d0f4addb44 100644 --- a/tests/phpunit/api/v3/ContactTest.php +++ b/tests/phpunit/api/v3/ContactTest.php @@ -357,6 +357,77 @@ class api_v3_ContactTest extends CiviUnitTestCase { $this->customGroupDelete($ids['custom_group_id']); } + /** + * CRM-15792 - create/update datetime field for contact. + */ + public function testCreateContactCustomFldDateTime() { + $customGroup = $this->customGroupCreate(array('extends' => 'Individual', 'title' => 'datetime_test_group')); + $dateTime = CRM_Utils_Date::currentDBDate(); + //check date custom field is saved along with time when time_format is set + $params = array( + 'first_name' => 'abc3', + 'last_name' => 'xyz3', + 'contact_type' => 'Individual', + 'email' => 'man3@yahoo.com', + 'api.CustomField.create' => array( + 'custom_group_id' => $customGroup['id'], + 'name' => 'test_datetime', + 'label' => 'Demo Date', + 'html_type' => 'Select Date', + 'data_type' => 'Date', + 'time_format' => 2, + 'weight' => 4, + 'is_required' => 1, + 'is_searchable' => 0, + 'is_active' => 1, + ), + ); + + + $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__, __FILE__); + $customFldId = $result['values'][$result['id']]['api.CustomField.create']['id']; + $this->assertNotNull($result['id'], 'in line ' . __LINE__); + $this->assertNotNull($customFldId, 'in line ' . __LINE__); + + $params = array( + 'id' => $result['id'], + "custom_{$customFldId}" => $dateTime, + 'api.CustomValue.get' => 1, + ); + + $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__, __FILE__); + $this->assertNotNull($result['id'], 'in line ' . __LINE__); + $customFldDate = date("YmdHis", strtotime($result['values'][$result['id']]['api.CustomValue.get']['values'][0]['latest'])); + $this->assertNotNull($customFldDate, 'in line ' . __LINE__); + $this->assertEquals($dateTime, $customFldDate); + $customValueId = $result['values'][$result['id']]['api.CustomValue.get']['values'][0]['id']; + $dateTime = date('Ymd'); + //date custom field should not contain time part when time_format is null + $params = array( + 'id' => $result['id'], + 'api.CustomField.create' => array( + 'id' => $customValueId, + 'html_type' => 'Select Date', + 'data_type' => 'Date', + 'time_format' => '', + ), + 'api.CustomValue.create' => array( + 'id' => $customValueId, + 'entity_id' => $result['id'], + "custom_{$customFldId}" => $dateTime, + ), + 'api.CustomValue.get' => 1, + ); + $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__, __FILE__); + $this->assertNotNull($result['id'], 'in line ' . __LINE__); + $customFldDate = date("Ymd", strtotime($result['values'][$result['id']]['api.CustomValue.get']['values'][0]['latest'])); + $customFldTime = date("His", strtotime($result['values'][$result['id']]['api.CustomValue.get']['values'][0]['latest'])); + $this->assertNotNull($customFldDate, 'in line ' . __LINE__); + $this->assertEquals($dateTime, $customFldDate); + $this->assertEquals(000000, $customFldTime); + $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__, __FILE__); + } + /** * Test creating a current employer through API. -- 2.25.1