Merge pull request #3838 from totten/master-phpunit-misc
authorTim Otten <to-git@think.hm>
Thu, 14 Aug 2014 05:36:01 +0000 (22:36 -0700)
committerTim Otten <to-git@think.hm>
Thu, 14 Aug 2014 05:36:01 +0000 (22:36 -0700)
INFRA-125, CRM-15011 - Import helper scripts for phpunit

14 files changed:
CRM/Contact/BAO/Query.php
CRM/Contact/Form/Search/Builder.php
CRM/Core/BAO/CustomField.php
CRM/Core/BAO/CustomGroup.php
CRM/Core/BAO/CustomQuery.php
CRM/Profile/Page/Listings.php
CRM/Utils/HttpClient.php
css/civicrm.css
js/angular-crmCaseType.js
partials/crmCaseType/caseTypeDetails.html
templates/CRM/Contact/Form/Search/Criteria/Basic.tpl
templates/CRM/Custom/Form/MultiValueSearch.js.tpl [new file with mode: 0644]
templates/CRM/Custom/Form/Search.tpl
templates/CRM/Profile/Form/Search.tpl

index 681142af2022b9b7e966469d1a6bc5e501849a9f..0c7df5514f0a27a21a0cdf7e8595a49f052c1488 100644 (file)
@@ -563,6 +563,13 @@ class CRM_Contact_BAO_Query {
         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;
       }
 
index e2a88eaded998ac030815779a672b973d8642f03..380d04a2696cb1f24b6df0a52a7de8fc0b65c6ce 100644 (file)
@@ -450,10 +450,14 @@ class CRM_Contact_Form_Search_Builder extends CRM_Contact_Form_Search {
       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') {
index 3336e02f20179c74ac6c1fee1f4cfc7a996154a8..4a902f1054e4b9135cc0b9101f06a4b9c3c048cd 100644 (file)
@@ -726,7 +726,7 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField {
    * @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
@@ -744,6 +744,7 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField {
     $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);
@@ -752,29 +753,44 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField {
     $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)) {
@@ -785,14 +801,15 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField {
      * 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
           );
@@ -816,7 +833,7 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField {
         if ($field->text_length) {
           $attributes .= ' maxlength=' . $field->text_length;
         }
-        $element = &$qf->add(strtolower($field->html_type),
+        $element = &$qf->add('textarea',
           $elementName,
           $label,
           $attributes,
@@ -861,20 +878,10 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField {
 
       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');
         }
@@ -883,34 +890,30 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField {
         }
         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' => '',
@@ -927,35 +930,11 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField {
         }
         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');
@@ -977,45 +956,6 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField {
         $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) {
@@ -1056,6 +996,7 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField {
           $attributes += array(
             'entity' => 'option_value',
             'placeholder' => $placeholder,
+            'multiple' => $search,
             'api' => array(
               'params' => array('option_group_id' => $field->option_group_id),
             ),
@@ -1074,7 +1015,7 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField {
           $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;
@@ -1084,7 +1025,7 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField {
           $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;
@@ -1094,23 +1035,15 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField {
           $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;
     }
@@ -1270,10 +1203,6 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField {
         $v = array();
         $p = array();
         foreach ($checkedData as $key => $val) {
-          if ($key === 'CiviCRM_OP_OR') {
-            continue;
-          }
-
           if ($html_type == 'CheckBox') {
             if ($val) {
               $p[] = $key;
@@ -2552,5 +2481,17 @@ WHERE cf.id = %1 AND cg.is_multiple = 1";
 
     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);
+  }
 }
 
index 060dd7dd1f37e64c00112efac997e0ea1f9b6a63..29a091598a43cc8a6a58ddd444a34d674c00f4ff 100644 (file)
@@ -1238,7 +1238,6 @@ ORDER BY civicrm_custom_group.weight,
       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'];
@@ -1255,7 +1254,6 @@ ORDER BY civicrm_custom_group.weight,
           continue;
         }
 
-        $fieldId = $field['id'];
         if (!empty($field['element_name'])) {
           $elementName = $field['element_name'];
         }
index 6a36b4468d27f5dc7005b070070ea236d1ceb1b2..8ca162022e06eefdfc34576835a797f4a35be9db 100644 (file)
@@ -347,101 +347,82 @@ SELECT label, value
       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)) {
@@ -451,7 +432,7 @@ SELECT label, 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'))) {
@@ -464,12 +445,12 @@ SELECT label, value
             $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)) {
@@ -479,7 +460,7 @@ SELECT label, 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)) {
@@ -495,12 +476,12 @@ SELECT label, 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);
@@ -544,34 +525,13 @@ SELECT label, 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' ) {
@@ -586,7 +546,7 @@ SELECT label, value
               $this->_where[$grouping][] = CRM_Contact_BAO_Query::buildClause($fieldName, $op);
               $this->_qill[$grouping][] = $field['label'] . " {$op} ";
             }
-            continue;
+            break;
         }
       }
     }
index a505ec9b22eb6839b07e3d017fa9cd3da199d571..1cdfb5fae8aa42399764ff9f37579182084881e9 100644 (file)
@@ -158,12 +158,8 @@ class CRM_Profile_Page_Listings extends CRM_Core_Page {
 
     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;
@@ -248,6 +244,10 @@ class CRM_Profile_Page_Listings extends CRM_Core_Page {
         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;
       }
     }
index 3148c536058f9e9538ae72670abd21aef5991d1c..dc88f47559b7b8f58b972092bc9dd4f52e2007b2 100644 (file)
@@ -217,7 +217,7 @@ class CRM_Utils_HttpClient {
    * @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);
   }
 
 }
index 050732ab45974e72c73778e76b22b9baeb93a355..e6e14e6c30e9c25414cd839cc5308a8eade19c18 100644 (file)
@@ -1327,11 +1327,11 @@ input.crm-form-entityref {
 
 #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 {
index 1841cb459db68f62ac441b0e8323d7ba22be1bd1..d9504a7943d86d0a8b0827df4c997bb9a059e377 100644 (file)
       }
     };
 
+    $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) {
index 8e84a394523c854e168b7318313d686a299a2330..3a24b86ee88380e9abdb557cb3844efb07fbdc92 100644 (file)
@@ -34,12 +34,14 @@ The original form used table layout; don't know if we have an alternative, CSS-b
         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>
index 9a091dd1b990dc102c9533e3885d999b44ec874a..6b302739c5d63d35f39f110503450b0e37ca9d0f 100644 (file)
         {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>
diff --git a/templates/CRM/Custom/Form/MultiValueSearch.js.tpl b/templates/CRM/Custom/Form/MultiValueSearch.js.tpl
new file mode 100644 (file)
index 0000000..a0c7de7
--- /dev/null
@@ -0,0 +1,39 @@
+{*
+ +--------------------------------------------------------------------+
+ | 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}
index 2dd5b37f380cc50c876bd1d6a9d96fe2b5dad262..792e6af02c01c128aedf8936a50be7c91459ba16 100644 (file)
     <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}
 
index 110c10d4917543a4e1bd883a988c468e7c59f5ef..9cb83280cb9780b6b402d1786696427198055e7e 100644 (file)
@@ -40,6 +40,7 @@
         {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'}
               &nbsp;&nbsp;{$form.$to.label}&nbsp;&nbsp;{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}