From 20306bb83b08050b0ab832836422ab35e69952aa Mon Sep 17 00:00:00 2001 From: eileen Date: Tue, 1 Mar 2016 14:23:44 +1300 Subject: [PATCH] CRM-18125 remove country_id from filter where state_province_id is present The country_id is implcit in the state_province_id, but in the absence of a combined filter including it hurts performance Change-Id: Ic311c4c438002e7390e2c0f7b21059bd26f618f3 --- CRM/Contact/BAO/Query.php | 27 +++++++++++++++++++++++++++ CRM/Contact/Form/Search/Advanced.php | 20 +++++++++++++++++++- 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/CRM/Contact/BAO/Query.php b/CRM/Contact/BAO/Query.php index 7db2bafb47..f7b9fd4fea 100644 --- a/CRM/Contact/BAO/Query.php +++ b/CRM/Contact/BAO/Query.php @@ -1507,6 +1507,8 @@ class CRM_Contact_BAO_Query { return $params; } + self::filterCountryFromValuesIfStateExists($formValues); + foreach ($formValues as $id => $values) { if (self::isAlreadyProcessedForQueryFormat($values)) { @@ -4456,6 +4458,31 @@ civicrm_relationship.is_permission_a_b = 0 return in_array($operator, CRM_Core_DAO::acceptedSQLOperators()); } + /** + * If the state and country are passed remove state. + * + * Country is implicit from the state, but including both results in + * a poor query as there is no combined index on state AND country. + * + * CRM-18125 + * + * @param array $formValues + */ + public static function filterCountryFromValuesIfStateExists(&$formValues) { + if (!empty($formValues['country'])) { + if (isset($formValues['state_province'])) { + // The use of array map sanitises the data by ensuring we are dealing with integers. + $states = implode(', ', array_map('intval', $formValues['state_province'])); + $countryList = CRM_Core_DAO::singleValueQuery( + "SELECT GROUP_CONCAT(country_id) FROM civicrm_state_province WHERE id IN ($states)" + ); + if ($countryList == $formValues['country']) { + unset($formValues['country']); + } + } + } + } + /** * Create and query the db for an contact search. * diff --git a/CRM/Contact/Form/Search/Advanced.php b/CRM/Contact/Form/Search/Advanced.php index aca7d35e79..7c059e41c8 100644 --- a/CRM/Contact/Form/Search/Advanced.php +++ b/CRM/Contact/Form/Search/Advanced.php @@ -381,11 +381,29 @@ class CRM_Contact_Form_Search_Advanced extends CRM_Contact_Form_Search { if (!is_array($defaults)) { $defaults = array(); } - + $this->loadDefaultCountryBasedOnState($defaults); if ($this->_ssID && empty($_POST)) { $defaults = array_merge($defaults, CRM_Contact_BAO_SavedSearch::getFormValues($this->_ssID)); } return $defaults; } + /** + * Set the default country for the form. + * + * For performance reasons country might be removed from the form CRM-18125 + * but we need to include it in our defaults or the state will not be visible. + * + * @param array $defaults + */ + public function loadDefaultCountryBasedOnState(&$defaults) { + if (!empty($defaults['state_province'])) { + $defaults['country'] = CRM_Core_DAO::singleValueQuery( + "SELECT country_id FROM civicrm_state_province + WHERE id = %1", + array(1 => array($defaults['state_province'][0], 'Integer')) + ); + } + } + } -- 2.25.1