Merge pull request #399 from agh1/batch-countrystatecounty-4.3
[civicrm-core.git] / CRM / Activity / Form / Activity.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.3 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2013 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
9 | |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
13 | |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
18 | |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
26*/
27
28/**
29 *
30 * @package CRM
31 * @copyright CiviCRM LLC (c) 2004-2013
32 * $Id$
33 *
34 */
35
36/**
37 * This class generates form components for Activity
38 *
39 */
40class CRM_Activity_Form_Activity extends CRM_Contact_Form_Task {
41
42 /**
43 * The id of the object being edited / created
44 *
45 * @var int
46 */
47 public $_activityId;
48
52c7b3a2
KJ
49 /**
50 * store activity ids when multiple activities are created
51 *
52 * @var int
53 */
54 public $_activityIds = array();
55
6a488035
TO
56 /**
57 * The id of activity type
58 *
59 * @var int
60 */
61 public $_activityTypeId;
62
63 /**
64 * The name of activity type
65 *
66 * @var string
67 */
68 public $_activityTypeName;
69
70 /**
71 * The id of currently viewed contact
72 *
73 * @var int
74 */
75 public $_currentlyViewedContactId;
76
77 /**
78 * The id of source contact and target contact
79 *
80 * @var int
81 */
82 protected $_sourceContactId;
83 protected $_targetContactId;
84 protected $_asigneeContactId;
85
86 protected $_single;
87
88 public $_context;
89 public $_compContext;
90 public $_action;
91 public $_activityTypeFile;
92
93 /**
94 * The id of the logged in user, used when add / edit
95 *
96 * @var int
97 */
98 public $_currentUserId;
99
100 /**
101 * The array of form field attributes
102 *
103 * @var array
104 */
105 public $_fields;
106
107 /**
108 * The the directory inside CRM, to include activity type file from
109 *
110 * @var string
111 */
112 protected $_crmDir = 'Activity';
113
114 /*
115 * Survey activity
116 *
117 * @var boolean
118 */
119
120 protected $_isSurveyActivity;
121
122 protected $_values = array();
123
124 /**
125 * The _fields var can be used by sub class to set/unset/edit the
126 * form fields based on their requirement
127 *
128 */
129 function setFields() {
130 $this->_fields = array(
131 'subject' => array(
132 'type' => 'text',
133 'label' => ts('Subject'),
134 'attributes' => CRM_Core_DAO::getAttribute('CRM_Activity_DAO_Activity',
135 'subject'
136 ),
137 ),
138 'duration' => array(
139 'type' => 'text',
140 'label' => ts('Duration'),
141 'attributes' => array('size' => 4, 'maxlength' => 8),
142 'required' => FALSE,
143 ),
144 'location' => array(
145 'type' => 'text',
146 'label' => ts('Location'),
147 'attributes' =>
148 CRM_Core_DAO::getAttribute('CRM_Activity_DAO_Activity',
149 'location'
150 ),
151 'required' => FALSE
152 ),
153 'details' => array(
154 'type' => 'wysiwyg',
155 'label' => ts('Details'),
156 // forces a smaller edit window
157 'attributes' => array('rows' => 4, 'cols' => 60),
158 'required' => FALSE
159 ),
160 'status_id' => array(
161 'type' => 'select',
162 'label' => ts('Status'),
163 'attributes' =>
164 CRM_Core_PseudoConstant::activityStatus(),
165 'required' => TRUE
166 ),
167 'priority_id' => array(
168 'type' => 'select',
169 'label' => ts('Priority'),
170 'attributes' =>
171 CRM_Core_PseudoConstant::priority(),
172 'required' => TRUE
173 ),
174 'source_contact_id' => array(
175 'type' => 'text',
176 'label' => ts('Added By'),
177 'required' => FALSE
178 ),
179 'followup_activity_type_id' => array(
180 'type' => 'select',
181 'label' => ts('Followup Activity'),
182 'attributes' => array(
183 '' => '- ' . ts('select activity') . ' -') +
184 CRM_Core_PseudoConstant::ActivityType(FALSE)
185 ),
186 // Add optional 'Subject' field for the Follow-up Activiity, CRM-4491
187 'followup_activity_subject' => array(
188 'type' => 'text',
189 'label' => ts('Subject'),
190 'attributes' => CRM_Core_DAO::getAttribute('CRM_Activity_DAO_Activity',
191 'subject'
192 )
193 )
194 );
195
196 if (($this->_context == 'standalone') &&
197 ($printPDF = CRM_Utils_Array::key('Print PDF Letter', $this->_fields['followup_activity_type_id']['attributes']))
198 ) {
199 unset($this->_fields['followup_activity_type_id']['attributes'][$printPDF]);
200 }
201 }
202
203 /**
204 * Function to build the form
205 *
206 * @return None
207 * @access public
208 */
209 function preProcess() {
210 $this->_cdType = CRM_Utils_Array::value('type', $_GET);
211 $this->assign('cdType', FALSE);
212 if ($this->_cdType) {
213 $this->assign('cdType', TRUE);
214 return CRM_Custom_Form_CustomData::preProcess($this);
215 }
216
217 $this->_atypefile = CRM_Utils_Array::value('atypefile', $_GET);
218 $this->assign('atypefile', FALSE);
219 if ($this->_atypefile) {
220 $this->assign('atypefile', TRUE);
221 }
222
223 $session = CRM_Core_Session::singleton();
224 $this->_currentUserId = $session->get('userID');
225
226 $this->_currentlyViewedContactId = $this->get('contactId');
227 if (!$this->_currentlyViewedContactId) {
228 $this->_currentlyViewedContactId = CRM_Utils_Request::retrieve('cid', 'Positive', $this);
229 }
230 $this->assign('contactId', $this->_currentlyViewedContactId);
231
232 if ($this->_currentlyViewedContactId) {
233 CRM_Contact_Page_View::setTitle($this->_currentlyViewedContactId);
234 }
235
236 //give the context.
237 if (!isset($this->_context)) {
238 $this->_context = CRM_Utils_Request::retrieve('context', 'String', $this);
239 if (CRM_Contact_Form_Search::isSearchContext($this->_context)) {
240 $this->_context = 'search';
241 }
242 elseif (!in_array($this->_context, array('dashlet', 'dashletFullscreen'))
243 && $this->_currentlyViewedContactId
244 ) {
245 $this->_context = 'activity';
246 }
247 $this->_compContext = CRM_Utils_Request::retrieve('compContext', 'String', $this);
248 }
249
250 $this->assign('context', $this->_context);
251
252 $this->_action = CRM_Utils_Request::retrieve('action', 'String', $this);
253
254 if ($this->_action & CRM_Core_Action::DELETE) {
255 if (!CRM_Core_Permission::check('delete activities')) {
256 CRM_Core_Error::fatal(ts('You do not have permission to access this page'));
257 }
258 }
259
260 //CRM-6957
261 //when we come from contact search, activity id never comes.
262 //so don't try to get from object, it might gives you wrong one.
263
264 // if we're not adding new one, there must be an id to
265 // an activity we're trying to work on.
266 if ($this->_action != CRM_Core_Action::ADD &&
267 get_class($this->controller) != 'CRM_Contact_Controller_Search'
268 ) {
269 $this->_activityId = CRM_Utils_Request::retrieve('id', 'Positive', $this);
270 }
271
272 $this->_activityTypeId = CRM_Utils_Request::retrieve('atype', 'Positive', $this);
273 $this->assign('atype', $this->_activityTypeId);
274
275 //check for required permissions, CRM-6264
276 if ($this->_activityId &&
277 in_array($this->_action, array(
278 CRM_Core_Action::UPDATE, CRM_Core_Action::VIEW)) &&
279 !CRM_Activity_BAO_Activity::checkPermission($this->_activityId, $this->_action)
280 ) {
281 CRM_Core_Error::fatal(ts('You do not have permission to access this page.'));
282 }
283 if (($this->_action & CRM_Core_Action::VIEW) &&
284 CRM_Activity_BAO_Activity::checkPermission($this->_activityId, CRM_Core_Action::UPDATE)
285 ) {
286 $this->assign('permission', 'edit');
287 }
288
289 if (!$this->_activityTypeId && $this->_activityId) {
290 $this->_activityTypeId = CRM_Core_DAO::getFieldValue('CRM_Activity_DAO_Activity',
291 $this->_activityId,
292 'activity_type_id'
293 );
294 }
295
296 //Assigning Activity type name
297 if ($this->_activityTypeId) {
298 $activityTName = CRM_Core_OptionGroup::values('activity_type', FALSE, FALSE, FALSE, 'AND v.value = ' . $this->_activityTypeId, 'name');
299 if ($activityTName[$this->_activityTypeId]) {
300 $this->_activityTypeName = $activityTName[$this->_activityTypeId];
301 $this->assign('activityTName', $activityTName[$this->_activityTypeId]);
302 }
303 }
304
305 // Assign pageTitle to be "Activity - "+ activity name
306 if (isset($activityTName)) {
307 $pageTitle = 'Activity - ' . CRM_Utils_Array::value($this->_activityTypeId, $activityTName);
308 $this->assign('pageTitle', $pageTitle);
309 }
310
311 //check the mode when this form is called either single or as
312 //search task action
313 if ($this->_activityTypeId ||
314 $this->_context == 'standalone' ||
315 $this->_currentlyViewedContactId
316 ) {
317 $this->_single = TRUE;
318 $this->assign('urlPath', 'civicrm/activity');
319 }
320 else {
321 //set the appropriate action
322 $url = CRM_Utils_System::currentPath();
323 $urlArray = explode('/', $url);
324 $seachPath = array_pop($urlArray);
325 $searchType = 'basic';
326 $this->_action = CRM_Core_Action::BASIC;
327 switch ($seachPath) {
328 case 'basic':
329 $searchType = $seachPath;
330 $this->_action = CRM_Core_Action::BASIC;
331 break;
332
333 case 'advanced':
334 $searchType = $seachPath;
335 $this->_action = CRM_Core_Action::ADVANCED;
336 break;
337
338 case 'builder':
339 $searchType = $seachPath;
340 $this->_action = CRM_Core_Action::PROFILE;
341 break;
342
343 case 'custom':
344 $this->_action = CRM_Core_Action::COPY;
345 $searchType = $seachPath;
346 break;
347 }
348
349 parent::preProcess();
350 $this->_single = FALSE;
351
352 $this->assign('urlPath', "civicrm/contact/search/$searchType");
353 $this->assign('urlPathVar', "_qf_Activity_display=true&qfKey={$this->controller->_key}");
354 }
355
356 $this->assign('single', $this->_single);
357 $this->assign('action', $this->_action);
358
359 if ($this->_action & CRM_Core_Action::VIEW) {
360 // get the tree of custom fields
361 $this->_groupTree = &CRM_Core_BAO_CustomGroup::getTree('Activity', $this,
362 $this->_activityId, 0, $this->_activityTypeId
363 );
364 }
365
366 if ($this->_activityTypeId) {
367 //set activity type name and description to template
368 list($this->_activityTypeName, $activityTypeDescription) = CRM_Core_BAO_OptionValue::getActivityTypeDetails($this->_activityTypeId);
369 $this->assign('activityTypeName', $this->_activityTypeName);
370 $this->assign('activityTypeDescription', $activityTypeDescription);
371 }
372
373 // set user context
374 $urlParams = $urlString = NULL;
9479d7d0
DS
375 $qfKey = CRM_Utils_Request::retrieve('key', 'String', $this);
376 if (!$qfKey) {
377 $qfKey = CRM_Utils_Request::retrieve('qfKey', 'String', $this);
378 }
6a488035
TO
379
380 //validate the qfKey
381 if (!CRM_Utils_Rule::qfKey($qfKey)) {
382 $qfKey = NULL;
383 }
384
385 if ($this->_context == 'fulltext') {
386 $keyName = '&qfKey';
387 $urlParams = 'force=1';
388 $urlString = 'civicrm/contact/search/custom';
389 if ($this->_action == CRM_Core_Action::UPDATE) {
390 $keyName = '&key';
391 $urlParams .= '&context=fulltext&action=view';
392 $urlString = 'civicrm/contact/view/activity';
393 }
394 if ($qfKey) {
395 $urlParams .= "$keyName=$qfKey";
396 }
397 $this->assign('searchKey', $qfKey);
398 }
399 elseif (in_array($this->_context, array(
400 'standalone', 'home', 'dashlet', 'dashletFullscreen'))) {
401 $urlParams = 'reset=1';
402 $urlString = 'civicrm/dashboard';
403 }
404 elseif ($this->_context == 'search') {
405 $urlParams = 'force=1';
406 if ($qfKey) {
407 $urlParams .= "&qfKey=$qfKey";
408 }
7964ef53
DS
409 $path = CRM_Utils_System::currentPath();
410 if ($this->_compContext == 'advanced' ||
411 $path == 'civicrm/contact/search/advanced') {
6a488035
TO
412 $urlString = 'civicrm/contact/search/advanced';
413 }
7964ef53
DS
414 else if ($path == 'civicrm/contact/search') {
415 $urlString = 'civicrm/contact/search';
416 }
6a488035
TO
417 else {
418 $urlString = 'civicrm/activity/search';
419 }
420 $this->assign('searchKey', $qfKey);
421 }
422 elseif ($this->_context != 'caseActivity') {
423 $urlParams = "action=browse&reset=1&cid={$this->_currentlyViewedContactId}&selectedChild=activity";
424 $urlString = 'civicrm/contact/view';
425 }
426
427 if ($urlString) {
428 $session->pushUserContext(CRM_Utils_System::url($urlString, $urlParams));
429 }
430
431 // hack to retrieve activity type id from post variables
432 if (!$this->_activityTypeId) {
433 $this->_activityTypeId = CRM_Utils_Array::value('activity_type_id', $_POST);
434 }
435
436 // when custom data is included in this page
437 if (CRM_Utils_Array::value('hidden_custom', $_POST)) {
438 // we need to set it in the session for the below code to work
439 // CRM-3014
440 //need to assign custom data subtype to the template
441 $this->set('type', 'Activity');
442 $this->set('subType', $this->_activityTypeId);
443 $this->set('entityId', $this->_activityId);
444 CRM_Custom_Form_CustomData::preProcess($this);
445 CRM_Custom_Form_CustomData::buildQuickForm($this);
446 CRM_Custom_Form_CustomData::setDefaultValues($this);
447 }
448
449 // add attachments part
450 CRM_Core_BAO_File::buildAttachment($this, 'civicrm_activity', $this->_activityId, NULL, TRUE);
451
452 // figure out the file name for activity type, if any
453 if ($this->_activityTypeId &&
454 $this->_activityTypeFile =
455 CRM_Activity_BAO_Activity::getFileForActivityTypeId($this->_activityTypeId, $this->_crmDir)
456 ) {
457 $this->assign('activityTypeFile', $this->_activityTypeFile);
458 $this->assign('crmDir', $this->_crmDir);
459 }
460
461 $this->setFields();
462
463 if ($this->_activityTypeFile) {
464 eval("CRM_{$this->_crmDir}_Form_Activity_{$this->_activityTypeFile}::preProcess( \$this );");
465 }
466
467 $this->_values = $this->get('values');
468 if (!is_array($this->_values)) {
469 $this->_values = array();
470 if (isset($this->_activityId) && $this->_activityId) {
471 $params = array('id' => $this->_activityId);
472 CRM_Activity_BAO_Activity::retrieve($params, $this->_values);
473 }
474 $this->set('values', $this->_values);
475 }
476 }
477
478 /**
479 * This function sets the default values for the form. For edit/view mode
480 * the default values are retrieved from the database
481 *
482 * @access public
483 *
484 * @return None
485 */
486 function setDefaultValues() {
487 if ($this->_cdType) {
488 return CRM_Custom_Form_CustomData::setDefaultValues($this);
489 }
490
491 $defaults = $this->_values;
492
493 // if we're editing...
494 if (isset($this->_activityId)) {
495 $defaults['source_contact_qid'] = CRM_Utils_Array::value( 'source_contact_id',
496 $defaults );
497 $defaults['source_contact_id'] = CRM_Utils_Array::value( 'source_contact',
498 $defaults );
499
500 if (!CRM_Utils_Array::crmIsEmptyArray($defaults['target_contact'])) {
501 $target_contact_value = explode(';', trim($defaults['target_contact_value']));
502 $target_contact = array_combine(array_unique($defaults['target_contact']), $target_contact_value);
503
504 if ($this->_action & CRM_Core_Action::VIEW) {
505 $this->assign('target_contact', $target_contact);
506 }
507 else {
508 //this assigned variable is used by newcontact creation widget to set defaults
509 $this->assign('prePopulateData', $this->formatContactValues($target_contact));
510 }
511 }
512
513 if (!CRM_Utils_Array::crmIsEmptyArray($defaults['assignee_contact'])) {
514 $assignee_contact_value = explode(';', trim($defaults['assignee_contact_value']));
515 $assignee_contact = array_combine($defaults['assignee_contact'], $assignee_contact_value);
516
517 if ($this->_action & CRM_Core_Action::VIEW) {
518 $this->assign('assignee_contact', $assignee_contact);
519 }
520 else {
521 $this->assign('assignee_contact', $this->formatContactValues($assignee_contact));
522 }
523 }
524
525 if (!CRM_Utils_Array::value('activity_date_time', $defaults)) {
526 list($defaults['activity_date_time'], $defaults['activity_date_time_time']) = CRM_Utils_Date::setDateDefaults(NULL, 'activityDateTime');
527 }
528 elseif ($this->_action & CRM_Core_Action::UPDATE) {
529 $this->assign('current_activity_date_time', $defaults['activity_date_time']);
530 list($defaults['activity_date_time'],
531 $defaults['activity_date_time_time']
532 ) = CRM_Utils_Date::setDateDefaults($defaults['activity_date_time'], 'activityDateTime');
533 }
534
535 //set the assigneed contact count to template
536 if (!empty($defaults['assignee_contact'])) {
537 $this->assign('assigneeContactCount', count($defaults['assignee_contact']));
538 }
539 else {
540 $this->assign('assigneeContactCount', 1);
541 }
542
543 //set the target contact count to template
544 if (!empty($defaults['target_contact'])) {
545 $this->assign('targetContactCount', count($defaults['target_contact']));
546 }
547 else {
548 $this->assign('targetContactCount', 1);
549 }
550
551 if ($this->_context != 'standalone') {
552 $this->assign('target_contact_value',
553 CRM_Utils_Array::value('target_contact_value', $defaults)
554 );
555 $this->assign('assignee_contact_value',
556 CRM_Utils_Array::value('assignee_contact_value', $defaults)
557 );
558 $this->assign('source_contact_value',
559 CRM_Utils_Array::value('source_contact', $defaults)
560 );
561 }
562
563 // set default tags if exists
564 $defaults['tag'] = CRM_Core_BAO_EntityTag::getTag($this->_activityId, 'civicrm_activity');
565 }
566 else {
567 // if it's a new activity, we need to set default values for associated contact fields
568 // since those are jQuery fields, unfortunately we cannot use defaults directly
569 $this->_sourceContactId = $this->_currentUserId;
570 $this->_targetContactId = $this->_currentlyViewedContactId;
571 $target_contact = array();
572
573 $defaults['source_contact_id'] = self::_getDisplayNameById($this->_sourceContactId);
574 $defaults['source_contact_qid'] = $this->_sourceContactId;
575 if ($this->_context != 'standalone' && isset($this->_targetContactId)) {
576 $target_contact[$this->_targetContactId] = self::_getDisplayNameById($this->_targetContactId);
577 }
578
579 //this assigned variable is used by newcontact creation widget to set defaults
580 $this->assign('prePopulateData', $this->formatContactValues($target_contact));
581
582 list($defaults['activity_date_time'], $defaults['activity_date_time_time']) =
583 CRM_Utils_Date::setDateDefaults(NULL, 'activityDateTime');
584 }
585
586 if ($this->_activityTypeId) {
587 $defaults['activity_type_id'] = $this->_activityTypeId;
588 }
589
590 if ($this->_action & (CRM_Core_Action::DELETE | CRM_Core_Action::RENEW)) {
591 $this->assign('delName', CRM_Utils_Array::value('subject', $defaults));
592 }
593
594 if ($this->_activityTypeFile) {
595 eval('$defaults += CRM_' . $this->_crmDir . '_Form_Activity_' .
596 $this->_activityTypeFile . '::setDefaultValues($this);'
597 );
598 }
599 if (!CRM_Utils_Array::value('priority_id', $defaults)) {
600 $priority = CRM_Core_PseudoConstant::priority();
601 $defaults['priority_id'] = array_search('Normal', $priority);
602 }
343d84fa
DG
603 if (!CRM_Utils_Array::value('status_id', $defaults)) {
604 $defaults['status_id'] = CRM_Core_OptionGroup::getDefaultValue('activity_status');
605 }
6a488035
TO
606 return $defaults;
607 }
608
609 /**
610 * Function to format contact values before assigning to autocomplete widget
611 *
612 * @param array $contactNames associated array of contact name and ids
613 *
614 * @return json encoded object
615 * @private
616 */
617 function formatContactValues(&$contactNames) {
618 //format target/assignee contact
619 $formatContacts = array();
620 foreach ($contactNames as $id => $name) {
621 $formatContacts[] = array(
622 'id' => $id,
623 'name' => $name
624 );
625 }
626
627 return json_encode($formatContacts);
628 }
629
630 public function buildQuickForm() {
631 if ($this->_action & (CRM_Core_Action::DELETE | CRM_Core_Action::RENEW)) {
632 //enable form element (ActivityLinks sets this true)
633 $this->assign('suppressForm', FALSE);
634
635 $button = ts('Delete');
636 if ($this->_action & CRM_Core_Action::RENEW) {
637 $button = ts('Restore');
638 }
639 $this->addButtons(array(
640 array(
641 'type' => 'next',
642 'name' => $button,
643 'spacing' => '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;',
644 'isDefault' => TRUE
645 ),
646 array(
647 'type' => 'cancel',
648 'name' => ts('Cancel')
649 )
650 ));
651 return;
652 }
653
654 if (!$this->_single && !empty($this->_contactIds)) {
655 $withArray = array();
656 foreach ($this->_contactIds as $contactId) {
657 $withDisplayName = self::_getDisplayNameById($contactId);
658 $withArray[] = "\"$withDisplayName\" ";
659 }
660 $this->assign('with', implode(', ', $withArray));
661 }
662
663 if ($this->_cdType) {
664 return CRM_Custom_Form_CustomData::buildQuickForm($this);
665 }
666
667 //build other activity links
cfcb7676 668 CRM_Activity_Form_ActivityLinks::commonBuildQuickForm($this);
6a488035
TO
669
670 //enable form element (ActivityLinks sets this true)
671 $this->assign('suppressForm', FALSE);
672
673 $element = &$this->add('select', 'activity_type_id', ts('Activity Type'),
674 $this->_fields['followup_activity_type_id']['attributes'],
675 FALSE, array(
676 'onchange' =>
677 "CRM.buildCustomData( 'Activity', this.value );",
678 )
679 );
680
681 //freeze for update mode.
682 if ($this->_action & CRM_Core_Action::UPDATE) {
683 $element->freeze();
684 }
685
686 foreach ($this->_fields as $field => $values) {
687 if (CRM_Utils_Array::value($field, $this->_fields)) {
688 $attribute = NULL;
689 if (CRM_Utils_Array::value('attributes', $values)) {
690 $attribute = $values['attributes'];
691 }
692
693 $required = FALSE;
694 if (CRM_Utils_Array::value('required', $values)) {
695 $required = TRUE;
696 }
697 if ($values['type'] == 'wysiwyg') {
698 $this->addWysiwyg($field, $values['label'], $attribute, $required);
699 }
700 else {
701 $this->add($values['type'], $field, $values['label'], $attribute, $required);
702 }
703 }
704 }
705
706 //CRM-7362 --add campaigns.
707 CRM_Campaign_BAO_Campaign::addCampaign($this, CRM_Utils_Array::value('campaign_id', $this->_values));
708
709 //add engagement level CRM-7775
710 $buildEngagementLevel = FALSE;
711 if (CRM_Campaign_BAO_Campaign::isCampaignEnable() &&
712 CRM_Campaign_BAO_Campaign::accessCampaign()
713 ) {
714 $buildEngagementLevel = TRUE;
715 $this->add('select', 'engagement_level',
716 ts('Engagement Index'),
717 array('' => ts('- select -')) + CRM_Campaign_PseudoConstant::engagementLevel()
718 );
719 $this->addRule('engagement_level',
720 ts('Please enter the engagement index as a number (integers only).'),
721 'positiveInteger'
722 );
723 }
724 $this->assign('buildEngagementLevel', $buildEngagementLevel);
725
726 // check for survey activity
727 $this->_isSurveyActivity = FALSE;
728
729 if ($this->_activityId && CRM_Campaign_BAO_Campaign::isCampaignEnable() &&
730 CRM_Campaign_BAO_Campaign::accessCampaign()
731 ) {
732
733 $this->_isSurveyActivity = CRM_Campaign_BAO_Survey::isSurveyActivity($this->_activityId);
734 if ($this->_isSurveyActivity) {
735 $surveyId = CRM_Core_DAO::getFieldValue('CRM_Activity_DAO_Activity',
736 $this->_activityId,
737 'source_record_id'
738 );
739 $responseOptions = CRM_Campaign_BAO_Survey::getResponsesOptions($surveyId);
740 if ($responseOptions) {
741 $this->add('select', 'result', ts('Result'),
742 array('' => ts('- select -')) + array_combine($responseOptions, $responseOptions)
743 );
744 }
745 $surveyTitle = NULL;
746 if ($surveyId) {
747 $surveyTitle = CRM_Core_DAO::getFieldValue('CRM_Campaign_DAO_Survey', $surveyId, 'title');
748 }
749 $this->assign('surveyTitle', $surveyTitle);
750 }
751 }
752 $this->assign('surveyActivity', $this->_isSurveyActivity);
753
52c7b3a2 754 // this option should be available only during add mode
ef89f226 755 if ($this->_action != CRM_Core_Action::UPDATE) {
d82cb206 756 $this->add('advcheckbox', 'is_multi_activity', ts('Create a separate activity for each contact.'));
52c7b3a2
KJ
757 }
758
6a488035
TO
759 $this->addRule('duration',
760 ts('Please enter the duration as number of minutes (integers only).'), 'positiveInteger'
761 );
762 $this->addDateTime('activity_date_time', ts('Date'), TRUE, array('formatType' => 'activityDateTime'));
763
764 //add followup date
765 $this->addDateTime('followup_date', ts('in'));
766
767 //autocomplete url
768 $dataUrl = CRM_Utils_System::url("civicrm/ajax/rest",
769 "className=CRM_Contact_Page_AJAX&fnName=getContactList&json=1&context=activity&reset=1",
770 FALSE, NULL, FALSE
771 );
772 $this->assign('dataUrl', $dataUrl);
773
774 //tokeninput url
775 $tokenUrl = CRM_Utils_System::url("civicrm/ajax/checkemail",
776 "noemail=1",
777 FALSE, NULL, FALSE
778 );
779 $this->assign('tokenUrl', $tokenUrl);
780
781 $admin = CRM_Core_Permission::check('administer CiviCRM');
782 //allow to edit sourcecontactfield field if context is civicase.
783 if ($this->_context == 'caseActivity') {
784 $admin = TRUE;
785 }
786
787 $this->assign('admin', $admin);
788
789 $sourceContactField = &$this->add($this->_fields['source_contact_id']['type'],
790 'source_contact_id',
791 $this->_fields['source_contact_id']['label'],
792 NULL,
793 $admin
794 );
795
796 $this->add('hidden', 'source_contact_qid', '', array('id' => 'source_contact_qid'));
797 CRM_Contact_Form_NewContact::buildQuickForm($this);
798
799 $this->add('text', 'assignee_contact_id', ts('assignee'));
800
801 if ($sourceContactField->getValue()) {
802 $this->assign('source_contact', $sourceContactField->getValue());
803 }
804 elseif ($this->_currentUserId) {
805 // we're setting currently LOGGED IN user as source for this activity
806 $this->assign('source_contact_value', self::_getDisplayNameById($this->_currentUserId));
807 }
808
809 //need to assign custom data type and subtype to the template
810 $this->assign('customDataType', 'Activity');
811 $this->assign('customDataSubType', $this->_activityTypeId);
812 $this->assign('entityID', $this->_activityId);
813
814 $tags = CRM_Core_BAO_Tag::getTags('civicrm_activity');
815
816 if (!empty($tags)) {
817 $this->add('select', 'tag', ts('Tags'), $tags, FALSE,
818 array('id' => 'tags', 'multiple' => 'multiple', 'title' => ts('- select -'))
819 );
820 }
821
822 // we need to hide activity tagset for special activities
823 $specialActivities = array('Open Case');
824
825 if (!in_array($this->_activityTypeName, $specialActivities)) {
826 // build tag widget
827 $parentNames = CRM_Core_BAO_Tag::getTagSet('civicrm_activity');
828 CRM_Core_Form_Tag::buildQuickForm($this, $parentNames, 'civicrm_activity', $this->_activityId, FALSE, TRUE);
829 }
830
831 // if we're viewing, we're assigning different buttons than for adding/editing
832 if ($this->_action & CRM_Core_Action::VIEW) {
833 if (isset($this->_groupTree)) {
834 CRM_Core_BAO_CustomGroup::buildCustomDataView($this, $this->_groupTree);
835 }
836 $buttons = array();
837 // do check for permissions
838 if (CRM_Case_BAO_Case::checkPermission($this->_activityId, 'File On Case', $this->_activityTypeId)) {
839 $buttons[] = array(
840 'type' => 'cancel',
841 'name' => ts('File on case'),
842 'subName' => 'file_on_case',
843 'js' => array('onClick' => "javascript:fileOnCase( \"file\", $this->_activityId ); return false;")
844 );
845 }
846 // form should be frozen for view mode
847 $this->freeze();
848
849 $buttons[] = array(
850 'type' => 'cancel',
851 'name' => ts('Done')
852 );
853
854 $this->addButtons($buttons);
855 }
856 else {
857 $message = array('completed' => ts('Are you sure? This is a COMPLETED activity with the DATE in the FUTURE. Click Cancel to change the date / status. Otherwise, click OK to save.'),
858 'scheduled' => ts('Are you sure? This is a SCHEDULED activity with the DATE in the PAST. Click Cancel to change the date / status. Otherwise, click OK to save.'),
859 );
860 $js = array('onclick' => "return activityStatus(" . json_encode($message) . ");");
861 $this->addButtons(array(
862 array(
863 'type' => 'upload',
864 'name' => ts('Save'),
865 'js' => $js,
866 'isDefault' => TRUE
867 ),
868 array(
869 'type' => 'cancel',
870 'name' => ts('Cancel')
871 )
872 )
873 );
874 }
875
876 if ($this->_activityTypeFile) {
877 eval("CRM_{$this->_crmDir}_Form_Activity_{$this->_activityTypeFile}::buildQuickForm( \$this );");
878 }
879
880 if ($this->_activityTypeFile) {
881 eval('$this->addFormRule' .
882 "(array(
883 'CRM_{$this->_crmDir}_Form_Activity_{$this->_activityTypeFile}', 'formrule'), \$this);"
884 );
885 }
886
887 $this->addFormRule(array('CRM_Activity_Form_Activity', 'formRule'), $this);
6db7e202
BS
888
889 if ( CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME,
890 'activity_assignee_notification' )
891 ) {
892 $this->assign('activityAssigneeNotification', true);
893 }
6a488035
TO
894 }
895
896 /**
897 * global form rule
898 *
899 * @param array $fields the input form values
900 * @param array $files the uploaded files if any
901 * @param array $options additional user data
902 *
903 * @return true if no errors, else array of errors
904 * @access public
905 * @static
906 */
907 static function formRule($fields, $files, $self) {
908 // skip form rule if deleting
909 if (CRM_Utils_Array::value('_qf_Activity_next_', $fields) == 'Delete') {
910 return TRUE;
911 }
912 $errors = array();
913 if (!$self->_single && !$fields['activity_type_id']) {
914 $errors['activity_type_id'] = ts('Activity Type is a required field');
915 }
916
917 //Activity type is mandatory if creating new activity, CRM-4515
918 if (array_key_exists('activity_type_id', $fields) &&
919 !CRM_Utils_Array::value('activity_type_id', $fields)
920 ) {
921 $errors['activity_type_id'] = ts('Activity Type is required field.');
922 }
923 //FIX me temp. comment
924 // make sure if associated contacts exist
925
926 if ($fields['source_contact_id'] && !is_numeric($fields['source_contact_qid'])) {
927 $errors['source_contact_id'] = ts('Source Contact non-existent!');
928 }
929
930 if (CRM_Utils_Array::value('activity_type_id', $fields) == 3 &&
931 CRM_Utils_Array::value('status_id', $fields) == 1
932 ) {
933 $errors['status_id'] = ts('You cannot record scheduled email activity.');
934 }
935 elseif (CRM_Utils_Array::value('activity_type_id', $fields) == 4 &&
936 CRM_Utils_Array::value('status_id', $fields) == 1
937 ) {
938 $errors['status_id'] = ts('You cannot record scheduled SMS activity.');
939 }
940
941 if (CRM_Utils_Array::value('followup_activity_type_id', $fields) && !CRM_Utils_Array::value('followup_date', $fields)) {
942 $errors['followup_date_time'] = ts('Followup date is a required field.');
943 }
944 //Activity type is mandatory if subject or follow-up date is specified for an Follow-up activity, CRM-4515
945 if ((CRM_Utils_Array::value('followup_activity_subject', $fields) || CRM_Utils_Array::value('followup_date', $fields)) &&
946 !CRM_Utils_Array::value('followup_activity_type_id', $fields)
947 ) {
948 $errors['followup_activity_subject'] = ts('Follow-up Activity type is a required field.');
949 }
950 return $errors;
951 }
952
953 /**
954 * Function to process the form
955 *
956 * @access public
957 *
958 * @return None
959 */
960 public function postProcess($params = NULL) {
961 if ($this->_action & CRM_Core_Action::DELETE) {
962 $deleteParams = array('id' => $this->_activityId);
963 $moveToTrash = CRM_Case_BAO_Case::isCaseActivity($this->_activityId);
964 CRM_Activity_BAO_Activity::deleteActivity($deleteParams, $moveToTrash);
965
966 // delete tags for the entity
967 $tagParams = array(
968 'entity_table' => 'civicrm_activity',
969 'entity_id' => $this->_activityId
970 );
971
972 CRM_Core_BAO_EntityTag::del($tagParams);
973
974 CRM_Core_Session::setStatus(ts("Selected Activity has been deleted successfully."), ts('Record Deleted'), 'success');
975 return;
976 }
977
978 // store the submitted values in an array
979 if (!$params) {
980 $params = $this->controller->exportValues($this->_name);
981 }
982
983 //set activity type id
984 if (!CRM_Utils_Array::value('activity_type_id', $params)) {
985 $params['activity_type_id'] = $this->_activityTypeId;
986 }
987
988 if (CRM_Utils_Array::value('hidden_custom', $params) &&
989 !isset($params['custom'])
990 ) {
991 $customFields = CRM_Core_BAO_CustomField::getFields('Activity', FALSE, FALSE,
992 $this->_activityTypeId
993 );
994 $customFields = CRM_Utils_Array::crmArrayMerge($customFields,
995 CRM_Core_BAO_CustomField::getFields('Activity', FALSE, FALSE,
996 NULL, NULL, TRUE
997 )
998 );
999 $params['custom'] = CRM_Core_BAO_CustomField::postProcess($params,
1000 $customFields,
1001 $this->_activityId,
1002 'Activity'
1003 );
1004 }
1005
1006 // store the date with proper format
1007 $params['activity_date_time'] = CRM_Utils_Date::processDate($params['activity_date_time'], $params['activity_date_time_time']);
1008
1009 // format with contact (target contact) values
1010 if (isset($params['contact'][1])) {
1011 $params['target_contact_id'] = explode(',', $params['contact'][1]);
1012 }
1013 else {
1014 $params['target_contact_id'] = array();
1015 }
1016
1017 // assigning formated value to related variable
1018 if (CRM_Utils_Array::value('assignee_contact_id', $params)) {
1019 $params['assignee_contact_id'] = explode(',', $params['assignee_contact_id']);
1020 }
1021 else {
1022 $params['assignee_contact_id'] = array();
1023 }
1024
1025 // get ids for associated contacts
1026 if (!$params['source_contact_id']) {
1027 $params['source_contact_id'] = $this->_currentUserId;
1028 }
1029 else {
1030 $params['source_contact_id'] = $this->_submitValues['source_contact_qid'];
1031 }
1032
1033 if (isset($this->_activityId)) {
1034 $params['id'] = $this->_activityId;
1035 }
1036
1037 // add attachments as needed
1038 CRM_Core_BAO_File::formatAttachment($params,
1039 $params,
1040 'civicrm_activity',
1041 $this->_activityId
1042 );
1043
1044 // format target params
1045 if (!$this->_single) {
1046 $params['target_contact_id'] = $this->_contactIds;
1047 }
1048
52c7b3a2
KJ
1049 $activity = array();
1050 if (CRM_Utils_Array::value('is_multi_activity', $params) &&
1051 !CRM_Utils_Array::crmIsEmptyArray($params['target_contact_id'])
1052 ) {
1053 $targetContacts = $params['target_contact_id'];
1054 foreach($targetContacts as $targetContactId) {
1055 $params['target_contact_id'] = array($targetContactId);
1056 // save activity
1057 $activity[] = $this->processActivity($params);
1058 }
1059 }
1060 else {
1061 // save activity
1062 $activity = $this->processActivity($params);
1063 }
1064
1065 return array('activity' => $activity);
1066 }
1067
1068 /**
1069 * Process activity creation
1070 *
1071 * @param array $params associated array of submitted values
1072 * @access protected
1073 */
1074 protected function processActivity(&$params) {
6a488035
TO
1075 $activityAssigned = array();
1076 // format assignee params
1077 if (!CRM_Utils_Array::crmIsEmptyArray($params['assignee_contact_id'])) {
1078 //skip those assignee contacts which are already assigned
1079 //while sending a copy.CRM-4509.
1080 $activityAssigned = array_flip($params['assignee_contact_id']);
1081 if ($this->_activityId) {
1082 $assigneeContacts = CRM_Activity_BAO_ActivityAssignment::getAssigneeNames($this->_activityId);
1083 $activityAssigned = array_diff_key($activityAssigned, $assigneeContacts);
1084 }
1085 }
1086
1087 // call begin post process. Idea is to let injecting file do
1088 // any processing before the activity is added/updated.
1089 $this->beginPostProcess($params);
1090
1091 $activity = CRM_Activity_BAO_Activity::create($params);
1092
1093 // add tags if exists
1094 $tagParams = array();
1095 if (!empty($params['tag'])) {
1096 foreach ($params['tag'] as $tag) {
1097 $tagParams[$tag] = 1;
1098 }
1099 }
1100
1101 //save static tags
1102 CRM_Core_BAO_EntityTag::create($tagParams, 'civicrm_activity', $activity->id);
1103
1104 //save free tags
1105 if (isset($params['activity_taglist']) && !empty($params['activity_taglist'])) {
1106 CRM_Core_Form_Tag::postProcess($params['activity_taglist'], $activity->id, 'civicrm_activity', $this);
1107 }
1108
1109 // call end post process. Idea is to let injecting file do any
1110 // processing needed, after the activity has been added/updated.
1111 $this->endPostProcess($params, $activity);
1112
1113 // CRM-9590
52c7b3a2
KJ
1114 if (CRM_Utils_Array::value('is_multi_activity', $params)) {
1115 $this->_activityIds[] = $activity->id;
1116 }
1117 else {
1118 $this->_activityId = $activity->id;
1119 }
6a488035
TO
1120
1121 // create follow up activity if needed
1122 $followupStatus = '';
1123 if (CRM_Utils_Array::value('followup_activity_type_id', $params)) {
52c7b3a2 1124 CRM_Activity_BAO_Activity::createFollowupActivity($activity->id, $params);
6a488035
TO
1125 $followupStatus = ts('A followup activity has been scheduled.');
1126 }
1127
1128 // send copy to assignee contacts.CRM-4509
1129 $mailStatus = '';
1130
1131 if (!CRM_Utils_Array::crmIsEmptyArray($params['assignee_contact_id']) &&
1132 CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME,
1133 'activity_assignee_notification'
1134 )
1135 ) {
1136 $mailToContacts = array();
1137 $assigneeContacts = CRM_Activity_BAO_ActivityAssignment::getAssigneeNames($activity->id, TRUE, FALSE);
1138
1139 //build an associative array with unique email addresses.
1140 foreach ($activityAssigned as $id => $dnc) {
1141 if (isset($id) && array_key_exists($id, $assigneeContacts)) {
1142 $mailToContacts[$assigneeContacts[$id]['email']] = $assigneeContacts[$id];
1143 }
1144 }
1145
1146 if (!CRM_Utils_array::crmIsEmptyArray($mailToContacts)) {
1147 //include attachments while sendig a copy of activity.
1148 $attachments = CRM_Core_BAO_File::getEntityFile('civicrm_activity', $activity->id);
1149
1150 $ics = new CRM_Activity_BAO_ICalendar( $activity );
1151 $ics->addAttachment( $attachments, $mailToContacts );
1152
1153 // CRM-8400 add param with _currentlyViewedContactId for URL link in mail
52c7b3a2 1154 CRM_Case_BAO_Case::sendActivityCopy(NULL, $activity->id, $mailToContacts, $attachments, NULL);
6a488035
TO
1155
1156 $ics->cleanup();
1157
1158 $mailStatus .= ts("A copy of the activity has also been sent to assignee contacts(s).");
1159 }
1160 }
1161
1162 // set status message
ef89f226 1163 $subject = '';
6a488035 1164 if (CRM_Utils_Array::value('subject', $params)) {
ef89f226 1165 $subject = "'" . $params['subject'] . "'";
6a488035
TO
1166 }
1167
1168 CRM_Core_Session::setStatus(ts('Activity %1 has been saved. %2. %3',
52c7b3a2 1169 array(
ef89f226 1170 1 => $subject,
52c7b3a2
KJ
1171 2 => $followupStatus,
1172 3 => $mailStatus
1173 )
1174 ), ts('Saved'), 'success');
6a488035 1175
52c7b3a2 1176 return $activity;
6a488035
TO
1177 }
1178
1179 /**
1180 * Shorthand for getting id by display name (makes code more readable)
1181 *
1182 * @access protected
1183 */
1184 protected function _getIdByDisplayName($displayName) {
1185 return CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact',
1186 $displayName,
1187 'id',
1188 'sort_name'
1189 );
1190 }
1191
1192 /**
1193 * Shorthand for getting display name by id (makes code more readable)
1194 *
1195 * @access protected
1196 */
1197 protected function _getDisplayNameById($id) {
1198 return CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact',
1199 $id,
1200 'sort_name',
1201 'id'
1202 );
1203 }
1204
1205 /**
1206 * Function to let injecting activity type file do any processing
1207 * needed, before the activity is added/updated
1208 *
1209 */
1210 function beginPostProcess(&$params) {
1211 if ($this->_activityTypeFile) {
1212 eval("CRM_{$this->_crmDir}_Form_Activity_{$this->_activityTypeFile}" .
1213 "::beginPostProcess( \$this, \$params );"
1214 );
1215 }
1216 }
1217
1218 /**
1219 * Function to let injecting activity type file do any processing
1220 * needed, after the activity has been added/updated
1221 *
1222 */
1223 function endPostProcess(&$params, &$activity) {
1224 if ($this->_activityTypeFile) {
1225 eval("CRM_{$this->_crmDir}_Form_Activity_{$this->_activityTypeFile}" .
1226 "::endPostProcess( \$this, \$params, \$activity );"
1227 );
1228 }
1229 }
1230}
1231