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