Commit | Line | Data |
---|---|---|
6a488035 TO |
1 | <?php |
2 | /* | |
3 | +--------------------------------------------------------------------+ | |
bc77d7c0 | 4 | | Copyright CiviCRM LLC. All rights reserved. | |
6a488035 | 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 | | |
6a488035 | 9 | +--------------------------------------------------------------------+ |
d25dd0ee | 10 | */ |
6a488035 TO |
11 | |
12 | /** | |
13 | * | |
14 | * @package CRM | |
ca5cec67 | 15 | * @copyright CiviCRM LLC https://civicrm.org/licensing |
6a488035 TO |
16 | */ |
17 | ||
18 | /** | |
b6c94f42 | 19 | * This class generates form components for Activity. |
6a488035 TO |
20 | */ |
21 | class CRM_Activity_Form_Activity extends CRM_Contact_Form_Task { | |
22 | ||
23 | /** | |
24 | * The id of the object being edited / created | |
25 | * | |
26 | * @var int | |
27 | */ | |
28 | public $_activityId; | |
29 | ||
52c7b3a2 | 30 | /** |
fe482240 | 31 | * Store activity ids when multiple activities are created. |
52c7b3a2 KJ |
32 | * |
33 | * @var int | |
34 | */ | |
96f94695 | 35 | public $_activityIds = []; |
52c7b3a2 | 36 | |
6a488035 | 37 | /** |
fe482240 | 38 | * The id of activity type. |
6a488035 TO |
39 | * |
40 | * @var int | |
41 | */ | |
42 | public $_activityTypeId; | |
43 | ||
44 | /** | |
b819b81a | 45 | * The label of the activity type. |
46 | * Unfortunately this variable is called Name but don't want to change it | |
47 | * since it's public and might be commonly used in customized code. See also | |
48 | * activityTypeNameAndLabel used in the smarty template. | |
6a488035 TO |
49 | * |
50 | * @var string | |
51 | */ | |
52 | public $_activityTypeName; | |
53 | ||
54 | /** | |
fe482240 | 55 | * The id of currently viewed contact. |
6a488035 TO |
56 | * |
57 | * @var int | |
58 | */ | |
59 | public $_currentlyViewedContactId; | |
60 | ||
61 | /** | |
fe482240 | 62 | * The id of source contact and target contact. |
6a488035 TO |
63 | * |
64 | * @var int | |
65 | */ | |
66 | protected $_sourceContactId; | |
67 | protected $_targetContactId; | |
68 | protected $_asigneeContactId; | |
69 | ||
70 | protected $_single; | |
71 | ||
72 | public $_context; | |
73 | public $_compContext; | |
74 | public $_action; | |
75 | public $_activityTypeFile; | |
76 | ||
77 | /** | |
78 | * The id of the logged in user, used when add / edit | |
79 | * | |
80 | * @var int | |
81 | */ | |
82 | public $_currentUserId; | |
83 | ||
84 | /** | |
fe482240 | 85 | * The array of form field attributes. |
6a488035 TO |
86 | * |
87 | * @var array | |
88 | */ | |
89 | public $_fields; | |
90 | ||
91 | /** | |
92 | * The the directory inside CRM, to include activity type file from | |
93 | * | |
94 | * @var string | |
95 | */ | |
96 | protected $_crmDir = 'Activity'; | |
97 | ||
c490a46a | 98 | /** |
fe482240 | 99 | * Survey activity. |
c490a46a | 100 | * |
d51c6add | 101 | * @var bool |
c490a46a | 102 | */ |
6a488035 TO |
103 | protected $_isSurveyActivity; |
104 | ||
96f94695 | 105 | protected $_values = []; |
6a488035 | 106 | |
c087eb82 | 107 | protected $unsavedWarn = TRUE; |
d5965a37 | 108 | |
62d3ee27 SL |
109 | /** |
110 | * | |
53c79877 SM |
111 | * Is it possible to create separate activities with this form? |
112 | * | |
113 | * When TRUE, the form will ask whether the user wants to create separate | |
114 | * activities (if the user has specified multiple contacts in the "with" | |
115 | * field). | |
116 | * | |
117 | * When FALSE, the form will create one activity with all contacts together | |
118 | * and won't ask the user anything. | |
119 | * | |
120 | * Note: This is a class property so that child classes can turn off this | |
121 | * behavior (e.g. in CRM_Case_Form_Activity) | |
122 | * | |
d51c6add | 123 | * @var bool |
62d3ee27 | 124 | * |
53c79877 SM |
125 | */ |
126 | protected $supportsActivitySeparation = TRUE; | |
127 | ||
423616fa CW |
128 | public $submitOnce = TRUE; |
129 | ||
d5965a37 | 130 | /** |
6e62b28c | 131 | * Explicitly declare the entity api name. |
7808aae6 SB |
132 | * |
133 | * @return string | |
6e62b28c TM |
134 | */ |
135 | public function getDefaultEntity() { | |
136 | return 'Activity'; | |
137 | } | |
59d63f8b | 138 | |
6a488035 TO |
139 | /** |
140 | * The _fields var can be used by sub class to set/unset/edit the | |
141 | * form fields based on their requirement | |
6a488035 | 142 | */ |
00be9182 | 143 | public function setFields() { |
056878d2 CW |
144 | // Remove print document activity type |
145 | $unwanted = CRM_Core_OptionGroup::values('activity_type', FALSE, FALSE, FALSE, "AND v.name = 'Print PDF Letter'"); | |
146 | $activityTypes = array_diff_key(CRM_Core_PseudoConstant::ActivityType(FALSE), $unwanted); | |
147 | ||
96f94695 | 148 | $this->_fields = [ |
149 | 'subject' => [ | |
6a488035 TO |
150 | 'type' => 'text', |
151 | 'label' => ts('Subject'), | |
96f94695 | 152 | 'attributes' => CRM_Core_DAO::getAttribute('CRM_Activity_DAO_Activity', 'activity_subject'), |
153 | ], | |
154 | 'duration' => [ | |
4b2fda1e | 155 | 'type' => 'number', |
6a488035 | 156 | 'label' => ts('Duration'), |
96f94695 | 157 | 'attributes' => ['class' => 'four', 'min' => 1], |
6a488035 | 158 | 'required' => FALSE, |
96f94695 | 159 | ], |
160 | 'location' => [ | |
6a488035 TO |
161 | 'type' => 'text', |
162 | 'label' => ts('Location'), | |
9d72cede | 163 | 'attributes' => CRM_Core_DAO::getAttribute('CRM_Activity_DAO_Activity', 'location'), |
21dfd5f5 | 164 | 'required' => FALSE, |
96f94695 | 165 | ], |
166 | 'details' => [ | |
6a488035 TO |
167 | 'type' => 'wysiwyg', |
168 | 'label' => ts('Details'), | |
96f94695 | 169 | 'attributes' => ['class' => 'huge'], |
21dfd5f5 | 170 | 'required' => FALSE, |
96f94695 | 171 | ], |
172 | 'status_id' => [ | |
6a488035 | 173 | 'type' => 'select', |
475e9f44 | 174 | 'required' => TRUE, |
96f94695 | 175 | ], |
176 | 'priority_id' => [ | |
6a488035 | 177 | 'type' => 'select', |
475e9f44 | 178 | 'required' => TRUE, |
96f94695 | 179 | ], |
180 | 'source_contact_id' => [ | |
c27ebe4e | 181 | 'type' => 'entityRef', |
ff3f9641 | 182 | 'label' => ts('Added by'), |
21dfd5f5 | 183 | 'required' => FALSE, |
96f94695 | 184 | ], |
185 | 'target_contact_id' => [ | |
c27ebe4e CW |
186 | 'type' => 'entityRef', |
187 | 'label' => ts('With Contact'), | |
96f94695 | 188 | 'attributes' => ['multiple' => TRUE, 'create' => TRUE], |
189 | ], | |
190 | 'assignee_contact_id' => [ | |
c27ebe4e | 191 | 'type' => 'entityRef', |
3bd48a28 | 192 | 'label' => ts('Assigned to'), |
96f94695 | 193 | 'attributes' => [ |
353ffa53 TO |
194 | 'multiple' => TRUE, |
195 | 'create' => TRUE, | |
96f94695 | 196 | 'api' => ['params' => ['is_deceased' => 0]], |
197 | ], | |
198 | ], | |
199 | 'activity_date_time' => [ | |
d104311a CW |
200 | 'type' => 'datepicker', |
201 | 'label' => ts('Date'), | |
202 | 'required' => TRUE, | |
96f94695 | 203 | ], |
204 | 'followup_assignee_contact_id' => [ | |
c27ebe4e | 205 | 'type' => 'entityRef', |
3bd48a28 | 206 | 'label' => ts('Assigned to'), |
96f94695 | 207 | 'attributes' => [ |
353ffa53 TO |
208 | 'multiple' => TRUE, |
209 | 'create' => TRUE, | |
96f94695 | 210 | 'api' => ['params' => ['is_deceased' => 0]], |
211 | ], | |
212 | ], | |
213 | 'followup_activity_type_id' => [ | |
6a488035 TO |
214 | 'type' => 'select', |
215 | 'label' => ts('Followup Activity'), | |
96f94695 | 216 | 'attributes' => ['' => '- ' . ts('select activity') . ' -'] + $activityTypes, |
217 | 'extra' => ['class' => 'crm-select2'], | |
218 | ], | |
6a488035 | 219 | // Add optional 'Subject' field for the Follow-up Activiity, CRM-4491 |
96f94695 | 220 | 'followup_activity_subject' => [ |
6a488035 TO |
221 | 'type' => 'text', |
222 | 'label' => ts('Subject'), | |
96f94695 | 223 | 'attributes' => CRM_Core_DAO::getAttribute('CRM_Activity_DAO_Activity', 'subject'), |
224 | ], | |
225 | ]; | |
6a488035 TO |
226 | } |
227 | ||
228 | /** | |
fe482240 | 229 | * Build the form object. |
92eacb41 | 230 | * |
231 | * @throws \CRM_Core_Exception | |
6a488035 | 232 | */ |
00be9182 | 233 | public function preProcess() { |
b334d9ad | 234 | CRM_Core_Form_RecurringEntity::preProcess('civicrm_activity'); |
6a488035 TO |
235 | |
236 | $session = CRM_Core_Session::singleton(); | |
3bdcd4ec | 237 | $this->_currentUserId = CRM_Core_Session::getLoggedInContactID(); |
6a488035 TO |
238 | |
239 | $this->_currentlyViewedContactId = $this->get('contactId'); | |
240 | if (!$this->_currentlyViewedContactId) { | |
241 | $this->_currentlyViewedContactId = CRM_Utils_Request::retrieve('cid', 'Positive', $this); | |
242 | } | |
243 | $this->assign('contactId', $this->_currentlyViewedContactId); | |
244 | ||
7808aae6 | 245 | // Give the context. |
6a488035 | 246 | if (!isset($this->_context)) { |
edc80cda | 247 | $this->_context = CRM_Utils_Request::retrieve('context', 'Alphanumeric', $this); |
6a488035 TO |
248 | if (CRM_Contact_Form_Search::isSearchContext($this->_context)) { |
249 | $this->_context = 'search'; | |
250 | } | |
0d48f1cc | 251 | elseif (!in_array($this->_context, ['dashlet', 'case', 'dashletFullscreen']) |
6a488035 TO |
252 | && $this->_currentlyViewedContactId |
253 | ) { | |
254 | $this->_context = 'activity'; | |
255 | } | |
256 | $this->_compContext = CRM_Utils_Request::retrieve('compContext', 'String', $this); | |
257 | } | |
258 | ||
259 | $this->assign('context', $this->_context); | |
260 | ||
261 | $this->_action = CRM_Utils_Request::retrieve('action', 'String', $this); | |
262 | ||
263 | if ($this->_action & CRM_Core_Action::DELETE) { | |
264 | if (!CRM_Core_Permission::check('delete activities')) { | |
2b795b1f | 265 | CRM_Core_Error::statusBounce(ts('You do not have permission to access this page.')); |
6a488035 TO |
266 | } |
267 | } | |
268 | ||
7808aae6 SB |
269 | // CRM-6957 |
270 | // When we come from contact search, activity id never comes. | |
271 | // So don't try to get from object, it might gives you wrong one. | |
6a488035 TO |
272 | |
273 | // if we're not adding new one, there must be an id to | |
274 | // an activity we're trying to work on. | |
275 | if ($this->_action != CRM_Core_Action::ADD && | |
5d7c2bd2 | 276 | get_class($this->controller) !== 'CRM_Contact_Controller_Search' |
6a488035 TO |
277 | ) { |
278 | $this->_activityId = CRM_Utils_Request::retrieve('id', 'Positive', $this); | |
279 | } | |
280 | ||
281 | $this->_activityTypeId = CRM_Utils_Request::retrieve('atype', 'Positive', $this); | |
282 | $this->assign('atype', $this->_activityTypeId); | |
283 | ||
5b7581f1 CW |
284 | $this->assign('activityId', $this->_activityId); |
285 | ||
7808aae6 | 286 | // Check for required permissions, CRM-6264. |
6a488035 | 287 | if ($this->_activityId && |
96f94695 | 288 | in_array($this->_action, [ |
19fc6ae4 | 289 | CRM_Core_Action::UPDATE, |
21dfd5f5 | 290 | CRM_Core_Action::VIEW, |
96f94695 | 291 | ]) && |
6a488035 TO |
292 | !CRM_Activity_BAO_Activity::checkPermission($this->_activityId, $this->_action) |
293 | ) { | |
2b795b1f | 294 | CRM_Core_Error::statusBounce(ts('You do not have permission to access this page.')); |
6a488035 TO |
295 | } |
296 | if (($this->_action & CRM_Core_Action::VIEW) && | |
297 | CRM_Activity_BAO_Activity::checkPermission($this->_activityId, CRM_Core_Action::UPDATE) | |
298 | ) { | |
299 | $this->assign('permission', 'edit'); | |
55806731 | 300 | $this->assign('allow_edit_inbound_emails', CRM_Activity_BAO_Activity::checkEditInboundEmailsPermissions()); |
6a488035 TO |
301 | } |
302 | ||
303 | if (!$this->_activityTypeId && $this->_activityId) { | |
304 | $this->_activityTypeId = CRM_Core_DAO::getFieldValue('CRM_Activity_DAO_Activity', | |
305 | $this->_activityId, | |
306 | 'activity_type_id' | |
307 | ); | |
308 | } | |
309 | ||
c6bbfc3a | 310 | $this->assignActivityType(); |
6a488035 | 311 | |
7808aae6 SB |
312 | // Check the mode when this form is called either single or as |
313 | // search task action. | |
6a488035 | 314 | if ($this->_activityTypeId || |
5d7c2bd2 | 315 | $this->_context === 'standalone' || |
6a488035 TO |
316 | $this->_currentlyViewedContactId |
317 | ) { | |
318 | $this->_single = TRUE; | |
319 | $this->assign('urlPath', 'civicrm/activity'); | |
320 | } | |
321 | else { | |
7808aae6 | 322 | // Set the appropriate action. |
6a488035 TO |
323 | $url = CRM_Utils_System::currentPath(); |
324 | $urlArray = explode('/', $url); | |
50237bc9 | 325 | $searchPath = array_pop($urlArray); |
6a488035 TO |
326 | $searchType = 'basic'; |
327 | $this->_action = CRM_Core_Action::BASIC; | |
50237bc9 | 328 | switch ($searchPath) { |
6a488035 | 329 | case 'basic': |
50237bc9 | 330 | $searchType = $searchPath; |
6a488035 TO |
331 | $this->_action = CRM_Core_Action::BASIC; |
332 | break; | |
333 | ||
334 | case 'advanced': | |
50237bc9 | 335 | $searchType = $searchPath; |
6a488035 TO |
336 | $this->_action = CRM_Core_Action::ADVANCED; |
337 | break; | |
338 | ||
339 | case 'builder': | |
50237bc9 | 340 | $searchType = $searchPath; |
6a488035 TO |
341 | $this->_action = CRM_Core_Action::PROFILE; |
342 | break; | |
343 | ||
344 | case 'custom': | |
345 | $this->_action = CRM_Core_Action::COPY; | |
50237bc9 | 346 | $searchType = $searchPath; |
6a488035 TO |
347 | break; |
348 | } | |
349 | ||
350 | parent::preProcess(); | |
351 | $this->_single = FALSE; | |
352 | ||
353 | $this->assign('urlPath', "civicrm/contact/search/$searchType"); | |
354 | $this->assign('urlPathVar', "_qf_Activity_display=true&qfKey={$this->controller->_key}"); | |
355 | } | |
356 | ||
357 | $this->assign('single', $this->_single); | |
358 | $this->assign('action', $this->_action); | |
359 | ||
360 | if ($this->_action & CRM_Core_Action::VIEW) { | |
7808aae6 | 361 | // Get the tree of custom fields. |
0b330e6d | 362 | $this->_groupTree = CRM_Core_BAO_CustomGroup::getTree('Activity', NULL, |
6a488035 TO |
363 | $this->_activityId, 0, $this->_activityTypeId |
364 | ); | |
365 | } | |
366 | ||
367 | if ($this->_activityTypeId) { | |
7808aae6 | 368 | // Set activity type name and description to template. |
6a488035 TO |
369 | list($this->_activityTypeName, $activityTypeDescription) = CRM_Core_BAO_OptionValue::getActivityTypeDetails($this->_activityTypeId); |
370 | $this->assign('activityTypeName', $this->_activityTypeName); | |
371 | $this->assign('activityTypeDescription', $activityTypeDescription); | |
372 | } | |
373 | ||
374 | // set user context | |
375 | $urlParams = $urlString = NULL; | |
9479d7d0 DS |
376 | $qfKey = CRM_Utils_Request::retrieve('key', 'String', $this); |
377 | if (!$qfKey) { | |
378 | $qfKey = CRM_Utils_Request::retrieve('qfKey', 'String', $this); | |
379 | } | |
6a488035 | 380 | |
7808aae6 | 381 | // Validate the qfKey. |
6a488035 TO |
382 | if (!CRM_Utils_Rule::qfKey($qfKey)) { |
383 | $qfKey = NULL; | |
384 | } | |
385 | ||
5d7c2bd2 | 386 | if ($this->_context === 'fulltext') { |
19fc6ae4 | 387 | $keyName = '&qfKey'; |
6a488035 TO |
388 | $urlParams = 'force=1'; |
389 | $urlString = 'civicrm/contact/search/custom'; | |
390 | if ($this->_action == CRM_Core_Action::UPDATE) { | |
391 | $keyName = '&key'; | |
392 | $urlParams .= '&context=fulltext&action=view'; | |
393 | $urlString = 'civicrm/contact/view/activity'; | |
394 | } | |
395 | if ($qfKey) { | |
396 | $urlParams .= "$keyName=$qfKey"; | |
397 | } | |
398 | $this->assign('searchKey', $qfKey); | |
399 | } | |
96f94695 | 400 | elseif (in_array($this->_context, [ |
19fc6ae4 | 401 | 'standalone', |
402 | 'home', | |
403 | 'dashlet', | |
21dfd5f5 | 404 | 'dashletFullscreen', |
96f94695 | 405 | ]) |
19fc6ae4 | 406 | ) { |
6a488035 TO |
407 | $urlParams = 'reset=1'; |
408 | $urlString = 'civicrm/dashboard'; | |
409 | } | |
5d7c2bd2 | 410 | elseif ($this->_context === 'search') { |
6a488035 TO |
411 | $urlParams = 'force=1'; |
412 | if ($qfKey) { | |
413 | $urlParams .= "&qfKey=$qfKey"; | |
414 | } | |
7964ef53 | 415 | $path = CRM_Utils_System::currentPath(); |
5d7c2bd2 | 416 | if ($this->_compContext === 'advanced') { |
6a488035 TO |
417 | $urlString = 'civicrm/contact/search/advanced'; |
418 | } | |
5d7c2bd2 | 419 | elseif ($path === 'civicrm/group/search' |
420 | || $path === 'civicrm/contact/search' | |
421 | || $path === 'civicrm/contact/search/advanced' | |
422 | || $path === 'civicrm/contact/search/custom' | |
423 | || $path === 'civicrm/group/search' | |
424 | || $path === 'civicrm/contact/search/builder' | |
353ffa53 | 425 | ) { |
d31f1ab3 AH |
426 | $urlString = $path; |
427 | } | |
6a488035 | 428 | else { |
d31f1ab3 | 429 | $urlString = 'civicrm/activity/search'; |
6a488035 TO |
430 | } |
431 | $this->assign('searchKey', $qfKey); | |
432 | } | |
5d7c2bd2 | 433 | elseif ($this->_context !== 'caseActivity') { |
6a488035 TO |
434 | $urlParams = "action=browse&reset=1&cid={$this->_currentlyViewedContactId}&selectedChild=activity"; |
435 | $urlString = 'civicrm/contact/view'; | |
436 | } | |
437 | ||
438 | if ($urlString) { | |
439 | $session->pushUserContext(CRM_Utils_System::url($urlString, $urlParams)); | |
440 | } | |
441 | ||
442 | // hack to retrieve activity type id from post variables | |
443 | if (!$this->_activityTypeId) { | |
9c1bc317 | 444 | $this->_activityTypeId = $_POST['activity_type_id'] ?? NULL; |
6a488035 TO |
445 | } |
446 | ||
447 | // when custom data is included in this page | |
2fcb4a7f | 448 | $this->assign('cid', $this->_currentlyViewedContactId); |
a7488080 | 449 | if (!empty($_POST['hidden_custom'])) { |
7808aae6 | 450 | // We need to set it in the session for the code below to work. |
6a488035 | 451 | // CRM-3014 |
7808aae6 | 452 | // Need to assign custom data subtype to the template. |
6a488035 TO |
453 | $this->set('type', 'Activity'); |
454 | $this->set('subType', $this->_activityTypeId); | |
455 | $this->set('entityId', $this->_activityId); | |
c5366541 | 456 | CRM_Custom_Form_CustomData::preProcess($this, NULL, $this->_activityTypeId, 1, 'Activity', $this->_activityId); |
6a488035 TO |
457 | CRM_Custom_Form_CustomData::buildQuickForm($this); |
458 | CRM_Custom_Form_CustomData::setDefaultValues($this); | |
459 | } | |
460 | ||
461 | // add attachments part | |
462 | CRM_Core_BAO_File::buildAttachment($this, 'civicrm_activity', $this->_activityId, NULL, TRUE); | |
463 | ||
464 | // figure out the file name for activity type, if any | |
465 | if ($this->_activityTypeId && | |
6c552737 | 466 | $this->_activityTypeFile = CRM_Activity_BAO_Activity::getFileForActivityTypeId($this->_activityTypeId, $this->_crmDir) |
6a488035 TO |
467 | ) { |
468 | $this->assign('activityTypeFile', $this->_activityTypeFile); | |
469 | $this->assign('crmDir', $this->_crmDir); | |
470 | } | |
471 | ||
472 | $this->setFields(); | |
473 | ||
474 | if ($this->_activityTypeFile) { | |
0e6e8724 DL |
475 | $className = "CRM_{$this->_crmDir}_Form_Activity_{$this->_activityTypeFile}"; |
476 | $className::preProcess($this); | |
6a488035 TO |
477 | } |
478 | ||
479 | $this->_values = $this->get('values'); | |
480 | if (!is_array($this->_values)) { | |
96f94695 | 481 | $this->_values = []; |
6a488035 | 482 | if (isset($this->_activityId) && $this->_activityId) { |
96f94695 | 483 | $params = ['id' => $this->_activityId]; |
6a488035 TO |
484 | CRM_Activity_BAO_Activity::retrieve($params, $this->_values); |
485 | } | |
ee90a98c | 486 | |
6a488035 TO |
487 | $this->set('values', $this->_values); |
488 | } | |
59d63f8b | 489 | |
78fe87e6 | 490 | if ($this->_action & CRM_Core_Action::UPDATE) { |
ee90a98c | 491 | // We filter out alternatives, in case this is a stored e-mail, before sending to front-end |
40e67970 SL |
492 | if (isset($this->_values['details'])) { |
493 | $this->_values['details'] = CRM_Utils_String::stripAlternatives($this->_values['details']) ?: ''; | |
494 | } | |
ee90a98c CR |
495 | |
496 | if ($this->_activityTypeName === 'Inbound Email' && | |
497 | !CRM_Core_Permission::check('edit inbound email basic information and content') | |
498 | ) { | |
499 | $this->_fields['details']['type'] = 'static'; | |
500 | } | |
501 | ||
8cec51b0 | 502 | CRM_Core_Form_RecurringEntity::preProcess('civicrm_activity'); |
78fe87e6 | 503 | } |
234fa48a NH |
504 | |
505 | if ($this->_action & CRM_Core_Action::VIEW) { | |
506 | $url = CRM_Utils_System::url(implode("/", $this->urlPath), "reset=1&id={$this->_activityId}&action=view&cid={$this->_values['source_contact_id']}"); | |
443f35e1 | 507 | CRM_Utils_Recent::add(CRM_Utils_Array::value('subject', $this->_values, ts('(no subject)')), |
234fa48a NH |
508 | $url, |
509 | $this->_values['id'], | |
510 | 'Activity', | |
511 | $this->_values['source_contact_id'], | |
512 | $this->_values['source_contact'] | |
513 | ); | |
514 | } | |
6a488035 | 515 | } |
59d63f8b | 516 | |
6a488035 | 517 | /** |
b6c94f42 | 518 | * Set default values for the form. |
6a488035 | 519 | * |
b6c94f42 | 520 | * For edit/view mode the default values are retrieved from the database. |
7808aae6 SB |
521 | * |
522 | * @return array | |
6a488035 | 523 | */ |
00be9182 | 524 | public function setDefaultValues() { |
6a488035 | 525 | |
d2a4c29b | 526 | $defaults = $this->_values + CRM_Core_Form_RecurringEntity::setDefaultValues(); |
6a488035 TO |
527 | // if we're editing... |
528 | if (isset($this->_activityId)) { | |
6a488035 | 529 | |
5d7c2bd2 | 530 | if ($this->_context !== 'standalone') { |
6a488035 TO |
531 | $this->assign('target_contact_value', |
532 | CRM_Utils_Array::value('target_contact_value', $defaults) | |
533 | ); | |
534 | $this->assign('assignee_contact_value', | |
535 | CRM_Utils_Array::value('assignee_contact_value', $defaults) | |
536 | ); | |
6a488035 TO |
537 | } |
538 | ||
c27ebe4e | 539 | // Fixme: why are we getting the wrong keys from upstream? |
9c1bc317 CW |
540 | $defaults['target_contact_id'] = $defaults['target_contact'] ?? NULL; |
541 | $defaults['assignee_contact_id'] = $defaults['assignee_contact'] ?? NULL; | |
c27ebe4e | 542 | |
6a488035 | 543 | // set default tags if exists |
b733747a | 544 | $defaults['tag'] = implode(',', CRM_Core_BAO_EntityTag::getTag($this->_activityId, 'civicrm_activity')); |
6a488035 TO |
545 | } |
546 | else { | |
547 | // if it's a new activity, we need to set default values for associated contact fields | |
6a488035 TO |
548 | $this->_sourceContactId = $this->_currentUserId; |
549 | $this->_targetContactId = $this->_currentlyViewedContactId; | |
6a488035 | 550 | |
f7305cbc | 551 | $defaults['source_contact_id'] = $this->_sourceContactId; |
c27ebe4e | 552 | $defaults['target_contact_id'] = $this->_targetContactId; |
d104311a | 553 | } |
6a488035 | 554 | |
d104311a CW |
555 | if (empty($defaults['activity_date_time'])) { |
556 | $defaults['activity_date_time'] = date('Y-m-d H:i:s'); | |
6a488035 TO |
557 | } |
558 | ||
559 | if ($this->_activityTypeId) { | |
560 | $defaults['activity_type_id'] = $this->_activityTypeId; | |
561 | } | |
562 | ||
ab911378 PJ |
563 | if (!$this->_single && !empty($this->_contactIds)) { |
564 | $defaults['target_contact_id'] = $this->_contactIds; | |
565 | } | |
566 | ||
b44e3f84 | 567 | // CRM-15472 - 50 is around the practical limit of how many items a select2 entityRef can handle |
531d3b28 | 568 | if ($this->_action == CRM_Core_Action::UPDATE && !empty($defaults['target_contact_id'])) { |
33913af6 CW |
569 | $count = count(is_array($defaults['target_contact_id']) ? $defaults['target_contact_id'] : explode(',', $defaults['target_contact_id'])); |
570 | if ($count > 50) { | |
96f94695 | 571 | $this->freeze(['target_contact_id']); |
33913af6 CW |
572 | } |
573 | } | |
574 | ||
6a488035 TO |
575 | if ($this->_action & (CRM_Core_Action::DELETE | CRM_Core_Action::RENEW)) { |
576 | $this->assign('delName', CRM_Utils_Array::value('subject', $defaults)); | |
577 | } | |
578 | ||
579 | if ($this->_activityTypeFile) { | |
0e6e8724 DL |
580 | $className = "CRM_{$this->_crmDir}_Form_Activity_{$this->_activityTypeFile}"; |
581 | $defaults += $className::setDefaultValues($this); | |
6a488035 | 582 | } |
a7488080 | 583 | if (empty($defaults['priority_id'])) { |
cbf48754 | 584 | $priority = CRM_Core_PseudoConstant::get('CRM_Activity_DAO_Activity', 'priority_id'); |
013d0f03 | 585 | $defaults['priority_id'] = CRM_Core_PseudoConstant::getKey('CRM_Activity_DAO_Activity', 'priority_id', 'Normal'); |
6a488035 | 586 | } |
a7488080 | 587 | if (empty($defaults['status_id'])) { |
343d84fa DG |
588 | $defaults['status_id'] = CRM_Core_OptionGroup::getDefaultValue('activity_status'); |
589 | } | |
6a488035 TO |
590 | return $defaults; |
591 | } | |
592 | ||
d51c6add | 593 | /** |
594 | * Build Quick form. | |
595 | * | |
596 | * @throws \CRM_Core_Exception | |
597 | * @throws \CiviCRM_API3_Exception | |
598 | */ | |
6a488035 TO |
599 | public function buildQuickForm() { |
600 | if ($this->_action & (CRM_Core_Action::DELETE | CRM_Core_Action::RENEW)) { | |
601 | //enable form element (ActivityLinks sets this true) | |
602 | $this->assign('suppressForm', FALSE); | |
603 | ||
604 | $button = ts('Delete'); | |
605 | if ($this->_action & CRM_Core_Action::RENEW) { | |
606 | $button = ts('Restore'); | |
607 | } | |
96f94695 | 608 | $this->addButtons([ |
609 | [ | |
19fc6ae4 | 610 | 'type' => 'next', |
611 | 'name' => $button, | |
612 | 'spacing' => ' ', | |
21dfd5f5 | 613 | 'isDefault' => TRUE, |
96f94695 | 614 | ], |
615 | [ | |
19fc6ae4 | 616 | 'type' => 'cancel', |
21dfd5f5 | 617 | 'name' => ts('Cancel'), |
96f94695 | 618 | ], |
619 | ]); | |
6a488035 TO |
620 | return; |
621 | } | |
622 | ||
7808aae6 | 623 | // Build other activity links. |
cfcb7676 | 624 | CRM_Activity_Form_ActivityLinks::commonBuildQuickForm($this); |
6a488035 | 625 | |
7808aae6 | 626 | // Enable form element (ActivityLinks sets this true). |
6a488035 TO |
627 | $this->assign('suppressForm', FALSE); |
628 | ||
92eacb41 | 629 | $element = $this->add('select', 'activity_type_id', ts('Activity Type'), |
96f94695 | 630 | ['' => '- ' . ts('select') . ' -'] + $this->_fields['followup_activity_type_id']['attributes'], |
631 | FALSE, [ | |
2fcb4a7f | 632 | 'onchange' => "CRM.buildCustomData( 'Activity', this.value, false, false, false, false, false, false, {$this->_currentlyViewedContactId});", |
ba6e6f51 | 633 | 'class' => 'crm-select2 required', |
96f94695 | 634 | ] |
6a488035 TO |
635 | ); |
636 | ||
7808aae6 | 637 | // Freeze for update mode. |
6a488035 TO |
638 | if ($this->_action & CRM_Core_Action::UPDATE) { |
639 | $element->freeze(); | |
b334d9ad | 640 | } |
641 | ||
7808aae6 | 642 | // Call to RecurringEntity buildQuickForm for add/update mode. |
b334d9ad | 643 | if ($this->_action & (CRM_Core_Action::UPDATE | CRM_Core_Action::ADD)) { |
78fe87e6 | 644 | CRM_Core_Form_RecurringEntity::buildQuickForm($this); |
6a488035 TO |
645 | } |
646 | ||
647 | foreach ($this->_fields as $field => $values) { | |
a7488080 | 648 | if (!empty($this->_fields[$field])) { |
9c1bc317 | 649 | $attribute = $values['attributes'] ?? NULL; |
475e9f44 | 650 | $required = !empty($values['required']); |
6a488035 | 651 | |
5d7c2bd2 | 652 | if ($values['type'] === 'select' && empty($attribute)) { |
96f94695 | 653 | $this->addSelect($field, ['entity' => 'activity'], $required); |
c27ebe4e | 654 | } |
5d7c2bd2 | 655 | elseif ($values['type'] === 'entityRef') { |
c27ebe4e | 656 | $this->addEntityRef($field, $values['label'], $attribute, $required); |
475e9f44 | 657 | } |
c27ebe4e | 658 | else { |
5e72d8ae | 659 | $this->add($values['type'], $field, $values['label'], $attribute, $required, CRM_Utils_Array::value('extra', $values)); |
6a488035 TO |
660 | } |
661 | } | |
662 | } | |
663 | ||
7808aae6 | 664 | // CRM-7362 --add campaigns. |
6a488035 TO |
665 | CRM_Campaign_BAO_Campaign::addCampaign($this, CRM_Utils_Array::value('campaign_id', $this->_values)); |
666 | ||
7808aae6 | 667 | // Add engagement level CRM-7775 |
6a488035 TO |
668 | $buildEngagementLevel = FALSE; |
669 | if (CRM_Campaign_BAO_Campaign::isCampaignEnable() && | |
670 | CRM_Campaign_BAO_Campaign::accessCampaign() | |
671 | ) { | |
672 | $buildEngagementLevel = TRUE; | |
96f94695 | 673 | $this->addSelect('engagement_level', ['entity' => 'activity']); |
6a488035 TO |
674 | $this->addRule('engagement_level', |
675 | ts('Please enter the engagement index as a number (integers only).'), | |
676 | 'positiveInteger' | |
677 | ); | |
678 | } | |
679 | $this->assign('buildEngagementLevel', $buildEngagementLevel); | |
680 | ||
681 | // check for survey activity | |
682 | $this->_isSurveyActivity = FALSE; | |
683 | ||
684 | if ($this->_activityId && CRM_Campaign_BAO_Campaign::isCampaignEnable() && | |
685 | CRM_Campaign_BAO_Campaign::accessCampaign() | |
686 | ) { | |
687 | ||
688 | $this->_isSurveyActivity = CRM_Campaign_BAO_Survey::isSurveyActivity($this->_activityId); | |
689 | if ($this->_isSurveyActivity) { | |
690 | $surveyId = CRM_Core_DAO::getFieldValue('CRM_Activity_DAO_Activity', | |
691 | $this->_activityId, | |
692 | 'source_record_id' | |
693 | ); | |
694 | $responseOptions = CRM_Campaign_BAO_Survey::getResponsesOptions($surveyId); | |
695 | if ($responseOptions) { | |
696 | $this->add('select', 'result', ts('Result'), | |
96f94695 | 697 | ['' => ts('- select -')] + array_combine($responseOptions, $responseOptions) |
6a488035 TO |
698 | ); |
699 | } | |
700 | $surveyTitle = NULL; | |
701 | if ($surveyId) { | |
702 | $surveyTitle = CRM_Core_DAO::getFieldValue('CRM_Campaign_DAO_Survey', $surveyId, 'title'); | |
703 | } | |
704 | $this->assign('surveyTitle', $surveyTitle); | |
705 | } | |
706 | } | |
707 | $this->assign('surveyActivity', $this->_isSurveyActivity); | |
708 | ||
598e9b75 | 709 | // Add the "Activity Separation" field |
03ca7bcb | 710 | $actionIsAdd = ($this->_action != CRM_Core_Action::UPDATE && $this->_action != CRM_Core_Action::VIEW); |
598e9b75 SM |
711 | $separationIsPossible = $this->supportsActivitySeparation; |
712 | if ($actionIsAdd && $separationIsPossible) { | |
a850c3fe SM |
713 | $this->addRadio( |
714 | 'separation', | |
715 | ts('Activity Separation'), | |
96f94695 | 716 | [ |
a850c3fe SM |
717 | 'separate' => ts('Create separate activities for each contact'), |
718 | 'combined' => ts('Create one activity with all contacts together'), | |
96f94695 | 719 | ] |
a850c3fe | 720 | ); |
52c7b3a2 KJ |
721 | } |
722 | ||
6a488035 TO |
723 | $this->addRule('duration', |
724 | ts('Please enter the duration as number of minutes (integers only).'), 'positiveInteger' | |
725 | ); | |
6a488035 | 726 | |
7808aae6 | 727 | // Add followup date. |
d7c5e6c3 | 728 | $this->add('datepicker', 'followup_date', ts('in')); |
6a488035 | 729 | |
f7305cbc | 730 | // Only admins and case-workers can change the activity source |
5d7c2bd2 | 731 | if (!CRM_Core_Permission::check('administer CiviCRM') && $this->_context !== 'caseActivity') { |
c27ebe4e | 732 | $this->getElement('source_contact_id')->freeze(); |
f7305cbc | 733 | } |
6a488035 | 734 | |
6a488035 TO |
735 | //need to assign custom data type and subtype to the template |
736 | $this->assign('customDataType', 'Activity'); | |
737 | $this->assign('customDataSubType', $this->_activityTypeId); | |
738 | $this->assign('entityID', $this->_activityId); | |
739 | ||
b733747a | 740 | $tags = CRM_Core_BAO_Tag::getColorTags('civicrm_activity'); |
6a488035 TO |
741 | |
742 | if (!empty($tags)) { | |
96f94695 | 743 | $this->add('select2', 'tag', ts('Tags'), $tags, FALSE, [ |
744 | 'class' => 'huge', | |
745 | 'placeholder' => ts('- select -'), | |
746 | 'multiple' => TRUE, | |
747 | ]); | |
6a488035 TO |
748 | } |
749 | ||
750 | // we need to hide activity tagset for special activities | |
96f94695 | 751 | $specialActivities = ['Open Case']; |
6a488035 TO |
752 | |
753 | if (!in_array($this->_activityTypeName, $specialActivities)) { | |
754 | // build tag widget | |
755 | $parentNames = CRM_Core_BAO_Tag::getTagSet('civicrm_activity'); | |
95ef220a | 756 | CRM_Core_Form_Tag::buildQuickForm($this, $parentNames, 'civicrm_activity', $this->_activityId); |
6a488035 TO |
757 | } |
758 | ||
759 | // if we're viewing, we're assigning different buttons than for adding/editing | |
760 | if ($this->_action & CRM_Core_Action::VIEW) { | |
761 | if (isset($this->_groupTree)) { | |
080d719e | 762 | CRM_Core_BAO_CustomGroup::buildCustomDataView($this, $this->_groupTree, FALSE, NULL, NULL, NULL, $this->_activityId); |
6a488035 | 763 | } |
6a488035 TO |
764 | // form should be frozen for view mode |
765 | $this->freeze(); | |
766 | ||
e517eb43 MWMC |
767 | $this->addButtons([ |
768 | [ | |
769 | 'type' => 'cancel', | |
770 | 'name' => ts('Done'), | |
771 | ], | |
772 | ]); | |
6a488035 TO |
773 | } |
774 | else { | |
e517eb43 MWMC |
775 | $this->addButtons([ |
776 | [ | |
c5c263ca AH |
777 | 'type' => 'upload', |
778 | 'name' => ts('Save'), | |
c5c263ca | 779 | 'isDefault' => TRUE, |
e517eb43 MWMC |
780 | ], |
781 | [ | |
c5c263ca AH |
782 | 'type' => 'cancel', |
783 | 'name' => ts('Cancel'), | |
e517eb43 MWMC |
784 | ], |
785 | ]); | |
6a488035 TO |
786 | } |
787 | ||
788 | if ($this->_activityTypeFile) { | |
0e6e8724 | 789 | $className = "CRM_{$this->_crmDir}_Form_Activity_{$this->_activityTypeFile}"; |
6a488035 | 790 | |
0e6e8724 | 791 | $className::buildQuickForm($this); |
96f94695 | 792 | $this->addFormRule([$className, 'formRule'], $this); |
6a488035 TO |
793 | } |
794 | ||
96f94695 | 795 | $this->addFormRule(['CRM_Activity_Form_Activity', 'formRule'], $this); |
6db7e202 | 796 | |
96f94695 | 797 | $doNotNotifyAssigneeFor = (array) Civi::settings() |
798 | ->get('do_not_notify_assignees_for'); | |
799 | if (($this->_activityTypeId && in_array($this->_activityTypeId, $doNotNotifyAssigneeFor)) || !Civi::settings() | |
62d3ee27 | 800 | ->get('activity_assignee_notification')) { |
e680ea41 | 801 | $this->assign('activityAssigneeNotification', FALSE); |
0086c33d DL |
802 | } |
803 | else { | |
e680ea41 | 804 | $this->assign('activityAssigneeNotification', TRUE); |
6db7e202 | 805 | } |
e680ea41 | 806 | $this->assign('doNotNotifyAssigneeFor', $doNotNotifyAssigneeFor); |
6a488035 TO |
807 | } |
808 | ||
809 | /** | |
fe482240 | 810 | * Global form rule. |
6a488035 | 811 | * |
041ab3d1 TO |
812 | * @param array $fields |
813 | * The input form values. | |
814 | * @param array $files | |
815 | * The uploaded files if any. | |
2a6da8d7 EM |
816 | * @param $self |
817 | * | |
72b3a70c CW |
818 | * @return bool|array |
819 | * true if no errors, else array of errors | |
6a488035 | 820 | */ |
00be9182 | 821 | public static function formRule($fields, $files, $self) { |
6a488035 | 822 | // skip form rule if deleting |
5d7c2bd2 | 823 | if (($fields['_qf_Activity_next_'] ?? NULL) === 'Delete') { |
6a488035 TO |
824 | return TRUE; |
825 | } | |
96f94695 | 826 | $errors = []; |
ba6e6f51 | 827 | if ((array_key_exists('activity_type_id', $fields) || !$self->_single) && empty($fields['activity_type_id'])) { |
6a488035 TO |
828 | $errors['activity_type_id'] = ts('Activity Type is a required field'); |
829 | } | |
830 | ||
9c1bc317 CW |
831 | $activity_type_id = $fields['activity_type_id'] ?? NULL; |
832 | $activity_status_id = $fields['status_id'] ?? NULL; | |
f47754ac ML |
833 | $scheduled_status_id = CRM_Core_PseudoConstant::getKey('CRM_Activity_BAO_Activity', 'status_id', 'Scheduled'); |
834 | ||
835 | if ($activity_type_id && $activity_status_id == $scheduled_status_id) { | |
836 | if ($activity_type_id == CRM_Core_PseudoConstant::getKey('CRM_Activity_BAO_Activity', 'activity_type_id', 'Email')) { | |
837 | $errors['status_id'] = ts('You cannot record scheduled email activity.'); | |
838 | } | |
839 | elseif ($activity_type_id == CRM_Core_PseudoConstant::getKey('CRM_Activity_BAO_Activity', 'activity_type_id', 'SMS')) { | |
840 | $errors['status_id'] = ts('You cannot record scheduled SMS activity'); | |
841 | } | |
6a488035 TO |
842 | } |
843 | ||
8cc574cf | 844 | if (!empty($fields['followup_activity_type_id']) && empty($fields['followup_date'])) { |
d7c5e6c3 | 845 | $errors['followup_date'] = ts('Followup date is a required field.'); |
6a488035 | 846 | } |
7808aae6 | 847 | // Activity type is mandatory if subject or follow-up date is specified for an Follow-up activity, CRM-4515. |
8cc574cf | 848 | if ((!empty($fields['followup_activity_subject']) || !empty($fields['followup_date'])) && empty($fields['followup_activity_type_id'])) { |
6a488035 TO |
849 | $errors['followup_activity_subject'] = ts('Follow-up Activity type is a required field.'); |
850 | } | |
53c79877 SM |
851 | |
852 | // Check that a value has been set for the "activity separation" field if needed | |
853 | $separationIsPossible = $self->supportsActivitySeparation; | |
a850c3fe SM |
854 | $actionIsAdd = $self->_action == CRM_Core_Action::ADD; |
855 | $hasMultipleTargetContacts = !empty($fields['target_contact_id']) && strpos($fields['target_contact_id'], ',') !== FALSE; | |
856 | $separationFieldIsEmpty = empty($fields['separation']); | |
53c79877 | 857 | if ($separationIsPossible && $actionIsAdd && $hasMultipleTargetContacts && $separationFieldIsEmpty) { |
a850c3fe SM |
858 | $errors['separation'] = ts('Activity Separation is a required field.'); |
859 | } | |
53c79877 | 860 | |
6a488035 TO |
861 | return $errors; |
862 | } | |
863 | ||
864 | /** | |
fe482240 | 865 | * Process the form submission. |
6a488035 | 866 | * |
6a488035 | 867 | * |
100fef9d | 868 | * @param array $params |
d51c6add | 869 | * |
100fef9d | 870 | * @return array|null |
531d3b28 | 871 | * @throws \CiviCRM_API3_Exception |
6a488035 TO |
872 | */ |
873 | public function postProcess($params = NULL) { | |
874 | if ($this->_action & CRM_Core_Action::DELETE) { | |
a6ebc13f KJ |
875 | // Look up any repeat activities to be deleted. |
876 | $activityIds = array_column(CRM_Core_BAO_RecurringEntity::getEntitiesFor($this->_activityId, 'civicrm_activity', TRUE, NULL), 'id'); | |
877 | if (!$activityIds) { | |
878 | // There are no repeat activities to delete - just this one. | |
879 | $activityIds = [$this->_activityId]; | |
880 | } | |
881 | ||
882 | // Delete each activity. | |
883 | foreach ($activityIds as $activityId) { | |
884 | $deleteParams = ['id' => $activityId]; | |
885 | $moveToTrash = CRM_Case_BAO_Case::isCaseActivity($activityId); | |
886 | CRM_Activity_BAO_Activity::deleteActivity($deleteParams, $moveToTrash); | |
6a488035 | 887 | |
a6ebc13f KJ |
888 | // delete tags for the entity |
889 | $tagParams = [ | |
890 | 'entity_table' => 'civicrm_activity', | |
891 | 'entity_id' => $activityId, | |
892 | ]; | |
6a488035 | 893 | |
a6ebc13f KJ |
894 | CRM_Core_BAO_EntityTag::del($tagParams); |
895 | } | |
896 | ||
897 | CRM_Core_Session::setStatus( | |
898 | ts("Selected Activity has been deleted successfully.", ['plural' => '%count Activities have been deleted successfully.', 'count' => count($activityIds)]), | |
899 | ts('Record Deleted', ['plural' => 'Records Deleted', 'count' => count($activityIds)]), 'success' | |
900 | ); | |
6a488035 | 901 | |
a1a2a83d | 902 | return NULL; |
6a488035 TO |
903 | } |
904 | ||
905 | // store the submitted values in an array | |
906 | if (!$params) { | |
907 | $params = $this->controller->exportValues($this->_name); | |
908 | } | |
909 | ||
7808aae6 | 910 | // Set activity type id. |
a7488080 | 911 | if (empty($params['activity_type_id'])) { |
6a488035 TO |
912 | $params['activity_type_id'] = $this->_activityTypeId; |
913 | } | |
914 | ||
a7488080 | 915 | if (!empty($params['hidden_custom']) && |
6a488035 TO |
916 | !isset($params['custom']) |
917 | ) { | |
918 | $customFields = CRM_Core_BAO_CustomField::getFields('Activity', FALSE, FALSE, | |
919 | $this->_activityTypeId | |
920 | ); | |
921 | $customFields = CRM_Utils_Array::crmArrayMerge($customFields, | |
922 | CRM_Core_BAO_CustomField::getFields('Activity', FALSE, FALSE, | |
923 | NULL, NULL, TRUE | |
924 | ) | |
925 | ); | |
926 | $params['custom'] = CRM_Core_BAO_CustomField::postProcess($params, | |
6a488035 TO |
927 | $this->_activityId, |
928 | 'Activity' | |
929 | ); | |
930 | } | |
931 | ||
c27ebe4e | 932 | // format params as arrays |
96f94695 | 933 | foreach (['target', 'assignee', 'followup_assignee'] as $name) { |
c27ebe4e CW |
934 | if (!empty($params["{$name}_contact_id"])) { |
935 | $params["{$name}_contact_id"] = explode(',', $params["{$name}_contact_id"]); | |
936 | } | |
937 | else { | |
96f94695 | 938 | $params["{$name}_contact_id"] = []; |
c27ebe4e | 939 | } |
6a488035 | 940 | } |
6a488035 TO |
941 | |
942 | // get ids for associated contacts | |
943 | if (!$params['source_contact_id']) { | |
944 | $params['source_contact_id'] = $this->_currentUserId; | |
945 | } | |
6a488035 TO |
946 | |
947 | if (isset($this->_activityId)) { | |
948 | $params['id'] = $this->_activityId; | |
949 | } | |
950 | ||
951 | // add attachments as needed | |
952 | CRM_Core_BAO_File::formatAttachment($params, | |
953 | $params, | |
954 | 'civicrm_activity', | |
955 | $this->_activityId | |
956 | ); | |
957 | ||
5d7c2bd2 | 958 | $params['is_multi_activity'] = ($params['separation'] ?? NULL) === 'separate'; |
a850c3fe | 959 | |
96f94695 | 960 | $activity = []; |
a7488080 | 961 | if (!empty($params['is_multi_activity']) && |
52c7b3a2 KJ |
962 | !CRM_Utils_Array::crmIsEmptyArray($params['target_contact_id']) |
963 | ) { | |
964 | $targetContacts = $params['target_contact_id']; | |
19fc6ae4 | 965 | foreach ($targetContacts as $targetContactId) { |
96f94695 | 966 | $params['target_contact_id'] = [$targetContactId]; |
52c7b3a2 KJ |
967 | // save activity |
968 | $activity[] = $this->processActivity($params); | |
969 | } | |
970 | } | |
971 | else { | |
972 | // save activity | |
973 | $activity = $this->processActivity($params); | |
974 | } | |
975 | ||
70f3519a | 976 | // Redirect to contact page or activity view in standalone mode |
5d7c2bd2 | 977 | if ($this->_context === 'standalone') { |
70f3519a CW |
978 | if (count($params['target_contact_id']) == 1) { |
979 | $url = CRM_Utils_System::url('civicrm/contact/view', ['cid' => CRM_Utils_Array::first($params['target_contact_id']), 'selectedChild' => 'activity']); | |
980 | } | |
981 | else { | |
982 | $url = CRM_Utils_System::url('civicrm/activity', ['action' => 'view', 'reset' => 1, 'id' => $this->_activityId]); | |
983 | } | |
984 | CRM_Core_Session::singleton()->pushUserContext($url); | |
985 | } | |
986 | ||
96f94695 | 987 | $activityIds = empty($this->_activityIds) ? [$this->_activityId] : $this->_activityIds; |
7a4bb524 | 988 | foreach ($activityIds as $activityId) { |
989 | // set params for repeat configuration in create mode | |
990 | $params['entity_id'] = $activityId; | |
991 | $params['entity_table'] = 'civicrm_activity'; | |
7a4bb524 | 992 | if (!empty($params['entity_id']) && !empty($params['entity_table'])) { |
993 | $checkParentExistsForThisId = CRM_Core_BAO_RecurringEntity::getParentFor($params['entity_id'], $params['entity_table']); | |
994 | if ($checkParentExistsForThisId) { | |
995 | $params['parent_entity_id'] = $checkParentExistsForThisId; | |
996 | $scheduleReminderDetails = CRM_Core_BAO_RecurringEntity::getReminderDetailsByEntityId($checkParentExistsForThisId, $params['entity_table']); | |
997 | } | |
998 | else { | |
999 | $params['parent_entity_id'] = $params['entity_id']; | |
1000 | $scheduleReminderDetails = CRM_Core_BAO_RecurringEntity::getReminderDetailsByEntityId($params['entity_id'], $params['entity_table']); | |
1001 | } | |
1002 | if (property_exists($scheduleReminderDetails, 'id')) { | |
1003 | $params['schedule_reminder_id'] = $scheduleReminderDetails->id; | |
1004 | } | |
fe87e754 | 1005 | } |
96f94695 | 1006 | $params['dateColumns'] = ['activity_date_time']; |
b334d9ad | 1007 | |
83f3c8a3 CW |
1008 | // Set default repetition start if it was not provided. |
1009 | if (empty($params['repetition_start_date'])) { | |
1010 | $params['repetition_start_date'] = $params['activity_date_time']; | |
1011 | } | |
1012 | ||
7a4bb524 | 1013 | // unset activity id |
1014 | unset($params['id']); | |
96f94695 | 1015 | $linkedEntities = [ |
1016 | [ | |
7a4bb524 | 1017 | 'table' => 'civicrm_activity_contact', |
96f94695 | 1018 | 'findCriteria' => [ |
7a4bb524 | 1019 | 'activity_id' => $activityId, |
96f94695 | 1020 | ], |
1021 | 'linkedColumns' => ['activity_id'], | |
7a4bb524 | 1022 | 'isRecurringEntityRecord' => FALSE, |
96f94695 | 1023 | ], |
1024 | ]; | |
7a4bb524 | 1025 | CRM_Core_Form_RecurringEntity::postProcess($params, 'civicrm_activity', $linkedEntities); |
1026 | } | |
b334d9ad | 1027 | |
96f94695 | 1028 | return ['activity' => $activity]; |
52c7b3a2 KJ |
1029 | } |
1030 | ||
1031 | /** | |
fe482240 | 1032 | * Process activity creation. |
52c7b3a2 | 1033 | * |
041ab3d1 TO |
1034 | * @param array $params |
1035 | * Associated array of submitted values. | |
77b97be7 | 1036 | * |
6c552737 | 1037 | * @return self|null|object |
5d7c2bd2 | 1038 | * @throws \CRM_Core_Exception |
52c7b3a2 KJ |
1039 | */ |
1040 | protected function processActivity(&$params) { | |
96f94695 | 1041 | $activityAssigned = []; |
44f817d4 | 1042 | $activityContacts = CRM_Activity_BAO_ActivityContact::buildOptions('record_type_id', 'validate'); |
034500d4 | 1043 | $assigneeID = CRM_Utils_Array::key('Activity Assignees', $activityContacts); |
6a488035 TO |
1044 | // format assignee params |
1045 | if (!CRM_Utils_Array::crmIsEmptyArray($params['assignee_contact_id'])) { | |
1046 | //skip those assignee contacts which are already assigned | |
1047 | //while sending a copy.CRM-4509. | |
1048 | $activityAssigned = array_flip($params['assignee_contact_id']); | |
1049 | if ($this->_activityId) { | |
034500d4 | 1050 | $assigneeContacts = CRM_Activity_BAO_ActivityContact::getNames($this->_activityId, $assigneeID); |
6a488035 TO |
1051 | $activityAssigned = array_diff_key($activityAssigned, $assigneeContacts); |
1052 | } | |
1053 | } | |
1054 | ||
1055 | // call begin post process. Idea is to let injecting file do | |
1056 | // any processing before the activity is added/updated. | |
1057 | $this->beginPostProcess($params); | |
1058 | ||
1059 | $activity = CRM_Activity_BAO_Activity::create($params); | |
1060 | ||
1061 | // add tags if exists | |
96f94695 | 1062 | $tagParams = []; |
6a488035 | 1063 | if (!empty($params['tag'])) { |
b733747a CW |
1064 | if (!is_array($params['tag'])) { |
1065 | $params['tag'] = explode(',', $params['tag']); | |
1066 | } | |
63b7aefc DB |
1067 | |
1068 | $tagParams = array_fill_keys($params['tag'], 1); | |
6a488035 TO |
1069 | } |
1070 | ||
7808aae6 | 1071 | // Save static tags. |
6a488035 TO |
1072 | CRM_Core_BAO_EntityTag::create($tagParams, 'civicrm_activity', $activity->id); |
1073 | ||
7808aae6 | 1074 | // Save free tags. |
6a488035 TO |
1075 | if (isset($params['activity_taglist']) && !empty($params['activity_taglist'])) { |
1076 | CRM_Core_Form_Tag::postProcess($params['activity_taglist'], $activity->id, 'civicrm_activity', $this); | |
1077 | } | |
1078 | ||
1079 | // call end post process. Idea is to let injecting file do any | |
1080 | // processing needed, after the activity has been added/updated. | |
1081 | $this->endPostProcess($params, $activity); | |
1082 | ||
1083 | // CRM-9590 | |
a7488080 | 1084 | if (!empty($params['is_multi_activity'])) { |
52c7b3a2 KJ |
1085 | $this->_activityIds[] = $activity->id; |
1086 | } | |
1087 | else { | |
1088 | $this->_activityId = $activity->id; | |
1089 | } | |
6a488035 TO |
1090 | |
1091 | // create follow up activity if needed | |
1092 | $followupStatus = ''; | |
90b05581 | 1093 | $followupActivity = NULL; |
a7488080 | 1094 | if (!empty($params['followup_activity_type_id'])) { |
90b05581 | 1095 | $followupActivity = CRM_Activity_BAO_Activity::createFollowupActivity($activity->id, $params); |
6a488035 TO |
1096 | $followupStatus = ts('A followup activity has been scheduled.'); |
1097 | } | |
1098 | ||
1099 | // send copy to assignee contacts.CRM-4509 | |
1100 | $mailStatus = ''; | |
1101 | ||
ac983377 | 1102 | if (Civi::settings()->get('activity_assignee_notification') |
96f94695 | 1103 | && !in_array($activity->activity_type_id, Civi::settings() |
1104 | ->get('do_not_notify_assignees_for'))) { | |
1105 | $activityIDs = [$activity->id]; | |
90b05581 | 1106 | if ($followupActivity) { |
96f94695 | 1107 | $activityIDs = array_merge($activityIDs, [$followupActivity->id]); |
90b05581 DG |
1108 | } |
1109 | $assigneeContacts = CRM_Activity_BAO_ActivityAssignment::getAssigneeNames($activityIDs, TRUE, FALSE); | |
6a488035 | 1110 | |
90b05581 | 1111 | if (!CRM_Utils_Array::crmIsEmptyArray($params['assignee_contact_id'])) { |
96f94695 | 1112 | $mailToContacts = []; |
90b05581 | 1113 | |
7808aae6 | 1114 | // Build an associative array with unique email addresses. |
90b05581 DG |
1115 | foreach ($activityAssigned as $id => $dnc) { |
1116 | if (isset($id) && array_key_exists($id, $assigneeContacts)) { | |
1117 | $mailToContacts[$assigneeContacts[$id]['email']] = $assigneeContacts[$id]; | |
1118 | } | |
6a488035 | 1119 | } |
6a488035 | 1120 | |
bc883279 | 1121 | $sent = CRM_Activity_BAO_Activity::sendToAssignee($activity, $mailToContacts); |
1122 | if ($sent) { | |
1123 | $mailStatus .= ts("A copy of the activity has also been sent to assignee contacts(s)."); | |
1124 | } | |
1125 | } | |
77b97be7 | 1126 | |
90b05581 DG |
1127 | // Also send email to follow-up activity assignees if set |
1128 | if ($followupActivity) { | |
96f94695 | 1129 | $mailToFollowupContacts = []; |
90b05581 DG |
1130 | foreach ($assigneeContacts as $values) { |
1131 | if ($values['activity_id'] == $followupActivity->id) { | |
1132 | $mailToFollowupContacts[$values['email']] = $values; | |
1133 | } | |
1134 | } | |
1135 | ||
2bbb4a91 | 1136 | $sentFollowup = CRM_Activity_BAO_Activity::sendToAssignee($followupActivity, $mailToFollowupContacts); |
bc883279 | 1137 | if ($sentFollowup) { |
f3c5a172 | 1138 | $mailStatus .= '<br />' . ts("A copy of the follow-up activity has also been sent to follow-up assignee contacts(s)."); |
bc883279 | 1139 | } |
6a488035 TO |
1140 | } |
1141 | } | |
1142 | ||
1143 | // set status message | |
ef89f226 | 1144 | $subject = ''; |
a7488080 | 1145 | if (!empty($params['subject'])) { |
ef89f226 | 1146 | $subject = "'" . $params['subject'] . "'"; |
6a488035 TO |
1147 | } |
1148 | ||
12e2d503 | 1149 | CRM_Core_Session::setStatus(ts('Activity %1 has been saved. %2 %3', |
96f94695 | 1150 | [ |
ef89f226 | 1151 | 1 => $subject, |
52c7b3a2 | 1152 | 2 => $followupStatus, |
21dfd5f5 | 1153 | 3 => $mailStatus, |
96f94695 | 1154 | ] |
52c7b3a2 | 1155 | ), ts('Saved'), 'success'); |
6a488035 | 1156 | |
52c7b3a2 | 1157 | return $activity; |
6a488035 TO |
1158 | } |
1159 | ||
1160 | /** | |
1161 | * Shorthand for getting id by display name (makes code more readable) | |
5d7c2bd2 | 1162 | * |
1163 | * @param string $displayName | |
1164 | * | |
645ee340 | 1165 | * @return null|string |
5d7c2bd2 | 1166 | * @throws \CRM_Core_Exception |
6a488035 TO |
1167 | */ |
1168 | protected function _getIdByDisplayName($displayName) { | |
1169 | return CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', | |
1170 | $displayName, | |
1171 | 'id', | |
1172 | 'sort_name' | |
1173 | ); | |
1174 | } | |
1175 | ||
1176 | /** | |
1177 | * Shorthand for getting display name by id (makes code more readable) | |
5d7c2bd2 | 1178 | * |
1179 | * @param int $id | |
1180 | * | |
645ee340 | 1181 | * @return null|string |
5d7c2bd2 | 1182 | * @throws \CRM_Core_Exception |
6a488035 TO |
1183 | */ |
1184 | protected function _getDisplayNameById($id) { | |
1185 | return CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', | |
1186 | $id, | |
1187 | 'sort_name', | |
1188 | 'id' | |
1189 | ); | |
1190 | } | |
1191 | ||
1192 | /** | |
fe482240 | 1193 | * Let injecting activity type file do any processing. |
6a488035 TO |
1194 | * needed, before the activity is added/updated |
1195 | * | |
100fef9d | 1196 | * @param array $params |
6a488035 | 1197 | */ |
00be9182 | 1198 | public function beginPostProcess(&$params) { |
6a488035 | 1199 | if ($this->_activityTypeFile) { |
0e6e8724 DL |
1200 | $className = "CRM_{$this->_crmDir}_Form_Activity_{$this->_activityTypeFile}"; |
1201 | $className::beginPostProcess($this, $params); | |
6a488035 TO |
1202 | } |
1203 | } | |
1204 | ||
1205 | /** | |
100fef9d | 1206 | * Let injecting activity type file do any processing |
6a488035 TO |
1207 | * needed, after the activity has been added/updated |
1208 | * | |
100fef9d CW |
1209 | * @param array $params |
1210 | * @param $activity | |
6a488035 | 1211 | */ |
00be9182 | 1212 | public function endPostProcess(&$params, &$activity) { |
6a488035 | 1213 | if ($this->_activityTypeFile) { |
0e6e8724 | 1214 | $className = "CRM_{$this->_crmDir}_Form_Activity_{$this->_activityTypeFile}"; |
100fef9d | 1215 | $className::endPostProcess($this, $params, $activity); |
6a488035 TO |
1216 | } |
1217 | } | |
96025800 | 1218 | |
794f8025 D |
1219 | /** |
1220 | * For the moment keeping this the same as the original pulled from preProcess(). Also note the "s" at the end of the function name - planning to change that but in baby steps. | |
1221 | * | |
1222 | * @return string[] | |
1223 | */ | |
1224 | public function getActivityTypeDisplayLabels() { | |
1225 | return CRM_Core_OptionGroup::values('activity_type', FALSE, FALSE, FALSE, 'AND v.value = ' . $this->_activityTypeId, 'label'); | |
1226 | } | |
1227 | ||
c6bbfc3a D |
1228 | /** |
1229 | * For the moment this is just pulled from preProcess | |
1230 | */ | |
1231 | public function assignActivityType() { | |
1232 | if ($this->_activityTypeId) { | |
1233 | $activityTypeDisplayLabels = $this->getActivityTypeDisplayLabels(); | |
1234 | if ($activityTypeDisplayLabels[$this->_activityTypeId]) { | |
1235 | $this->_activityTypeName = $activityTypeDisplayLabels[$this->_activityTypeId]; | |
11a60382 D |
1236 | |
1237 | // At the moment this is duplicating other code in this section, but refactoring in small steps. | |
1238 | $activityTypeObj = new CRM_Activity_BAO_ActivityType($this->_activityTypeId); | |
f692bf33 | 1239 | $this->assign('activityTypeNameAndLabel', $activityTypeObj->getActivityType()); |
c6bbfc3a D |
1240 | } |
1241 | // Set title. | |
1242 | if (isset($activityTypeDisplayLabels)) { | |
1243 | // FIXME - it's not clear why the if line just above is needed here and why we can't just set this once above and re-use. What is interesting, but can't possibly be the reason, is that the first if block will fail if the label is the string '0', whereas this one won't. But who would have an activity type called '0'? | |
9c1bc317 | 1244 | $activityTypeDisplayLabel = $activityTypeDisplayLabels[$this->_activityTypeId] ?? NULL; |
c6bbfc3a D |
1245 | |
1246 | if ($this->_currentlyViewedContactId) { | |
1247 | $displayName = CRM_Contact_BAO_Contact::displayName($this->_currentlyViewedContactId); | |
1248 | // Check if this is default domain contact CRM-10482. | |
1249 | if (CRM_Contact_BAO_Contact::checkDomainContact($this->_currentlyViewedContactId)) { | |
1250 | $displayName .= ' (' . ts('default organization') . ')'; | |
1251 | } | |
1252 | CRM_Utils_System::setTitle($displayName . ' - ' . $activityTypeDisplayLabel); | |
1253 | } | |
1254 | else { | |
1255 | CRM_Utils_System::setTitle(ts('%1 Activity', [1 => $activityTypeDisplayLabel])); | |
1256 | } | |
1257 | } | |
1258 | } | |
1259 | } | |
1260 | ||
6a488035 | 1261 | } |