Merge pull request #15927 from eileenmcnaughton/event_form
[civicrm-core.git] / CRM / Activity / Form / Activity.php
CommitLineData
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 */
21class 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 /**
fe482240 45 * The name of activity type.
6a488035
TO
46 *
47 * @var string
48 */
49 public $_activityTypeName;
50
51 /**
fe482240 52 * The id of currently viewed contact.
6a488035
TO
53 *
54 * @var int
55 */
56 public $_currentlyViewedContactId;
57
58 /**
fe482240 59 * The id of source contact and target contact.
6a488035
TO
60 *
61 * @var int
62 */
63 protected $_sourceContactId;
64 protected $_targetContactId;
65 protected $_asigneeContactId;
66
67 protected $_single;
68
69 public $_context;
70 public $_compContext;
71 public $_action;
72 public $_activityTypeFile;
73
74 /**
75 * The id of the logged in user, used when add / edit
76 *
77 * @var int
78 */
79 public $_currentUserId;
80
81 /**
fe482240 82 * The array of form field attributes.
6a488035
TO
83 *
84 * @var array
85 */
86 public $_fields;
87
88 /**
89 * The the directory inside CRM, to include activity type file from
90 *
91 * @var string
92 */
93 protected $_crmDir = 'Activity';
94
c490a46a 95 /**
fe482240 96 * Survey activity.
c490a46a 97 *
d51c6add 98 * @var bool
c490a46a 99 */
6a488035
TO
100 protected $_isSurveyActivity;
101
96f94695 102 protected $_values = [];
6a488035 103
c087eb82 104 protected $unsavedWarn = TRUE;
d5965a37 105
62d3ee27
SL
106 /**
107 *
53c79877
SM
108 * Is it possible to create separate activities with this form?
109 *
110 * When TRUE, the form will ask whether the user wants to create separate
111 * activities (if the user has specified multiple contacts in the "with"
112 * field).
113 *
114 * When FALSE, the form will create one activity with all contacts together
115 * and won't ask the user anything.
116 *
117 * Note: This is a class property so that child classes can turn off this
118 * behavior (e.g. in CRM_Case_Form_Activity)
119 *
d51c6add 120 * @var bool
62d3ee27 121 *
53c79877
SM
122 */
123 protected $supportsActivitySeparation = TRUE;
124
423616fa
CW
125 public $submitOnce = TRUE;
126
d5965a37 127 /**
6e62b28c 128 * Explicitly declare the entity api name.
7808aae6
SB
129 *
130 * @return string
6e62b28c
TM
131 */
132 public function getDefaultEntity() {
133 return 'Activity';
134 }
59d63f8b 135
6a488035
TO
136 /**
137 * The _fields var can be used by sub class to set/unset/edit the
138 * form fields based on their requirement
6a488035 139 */
00be9182 140 public function setFields() {
056878d2
CW
141 // Remove print document activity type
142 $unwanted = CRM_Core_OptionGroup::values('activity_type', FALSE, FALSE, FALSE, "AND v.name = 'Print PDF Letter'");
143 $activityTypes = array_diff_key(CRM_Core_PseudoConstant::ActivityType(FALSE), $unwanted);
144
96f94695 145 $this->_fields = [
146 'subject' => [
6a488035
TO
147 'type' => 'text',
148 'label' => ts('Subject'),
96f94695 149 'attributes' => CRM_Core_DAO::getAttribute('CRM_Activity_DAO_Activity', 'activity_subject'),
150 ],
151 'duration' => [
4b2fda1e 152 'type' => 'number',
6a488035 153 'label' => ts('Duration'),
96f94695 154 'attributes' => ['class' => 'four', 'min' => 1],
6a488035 155 'required' => FALSE,
96f94695 156 ],
157 'location' => [
6a488035
TO
158 'type' => 'text',
159 'label' => ts('Location'),
9d72cede 160 'attributes' => CRM_Core_DAO::getAttribute('CRM_Activity_DAO_Activity', 'location'),
21dfd5f5 161 'required' => FALSE,
96f94695 162 ],
163 'details' => [
6a488035
TO
164 'type' => 'wysiwyg',
165 'label' => ts('Details'),
96f94695 166 'attributes' => ['class' => 'huge'],
21dfd5f5 167 'required' => FALSE,
96f94695 168 ],
169 'status_id' => [
6a488035 170 'type' => 'select',
475e9f44 171 'required' => TRUE,
96f94695 172 ],
173 'priority_id' => [
6a488035 174 'type' => 'select',
475e9f44 175 'required' => TRUE,
96f94695 176 ],
177 'source_contact_id' => [
c27ebe4e 178 'type' => 'entityRef',
6a488035 179 'label' => ts('Added By'),
21dfd5f5 180 'required' => FALSE,
96f94695 181 ],
182 'target_contact_id' => [
c27ebe4e
CW
183 'type' => 'entityRef',
184 'label' => ts('With Contact'),
96f94695 185 'attributes' => ['multiple' => TRUE, 'create' => TRUE],
186 ],
187 'assignee_contact_id' => [
c27ebe4e 188 'type' => 'entityRef',
3bd48a28 189 'label' => ts('Assigned to'),
96f94695 190 'attributes' => [
353ffa53
TO
191 'multiple' => TRUE,
192 'create' => TRUE,
96f94695 193 'api' => ['params' => ['is_deceased' => 0]],
194 ],
195 ],
196 'activity_date_time' => [
d104311a
CW
197 'type' => 'datepicker',
198 'label' => ts('Date'),
199 'required' => TRUE,
96f94695 200 ],
201 'followup_assignee_contact_id' => [
c27ebe4e 202 'type' => 'entityRef',
3bd48a28 203 'label' => ts('Assigned to'),
96f94695 204 'attributes' => [
353ffa53
TO
205 'multiple' => TRUE,
206 'create' => TRUE,
96f94695 207 'api' => ['params' => ['is_deceased' => 0]],
208 ],
209 ],
210 'followup_activity_type_id' => [
6a488035
TO
211 'type' => 'select',
212 'label' => ts('Followup Activity'),
96f94695 213 'attributes' => ['' => '- ' . ts('select activity') . ' -'] + $activityTypes,
214 'extra' => ['class' => 'crm-select2'],
215 ],
6a488035 216 // Add optional 'Subject' field for the Follow-up Activiity, CRM-4491
96f94695 217 'followup_activity_subject' => [
6a488035
TO
218 'type' => 'text',
219 'label' => ts('Subject'),
96f94695 220 'attributes' => CRM_Core_DAO::getAttribute('CRM_Activity_DAO_Activity', 'subject'),
221 ],
222 ];
6a488035
TO
223 }
224
225 /**
fe482240 226 * Build the form object.
6a488035 227 */
00be9182 228 public function preProcess() {
b334d9ad 229 CRM_Core_Form_RecurringEntity::preProcess('civicrm_activity');
6a488035
TO
230 $this->_atypefile = CRM_Utils_Array::value('atypefile', $_GET);
231 $this->assign('atypefile', FALSE);
232 if ($this->_atypefile) {
233 $this->assign('atypefile', TRUE);
234 }
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 &&
276 get_class($this->controller) != 'CRM_Contact_Controller_Search'
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
TO
314 if ($this->_activityTypeId ||
315 $this->_context == 'standalone' ||
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
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 }
410 elseif ($this->_context == 'search') {
411 $urlParams = 'force=1';
412 if ($qfKey) {
413 $urlParams .= "&qfKey=$qfKey";
414 }
7964ef53 415 $path = CRM_Utils_System::currentPath();
481a74f4 416 if ($this->_compContext == 'advanced') {
6a488035
TO
417 $urlString = 'civicrm/contact/search/advanced';
418 }
a26bae24 419 elseif ($path == 'civicrm/group/search'
353ffa53 420 || $path == 'civicrm/contact/search'
d31f1ab3 421 || $path == 'civicrm/contact/search/advanced'
7a60b836 422 || $path == 'civicrm/contact/search/custom'
353ffa53 423 || $path == 'civicrm/group/search'
7974a65a 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 }
433 elseif ($this->_context != 'caseActivity') {
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) {
444 $this->_activityTypeId = CRM_Utils_Array::value('activity_type_id', $_POST);
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
6a488035
TO
530 if ($this->_context != 'standalone') {
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?
28ded762
JP
540 $defaults['target_contact_id'] = CRM_Utils_Array::value('target_contact', $defaults);
541 $defaults['assignee_contact_id'] = CRM_Utils_Array::value('assignee_contact', $defaults);
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');
6a488035
TO
585 $defaults['priority_id'] = array_search('Normal', $priority);
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' => '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;',
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
353ffa53 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])) {
475e9f44
CW
649 $attribute = CRM_Utils_Array::value('attributes', $values);
650 $required = !empty($values['required']);
6a488035 651
13d9bc82 652 if ($values['type'] == 'select' && empty($attribute)) {
96f94695 653 $this->addSelect($field, ['entity' => 'activity'], $required);
c27ebe4e
CW
654 }
655 elseif ($values['type'] == 'entityRef') {
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
CW
730 // Only admins and case-workers can change the activity source
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
TO
822 // skip form rule if deleting
823 if (CRM_Utils_Array::value('_qf_Activity_next_', $fields) == 'Delete') {
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
f47754ac
ML
831 $activity_type_id = CRM_Utils_Array::value('activity_type_id', $fields);
832 $activity_status_id = CRM_Utils_Array::value('status_id', $fields);
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
a850c3fe
SM
958 $params['is_multi_activity'] = CRM_Utils_Array::value('separation', $params) == 'separate';
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
CW
976 // Redirect to contact page or activity view in standalone mode
977 if ($this->_context == 'standalone') {
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
52c7b3a2
KJ
1038 */
1039 protected function processActivity(&$params) {
96f94695 1040 $activityAssigned = [];
44f817d4 1041 $activityContacts = CRM_Activity_BAO_ActivityContact::buildOptions('record_type_id', 'validate');
034500d4 1042 $assigneeID = CRM_Utils_Array::key('Activity Assignees', $activityContacts);
6a488035
TO
1043 // format assignee params
1044 if (!CRM_Utils_Array::crmIsEmptyArray($params['assignee_contact_id'])) {
1045 //skip those assignee contacts which are already assigned
1046 //while sending a copy.CRM-4509.
1047 $activityAssigned = array_flip($params['assignee_contact_id']);
1048 if ($this->_activityId) {
034500d4 1049 $assigneeContacts = CRM_Activity_BAO_ActivityContact::getNames($this->_activityId, $assigneeID);
6a488035
TO
1050 $activityAssigned = array_diff_key($activityAssigned, $assigneeContacts);
1051 }
1052 }
1053
1054 // call begin post process. Idea is to let injecting file do
1055 // any processing before the activity is added/updated.
1056 $this->beginPostProcess($params);
1057
1058 $activity = CRM_Activity_BAO_Activity::create($params);
1059
1060 // add tags if exists
96f94695 1061 $tagParams = [];
6a488035 1062 if (!empty($params['tag'])) {
b733747a
CW
1063 if (!is_array($params['tag'])) {
1064 $params['tag'] = explode(',', $params['tag']);
1065 }
63b7aefc
DB
1066
1067 $tagParams = array_fill_keys($params['tag'], 1);
6a488035
TO
1068 }
1069
7808aae6 1070 // Save static tags.
6a488035
TO
1071 CRM_Core_BAO_EntityTag::create($tagParams, 'civicrm_activity', $activity->id);
1072
7808aae6 1073 // Save free tags.
6a488035
TO
1074 if (isset($params['activity_taglist']) && !empty($params['activity_taglist'])) {
1075 CRM_Core_Form_Tag::postProcess($params['activity_taglist'], $activity->id, 'civicrm_activity', $this);
1076 }
1077
1078 // call end post process. Idea is to let injecting file do any
1079 // processing needed, after the activity has been added/updated.
1080 $this->endPostProcess($params, $activity);
1081
1082 // CRM-9590
a7488080 1083 if (!empty($params['is_multi_activity'])) {
52c7b3a2
KJ
1084 $this->_activityIds[] = $activity->id;
1085 }
1086 else {
1087 $this->_activityId = $activity->id;
1088 }
6a488035
TO
1089
1090 // create follow up activity if needed
1091 $followupStatus = '';
90b05581 1092 $followupActivity = NULL;
a7488080 1093 if (!empty($params['followup_activity_type_id'])) {
90b05581 1094 $followupActivity = CRM_Activity_BAO_Activity::createFollowupActivity($activity->id, $params);
6a488035
TO
1095 $followupStatus = ts('A followup activity has been scheduled.');
1096 }
1097
1098 // send copy to assignee contacts.CRM-4509
1099 $mailStatus = '';
1100
ac983377 1101 if (Civi::settings()->get('activity_assignee_notification')
96f94695 1102 && !in_array($activity->activity_type_id, Civi::settings()
1103 ->get('do_not_notify_assignees_for'))) {
1104 $activityIDs = [$activity->id];
90b05581 1105 if ($followupActivity) {
96f94695 1106 $activityIDs = array_merge($activityIDs, [$followupActivity->id]);
90b05581
DG
1107 }
1108 $assigneeContacts = CRM_Activity_BAO_ActivityAssignment::getAssigneeNames($activityIDs, TRUE, FALSE);
6a488035 1109
90b05581 1110 if (!CRM_Utils_Array::crmIsEmptyArray($params['assignee_contact_id'])) {
96f94695 1111 $mailToContacts = [];
90b05581 1112
7808aae6 1113 // Build an associative array with unique email addresses.
90b05581
DG
1114 foreach ($activityAssigned as $id => $dnc) {
1115 if (isset($id) && array_key_exists($id, $assigneeContacts)) {
1116 $mailToContacts[$assigneeContacts[$id]['email']] = $assigneeContacts[$id];
1117 }
6a488035 1118 }
6a488035 1119
bc883279 1120 $sent = CRM_Activity_BAO_Activity::sendToAssignee($activity, $mailToContacts);
1121 if ($sent) {
1122 $mailStatus .= ts("A copy of the activity has also been sent to assignee contacts(s).");
1123 }
1124 }
77b97be7 1125
90b05581
DG
1126 // Also send email to follow-up activity assignees if set
1127 if ($followupActivity) {
96f94695 1128 $mailToFollowupContacts = [];
90b05581
DG
1129 foreach ($assigneeContacts as $values) {
1130 if ($values['activity_id'] == $followupActivity->id) {
1131 $mailToFollowupContacts[$values['email']] = $values;
1132 }
1133 }
1134
2bbb4a91 1135 $sentFollowup = CRM_Activity_BAO_Activity::sendToAssignee($followupActivity, $mailToFollowupContacts);
bc883279 1136 if ($sentFollowup) {
f3c5a172 1137 $mailStatus .= '<br />' . ts("A copy of the follow-up activity has also been sent to follow-up assignee contacts(s).");
bc883279 1138 }
6a488035
TO
1139 }
1140 }
1141
1142 // set status message
ef89f226 1143 $subject = '';
a7488080 1144 if (!empty($params['subject'])) {
ef89f226 1145 $subject = "'" . $params['subject'] . "'";
6a488035
TO
1146 }
1147
12e2d503 1148 CRM_Core_Session::setStatus(ts('Activity %1 has been saved. %2 %3',
96f94695 1149 [
ef89f226 1150 1 => $subject,
52c7b3a2 1151 2 => $followupStatus,
21dfd5f5 1152 3 => $mailStatus,
96f94695 1153 ]
52c7b3a2 1154 ), ts('Saved'), 'success');
6a488035 1155
52c7b3a2 1156 return $activity;
6a488035
TO
1157 }
1158
1159 /**
1160 * Shorthand for getting id by display name (makes code more readable)
645ee340
EM
1161 * @param $displayName
1162 * @return null|string
6a488035
TO
1163 */
1164 protected function _getIdByDisplayName($displayName) {
1165 return CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact',
1166 $displayName,
1167 'id',
1168 'sort_name'
1169 );
1170 }
1171
1172 /**
1173 * Shorthand for getting display name by id (makes code more readable)
645ee340
EM
1174 * @param $id
1175 * @return null|string
6a488035
TO
1176 */
1177 protected function _getDisplayNameById($id) {
1178 return CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact',
1179 $id,
1180 'sort_name',
1181 'id'
1182 );
1183 }
1184
1185 /**
fe482240 1186 * Let injecting activity type file do any processing.
6a488035
TO
1187 * needed, before the activity is added/updated
1188 *
100fef9d 1189 * @param array $params
6a488035 1190 */
00be9182 1191 public function beginPostProcess(&$params) {
6a488035 1192 if ($this->_activityTypeFile) {
0e6e8724
DL
1193 $className = "CRM_{$this->_crmDir}_Form_Activity_{$this->_activityTypeFile}";
1194 $className::beginPostProcess($this, $params);
6a488035
TO
1195 }
1196 }
1197
1198 /**
100fef9d 1199 * Let injecting activity type file do any processing
6a488035
TO
1200 * needed, after the activity has been added/updated
1201 *
100fef9d
CW
1202 * @param array $params
1203 * @param $activity
6a488035 1204 */
00be9182 1205 public function endPostProcess(&$params, &$activity) {
6a488035 1206 if ($this->_activityTypeFile) {
0e6e8724 1207 $className = "CRM_{$this->_crmDir}_Form_Activity_{$this->_activityTypeFile}";
100fef9d 1208 $className::endPostProcess($this, $params, $activity);
6a488035
TO
1209 }
1210 }
96025800 1211
794f8025
D
1212 /**
1213 * 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.
1214 *
1215 * @return string[]
1216 */
1217 public function getActivityTypeDisplayLabels() {
1218 return CRM_Core_OptionGroup::values('activity_type', FALSE, FALSE, FALSE, 'AND v.value = ' . $this->_activityTypeId, 'label');
1219 }
1220
c6bbfc3a
D
1221 /**
1222 * For the moment this is just pulled from preProcess
1223 */
1224 public function assignActivityType() {
1225 if ($this->_activityTypeId) {
1226 $activityTypeDisplayLabels = $this->getActivityTypeDisplayLabels();
1227 if ($activityTypeDisplayLabels[$this->_activityTypeId]) {
1228 $this->_activityTypeName = $activityTypeDisplayLabels[$this->_activityTypeId];
11a60382
D
1229
1230 // At the moment this is duplicating other code in this section, but refactoring in small steps.
1231 $activityTypeObj = new CRM_Activity_BAO_ActivityType($this->_activityTypeId);
f692bf33 1232 $this->assign('activityTypeNameAndLabel', $activityTypeObj->getActivityType());
c6bbfc3a
D
1233 }
1234 // Set title.
1235 if (isset($activityTypeDisplayLabels)) {
1236 // 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'?
1237 $activityTypeDisplayLabel = CRM_Utils_Array::value($this->_activityTypeId, $activityTypeDisplayLabels);
1238
1239 if ($this->_currentlyViewedContactId) {
1240 $displayName = CRM_Contact_BAO_Contact::displayName($this->_currentlyViewedContactId);
1241 // Check if this is default domain contact CRM-10482.
1242 if (CRM_Contact_BAO_Contact::checkDomainContact($this->_currentlyViewedContactId)) {
1243 $displayName .= ' (' . ts('default organization') . ')';
1244 }
1245 CRM_Utils_System::setTitle($displayName . ' - ' . $activityTypeDisplayLabel);
1246 }
1247 else {
1248 CRM_Utils_System::setTitle(ts('%1 Activity', [1 => $activityTypeDisplayLabel]));
1249 }
1250 }
1251 }
1252 }
1253
6a488035 1254}