3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.3 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2013 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
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. |
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. |
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 +--------------------------------------------------------------------+
31 * @copyright CiviCRM LLC (c) 2004-2013
37 * This class generates form components for Activity
40 class CRM_Activity_Form_Activity
extends CRM_Contact_Form_Task
{
43 * The id of the object being edited / created
50 * store activity ids when multiple activities are created
54 public $_activityIds = array();
57 * The id of activity type
61 public $_activityTypeId;
64 * The name of activity type
68 public $_activityTypeName;
71 * The id of currently viewed contact
75 public $_currentlyViewedContactId;
78 * The id of source contact and target contact
82 protected $_sourceContactId;
83 protected $_targetContactId;
84 protected $_asigneeContactId;
91 public $_activityTypeFile;
94 * The id of the logged in user, used when add / edit
98 public $_currentUserId;
101 * The array of form field attributes
108 * The the directory inside CRM, to include activity type file from
112 protected $_crmDir = 'Activity';
120 protected $_isSurveyActivity;
122 protected $_values = array();
125 * The _fields var can be used by sub class to set/unset/edit the
126 * form fields based on their requirement
129 function setFields() {
130 $this->_fields
= array(
133 'label' => ts('Subject'),
134 'attributes' => CRM_Core_DAO
::getAttribute('CRM_Activity_DAO_Activity',
140 'label' => ts('Duration'),
141 'attributes' => array('size' => 4, 'maxlength' => 8),
146 'label' => ts('Location'),
148 CRM_Core_DAO
::getAttribute('CRM_Activity_DAO_Activity',
155 'label' => ts('Details'),
156 // forces a smaller edit window
157 'attributes' => array('rows' => 4, 'cols' => 60),
160 'status_id' => array(
162 'label' => ts('Status'),
164 CRM_Core_PseudoConstant
::activityStatus(),
167 'priority_id' => array(
169 'label' => ts('Priority'),
171 CRM_Core_PseudoConstant
::priority(),
174 'source_contact_id' => array(
176 'label' => ts('Added By'),
179 'followup_activity_type_id' => array(
181 'label' => ts('Followup Activity'),
182 'attributes' => array(
183 '' => '- ' . ts('select activity') . ' -') +
184 CRM_Core_PseudoConstant
::ActivityType(FALSE)
186 // Add optional 'Subject' field for the Follow-up Activiity, CRM-4491
187 'followup_activity_subject' => array(
189 'label' => ts('Subject'),
190 'attributes' => CRM_Core_DAO
::getAttribute('CRM_Activity_DAO_Activity',
196 if (($this->_context
== 'standalone') &&
197 ($printPDF = CRM_Utils_Array
::key('Print PDF Letter', $this->_fields
['followup_activity_type_id']['attributes']))
199 unset($this->_fields
['followup_activity_type_id']['attributes'][$printPDF]);
204 * Function to build the form
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);
217 $this->_atypefile
= CRM_Utils_Array
::value('atypefile', $_GET);
218 $this->assign('atypefile', FALSE);
219 if ($this->_atypefile
) {
220 $this->assign('atypefile', TRUE);
223 $session = CRM_Core_Session
::singleton();
224 $this->_currentUserId
= $session->get('userID');
226 $this->_currentlyViewedContactId
= $this->get('contactId');
227 if (!$this->_currentlyViewedContactId
) {
228 $this->_currentlyViewedContactId
= CRM_Utils_Request
::retrieve('cid', 'Positive', $this);
230 $this->assign('contactId', $this->_currentlyViewedContactId
);
232 if ($this->_currentlyViewedContactId
) {
233 CRM_Contact_Page_View
::setTitle($this->_currentlyViewedContactId
);
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';
242 elseif (!in_array($this->_context
, array('dashlet', 'dashletFullscreen'))
243 && $this->_currentlyViewedContactId
245 $this->_context
= 'activity';
247 $this->_compContext
= CRM_Utils_Request
::retrieve('compContext', 'String', $this);
250 $this->assign('context', $this->_context
);
252 $this->_action
= CRM_Utils_Request
::retrieve('action', 'String', $this);
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'));
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.
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'
269 $this->_activityId
= CRM_Utils_Request
::retrieve('id', 'Positive', $this);
272 $this->_activityTypeId
= CRM_Utils_Request
::retrieve('atype', 'Positive', $this);
273 $this->assign('atype', $this->_activityTypeId
);
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
)
281 CRM_Core_Error
::fatal(ts('You do not have permission to access this page.'));
283 if (($this->_action
& CRM_Core_Action
::VIEW
) &&
284 CRM_Activity_BAO_Activity
::checkPermission($this->_activityId
, CRM_Core_Action
::UPDATE
)
286 $this->assign('permission', 'edit');
289 if (!$this->_activityTypeId
&& $this->_activityId
) {
290 $this->_activityTypeId
= CRM_Core_DAO
::getFieldValue('CRM_Activity_DAO_Activity',
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
]);
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);
311 //check the mode when this form is called either single or as
313 if ($this->_activityTypeId ||
314 $this->_context
== 'standalone' ||
315 $this->_currentlyViewedContactId
317 $this->_single
= TRUE;
318 $this->assign('urlPath', 'civicrm/activity');
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) {
329 $searchType = $seachPath;
330 $this->_action
= CRM_Core_Action
::BASIC
;
334 $searchType = $seachPath;
335 $this->_action
= CRM_Core_Action
::ADVANCED
;
339 $searchType = $seachPath;
340 $this->_action
= CRM_Core_Action
::PROFILE
;
344 $this->_action
= CRM_Core_Action
::COPY
;
345 $searchType = $seachPath;
349 parent
::preProcess();
350 $this->_single
= FALSE;
352 $this->assign('urlPath', "civicrm/contact/search/$searchType");
353 $this->assign('urlPathVar', "_qf_Activity_display=true&qfKey={$this->controller->_key}");
356 $this->assign('single', $this->_single
);
357 $this->assign('action', $this->_action
);
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
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);
374 $urlParams = $urlString = NULL;
375 $qfKey = CRM_Utils_Request
::retrieve('key', 'String', $this);
377 $qfKey = CRM_Utils_Request
::retrieve('qfKey', 'String', $this);
381 if (!CRM_Utils_Rule
::qfKey($qfKey)) {
385 if ($this->_context
== 'fulltext') {
387 $urlParams = 'force=1';
388 $urlString = 'civicrm/contact/search/custom';
389 if ($this->_action
== CRM_Core_Action
::UPDATE
) {
391 $urlParams .= '&context=fulltext&action=view';
392 $urlString = 'civicrm/contact/view/activity';
395 $urlParams .= "$keyName=$qfKey";
397 $this->assign('searchKey', $qfKey);
399 elseif (in_array($this->_context
, array(
400 'standalone', 'home', 'dashlet', 'dashletFullscreen'))) {
401 $urlParams = 'reset=1';
402 $urlString = 'civicrm/dashboard';
404 elseif ($this->_context
== 'search') {
405 $urlParams = 'force=1';
407 $urlParams .= "&qfKey=$qfKey";
409 $path = CRM_Utils_System
::currentPath();
410 if ($this->_compContext
== 'advanced' ||
411 $path == 'civicrm/contact/search/advanced') {
412 $urlString = 'civicrm/contact/search/advanced';
414 else if ($path == 'civicrm/contact/search') {
415 $urlString = 'civicrm/contact/search';
418 $urlString = 'civicrm/activity/search';
420 $this->assign('searchKey', $qfKey);
422 elseif ($this->_context
!= 'caseActivity') {
423 $urlParams = "action=browse&reset=1&cid={$this->_currentlyViewedContactId}&selectedChild=activity";
424 $urlString = 'civicrm/contact/view';
428 $session->pushUserContext(CRM_Utils_System
::url($urlString, $urlParams));
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);
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
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);
449 // add attachments part
450 CRM_Core_BAO_File
::buildAttachment($this, 'civicrm_activity', $this->_activityId
, NULL, TRUE);
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
)
457 $this->assign('activityTypeFile', $this->_activityTypeFile
);
458 $this->assign('crmDir', $this->_crmDir
);
463 if ($this->_activityTypeFile
) {
464 eval("CRM_{$this->_crmDir}_Form_Activity_{$this->_activityTypeFile}::preProcess( \$this );");
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
);
474 $this->set('values', $this->_values
);
479 * This function sets the default values for the form. For edit/view mode
480 * the default values are retrieved from the database
486 function setDefaultValues() {
487 if ($this->_cdType
) {
488 return CRM_Custom_Form_CustomData
::setDefaultValues($this);
491 $defaults = $this->_values
;
493 // if we're editing...
494 if (isset($this->_activityId
)) {
495 $defaults['source_contact_qid'] = CRM_Utils_Array
::value( 'source_contact_id',
497 $defaults['source_contact_id'] = CRM_Utils_Array
::value( 'source_contact',
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);
504 if ($this->_action
& CRM_Core_Action
::VIEW
) {
505 $this->assign('target_contact', $target_contact);
508 //this assigned variable is used by newcontact creation widget to set defaults
509 $this->assign('prePopulateData', $this->formatContactValues($target_contact));
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);
517 if ($this->_action
& CRM_Core_Action
::VIEW
) {
518 $this->assign('assignee_contact', $assignee_contact);
521 $this->assign('assignee_contact', $this->formatContactValues($assignee_contact));
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');
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');
535 //set the assigneed contact count to template
536 if (!empty($defaults['assignee_contact'])) {
537 $this->assign('assigneeContactCount', count($defaults['assignee_contact']));
540 $this->assign('assigneeContactCount', 1);
543 //set the target contact count to template
544 if (!empty($defaults['target_contact'])) {
545 $this->assign('targetContactCount', count($defaults['target_contact']));
548 $this->assign('targetContactCount', 1);
551 if ($this->_context
!= 'standalone') {
552 $this->assign('target_contact_value',
553 CRM_Utils_Array
::value('target_contact_value', $defaults)
555 $this->assign('assignee_contact_value',
556 CRM_Utils_Array
::value('assignee_contact_value', $defaults)
558 $this->assign('source_contact_value',
559 CRM_Utils_Array
::value('source_contact', $defaults)
563 // set default tags if exists
564 $defaults['tag'] = CRM_Core_BAO_EntityTag
::getTag($this->_activityId
, 'civicrm_activity');
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();
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
);
579 //this assigned variable is used by newcontact creation widget to set defaults
580 $this->assign('prePopulateData', $this->formatContactValues($target_contact));
582 list($defaults['activity_date_time'], $defaults['activity_date_time_time']) =
583 CRM_Utils_Date
::setDateDefaults(NULL, 'activityDateTime');
586 if ($this->_activityTypeId
) {
587 $defaults['activity_type_id'] = $this->_activityTypeId
;
590 if ($this->_action
& (CRM_Core_Action
::DELETE | CRM_Core_Action
::RENEW
)) {
591 $this->assign('delName', CRM_Utils_Array
::value('subject', $defaults));
594 if ($this->_activityTypeFile
) {
595 eval('$defaults += CRM_' . $this->_crmDir
. '_Form_Activity_' .
596 $this->_activityTypeFile
. '::setDefaultValues($this);'
599 if (!CRM_Utils_Array
::value('priority_id', $defaults)) {
600 $priority = CRM_Core_PseudoConstant
::priority();
601 $defaults['priority_id'] = array_search('Normal', $priority);
603 if (!CRM_Utils_Array
::value('status_id', $defaults)) {
604 $defaults['status_id'] = CRM_Core_OptionGroup
::getDefaultValue('activity_status');
610 * Function to format contact values before assigning to autocomplete widget
612 * @param array $contactNames associated array of contact name and ids
614 * @return json encoded object
617 function formatContactValues(&$contactNames) {
618 //format target/assignee contact
619 $formatContacts = array();
620 foreach ($contactNames as $id => $name) {
621 $formatContacts[] = array(
627 return json_encode($formatContacts);
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);
635 $button = ts('Delete');
636 if ($this->_action
& CRM_Core_Action
::RENEW
) {
637 $button = ts('Restore');
639 $this->addButtons(array(
643 'spacing' => ' ',
648 'name' => ts('Cancel')
654 if (!$this->_single
&& !empty($this->_contactIds
)) {
655 $withArray = array();
656 foreach ($this->_contactIds
as $contactId) {
657 $withDisplayName = self
::_getDisplayNameById($contactId);
658 $withArray[] = "\"$withDisplayName\" ";
660 $this->assign('with', implode(', ', $withArray));
663 if ($this->_cdType
) {
664 return CRM_Custom_Form_CustomData
::buildQuickForm($this);
667 //build other activity links
668 CRM_Activity_Form_ActivityLinks
::commonBuildQuickForm($this);
670 //enable form element (ActivityLinks sets this true)
671 $this->assign('suppressForm', FALSE);
673 $element = &$this->add('select', 'activity_type_id', ts('Activity Type'),
674 $this->_fields
['followup_activity_type_id']['attributes'],
677 "CRM.buildCustomData( 'Activity', this.value );",
681 //freeze for update mode.
682 if ($this->_action
& CRM_Core_Action
::UPDATE
) {
686 foreach ($this->_fields
as $field => $values) {
687 if (CRM_Utils_Array
::value($field, $this->_fields
)) {
689 if (CRM_Utils_Array
::value('attributes', $values)) {
690 $attribute = $values['attributes'];
694 if (CRM_Utils_Array
::value('required', $values)) {
697 if ($values['type'] == 'wysiwyg') {
698 $this->addWysiwyg($field, $values['label'], $attribute, $required);
701 $this->add($values['type'], $field, $values['label'], $attribute, $required);
706 //CRM-7362 --add campaigns.
707 CRM_Campaign_BAO_Campaign
::addCampaign($this, CRM_Utils_Array
::value('campaign_id', $this->_values
));
709 //add engagement level CRM-7775
710 $buildEngagementLevel = FALSE;
711 if (CRM_Campaign_BAO_Campaign
::isCampaignEnable() &&
712 CRM_Campaign_BAO_Campaign
::accessCampaign()
714 $buildEngagementLevel = TRUE;
715 $this->add('select', 'engagement_level',
716 ts('Engagement Index'),
717 array('' => ts('- select -')) + CRM_Campaign_PseudoConstant
::engagementLevel()
719 $this->addRule('engagement_level',
720 ts('Please enter the engagement index as a number (integers only).'),
724 $this->assign('buildEngagementLevel', $buildEngagementLevel);
726 // check for survey activity
727 $this->_isSurveyActivity
= FALSE;
729 if ($this->_activityId
&& CRM_Campaign_BAO_Campaign
::isCampaignEnable() &&
730 CRM_Campaign_BAO_Campaign
::accessCampaign()
733 $this->_isSurveyActivity
= CRM_Campaign_BAO_Survey
::isSurveyActivity($this->_activityId
);
734 if ($this->_isSurveyActivity
) {
735 $surveyId = CRM_Core_DAO
::getFieldValue('CRM_Activity_DAO_Activity',
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)
747 $surveyTitle = CRM_Core_DAO
::getFieldValue('CRM_Campaign_DAO_Survey', $surveyId, 'title');
749 $this->assign('surveyTitle', $surveyTitle);
752 $this->assign('surveyActivity', $this->_isSurveyActivity
);
754 // this option should be available only during add mode
755 if ($this->_action
!= CRM_Core_Action
::UPDATE
) {
756 $this->add('advcheckbox', 'is_multi_activity', ts('Create a separate activity for each contact.'));
759 $this->addRule('duration',
760 ts('Please enter the duration as number of minutes (integers only).'), 'positiveInteger'
762 $this->addDateTime('activity_date_time', ts('Date'), TRUE, array('formatType' => 'activityDateTime'));
765 $this->addDateTime('followup_date', ts('in'), FALSE, array('formatType' => 'activityDateTime'));
768 $dataUrl = CRM_Utils_System
::url("civicrm/ajax/rest",
769 "className=CRM_Contact_Page_AJAX&fnName=getContactList&json=1&context=activity&reset=1",
772 $this->assign('dataUrl', $dataUrl);
775 $tokenUrl = CRM_Utils_System
::url("civicrm/ajax/checkemail",
779 $this->assign('tokenUrl', $tokenUrl);
781 $admin = CRM_Core_Permission
::check('administer CiviCRM');
782 //allow to edit sourcecontactfield field if context is civicase.
783 if ($this->_context
== 'caseActivity') {
787 $this->assign('admin', $admin);
789 $sourceContactField = &$this->add($this->_fields
['source_contact_id']['type'],
791 $this->_fields
['source_contact_id']['label'],
796 $this->add('hidden', 'source_contact_qid', '', array('id' => 'source_contact_qid'));
797 CRM_Contact_Form_NewContact
::buildQuickForm($this);
799 $this->add('text', 'assignee_contact_id', ts('assignee'));
801 if ($sourceContactField->getValue()) {
802 $this->assign('source_contact', $sourceContactField->getValue());
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
));
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
);
814 $tags = CRM_Core_BAO_Tag
::getTags('civicrm_activity');
817 $this->add('select', 'tag', ts('Tags'), $tags, FALSE,
818 array('id' => 'tags', 'multiple' => 'multiple', 'title' => ts('- select -'))
822 // we need to hide activity tagset for special activities
823 $specialActivities = array('Open Case');
825 if (!in_array($this->_activityTypeName
, $specialActivities)) {
827 $parentNames = CRM_Core_BAO_Tag
::getTagSet('civicrm_activity');
828 CRM_Core_Form_Tag
::buildQuickForm($this, $parentNames, 'civicrm_activity', $this->_activityId
, FALSE, TRUE);
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
);
837 // do check for permissions
838 if (CRM_Case_BAO_Case
::checkPermission($this->_activityId
, 'File On Case', $this->_activityTypeId
)) {
841 'name' => ts('File on case'),
842 'subName' => 'file_on_case',
843 'js' => array('onClick' => "javascript:fileOnCase( \"file\", $this->_activityId ); return false;")
846 // form should be frozen for view mode
854 $this->addButtons($buttons);
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.'),
860 $js = array('onclick' => "return activityStatus(" . json_encode($message) . ");");
861 $this->addButtons(array(
864 'name' => ts('Save'),
870 'name' => ts('Cancel')
876 if ($this->_activityTypeFile
) {
877 eval("CRM_{$this->_crmDir}_Form_Activity_{$this->_activityTypeFile}::buildQuickForm( \$this );");
880 if ($this->_activityTypeFile
) {
881 eval('$this->addFormRule' .
883 'CRM_{$this->_crmDir}_Form_Activity_{$this->_activityTypeFile}', 'formrule'), \$this);"
887 $this->addFormRule(array('CRM_Activity_Form_Activity', 'formRule'), $this);
889 if (CRM_Core_BAO_Setting
::getItem(
890 CRM_Core_BAO_Setting
::SYSTEM_PREFERENCES_NAME
,
891 'activity_assignee_notification'
894 $this->assign('activityAssigneeNotification', TRUE);
897 $this->assign('activityAssigneeNotification', FALSE);
904 * @param array $fields the input form values
905 * @param array $files the uploaded files if any
906 * @param array $options additional user data
908 * @return true if no errors, else array of errors
912 static function formRule($fields, $files, $self) {
913 // skip form rule if deleting
914 if (CRM_Utils_Array
::value('_qf_Activity_next_', $fields) == 'Delete') {
918 if (!$self->_single
&& !$fields['activity_type_id']) {
919 $errors['activity_type_id'] = ts('Activity Type is a required field');
922 //Activity type is mandatory if creating new activity, CRM-4515
923 if (array_key_exists('activity_type_id', $fields) &&
924 !CRM_Utils_Array
::value('activity_type_id', $fields)
926 $errors['activity_type_id'] = ts('Activity Type is required field.');
928 //FIX me temp. comment
929 // make sure if associated contacts exist
931 if ($fields['source_contact_id'] && !is_numeric($fields['source_contact_qid'])) {
932 $errors['source_contact_id'] = ts('Source Contact non-existent!');
935 if (CRM_Utils_Array
::value('activity_type_id', $fields) == 3 &&
936 CRM_Utils_Array
::value('status_id', $fields) == 1
938 $errors['status_id'] = ts('You cannot record scheduled email activity.');
940 elseif (CRM_Utils_Array
::value('activity_type_id', $fields) == 4 &&
941 CRM_Utils_Array
::value('status_id', $fields) == 1
943 $errors['status_id'] = ts('You cannot record scheduled SMS activity.');
946 if (CRM_Utils_Array
::value('followup_activity_type_id', $fields) && !CRM_Utils_Array
::value('followup_date', $fields)) {
947 $errors['followup_date_time'] = ts('Followup date is a required field.');
949 //Activity type is mandatory if subject or follow-up date is specified for an Follow-up activity, CRM-4515
950 if ((CRM_Utils_Array
::value('followup_activity_subject', $fields) || CRM_Utils_Array
::value('followup_date', $fields)) &&
951 !CRM_Utils_Array
::value('followup_activity_type_id', $fields)
953 $errors['followup_activity_subject'] = ts('Follow-up Activity type is a required field.');
959 * Function to process the form
965 public function postProcess($params = NULL) {
966 if ($this->_action
& CRM_Core_Action
::DELETE
) {
967 $deleteParams = array('id' => $this->_activityId
);
968 $moveToTrash = CRM_Case_BAO_Case
::isCaseActivity($this->_activityId
);
969 CRM_Activity_BAO_Activity
::deleteActivity($deleteParams, $moveToTrash);
971 // delete tags for the entity
973 'entity_table' => 'civicrm_activity',
974 'entity_id' => $this->_activityId
977 CRM_Core_BAO_EntityTag
::del($tagParams);
979 CRM_Core_Session
::setStatus(ts("Selected Activity has been deleted successfully."), ts('Record Deleted'), 'success');
983 // store the submitted values in an array
985 $params = $this->controller
->exportValues($this->_name
);
988 //set activity type id
989 if (!CRM_Utils_Array
::value('activity_type_id', $params)) {
990 $params['activity_type_id'] = $this->_activityTypeId
;
993 if (CRM_Utils_Array
::value('hidden_custom', $params) &&
994 !isset($params['custom'])
996 $customFields = CRM_Core_BAO_CustomField
::getFields('Activity', FALSE, FALSE,
997 $this->_activityTypeId
999 $customFields = CRM_Utils_Array
::crmArrayMerge($customFields,
1000 CRM_Core_BAO_CustomField
::getFields('Activity', FALSE, FALSE,
1004 $params['custom'] = CRM_Core_BAO_CustomField
::postProcess($params,
1011 // store the date with proper format
1012 $params['activity_date_time'] = CRM_Utils_Date
::processDate($params['activity_date_time'], $params['activity_date_time_time']);
1014 // format with contact (target contact) values
1015 if (isset($params['contact'][1])) {
1016 $params['target_contact_id'] = explode(',', $params['contact'][1]);
1019 $params['target_contact_id'] = array();
1022 // assigning formated value to related variable
1023 if (CRM_Utils_Array
::value('assignee_contact_id', $params)) {
1024 $params['assignee_contact_id'] = explode(',', $params['assignee_contact_id']);
1027 $params['assignee_contact_id'] = array();
1030 // get ids for associated contacts
1031 if (!$params['source_contact_id']) {
1032 $params['source_contact_id'] = $this->_currentUserId
;
1035 $params['source_contact_id'] = $this->_submitValues
['source_contact_qid'];
1038 if (isset($this->_activityId
)) {
1039 $params['id'] = $this->_activityId
;
1042 // add attachments as needed
1043 CRM_Core_BAO_File
::formatAttachment($params,
1049 // format target params
1050 if (!$this->_single
) {
1051 $params['target_contact_id'] = $this->_contactIds
;
1054 $activity = array();
1055 if (CRM_Utils_Array
::value('is_multi_activity', $params) &&
1056 !CRM_Utils_Array
::crmIsEmptyArray($params['target_contact_id'])
1058 $targetContacts = $params['target_contact_id'];
1059 foreach($targetContacts as $targetContactId) {
1060 $params['target_contact_id'] = array($targetContactId);
1062 $activity[] = $this->processActivity($params);
1067 $activity = $this->processActivity($params);
1070 return array('activity' => $activity);
1074 * Process activity creation
1076 * @param array $params associated array of submitted values
1079 protected function processActivity(&$params) {
1080 $activityAssigned = array();
1081 $activityContacts = CRM_Core_PseudoConstant
::activityContacts('name');
1082 $assigneeID = CRM_Utils_Array
::key('Activity Assignees', $activityContacts);
1083 // format assignee params
1084 if (!CRM_Utils_Array
::crmIsEmptyArray($params['assignee_contact_id'])) {
1085 //skip those assignee contacts which are already assigned
1086 //while sending a copy.CRM-4509.
1087 $activityAssigned = array_flip($params['assignee_contact_id']);
1088 if ($this->_activityId
) {
1089 $assigneeContacts = CRM_Activity_BAO_ActivityContact
::getNames($this->_activityId
, $assigneeID);
1090 $activityAssigned = array_diff_key($activityAssigned, $assigneeContacts);
1094 // call begin post process. Idea is to let injecting file do
1095 // any processing before the activity is added/updated.
1096 $this->beginPostProcess($params);
1098 $activity = CRM_Activity_BAO_Activity
::create($params);
1100 // add tags if exists
1101 $tagParams = array();
1102 if (!empty($params['tag'])) {
1103 foreach ($params['tag'] as $tag) {
1104 $tagParams[$tag] = 1;
1109 CRM_Core_BAO_EntityTag
::create($tagParams, 'civicrm_activity', $activity->id
);
1112 if (isset($params['activity_taglist']) && !empty($params['activity_taglist'])) {
1113 CRM_Core_Form_Tag
::postProcess($params['activity_taglist'], $activity->id
, 'civicrm_activity', $this);
1116 // call end post process. Idea is to let injecting file do any
1117 // processing needed, after the activity has been added/updated.
1118 $this->endPostProcess($params, $activity);
1121 if (CRM_Utils_Array
::value('is_multi_activity', $params)) {
1122 $this->_activityIds
[] = $activity->id
;
1125 $this->_activityId
= $activity->id
;
1128 // create follow up activity if needed
1129 $followupStatus = '';
1130 if (CRM_Utils_Array
::value('followup_activity_type_id', $params)) {
1131 CRM_Activity_BAO_Activity
::createFollowupActivity($activity->id
, $params);
1132 $followupStatus = ts('A followup activity has been scheduled.');
1135 // send copy to assignee contacts.CRM-4509
1138 if (!CRM_Utils_Array
::crmIsEmptyArray($params['assignee_contact_id']) &&
1139 CRM_Core_BAO_Setting
::getItem(CRM_Core_BAO_Setting
::SYSTEM_PREFERENCES_NAME
,
1140 'activity_assignee_notification'
1143 $mailToContacts = array();
1144 //FIX ME : add more parameters to 'getNames' function
1145 $assigneeContacts = CRM_Activity_BAO_ActivityContact
::getNames($activity->id
, $assigneeID, TRUE, FALSE);
1147 //build an associative array with unique email addresses.
1148 foreach ($activityAssigned as $id => $dnc) {
1149 if (isset($id) && array_key_exists($id, $assigneeContacts)) {
1150 $mailToContacts[$assigneeContacts[$id]['email']] = $assigneeContacts[$id];
1154 if (!CRM_Utils_array
::crmIsEmptyArray($mailToContacts)) {
1155 //include attachments while sendig a copy of activity.
1156 $attachments = CRM_Core_BAO_File
::getEntityFile('civicrm_activity', $activity->id
);
1158 $ics = new CRM_Activity_BAO_ICalendar( $activity );
1159 $ics->addAttachment( $attachments, $mailToContacts );
1161 // CRM-8400 add param with _currentlyViewedContactId for URL link in mail
1162 CRM_Case_BAO_Case
::sendActivityCopy(NULL, $activity->id
, $mailToContacts, $attachments, NULL);
1166 $mailStatus .= ts("A copy of the activity has also been sent to assignee contacts(s).");
1170 // set status message
1172 if (CRM_Utils_Array
::value('subject', $params)) {
1173 $subject = "'" . $params['subject'] . "'";
1176 CRM_Core_Session
::setStatus(ts('Activity %1 has been saved. %2. %3',
1179 2 => $followupStatus,
1182 ), ts('Saved'), 'success');
1188 * Shorthand for getting id by display name (makes code more readable)
1192 protected function _getIdByDisplayName($displayName) {
1193 return CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_Contact',
1201 * Shorthand for getting display name by id (makes code more readable)
1205 protected function _getDisplayNameById($id) {
1206 return CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_Contact',
1214 * Function to let injecting activity type file do any processing
1215 * needed, before the activity is added/updated
1218 function beginPostProcess(&$params) {
1219 if ($this->_activityTypeFile
) {
1220 eval("CRM_{$this->_crmDir}_Form_Activity_{$this->_activityTypeFile}" .
1221 "::beginPostProcess( \$this, \$params );"
1227 * Function to let injecting activity type file do any processing
1228 * needed, after the activity has been added/updated
1231 function endPostProcess(&$params, &$activity) {
1232 if ($this->_activityTypeFile
) {
1233 eval("CRM_{$this->_crmDir}_Form_Activity_{$this->_activityTypeFile}" .
1234 "::endPostProcess( \$this, \$params, \$activity );"