Skip to content

Commit

Permalink
Merge pull request civicrm#9772 from jitendrapurohit/CRM-4287fix
Browse files Browse the repository at this point in the history
CRM:4287 - add searchPrimaryDetailsOnly setting
  • Loading branch information
colemanw authored Mar 8, 2017
2 parents c469942 + 06638f5 commit c9b8a4f
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 12 deletions.
1 change: 1 addition & 0 deletions CRM/Admin/Form/Setting/Search.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class CRM_Admin_Form_Setting_Search extends CRM_Admin_Form_Setting {
'includeOrderByClause' => CRM_Core_BAO_Setting::SEARCH_PREFERENCES_NAME,
'smartGroupCacheTimeout' => CRM_Core_BAO_Setting::SEARCH_PREFERENCES_NAME,
'defaultSearchProfileID' => CRM_Core_BAO_Setting::SEARCH_PREFERENCES_NAME,
'searchPrimaryDetailsOnly' => CRM_Core_BAO_Setting::SEARCH_PREFERENCES_NAME,
);

/**
Expand Down
27 changes: 15 additions & 12 deletions CRM/Contact/BAO/Query.php
Original file line number Diff line number Diff line change
Expand Up @@ -514,7 +514,7 @@ public function initialize($apiEntity = NULL) {
CRM_Financial_BAO_FinancialType::buildPermissionedClause($this->_whereClause, $component);
}

$this->_fromClause = self::fromClause($this->_tables, NULL, NULL, $this->_primaryLocation, $this->_mode);
$this->_fromClause = self::fromClause($this->_tables, NULL, NULL, $this->_primaryLocation, $this->_mode, $apiEntity);
$this->_simpleFromClause = self::fromClause($this->_whereTables, NULL, NULL, $this->_primaryLocation, $this->_mode);

$this->openedSearchPanes(TRUE);
Expand Down Expand Up @@ -2509,11 +2509,12 @@ public static function getWhereClause($params, $fields, &$tables, &$whereTables,
*
* @param bool $primaryLocation
* @param int $mode
* @param string|NULL $apiEntity
*
* @return string
* the from clause
*/
public static function fromClause(&$tables, $inner = NULL, $right = NULL, $primaryLocation = TRUE, $mode = 1) {
public static function fromClause(&$tables, $inner = NULL, $right = NULL, $primaryLocation = TRUE, $mode = 1, $apiEntity = NULL) {

$from = ' FROM civicrm_contact contact_a';
if (empty($tables)) {
Expand Down Expand Up @@ -2604,27 +2605,29 @@ public static function fromClause(&$tables, $inner = NULL, $right = NULL, $prima
}
continue;
}
$searchPrimary = '';
if (Civi::settings()->get('searchPrimaryDetailsOnly') || $apiEntity) {
$searchPrimary = "AND {$name}.is_primary = 1";
}
switch ($name) {
case 'civicrm_address':
if ($primaryLocation) {
$from .= " $side JOIN civicrm_address ON ( contact_a.id = civicrm_address.contact_id AND civicrm_address.is_primary = 1 )";
}
else {
//CRM-14263 further handling of address joins further down...
$from .= " $side JOIN civicrm_address ON ( contact_a.id = civicrm_address.contact_id ) ";
//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} )";
continue;

case 'civicrm_phone':
$from .= " $side JOIN civicrm_phone ON (contact_a.id = civicrm_phone.contact_id AND civicrm_phone.is_primary = 1) ";
$from .= " $side JOIN civicrm_phone ON (contact_a.id = civicrm_phone.contact_id {$searchPrimary}) ";
continue;

case 'civicrm_email':
$from .= " $side JOIN civicrm_email ON (contact_a.id = civicrm_email.contact_id AND civicrm_email.is_primary = 1) ";
$from .= " $side JOIN civicrm_email ON (contact_a.id = civicrm_email.contact_id {$searchPrimary})";
continue;

case 'civicrm_im':
$from .= " $side JOIN civicrm_im ON (contact_a.id = civicrm_im.contact_id AND civicrm_im.is_primary = 1) ";
$from .= " $side JOIN civicrm_im ON (contact_a.id = civicrm_im.contact_id {$searchPrimary}) ";
continue;

case 'im_provider':
Expand All @@ -2634,7 +2637,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 AND civicrm_openid.is_primary = 1 )";
$from .= " $side JOIN civicrm_openid ON ( civicrm_openid.contact_id = contact_a.id {$searchPrimary} )";
continue;

case 'civicrm_worldregion':
Expand Down
14 changes: 14 additions & 0 deletions settings/Search.setting.php
Original file line number Diff line number Diff line change
Expand Up @@ -197,4 +197,18 @@
'description' => 'If set, this will be the default profile used for contact search.',
'help_text' => NULL,
),
'searchPrimaryDetailsOnly' => array(
'group_name' => 'Search Preferences',
'group' => 'Search Preferences',
'name' => 'searchPrimaryDetailsOnly',
'type' => 'Boolean',
'quick_form_type' => 'YesNo',
'default' => 1,
'add' => '4.7',
'title' => 'Search Primary Details Only',
'is_domain' => 1,
'is_contact' => 0,
'description' => 'If enabled, only primary details (eg contact\'s primary email, phone, etc) will be included in Basic and Advanced Search results. Disabling this feature will allow users to match contacts using any email, phone etc detail.',
'help_text' => NULL,
),
);
6 changes: 6 additions & 0 deletions templates/CRM/Admin/Form/Setting/Search.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@
<td>{$form.includeEmailInName.html}<br />
<span class="description">{ts}If enabled, email addresses are automatically included when users search by Name. Disabling this feature will speed up search significantly for larger databases, but users will need to use the Email search fields (from Advanced Search, Search Builder, or Profiles) to find contacts by email address.{/ts}</span></td>
</tr>
<tr class="crm-search-setting-form-block-searchPrimaryDetailsOnly">
<td class="label">{$form.searchPrimaryDetailsOnly.label}</td>
<td>{$form.searchPrimaryDetailsOnly.html}<br />
<span class="description">{ts}If enabled, only primary details (eg contact's primary email, phone, etc) will be included in Basic and Advanced Search results. Disabling this feature will allow users to match contacts using any email, phone etc detail.{/ts}</span>
</td>
</tr>
<tr class="crm-search-setting-form-block-includeNickNameInName">
<td class="label">{$form.includeNickNameInName.label}</td>
<td>{$form.includeNickNameInName.html}<br />
Expand Down
56 changes: 56 additions & 0 deletions tests/phpunit/CRM/Contact/BAO/QueryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,62 @@ public function testSearchProfileHomeCityNoResultsCRM14263() {
}
}

/**
* Test searchPrimaryDetailsOnly setting.
*/
public function testSearchPrimaryLocTypes() {
$contactID = $this->individualCreate();
$params = array(
'contact_id' => $contactID,
'email' => 'primary@example.com',
'is_primary' => 1,
);
$this->callAPISuccess('email', 'create', $params);

unset($params['is_primary']);
$params['email'] = 'secondary@team.com';
$this->callAPISuccess('email', 'create', $params);

foreach (array(0, 1) as $searchPrimary) {
Civi::settings()->set('searchPrimaryDetailsOnly', $searchPrimary);

$params = array(
0 => array(
0 => 'email',
1 => 'LIKE',
2 => 'secondary@example.com',
3 => 0,
4 => 1,
),
);
$returnProperties = array(
'contact_type' => 1,
'contact_sub_type' => 1,
'sort_name' => 1,
);

$queryObj = new CRM_Contact_BAO_Query($params, $returnProperties);
$resultDAO = $queryObj->searchQuery(0, 0, NULL,
FALSE, FALSE,
FALSE, FALSE,
FALSE);

if ($searchPrimary) {
$this->assertEquals($resultDAO->N, 0);
}
else {
//Assert secondary email gets included in search results.
while ($resultDAO->fetch()) {
$this->assertEquals('secondary@example.com', $resultDAO->email);
}
}

// API should always return primary email.
$result = $this->callAPISuccess('Contact', 'get', array('contact_id' => $contactID));
$this->assertEquals('primary@example.com', $result['values'][$contactID]['email']);
}
}

/**
* CRM-14263 search builder failure with search profile & address in criteria
* We are retrieving primary here - checking the actual sql seems super prescriptive - but since the massive query object has
Expand Down

0 comments on commit c9b8a4f

Please sign in to comment.