From 21b8bcb53165965a178bfc992fe1c68b0af97f23 Mon Sep 17 00:00:00 2001 From: Seamus Lee Date: Thu, 16 Jul 2020 17:06:11 +1000 Subject: [PATCH] Fix trash searching now with the alternate join and add in new test to prove that when someone doesn't have view all contacts but does have access deleted contacts and we are searching in the trash an appropriate where clause is generated --- CRM/Contact/BAO/Query.php | 14 ++++++++-- tests/phpunit/CRM/Contact/SelectorTest.php | 31 ++++++++++++++++++++++ 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/CRM/Contact/BAO/Query.php b/CRM/Contact/BAO/Query.php index 8eb59e32aa..14ad083a4f 100644 --- a/CRM/Contact/BAO/Query.php +++ b/CRM/Contact/BAO/Query.php @@ -5061,8 +5061,18 @@ civicrm_relationship.start_date > {$today} $this->_permissionWhereClause = $permissionClauses[1]; $this->_permissionFromClause = $permissionClauses[0]; - if (!$onlyDeleted && CRM_Core_Permission::check('access deleted contacts')) { - $this->_permissionWhereClause = str_replace(' ( 1 ) ', '(contact_a.is_deleted = 0)', $this->_permissionWhereClause); + if (CRM_Core_Permission::check('access deleted contacts')) { + if (!$onlyDeleted) { + $this->_permissionWhereClause = str_replace('( 1 )', '(contact_a.is_deleted = 0)', $this->_permissionWhereClause); + } + else { + if ($this->_permissionWhereClause === '( 1 )') { + $this->_permissionWhereClause = str_replace('( 1 )', '(contact_a.is_deleted)', $this->_permissionWhereClause); + } + else { + $this->_permissionWhereClause .= " AND (contact_a.is_deleted) "; + } + } } if (isset($this->_tables['civicrm_activity'])) { diff --git a/tests/phpunit/CRM/Contact/SelectorTest.php b/tests/phpunit/CRM/Contact/SelectorTest.php index fd10b18eeb..bb103b9c12 100644 --- a/tests/phpunit/CRM/Contact/SelectorTest.php +++ b/tests/phpunit/CRM/Contact/SelectorTest.php @@ -32,6 +32,12 @@ class CRM_Contact_SelectorTest extends CiviUnitTestCase { * @throws \Exception */ public function testSelectorQuery($dataSet) { + if (!empty($dataSet['limitedPermissions'])) { + CRM_Core_Config::singleton()->userPermissionClass->permissions = [ + 'access CiviCRM', + 'access deleted contacts', + ]; + } $params = CRM_Contact_BAO_Query::convertFormValues($dataSet['form_values'], 0, FALSE, NULL, []); $isDeleted = in_array(['deleted_contacts', '=', 1, 0, 0], $params); foreach ($dataSet['settings'] as $setting) { @@ -90,6 +96,9 @@ class CRM_Contact_SelectorTest extends CiviUnitTestCase { $selector->getQueryObject()->getCachedContacts([$contactID], FALSE); } } + if (!empty($dataSet['limitedPermissions'])) { + $this->cleanUpAfterACLs(); + } } /** @@ -314,6 +323,28 @@ class CRM_Contact_SelectorTest extends CiviUnitTestCase { 2 => "WHERE ( civicrm_email.email LIKE 'mickey@mouseville.com%' AND ( ( ( contact_a.sort_name LIKE 'Mouse%' ) OR ( civicrm_email.email LIKE 'Mouse%' ) ) ) ) AND (contact_a.is_deleted)", ], ], + ], + [ + [ + 'description' => 'Ensure that the Join to the acl contact cache is correct and that if we are searching in deleted contacts appropriate where clause is added', + 'class' => 'CRM_Contact_Selector', + 'settings' => [['name' => 'includeWildCardInName', 'value' => FALSE]], + 'form_values' => ['email' => 'mickey@mouseville.com', 'sort_name' => 'Mouse', 'deleted_contacts' => 1], + 'params' => [], + 'return_properties' => NULL, + 'context' => 'advanced', + 'action' => CRM_Core_Action::ADVANCED, + 'includeContactIds' => NULL, + 'searchDescendentGroups' => FALSE, + 'limitedPermissions' => TRUE, + 'expected_query' => [ + 0 => 'default', + 1 => 'FROM civicrm_contact contact_a LEFT JOIN civicrm_address ON ( contact_a.id = civicrm_address.contact_id AND civicrm_address.is_primary = 1 ) LEFT JOIN civicrm_country ON ( civicrm_address.country_id = civicrm_country.id ) LEFT JOIN civicrm_email ON (contact_a.id = civicrm_email.contact_id AND civicrm_email.is_primary = 1) LEFT JOIN civicrm_phone ON (contact_a.id = civicrm_phone.contact_id AND civicrm_phone.is_primary = 1) LEFT JOIN civicrm_im ON (contact_a.id = civicrm_im.contact_id AND civicrm_im.is_primary = 1) LEFT JOIN civicrm_worldregion ON civicrm_country.region_id = civicrm_worldregion.id INNER JOIN civicrm_acl_contact_cache aclContactCache ON contact_a.id = aclContactCache.contact_id', + 2 => "WHERE ( civicrm_email.email LIKE 'mickey@mouseville.com%' AND ( ( ( contact_a.sort_name LIKE 'Mouse%' ) OR ( civicrm_email.email LIKE 'Mouse%' ) ) ) ) AND aclContactCache.user_id = 0 AND (contact_a.is_deleted)", + ], + ], + ], + [ [ 'description' => 'Use of quotes for exact string', 'use_case_comments' => 'This is something that was in the code but seemingly not working. No UI info on it though!', -- 2.25.1