[MOSS] CIV-01-020 Validate value in the query building logic for privacy flag fields
authorSeamus Lee <seamuslee001@gmail.com>
Tue, 3 Mar 2020 20:48:35 +0000 (07:48 +1100)
committerSeamus Lee <seamuslee001@gmail.com>
Sat, 11 Apr 2020 20:49:43 +0000 (06:49 +1000)
CRM/Contact/BAO/Query.php
tests/phpunit/api/v3/ContactTest.php

index 04e33776d16aba525dec7c8f6a6c4851d8def2cb..4ccb455f216f45b12dd9b69e737d91c36307d1f1 100644 (file)
@@ -3092,7 +3092,7 @@ class CRM_Contact_BAO_Query {
       $groupContactCacheClause = $this->addGroupContactCache($smartGroupIDs, $gccTableAlias, "contact_a", $op);
       if (!empty($groupContactCacheClause)) {
         if ($isNotOp) {
-          $groupIds = implode(',', (array) $smartGroupIDs);
+          $groupIds = CRM_Utils_Type::validate(implode(',', (array) $smartGroupIDs), 'CommaSeparatedIntegers');
           $gcTable = "civicrm_group_contact_{$this->_groupUniqueKey}";
           $joinClause = ["contact_a.id = {$gcTable}.contact_id"];
           $this->_tables[$gcTable] = $this->_whereTables[$gcTable] = " LEFT JOIN civicrm_group_contact {$gcTable} ON (" . implode(' AND ', $joinClause) . ")";
@@ -4050,12 +4050,19 @@ WHERE  $smartGroupClause
   public function privacy(&$values) {
     list($name, $op, $value, $grouping) = $values;
     //fixed for profile search listing CRM-4633
+    if (is_array($value)) {
+      if (in_array(key($value), CRM_Core_DAO::acceptedSQLOperators(), TRUE)) {
+        $op = key($value);
+        $value = $value[$op];
+      }
+    }
     if (strpbrk($value, "[")) {
       $value = "'{$value}'";
       $op = "!{$op}";
       $this->_where[$grouping][] = "contact_a.{$name} $op $value";
     }
     else {
+      CRM_Utils_Type::validate($value, 'Integer');
       $this->_where[$grouping][] = "contact_a.{$name} $op $value";
     }
     $field = CRM_Utils_Array::value($name, $this->_fields);
index e81df03a6f6658cbf6e3307838700d4b5619ad66..99f28541e3d311c1c33e8d174eef6eb3acbb692a 100644 (file)
@@ -4571,4 +4571,36 @@ class api_v3_ContactTest extends CiviUnitTestCase {
     return [$contact1, $contact2];
   }
 
+  public function versionAndPrivacyOption() {
+    $version = [3, 4];
+    $fields = ['do_not_mail', 'do_not_email', 'do_not_sms', 'is_opt_out', 'do_not_trade'];
+    $tests = [];
+    foreach ($fields as $field) {
+      foreach ($version as $v) {
+        $tests[] = [$v, 1, $field, 1];
+        $tests[] = [$v, 0, $field, 3];
+        $tests[] = [$v, ['!=' => 1], $field, 3];
+        $tests[] = [$v, ['!=' => 0], $field, 1];
+      }
+    }
+    return $tests;
+  }
+
+ /**
+   * CRM-14743 - test api respects search operators.
+   *
+   * @param int $version
+   *
+   * @dataProvider versionAndPrivacyOption
+   */
+  public function testGetContactsByPrivacyFlag($version, $query, $field, $expected) {
+    $this->_apiversion = $version;
+    $contact1 = $this->individualCreate();
+    $contact2 = $this->individualCreate([$field => 1]);
+    $contact = $this->callAPISuccess('Contact', 'get', [$field => $query]);
+    $this->assertEquals($expected, $contact['count']);
+    $this->callAPISuccess('Contact', 'delete', ['id' => $contact1, 'skip_undelete' => 1]);
+    $this->callAPISuccess('Contact', 'delete', ['id' => $contact2, 'skip_undelete' => 1]);
+  }
+
 }