Skip to content

Commit

Permalink
dev/core#692: Unable to use url search arguments in 'Advanced Search'…
Browse files Browse the repository at this point in the history
… using force=1
  • Loading branch information
monishdeb committed Feb 27, 2019
1 parent c4512f9 commit b88644b
Show file tree
Hide file tree
Showing 3 changed files with 205 additions and 63 deletions.
35 changes: 29 additions & 6 deletions CRM/Contact/Form/Search.php
Original file line number Diff line number Diff line change
Expand Up @@ -526,18 +526,14 @@ public function preProcess() {
* we allow the controller to set force/reset externally, useful when we are being
* driven by the wizard framework
*/

$this->_reset = CRM_Utils_Request::retrieve('reset', 'Boolean');

$this->_force = CRM_Utils_Request::retrieve('force', 'Boolean');
$this->_groupID = CRM_Utils_Request::retrieve('gid', 'Positive', $this);
$this->_amtgID = CRM_Utils_Request::retrieve('amtgID', 'Positive', $this);
$this->_ssID = CRM_Utils_Request::retrieve('ssID', 'Positive', $this);
$this->_sortByCharacter = CRM_Utils_Request::retrieve('sortByCharacter', 'String', $this);
$this->_ufGroupID = CRM_Utils_Request::retrieve('id', 'Positive', $this);
$this->_componentMode = CRM_Utils_Request::retrieve('component_mode', 'Positive', $this, FALSE, CRM_Contact_BAO_Query::MODE_CONTACTS, $_REQUEST);
$this->_operator = CRM_Utils_Request::retrieve('operator', 'String', $this, FALSE, CRM_Contact_BAO_Query::SEARCH_OPERATOR_AND, 'REQUEST');

$this->loadStandardSearchOptionsFromUrl();
/**
* set the button names
*/
Expand All @@ -555,7 +551,6 @@ public function preProcess() {
}

// assign context to drive the template display, make sure context is valid
$this->_context = CRM_Utils_Request::retrieve('context', 'Alphanumeric', $this, FALSE, 'search');
if (!CRM_Utils_Array::value($this->_context, self::validContext())) {
$this->_context = 'search';
}
Expand Down Expand Up @@ -753,6 +748,32 @@ public function preProcess() {
$controller->moveFromSessionToTemplate();
}

/**
* Responsible to set search params found as url arguments
*/
public static function setSearchParamFromUrl(&$form) {
if (!CRM_Utils_Request::retrieve('force', 'Boolean', $form, FALSE) && empty($form->_ssID)) {
return;
}

$searchFields = array_merge(
CRM_Utils_Array::collect('data_type', CRM_Contact_Form_Search_Criteria::getBasicSearchFields()),
CRM_Utils_Array::collect('data_type', CRM_Contact_Form_Search_Criteria::getDemographicsSearchFields()),
CRM_Utils_Array::collect('data_type', CRM_Contact_Form_Search_Criteria::getLocationSearchFields()),
CRM_Utils_Array::collect('data_type', CRM_Contact_Form_Search_Criteria::getChangeLogSearchFields()),
CRM_Utils_Array::collect('data_type', CRM_Contact_Form_Search_Criteria::getCustomSearchFields())
);
foreach ($searchFields as $name => $type) {
if ($value = CRM_Utils_Request::retrieve($name, $type)) {
$form->_formValues[$name] = $value;
}
}

$form->_params = CRM_Contact_BAO_Query::convertFormValues($form->_formValues);
$form->set('formValues', $form->_formValues);
$form->set('queryParams', $form->_params);
}

/**
* @return array
*/
Expand Down Expand Up @@ -808,6 +829,8 @@ public function postProcess() {
unset($this->_formValues['deleted_contacts']);
}

$this->loadSearchParamsFromUrl();

$this->set('type', $this->_action);
$this->set('formValues', $this->_formValues);
$this->set('queryParams', $this->_params);
Expand Down
197 changes: 140 additions & 57 deletions CRM/Contact/Form/Search/Criteria.php
Original file line number Diff line number Diff line change
Expand Up @@ -259,68 +259,156 @@ public static function basic(&$form) {
* @param CRM_Core_Form $form
*/
protected static function setBasicSearchFields($form) {
$userFramework = CRM_Core_Config::singleton()->userFramework;
$form->assign('basicSearchFields', self::getBasicSearchFields());
}

$form->assign('basicSearchFields', [
'sort_name' => ['name' => 'sort_name'],
'email' => ['name' => 'email'],
'contact_type' => ['name' => 'contact_type'],
/**
* Return list of basic contact fields that can be displayed for the basic search section.
*
* @param array
*/
public static function getBasicSearchFields() {
return [
'sort_name' => ['name' => 'sort_name', 'data_type' => 'String'],
'email' => ['name' => 'email', 'data_type' => 'String'],
'email_on_hold' => ['name' => 'email_on_hold', 'data_type' => 'CommaSeparatedIntegers'],
'contact_type' => ['name' => 'contact_type', 'data_type' => 'String'],
'group' => [
'name' => 'group',
'template' => 'CRM/Contact/Form/Search/Criteria/Fields/group.tpl',
'data_type' => 'CommaSeparatedIntegers',
],
'contact_tags' => ['name' => 'contact_tags'],
'tag_types_text' => ['name' => 'tag_types_text'],
'contact_tags' => ['name' => 'contact_tags', 'data_type' => 'CommaSeparatedIntegers'],
'tag_types_text' => ['name' => 'tag_types_text', 'data_type' => 'String'],
'tag_search' => [
'name' => 'tag_search',
'help' => ['id' => 'id-all-tags'],
'data_type' => 'String',
],
'tag_set' => [
'name' => 'tag_set',
'is_custom' => TRUE,
'template' => 'CRM/Contact/Form/Search/Criteria/Fields/tag_set.tpl',
'data_type' => 'CommaSeparatedIntegers',
],
'all_tag_types' => [
'name' => 'all_tag_types',
'class' => 'search-field__span-3 search-field__checkbox',
'help' => ['id' => 'id-all-tag-types']
'help' => ['id' => 'id-all-tag-types'],
'data_type' => 'String',
],
'phone_numeric' => [
'name' => 'phone_numeric',
'description' => ts('Punctuation and spaces are ignored.'),
'data_type' => 'String',
],
'phone_location_type_id' => ['name' => 'phone_location_type_id'],
'phone_phone_type_id' => ['name' => 'phone_phone_type_id'],
'phone_location_type_id' => ['name' => 'phone_location_type_id', 'data_type' => 'Integer'],
'phone_phone_type_id' => ['name' => 'phone_phone_type_id', 'data_type' => 'Integer'],
'privacy_toggle' => [
'name' => 'privacy_toggle',
'class' => 'search-field__span-2',
'template' => 'CRM/Contact/Form/Search/Criteria/Fields/privacy_toggle.tpl',
'data_type' => 'Integer',
],
'preferred_communication_method' => [
'name' => 'preferred_communication_method',
'template' => 'CRM/Contact/Form/Search/Criteria/Fields/preferred_communication_method.tpl',
'data_type' => 'String',
],
'contact_source' => [
'name' => 'contact_source',
'help' => ['id' => 'id-source', 'file' => 'CRM/Contact/Form/Contact'],
'data_type' => 'String',
],
'job_title' => ['name' => 'job_title'],
'preferred_language' => ['name' => 'preferred_language'],
'job_title' => ['name' => 'job_title', 'data_type' => 'String'],
'preferred_language' => ['name' => 'preferred_language', 'data_type' => 'String'],
'contact_id' => [
'name' => 'contact_id',
'help' => ['id' => 'id-contact-id', 'file' => 'CRM/Contact/Form/Contact'],
'data_type' => 'Integer',
],
'external_identifier' => [
'name' => 'external_identifier',
'help' => ['id' => 'id-external-id', 'file' => 'CRM/Contact/Form/Contact'],
'data_type' => 'String',
],
'uf_user' => [
'name' => 'uf_user',
'description' => ts('Does the contact have a %1 Account?', [$userFramework]),
'description' => ts('Does the contact have a %1 Account?', [CRM_Core_Config::singleton()->userFramework]),
'data_type' => 'Positive',
],
]);
];
}

/**
* Return list of location fields that can be displayed for the Address search section.
*
* @param array
*/
public static function getLocationSearchFields() {
return array(
'street_address' => ['title' => ts('Street Address'), 'data_type' => 'String'],
'supplemental_address_1' => ['title' => ts('Supplemental Address 1'), 'data_type' => 'String'],
'supplemental_address_2' => ['title' => ts('Supplemental Address 2'), 'data_type' => 'String'],
'supplemental_address_3' => ['title' => ts('Supplemental Address 3'), 'data_type' => 'String'],
'city' => ['title' => ts('City'), 'data_type' => 'String'],
'postal_code' => ['title' => ts('Postal Code'), 'data_type' => 'String'],
'country' => ['title' => ts('Country'), 'data_type' => 'Integer', 'select' => 'country'],
'state_province' => ['title' => ts('State/Province'), 'data_type' => 'Integer', 'select' => 'stateProvince'],
'county' => ['title' => ts('County'), 'data_type' => 'Integer', 'select' => 'county'],
'address_name' => ['title' => ts('Address Name'), 'data_type' => 'String'],
'street_number' => ['title' => ts('Street Number'), 'data_type' => 'String'],
'street_name' => ['title' => ts('Street Name'), 'data_type' => 'String'],
'street_unit' => ['title' => ts('Apt/Unit/Suite'), 'data_type' => 'String'],
);
}

/**
* Return list of demographic fields that can be displayed for the Demographics search section.
*
* @param array
*/
public static function getDemographicsSearchFields() {
return [
'gender_id' => ['title' => ts('Gender'), 'data_type' => 'String'],
'age_low' => ['title' => ts('Min Age'), 'data_type' => 'String'],
'age_high' => ['title' => ts('Max Age'), 'data_type' => 'String'],
'birth_date' => ['data_type' => 'String'],
'deceased_date' => ['data_type' => 'String'],
'is_deceased' => ['title' => ts('Deceased'), 'data_type' => 'Positive'],
];
}

public static function getChangeLogSearchFields() {
return [
'changed_by' => ['title' => ts('Modified By'), 'data_type' => 'String'],
'log_date' => ['title' => NULL, 'data_type' => 'Positive'],
'log_date_relative' => ['data_type' => 'String'],
];
}

/**
* Return list of custom fields that can be displayed for the Custom Fields search section.
*
* @param array
*/
public static function getCustomSearchFields() {
$extends = array_merge(array('Contact', 'Individual', 'Household', 'Organization', 'Address'),
CRM_Contact_BAO_ContactType::subTypes()
);
$groupDetails = CRM_Core_BAO_CustomGroup::getGroupDetail(NULL, TRUE,
$extends
);

$customFields = [];
foreach ($groupDetails as $key => $group) {
foreach ($group['fields'] as $field) {
$customFields['custom_' . $field['id']] = ['data_type' => $field['data_type']];
}
}

return $customFields;
}

/**
* @param CRM_Core_Form $form
Expand All @@ -341,28 +429,19 @@ public static function location(&$form) {
'address_options', TRUE, NULL, TRUE
);

$attributes = CRM_Core_DAO::getAttribute('CRM_Core_DAO_Address');

$elements = array(
'street_address' => array(ts('Street Address'), $attributes['street_address'], NULL, NULL),
'supplemental_address_1' => array(ts('Supplemental Address 1'), $attributes['supplemental_address_1'], NULL, NULL),
'supplemental_address_2' => array(ts('Supplemental Address 2'), $attributes['supplemental_address_2'], NULL, NULL),
'supplemental_address_3' => array(ts('Supplemental Address 3'), $attributes['supplemental_address_3'], NULL, NULL),
'city' => array(ts('City'), $attributes['city'], NULL, NULL),
'postal_code' => array(ts('Postal Code'), $attributes['postal_code'], NULL, NULL),
'country' => array(ts('Country'), $attributes['country_id'], 'country', FALSE),
'state_province' => array(ts('State/Province'), $attributes['state_province_id'], 'stateProvince', TRUE),
'county' => array(ts('County'), $attributes['county_id'], 'county', TRUE),
'address_name' => array(ts('Address Name'), $attributes['address_name'], NULL, NULL),
'street_number' => array(ts('Street Number'), $attributes['street_number'], NULL, NULL),
'street_name' => array(ts('Street Name'), $attributes['street_name'], NULL, NULL),
'street_unit' => array(ts('Apt/Unit/Suite'), $attributes['street_unit'], NULL, NULL),
);

$parseStreetAddress = CRM_Utils_Array::value('street_address_parsing', $addressOptions, 0);
$form->assign('parseStreetAddress', $parseStreetAddress);
foreach ($elements as $name => $v) {
list($title, $attributes, $select, $multiSelect) = $v;

$addressAttributes = CRM_Core_DAO::getAttribute('CRM_Core_DAO_Address');
foreach (self::getLocationSearchFields() as $name => $v) {
if (in_array($name, ['state_province', 'country'])) {
$attributes = $addressAttributes[$name . '_id'];
}
else {
$attributes = $addressAttributes[$name];
}
$title = $v['title'];
$select = CRM_Utils_Array::value('select', $v);

if (in_array($name,
array('street_number', 'street_name', 'street_unit')
Expand All @@ -387,7 +466,7 @@ public static function location(&$form) {
$selectElements = array('' => ts('- any -')) + CRM_Core_PseudoConstant::$select();
$element = $form->add('select', $name, $title, $selectElements, FALSE, array('class' => 'crm-select2'));
}
if ($multiSelect) {
if (in_array($name, ['state_province', 'county'])) {
$element->setMultiple(TRUE);
}
}
Expand Down Expand Up @@ -498,29 +577,33 @@ public static function relationship(&$form) {
*/
public static function demographics(&$form) {
$form->add('hidden', 'hidden_demographics', 1);
// radio button for gender
$genderOptions = array();
$gender = CRM_Core_PseudoConstant::get('CRM_Contact_DAO_Contact', 'gender_id');
foreach ($gender as $key => $var) {
$genderOptions[$key] = $form->createElement('radio', NULL,
ts('Gender'), $var, $key,
array('id' => "civicrm_gender_{$var}_{$key}")
);
}
$form->addGroup($genderOptions, 'gender_id', ts('Gender'))->setAttribute('allowClear', TRUE);

$form->add('text', 'age_low', ts('Min Age'), array('size' => 6));
$form->addRule('age_low', ts('Please enter a positive integer'), 'positiveInteger');
$form->add('text', 'age_high', ts('Max Age'), array('size' => 6));
$form->addRule('age_high', ts('Please enter a positive integer'), 'positiveInteger');
$form->addDate('age_asof_date', ts('Age as of Date'), FALSE, array('formatType' => 'searchDate'));

CRM_Core_Form_Date::buildDateRange($form, 'birth_date', 1, '_low', '_high', ts('From'), FALSE, FALSE, 'birth');

CRM_Core_Form_Date::buildDateRange($form, 'deceased_date', 1, '_low', '_high', ts('From'), FALSE, FALSE, 'birth');

// radio button for is_deceased
$form->addYesNo('is_deceased', ts('Deceased'), TRUE);
foreach (self::getDemographicsSearchFields() as $name => $attributes) {
if ($name == 'gender_id') {
// radio button for gender
$genderOptions = array();
$gender = CRM_Core_PseudoConstant::get('CRM_Contact_DAO_Contact', 'gender_id');
foreach ($gender as $key => $var) {
$genderOptions[$key] = $form->createElement('radio', NULL,
ts('Gender'), $var, $key,
array('id' => "civicrm_gender_{$var}_{$key}")
);
}
$form->addGroup($genderOptions, 'gender_id', $attributes['title'])->setAttribute('allowClear', TRUE);
}
elseif (strstr($name, 'age_')) {
$form->add('text', $name, $attributes['title'], array('size' => 6));
$form->addRule($name, ts('Please enter a positive integer'), 'positiveInteger');
$form->addDate('age_asof_date', ts('Age as of Date'), FALSE, array('formatType' => 'searchDate'));
}
elseif (in_array($name, ['birth_date', 'deceased_date'])) {
CRM_Core_Form_Date::buildDateRange($form, $name, 1, '_low', '_high', ts('From'), FALSE, FALSE, 'birth');
}
elseif ($name == 'is_deceased') {
// radio button for is_deceased
$form->addYesNo($name, $attributes['title'], TRUE);
}
}
}

/**
Expand Down
36 changes: 36 additions & 0 deletions CRM/Core/Form/Search.php
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,13 @@ class CRM_Core_Form_Search extends CRM_Core_Form {
*/
protected $entityReferenceFields = array();

/**
* Indicates the Civi component overriden by respective search classes
*
* @var string
*/
protected $_component;

/**
* Builds the list of tasks or actions that a searcher can perform on a result set.
*
Expand Down Expand Up @@ -336,6 +343,35 @@ protected function loadStandardSearchOptionsFromUrl() {
$this->assign("context", $this->_context);
}

/**
* This function call setSearchParamFromUrl() of respective component's Search form and
* is responsible to set search params found as url arguments
*/
protected function loadSearchParamsFromUrl() {
if (!$this->_force && (!empty($_POST) || !empty($form->_ssID))) {
return;
}

$enabledComponents = CRM_Core_Component::getEnabledComponents();
if (!$this->_component) {
if (method_exists('CRM_Contact_Form_Search', 'setSearchParamFromUrl')) {
CRM_Contact_Form_Search::setSearchParamFromUrl($this);
}
foreach ($enabledComponents as $component) {
$searchClass = $component->namespace . '_Form_Search';
if (method_exists($searchClass, 'setSearchParamFromUrl')) {
$searchClass::setSearchParamFromUrl($this);
}
}
}
elseif (array_key_exists($this->_component, $enabledComponents)) {
$searchClass = $enabledComponents[$this->_component]->namespace . '_Form_Search';
if (method_exists($searchClass, 'setSearchParamFromUrl')) {
$searchClass::setSearchParamFromUrl($this);
}
}
}

/**
* Get user submitted values.
*
Expand Down

0 comments on commit b88644b

Please sign in to comment.