Commit | Line | Data |
---|---|---|
3efb5b86 CW |
1 | <?php |
2 | /* | |
3 | +--------------------------------------------------------------------+ | |
bc77d7c0 | 4 | | Copyright CiviCRM LLC. All rights reserved. | |
3efb5b86 | 5 | | | |
bc77d7c0 TO |
6 | | This work is published under the GNU AGPLv3 license with some | |
7 | | permitted exceptions and without any warranty. For full license | | |
8 | | and copyright information, see https://civicrm.org/licensing | | |
3efb5b86 | 9 | +--------------------------------------------------------------------+ |
d25dd0ee | 10 | */ |
3efb5b86 CW |
11 | |
12 | /** | |
13 | * Base class for most search forms | |
14 | */ | |
15 | class CRM_Core_Form_Search extends CRM_Core_Form { | |
16 | ||
48473171 CW |
17 | /** |
18 | * Are we forced to run a search | |
19 | * | |
20 | * @var int | |
48473171 CW |
21 | */ |
22 | protected $_force; | |
23 | ||
48473171 | 24 | /** |
100fef9d | 25 | * Name of action button |
48473171 CW |
26 | * |
27 | * @var string | |
48473171 CW |
28 | */ |
29 | protected $_actionButtonName; | |
30 | ||
31 | /** | |
100fef9d | 32 | * Form values that we will be using |
48473171 CW |
33 | * |
34 | * @var array | |
48473171 CW |
35 | */ |
36 | public $_formValues; | |
37 | ||
38 | /** | |
100fef9d | 39 | * Have we already done this search |
48473171 | 40 | * |
b67daa72 | 41 | * @var bool |
48473171 CW |
42 | */ |
43 | protected $_done; | |
44 | ||
45 | /** | |
100fef9d | 46 | * What context are we being invoked from |
48473171 | 47 | * |
48473171 CW |
48 | * @var string |
49 | */ | |
51299070 | 50 | protected $_context; |
48473171 | 51 | |
7a3978aa FG |
52 | /** |
53 | * The list of tasks or actions that a searcher can perform on a result set. | |
54 | * | |
55 | * @var array | |
56 | */ | |
be2fb01f | 57 | protected $_taskList = []; |
7a3978aa | 58 | |
df60621b | 59 | /** |
60 | * Declare entity reference fields as they will need to be converted. | |
61 | * | |
62 | * The entity reference format looks like '2,3' whereas the Query object expects array(2, 3) | |
63 | * or array('IN' => array(2, 3). The latter is the one we are moving towards standardising on. | |
64 | * | |
65 | * @var array | |
66 | */ | |
be2fb01f | 67 | protected $entityReferenceFields = []; |
df60621b | 68 | |
7a3978aa FG |
69 | /** |
70 | * Builds the list of tasks or actions that a searcher can perform on a result set. | |
71 | * | |
72 | * To modify the task list, child classes should alter $this->_taskList, | |
73 | * preferably by extending this method. | |
74 | * | |
75 | * @return array | |
76 | */ | |
77 | protected function buildTaskList() { | |
78 | return $this->_taskList; | |
79 | } | |
80 | ||
c82067be SL |
81 | /** |
82 | * Should we be adding all the metadata for contact search fields or just for the sort name. | |
83 | * | |
84 | * @var bool | |
85 | */ | |
86 | protected $sortNameOnly = FALSE; | |
87 | ||
e6dda67a | 88 | /** |
89 | * Metadata for fields on the search form. | |
90 | * | |
8c9caddc | 91 | * Instantiate with empty array for contact to prevent e-notices. |
92 | * | |
e6dda67a | 93 | * @var array |
94 | */ | |
8c9caddc | 95 | protected $searchFieldMetadata = ['Contact' => []]; |
e6dda67a | 96 | |
97 | /** | |
98 | * @return array | |
99 | */ | |
100 | public function getSearchFieldMetadata() { | |
101 | return $this->searchFieldMetadata; | |
102 | } | |
103 | ||
104 | /** | |
105 | * @param array $searchFieldMetadata | |
106 | */ | |
107 | public function addSearchFieldMetadata($searchFieldMetadata) { | |
108 | $this->searchFieldMetadata = array_merge($this->searchFieldMetadata, $searchFieldMetadata); | |
109 | } | |
110 | ||
e9f51713 | 111 | /** |
112 | * Prepare for search by loading options from the url, handling force searches, retrieving form values. | |
113 | * | |
114 | * @throws \CRM_Core_Exception | |
115 | * @throws \CiviCRM_API3_Exception | |
116 | */ | |
117 | public function preProcess() { | |
118 | $this->loadStandardSearchOptionsFromUrl(); | |
119 | if ($this->_force) { | |
120 | $this->handleForcedSearch(); | |
121 | } | |
122 | $this->_formValues = $this->getFormValues(); | |
461c8a93 EM |
123 | // For searchResultsTasks.tpl. |
124 | $this->addExpectedSmartyVariables(['savedSearch', 'selectorLabel']); | |
e9f51713 | 125 | } |
126 | ||
8c9caddc | 127 | /** |
128 | * This virtual function is used to set the default values of various form elements. | |
129 | * | |
130 | * @return array|NULL | |
131 | * reference to the array of default values | |
5f1bf12f | 132 | * @throws \CRM_Core_Exception |
8c9caddc | 133 | */ |
134 | public function setDefaultValues() { | |
e9f51713 | 135 | // Use the form values stored to the form. Ideally 'formValues' |
136 | // would remain 'pure' & another array would be wrangled. | |
137 | // We don't do that - so we want the version of formValues stored early on. | |
138 | $defaults = (array) $this->get('formValues'); | |
f90f8d32 | 139 | foreach (array_keys($this->getSearchFieldMetadata()) as $entity) { |
e8082ca5 | 140 | $defaults = array_merge($this->getEntityDefaults($entity), $defaults); |
141 | } | |
142 | return $defaults; | |
8c9caddc | 143 | } |
144 | ||
359fdb6f | 145 | /** |
146 | * Set the form values based on input and preliminary processing. | |
f90f8d32 | 147 | * |
a13c931b | 148 | * @throws \CRM_Core_Exception |
359fdb6f | 149 | */ |
150 | protected function setFormValues() { | |
5f1bf12f | 151 | $this->_formValues = $this->getFormValues(); |
e9f51713 | 152 | $this->set('formValues', $this->_formValues); |
359fdb6f | 153 | $this->convertTextStringsToUseLikeOperator(); |
154 | } | |
155 | ||
34197a55 | 156 | /** |
0955d6b9 | 157 | * Common buildForm tasks required by all searches. |
51299070 | 158 | * |
159 | * @throws \CRM_Core_Exception | |
34197a55 | 160 | */ |
61b4d091 | 161 | public function buildQuickForm() { |
13d9bc82 | 162 | CRM_Core_Resources::singleton() |
562fda4b CW |
163 | ->addScriptFile('civicrm', 'js/crm.searchForm.js', 1, 'html-header') |
164 | ->addStyleFile('civicrm', 'css/searchForm.css', 1, 'html-header'); | |
3efb5b86 | 165 | |
be2fb01f CW |
166 | $this->addButtons([ |
167 | [ | |
3efb5b86 CW |
168 | 'type' => 'refresh', |
169 | 'name' => ts('Search'), | |
170 | 'isDefault' => TRUE, | |
be2fb01f CW |
171 | ], |
172 | ]); | |
8d36b801 | 173 | |
023e90c3 | 174 | $this->addClass('crm-search-form'); |
7a3978aa | 175 | |
7a3978aa FG |
176 | $tasks = $this->buildTaskList(); |
177 | $this->addTaskMenu($tasks); | |
8d36b801 CW |
178 | } |
179 | ||
e6dda67a | 180 | /** |
181 | * Add any fields described in metadata to the form. | |
182 | * | |
183 | * The goal is to describe all fields in metadata and handle from metadata rather | |
184 | * than existing ad hoc handling. | |
51299070 | 185 | * |
186 | * @throws \CiviCRM_API3_Exception | |
e6dda67a | 187 | */ |
188 | public function addFormFieldsFromMetadata() { | |
2307be08 | 189 | $this->addFormRule(['CRM_Core_Form_Search', 'formRule'], $this); |
e6dda67a | 190 | $this->_action = CRM_Core_Action::ADVANCED; |
191 | foreach ($this->getSearchFieldMetadata() as $entity => $fields) { | |
192 | foreach ($fields as $fieldName => $fieldSpec) { | |
d7cc9ca9 | 193 | $fieldType = $fieldSpec['type'] ?? ''; |
0058ef3f | 194 | if ($fieldType === CRM_Utils_Type::T_DATE || $fieldType === (CRM_Utils_Type::T_DATE + CRM_Utils_Type::T_TIME) || $fieldType === CRM_Utils_Type::T_TIMESTAMP) { |
1157f03f | 195 | $title = empty($fieldSpec['unique_title']) ? $fieldSpec['title'] : $fieldSpec['unique_title']; |
0058ef3f | 196 | $this->addDatePickerRange($fieldName, $title, ($fieldType === (CRM_Utils_Type::T_DATE + CRM_Utils_Type::T_TIME) || $fieldType === CRM_Utils_Type::T_TIMESTAMP)); |
0bcac7e7 | 197 | } |
198 | else { | |
d7cc9ca9 | 199 | // Not quite sure about moving to a mix of keying by entity vs permitting entity to |
200 | // be passed in. The challenge of the former is that it doesn't permit ordering. | |
201 | // Perhaps keying was the wrong starting point & we should do a flat array as all | |
202 | // fields eventually need to be unique. | |
203 | $props = ['entity' => $fieldSpec['entity'] ?? $entity]; | |
1157f03f SL |
204 | if (isset($fields[$fieldName]['unique_title'])) { |
205 | $props['label'] = $fields[$fieldName]['unique_title']; | |
206 | } | |
03ee227b | 207 | elseif (isset($fields[$fieldName]['html']['label'])) { |
208 | $props['label'] = $fields[$fieldName]['html']['label']; | |
209 | } | |
1157f03f | 210 | elseif (isset($fields[$fieldName]['title'])) { |
8c9caddc | 211 | $props['label'] = $fields[$fieldName]['title']; |
212 | } | |
359fdb6f | 213 | if (empty($fieldSpec['is_pseudofield'])) { |
214 | $this->addField($fieldName, $props); | |
215 | } | |
0bcac7e7 | 216 | } |
e6dda67a | 217 | } |
218 | } | |
219 | } | |
220 | ||
2307be08 | 221 | /** |
222 | * Global validation rules for the form. | |
223 | * | |
224 | * @param array $fields | |
225 | * Posted values of the form. | |
518fa0ee SL |
226 | * @param array $files |
227 | * @param object $form | |
2307be08 | 228 | * |
229 | * @return array | |
230 | * list of errors to be posted back to the form | |
231 | */ | |
232 | public static function formRule($fields, $files, $form) { | |
233 | $errors = []; | |
b9c90943 | 234 | if (!is_a($form, 'CRM_Core_Form_Search')) { |
235 | // So this gets hit with a form object when doing an activity date search from | |
236 | // advanced search, but a NULL object when doing a pledge search. | |
237 | return $errors; | |
238 | } | |
2307be08 | 239 | foreach ($form->getSearchFieldMetadata() as $entity => $spec) { |
240 | foreach ($spec as $fieldName => $fieldSpec) { | |
241 | if ($fieldSpec['type'] === CRM_Utils_Type::T_DATE || $fieldSpec['type'] === (CRM_Utils_Type::T_DATE + CRM_Utils_Type::T_TIME)) { | |
8a6fde27 | 242 | if (!empty($fields[$fieldName . '_high']) && !empty($fields[$fieldName . '_low']) && empty($fields[$fieldName . '_relative'])) { |
2307be08 | 243 | if (strtotime($fields[$fieldName . '_low']) > strtotime($fields[$fieldName . '_high'])) { |
244 | $errors[$fieldName . '_low'] = ts('%1: Please check that your date range is in correct chronological order.', [1 => $fieldSpec['title']]); | |
245 | } | |
246 | } | |
247 | } | |
248 | } | |
249 | } | |
250 | return $errors; | |
251 | } | |
252 | ||
e6dda67a | 253 | /** |
254 | * Get the validation rule to apply to a function. | |
255 | * | |
256 | * Alphanumeric is designed to always be safe & for now we just return | |
257 | * that but in future we can use tighter rules for types like int, bool etc. | |
258 | * | |
259 | * @param string $entity | |
260 | * @param string $fieldName | |
261 | * | |
262 | * @return string | |
263 | */ | |
264 | protected function getValidationTypeForField($entity, $fieldName) { | |
265 | switch ($this->getSearchFieldMetadata()[$entity][$fieldName]['type']) { | |
266 | case CRM_Utils_Type::T_BOOLEAN: | |
267 | return 'Boolean'; | |
268 | ||
269 | case CRM_Utils_Type::T_INT: | |
270 | return 'CommaSeparatedIntegers'; | |
271 | ||
27cedb98 | 272 | case CRM_Utils_Type::T_DATE: |
273 | case CRM_Utils_Type::T_DATE + CRM_Utils_Type::T_TIME: | |
274 | return 'Timestamp'; | |
275 | ||
e6dda67a | 276 | default: |
277 | return 'Alphanumeric'; | |
278 | } | |
279 | } | |
280 | ||
281 | /** | |
282 | * Get the defaults for the entity for any fields described in metadata. | |
283 | * | |
284 | * @param string $entity | |
285 | * | |
286 | * @return array | |
81959827 | 287 | * |
288 | * @throws \CRM_Core_Exception | |
e6dda67a | 289 | */ |
290 | protected function getEntityDefaults($entity) { | |
291 | $defaults = []; | |
e8082ca5 | 292 | foreach (CRM_Utils_Array::value($entity, $this->getSearchFieldMetadata(), []) as $fieldName => $fieldSpec) { |
293 | if (empty($_POST[$fieldName])) { | |
294 | $value = CRM_Utils_Request::retrieveValue($fieldName, $this->getValidationTypeForField($entity, $fieldName), NULL, NULL, 'GET'); | |
c5c17034 | 295 | if ($value !== NULL) { |
1d81be90 | 296 | if ($fieldSpec['html']['type'] === 'Select') { |
297 | $defaults[$fieldName] = explode(',', $value); | |
298 | } | |
299 | else { | |
300 | $defaults[$fieldName] = $value; | |
301 | } | |
e6dda67a | 302 | } |
27cedb98 | 303 | if ($fieldSpec['type'] === CRM_Utils_Type::T_DATE || ($fieldSpec['type'] === CRM_Utils_Type::T_DATE + CRM_Utils_Type::T_TIME)) { |
e8082ca5 | 304 | $low = CRM_Utils_Request::retrieveValue($fieldName . '_low', 'Timestamp', NULL, NULL, 'GET'); |
305 | $high = CRM_Utils_Request::retrieveValue($fieldName . '_high', 'Timestamp', NULL, NULL, 'GET'); | |
306 | if ($low !== NULL || $high !== NULL) { | |
c5c17034 | 307 | $defaults[$fieldName . '_relative'] = 0; |
308 | $defaults[$fieldName . '_low'] = $low ? date('Y-m-d H:i:s', strtotime($low)) : NULL; | |
309 | $defaults[$fieldName . '_high'] = $high ? date('Y-m-d H:i:s', strtotime($high)) : NULL; | |
27cedb98 | 310 | } |
81959827 | 311 | else { |
312 | $relative = CRM_Utils_Request::retrieveValue($fieldName . '_relative', 'String', NULL, NULL, 'GET'); | |
313 | if (!empty($relative) && isset(CRM_Core_OptionGroup::values('relative_date_filters')[$relative])) { | |
314 | $defaults[$fieldName . '_relative'] = $relative; | |
315 | } | |
316 | } | |
27cedb98 | 317 | } |
e6dda67a | 318 | } |
319 | } | |
320 | return $defaults; | |
321 | } | |
322 | ||
7123f88c | 323 | /** |
324 | * Convert any submitted text fields to use 'like' rather than '=' as the operator. | |
325 | * | |
326 | * This excludes any with options. | |
327 | * | |
328 | * Note this will only pick up fields declared via metadata. | |
329 | */ | |
330 | protected function convertTextStringsToUseLikeOperator() { | |
359fdb6f | 331 | foreach ($this->getSearchFieldMetadata() as $entity => $fields) { |
332 | foreach ($fields as $fieldName => $field) { | |
333 | if (!empty($this->_formValues[$fieldName]) && empty($field['options']) && empty($field['pseudoconstant'])) { | |
334 | if (in_array($field['type'], [CRM_Utils_Type::T_STRING, CRM_Utils_Type::T_TEXT])) { | |
1f865dbb BS |
335 | $val = $this->_formValues[$fieldName]; |
336 | if (is_array($val)) { | |
337 | $val = $val['LIKE']; | |
338 | } | |
339 | $this->_formValues[$fieldName] = ['LIKE' => CRM_Contact_BAO_Query::getWildCardedValue(TRUE, 'LIKE', trim($val))]; | |
359fdb6f | 340 | } |
7123f88c | 341 | } |
342 | } | |
343 | } | |
344 | } | |
345 | ||
8d36b801 | 346 | /** |
0955d6b9 | 347 | * Add checkboxes for each row plus a master checkbox. |
ad37ac8e | 348 | * |
349 | * @param array $rows | |
8d36b801 | 350 | */ |
00be9182 | 351 | public function addRowSelectors($rows) { |
be2fb01f | 352 | $this->addElement('checkbox', 'toggleSelect', NULL, NULL, ['class' => 'select-rows']); |
4126499f | 353 | if (!empty($rows)) { |
354 | foreach ($rows as $row) { | |
de6c59ca | 355 | if (!empty($row['checkbox'])) { |
be2fb01f | 356 | $this->addElement('checkbox', $row['checkbox'], NULL, NULL, ['class' => 'select-row']); |
6eb91e49 | 357 | } |
4126499f | 358 | } |
8d36b801 | 359 | } |
3efb5b86 | 360 | } |
34197a55 | 361 | |
44543184 | 362 | /** |
363 | * Add actions menu to search results form. | |
364 | * | |
365 | * @param array $tasks | |
366 | */ | |
367 | public function addTaskMenu($tasks) { | |
be2fb01f | 368 | $taskMetaData = []; |
44543184 | 369 | foreach ($tasks as $key => $task) { |
be2fb01f | 370 | $taskMetaData[$key] = ['title' => $task]; |
44543184 | 371 | } |
372 | parent::addTaskMenu($taskMetaData); | |
373 | } | |
374 | ||
e597fc33 DG |
375 | /** |
376 | * Add the sort-name field to the form. | |
377 | * | |
378 | * There is a setting to determine whether email is included in the search & we look this up to determine | |
379 | * which text to choose. | |
380 | * | |
381 | * Note that for translation purposes the full string works better than using 'prefix' hence we use override-able functions | |
382 | * to define the string. | |
51299070 | 383 | * |
384 | * @throws \CiviCRM_API3_Exception | |
e597fc33 DG |
385 | */ |
386 | protected function addSortNameField() { | |
e8082ca5 | 387 | $title = civicrm_api3('setting', 'getvalue', ['name' => 'includeEmailInName', 'group' => 'Search Preferences']) ? $this->getSortNameLabelWithEmail() : $this->getSortNameLabelWithOutEmail(); |
e597fc33 DG |
388 | $this->addElement( |
389 | 'text', | |
390 | 'sort_name', | |
e8082ca5 | 391 | $title, |
e597fc33 DG |
392 | CRM_Core_DAO::getAttribute('CRM_Contact_DAO_Contact', 'sort_name') |
393 | ); | |
1d81be90 | 394 | $this->searchFieldMetadata['Contact']['sort_name'] = array_merge(CRM_Contact_DAO_Contact::fields()['sort_name'], ['name' => 'sort_name', 'title' => $title, 'type' => CRM_Utils_Type::T_STRING]); |
e597fc33 DG |
395 | } |
396 | ||
397 | /** | |
398 | * Get the label for the sortName field if email searching is on. | |
399 | * | |
400 | * (email searching is a setting under search preferences). | |
401 | * | |
402 | * @return string | |
403 | */ | |
404 | protected function getSortNameLabelWithEmail() { | |
405 | return ts('Name or Email'); | |
406 | } | |
407 | ||
408 | /** | |
409 | * Get the label for the sortName field if email searching is off. | |
410 | * | |
411 | * (email searching is a setting under search preferences). | |
412 | * | |
413 | * @return string | |
414 | */ | |
415 | protected function getSortNameLabelWithOutEmail() { | |
416 | return ts('Name'); | |
417 | } | |
418 | ||
2ee21eaa CW |
419 | /** |
420 | * Explicitly declare the form context for addField(). | |
421 | */ | |
422 | public function getDefaultContext() { | |
423 | return 'search'; | |
424 | } | |
425 | ||
0573fd28 | 426 | /** |
427 | * Add generic fields that specify the contact. | |
51299070 | 428 | * |
429 | * @throws \CiviCRM_API3_Exception | |
0573fd28 | 430 | */ |
431 | protected function addContactSearchFields() { | |
240b0e65 | 432 | if (!$this->isFormInViewOrEditMode()) { |
433 | return; | |
434 | } | |
0573fd28 | 435 | $this->addSortNameField(); |
c82067be SL |
436 | if ($this->sortNameOnly) { |
437 | return; | |
438 | } | |
0573fd28 | 439 | |
440 | $this->_group = CRM_Core_PseudoConstant::nestedGroup(); | |
441 | if ($this->_group) { | |
442 | $this->add('select', 'group', $this->getGroupLabel(), $this->_group, FALSE, | |
be2fb01f | 443 | [ |
0573fd28 | 444 | 'id' => 'group', |
445 | 'multiple' => 'multiple', | |
446 | 'class' => 'crm-select2', | |
be2fb01f | 447 | ] |
0573fd28 | 448 | ); |
87a26496 | 449 | $this->searchFieldMetadata['Contact']['group'] = ['name' => 'group', 'type' => CRM_Utils_Type::T_INT, 'is_pseudofield' => TRUE, 'html' => ['type' => 'Select']]; |
0573fd28 | 450 | } |
451 | ||
452 | $contactTags = CRM_Core_BAO_Tag::getTags(); | |
453 | if ($contactTags) { | |
454 | $this->add('select', 'contact_tags', $this->getTagLabel(), $contactTags, FALSE, | |
be2fb01f | 455 | [ |
0573fd28 | 456 | 'id' => 'contact_tags', |
457 | 'multiple' => 'multiple', | |
458 | 'class' => 'crm-select2', | |
be2fb01f | 459 | ] |
0573fd28 | 460 | ); |
461 | } | |
87a26496 | 462 | $this->searchFieldMetadata['Contact']['contact_tags'] = ['name' => 'contact_tags', 'type' => CRM_Utils_Type::T_INT, 'is_pseudofield' => TRUE, 'html' => ['type' => 'Select']]; |
be2fb01f | 463 | $this->addField('contact_type', ['entity' => 'Contact']); |
c82067be | 464 | $this->searchFieldMetadata['Contact']['contact_type'] = CRM_Contact_DAO_Contact::fields()['contact_type']; |
0573fd28 | 465 | |
466 | if (CRM_Core_Permission::check('access deleted contacts') && Civi::settings()->get('contact_undelete')) { | |
467 | $this->addElement('checkbox', 'deleted_contacts', ts('Search in Trash') . '<br />' . ts('(deleted contacts)')); | |
87a26496 | 468 | $this->searchFieldMetadata['Contact']['deleted_contacts'] = ['name' => 'deleted_contacts', 'type' => CRM_Utils_Type::T_INT, 'is_pseudofield' => TRUE, 'html' => ['type' => 'Checkbox']]; |
0573fd28 | 469 | } |
470 | ||
471 | } | |
472 | ||
f8fe52e0 | 473 | /** |
474 | * Get the label for the group field. | |
475 | * | |
476 | * @return string | |
477 | */ | |
478 | protected function getGroupLabel() { | |
479 | return ts('Group(s)'); | |
480 | } | |
481 | ||
482 | /** | |
483 | * Get the label for the tag field. | |
484 | * | |
485 | * We do this in a function so the 'ts' wraps the whole string to allow | |
486 | * better translation. | |
487 | * | |
488 | * @return string | |
489 | */ | |
490 | protected function getTagLabel() { | |
491 | return ts('Tag(s)'); | |
492 | } | |
493 | ||
09e47399 | 494 | /** |
495 | * we allow the controller to set force/reset externally, useful when we are being | |
496 | * driven by the wizard framework | |
51299070 | 497 | * |
498 | * @throws \CRM_Core_Exception | |
09e47399 | 499 | */ |
64ffcefd | 500 | protected function loadStandardSearchOptionsFromUrl() { |
09e47399 | 501 | $this->_reset = CRM_Utils_Request::retrieve('reset', 'Boolean'); |
502 | $this->_force = CRM_Utils_Request::retrieve('force', 'Boolean', $this, FALSE); | |
503 | $this->_limit = CRM_Utils_Request::retrieve('limit', 'Positive', $this); | |
504 | $this->_context = CRM_Utils_Request::retrieve('context', 'Alphanumeric', $this, FALSE, 'search'); | |
505 | $this->_ssID = CRM_Utils_Request::retrieve('ssID', 'Positive', $this); | |
506 | $this->assign("context", $this->_context); | |
507 | } | |
508 | ||
509 | /** | |
510 | * Get user submitted values. | |
511 | * | |
512 | * Get it from controller only if form has been submitted, else preProcess has set this | |
513 | */ | |
64ffcefd | 514 | protected function loadFormValues() { |
09e47399 | 515 | if (!empty($_POST) && !$this->controller->isModal()) { |
516 | $this->_formValues = $this->controller->exportValues($this->_name); | |
517 | } | |
518 | else { | |
519 | $this->_formValues = $this->get('formValues'); | |
520 | } | |
521 | ||
522 | if (empty($this->_formValues)) { | |
523 | if (isset($this->_ssID)) { | |
524 | $this->_formValues = CRM_Contact_BAO_SavedSearch::getFormValues($this->_ssID); | |
525 | } | |
526 | } | |
527 | } | |
528 | ||
5f1bf12f | 529 | /** |
530 | * Get the form values. | |
531 | * | |
532 | * @todo consolidate with loadFormValues() | |
533 | * | |
534 | * @return array | |
535 | * | |
536 | * @throws \CRM_Core_Exception | |
537 | */ | |
538 | protected function getFormValues() { | |
539 | if (!empty($_POST) && !$this->_force) { | |
540 | return $this->controller->exportValues($this->_name); | |
541 | } | |
542 | if ($this->_force) { | |
543 | return $this->setDefaultValues(); | |
544 | } | |
545 | return (array) $this->get('formValues'); | |
546 | } | |
547 | ||
b5c63125 | 548 | /** |
549 | * Get the string processed to determine sort order. | |
550 | * | |
551 | * This looks like 'sort_name_u' for Sort name ascending. | |
552 | * | |
553 | * @return string|null | |
554 | */ | |
555 | protected function getSortID() { | |
556 | if ($this->get(CRM_Utils_Sort::SORT_ID)) { | |
557 | return CRM_Utils_Sort::sortIDValue($this->get(CRM_Utils_Sort::SORT_ID), | |
558 | $this->get(CRM_Utils_Sort::SORT_DIRECTION) | |
559 | ); | |
560 | } | |
561 | return NULL; | |
562 | } | |
563 | ||
3a27e13e | 564 | /** |
565 | * Set the metadata for the form. | |
566 | * | |
567 | * @throws \CiviCRM_API3_Exception | |
568 | */ | |
569 | protected function setSearchMetadata() {} | |
570 | ||
571 | /** | |
572 | * Handle force=1 in the url. | |
573 | * | |
574 | * Search field metadata is normally added in buildForm but we are bypassing that in this flow | |
575 | * (I've always found the flow kinda confusing & perhaps that is the problem but this mitigates) | |
576 | * | |
577 | * @throws \CiviCRM_API3_Exception | |
578 | */ | |
579 | protected function handleForcedSearch() { | |
580 | $this->setSearchMetadata(); | |
e9f51713 | 581 | $this->addContactSearchFields(); |
3a27e13e | 582 | $this->postProcess(); |
583 | $this->set('force', 0); | |
584 | } | |
585 | ||
3efb5b86 | 586 | } |