if (!array_key_exists($cfID, $this->_cfIDs)) {
$this->_cfIDs[$cfID] = array();
}
+ // Set wildcard value based on "and/or" selection
+ foreach ($this->_params as $key => $param) {
+ if ($param[0] == $value[0] . '_operator') {
+ $value[4] = $param[2] == 'or';
+ break;
+ }
+ }
$this->_cfIDs[$cfID][] = $value;
}
foreach ($fields['values'] as $field => $info) {
if (!empty($info['options']) || !empty($info['pseudoconstant']) || !empty($info['option_group_id'])) {
$options[$field] = $entity;
+ // Hack for when search field doesn't match db field - e.g. "country" instead of "country_id"
if (substr($field, -3) == '_id') {
$options[substr($field, 0, -3)] = $entity;
}
}
+ elseif (!empty($info['data_type']) && in_array($info['data_type'], array('StateProvince', 'Country'))) {
+ $options[$field] = $entity;
+ }
elseif (in_array(substr($field, 0, 3), array('is_', 'do_')) || CRM_Utils_Array::value('data_type', $info) == 'Boolean') {
$options[$field] = 'yesno';
if ($entity != 'contact') {
* @param CRM_Core_Form $qf form object (reference)
* @param string $elementName name of the custom field
* @param $fieldId
- * @param boolean $inactiveNeeded
+ * @param boolean $inactiveNeeded -deprecated
* @param bool $useRequired
* @param boolean $search true if used for search else false
* @param string $label label for custom field
$label = NULL
) {
$field = self::getFieldObject($fieldId);
+ $widget = $field->html_type;
// Custom field HTML should indicate group+field name
$groupName = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_CustomGroup', $field->custom_group_id);
$field->attributes .= $dataCrmCustomAttr;
// Fixed for Issue CRM-2183
- if ($field->html_type == 'TextArea' && $search) {
- $field->html_type = 'Text';
+ if ($widget == 'TextArea' && $search) {
+ $widget = 'Text';
+ }
+
+ if ($widget == 'Select State/Province' || $widget == 'Select Country') {
+ $qf->_stateCountryMap[$widget == 'Select Country' ? 'country' : 'state_province'][] = $elementName;
}
$placeholder = $search ? ts('- any -') : ($useRequired ? ts('- select -') : ts('- none -'));
// FIXME: Why are select state/country separate widget types?
- if (in_array($field->html_type, array('Select', 'Multi-Select', 'Select State/Province', 'Multi-Select State/Province', 'Select Country', 'Multi-Select Country'))) {
+ $isSelect = (in_array($widget, array('Select', 'Multi-Select', 'Select State/Province', 'Multi-Select State/Province', 'Select Country', 'Multi-Select Country', 'AdvMulti-Select', 'CheckBox', 'Radio')));
+
+ if ($isSelect) {
+ $options = CRM_Utils_Array::value('values', civicrm_api3('contact', 'getoptions', array('field' => "custom_$fieldId", 'context' => $search ? 'search' : 'create'), array()));
+
+ // Consolidate widget types to simplify the below switch statement
+ if ($search || ($widget !== 'AdvMulti-Select' && strpos($widget, 'Select') !== FALSE)) {
+ $widget = 'Select';
+ }
$selectAttributes = array(
'data-crm-custom' => $dataCrmCustomVal,
'class' => 'crm-select2',
);
- if (strpos($field->html_type, 'Multi') === 0) {
+ // Search field is always multi-select
+ if ($search || strpos($field->html_type, 'Multi') !== FALSE) {
+ $selectAttributes['class'] .= ' huge';
$selectAttributes['multiple'] = 'multiple';
+ $selectAttributes['placeholder'] = $placeholder;
+ }
+ // Add data for popup link. Normally this is handled by CRM_Core_Form->addSelect
+ if ($field->option_group_id && !$search && $widget == 'Select' && CRM_Core_Permission::check('administer CiviCRM')) {
+ $selectAttributes += array(
+ 'data-api-entity' => 'contact', // FIXME: This works because the getoptions api isn't picky about custom fields, but it's WRONG
+ 'data-api-field' => 'custom_' . $field->id,
+ 'data-option-edit-path' => 'civicrm/admin/options/' . CRM_Core_DAO::getFieldValue('CRM_Core_DAO_OptionGroup', $field->option_group_id),
+ );
}
- }
- // Add data so popup link. Normally this is handled by CRM_Core_Form->addSelect
- if ($field->option_group_id && !$search && in_array($field->html_type, array('Select', 'Multi-Select')) && CRM_Core_Permission::check('administer CiviCRM')) {
- $selectAttributes += array(
- 'data-api-entity' => 'contact', // FIXME: This works because the getoptions api isn't picky about custom fields, but it's WRONG
- 'data-api-field' => 'custom_' . $field->id,
- 'data-option-edit-path' => 'civicrm/admin/options/' . CRM_Core_DAO::getFieldValue('CRM_Core_DAO_OptionGroup', $field->option_group_id),
- );
}
if (!isset($label)) {
* at some point in time we might want to split the below into small functions
**/
- switch ($field->html_type) {
+ switch ($widget) {
case 'Text':
+ case 'Link':
if ($field->is_search_range && $search) {
$qf->add('text', $elementName . '_from', $label . ' ' . ts('From'), $field->attributes);
$qf->add('text', $elementName . '_to', ts('To'), $field->attributes);
}
else {
- $element = &$qf->add(strtolower($field->html_type), $elementName, $label,
+ $element = &$qf->add('text', $elementName, $label,
$field->attributes,
$useRequired && !$search
);
if ($field->text_length) {
$attributes .= ' maxlength=' . $field->text_length;
}
- $element = &$qf->add(strtolower($field->html_type),
+ $element = &$qf->add('textarea',
$elementName,
$label,
$attributes,
case 'Radio':
$choice = array();
- if ($field->data_type != 'Boolean') {
- $customOption = CRM_Core_BAO_CustomOption::valuesByID($field->id,
- $field->option_group_id
- );
- foreach ($customOption as $v => $l) {
- $choice[] = $qf->createElement('radio', NULL, '', $l, (string)$v, $field->attributes);
- }
- $group = $qf->addGroup($choice, $elementName, $label);
- }
- else {
- $choice[] = $qf->createElement('radio', NULL, '', ts('Yes'), '1', $field->attributes);
- $choice[] = $qf->createElement('radio', NULL, '', ts('No'), '0', $field->attributes);
- $group = $qf->addGroup($choice, $elementName, $label);
+ foreach ($options as $v => $l) {
+ $choice[] = $qf->createElement('radio', NULL, '', $l, (string)$v, $field->attributes);
}
+ $group = $qf->addGroup($choice, $elementName, $label);
if ($useRequired && !$search) {
$qf->addRule($elementName, ts('%1 is a required field.', array(1 => $label)), 'required');
}
}
break;
+ // For all select elements
case 'Select':
- $selectOption = CRM_Core_BAO_CustomOption::valuesByID($field->id,
- $field->option_group_id
- );
-
- $qf->add('select', $elementName, $label,
- array('' => $placeholder) + $selectOption,
- $useRequired && !$search,
- $selectAttributes
- );
- break;
+ if (empty($selectAttributes['multiple'])) {
+ $options = array('' => $placeholder) + $options;
+ }
+ $qf->add('select', $elementName, $label, $options, $useRequired && !$search, $selectAttributes);
- //added for select multiple
+ // Add and/or option for fields that store multiple values
+ if ($search && self::isSerialized($field)) {
- case 'AdvMulti-Select':
- $selectOption = CRM_Core_BAO_CustomOption::valuesByID($field->id,
- $field->option_group_id
- );
- if ($search &&
- count($selectOption) > 1
- ) {
- $selectOption['CiviCRM_OP_OR'] = ts('Select to match ANY; unselect to match ALL');
+ $operators = array(
+ $qf->createElement('radio', NULL, '', ts('Any'), 'or', array('title' => ts('Results may contain any of the selected options'))),
+ $qf->createElement('radio', NULL, '', ts('All'), 'and', array('title' => ts('Results must have all of the selected options'))),
+ );
+ $qf->addGroup($operators, $elementName . '_operator');
+ $qf->setDefaults(array($elementName . '_operator' => 'or'));
}
+ break;
+ case 'AdvMulti-Select':
$include =& $qf->addElement(
'advmultiselect',
$elementName,
- $label, $selectOption,
+ $label, $options,
array(
'size' => 5,
'style' => '',
}
break;
- case 'Multi-Select':
- $selectOption = CRM_Core_BAO_CustomOption::valuesByID($field->id,
- $field->option_group_id
- );
- if ($search &&
- count($selectOption) > 1
- ) {
- $selectOption['CiviCRM_OP_OR'] = ts('Select to match ANY; unselect to match ALL');
- }
- $qf->addElement('select', $elementName, $label, $selectOption, $selectAttributes);
-
- if ($useRequired && !$search) {
- $qf->addRule($elementName, ts('%1 is a required field.', array(1 => $label)), 'required');
- }
- break;
-
case 'CheckBox':
- $customOption = CRM_Core_BAO_CustomOption::valuesByID($field->id,
- $field->option_group_id
- );
$check = array();
- foreach ($customOption as $v => $l) {
+ foreach ($options as $v => $l) {
$check[] = &$qf->addElement('advcheckbox', $v, NULL, $l, array('data-crm-custom' => $dataCrmCustomVal));
}
- if ($search &&
- count($check) > 1
- ) {
- $check[] = &$qf->addElement('advcheckbox', 'CiviCRM_OP_OR', NULL, ts('Check to match ANY; uncheck to match ALL'), array('data-crm-custom' => $dataCrmCustomVal));
- }
$qf->addGroup($check, $elementName, $label);
if ($useRequired && !$search) {
$qf->addRule($elementName, ts('%1 is a required field.', array(1 => $label)), 'required');
$qf->addUploadElement($elementName);
break;
- case 'Select State/Province':
- //Add State
- $stateOption = array('' => $placeholder) + CRM_Core_PseudoConstant::stateProvince();
- $qf->add('select', $elementName, $label, $stateOption,
- $useRequired && !$search,
- $selectAttributes
- );
- $qf->_stateCountryMap['state_province'][] = $elementName;
- break;
-
- case 'Multi-Select State/Province':
- //Add Multi-select State/Province
- $stateOption = CRM_Core_PseudoConstant::stateProvince();
-
- $qf->addElement('select', $elementName, $label, $stateOption, $selectAttributes);
- if ($useRequired && !$search) {
- $qf->addRule($elementName, ts('%1 is a required field.', array(1 => $label)), 'required');
- }
- break;
-
- case 'Select Country':
- //Add Country
- $countryOption = array('' => $placeholder) + CRM_Core_PseudoConstant::country();
- $qf->add('select', $elementName, $label, $countryOption,
- $useRequired && !$search,
- $selectAttributes
- );
- $qf->_stateCountryMap['country'][] = $elementName;
- break;
-
- case 'Multi-Select Country':
- //Add Country
- $countryOption = CRM_Core_PseudoConstant::country();
- $qf->addElement('select', $elementName, $label, $countryOption, $selectAttributes);
- if ($useRequired && !$search) {
- $qf->addRule($elementName, ts('%1 is a required field.', array(1 => $label)), 'required');
- }
- break;
-
case 'RichTextEditor':
$attributes = array('rows' => $field->note_rows, 'cols' => $field->note_columns, 'data-crm-custom' => $dataCrmCustomVal);
if ($field->text_length) {
$attributes += array(
'entity' => 'option_value',
'placeholder' => $placeholder,
+ 'multiple' => $search,
'api' => array(
'params' => array('option_group_id' => $field->option_group_id),
),
$qf->addRule($elementName . '_from', ts('%1 From must be an integer (whole number).', array(1 => $label)), 'integer');
$qf->addRule($elementName . '_to', ts('%1 To must be an integer (whole number).', array(1 => $label)), 'integer');
}
- else {
+ elseif ($widget == 'Text') {
$qf->addRule($elementName, ts('%1 must be an integer (whole number).', array(1 => $label)), 'integer');
}
break;
$qf->addRule($elementName . '_from', ts('%1 From must be a number (with or without decimal point).', array(1 => $label)), 'numeric');
$qf->addRule($elementName . '_to', ts('%1 To must be a number (with or without decimal point).', array(1 => $label)), 'numeric');
}
- else {
+ elseif ($widget == 'Text') {
$qf->addRule($elementName, ts('%1 must be a number (with or without decimal point).', array(1 => $label)), 'numeric');
}
break;
$qf->addRule($elementName . '_from', ts('%1 From must in proper money format. (decimal point/comma/space is allowed).', array(1 => $label)), 'money');
$qf->addRule($elementName . '_to', ts('%1 To must in proper money format. (decimal point/comma/space is allowed).', array(1 => $label)), 'money');
}
- else {
+ elseif ($widget == 'Text') {
$qf->addRule($elementName, ts('%1 must be in proper money format. (decimal point/comma/space is allowed).', array(1 => $label)), 'money');
}
break;
case 'Link':
- $qf->add(
- 'text',
- $elementName,
- $label,
- array(
- 'onfocus' => "if (!this.value) { this.value='http://';} else return false",
- 'onblur' => "if ( this.value == 'http://') { this.value='';} else return false",
- 'data-crm-custom' => $dataCrmCustomVal,
- ),
- $useRequired && !$search
- );
+ $element->setAttribute('onfocus', "if (!this.value) {this.value='http://';}");
+ $element->setAttribute('onblur', "if (this.value == 'http://') {this.value='';}");
+ $element->setAttribute('class', "url");
$qf->addRule($elementName, ts('Enter a valid Website.'), 'wikiURL');
break;
}
$v = array();
$p = array();
foreach ($checkedData as $key => $val) {
- if ($key === 'CiviCRM_OP_OR') {
- continue;
- }
-
if ($html_type == 'CheckBox') {
if ($val) {
$p[] = $key;
return $isMultipleWithGid;
}
+
+ /**
+ * Does this field store a serialized string?
+ * @param CRM_Core_DAO_CustomField|array $field
+ * @return bool
+ */
+ static function isSerialized($field) {
+ // Fields retrieved via api are an array, or from the dao are an object. We'll accept either.
+ $field = (array) $field;
+ // FIXME: Currently the only way to know if data is serialized is by looking at the html_type. It would be cleaner to decouple this.
+ return ($field['html_type'] == 'CheckBox' || strpos($field['html_type'], 'Multi') !== FALSE);
+ }
}
if (!isset($group['fields'])) {
continue;
}
- $groupId = CRM_Utils_Array::value('id', $group);
foreach ($group['fields'] as $field) {
if (CRM_Utils_Array::value('element_value', $field) !== NULL) {
$value = $field['element_value'];
continue;
}
- $fieldId = $field['id'];
if (!empty($field['element_name'])) {
$elementName = $field['element_name'];
}
foreach ($values as $tuple) {
list($name, $op, $value, $grouping, $wildcard) = $tuple;
- // fix $value here to escape sql injection attacks
$field = $this->_fields[$id];
- $qillValue = CRM_Core_BAO_CustomField::getDisplayValue($value, $id, $this->_options);
+ $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);
+ }
+
+ // Handle multi-select search for any data type
+ if (is_array($value) && !$field['is_search_range']) {
+ $isSerialized = CRM_Core_BAO_CustomField::isSerialized($field);
+ $wildcard = $isSerialized ? $wildcard : TRUE;
+ $options = CRM_Utils_Array::value('values', civicrm_api3('contact', 'getoptions', array('field' => $name, 'context' => 'search'), array()));
+ $qillValue = '';
+ $sqlOP = $wildcard ? ' OR ' : ' AND ';
+ $sqlValue = array();
+ foreach ($value as $num => &$v) {
+ $sep = count($value) > (1 + $num) ? ', ' : (' ' . ($wildcard ? ts('OR') : ts('AND')) . ' ');
+ $qillValue .= ($num ? $sep : '') . $options[$v];
+ $v = CRM_Core_DAO::escapeString($v);
+ if ($isSerialized) {
+ $sqlValue[] = "( $fieldName like '%" . CRM_Core_DAO::VALUE_SEPARATOR . $v . CRM_Core_DAO::VALUE_SEPARATOR . "%' ) ";
+ }
+ else {
+ $v = "'$v'";
+ }
+ }
+ if (!$isSerialized) {
+ $sqlValue = array("$fieldName IN (" . implode(',', $value) . ")");
+ }
+ $this->_where[$grouping][] = ' ( ' . implode($sqlOP, $sqlValue) . ' ) ';
+ $this->_qill[$grouping][] = "$field[label] $op $qillValue";
+ continue;
+ }
+
+ // fix $value here to escape sql injection attacks
if (!is_array($value)) {
$value = CRM_Core_DAO::escapeString(trim($value));
}
- $fieldName = "{$field['table_name']}.{$field['column_name']}";
+ $qillValue = CRM_Core_BAO_CustomField::getDisplayValue($value, $id, $this->_options);
+
switch ($field['data_type']) {
case 'String':
$sql = "$fieldName";
- // if we are coming in from listings,
- // for checkboxes the value is already in the right format and is NOT an array
- if (is_array($value)) {
-
- //ignoring $op value for checkbox and multi select
- $sqlValue = array();
- $sqlOP = ' AND ';
- $sqlOPlabel = ts('match ALL');
- if ($field['html_type'] == 'CheckBox') {
- foreach ($value as $k => $v) {
- if ($v) {
- if ($k == 'CiviCRM_OP_OR') {
- $sqlOP = ' OR ';
- $sqlOPlabel = ts('match ANY');
- continue;
- }
-
- $sqlValue[] = "( $sql like '%" . CRM_Core_DAO::VALUE_SEPARATOR . $k . CRM_Core_DAO::VALUE_SEPARATOR . "%' ) ";
- }
- }
- //if user check only 'CiviCRM_OP_OR' check box
- //of custom checkbox field, then ignore this field.
- if (!empty($sqlValue)) {
- $this->_where[$grouping][] = ' ( ' . implode($sqlOP, $sqlValue) . ' ) ';
- $this->_qill[$grouping][] = "{$field['label']} $op $qillValue ( $sqlOPlabel )";
- }
- // for multi select
- }
- else {
- foreach ($value as $k => $v) {
- if ($v == 'CiviCRM_OP_OR') {
- $sqlOP = ' OR ';
- $sqlOPlabel = ts('match ANY');
- continue;
- }
- $v = CRM_Core_DAO::escapeString($v);
- $sqlValue[] = "( $sql like '%" . CRM_Core_DAO::VALUE_SEPARATOR . $v . CRM_Core_DAO::VALUE_SEPARATOR . "%' ) ";
- }
- //if user select only 'CiviCRM_OP_OR' value
- //of custom multi select field, then ignore this field.
- if (!empty($sqlValue)) {
- $this->_where[$grouping][] = ' ( ' . implode($sqlOP, $sqlValue) . ' ) ';
- $this->_qill[$grouping][] = "$field[label] $op $qillValue ( $sqlOPlabel )";
- }
- }
+
+ if ($field['is_search_range'] && is_array($value)) {
+ $this->searchRange($field['id'],
+ $field['label'],
+ $field['data_type'],
+ $fieldName,
+ $value,
+ $grouping
+ );
}
else {
- if ($field['is_search_range'] && is_array($value)) {
- $this->searchRange($field['id'],
- $field['label'],
- $field['data_type'],
- $fieldName,
- $value,
- $grouping
- );
- }
- else {
- if (in_array($field['html_type'], array('Select', 'Radio', 'Autocomplete-Select'))) {
- $wildcard = FALSE;
- $val = CRM_Utils_Type::escape($value, 'String');
- }
- else {
- $val = CRM_Utils_Type::escape($strtolower(trim($value)), 'String');
- }
-
- if ($wildcard) {
- $val = $strtolower(CRM_Core_DAO::escapeString($val));
- $val = "%$val%";
- $op = 'LIKE';
- }
-
- //FIX for custom data query fired against no value(NULL/NOT NULL)
- $this->_where[$grouping][] = CRM_Contact_BAO_Query::buildClause($sql, $op, $val, $field['data_type']);
- $this->_qill[$grouping][] = "$field[label] $op $qillValue";
+ $val = CRM_Utils_Type::escape($strtolower(trim($value)), 'String');
+
+ if ($wildcard) {
+ $val = $strtolower(CRM_Core_DAO::escapeString($val));
+ $val = "%$val%";
+ $op = 'LIKE';
}
+
+ //FIX for custom data query fired against no value(NULL/NOT NULL)
+ $this->_where[$grouping][] = CRM_Contact_BAO_Query::buildClause($sql, $op, $val, $field['data_type']);
+ $this->_qill[$grouping][] = "$field[label] $op $qillValue";
}
- continue;
+ break;
case 'ContactReference':
$label = $value ? CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $value, 'sort_name') : '';
$this->_where[$grouping][] = CRM_Contact_BAO_Query::buildClause($fieldName, $op, $value, 'String');
$this->_qill[$grouping][] = $field['label'] . " $op $label";
- continue;
+ break;
case 'Int':
if ($field['is_search_range'] && is_array($value)) {
$this->_where[$grouping][] = CRM_Contact_BAO_Query::buildClause($fieldName, $op, $value, 'Integer');
$this->_qill[$grouping][] = $field['label'] . " $op $value";
}
- continue;
+ break;
case 'Boolean':
if (strtolower($value) == 'yes' || strtolower($value) == strtolower(ts('Yes'))) {
$this->_where[$grouping][] = CRM_Contact_BAO_Query::buildClause($fieldName, $op, $value, 'Integer');
$value = $value ? ts('Yes') : ts('No');
$this->_qill[$grouping][] = $field['label'] . " {$op} {$value}";
- continue;
+ break;
case 'Link':
$this->_where[$grouping][] = CRM_Contact_BAO_Query::buildClause($fieldName, $op, $value, 'String');
$this->_qill[$grouping][] = $field['label'] . " $op $value";
- continue;
+ break;
case 'Float':
if ($field['is_search_range'] && is_array($value)) {
$this->_where[$grouping][] = CRM_Contact_BAO_Query::buildClause($fieldName, $op, $value, 'Float');
$this->_qill[$grouping][] = $field['label'] . " {$op} {$value}";
}
- continue;
+ break;
case 'Money':
if ($field['is_search_range'] && is_array($value)) {
$this->_where[$grouping][] = CRM_Contact_BAO_Query::buildClause($fieldName, $op, $value, 'Float');
$this->_qill[$grouping][] = $field['label'] . " {$op} {$value}";
}
- continue;
+ break;
case 'Memo':
$this->_where[$grouping][] = CRM_Contact_BAO_Query::buildClause($fieldName, $op, $value, 'String');
$this->_qill[$grouping][] = "$field[label] $op $value";
- continue;
+ break;
case 'Date':
$fromValue = CRM_Utils_Array::value('from', $value);
$this->_qill[$grouping][] = $field['label'] . ' <= ' . CRM_Utils_Date::customFormat($toDate);
}
}
- continue;
+ break;
case 'StateProvince':
case 'Country':
- if (!is_array($value)) {
- $this->_where[$grouping][] = "$fieldName {$op} " . CRM_Utils_Type::escape($value, 'Int');
- $this->_qill[$grouping][] = $field['label'] . " {$op} {$qillValue}";
- }
- else {
- $sqlOP = ' AND ';
- $sqlOPlabel = ts('match ALL');
- foreach ($value as $k => $v) {
- if ($v == 'CiviCRM_OP_OR') {
- $sqlOP = ' OR ';
- $sqlOPlabel = ts('match ANY');
- continue;
- }
- $sqlValue[] = "( $fieldName like '%" . CRM_Core_DAO::VALUE_SEPARATOR . $v . CRM_Core_DAO::VALUE_SEPARATOR . "%' ) ";
- }
-
- //if user select only 'CiviCRM_OP_OR' value
- //of custom multi select field, then ignore this field.
- if (!empty($sqlValue)) {
- $this->_where[$grouping][] = " ( " . implode($sqlOP, $sqlValue) . " ) ";
- $this->_qill[$grouping][] = "$field[label] $op $qillValue ( $sqlOPlabel )";
- }
- }
- continue;
+ $this->_where[$grouping][] = "$fieldName {$op} " . CRM_Utils_Type::escape($value, 'Int');
+ $this->_qill[$grouping][] = $field['label'] . " {$op} {$qillValue}";
+ break;
case 'File':
if ( $op == 'IS NULL' || $op == 'IS NOT NULL' || $op == 'IS EMPTY' || $op == 'IS NOT EMPTY' ) {
$this->_where[$grouping][] = CRM_Contact_BAO_Query::buildClause($fieldName, $op);
$this->_qill[$grouping][] = $field['label'] . " {$op} ";
}
- continue;
+ break;
}
}
}
foreach ($this->_fields as $name => $field) {
if ((substr($name, 0, 6) == 'custom') && !empty($field['is_search_range'])) {
- $from = CRM_Utils_Request::retrieve($name . '_from', 'String',
- $this, FALSE, NULL, 'REQUEST'
- );
- $to = CRM_Utils_Request::retrieve($name . '_to', 'String',
- $this, FALSE, NULL, 'REQUEST'
- );
+ $from = CRM_Utils_Request::retrieve($name . '_from', 'String', $this);
+ $to = CRM_Utils_Request::retrieve($name . '_to', 'String', $this);
$value = array();
if ($from && $to) {
$value['from'] = $from;
if (!is_array($value)) {
$value = trim($value);
}
+ $operator = CRM_Utils_Request::retrieve($name . '_operator', 'String', $this);
+ if ($operator) {
+ $this->_params[$name . '_operator'] = $operator;
+ }
$this->_params[$name] = $this->_fields[$name]['value'] = $value;
}
}
* @return bool
*/
public function isRedirectSupported() {
- return (ini_get('open_basedir') == '') && (ini_get('safe_mode') == 'Off' || ini_get('safe_mode') === FALSE);
+ return (ini_get('open_basedir') == '') && (ini_get('safe_mode') == 'Off' || ini_get('safe_mode') == '' || ini_get('safe_mode') === FALSE);
}
}
#crm-container input.submit-link {
color: #285286;
- background-color: transparent;
+ background: none transparent;
border: none;
cursor: pointer;
- cursor: hand;
margin: 0em -0.5em 0em -0.5em;
+ text-shadow: none;
}
.crm-container .underline-effect {
}
};
+ $scope.isValidName = function(name) {
+ return !name || name.match(/^[a-zA-Z0-9_]+$/);
+ };
+
$scope.getWorkflowName = function(activitySet) {
var result = 'Unknown';
_.each($scope.workflows, function(value, key) {
name="caseTypeName"
ng-model="caseType.name"
ng-disabled="locks.caseTypeName"
- ng-pattern="/^[a-zA-Z0-9_]+$/"
required
class="big crm-form-text"/>
<a crm-ui-lock binding="locks.caseTypeName"></a>
+ <div ng-show="!isValidName(caseType.name)">
+ <em>WARNING: The case type name includes deprecated characters.</em>
+ </div>
<div ng-show="caseType.id && !locks.caseTypeName">
<em>WARNING: If any external files or programs reference the old "Name", then they must be updated manually.</em>
</div>
{include file="CRM/common/formButtons.tpl" location="top" buttonStyle="width:80px; text-align:center;"}
</div>
<div class="crm-submit-buttons reset-advanced-search">
- <a href="{crmURL p='civicrm/contact/search/advanced' q='reset=1'}" id="resetAdvancedSearch" class="button" style="width:70px; text-align:center;"><span>{ts}Reset Form{/ts}</span></a>
+ <a href="{crmURL p='civicrm/contact/search/advanced' q='reset=1'}" id="resetAdvancedSearch" class="crm-hover-button" title="{ts}Clear all search criteria{/ts}">
+ <span class="icon ui-icon-circle-close"></span>
+ {ts}Reset Form{/ts}
+ </a>
</div>
</td>
</tr>
--- /dev/null
+{*
+ +--------------------------------------------------------------------+
+ | CiviCRM version 4.5 |
+ +--------------------------------------------------------------------+
+ | Copyright CiviCRM LLC (c) 2004-2014 |
+ +--------------------------------------------------------------------+
+ | This file is a part of CiviCRM. |
+ | |
+ | CiviCRM is free software; you can copy, modify, and distribute it |
+ | under the terms of the GNU Affero General Public License |
+ | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
+ | |
+ | CiviCRM is distributed in the hope that it will be useful, but |
+ | WITHOUT ANY WARRANTY; without even the implied warranty of |
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
+ | See the GNU Affero General Public License for more details. |
+ | |
+ | You should have received a copy of the GNU Affero General Public |
+ | License and the CiviCRM Licensing Exception along |
+ | with this program; if not, contact CiviCRM LLC |
+ | at info[AT]civicrm[DOT]org. If you have questions about the |
+ | GNU Affero General Public License or the licensing of CiviCRM, |
+ | see the CiviCRM license FAQ at http://civicrm.org/licensing |
+ +--------------------------------------------------------------------+
+*}
+{literal}
+ <script type="text/javascript">
+ CRM.$(function($) {
+ function showHideOperator() {
+ var val = $(this).val();
+ $(this).siblings("span.crm-multivalue-search-op").toggle(!!(val && val.length > 1));
+ }
+ $("span.crm-multivalue-search-op").siblings('select')
+ .off('.crmMultiValue')
+ .on('change.crmMultiValue', showHideOperator)
+ .each(showHideOperator);
+ });
+ </script>
+{/literal}
<div class="crm-accordion-body">
<table class="form-layout-compressed">
{foreach from=$cd_edit.fields item=element key=field_id}
- {assign var="element_name" value='custom_'|cat:$field_id}
- {if $element.options_per_line != 0}
- <tr>
- <td class="label">{$form.$element_name.label}</td>
- <td>
- {assign var="count" value="1"}
- {strip}
- <table class="form-layout-compressed">
- <tr>
- {* sort by fails for option per line. Added a variable to iterate through the element array*}
- {assign var="index" value="1"}
- {foreach name=outer key=key item=item from=$form.$element_name}
- {if $index < 10} {* Hack to skip QF field properties that are not checkbox elements. *}
- {assign var="index" value=`$index+1`}
- {else}
- {if $element.html_type EQ 'CheckBox' AND $smarty.foreach.outer.last EQ 1} {* Put 'match ANY / match ALL' checkbox in separate row. *}
- </tr>
- <tr>
- <td class="op-checkbox" colspan="{$element.options_per_line}" style="padding-top: 0px;">{$form.$element_name.$key.html}</td>
- {else}
- <td class="labels font-light">{$form.$element_name.$key.html}</td>
- {if $count EQ $element.options_per_line}
- </tr>
- <tr>
- {assign var="count" value="1"}
- {else}
- {assign var="count" value=`$count+1`}
- {/if}
- {/if}
- {/if}
- {/foreach}
- </tr>
- </table>
- {/strip}
- </td>
- </tr>
- {else}
{assign var="type" value=`$element.html_type`}
{assign var="element_name" value='custom_'|cat:$field_id}
+ {assign var="operator_name" value='custom_'|cat:$field_id|cat:'_operator'}
{if $element.is_search_range}
{assign var="element_name_from" value=$element_name|cat:"_from"}
{assign var="element_name_to" value=$element_name|cat:"_to"}
{elseif $element.skip_calendar NEQ true }
{include file="CRM/common/jcalendar.tpl" elementName=$element_name}
{/if}
+ {if !empty($form.$operator_name)}
+ <span class="crm-multivalue-search-op" for="{$element_name}">{$form.$operator_name.html}</span>
+ {assign var="add_multivalue_js" value=true}
+ {/if}
{/if}
{if $element.html_type eq 'Autocomplete-Select'}
{if $element.data_type eq 'ContactReference'}
{/if}
</td>
</tr>
- {/if}
{/foreach}
</table>
</div><!-- /.crm-accordion-body -->
</div><!-- /.crm-accordion-wrapper -->
{/foreach}
+ {if !empty($add_multivalue_js)}
+ {include file="CRM/Custom/Form/MultiValueSearch.js.tpl"}
+ {/if}
{/if}
{continue}
{/if}
{assign var=n value=$field.name}
+ {assign var="operator_name" value=$n|cat:'_operator'}
{if $field.is_search_range}
{assign var=from value=$field.name|cat:'_from'}
{assign var=to value=$field.name|cat:'_to'}
{$form.$to.label} {include file="CRM/common/jcalendar.tpl" elementName=$to}</td>
</tr>
{/if}
- {elseif $field.options_per_line}
- <tr>
- <td class="option-label">{$form.$n.label}</td>
- <td>
- {assign var="count" value="1"}
- {strip}
- <table class="form-layout-compressed">
- <tr>
- {* sort by fails for option per line. Added a variable to iterate through the element array*}
- {assign var="index" value="1"}
- {foreach name=outer key=key item=item from=$form.$n}
- {if $index < 10} {* Hack to skip QF field properties that are not checkbox elements. *}
- {assign var="index" value=`$index+1`}
- {else}
- {if $field.html_type EQ 'CheckBox' AND $smarty.foreach.outer.last EQ 1} {* Put 'match ANY / match ALL' checkbox in separate row. *}
- </tr>
- <tr>
- <td class="op-checkbox" colspan="{$field.options_per_line}" style="padding-top: 0px;">{$form.$n.$key.html}</td>
- {else}
- <td class="labels font-light">{$form.$n.$key.html}</td>
- {if $count EQ $field.options_per_line}
- </tr>
- <tr>
- {assign var="count" value="1"}
- {else}
- {assign var="count" value=`$count+1`}
- {/if}
- {/if}
- {/if}
- {/foreach}
- </tr>
- </table>
- {/strip}
- </td>
- </tr>
{else}
<tr>
<td class="label">
{else}
{$form.$n.html}
{/if}
- {if $field.html_type eq 'Autocomplete-Select'}
- {if $field.data_type eq 'ContactReference'}
- {include file="CRM/Custom/Form/ContactReference.tpl" element_name = $n}
- {/if}
+ {if $field.html_type eq 'Autocomplete-Select' and $field.data_type eq 'ContactReference'}
+ {include file="CRM/Custom/Form/ContactReference.tpl" element_name = $n}
+ {/if}
+ {if !empty($form.$operator_name)}
+ <span class="crm-multivalue-search-op" for="{$n}">{$form.$operator_name.html}</span>
+ {assign var="add_multivalue_js" value=true}
{/if}
</td>
{/if}
});
</script>
{/literal}
+
+{if !empty($add_multivalue_js)}
+ {include file="CRM/Custom/Form/MultiValueSearch.js.tpl"}
+{/if}