}
$this->_tables[$gcTable] = $this->_whereTables[$gcTable] = " LEFT JOIN civicrm_group_contact {$gcTable} ON (" . implode(' AND ', $joinClause) . ")";
if (strpos($op, 'IN') !== FALSE) {
- $groupClause[] = "{$gcTable}.group_id $op ( $groupIds )";
+ $clause = "{$gcTable}.group_id $op ( $groupIds ) %s ";
}
elseif ($op == '!=') {
- $groupClause[] = "{$gcTable}.contact_id NOT IN (SELECT contact_id FROM civicrm_group_contact cgc WHERE cgc.group_id = $groupIds)";
+ $clause = "{$gcTable}.contact_id NOT IN (SELECT contact_id FROM civicrm_group_contact cgc WHERE cgc.group_id = $groupIds %s)";
}
else {
- $groupClause[] = "{$gcTable}.group_id $op $groupIds";
+ $clause = "{$gcTable}.group_id $op $groupIds %s ";
}
+
+ // include child groups IDs if any
+ $childGroupIds = self::getChildGroupIds($regularGroupIDs);
+ $childClause = '';
+ if (count($childGroupIds)) {
+ $gcTable = ($op == '!=') ? 'cgc' : $gcTable;
+ $childClause = " OR {$gcTable}.group_id IN (" . implode(',', $childGroupIds) . ") ";
+ }
+ $groupClause[] = sprintf($clause, $childClause);
}
//CRM-19589: contact(s) removed from a Smart Group, resides in civicrm_group_contact table
}
}
+ /**
+ * Get child group ids
+ *
+ * @param array $ids
+ * Parent Group IDs
+ *
+ * @return array
+ */
+ public static function getChildGroupIds($ids) {
+ $notFound = FALSE;
+ $childGroupIds = array();
+ foreach ($ids as $id) {
+ $childId = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Group', $id, 'children');
+ while (!empty($childId)) {
+ $childGroupIds[] = $childId;
+ $childId = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Group', $childId, 'children');
+ }
+ }
+
+ return $childGroupIds;
+ }
+
/**
* Function translates selection of group type into a list of groups.
* @param $value
$this->assertEquals(array(), array_diff($validChildContactIds, $resultChildContactIds), 'Check that the difference between two arrays should be blank array');
}
+
+ /**
+ * CRM-19698: Test case for combine contact search in regular and smart group
+ */
+ public function testContactCombineGroupSearch() {
+ // create regular group based
+ $regularGroup = $this->callAPISuccess('Group', 'create', array(
+ 'title' => 'Regular Group',
+ 'description' => 'Regular Group',
+ 'visibility' => 'User and User Admin Only',
+ 'is_active' => 1,
+ ));
+
+ // Create contact with Gender - Male
+ $contact1 = $this->individualCreate(array(
+ 'gender_id' => "Male",
+ ));
+
+ // Create contact with Gender - Male and in regular group
+ $contact2 = $this->individualCreate(array(
+ 'group' => array($regularGroup['id'] => 1),
+ 'gender_id' => "Male",
+ ), 1);
+
+ // Create contact with Gender - Female and in regular group
+ $contact3 = $this->individualCreate(array(
+ 'group' => array($regularGroup['id'] => 1),
+ 'gender_id' => "Female",
+ ), 1);
+
+ // create smart group based on saved criteria Gender = Male
+ $batch = $this->callAPISuccess('SavedSearch', 'create', array(
+ 'form_values' => 'a:1:{i:0;a:5:{i:0;s:9:"gender_id";i:1;s:1:"=";i:2;i:2;i:3;i:0;i:4;i:0;}}',
+ ));
+ $smartGroup = $this->callAPISuccess('Group', 'create', array(
+ 'title' => 'Smart Group',
+ 'description' => 'Smart Group',
+ 'visibility' => 'User and User Admin Only',
+ 'saved_search_id' => $batch['id'],
+ 'is_active' => 1,
+ ));
+
+ $useCases = array(
+ //Case 1: Find all contacts in regular group
+ array(
+ 'form_value' => array('group' => $regularGroup['id']),
+ 'expected_count' => 2,
+ 'operator' => 'AND',
+ 'expected_contact' => array($contact2, $contact3),
+ ),
+ //Case 2: Find all contacts in smart group
+ array(
+ 'form_value' => array('group' => $smartGroup['id']),
+ 'expected_count' => 2,
+ 'operator' => 'AND',
+ 'expected_contact' => array($contact1, $contact2),
+ ),
+ //Case 3: Find all contacts in regular group AND smart group
+ array(
+ 'form_value' => array('group' => array('IN' => array($regularGroup['id'], $smartGroup['id']))),
+ 'expected_count' => 1,
+ 'operator' => 'AND',
+ 'expected_contact' => array($contact2),
+ ),
+ //Case 4: Find all contacts in regular group OR smart group
+ array(
+ 'form_value' => array('group' => array('IN' => array($regularGroup['id'], $smartGroup['id']))),
+ 'expected_count' => 3,
+ 'operator' => 'OR',
+ 'expected_contact' => array($contact1, $contact2, $contact3),
+ ),
+ );
+ foreach ($useCases as $case) {
+ $query = new CRM_Contact_BAO_Query(
+ CRM_Contact_BAO_Query::convertFormValues($case['form_value']),
+ NULL, NULL,
+ FALSE, FALSE, 1,
+ FALSE, TRUE,
+ TRUE, NULL,
+ $case['operator']
+ );
+ list($select, $from, $where, $having) = $query->query();
+ $groupContacts = CRM_Core_DAO::executeQuery("SELECT DISTINCT contact_a.id $from $where")->fetchAll();
+ foreach ($groupContacts as $key => $value) {
+ $groupContacts[$key] = $value['id'];
+ }
+ $this->assertEquals($case['expected_count'], count($groupContacts));
+ $this->checkArrayEquals($case['expected_contact'], $groupContacts);
+ }
+ }
+
}