Skip to content

Commit

Permalink
Fix api profile.submit to work with tag & note fields
Browse files Browse the repository at this point in the history
  • Loading branch information
colemanw committed Sep 15, 2018
1 parent c344b98 commit fb4b656
Show file tree
Hide file tree
Showing 3 changed files with 143 additions and 22 deletions.
44 changes: 42 additions & 2 deletions api/v3/EntityTag.php
Original file line number Diff line number Diff line change
Expand Up @@ -101,15 +101,20 @@ function _civicrm_api3_entity_tag_delete_spec(&$params) {
*/
function _civicrm_api3_entity_tag_common($params, $op = 'add') {

$entityIDs = array();
$entityIDs = $tagIDs = array();
$entityTable = 'civicrm_contact';
if (is_array($params)) {
foreach ($params as $n => $v) {
if ((substr($n, 0, 10) == 'contact_id') || (substr($n, 0, 9) == 'entity_id')) {
$entityIDs[] = $v;
}
elseif (substr($n, 0, 6) == 'tag_id') {
$tagIDs[] = $v;
if (is_array($v)) {
$tagIDs = array_merge($tagIDs, $v);
}
else {
$tagIDs[] = $v;
}
}
elseif (substr($n, 0, 12) == 'entity_table') {
$entityTable = $v;
Expand Down Expand Up @@ -156,3 +161,38 @@ function _civicrm_api3_entity_tag_common($params, $op = 'add') {
}
return $values;
}

/**
* Replace tags for an entity
*/
function civicrm_api3_entity_tag_replace($params) {
$transaction = new CRM_Core_Transaction();
try {
civicrm_api3_verify_one_mandatory($params, NULL, ['values', 'tag_id']);

$baseParams = _civicrm_api3_generic_replace_base_params($params);
unset($baseParams['tag_id']);

// Lookup pre-existing records
$preexisting = civicrm_api3('entity_tag', 'get', $baseParams);
$preexisting = array_column($preexisting['values'], 'tag_id');
$toAdd = isset($params['tag_id']) ? $params['tag_id'] : array_column($params['values'], 'tag_id');
$toRemove = array_diff($preexisting, $toAdd);

$result = [];
if ($toAdd) {
$result = _civicrm_api3_entity_tag_common(array_merge($baseParams, ['tag_id' => $toAdd]), 'add');
}
if ($toRemove) {
$result += _civicrm_api3_entity_tag_common(array_merge($baseParams, ['tag_id' => $toRemove]), 'remove');
}
// Not really errors
unset($result['is_error'], $result['error_message']);

return civicrm_api3_create_success($result, $params, 'EntityTag', 'replace');
}
catch(Exception $e) {
$transaction->rollback();
return civicrm_api3_create_error($e->getMessage());
}
}
43 changes: 34 additions & 9 deletions api/v3/Profile.php
Original file line number Diff line number Diff line change
Expand Up @@ -202,14 +202,35 @@ function civicrm_api3_profile_submit($params) {

$entity = strtolower(CRM_Utils_Array::value('entity', $field));
if ($entity && !in_array($entity, array_merge($contactEntities, $locationEntities))) {
$contactParams['api.' . $entity . '.create'][$fieldName] = $value;
//@todo we are not currently declaring this option
if (isset($params['batch_id']) && strtolower($entity) == 'contribution') {
$contactParams['api.' . $entity . '.create']['batch_id'] = $params['batch_id'];
}
if (isset($params[$entity . '_id'])) {
//todo possibly declare $entity_id in getfields ?
$contactParams['api.' . $entity . '.create']['id'] = $params[$entity . '_id'];
switch ($entity) {
case 'note':
if ($value) {
$contactParams['api.Note.create'] = [
'note' => $value,
'contact_id' => 'user_contact_id',
];
}
break;

case 'entity_tag':
if (!is_array($value)) {
$value = $value ? explode(',', $value) : [];
}
$contactParams['api.entity_tag.replace'] = [
'tag_id' => $value,
];
break;

default:
$contactParams['api.' . $entity . '.create'][$fieldName] = $value;
//@todo we are not currently declaring this option
if (isset($params['batch_id']) && strtolower($entity) == 'contribution') {
$contactParams['api.' . $entity . '.create']['batch_id'] = $params['batch_id'];
}
if (isset($params[$entity . '_id'])) {
//todo possibly declare $entity_id in getfields ?
$contactParams['api.' . $entity . '.create']['id'] = $params[$entity . '_id'];
}
}
}
else {
Expand All @@ -230,7 +251,7 @@ function civicrm_api3_profile_submit($params) {
);
}

$contactParams['contact_id'] = CRM_Utils_Array::value('contact_id', $params);
$contactParams['contact_id'] = empty($params['contact_id']) ? CRM_Utils_Array::value('id', $params) : $params['contact_id'];
$contactParams['profile_id'] = $profileID;
$contactParams['skip_custom'] = 1;

Expand Down Expand Up @@ -291,6 +312,9 @@ function _civicrm_api3_profile_submit_spec(&$params, $apirequest) {
}
$params['profile_id']['api.required'] = TRUE;
$params['profile_id']['title'] = 'Profile ID';
// Profile forms submit tag values as a string; hack to get past api wrapper validation
unset($params['tag_id']['pseudoconstant']);
$params['tag_id']['type'] = CRM_Utils_Type::T_STRING;
}

/**
Expand Down Expand Up @@ -663,6 +687,7 @@ function _civicrm_api3_map_profile_fields_to_entity(&$field) {
'soft_credit_type' => 'contribution_soft',
'group' => 'group_contact',
'tag' => 'entity_tag',
'note' => 'note',
);
if (array_key_exists($fieldName, $hardCodedEntityMappings)) {
$entity = $hardCodedEntityMappings[$fieldName];
Expand Down
78 changes: 67 additions & 11 deletions tests/phpunit/api/v3/ProfileTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ public function testProfileGetInvalidProfileId() {
*/
public function testProfileGet() {
$profileFieldValues = $this->_createIndividualContact();
$expected = current($profileFieldValues);
$expected = reset($profileFieldValues);
$contactId = key($profileFieldValues);
$params = array(
'profile_id' => $this->_profileID,
Expand All @@ -99,7 +99,7 @@ public function testProfileGet() {

public function testProfileGetMultiple() {
$profileFieldValues = $this->_createIndividualContact();
$expected = current($profileFieldValues);
$expected = reset($profileFieldValues);
$contactId = key($profileFieldValues);
$params = array(
'profile_id' => array($this->_profileID, 1, 'Billing'),
Expand Down Expand Up @@ -382,9 +382,8 @@ public function testProfileSubmitInvalidProfileId() {
* Check with missing required field in profile.
*/
public function testProfileSubmitCheckProfileRequired() {
$pofileFieldValues = $this->_createIndividualContact();
current($pofileFieldValues);
$contactId = key($pofileFieldValues);
$profileFieldValues = $this->_createIndividualContact();
$contactId = key($profileFieldValues);
$updateParams = array(
'first_name' => 'abc2',
'last_name' => 'xyz2',
Expand All @@ -406,9 +405,8 @@ public function testProfileSubmitCheckProfileRequired() {
* Check with success.
*/
public function testProfileSubmit() {
$pofileFieldValues = $this->_createIndividualContact();
current($pofileFieldValues);
$contactId = key($pofileFieldValues);
$profileFieldValues = $this->_createIndividualContact();
$contactId = key($profileFieldValues);

$updateParams = array(
'first_name' => 'abc2',
Expand Down Expand Up @@ -505,9 +503,8 @@ public function testProfileSubmitMembershipBatch() {
* Set is deprecated but we need to ensure it still works.
*/
public function testLegacySet() {
$pofileFieldValues = $this->_createIndividualContact();
current($pofileFieldValues);
$contactId = key($pofileFieldValues);
$profileFieldValues = $this->_createIndividualContact();
$contactId = key($profileFieldValues);

$updateParams = array(
'first_name' => 'abc2',
Expand Down Expand Up @@ -706,6 +703,65 @@ public function testProfileApply() {
}
}

/**
* Check success with tags.
*/
public function testSubmitWithTags() {
$profileFieldValues = $this->_createIndividualContact();
$params = reset($profileFieldValues);
$contactId = key($profileFieldValues);
$params['profile_id'] = $this->_profileID;
$params['contact_id'] = $contactId;

$this->callAPISuccess('ufField', 'create', array(
'uf_group_id' => $this->_profileID,
'field_name' => 'tag',
'visibility' => 'Public Pages and Listings',
'field_type' => 'Contact',
'label' => 'Tags',
));

$tag_1 = $this->callAPISuccess('tag', 'create', ['name' => 'abc'])['id'];
$tag_2 = $this->callAPISuccess('tag', 'create', ['name' => 'def'])['id'];

$params['tag'] = "$tag_1,$tag_2";
$result = $this->callAPISuccess('profile', 'submit', $params);

$tags = $this->callAPISuccess('entityTag', 'get', ['entity_id' => $contactId]);
$this->assertEquals(2, $tags['count']);

$params['tag'] = [$tag_1];
$result = $this->callAPISuccess('profile', 'submit', $params);

$tags = $this->callAPISuccess('entityTag', 'get', ['entity_id' => $contactId]);
$this->assertEquals(1, $tags['count']);
}

/**
* Check success with a note.
*/
public function testSubmitWithNote() {
$profileFieldValues = $this->_createIndividualContact();
$params = reset($profileFieldValues);
$contactId = key($profileFieldValues);
$params['profile_id'] = $this->_profileID;
$params['contact_id'] = $contactId;

$this->callAPISuccess('ufField', 'create', array(
'uf_group_id' => $this->_profileID,
'field_name' => 'note',
'visibility' => 'Public Pages and Listings',
'field_type' => 'Contact',
'label' => 'Note',
));

$params['note'] = "Hello 123";
$this->callAPISuccess('profile', 'submit', $params);

$note = $this->callAPISuccessGetSingle('note', ['entity_id' => $contactId]);
$this->assertEquals("Hello 123", $note['note']);
}

/**
* Helper function to create an Individual with address/email/phone info. Import UF Group and UF Fields
* @param array $params
Expand Down

0 comments on commit fb4b656

Please sign in to comment.