$fieldName = "{$field['table_name']}.{$field['column_name']}";
- // Autocomplete comes back as a string not an array
- if ($field['data_type'] == 'String' && $field['html_type'] == 'Autocomplete-Select' && $op == '=') {
- $value = explode(',', $value);
- }
-
$isSerialized = CRM_Core_BAO_CustomField::isSerialized($field);
// fix $value here to escape sql injection attacks
}
elseif (count($value) && in_array(key($value), CRM_Core_DAO::acceptedSQLOperators(), TRUE)) {
$op = key($value);
- $qillValue = CRM_Core_BAO_CustomField::getDisplayValue($value[$op], $id, $this->_options);
+ $qillValue = strstr($op, 'NULL') ? NULL : CRM_Core_BAO_CustomField::getDisplayValue($value[$op], $id, $this->_options);
}
else {
- $op = 'IN';
+ $op = strstr($op, 'IN') ? $op : 'IN';
$qillValue = CRM_Core_BAO_CustomField::getDisplayValue($value, $id, $this->_options);
}
$op = key($value);
$value = $value[$op];
}
- $value = implode(',', $value);
+ $value = implode(',', (array) $value);
}
// CRM-14563,CRM-16575 : Special handling of multi-select custom fields
- if ($isSerialized && !empty($value)) {
+ if ($isSerialized && !empty($value) && !strstr($op, 'NULL')) {
if (strstr($op, 'IN')) {
$value = str_replace(",", "[[:cntrl:]]*|[[:cntrl:]]*", $value);
$value = str_replace('(', '[[.left-parenthesis.]]', $value);
break;
case 'Money':
+ $value = CRM_Utils_Array::value($op, (array) $value, $value);
if (is_array($value)) {
- $value = CRM_Utils_Array::value($op, $value, $value);
foreach ($value as $key => $val) {
- $moneyFormat = CRM_Utils_Rule::cleanMoney($value[$key]);
- $value[$key] = $moneyFormat;
+ $value[$key] = CRM_Utils_Rule::cleanMoney($value[$key]);
}
}
else {
case 'Date':
$fromValue = CRM_Utils_Array::value('from', $value);
$toValue = CRM_Utils_Array::value('to', $value);
+ $value = CRM_Utils_Array::value($op, $value, $value);
if (!$fromValue && !$toValue) {
- if (!CRM_Utils_Date::processDate($value) && !in_array($op, array('IS NULL', 'IS NOT NULL', 'IS EMPTY', 'IS NOT EMPTY'))) {
+ if (!is_array($value) && !CRM_Utils_Date::processDate($value) && !in_array($op, array('IS NULL', 'IS NOT NULL', 'IS EMPTY', 'IS NOT EMPTY'))) {
continue;
}
$value = "01-01-{$value}";
}
- $date = CRM_Utils_Date::processDate($value);
+ if (is_array($value)) {
+ $date = $qillValue = array();
+ foreach ($value as $key => $val) {
+ $date[$key] = CRM_Utils_Date::processDate($val);
+ $qillValue[$key] = CRM_Utils_Date::customFormat($date[$key]);
+ }
+ }
+ else {
+ $date = CRM_Utils_Date::processDate($value);
+ $qillValue = CRM_Utils_Date::customFormat($date);
+ }
+
$this->_where[$grouping][] = CRM_Contact_BAO_Query::buildClause($fieldName, $op, $date, 'String');
- $this->_qill[$grouping][] = $field['label'] . " {$qillOp} " . CRM_Utils_Date::customFormat($date);
+ $this->_qill[$grouping][] = $field['label'] . " {$qillOp} " . implode(', ', (array) $qillValue);
}
else {
if (is_numeric($fromValue) && strlen($fromValue) == 4) {
*/
class api_v3_CustomValueTest extends CiviUnitTestCase {
protected $_apiversion = 3;
- protected $individual;
- protected $params;
protected $ids;
+ protected $optionGroup;
public $DBResetRequired = FALSE;
public function setUp() {
parent::setUp();
- $this->individual = $this->individualCreate();
- $this->params = array(
- 'entity_id' => $this->individual,
+
+ $this->_populateOptionAndCustomGroup();
+ }
+
+ public function _populateOptionAndCustomGroup() {
+ $dataValues = array(
+ 'integer' => array(1,2,3),
+ 'number' => array(10.11,20.22,30.33),
+ 'string' => array(substr(sha1(rand()), 0, 4), substr(sha1(rand()), 0, 3), substr(sha1(rand()), 0, 2)),
+ 'country' => array_rand(CRM_Core_PseudoConstant::country(FALSE, FALSE), 3),
+ 'state_province' => array_rand(CRM_Core_PseudoConstant::stateProvince(FALSE, FALSE), 3),
+ 'date' => NULL,
);
- $this->ids['single'] = $this->entityCustomGroupWithSingleFieldCreate('mySingleField', 'Contacts');
- $this->ids['multi'] = $this->CustomGroupMultipleCreateWithFields();
- $this->ids['multi2'] = $this->CustomGroupMultipleCreateWithFields(array('title' => 'group2'));
+
+ foreach ($dataValues as $dataType => $values) {
+ if (!empty($values)) {
+ $this->optionGroup[$dataType] = array('values' => $values);
+ $result = $this->callAPISuccess('OptionGroup', 'create',
+ array(
+ 'name' => "{$dataType}_group",
+ 'api.option_value.create' => array('label' => "$dataType 1", 'value' => $values[0]),
+ 'api.option_value.create.1' => array('label' => "$dataType 2", 'value' => $values[1]),
+ 'api.option_value.create.2' => array('label' => "$dataType 3", 'value' => $values[2]),
+ )
+ );
+ $this->optionGroup[$dataType]['id'] = $result['id'];
+ }
+ $this->ids[$dataType] = $this->entityCustomGroupWithSingleFieldCreate("$dataType Custom Group", 'Contacts');
+ }
+
}
public function tearDown() {
}
public function testCreateCustomValue() {
- $params = array(
- 'custom_' . $this->ids['single']['custom_field_id'] => 'customString',
- ) + $this->params;
+ $customFieldDataType = CRM_Core_BAO_CustomField::dataType();
+ $dataToHtmlTypes = CRM_Core_BAO_CustomField::dataToHtml();
+ $count = 0;
- $result = $this->callAPIAndDocument('custom_value', 'create', $params, __FUNCTION__, __FILE__);
- $this->assertEquals(1, $result['count'], 'In line ' . __LINE__);
- $result = $this->callAPISuccess('custom_value', 'get', $params);
- }
+ foreach ($customFieldDataType as $dataType => $label) {
+ $validSQLOperator = array('=', "!=", 'IN', 'NOT IN', 'IS NOT NULL', 'IS NULL');
+ switch ($dataType) {
+ case 'Date':
+ case 'StateProvince';
+ case 'String':
+ case 'Link':
+ case 'Int':
+ case 'Float':
+ case 'Money':
+
+ if (in_array($dataType, array('String', 'Link'))) {
+ $validSQLOperator += array('LIKE', "NOT LIKE");
+ $type = 'string';
+ }
+ else {
+ if ($dataType == 'Country') {
+ $type == 'country';
+ }
+ elseif ($dataType == 'StateProvince') {
+ $type = 'state_province';
+ }
+ else {
+ $type = $dataType == 'Int' ? 'integer' : ($dataType == 'Date' ? 'date' : 'number');
+ }
+ $validSQLOperator += array('<=', '>=', '>', '<');
+ }
- public function testGetMultipleCustomValues() {
+ foreach ($dataToHtmlTypes[$count] as $html) {
+ $params = array(
+ 'custom_group_id' => $this->ids[$type]['custom_group_id'],
+ 'label' => "$dataType - $html",
+ 'data_type' => $dataType,
+ 'html_type' => $html,
+ 'default_value' => NULL,
+ );
+ if (!in_array($html, array('Text', 'TextArea', 'Link', 'Select Date'))) {
+ $params += array('option_group_id' => $this->optionGroup[$type]['id']);
+ }
+ $customField = $this->customFieldCreate($params);
+ $this->_testCustomValue($customField['values'][$customField['id']], $validSQLOperator, $type);
+ }
+ $count++;
+ break;
- $description = "This demonstrates the use of CustomValue get to fetch single and multi-valued custom data.";
+ case 'ContactReference':
+ $validSQLOperator += array('<=', '>=', '>', '<');
+ $count++;
+ break;
+ default:
+ $count++;
+ break;
+ }
+ }
+ }
+
+ public function _testCustomValue($customField, $sqlOps, $type) {
+ $isSerialized = CRM_Core_BAO_CustomField::isSerialized($customField);
+ $customId = $customField['id'];
$params = array(
- 'first_name' => 'abc3',
- 'last_name' => 'xyz3',
'contact_type' => 'Individual',
- 'email' => 'man3@yahoo.com',
- 'custom_' . $this->ids['single']['custom_field_id'] => "value 1",
- 'custom_' . $this->ids['multi']['custom_field_id'][0] => "value 2",
- 'custom_' . $this->ids['multi']['custom_field_id'][1] => "warm beer",
- 'custom_' . $this->ids['multi']['custom_field_id'][2] => "fl* w*",
- 'custom_' . $this->ids['multi2']['custom_field_id'][2] => "vegemite",
+ 'email' => substr(sha1(rand()), 0, 7) . 'man1@yahoo.com',
);
-
$result = $this->callAPISuccess('Contact', 'create', $params);
- $contact_id = $result['id'];
- $firstCustomField = $this->ids['multi']['custom_field_id'][0];
- $secondCustomField = $this->ids['multi2']['custom_field_id'][0];
- $thirdCustomField = $this->ids['multi2']['custom_field_id'][1];
- $createParams = array(
- 'contact_type' => 'Individual',
- 'id' => $contact_id,
- 'custom_' . $firstCustomField => "value 3",
- 'custom_' . $secondCustomField => "coffee",
- 'custom_' . $thirdCustomField => "value 4",
- );
- $result = $this->callAPISuccess('Contact', 'create', $createParams);
+ $contactId = $result['id'];
- $params = array(
- 'id' => $result['id'],
- 'entity_id' => $result['id'],
- );
+ $count = rand(1,2);
+ $seperator = CRM_Core_DAO::VALUE_SEPARATOR;
+ if ($isSerialized) {
+ $selectedValue = $this->optionGroup[$type]['values'];
+ $notselectedValue = $selectedValue[$count];
+ unset($selectedValue[$count]);
+ }
+ elseif ($customField['html_type'] == 'Link') {
+ $selectedValue = "http://" . substr(sha1(rand()), 0, 7) . ".com";
+ $notselectedValue = "http://" . substr(sha1(rand()), 0, 7) . ".com";
+ }
+ elseif ($type == 'date') {
+ $selectedValue = date('Ymd');
+ $notselectedValue = date('Ymd', strtotime('yesterday'));
+ }
+ else {
+ $selectedValue = $this->optionGroup[$type]['values'][0];
+ $notselectedValue = $this->optionGroup[$type]['values'][$count];
+ }
- $result = $this->callAPIAndDocument('CustomValue', 'Get', $params, __FUNCTION__, __FILE__, $description);
- $params['format.field_names'] = 1;
- $resultformatted = $this->callAPIAndDocument('CustomValue', 'Get', $params, __FUNCTION__, __FILE__, "utilises field names", 'FormatFieldName');
- // delete the contact
- $this->callAPISuccess('contact', 'delete', array('id' => $contact_id));
- $this->assertEquals('coffee', $result['values'][$secondCustomField]['2']);
- $this->assertEquals('coffee', $result['values'][$secondCustomField]['latest']);
- $this->assertEquals($secondCustomField, $result['values'][$secondCustomField]['id']);
- $this->assertEquals('defaultValue', $result['values'][$secondCustomField]['1']);
- $this->assertEquals($contact_id, $result['values'][$secondCustomField]['entity_id']);
- $this->assertEquals('value 1', $result['values'][$this->ids['single']['custom_field_id']]['0']);
- $this->assertEquals('value 1', $result['values'][$this->ids['single']['custom_field_id']]['latest']);
- $this->assertEquals('value 1', $resultformatted['values']['mySingleField']['latest']);
- $this->assertEquals('', $result['values'][$thirdCustomField]['1']);
- $this->assertEquals('value 4', $result['values'][$thirdCustomField]['2']);
- }
+ $params = array('entity_id' => $contactId, 'custom_' . $customId => $selectedValue);
+ $this->callAPISuccess('CustomValue', 'create', $params);
- public function testMultipleCustomValues() {
- $params = array(
- 'first_name' => 'abc3',
- 'last_name' => 'xyz3',
- 'contact_type' => 'Individual',
- 'email' => 'man3@yahoo.com',
- 'custom_' . $this->ids['single']['custom_field_id'] => "value 1",
- 'custom_' . $this->ids['multi']['custom_field_id'][0] . '-1' => "multi value 1",
- 'custom_' . $this->ids['multi']['custom_field_id'][0] . '-2' => "multi value 2",
- 'custom_' . $this->ids['multi']['custom_field_id'][1] => "second multi value 1",
- );
+ foreach ($sqlOps as $op) {
+ $description = "Find Contact whose $customField[label] $op $notselectedValue";
+ switch ($op) {
+ case '!=':
+ $result = $this->callAPIAndDocument('Contact', 'Get', array('custom_' . $customId => array($op => $notselectedValue)), __FUNCTION__, __FILE__, $description);
+ $this->assertEquals($contactId, $result['id']);
+ break;
- $result = $this->callAPISuccess('Contact', 'create', $params);
- $contact_id = $result['id'];
- $firstCustomField = $this->ids['multi']['custom_field_id'][1];
- $secondCustomField = $this->ids['single']['custom_field_id'];
- $thirdCustomField = $this->ids['multi']['custom_field_id'][0];
+ case '>':
+ case '<':
+ case '>=':
+ case '<=':
+ // To be precise in for these operator we can't just rely on one contact,
+ // hence creating multiple contact with custom value less/more then $selectedValue respectively
+ $result = $this->callAPISuccess('Contact', 'create', array('contact_type' => 'Individual', 'email' => substr(sha1(rand()), 0, 7) . 'man2@yahoo.com'));
+ $contactId2 = $result['id'];
+ $lesserSelectedValue = $type == 'date' ? date('Ymd', strtotime('- 1 day')) : $selectedValue - 1;
+ $this->callAPISuccess('CustomValue', 'create', array('entity_id' => $contactId2, 'custom_' . $customId => $lesserSelectedValue));
- $createParams = array(
- 'contact_type' => 'Individual',
- 'id' => $contact_id,
- 'custom_' . $firstCustomField . '-1' => "second multi value 2",
- 'custom_' . $firstCustomField . '-2' => "second multi value 3",
- );
- $result = $this->callAPISuccess('Contact', 'create', $createParams);
+ if ($op == '>') {
+ $result = $this->callAPIAndDocument('Contact', 'Get', array('custom_' . $customId => array($op => $lesserSelectedValue)), __FUNCTION__, __FILE__, $description);
+ $this->assertEquals($contactId, $result['id']);
+ }
+ elseif ($op == '<') {
+ $result = $this->callAPIAndDocument('Contact', 'Get', array('custom_' . $customId => array($op => $selectedValue)), __FUNCTION__, __FILE__, $description);
+ $this->assertEquals($contactId2, $result['id']);
+ }
+ else {
+ $result = $this->callAPISuccess('Contact', 'create', array('contact_type' => 'Individual', 'email' => substr(sha1(rand()), 0, 7) . 'man3@yahoo.com'));
+ $contactId3 = $result['id'];
+ $greaterSelectedValue = $type == 'date' ? date('Ymd', strtotime('+ 1 day')) : $selectedValue + 1;
+ $this->callAPISuccess('CustomValue', 'create', array('entity_id' => $contactId3, 'custom_' . $customId => $greaterSelectedValue));
- $params = array(
- 'id' => $result['id'],
- 'entity_id' => $result['id'],
- );
+ $result = $this->callAPIAndDocument('Contact', 'Get', array('custom_' . $customId => array($op => $selectedValue)), __FUNCTION__, __FILE__, $description);
+
+ $this->assertEquals($contactId, $result['values'][$contactId]['id']);
+ if ($op == '>=') {
+ $this->assertEquals($contactId3, $result['values'][$contactId3]['id']);
+ }
+ else {
+ $this->assertEquals($contactId2, $result['values'][$contactId2]['id']);
+ }
+ $this->callAPISuccess('contact', 'delete', array('id' => $contactId3));
+ }
+
+ $this->callAPISuccess('contact', 'delete', array('id' => $contactId2));
+ break;
+
+ case 'IN':
+ $result = $this->callAPIAndDocument('Contact', 'Get', array('custom_' . $customId => array($op => (array) $selectedValue)), __FUNCTION__, __FILE__, $description);
+ $this->assertEquals($contactId, $result['id']);
+ break;
+
+ case 'NOT IN':
+ $result = $this->callAPIAndDocument('Contact', 'Get', array('custom_' . $customId => array($op => (array) $notselectedValue)), __FUNCTION__, __FILE__, $description);
+ $this->assertEquals($contactId, $result['id']);
+ break;
+
+ case 'LIKE':
+ $result = $this->callAPIAndDocument('Contact', 'Get',
+ array('custom_' . $customId =>
+ array($op => (is_array($selectedValue) ? "%" . $selectedValue[0] . "%" : $selectedValue)
+ )),
+ __FUNCTION__, __FILE__, $description
+ );
+ $this->assertEquals($contactId, $result['id']);
+ break;
+
+ case 'NOT LIKE':
+ $result = $this->callAPIAndDocument('Contact', 'Get', array('custom_' . $customId => array($op => $notselectedValue)), __FUNCTION__, __FILE__, $description);
+ $this->assertEquals($contactId, $result['id']);
+ break;
- $result = $this->callAPISuccess('CustomValue', 'Get', $params);
- // delete the contact
- $this->callAPISuccess('contact', 'delete', array('id' => $contact_id));
+ case 'IS NULL':
+ $result = $this->callAPIAndDocument('Contact', 'Get', array('custom_' . $customId => array($op => 1)), __FUNCTION__, __FILE__, $description);
+ $this->assertEquals(FALSE, array_key_exists($contactId, $result['values']));
+ break;
- $this->assertEquals($contact_id, $result['values'][$secondCustomField]['entity_id']);
- $this->assertEquals('value 1', $result['values'][$secondCustomField]['latest']);
- $this->assertEquals('value 1', $result['values'][$secondCustomField][0]);
+ case 'IS NOT NULL':
+ $result = $this->callAPIAndDocument('Contact', 'Get', array('custom_' . $customId => array($op => 1)),__FUNCTION__, __FILE__, $description);
+ $this->assertEquals($contactId, $result['id']);
+ break;
- $this->assertEquals($contact_id, $result['values'][$thirdCustomField]['entity_id']);
- $this->assertEquals('multi value 1', $result['values'][$thirdCustomField][1]);
- $this->assertEquals('multi value 2', $result['values'][$thirdCustomField][2]);
+ default:
+ $result = $this->callAPIAndDocument('Contact', 'Get', array('custom_' . $customId => (is_array($selectedValue) ? implode($seperator, $selectedValue) : $selectedValue)), __FUNCTION__, __FILE__, $description);
+ $this->assertEquals($contactId, $result['id']);
+ break;
+ }
+ }
- $this->assertEquals($contact_id, $result['values'][$firstCustomField]['entity_id']);
- $this->assertEquals('second multi value 1', $result['values'][$firstCustomField][1]);
- $this->assertEquals('', $result['values'][$firstCustomField][2]);
- $this->assertEquals('second multi value 2', $result['values'][$firstCustomField][3]);
- $this->assertEquals('second multi value 3', $result['values'][$firstCustomField][4]);
- $this->assertEquals('second multi value 3', $result['values'][$firstCustomField]['latest']);
+ $this->callAPISuccess('Contact', 'delete', array('id' => $contactId));
+ //$this->callAPISuccess('CustomField', 'delete', array('id' => $customId));
}
}