Merge pull request #15818 from colemanw/fields
[civicrm-core.git] / CRM / Activity / Form / Search.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
5 | |
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 |
9 +--------------------------------------------------------------------+
10 */
11
12 /**
13 *
14 * @package CRM
15 * @copyright CiviCRM LLC https://civicrm.org/licensing
16 */
17
18 /**
19 * This file is for activity search.
20 */
21 class CRM_Activity_Form_Search extends CRM_Core_Form_Search {
22
23 /**
24 * The params that are sent to the query.
25 *
26 * @var array
27 */
28 protected $_queryParams;
29
30 /**
31 * Are we restricting ourselves to a single contact.
32 *
33 * @var bool
34 */
35 protected $_single = FALSE;
36
37 /**
38 * Are we restricting ourselves to a single contact.
39 *
40 * @var bool
41 */
42 protected $_limit = NULL;
43
44 /**
45 * Prefix for the controller.
46 * @var string
47 */
48 protected $_prefix = "activity_";
49
50 /**
51 * The saved search ID retrieved from the GET vars.
52 *
53 * @var int
54 */
55 protected $_ssID;
56
57 /**
58 * @return string
59 */
60 public function getDefaultEntity() {
61 return 'Activity';
62 }
63
64 /**
65 * Processing needed for buildForm and later.
66 */
67 public function preProcess() {
68 $this->set('searchFormName', 'Search');
69
70 // set the button names
71 $this->_searchButtonName = $this->getButtonName('refresh');
72 $this->_actionButtonName = $this->getButtonName('next', 'action');
73
74 $this->_done = FALSE;
75
76 $this->loadStandardSearchOptionsFromUrl();
77
78 // get user submitted values
79 // get it from controller only if form has been submitted, else preProcess has set this
80 if (!empty($_POST) && !$this->controller->isModal()) {
81 $this->_formValues = $this->controller->exportValues($this->_name);
82 }
83 else {
84 $this->_formValues = $this->get('formValues');
85
86 if ($this->_force) {
87 // If we force the search then merge form values with url values
88 // and set submit values to form values.
89 // @todo this is not good security practice. Instead define the fields in metadata & use
90 // getEntityDefaults.
91 $this->_formValues = array_merge((array) $this->_formValues, CRM_Utils_Request::exportValues());
92 $this->_submitValues = $this->_formValues;
93 }
94 }
95
96 if (empty($this->_formValues)) {
97 if (isset($this->_ssID)) {
98 $this->_formValues = CRM_Contact_BAO_SavedSearch::getFormValues($this->_ssID);
99 }
100 }
101
102 if ($this->_force) {
103 $this->postProcess();
104 $this->set('force', 0);
105 }
106
107 $sortID = NULL;
108 if ($this->get(CRM_Utils_Sort::SORT_ID)) {
109 $sortID = CRM_Utils_Sort::sortIDValue($this->get(CRM_Utils_Sort::SORT_ID),
110 $this->get(CRM_Utils_Sort::SORT_DIRECTION)
111 );
112 }
113
114 $this->_queryParams = CRM_Contact_BAO_Query::convertFormValues($this->_formValues);
115 $selector = new CRM_Activity_Selector_Search($this->_queryParams,
116 $this->_action,
117 NULL,
118 $this->_single,
119 $this->_limit,
120 $this->_context
121 );
122 $prefix = NULL;
123 if ($this->_context == 'user') {
124 $prefix = $this->_prefix;
125 }
126
127 $this->assign("{$prefix}limit", $this->_limit);
128 $this->assign("{$prefix}single", $this->_single);
129
130 $controller = new CRM_Core_Selector_Controller($selector,
131 $this->get(CRM_Utils_Pager::PAGE_ID),
132 $sortID,
133 CRM_Core_Action::VIEW,
134 $this,
135 CRM_Core_Selector_Controller::TRANSFER,
136 $prefix
137 );
138 $controller->setEmbedded(TRUE);
139 $controller->moveFromSessionToTemplate();
140
141 $this->assign('summary', $this->get('summary'));
142 }
143
144 /**
145 * Build the form object.
146 */
147 public function buildQuickForm() {
148 parent::buildQuickForm();
149 $this->addSortNameField();
150
151 CRM_Activity_BAO_Query::buildSearchForm($this);
152
153 $rows = $this->get('rows');
154 if (is_array($rows)) {
155 if (!$this->_single) {
156 $this->addRowSelectors($rows);
157 }
158
159 $this->addTaskMenu(CRM_Activity_Task::permissionedTaskTitles(CRM_Core_Permission::getPermission()));
160 }
161
162 }
163
164 /**
165 * The post processing of the form gets done here.
166 *
167 * Key things done during post processing are
168 * - check for reset or next request. if present, skip post procesing.
169 * - now check if user requested running a saved search, if so, then
170 * the form values associated with the saved search are used for searching.
171 * - if user has done a submit with new values the regular post submissing is
172 * done.
173 *
174 * The processing consists of using a Selector / Controller framework for getting the
175 * search results.
176 */
177 public function postProcess() {
178 if ($this->_done) {
179 return;
180 }
181
182 $this->_done = TRUE;
183 $this->setFormValues();
184 if (!empty($_POST)) {
185 $specialParams = [
186 'activity_type_id',
187 'status_id',
188 'priority_id',
189 ];
190 $changeNames = [
191 'status_id' => 'activity_status_id',
192 'priority_id' => 'activity_priority_id',
193 ];
194
195 CRM_Contact_BAO_Query::processSpecialFormValue($this->_formValues, $specialParams, $changeNames);
196 }
197 $this->fixFormValues();
198
199 if (isset($this->_ssID) && empty($_POST)) {
200 // if we are editing / running a saved search and the form has not been posted
201 $this->_formValues = CRM_Contact_BAO_SavedSearch::getFormValues($this->_ssID);
202 }
203
204 // We don't show test records in summaries or dashboards
205 if (empty($this->_formValues['activity_test']) && $this->_force) {
206 $this->_formValues["activity_test"] = 0;
207 }
208
209 CRM_Core_BAO_CustomValue::fixCustomFieldValue($this->_formValues);
210
211 $this->_queryParams = CRM_Contact_BAO_Query::convertFormValues($this->_formValues);
212
213 $this->set('formValues', $this->_formValues);
214 $this->set('queryParams', $this->_queryParams);
215
216 $buttonName = $this->controller->getButtonName();
217 if ($buttonName == $this->_actionButtonName) {
218 // check actionName and if next, then do not repeat a search, since we are going to the next page
219 // hack, make sure we reset the task values
220 $stateMachine = $this->controller->getStateMachine();
221 $formName = $stateMachine->getTaskFormName();
222 $this->controller->resetPage($formName);
223 return;
224 }
225
226 $sortID = NULL;
227 if ($this->get(CRM_Utils_Sort::SORT_ID)) {
228 $sortID = CRM_Utils_Sort::sortIDValue($this->get(CRM_Utils_Sort::SORT_ID),
229 $this->get(CRM_Utils_Sort::SORT_DIRECTION)
230 );
231 }
232
233 $this->_queryParams = CRM_Contact_BAO_Query::convertFormValues($this->_formValues);
234
235 $selector = new CRM_Activity_Selector_Search($this->_queryParams,
236 $this->_action,
237 NULL,
238 $this->_single,
239 $this->_limit,
240 $this->_context
241 );
242 $selector->setKey($this->controller->_key);
243
244 $prefix = NULL;
245 if ($this->_context == 'basic' || $this->_context == 'user') {
246 $prefix = $this->_prefix;
247 }
248
249 $controller = new CRM_Core_Selector_Controller($selector,
250 $this->get(CRM_Utils_Pager::PAGE_ID),
251 $sortID,
252 CRM_Core_Action::VIEW,
253 $this,
254 CRM_Core_Selector_Controller::SESSION,
255 $prefix
256 );
257 $controller->setEmbedded(TRUE);
258 $query = &$selector->getQuery();
259
260 if ($this->_context == 'user') {
261 $query->setSkipPermission(TRUE);
262 }
263 $controller->run();
264 }
265
266 public function fixFormValues() {
267 if (!$this->_force) {
268 return;
269 }
270
271 $status = CRM_Utils_Request::retrieve('status', 'String', $this);
272 if ($status) {
273 $this->_formValues['activity_status_id'] = $status;
274 $this->_defaults['activity_status_id'] = $status;
275 }
276
277 $survey = CRM_Utils_Request::retrieve('survey', 'Positive');
278
279 if ($survey) {
280 $this->_formValues['activity_survey_id'] = $this->_defaults['activity_survey_id'] = $survey;
281 $sid = CRM_Utils_Array::value('activity_survey_id', $this->_formValues);
282 $activity_type_id = CRM_Core_DAO::getFieldValue('CRM_Campaign_DAO_Survey', $sid, 'activity_type_id');
283
284 // since checkbox are replaced by multiple select option
285 $this->_formValues['activity_type_id'] = $activity_type_id;
286 $this->_defaults['activity_type_id'] = $activity_type_id;
287 }
288 $cid = CRM_Utils_Request::retrieve('cid', 'Positive', $this);
289
290 if ($cid) {
291 $cid = CRM_Utils_Type::escape($cid, 'Integer');
292 if ($cid > 0) {
293 $this->_formValues['contact_id'] = $cid;
294
295 $activity_role = CRM_Utils_Request::retrieve('activity_role', 'Positive', $this);
296
297 if ($activity_role) {
298 $this->_formValues['activity_role'] = $activity_role;
299 }
300 else {
301 $this->_defaults['sort_name'] = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $cid, 'sort_name');
302 }
303 // also assign individual mode to the template
304 $this->_single = TRUE;
305 }
306 }
307
308 // Enable search activity by custom value
309 // @todo this is not good security practice. Instead define entity fields in metadata &
310 // use getEntity Defaults
311 $requestParams = CRM_Utils_Request::exportValues();
312 foreach (array_keys($requestParams) as $key) {
313 if (substr($key, 0, 7) != 'custom_') {
314 continue;
315 }
316 elseif (empty($requestParams[$key])) {
317 continue;
318 }
319 $customValue = CRM_Utils_Request::retrieve($key, 'String', $this);
320 if ($customValue) {
321 $this->_formValues[$key] = $customValue;
322 $this->_defaults[$key] = $customValue;
323 }
324 }
325
326 if (!empty($this->_defaults)) {
327 $this->setDefaults($this->_defaults);
328 }
329 }
330
331 /**
332 * Return a descriptive name for the page, used in wizard header
333 *
334 * @return string
335 */
336 public function getTitle() {
337 return ts('Find Activities');
338 }
339
340 protected function getEntityMetadata() {
341 return CRM_Activity_BAO_Query::getSearchFieldMetadata();
342 }
343
344 /**
345 * Set the metadata for the form.
346 */
347 protected function setSearchMetadata() {
348 $this->addSearchFieldMetadata(['Activity' => $this->getEntityMetadata()]);
349 }
350
351 }