From 9178793e023e584d544c508baec50ec2bd3940ec Mon Sep 17 00:00:00 2001 From: eileen Date: Tue, 10 Sep 2019 10:14:49 +1200 Subject: [PATCH] Fix regression on searching by contact in advanced search --- CRM/Contact/BAO/Query.php | 59 ++++++++++++++++++++-------- tests/phpunit/api/v3/ContactTest.php | 11 ++++++ 2 files changed, 53 insertions(+), 17 deletions(-) diff --git a/CRM/Contact/BAO/Query.php b/CRM/Contact/BAO/Query.php index d62f6279d2..9d5e64a38a 100644 --- a/CRM/Contact/BAO/Query.php +++ b/CRM/Contact/BAO/Query.php @@ -566,7 +566,8 @@ class CRM_Contact_BAO_Query { $this->_whereTables = $this->_tables; $this->selectClause($apiEntity); - $this->_whereClause = $this->whereClause($apiEntity); + $isForcePrimaryOnly = !empty($apiEntity); + $this->_whereClause = $this->whereClause($isForcePrimaryOnly); if (array_key_exists('civicrm_contribution', $this->_whereTables)) { $component = 'contribution'; } @@ -1818,9 +1819,11 @@ class CRM_Contact_BAO_Query { * Get the where clause for a single field. * * @param array $values - * @param string $apiEntity + * @param bool $isForcePrimaryOnly + * + * @throws \CRM_Core_Exception */ - public function whereClauseSingle(&$values, $apiEntity = NULL) { + public function whereClauseSingle(&$values, $isForcePrimaryOnly = FALSE) { if ($this->isARelativeDateField($values[0])) { $this->buildRelativeDateQuery($values); return; @@ -1897,7 +1900,7 @@ class CRM_Contact_BAO_Query { case 'email': case 'email_id': - $this->email($values, $apiEntity); + $this->email($values, $isForcePrimaryOnly); return; case 'phone_numeric': @@ -2066,11 +2069,12 @@ class CRM_Contact_BAO_Query { /** * Given a list of conditions in params generate the required where clause. * - * @param string $apiEntity + * @param bool $isForcePrimaryEmailOnly * * @return string + * @throws \CRM_Core_Exception */ - public function whereClause($apiEntity = NULL) { + public function whereClause($isForcePrimaryEmailOnly = NULL) { $this->_where[0] = []; $this->_qill[0] = []; @@ -2097,7 +2101,7 @@ class CRM_Contact_BAO_Query { ]); } else { - $this->whereClauseSingle($this->_params[$id], $apiEntity); + $this->whereClauseSingle($this->_params[$id], $isForcePrimaryEmailOnly); } } @@ -3569,26 +3573,29 @@ WHERE $smartGroupClause * Where / qill clause for email * * @param array $values - * @param string $apiEntity + * @param string $isForcePrimaryOnly + * + * @throws \CRM_Core_Exception */ - protected function email(&$values, $apiEntity) { + protected function email(&$values, $isForcePrimaryOnly) { list($name, $op, $value, $grouping, $wildcard) = $values; $this->_tables['civicrm_email'] = $this->_whereTables['civicrm_email'] = 1; // CRM-18147: for Contact's GET API, email fieldname got appended with its entity as in {$apiEntiy}_{$name} // so following code is use build whereClause for contact's primart email id - if (!empty($apiEntity)) { - $dataType = 'String'; - if ($name == 'email_id') { - $dataType = 'Integer'; - $name = 'id'; - } - + if (!empty($isForcePrimaryOnly)) { $this->_where[$grouping][] = self::buildClause('civicrm_email.is_primary', '=', 1, 'Integer'); - $this->_where[$grouping][] = self::buildClause("civicrm_email.$name", $op, $value, $dataType); + } + // @todo - this should come from the $this->_fields array + $dbName = $name === 'email_id' ? 'id' : $name; + + if (is_array($value) || $name === 'email_id') { + $this->_qill[$grouping][] = $this->getQillForField($name, $value, $op); + $this->_where[$grouping][] = self::buildClause('civicrm_email.' . $dbName, $op, $value, 'String'); return; } + // Is this ever hit now? Ideally ensure always an array & handle above. $n = trim($value); if ($n) { if (substr($n, 0, 1) == '"' && @@ -7118,4 +7125,22 @@ AND displayRelType.is_active = 1 return $statuses; } + /** + * Get the qill value for the field. + * + * @param $name + * @param array|int|string $value + * @param $op + * + * @return string + */ + protected function getQillForField($name, $value, $op): string { + list($qillop, $qillVal) = CRM_Contact_BAO_Query::buildQillForFieldValue(NULL, $name, $value, $op); + return (string) ts("%1 %2 %3", [ + 1 => ts('Email'), + 2 => $qillop, + 3 => $qillVal, + ]); + } + } diff --git a/tests/phpunit/api/v3/ContactTest.php b/tests/phpunit/api/v3/ContactTest.php index 146d5abad7..3883c0ecee 100644 --- a/tests/phpunit/api/v3/ContactTest.php +++ b/tests/phpunit/api/v3/ContactTest.php @@ -938,6 +938,17 @@ class api_v3_ContactTest extends CiviUnitTestCase { $this->callAPISuccess($this->_entity, 'delete', ['id' => $c2['id']]); } + /** + * Test the like operator works for Contact.get + * + * @throws \CRM_Core_Exception + */ + public function testGetEmailLike() { + $this->individualCreate(); + $this->callAPISuccessGetCount('Contact', ['email' => ['LIKE' => 'an%']], 1); + $this->callAPISuccessGetCount('Contact', ['email' => ['LIKE' => 'ab%']], 0); + } + /** * Test that we can retrieve contacts using array syntax. * -- 2.25.1