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