Merge pull request #6450 from civicrm/4.6
[civicrm-core.git] / CRM / Contact / Form / Search / Builder.php
index c11efbd956cdd3beab188d56c52bcecd9eddc401..7a702587bec0ac79a45208a0aee42cefc0f28207 100644 (file)
@@ -1,9 +1,9 @@
 <?php
 /*
  +--------------------------------------------------------------------+
- | CiviCRM version 4.5                                                |
+ | CiviCRM version 4.6                                                |
  +--------------------------------------------------------------------+
- | Copyright CiviCRM LLC (c) 2004-2014                                |
+ | Copyright CiviCRM LLC (c) 2004-2015                                |
  +--------------------------------------------------------------------+
  | This file is a part of CiviCRM.                                    |
  |                                                                    |
  | GNU Affero General Public License or the licensing of CiviCRM,     |
  | see the CiviCRM license FAQ at http://civicrm.org/licensing        |
  +--------------------------------------------------------------------+
-*/
+ */
 
 /**
  *
  * @package CRM
- * @copyright CiviCRM LLC (c) 2004-2014
+ * @copyright CiviCRM LLC (c) 2004-2015
  * $Id$
  *
  */
 class CRM_Contact_Form_Search_Builder extends CRM_Contact_Form_Search {
 
   /**
-   * number of columns in where
+   * Number of columns in where.
    *
    * @var int
-   * @access public
    */
   public $_columnCount;
 
   /**
-   * number of blocks to be shown
+   * Number of blocks to be shown.
    *
    * @var int
-   * @access public
    */
   public $_blockCount;
 
   /**
-   * Function to actually build the form
+   * Build the form object.
    *
    * @return void
-   * @access public
    */
   public function preProcess() {
     $this->set('searchFormName', 'Builder');
@@ -126,30 +123,26 @@ class CRM_Contact_Form_Search_Builder extends CRM_Contact_Form_Search {
   }
 
   /**
-   * Add local and global form rules
+   * Add local and global form rules.
    *
-   * @access protected
    *
    * @return void
    */
-  function addRules() {
+  public function addRules() {
     $this->addFormRule(array('CRM_Contact_Form_Search_Builder', 'formRule'), $this);
   }
 
   /**
-   * global validation rules for the form
+   * Global validation rules for the form.
    *
    * @param $values
    * @param $files
    * @param $self
    *
-   * @internal param array $fields posted values of the form
-   *
-   * @return array list of errors to be posted back to the form
-   * @static
-   * @access public
+   * @return array
+   *   list of errors to be posted back to the form
    */
-  static function formRule($values, $files, $self) {
+  public static function formRule($values, $files, $self) {
     if (!empty($values['addMore']) || !empty($values['addBlock'])) {
       return TRUE;
     }
@@ -166,7 +159,8 @@ class CRM_Contact_Form_Search_Builder extends CRM_Contact_Form_Search {
         $v[2] = self::checkArrayKeyEmpty($v[2]);
 
         if (in_array($v[1], array('IS NULL', 'IS NOT NULL', 'IS EMPTY', 'IS NOT EMPTY')) &&
-          !empty($v[2])) {
+          !empty($v[2])
+        ) {
           $errorMsg["value[$v[3]][$v[4]]"] = ts('Please clear your value if you want to use %1 operator.', array(1 => $v[1]));
         }
         elseif (($v[0] == 'group' || $v[0] == 'tag') && !empty($v[2])) {
@@ -182,7 +176,7 @@ class CRM_Contact_Form_Search_Builder extends CRM_Contact_Form_Search {
             foreach ($grpId as $val) {
               $error = CRM_Utils_Type::validate($val, 'Integer', FALSE);
               if ($error != $val) {
-                $errorMsg["value[$v[3]][$v[4]]"] = ts("Please enter valid value.");
+                $errorMsg["value[$v[3]][$v[4]]"] = ts("Please enter valid value.");
                 break;
               }
             }
@@ -218,7 +212,9 @@ class CRM_Contact_Form_Search_Builder extends CRM_Contact_Form_Search {
 
             // hack to handle custom data of type state and country
             if (in_array($type, array(
-              'Country', 'StateProvince'))) {
+              'Country',
+              'StateProvince',
+            ))) {
               $type = "Integer";
             }
           }
@@ -233,9 +229,16 @@ class CRM_Contact_Form_Search_Builder extends CRM_Contact_Form_Search {
             $fldValue = CRM_Utils_Array::value($fldName, $fields);
             $fldType = CRM_Utils_Array::value('type', $fldValue);
             $type = CRM_Utils_Type::typeToString($fldType);
+
+            if (strstr($v[1], 'IN')) {
+              if (empty($v[2])) {
+                $errorMsg["value[$v[3]][$v[4]]"] = ts("Please enter a value.");
+              }
+            }
             // Check Empty values for Integer Or Boolean Or Date type For operators other than IS NULL and IS NOT NULL.
-            if (!in_array($v[1],
-                array('IS NULL', 'IS NOT NULL', 'IS EMPTY', 'IS NOT EMPTY'))) {
+            elseif (!in_array($v[1],
+              array('IS NULL', 'IS NOT NULL', 'IS EMPTY', 'IS NOT EMPTY'))
+            ) {
               if ((($type == 'Int' || $type == 'Boolean') && !is_array($v[2]) && !trim($v[2])) && $v[2] != '0') {
                 $errorMsg["value[$v[3]][$v[4]]"] = ts("Please enter a value.");
               }
@@ -247,17 +250,17 @@ class CRM_Contact_Form_Search_Builder extends CRM_Contact_Form_Search {
 
           if ($type && empty($errorMsg)) {
             // check for valid format while using IN Operator
-            if ($v[1] == 'IN') {
+            if (strstr($v[1], 'IN')) {
               if (!is_array($v[2])) {
                 $inVal = trim($v[2]);
                 //checking for format to avoid db errors
                 if ($type == 'Int') {
-                  if (!preg_match('/^[(]([A-Za-z0-9\,]+)[)]$/', $inVal)) {
+                  if (!preg_match('/^[A-Za-z0-9\,]+$/', $inVal)) {
                     $errorMsg["value[$v[3]][$v[4]]"] = ts("Please enter correct Data (in valid format).");
                   }
                 }
                 else {
-                  if (!(substr($inVal, 0, 1) == '(' && substr($inVal, -1, 1) == ')') && !preg_match('/^[(]([A-Za-z0-9åäöÅÄÖüÜœŒæÆøØ\,\s]+)[)]$/', $inVal)) {
+                  if (!preg_match('/^[A-Za-z0-9åäöÅÄÖüÜœŒæÆøØ()\,\s]+$/', $inVal)) {
                     $errorMsg["value[$v[3]][$v[4]]"] = ts("Please enter correct Data (in valid format).");
                   }
                 }
@@ -266,9 +269,17 @@ class CRM_Contact_Form_Search_Builder extends CRM_Contact_Form_Search {
               // Validate each value in parenthesis to avoid db errors
               if (empty($errorMsg)) {
                 $parenValues = array();
-                $parenValues = is_array($v[2]) ? $v[2] : explode(',', trim($inVal, "(..)"));
+                $parenValues = is_array($v[2]) ? (array_key_exists($v[1], $v[2])) ? $v[2][$v[1]] : $v[2] : explode(',', trim($inVal, "(..)"));
                 foreach ($parenValues as $val) {
-                  $val = trim($val);
+                  if ($type == 'Date' || $type == 'Timestamp') {
+                    $val = CRM_Utils_Date::processDate($val);
+                    if ($type == 'Date') {
+                      $val = substr($val, 0, 8);
+                    }
+                  }
+                  else {
+                    $val = trim($val);
+                  }
                   if (!$val && $val != '0') {
                     $errorMsg["value[$v[3]][$v[4]]"] = ts("Please enter the values correctly.");
                   }
@@ -302,7 +313,8 @@ class CRM_Contact_Form_Search_Builder extends CRM_Contact_Form_Search {
     return TRUE;
   }
 
-  public function normalizeFormValues() {}
+  public function normalizeFormValues() {
+  }
 
   /**
    * @param $formValues
@@ -321,10 +333,9 @@ class CRM_Contact_Form_Search_Builder extends CRM_Contact_Form_Search {
   }
 
   /**
-   * Process the uploaded file
+   * Process the uploaded file.
    *
    * @return void
-   * @access public
    */
   public function postProcess() {
     $this->set('isAdvanced', '2');
@@ -345,7 +356,7 @@ class CRM_Contact_Form_Search_Builder extends CRM_Contact_Form_Search {
       $addMore = CRM_Utils_Array::value('addMore', $params);
       for ($x = 1; $x <= $this->_blockCount; $x++) {
         if (!empty($addMore[$x])) {
-          $this->set('newBlock',  $x);
+          $this->set('newBlock', $x);
           $this->_columnCount[$x] = $this->_columnCount[$x] + 5;
           $this->set('columnCount', $this->_columnCount);
           $this->set('showSearchForm', TRUE);
@@ -411,7 +422,7 @@ class CRM_Contact_Form_Search_Builder extends CRM_Contact_Form_Search {
   /**
    * @return array
    */
-  static function fields() {
+  public static function fields() {
     $fields = array_merge(
       CRM_Contact_BAO_Contact::exportableFields('All', FALSE, TRUE),
       CRM_Core_Component::getQueryFields(),
@@ -424,10 +435,11 @@ class CRM_Contact_Form_Search_Builder extends CRM_Contact_Form_Search {
   /**
    * CRM-9434 Hackish function to fetch fields with options.
    * FIXME: When our core fields contain reliable metadata this will be much simpler.
-   * @return array: (string => string) key: field_name value: api entity name
-   * Note: options are fetched via ajax using the api "getoptions" method
+   * @return array
+   *   (string => string) key: field_name value: api entity name
+   *   Note: options are fetched via ajax using the api "getoptions" method
    */
-  static function fieldOptions() {
+  public static function fieldOptions() {
     // Hack to add options not retrieved by getfields
     // This list could go on and on, but it would be better to fix getfields
     $options = array(
@@ -443,7 +455,17 @@ class CRM_Contact_Form_Search_Builder extends CRM_Contact_Form_Search {
       'member_is_pay_later' => 'yesno',
       'is_override' => 'yesno',
     );
-    $entities = array('contact', 'address', 'activity', 'participant', 'pledge', 'member', 'contribution');
+    $entities = array(
+      'contact',
+      'address',
+      'activity',
+      'participant',
+      'pledge',
+      'member',
+      'contribution',
+      'case',
+      'grant',
+    );
     CRM_Contact_BAO_Query_Hook::singleton()->alterSearchBuilderOptions($entities, $options);
     foreach ($entities as $entity) {
       $fields = civicrm_api3($entity, 'getfields');
@@ -458,7 +480,11 @@ class CRM_Contact_Form_Search_Builder extends CRM_Contact_Form_Search {
         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') {
+        elseif (in_array(substr($field, 0, 3), array(
+              'is_',
+              'do_',
+            )) || CRM_Utils_Array::value('data_type', $info) == 'Boolean'
+        ) {
           $options[$field] = 'yesno';
           if ($entity != 'contact') {
             $options[$entity . '_' . $field] = 'yesno';
@@ -476,21 +502,21 @@ class CRM_Contact_Form_Search_Builder extends CRM_Contact_Form_Search {
    * CRM-10338
    * tags and groups use array keys for selection list.
    * if using IS NULL/NOT NULL, an array with no array key is created
-   * convert that to simple null so processing can proceed
+   * convert that to simple NULL so processing can proceed
    */
-  static function checkArrayKeyEmpty($val) {
+  public static function checkArrayKeyEmpty($val) {
     if (is_array($val)) {
-      $v2empty = true;
+      $v2empty = TRUE;
       foreach ($val as $vk => $vv) {
         if (!empty($vk)) {
-          $v2empty = false;
+          $v2empty = FALSE;
         }
       }
       if ($v2empty) {
-        $val = null;
+        $val = NULL;
       }
     }
     return $val;
   }
-}
 
+}