DAO - Handle OR clauses in getDynamicFkAclClauses, improve sql formatting for readability
authorcolemanw <coleman@civicrm.org>
Thu, 5 Oct 2023 18:01:25 +0000 (14:01 -0400)
committercolemanw <coleman@civicrm.org>
Sat, 7 Oct 2023 19:07:45 +0000 (15:07 -0400)
Follow-up to 918e583a146876fb42932a1d959796fd710b7b74 - this correctly joins sub-arrays using OR

CRM/Contact/BAO/Query.php
CRM/Core/DAO.php
CRM/Utils/SQL.php
CRM/Utils/SQL/Select.php

index 23499c9219b4f9a9c615d626baf1b1eef88c04c5..57039fdb896352f803bed6617867e0d983fd852d 100644 (file)
@@ -583,10 +583,10 @@ class CRM_Contact_BAO_Query {
       // Unit test coverage in api_v3_FinancialTypeACLTest::testGetACLContribution.
       $clauses = [];
       if ($component === 'contribution') {
-        $clauses = CRM_Contribute_BAO_Contribution::getSelectWhereClause();
+        $clauses = array_filter(CRM_Contribute_BAO_Contribution::getSelectWhereClause());
       }
       if ($component === 'membership') {
-        $clauses = CRM_Member_BAO_Membership::getSelectWhereClause();
+        $clauses = array_filter(CRM_Member_BAO_Membership::getSelectWhereClause());
       }
       if ($clauses) {
         $this->_whereClause .= ' AND ' . implode(' AND ', $clauses);
index bd7147725b030bc8c70dacd3be94edfaf25f89a1..027ea8c5abc7d13ae741f3088cd0dfaa23b72cc7 100644 (file)
@@ -3142,7 +3142,16 @@ SELECT contact_id
       // Prevent infinite recursion
       $subquery = $table === static::getTableName() ? NULL : CRM_Utils_SQL::mergeSubquery($ent);
       if ($subquery) {
-        $relatedClauses[] = "= '$table' AND {{$entityIdField}} " . implode(" AND {{$entityIdField}} ", $subquery);
+        foreach ($subquery as $index => $condition) {
+          // Join OR clauses
+          if (is_array($condition)) {
+            $subquery[$index] = "(({{$entityIdField}} " . implode(") OR ({{$entityIdField}} ", $condition) . '))';
+          }
+          else {
+            $subquery[$index] = "{{$entityIdField}} $condition";
+          }
+        }
+        $relatedClauses[] = "= '$table' AND " . implode(" AND ", $subquery);
       }
       // If it's the only value with no conditions, don't need to add it
       elseif (!$entityTableValues || count($relatedEntities) > 1) {
index 5f7311d6096ee38081b1663e185bcac351e44346..2f5e0784327320e81d2a4b76036c740a0c2bf76c 100644 (file)
@@ -71,7 +71,7 @@ class CRM_Utils_SQL {
           }
           // Arrays of arrays get joined with OR (similar to CRM_Core_Permission::check)
           elseif (is_array($formattedClause)) {
-            $subClauses[] = "($fieldName " . implode(" OR $fieldName ", $formattedClause) . ')';
+            $subClauses[] = "(($fieldName " . implode(") OR ($fieldName ", $formattedClause) . '))';
           }
           else {
             $subClauses[] = "$fieldName $formattedClause";
index 2e93386531340146c5f35960c5bf679c5f8497d6..3ffcb18a4379755907a0a5ec5da0a03a6757470a 100644 (file)
@@ -581,13 +581,13 @@ class CRM_Utils_SQL_Select extends CRM_Utils_SQL_BaseParamQuery {
       $sql .= $join . "\n";
     }
     if ($this->wheres) {
-      $sql .= 'WHERE (' . implode(') AND (', $this->wheres) . ")\n";
+      $sql .= 'WHERE (' . implode(")\n  AND (", $this->wheres) . ")\n";
     }
     if ($this->groupBys) {
       $sql .= 'GROUP BY ' . implode(', ', $this->groupBys) . "\n";
     }
     if ($this->havings) {
-      $sql .= 'HAVING (' . implode(') AND (', $this->havings) . ")\n";
+      $sql .= 'HAVING (' . implode(")\n  AND (", $this->havings) . ")\n";
     }
     if ($this->orderBys) {
       $orderBys = CRM_Utils_Array::crmArraySortByField($this->orderBys,