Commit | Line | Data |
---|---|---|
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 | class CRM_Case_XMLProcessor_Process extends CRM_Case_XMLProcessor { | |
36 | function run($caseType, &$params) { | |
37 | $xml = $this->retrieve($caseType); | |
38 | ||
39 | if ($xml === FALSE) { | |
40 | $docLink = CRM_Utils_System::docURL2("user/case-management/setup"); | |
41 | CRM_Core_Error::fatal(ts("Configuration file could not be retrieved for case type = '%1' %2.", | |
42 | array(1 => $caseType, 2 => $docLink) | |
43 | )); | |
44 | return FALSE; | |
45 | } | |
46 | ||
47 | $xmlProcessorProcess = new CRM_Case_XMLProcessor_Process(); | |
48 | $this->_isMultiClient = $xmlProcessorProcess->getAllowMultipleCaseClients(); | |
49 | ||
50 | $this->process($xml, $params); | |
51 | } | |
52 | ||
53 | function get($caseType, $fieldSet, $isLabel = FALSE, $maskAction = FALSE) { | |
54 | $xml = $this->retrieve($caseType); | |
55 | if ($xml === FALSE) { | |
56 | $docLink = CRM_Utils_System::docURL2("user/case-management/setup"); | |
57 | CRM_Core_Error::fatal(ts("Unable to load configuration file for the referenced case type: '%1' %2.", | |
58 | array(1 => $caseType, 2 => $docLink) | |
59 | )); | |
60 | return FALSE; | |
61 | } | |
62 | ||
63 | switch ($fieldSet) { | |
64 | case 'CaseRoles': | |
65 | return $this->caseRoles($xml->CaseRoles); | |
66 | ||
67 | case 'ActivitySets': | |
68 | return $this->activitySets($xml->ActivitySets); | |
69 | ||
70 | case 'ActivityTypes': | |
71 | return $this->activityTypes($xml->ActivityTypes, FALSE, $isLabel, $maskAction); | |
72 | } | |
73 | } | |
74 | ||
75 | function process($xml, &$params) { | |
76 | $standardTimeline = CRM_Utils_Array::value('standardTimeline', $params); | |
77 | $activitySetName = CRM_Utils_Array::value('activitySetName', $params); | |
78 | $activityTypeName = CRM_Utils_Array::value('activityTypeName', $params); | |
79 | ||
80 | if ('Open Case' == CRM_Utils_Array::value('activityTypeName', $params)) { | |
81 | // create relationships for the ones that are required | |
82 | foreach ($xml->CaseRoles as $caseRoleXML) { | |
83 | foreach ($caseRoleXML->RelationshipType as $relationshipTypeXML) { | |
84 | if ((int ) $relationshipTypeXML->creator == 1) { | |
85 | if (!$this->createRelationships((string ) $relationshipTypeXML->name, | |
86 | $params | |
87 | )) { | |
88 | CRM_Core_Error::fatal(); | |
89 | return FALSE; | |
90 | } | |
91 | } | |
92 | } | |
93 | } | |
94 | } | |
95 | ||
96 | if ('Change Case Start Date' == CRM_Utils_Array::value('activityTypeName', $params)) { | |
97 | // delete all existing activities which are non-empty | |
98 | $this->deleteEmptyActivity($params); | |
99 | } | |
100 | ||
101 | foreach ($xml->ActivitySets as $activitySetsXML) { | |
102 | foreach ($activitySetsXML->ActivitySet as $activitySetXML) { | |
103 | if ($standardTimeline) { | |
104 | if ((boolean ) $activitySetXML->timeline) { | |
105 | return $this->processStandardTimeline($activitySetXML, | |
106 | $params | |
107 | ); | |
108 | } | |
109 | } | |
110 | elseif ($activitySetName) { | |
111 | $name = (string ) $activitySetXML->name; | |
112 | if ($name == $activitySetName) { | |
113 | return $this->processActivitySet($activitySetXML, | |
114 | $params | |
115 | ); | |
116 | } | |
117 | } | |
118 | } | |
119 | } | |
120 | } | |
121 | ||
122 | function processStandardTimeline($activitySetXML, &$params) { | |
123 | if ('Change Case Type' == CRM_Utils_Array::value('activityTypeName', $params)) { | |
124 | // delete all existing activities which are non-empty | |
125 | $this->deleteEmptyActivity($params); | |
126 | } | |
127 | ||
128 | foreach ($activitySetXML->ActivityTypes as $activityTypesXML) { | |
129 | foreach ($activityTypesXML as $activityTypeXML) { | |
130 | $this->createActivity($activityTypeXML, $params); | |
131 | } | |
132 | } | |
133 | } | |
134 | ||
135 | function processActivitySet($activitySetXML, &$params) { | |
136 | foreach ($activitySetXML->ActivityTypes as $activityTypesXML) { | |
137 | foreach ($activityTypesXML as $activityTypeXML) { | |
138 | $this->createActivity($activityTypeXML, $params); | |
139 | } | |
140 | } | |
141 | } | |
142 | ||
143 | function &caseRoles($caseRolesXML, $isCaseManager = FALSE) { | |
144 | $relationshipTypes = &$this->allRelationshipTypes(); | |
145 | ||
146 | $result = array(); | |
147 | foreach ($caseRolesXML as $caseRoleXML) { | |
148 | foreach ($caseRoleXML->RelationshipType as $relationshipTypeXML) { | |
149 | $relationshipTypeName = (string ) $relationshipTypeXML->name; | |
150 | $relationshipTypeID = array_search($relationshipTypeName, | |
151 | $relationshipTypes | |
152 | ); | |
153 | if ($relationshipTypeID === FALSE) { | |
154 | continue; | |
155 | } | |
156 | ||
157 | if (!$isCaseManager) { | |
158 | $result[$relationshipTypeID] = $relationshipTypeName; | |
159 | } | |
160 | elseif ($relationshipTypeXML->manager) { | |
161 | return $relationshipTypeID; | |
162 | } | |
163 | } | |
164 | } | |
165 | return $result; | |
166 | } | |
167 | ||
168 | function createRelationships($relationshipTypeName, &$params) { | |
169 | $relationshipTypes = &$this->allRelationshipTypes(); | |
170 | // get the relationship id | |
171 | $relationshipTypeID = array_search($relationshipTypeName, $relationshipTypes); | |
172 | ||
173 | if ($relationshipTypeID === FALSE) { | |
174 | $docLink = CRM_Utils_System::docURL2("user/case-management/setup"); | |
175 | CRM_Core_Error::fatal(ts('Relationship type %1, found in case configuration file, is not present in the database %2', | |
176 | array(1 => $relationshipTypeName, 2 => $docLink) | |
177 | )); | |
178 | return FALSE; | |
179 | } | |
180 | ||
181 | $client = $params['clientID']; | |
182 | if (!is_array($client)) { | |
183 | $client = array($client); | |
184 | } | |
185 | ||
186 | foreach ($client as $key => $clientId) { | |
187 | $relationshipParams = array( | |
188 | 'relationship_type_id' => $relationshipTypeID, | |
189 | 'contact_id_a' => $clientId, | |
190 | 'contact_id_b' => $params['creatorID'], | |
191 | 'is_active' => 1, | |
192 | 'case_id' => $params['caseID'], | |
193 | 'start_date' => date("Ymd"), | |
194 | ); | |
195 | ||
196 | if (!$this->createRelationship($relationshipParams)) { | |
197 | CRM_Core_Error::fatal(); | |
198 | return FALSE; | |
199 | } | |
200 | } | |
201 | return TRUE; | |
202 | } | |
203 | ||
204 | function createRelationship(&$params) { | |
205 | $dao = new CRM_Contact_DAO_Relationship(); | |
206 | $dao->copyValues($params); | |
207 | // only create a relationship if it does not exist | |
208 | if (!$dao->find(TRUE)) { | |
209 | $dao->save(); | |
210 | } | |
211 | return TRUE; | |
212 | } | |
213 | ||
214 | function activityTypes($activityTypesXML, $maxInst = FALSE, $isLabel = FALSE, $maskAction = FALSE) { | |
215 | $activityTypes = &$this->allActivityTypes(TRUE, TRUE); | |
216 | $result = array(); | |
217 | foreach ($activityTypesXML as $activityTypeXML) { | |
218 | foreach ($activityTypeXML as $recordXML) { | |
219 | $activityTypeName = (string ) $recordXML->name; | |
220 | $maxInstances = (string ) $recordXML->max_instances; | |
221 | $activityTypeInfo = CRM_Utils_Array::value($activityTypeName, $activityTypes); | |
222 | ||
223 | if ($activityTypeInfo['id']) { | |
224 | if ($maskAction) { | |
225 | if ($maskAction == 'edit' && '0' === (string ) $recordXML->editable) { | |
226 | $result[$maskAction][] = $activityTypeInfo['id']; | |
227 | } | |
228 | } | |
229 | else { | |
230 | if (!$maxInst) { | |
231 | //if we want,labels of activities should be returned. | |
232 | if ($isLabel) { | |
233 | $result[$activityTypeInfo['id']] = $activityTypeInfo['label']; | |
234 | } | |
235 | else { | |
236 | $result[$activityTypeInfo['id']] = $activityTypeName; | |
237 | } | |
238 | } | |
239 | else { | |
240 | if ($maxInstances) { | |
241 | $result[$activityTypeName] = $maxInstances; | |
242 | } | |
243 | } | |
244 | } | |
245 | } | |
246 | } | |
247 | } | |
248 | ||
249 | // call option value hook | |
250 | CRM_Utils_Hook::optionValues($result, 'case_activity_type'); | |
251 | ||
252 | return $result; | |
253 | } | |
254 | ||
255 | function deleteEmptyActivity(&$params) { | |
9e74e3ce | 256 | $activityContacts = CRM_Core_PseudoConstant::activityContacts('name'); |
257 | $targetID = CRM_Utils_Array::key('Activity Targets', $activityContacts); | |
258 | ||
6a488035 TO |
259 | $query = " |
260 | DELETE a | |
261 | FROM civicrm_activity a | |
91da6cd5 DL |
262 | INNER JOIN civicrm_activity_contact t ON t.activity_id = a.id |
263 | WHERE t.contact_id = %1 | |
9e74e3ce | 264 | AND t.record_type_id = $targetID |
6a488035 TO |
265 | AND a.is_auto = 1 |
266 | AND a.is_current_revision = 1 | |
267 | "; | |
268 | $sqlParams = array(1 => array($params['clientID'], 'Integer')); | |
269 | CRM_Core_DAO::executeQuery($query, $sqlParams); | |
270 | } | |
271 | ||
272 | function isActivityPresent(&$params) { | |
273 | $query = " | |
274 | SELECT count(a.id) | |
275 | FROM civicrm_activity a | |
276 | INNER JOIN civicrm_case_activity ca on ca.activity_id = a.id | |
277 | WHERE a.activity_type_id = %1 | |
278 | AND ca.case_id = %2 | |
279 | AND a.is_deleted = 0 | |
280 | "; | |
281 | ||
282 | $sqlParams = array(1 => array($params['activityTypeID'], 'Integer'), | |
283 | 2 => array($params['caseID'], 'Integer'), | |
284 | ); | |
285 | $count = CRM_Core_DAO::singleValueQuery($query, $sqlParams); | |
286 | ||
287 | // check for max instance | |
288 | $caseType = CRM_Case_BAO_Case::getCaseType($params['caseID'], 'name'); | |
289 | $maxInstance = self::getMaxInstance($caseType, $params['activityTypeName']); | |
290 | ||
291 | return $maxInstance ? ($count < $maxInstance ? FALSE : TRUE) : FALSE; | |
292 | } | |
293 | ||
294 | function createActivity($activityTypeXML, &$params) { | |
295 | $activityTypeName = (string) $activityTypeXML->name; | |
296 | $activityTypes = &$this->allActivityTypes(TRUE, TRUE); | |
297 | $activityTypeInfo = CRM_Utils_Array::value($activityTypeName, $activityTypes); | |
298 | ||
299 | if (!$activityTypeInfo) { | |
300 | $docLink = CRM_Utils_System::docURL2("user/case-management/setup"); | |
301 | CRM_Core_Error::fatal(ts('Activity type %1, found in case configuration file, is not present in the database %2', | |
302 | array(1 => $activityTypeName, 2 => $docLink) | |
303 | )); | |
304 | return FALSE; | |
305 | } | |
306 | ||
307 | $activityTypeID = $activityTypeInfo['id']; | |
308 | ||
309 | if (isset($activityTypeXML->status)) { | |
310 | $statusName = (string) $activityTypeXML->status; | |
311 | } | |
312 | else { | |
313 | $statusName = 'Scheduled'; | |
314 | } | |
315 | ||
316 | if ($this->_isMultiClient) { | |
317 | $client = $params['clientID']; | |
318 | } | |
319 | else { | |
320 | $client = array(1 => $params['clientID']); | |
321 | } | |
322 | ||
323 | //set order | |
324 | $orderVal = ''; | |
325 | if (isset($activityTypeXML->order)) { | |
326 | $orderVal = (string) $activityTypeXML->order; | |
327 | } | |
328 | ||
329 | if ($activityTypeName == 'Open Case') { | |
330 | $activityParams = array( | |
331 | 'activity_type_id' => $activityTypeID, | |
332 | 'source_contact_id' => $params['creatorID'], | |
333 | 'is_auto' => FALSE, | |
334 | 'is_current_revision' => 1, | |
335 | 'subject' => CRM_Utils_Array::value('subject', $params) ? $params['subject'] : $activityTypeName, | |
336 | 'status_id' => CRM_Core_OptionGroup::getValue('activity_status', | |
337 | $statusName, | |
338 | 'name' | |
339 | ), | |
340 | 'target_contact_id' => $client, | |
341 | 'medium_id' => CRM_Utils_Array::value('medium_id', $params), | |
342 | 'location' => CRM_Utils_Array::value('location', $params), | |
343 | 'details' => CRM_Utils_Array::value('details', $params), | |
344 | 'duration' => CRM_Utils_Array::value('duration', $params), | |
345 | 'weight' => $orderVal, | |
346 | ); | |
347 | } | |
348 | else { | |
349 | $activityParams = array( | |
350 | 'activity_type_id' => $activityTypeID, | |
351 | 'source_contact_id' => $params['creatorID'], | |
352 | 'is_auto' => TRUE, | |
353 | 'is_current_revision' => 1, | |
354 | 'status_id' => CRM_Core_OptionGroup::getValue('activity_status', | |
355 | $statusName, | |
356 | 'name' | |
357 | ), | |
358 | 'target_contact_id' => $client, | |
359 | 'weight' => $orderVal, | |
360 | ); | |
361 | } | |
362 | ||
363 | //parsing date to default preference format | |
364 | $params['activity_date_time'] = CRM_Utils_Date::processDate($params['activity_date_time']); | |
365 | ||
366 | if ($activityTypeName == 'Open Case') { | |
367 | // we don't set activity_date_time for auto generated | |
368 | // activities, but we want it to be set for open case. | |
369 | $activityParams['activity_date_time'] = $params['activity_date_time']; | |
370 | if (array_key_exists('custom', $params) && is_array($params['custom'])) { | |
371 | $activityParams['custom'] = $params['custom']; | |
372 | } | |
373 | ||
374 | // Add parameters for attachments | |
375 | ||
376 | $numAttachments = CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME, 'max_attachments'); | |
377 | for ( $i = 1; $i <= $numAttachments; $i++ ) { | |
378 | $attachName = "attachFile_$i"; | |
379 | if ( isset( $params[$attachName] ) && !empty( $params[$attachName] ) ) { | |
380 | $activityParams[$attachName] = $params[$attachName]; | |
381 | } | |
382 | } | |
383 | } | |
384 | else { | |
385 | $activityDate = NULL; | |
386 | //get date of reference activity if set. | |
387 | if ($referenceActivityName = (string) $activityTypeXML->reference_activity) { | |
388 | ||
389 | //we skip open case as reference activity.CRM-4374. | |
390 | if (CRM_Utils_Array::value('resetTimeline', $params) && $referenceActivityName == 'Open Case') { | |
391 | $activityDate = $params['activity_date_time']; | |
392 | } | |
393 | else { | |
394 | $referenceActivityInfo = CRM_Utils_Array::value($referenceActivityName, $activityTypes); | |
395 | if ($referenceActivityInfo['id']) { | |
396 | $caseActivityParams = array('activity_type_id' => $referenceActivityInfo['id']); | |
397 | ||
398 | //if reference_select is set take according activity. | |
399 | if ($referenceSelect = (string) $activityTypeXML->reference_select) { | |
400 | $caseActivityParams[$referenceSelect] = 1; | |
401 | } | |
402 | ||
403 | $referenceActivity = CRM_Case_BAO_Case::getCaseActivityDates($params['caseID'], $caseActivityParams, TRUE); | |
404 | ||
405 | if (is_array($referenceActivity)) { | |
406 | foreach ($referenceActivity as $aId => $details) { | |
407 | $activityDate = CRM_Utils_Array::value('activity_date', $details); | |
408 | break; | |
409 | } | |
410 | } | |
411 | } | |
412 | } | |
413 | } | |
414 | if (!$activityDate) { | |
415 | $activityDate = $params['activity_date_time']; | |
416 | } | |
417 | list($activity_date, $activity_time) = CRM_Utils_Date::setDateDefaults($activityDate); | |
418 | $activityDateTime = CRM_Utils_Date::processDate($activity_date, $activity_time); | |
419 | //add reference offset to date. | |
420 | if ((int) $activityTypeXML->reference_offset) { | |
421 | $activityDateTime = CRM_Utils_Date::intervalAdd('day', (int) $activityTypeXML->reference_offset, | |
422 | $activityDateTime | |
423 | ); | |
424 | } | |
425 | ||
426 | $activityParams['activity_date_time'] = CRM_Utils_Date::format($activityDateTime); | |
427 | } | |
428 | ||
429 | // if same activity is already there, skip and dont touch | |
430 | $params['activityTypeID'] = $activityTypeID; | |
431 | $params['activityTypeName'] = $activityTypeName; | |
432 | if ($this->isActivityPresent($params)) { | |
433 | return TRUE; | |
434 | } | |
435 | $activityParams['case_id'] = $params['caseID']; | |
436 | if (CRM_Utils_Array::value('is_auto', $activityParams)) { | |
437 | $activityParams['skipRecentView'] = TRUE; | |
438 | } | |
439 | ||
440 | $activity = CRM_Activity_BAO_Activity::create($activityParams); | |
441 | ||
442 | if (!$activity) { | |
443 | CRM_Core_Error::fatal(); | |
444 | return FALSE; | |
445 | } | |
446 | ||
447 | // create case activity record | |
448 | $caseParams = array( | |
449 | 'activity_id' => $activity->id, | |
450 | 'case_id' => $params['caseID'], | |
451 | ); | |
452 | CRM_Case_BAO_Case::processCaseActivity($caseParams); | |
453 | return TRUE; | |
454 | } | |
455 | ||
456 | function activitySets($activitySetsXML) { | |
457 | $result = array(); | |
458 | foreach ($activitySetsXML as $activitySetXML) { | |
459 | foreach ($activitySetXML as $recordXML) { | |
460 | $activitySetName = (string ) $recordXML->name; | |
461 | $activitySetLabel = (string ) $recordXML->label; | |
462 | $result[$activitySetName] = $activitySetLabel; | |
463 | } | |
464 | } | |
465 | ||
466 | return $result; | |
467 | } | |
468 | ||
469 | function getMaxInstance($caseType, $activityTypeName = NULL) { | |
470 | $xml = $this->retrieve($caseType); | |
471 | ||
472 | if ($xml === FALSE) { | |
473 | CRM_Core_Error::fatal(); | |
474 | return FALSE; | |
475 | } | |
476 | ||
477 | $activityInstances = $this->activityTypes($xml->ActivityTypes, TRUE); | |
478 | return $activityTypeName ? CRM_Utils_Array::value($activityTypeName, $activityInstances) : $activityInstances; | |
479 | } | |
480 | ||
481 | function getCaseManagerRoleId($caseType) { | |
482 | $xml = $this->retrieve($caseType); | |
483 | return $this->caseRoles($xml->CaseRoles, TRUE); | |
484 | } | |
485 | ||
486 | function getRedactActivityEmail() { | |
487 | $xml = $this->retrieve("Settings"); | |
488 | return ( string ) $xml->RedactActivityEmail ? 1 : 0; | |
489 | } | |
490 | ||
491 | /** | |
492 | * Retrieves AllowMultipleCaseClients setting | |
493 | * | |
494 | * @return string 1 if allowed, 0 if not | |
495 | */ | |
496 | function getAllowMultipleCaseClients() { | |
497 | $xml = $this->retrieve("Settings"); | |
498 | if ($xml) { | |
499 | return ( string ) $xml->AllowMultipleCaseClients ? 1 : 0; | |
500 | } | |
501 | return 0; | |
502 | } | |
503 | ||
504 | /** | |
505 | * Retrieves NaturalActivityTypeSort setting | |
506 | * | |
507 | * @return string 1 if natural, 0 if alphabetic | |
508 | */ | |
509 | function getNaturalActivityTypeSort() { | |
510 | $xml = $this->retrieve("Settings"); | |
511 | return ( string ) $xml->NaturalActivityTypeSort ? 1 : 0; | |
512 | } | |
513 | } | |
514 |