From dab118091de2b4c43625d67143934cc554b2f465 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 | 58 +++++++++++++++++++--------- tests/phpunit/api/v3/ContactTest.php | 12 ++++++ 2 files changed, 52 insertions(+), 18 deletions(-) diff --git a/CRM/Contact/BAO/Query.php b/CRM/Contact/BAO/Query.php index d62f6279d24c..c92eb209a77d 100644 --- a/CRM/Contact/BAO/Query.php +++ b/CRM/Contact/BAO/Query.php @@ -566,7 +566,8 @@ public function initialize($apiEntity = NULL) { $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 @@ public static function fixWhereValues($id, &$values, $wildcard = 0, $useEquals = * 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 @@ public function whereClauseSingle(&$values, $apiEntity = NULL) { case 'email': case 'email_id': - $this->email($values, $apiEntity); + $this->email($values, $isForcePrimaryOnly); return; case 'phone_numeric': @@ -2066,11 +2069,12 @@ public function whereClauseSingle(&$values, $apiEntity = NULL) { /** * 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 @@ public function whereClause($apiEntity = NULL) { ]); } else { - $this->whereClauseSingle($this->_params[$id], $apiEntity); + $this->whereClauseSingle($this->_params[$id], $isForcePrimaryEmailOnly); } } @@ -3569,26 +3573,26 @@ public function greetings(&$values) { * 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); - return; } + if (is_array($value)) { + $this->_qill[$grouping][] = $this->getQillForField($name, $value, $op); + $this->_where[$grouping][] = self::buildClause('civicrm_email.email', $op, $value, 'String'); + return; + } + // Is this ever hit now? Ideally ensure alwasy an array & handled above. $n = trim($value); if ($n) { if (substr($n, 0, 1) == '"' && @@ -7118,4 +7122,22 @@ protected function getSelectedGroupStatuses($grouping) { return $statuses; } + /** + * Get the qill value for the field. + * + * @param $name + * @param array $value + * @param $op + * + * @return string + */ + protected function getQillForField($name, array $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 146d5abad7e0..a6b250f775de 100644 --- a/tests/phpunit/api/v3/ContactTest.php +++ b/tests/phpunit/api/v3/ContactTest.php @@ -938,6 +938,18 @@ public function testGetSort() { $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. *