Skip to content

Commit

Permalink
Merge pull request #12249 from hosseinamin/master
Browse files Browse the repository at this point in the history
fix of issue dev/core#127 (at gitlab), incorrect cache records for smart groups
  • Loading branch information
seamuslee001 authored Jun 4, 2018
2 parents 6a8366e + 2bedfb3 commit 0d4655e
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 19 deletions.
51 changes: 32 additions & 19 deletions CRM/Contact/BAO/Query.php
Original file line number Diff line number Diff line change
Expand Up @@ -5779,13 +5779,26 @@ public function getOperator() {
* @param $having
*/
public function filterRelatedContacts(&$from, &$where, &$having) {
static $_rTypeProcessed = NULL;
static $_rTypeFrom = NULL;
static $_rTypeWhere = NULL;

if (!$_rTypeProcessed) {
$_rTypeProcessed = TRUE;

if (!isset(Civi::$statics[__CLASS__]['related_contacts_filter'])) {
Civi::$statics[__CLASS__]['related_contacts_filter'] = array();
}
$_rTempCache =& Civi::$statics[__CLASS__]['related_contacts_filter'];
// skip if filter has already applied
foreach ($_rTempCache as $acache) {
if (strpos($from, $acache['from']) !== FALSE) {
$having = NULL;
return;
}
}
$arg_sig = sha1("$from $where $having");
if (isset($_rTempCache[$arg_sig])) {
$cache = $_rTempCache[$arg_sig];
}
else {
$cache = array(
"from" => "",
"where" => "",
);
// create temp table with contact ids
$tableName = CRM_Core_DAO::createTempTableName('civicrm_transform', TRUE);
$sql = "CREATE TEMPORARY TABLE $tableName ( contact_id int primary key) ENGINE=HEAP";
Expand All @@ -5805,11 +5818,11 @@ public function filterRelatedContacts(&$from, &$where, &$having) {

if (is_numeric($this->_displayRelationshipType)) {
$relationshipTypeLabel = $rTypes[$this->_displayRelationshipType]['label_a_b'];
$_rTypeFrom = "
$cache['from'] = "
INNER JOIN civicrm_relationship displayRelType ON ( displayRelType.contact_id_a = contact_a.id OR displayRelType.contact_id_b = contact_a.id )
INNER JOIN $tableName transform_temp ON ( transform_temp.contact_id = displayRelType.contact_id_a OR transform_temp.contact_id = displayRelType.contact_id_b )
";
$_rTypeWhere = "
$cache['where'] = "
WHERE displayRelType.relationship_type_id = {$this->_displayRelationshipType}
AND displayRelType.is_active = 1
";
Expand All @@ -5818,36 +5831,36 @@ public function filterRelatedContacts(&$from, &$where, &$having) {
list($relType, $dirOne, $dirTwo) = explode('_', $this->_displayRelationshipType);
if ($dirOne == 'a') {
$relationshipTypeLabel = $rTypes[$relType]['label_a_b'];
$_rTypeFrom .= "
$cache['from'] .= "
INNER JOIN civicrm_relationship displayRelType ON ( displayRelType.contact_id_a = contact_a.id )
INNER JOIN $tableName transform_temp ON ( transform_temp.contact_id = displayRelType.contact_id_b )
";
}
else {
$relationshipTypeLabel = $rTypes[$relType]['label_b_a'];
$_rTypeFrom .= "
$cache['from'] .= "
INNER JOIN civicrm_relationship displayRelType ON ( displayRelType.contact_id_b = contact_a.id )
INNER JOIN $tableName transform_temp ON ( transform_temp.contact_id = displayRelType.contact_id_a )
";
}
$_rTypeWhere = "
$cache['where'] = "
WHERE displayRelType.relationship_type_id = $relType
AND displayRelType.is_active = 1
";
}
$this->_qill[0][] = $qillMessage . "'" . $relationshipTypeLabel . "'";
$_rTempCache[$arg_sig] = $cache;
}

if (!empty($this->_permissionWhereClause)) {
$_rTypeWhere .= "AND $this->_permissionWhereClause";
}

if (strpos($from, $_rTypeFrom) === FALSE) {
if (strpos($from, $cache['from']) === FALSE) {
// lets replace all the INNER JOIN's in the $from so we dont exclude other data
// this happens when we have an event_type in the quert (CRM-7969)
$from = str_replace("INNER JOIN", "LEFT JOIN", $from);
$from .= $_rTypeFrom;
$where = $_rTypeWhere;
$from .= $cache['from'];
$where = $cache['where'];
if (!empty($this->_permissionWhereClause)) {
$where .= "AND $this->_permissionWhereClause";
}
}

$having = NULL;
Expand Down
4 changes: 4 additions & 0 deletions contributor-key.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1354,3 +1354,7 @@
name : Yashodha Chaku
organization: CiviDesk
jira : yashodha

- github : hosseinamin
name : Hossein Amin
jira : hosseinamin
51 changes: 51 additions & 0 deletions tests/phpunit/api/v3/ContactTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3785,4 +3785,55 @@ public function testContactGetUnique() {
$this->assertEquals(array('external_identifier'), $result['values']['UI_external_identifier']);
}

public function testSmartGroupsForRelatedContacts() {
$rtype1 = $this->callAPISuccess('relationship_type', 'create', array(
"name_a_b" => uniqid() . " Child of",
"name_b_a" => uniqid() . " Parent of",
));
$rtype2 = $this->callAPISuccess('relationship_type', 'create', array(
"name_a_b" => uniqid() . " Household Member of",
"name_b_a" => uniqid() . " Household Member is",
));
$h1 = $this->householdCreate();
$c1 = $this->individualCreate(array('last_name' => 'Adams'));
$c2 = $this->individualCreate(array('last_name' => 'Adams'));
$this->callAPISuccess('relationship', 'create', array(
'contact_id_a' => $c1,
'contact_id_b' => $c2,
'is_active' => 1,
'relationship_type_id' => $rtype1['id'], // Child of
));
$this->callAPISuccess('relationship', 'create', array(
'contact_id_a' => $c1,
'contact_id_b' => $h1,
'is_active' => 1,
'relationship_type_id' => $rtype2['id'], // Household Member of
));
$this->callAPISuccess('relationship', 'create', array(
'contact_id_a' => $c2,
'contact_id_b' => $h1,
'is_active' => 1,
'relationship_type_id' => $rtype2['id'], // Household Member of
));

$ssParams = array(
'formValues' => array(
'display_relationship_type' => $rtype1['id'] . '_a_b', // Child of
'sort_name' => 'Adams',
),
);
$g1ID = $this->smartGroupCreate($ssParams, array('name' => uniqid(), 'title' => uniqid()));
$ssParams = array(
'formValues' => array(
'display_relationship_type' => $rtype2['id'] . '_a_b', // Household Member of
),
);
$g2ID = $this->smartGroupCreate($ssParams, array('name' => uniqid(), 'title' => uniqid()));
CRM_Contact_BAO_GroupContactCache::loadAll();
$g1Contacts = $this->callAPISuccess('contact', 'get', array('group' => $g1ID));
$g2Contacts = $this->callAPISuccess('contact', 'get', array('group' => $g2ID));
$this->assertTrue($g1Contacts['count'] == 1);
$this->assertTrue($g2Contacts['count'] == 2);
}

}

0 comments on commit 0d4655e

Please sign in to comment.