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