return $options;
}
+ /**
+ * When changing the value of an option this is called to update all corresponding custom data
+ *
+ * @param int $optionId
+ * @param string $newValue
+ */
+ public static function updateValue($optionId, $newValue) {
+ $optionValue = new CRM_Core_DAO_OptionValue();
+ $optionValue->id = $optionId;
+ $optionValue->find(TRUE);
+ $oldValue = $optionValue->value;
+ if ($oldValue == $newValue) {
+ return;
+ }
+
+ $customField = new CRM_Core_DAO_CustomField();
+ $customField->option_group_id = $optionValue->option_group_id;
+ $customField->find();
+ while ($customField->fetch()) {
+ $customGroup = new CRM_Core_DAO_CustomGroup();
+ $customGroup->id = $customField->custom_group_id;
+ $customGroup->find(TRUE);
+ if (CRM_Core_BAO_CustomField::isSerialized($customField)) {
+ $params = array(
+ 1 => array(CRM_Utils_Array::implodePadded($oldValue), 'String'),
+ 2 => array(CRM_Utils_Array::implodePadded($newValue), 'String'),
+ 3 => array('%' . CRM_Utils_Array::implodePadded($oldValue) . '%', 'String'),
+ );
+ }
+ else {
+ $params = array(
+ 1 => array($oldValue, 'String'),
+ 2 => array($newValue, 'String'),
+ 3 => array($oldValue, 'String'),
+ );
+ }
+ $sql = "UPDATE `{$customGroup->table_name}` SET `{$customField->column_name}` = REPLACE(`{$customField->column_name}`, %1, %2) WHERE `{$customField->column_name}` LIKE %3";
+ $customGroup->free();
+ CRM_Core_DAO::executeQuery($sql, $params);
+ }
+ $customField->free();
+ }
+
}
// Array created for passing options in params.
if (isset($params['option_values']) && is_array($params['option_values'])) {
+ $weight = 0;
foreach ($params['option_values'] as $key => $value) {
+ // Translate simple key/value pairs into full-blown option values
+ if (!is_array($value)) {
+ $value = array(
+ 'label' => $value,
+ 'value' => $key,
+ 'is_active' => 1,
+ 'weight' => $weight,
+ );
+ $key = $weight++;
+ }
$params['option_label'][$key] = $value['label'];
$params['option_value'][$key] = $value['value'];
$params['option_status'][$key] = $value['is_active'];
$params['label']['api.required'] = 1;
$params['custom_group_id']['api.required'] = 1;
$params['is_active']['api.default'] = 1;
+ $params['option_values'] = array(
+ 'title' => 'Option Values',
+ 'description' => "Pass an array of options (value => label) to create this field's option values",
+ );
+ // TODO: Why expose this to the api at all?
$params['option_type'] = array(
'title' => 'Option Type',
'description' => 'This (boolean) field tells the BAO to create an option group for the field if the field type is appropriate',
$this->assertEquals('second multi value 3', $result['values'][$firstCustomField]['latest']);
}
+ /**
+ * Ensure custom data is updated when option values are modified
+ *
+ * @link https://issues.civicrm.org/jira/browse/CRM-11856
+ *
+ * @throws \CiviCRM_API3_Exception
+ */
+ public function testAlterOptionValue() {
+ $selectField = $this->customFieldCreate(array(
+ 'custom_group_id' => $this->ids['single']['custom_group_id'],
+ 'label' => 'Custom Select',
+ 'html_type' => 'Select',
+ 'option_values' => array(
+ 'one' => 'Option1',
+ 'two' => 'Option2',
+ 'notone' => 'OptionNotOne',
+ ),
+ ));
+ $selectField = civicrm_api3('customField', 'getsingle', array('id' => $selectField['id']));
+ $radioField = $this->customFieldCreate(array(
+ 'custom_group_id' => $this->ids['single']['custom_group_id'],
+ 'label' => 'Custom Radio',
+ 'html_type' => 'Radio',
+ 'option_group_id' => $selectField['option_group_id'],
+ ));
+ $multiSelectField = $this->customFieldCreate(array(
+ 'custom_group_id' => $this->ids['single']['custom_group_id'],
+ 'label' => 'Custom Multi-Select',
+ 'html_type' => 'Multi-Select',
+ 'option_group_id' => $selectField['option_group_id'],
+ ));
+ $selectName = 'custom_' . $selectField['id'];
+ $radioName = 'custom_' . $radioField['id'];
+ $multiSelectName = 'custom_' . $multiSelectField['id'];
+ $controlFieldName = 'custom_' . $this->ids['single']['custom_field_id'];
+
+ $params = array(
+ 'first_name' => 'abc4',
+ 'last_name' => 'xyz4',
+ 'contact_type' => 'Individual',
+ 'email' => 'man4@yahoo.com',
+ $selectName => 'one',
+ $multiSelectName => array('one', 'two', 'notone'),
+ $radioName => 'notone',
+ // The control group in a science experiment should be unaffected
+ $controlFieldName => 'one',
+ );
+
+ $contact = $this->callAPISuccess('Contact', 'create', $params);
+
+ $result = $this->callAPISuccess('Contact', 'getsingle', array(
+ 'id' => $contact['id'],
+ 'return' => array($selectName, $multiSelectName),
+ ));
+ $this->assertEquals('one', $result[$selectName]);
+ $this->assertEquals(array('one', 'two', 'notone'), $result[$multiSelectName]);
+
+ $this->callAPISuccess('OptionValue', 'create', array(
+ 'value' => 'one-modified',
+ 'option_group_id' => $selectField['option_group_id'],
+ 'name' => 'Option1',
+ 'options' => array(
+ 'match-mandatory' => array('option_group_id', 'name'),
+ ),
+ ));
+
+ $result = $this->callAPISuccess('Contact', 'getsingle', array(
+ 'id' => $contact['id'],
+ 'return' => array($selectName, $multiSelectName, $controlFieldName, $radioName),
+ ));
+ // Ensure the relevant fields have been updated
+ $this->assertEquals('one-modified', $result[$selectName]);
+ $this->assertEquals(array('one-modified', 'two', 'notone'), $result[$multiSelectName]);
+ // This field should not have changed because we didn't alter this option
+ $this->assertEquals('notone', $result[$radioName]);
+ // This should not have changed because this field doesn't use the affected option group
+ $this->assertEquals('one', $result[$controlFieldName]);
+ }
+
}