Merge pull request #17298 from demeritcowboy/activity-attachment-delete
[civicrm-core.git] / CRM / Case / Form / Case.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
bc77d7c0 4 | Copyright CiviCRM LLC. All rights reserved. |
6a488035 5 | |
bc77d7c0
TO
6 | This work is published under the GNU AGPLv3 license with some |
7 | permitted exceptions and without any warranty. For full license |
8 | and copyright information, see https://civicrm.org/licensing |
6a488035 9 +--------------------------------------------------------------------+
d25dd0ee 10 */
6a488035
TO
11
12/**
13 *
14 * @package CRM
ca5cec67 15 * @copyright CiviCRM LLC https://civicrm.org/licensing
6a488035
TO
16 */
17
18/**
df371444 19 * This class generates form components for case activity.
6a488035
TO
20 */
21class CRM_Case_Form_Case extends CRM_Core_Form {
22
23 /**
24 * The context
25 *
26 * @var string
27 */
28 public $_context = 'case';
29
30 /**
31 * Case Id
f157740d 32 * @var int
6a488035
TO
33 */
34 public $_caseId = NULL;
35
36 /**
37 * Client Id
f157740d 38 * @var int
6a488035
TO
39 */
40 public $_currentlyViewedContactId = NULL;
41
42 /**
43 * Activity Type File
f157740d 44 * @var int
6a488035
TO
45 */
46 public $_activityTypeFile = NULL;
47
48 /**
100fef9d 49 * Logged in contact Id
f157740d 50 * @var int
6a488035
TO
51 */
52 public $_currentUserId = NULL;
53
54 /**
100fef9d 55 * Activity type Id
f157740d 56 * @var int
6a488035
TO
57 */
58 public $_activityTypeId = NULL;
59
60 /**
100fef9d 61 * Activity type Id
f157740d 62 * @var int
6a488035
TO
63 */
64 public $_activityId = NULL;
65
66 /**
100fef9d 67 * Action
f157740d 68 * @var int
6a488035
TO
69 */
70 public $_action;
71
74fb6e99 72 /**
100fef9d 73 * Case type id
f157740d 74 * @var int
74fb6e99
PJ
75 */
76 public $_caseTypeId = NULL;
77
423616fa
CW
78 public $submitOnce = TRUE;
79
cc3dbc01
MWMC
80 /**
81 * Explicitly declare the entity api name.
82 */
83 public function getDefaultEntity() {
84 return 'Case';
85 }
86
87 /**
88 * Get the entity id being edited.
89 *
90 * @return int|null
91 */
92 public function getEntityId() {
93 return $this->_caseId;
94 }
95
6a488035 96 /**
fe482240 97 * Build the form object.
6a488035 98 */
00be9182 99 public function preProcess() {
a61c5f8f
MWMC
100 if (empty($this->_action)) {
101 $this->_action = CRM_Core_Action::ADD;
102 }
6a488035
TO
103
104 $this->_caseId = CRM_Utils_Request::retrieve('id', 'Positive', $this);
105
106 $this->_currentlyViewedContactId = CRM_Utils_Request::retrieve('cid', 'Positive', $this);
107
108 if ($this->_action & CRM_Core_Action::ADD && !$this->_currentlyViewedContactId) {
109 // check for add contacts permissions
110 if (!CRM_Core_Permission::check('add contacts')) {
111 CRM_Utils_System::permissionDenied();
112 return;
113 }
114 }
115
116 //CRM-4418
117 if (!CRM_Core_Permission::checkActionPermission('CiviCase', $this->_action)) {
e22ec653 118 CRM_Core_Error::statusBounce(ts('You do not have permission to access this page.'));
6a488035
TO
119 }
120
121 if ($this->_action & CRM_Core_Action::DELETE || $this->_action & CRM_Core_Action::RENEW) {
122 return TRUE;
123 }
124
125 if (!$this->_caseId) {
be2fb01f 126 $caseAttributes = [
7a5c0c6c
CW
127 'case_type_id' => ts('Case Type'),
128 'status_id' => ts('Case Status'),
129 'medium_id' => ts('Activity Medium'),
be2fb01f 130 ];
6a488035 131
7a5c0c6c
CW
132 foreach ($caseAttributes as $key => $label) {
133 if (!CRM_Case_BAO_Case::buildOptions($key, 'create')) {
e22ec653 134 CRM_Core_Error::statusBounce(ts('You do not have any active %1', [1 => $label]));
6a488035
TO
135 }
136 }
137 }
138
139 if ($this->_action & CRM_Core_Action::ADD) {
9c248a42 140 $this->_activityTypeId = CRM_Core_PseudoConstant::getKey('CRM_Activity_BAO_Activity', 'activity_type_id', 'Open Case');
6a488035 141 if (!$this->_activityTypeId) {
e22ec653 142 CRM_Core_Error::statusBounce(ts('The Open Case activity type is missing or disabled. Please have your site administrator check Administer > Option Lists > Activity Types for the CiviCase component.'));
6a488035
TO
143 }
144 }
145
146 //check for case permissions.
147 if (!CRM_Case_BAO_Case::accessCiviCase()) {
e22ec653 148 CRM_Core_Error::statusBounce(ts('You are not authorized to access this page.'));
6a488035
TO
149 }
150 if (($this->_action & CRM_Core_Action::ADD) &&
151 (!CRM_Core_Permission::check('access all cases and activities') &&
152 !CRM_Core_Permission::check('add cases')
153 )
154 ) {
e22ec653 155 CRM_Core_Error::statusBounce(ts('You are not authorized to access this page.'));
6a488035
TO
156 }
157
28a04ea9 158 if ($this->_activityTypeFile = CRM_Activity_BAO_Activity::getFileForActivityTypeId($this->_activityTypeId,
6a488035
TO
159 'Case'
160 )
161 ) {
162 $this->assign('activityTypeFile', $this->_activityTypeFile);
163 }
164
165 $details = CRM_Case_PseudoConstant::caseActivityType(FALSE);
166
167 CRM_Utils_System::setTitle($details[$this->_activityTypeId]['label']);
168 $this->assign('activityType', $details[$this->_activityTypeId]['label']);
169 $this->assign('activityTypeDescription', $details[$this->_activityTypeId]['description']);
170
171 if (isset($this->_currentlyViewedContactId)) {
172 $contact = new CRM_Contact_DAO_Contact();
173 $contact->id = $this->_currentlyViewedContactId;
174 if (!$contact->find(TRUE)) {
be2fb01f 175 CRM_Core_Error::statusBounce(ts('Client contact does not exist: %1', [1 => $this->_currentlyViewedContactId]));
6a488035
TO
176 }
177 $this->assign('clientName', $contact->display_name);
178 }
179
6a488035
TO
180 $session = CRM_Core_Session::singleton();
181 $this->_currentUserId = $session->get('userID');
182
cc3dbc01 183 //Add activity custom data is included in this page
6a488035 184 CRM_Custom_Form_CustomData::preProcess($this, NULL, $this->_activityTypeId, 1, 'Activity');
0e6e8724
DL
185 $className = "CRM_Case_Form_Activity_{$this->_activityTypeFile}";
186 $className::preProcess($this);
6a488035
TO
187 $activityGroupTree = $this->_groupTree;
188
cc3dbc01
MWMC
189 // Add case custom data to form
190 $caseTypeId = CRM_Utils_Array::value('case_type_id', CRM_Utils_Request::exportValues(), $this->_caseTypeId);
191 CRM_Custom_Form_CustomData::addToForm($this, $caseTypeId);
6a488035
TO
192
193 // so that grouptree is not populated with case fields, since the grouptree is used
194 // for populating activity custom fields.
195 $this->_groupTree = $activityGroupTree;
196 }
197
198 /**
df371444 199 * Set default values for the form.
6a488035 200 */
00be9182 201 public function setDefaultValues() {
39082712 202 if ($this->_action & CRM_Core_Action::DELETE || $this->_action & CRM_Core_Action::RENEW) {
6a488035
TO
203 return TRUE;
204 }
0e6e8724
DL
205 $className = "CRM_Case_Form_Activity_{$this->_activityTypeFile}";
206 $defaults = $className::setDefaultValues($this);
6a488035
TO
207 $defaults = array_merge($defaults, CRM_Custom_Form_CustomData::setDefaultValues($this));
208 return $defaults;
209 }
210
211 public function buildQuickForm() {
212 $xmlProcessorProcess = new CRM_Case_XMLProcessor_Process();
213 $isMultiClient = $xmlProcessorProcess->getAllowMultipleCaseClients();
214 $this->assign('multiClient', $isMultiClient);
215
216 if ($this->_action & CRM_Core_Action::DELETE || $this->_action & CRM_Core_Action::RENEW) {
e60e0c01 217 $title = ts('Delete');
6a488035 218 if ($this->_action & CRM_Core_Action::RENEW) {
e60e0c01 219 $title = ts('Restore');
6a488035 220 }
be2fb01f 221 $this->addButtons([
5d4fcf54
TO
222 [
223 'type' => 'next',
224 'name' => $title,
225 'spacing' => '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;',
226 'isDefault' => TRUE,
227 ],
228 [
229 'type' => 'cancel',
230 'name' => ts('Cancel'),
231 ],
232 ]);
6a488035
TO
233 return;
234 }
235
cc3dbc01 236 // Add the activity custom data to the form
6a488035 237 CRM_Custom_Form_CustomData::buildQuickForm($this);
cc3dbc01 238
6a488035
TO
239 // we don't want to show button on top of custom form
240 $this->assign('noPreCustomButton', TRUE);
241
242 $s = CRM_Core_DAO::getAttribute('CRM_Activity_DAO_Activity', 'subject');
243 if (!is_array($s)) {
be2fb01f 244 $s = [];
6a488035
TO
245 }
246 $this->add('text', 'activity_subject', ts('Subject'),
be2fb01f 247 array_merge($s, [
28a04ea9 248 'maxlength' => '128',
be2fb01f 249 ]), TRUE
6a488035
TO
250 );
251
b733747a 252 $tags = CRM_Core_BAO_Tag::getColorTags('civicrm_case');
47358d92 253
6a488035 254 if (!empty($tags)) {
b733747a 255 $this->add('select2', 'tag', ts('Tags'), $tags, FALSE,
be2fb01f 256 ['class' => 'huge', 'multiple' => 'multiple']
6a488035
TO
257 );
258 }
259
260 // build tag widget
261 $parentNames = CRM_Core_BAO_Tag::getTagSet('civicrm_case');
95ef220a 262 CRM_Core_Form_Tag::buildQuickForm($this, $parentNames, 'civicrm_case', NULL, FALSE, TRUE);
6a488035 263
be2fb01f 264 $this->addButtons([
5d4fcf54
TO
265 [
266 'type' => 'next',
267 'name' => ts('Save'),
268 'spacing' => '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;',
269 'isDefault' => TRUE,
270 ],
271 [
272 'type' => 'cancel',
273 'name' => ts('Cancel'),
274 ],
275 ]);
6a488035 276
0e6e8724
DL
277 $className = "CRM_Case_Form_Activity_{$this->_activityTypeFile}";
278 $className::buildQuickForm($this);
6a488035
TO
279 }
280
281 /**
fe482240 282 * Add local and global form rules.
6a488035 283 *
df371444 284 * @return bool
6a488035 285 */
00be9182 286 public function addRules() {
39082712 287 if ($this->_action & CRM_Core_Action::DELETE || $this->_action & CRM_Core_Action::RENEW) {
6a488035
TO
288 return TRUE;
289 }
0e6e8724 290 $className = "CRM_Case_Form_Activity_{$this->_activityTypeFile}";
be2fb01f
CW
291 $this->addFormRule([$className, 'formRule'], $this);
292 $this->addFormRule(['CRM_Case_Form_Case', 'formRule'], $this);
6a488035
TO
293 }
294
295 /**
fe482240 296 * Global validation rules for the form.
6a488035 297 *
64bd5a0e
TO
298 * @param array $values
299 * Posted values of the form.
6a488035 300 *
da6b46f4 301 * @param $files
c490a46a 302 * @param CRM_Core_Form $form
da6b46f4 303 *
a6c01b45
CW
304 * @return array
305 * list of errors to be posted back to the form
6a488035 306 */
00be9182 307 public static function formRule($values, $files, $form) {
6a488035
TO
308 return TRUE;
309 }
310
311 /**
110a4e22
AP
312 * Wrapper for unit testing the post process submit function.
313 *
314 * @param $params
315 * @param $activityTypeFile
316 * @param $contactId
317 * @param $context
318 * @return CRM_Case_BAO_Case
6a488035 319 */
110a4e22
AP
320 public function testSubmit($params, $activityTypeFile, $contactId, $context = "case") {
321 $this->controller = new CRM_Core_Controller();
6a488035 322
110a4e22
AP
323 $this->_activityTypeFile = $activityTypeFile;
324 $this->_currentUserId = $contactId;
325 $this->_context = $context;
6a488035 326
110a4e22
AP
327 return $this->submit($params);
328 }
6a488035 329
110a4e22
AP
330 /**
331 * Submit the form with given params.
332 *
333 * @param $params
334 */
335 public function submit(&$params) {
6a488035
TO
336 $params['now'] = date("Ymd");
337
6a488035
TO
338 // 1. call begin post process
339 if ($this->_activityTypeFile) {
0e6e8724 340 $className = "CRM_Case_Form_Activity_{$this->_activityTypeFile}";
481a74f4 341 $className::beginPostProcess($this, $params);
6a488035
TO
342 }
343
a7488080 344 if (!empty($params['hidden_custom']) &&
6a488035
TO
345 !isset($params['custom'])
346 ) {
0e6e8724
DL
347 $params['custom'] = CRM_Core_BAO_CustomField::postProcess(
348 $params,
6a488035
TO
349 NULL,
350 'Case'
351 );
352 }
353
354 // 2. create/edit case
a7488080 355 if (!empty($params['case_type_id'])) {
d14b35a4 356 $params['case_type'] = CRM_Core_DAO::getFieldValue('CRM_Case_DAO_CaseType', $params['case_type_id'], 'name', 'id');
6a488035 357 $params['subject'] = $params['activity_subject'];
a0269370 358 // 'civicrm_case.details' is not used in core but is used in the CiviCase extension
fa681126 359 $params['details'] = $params['activity_details'];
6a488035
TO
360 }
361 $caseObj = CRM_Case_BAO_Case::create($params);
aec75ba0 362 $this->_caseId = $params['case_id'] = $caseObj->id;
6a488035
TO
363 // unset any ids, custom data
364 unset($params['id'], $params['custom']);
365
366 // add tags if exists
be2fb01f 367 $tagParams = [];
6a488035 368 if (!empty($params['tag'])) {
be2fb01f 369 $tagParams = [];
b733747a
CW
370 if (!is_array($params['tag'])) {
371 $params['tag'] = explode(',', $params['tag']);
372 }
6a488035
TO
373 foreach ($params['tag'] as $tag) {
374 $tagParams[$tag] = 1;
375 }
376 }
377 CRM_Core_BAO_EntityTag::create($tagParams, 'civicrm_case', $caseObj->id);
378
379 //save free tags
380 if (isset($params['case_taglist']) && !empty($params['case_taglist'])) {
381 CRM_Core_Form_Tag::postProcess($params['case_taglist'], $caseObj->id, 'civicrm_case', $this);
382 }
383
384 // user context
385 $url = CRM_Utils_System::url('civicrm/contact/view/case',
386 "reset=1&action=view&cid={$this->_currentlyViewedContactId}&id={$caseObj->id}"
387 );
1ff6ec79 388 CRM_Core_Session::singleton()->pushUserContext($url);
6a488035
TO
389
390 // 3. format activity custom data
a7488080 391 if (!empty($params['hidden_custom'])) {
6a488035
TO
392 $customFields = CRM_Core_BAO_CustomField::getFields('Activity', FALSE, FALSE, $this->_activityTypeId);
393 $customFields = CRM_Utils_Array::crmArrayMerge($customFields,
394 CRM_Core_BAO_CustomField::getFields('Activity', FALSE, FALSE,
395 NULL, NULL, TRUE
396 )
397 );
398 $params['custom'] = CRM_Core_BAO_CustomField::postProcess($params,
6a488035
TO
399 $this->_activityId,
400 'Activity'
401 );
402 }
403
404 // 4. call end post process
405 if ($this->_activityTypeFile) {
481a74f4 406 $className::endPostProcess($this, $params);
6a488035
TO
407 }
408
110a4e22
AP
409 return $caseObj;
410 }
411
412 /**
413 * Process the form submission.
414 */
415 public function postProcess() {
416 $transaction = new CRM_Core_Transaction();
417
418 // check if dedupe button, if so return.
419 $buttonName = $this->controller->getButtonName();
420 if (isset($this->_dedupeButtonName) && $buttonName == $this->_dedupeButtonName) {
421 return;
422 }
423
424 if ($this->_action & CRM_Core_Action::DELETE) {
425 $caseDelete = CRM_Case_BAO_Case::deleteCase($this->_caseId, TRUE);
426 if ($caseDelete) {
427 CRM_Core_Session::setStatus(ts('You can view and / or restore deleted cases by checking the "Deleted Cases" option under Find Cases.'), ts('Case Deleted'), 'success');
428 }
429 return;
430 }
431
432 if ($this->_action & CRM_Core_Action::RENEW) {
433 $caseRestore = CRM_Case_BAO_Case::restoreCase($this->_caseId);
434 if ($caseRestore) {
435 CRM_Core_Session::setStatus(ts('The selected case has been restored.'), ts('Restored'), 'success');
436 }
437 return;
438 }
439 // store the submitted values in an array
440 $params = $this->controller->exportValues($this->_name);
441 $this->submit($params);
442
79dc2175 443 CRM_Core_Session::setStatus($params['statusMsg'], ts('Saved'), 'success');
110a4e22 444
6a488035 445 }
96025800 446
6a488035 447}