-
-
Notifications
You must be signed in to change notification settings - Fork 825
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CRM-20855: Disabling "Search Primary Details Only" causes partial CiviMail delivery failure #10915
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -420,17 +420,21 @@ class CRM_Contact_BAO_Query { | |
* @param null $displayRelationshipType | ||
* @param string $operator | ||
* @param string $apiEntity | ||
* | ||
* @return \CRM_Contact_BAO_Query | ||
* @param bool|NULL $primaryLocationOnly | ||
*/ | ||
public function __construct( | ||
$params = NULL, $returnProperties = NULL, $fields = NULL, | ||
$includeContactIds = FALSE, $strict = FALSE, $mode = 1, | ||
$skipPermission = FALSE, $searchDescendentGroups = TRUE, | ||
$smartGroupCache = TRUE, $displayRelationshipType = NULL, | ||
$operator = 'AND', | ||
$apiEntity = NULL | ||
$apiEntity = NULL, | ||
$primaryLocationOnly = NULL | ||
) { | ||
if ($primaryLocationOnly === NULL) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Perhaps this could just be FALSE ie. if it is FALSE then we check the setting & possibly update to TRUE. For TRUE always stay TRUE. I'm on the fence here |
||
$primaryLocationOnly = Civi::settings()->get('searchPrimaryDetailsOnly'); | ||
} | ||
$this->_primaryLocation = $primaryLocationOnly; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It turns out there is already a property for primary only so let's use that. |
||
$this->_params = &$params; | ||
if ($this->_params == NULL) { | ||
$this->_params = array(); | ||
|
@@ -2633,29 +2637,25 @@ public static function fromClause(&$tables, $inner = NULL, $right = NULL, $prima | |
} | ||
continue; | ||
} | ||
$searchPrimary = ''; | ||
if (Civi::settings()->get('searchPrimaryDetailsOnly') || $apiEntity) { | ||
$searchPrimary = "AND {$name}.is_primary = 1"; | ||
} | ||
|
||
$limitToPrimaryClause = $primaryLocation ? "AND {$name}.is_primary = 1" : ''; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this name for the var is closer. Let's always pass in $primaryLocation correctly & not try to derive in this function |
||
|
||
switch ($name) { | ||
case 'civicrm_address': | ||
//CRM-14263 further handling of address joins further down... | ||
if (!$primaryLocation) { | ||
$searchPrimary = ''; | ||
} | ||
$from .= " $side JOIN civicrm_address ON ( contact_a.id = civicrm_address.contact_id {$searchPrimary} )"; | ||
$from .= " $side JOIN civicrm_address ON ( contact_a.id = civicrm_address.contact_id {$limitToPrimaryClause} )"; | ||
continue; | ||
|
||
case 'civicrm_phone': | ||
$from .= " $side JOIN civicrm_phone ON (contact_a.id = civicrm_phone.contact_id {$searchPrimary}) "; | ||
$from .= " $side JOIN civicrm_phone ON (contact_a.id = civicrm_phone.contact_id {$limitToPrimaryClause}) "; | ||
continue; | ||
|
||
case 'civicrm_email': | ||
$from .= " $side JOIN civicrm_email ON (contact_a.id = civicrm_email.contact_id {$searchPrimary})"; | ||
$from .= " $side JOIN civicrm_email ON (contact_a.id = civicrm_email.contact_id {$limitToPrimaryClause})"; | ||
continue; | ||
|
||
case 'civicrm_im': | ||
$from .= " $side JOIN civicrm_im ON (contact_a.id = civicrm_im.contact_id {$searchPrimary}) "; | ||
$from .= " $side JOIN civicrm_im ON (contact_a.id = civicrm_im.contact_id {$limitToPrimaryClause}) "; | ||
continue; | ||
|
||
case 'im_provider': | ||
|
@@ -2665,7 +2665,7 @@ public static function fromClause(&$tables, $inner = NULL, $right = NULL, $prima | |
continue; | ||
|
||
case 'civicrm_openid': | ||
$from .= " $side JOIN civicrm_openid ON ( civicrm_openid.contact_id = contact_a.id {$searchPrimary} )"; | ||
$from .= " $side JOIN civicrm_openid ON ( civicrm_openid.contact_id = contact_a.id {$limitToPrimaryClause} )"; | ||
continue; | ||
|
||
case 'civicrm_worldregion': | ||
|
@@ -4428,6 +4428,7 @@ public static function getQuery($params = NULL, $returnProperties = NULL, $count | |
* The api entity being called. | ||
* This sort-of duplicates $mode in a confusing way. Probably not by design. | ||
* | ||
* @param bool|null $primaryLocationOnly | ||
* @return array | ||
*/ | ||
public static function apiQuery( | ||
|
@@ -4441,7 +4442,8 @@ public static function apiQuery( | |
$count = FALSE, | ||
$skipPermissions = TRUE, | ||
$mode = CRM_Contact_BAO_Query::MODE_CONTACTS, | ||
$apiEntity = NULL | ||
$apiEntity = NULL, | ||
$primaryLocationOnly = NULL | ||
) { | ||
|
||
$query = new CRM_Contact_BAO_Query( | ||
|
@@ -4450,7 +4452,7 @@ public static function apiQuery( | |
$skipPermissions, | ||
TRUE, $smartGroupCache, | ||
NULL, 'AND', | ||
$apiEntity | ||
$apiEntity, $primaryLocationOnly | ||
); | ||
|
||
//this should add a check for view deleted if permissions are enabled | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -570,7 +570,8 @@ function _civicrm_api3_get_using_query_object($entity, $params, $additional_opti | |
$getCount, | ||
$skipPermissions, | ||
$mode, | ||
$entity | ||
$entity, | ||
TRUE | ||
); | ||
|
||
return $entities; | ||
|
@@ -603,7 +604,8 @@ function _civicrm_api3_get_query_object($params, $mode, $entity) { | |
$newParams = CRM_Contact_BAO_Query::convertFormValues($inputParams, 0, FALSE, $entity); | ||
$query = new CRM_Contact_BAO_Query($newParams, $returnProperties, NULL, | ||
FALSE, FALSE, $mode, | ||
empty($params['check_permissions']) | ||
empty($params['check_permissions']), | ||
TRUE, TRUE, NULL, 'AND', 'NULL', TRUE | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. set extras explicitly including SearchPrimary |
||
); | ||
list($select, $from, $where, $having) = $query->query(); | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,27 +16,44 @@ public function testGetTokenDetails() { | |
} | ||
|
||
/** | ||
* Test for replaceGreetingTokens. | ||
* Test getting contacts w/o primary location type | ||
* | ||
* Check for situation described in CRM-19876. | ||
*/ | ||
public function testReplaceGreetingTokens() { | ||
$tokenString = 'First Name: {contact.first_name} Last Name: {contact.last_name} Birth Date: {contact.birth_date} Prefix: {contact.prefix_id} Suffix: {contact.individual_suffix}'; | ||
$contactDetails = array( | ||
array( | ||
2811 => array( | ||
'id' => '2811', | ||
'contact_type' => 'Individual', | ||
'first_name' => 'Morticia', | ||
'last_name' => 'Addams', | ||
'prefix_id' => 2, | ||
), | ||
), | ||
); | ||
$contactId = 2811; | ||
$className = 'CRM_Contact_BAO_Contact'; | ||
$escapeSmarty = TRUE; | ||
CRM_Utils_Token::replaceGreetingTokens($tokenString, $contactDetails, $contactId, $className, $escapeSmarty); | ||
$this->assertEquals($tokenString, 'First Name: Morticia Last Name: Addams Birth Date: Prefix: Ms. Suffix: '); | ||
public function testSearchByPrimaryLocation() { | ||
// Disable searchPrimaryDetailsOnly civi settings so we could test the functionality without it. | ||
Civi::settings()->set('searchPrimaryDetailsOnly', '0'); | ||
|
||
// create a contact with multiple email address and among which one is primary | ||
$contactID = $this->individualCreate(); | ||
$primaryEmail = uniqid() . '@primary.com'; | ||
$this->callAPISuccess('Email', 'create', array( | ||
'contact_id' => $contactID, | ||
'email' => $primaryEmail, | ||
'location_type_id' => 'Other', | ||
'is_primary' => 1, | ||
)); | ||
$this->callAPISuccess('Email', 'create', array( | ||
'contact_id' => $contactID, | ||
'email' => uniqid() . '@galaxy.com', | ||
'location_type_id' => 'Work', | ||
'is_primary' => 0, | ||
)); | ||
$this->callAPISuccess('Email', 'create', array( | ||
'contact_id' => $contactID, | ||
'email' => uniqid() . '@galaxy.com', | ||
'location_type_id' => 'Work', | ||
'is_primary' => 0, | ||
)); | ||
|
||
$contactIDs = array($contactID); | ||
|
||
// when we are fetching contact details ON basis of primary address fields | ||
$contactDetails = CRM_Utils_Token::getTokenDetails($contactIDs); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I removed the one that involves passing in $extraParams because that is a weird funky way of passing stuff in. It is merged into $params & passed on so you don't really know what will wind up where |
||
$this->assertEquals($primaryEmail, $contactDetails[0][$contactID]['email']); | ||
|
||
// restore setting | ||
Civi::settings()->set('searchPrimaryDetailsOnly', '1'); | ||
} | ||
|
||
/** | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's pass in a var that says what we want to do, rather than overload one we don't really understand