dev/core#210: Regex filter broken in Search Builder
authordeb.monish <monish.deb@jmaconsulting.biz>
Tue, 26 Jun 2018 10:33:17 +0000 (16:03 +0530)
committerdeb.monish <monish.deb@jmaconsulting.biz>
Thu, 28 Jun 2018 06:36:16 +0000 (12:06 +0530)
CRM/Contact/BAO/Query.php
tests/phpunit/CRM/Contact/SelectorTest.php

index eda7792aa7d315e4c17307b001562a4b3acf2dd9..61a76fe274a9c23e182d1ec44fb85a912e4eac6c 100644 (file)
@@ -2341,7 +2341,7 @@ class CRM_Contact_BAO_Query {
         $this->_where[$grouping][] = CRM_Core_DAO::createSQLFilter($fieldName, $value, $type);
       }
       else {
-        if (!strpos($op, 'IN')) {
+        if (!self::caseImportant($op)) {
           $value = $strtolower($value);
         }
         if ($wildcard) {
@@ -5669,6 +5669,9 @@ SELECT COUNT( conts.total_amount ) as cancel_count,
         $clause = ($dataType == 'Date') ? " $field IS NOT NULL " : " (NULLIF($field, '') IS NOT NULL) ";
         return $clause;
 
+      case 'RLIKE':
+        return " {$clause} BINARY '{$value}' ";
+
       case 'IN':
       case 'NOT IN':
         // I feel like this would be escaped properly if passed through $queryString = CRM_Core_DAO::createSqlFilter.
index a000c70e1c2c8631a30cf967fdd9f51bd837f65e..6394847a5b299d15d4a9368aabd80b4a2589fa94 100644 (file)
@@ -367,6 +367,53 @@ class CRM_Contact_Form_SelectorTest extends CiviUnitTestCase {
     $this->assertEquals('test@test.com', $rows[$contactID]['Non_ASCII_Location_Type-email']);
   }
 
+  /**
+   * Test the value use in where clause if it's case sensitive or not against each MySQL operators
+   */
+  public function testWhereClauseByOperator() {
+    $contactID = $this->individualCreate(['first_name' => 'Adam']);
+
+    $filters = [
+      'IS NOT NULL' => 1,
+      '=' => 'Adam',
+      'LIKE' => '%Ad%',
+      'RLIKE' => '^A[a-z]{3}$',
+      'IN' => ['IN' => ['Adam']],
+    ];
+    $filtersByWhereClause = [
+      'IS NOT NULL' => '( contact_a.first_name IS NOT NULL )', // doesn't matter
+      '=' => "( contact_a.first_name = 'Adam' )", // case sensitive check
+      'LIKE' => "( contact_a.first_name LIKE '%ad%' )", // case insensitive check
+      'RLIKE' => "(  contact_a.first_name RLIKE BINARY '^A[a-z]{3}$'  )", // case sensitive check
+      'IN' => '( contact_a.first_name IN ("Adam") )', // case sensitive check
+    ];
+    foreach ($filters as $op => $filter) {
+      $selector = new CRM_Contact_Selector(
+        'CRM_Contact_Selector',
+        ['first_name' => [$op => $filter]],
+        [[
+          0 => 'first_name',
+          1 => $op,
+          2 => $filter,
+          3 => 1,
+          4 => 0,
+        ]],
+        [],
+        CRM_Core_Action::NONE,
+        NULL,
+        FALSE,
+        'builder'
+      );
+
+      $sql = $selector->getQueryObject()->query();
+      $this->assertEquals(TRUE, strpos($sql[2], $filtersByWhereClause[$op]));
+
+      $rows = $selector->getRows(CRM_Core_Action::VIEW, 0, TRUE, NULL);
+      $this->assertEquals(1, count($rows));
+      $this->assertEquals($contactID, key($rows));
+    }
+  }
+
   /**
    * Test if custom table is added in from clause when
    * search results are ordered by a custom field.