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) { | |
256 | $query = " | |
257 | DELETE a | |
258 | FROM civicrm_activity a | |
259 | INNER JOIN civicrm_activity_target t ON t.activity_id = a.id | |
260 | WHERE t.target_contact_id = %1 | |
261 | AND a.is_auto = 1 | |
262 | AND a.is_current_revision = 1 | |
263 | "; | |
264 | $sqlParams = array(1 => array($params['clientID'], 'Integer')); | |
265 | CRM_Core_DAO::executeQuery($query, $sqlParams); | |
266 | } | |
267 | ||
268 | function isActivityPresent(&$params) { | |
269 | $query = " | |
270 | SELECT count(a.id) | |
271 | FROM civicrm_activity a | |
272 | INNER JOIN civicrm_case_activity ca on ca.activity_id = a.id | |
273 | WHERE a.activity_type_id = %1 | |
274 | AND ca.case_id = %2 | |
275 | AND a.is_deleted = 0 | |
276 | "; | |
277 | ||
278 | $sqlParams = array(1 => array($params['activityTypeID'], 'Integer'), | |
279 | 2 => array($params['caseID'], 'Integer'), | |
280 | ); | |
281 | $count = CRM_Core_DAO::singleValueQuery($query, $sqlParams); | |
282 | ||
283 | // check for max instance | |
284 | $caseType = CRM_Case_BAO_Case::getCaseType($params['caseID'], 'name'); | |
285 | $maxInstance = self::getMaxInstance($caseType, $params['activityTypeName']); | |
286 | ||
287 | return $maxInstance ? ($count < $maxInstance ? FALSE : TRUE) : FALSE; | |
288 | } | |
289 | ||
290 | function createActivity($activityTypeXML, &$params) { | |
291 | $activityTypeName = (string) $activityTypeXML->name; | |
292 | $activityTypes = &$this->allActivityTypes(TRUE, TRUE); | |
293 | $activityTypeInfo = CRM_Utils_Array::value($activityTypeName, $activityTypes); | |
294 | ||
295 | if (!$activityTypeInfo) { | |
296 | $docLink = CRM_Utils_System::docURL2("user/case-management/setup"); | |
297 | CRM_Core_Error::fatal(ts('Activity type %1, found in case configuration file, is not present in the database %2', | |
298 | array(1 => $activityTypeName, 2 => $docLink) | |
299 | )); | |
300 | return FALSE; | |
301 | } | |
302 | ||
303 | $activityTypeID = $activityTypeInfo['id']; | |
304 | ||
305 | if (isset($activityTypeXML->status)) { | |
306 | $statusName = (string) $activityTypeXML->status; | |
307 | } | |
308 | else { | |
309 | $statusName = 'Scheduled'; | |
310 | } | |
311 | ||
312 | if ($this->_isMultiClient) { | |
313 | $client = $params['clientID']; | |
314 | } | |
315 | else { | |
316 | $client = array(1 => $params['clientID']); | |
317 | } | |
318 | ||
319 | //set order | |
320 | $orderVal = ''; | |
321 | if (isset($activityTypeXML->order)) { | |
322 | $orderVal = (string) $activityTypeXML->order; | |
323 | } | |
324 | ||
325 | if ($activityTypeName == 'Open Case') { | |
326 | $activityParams = array( | |
327 | 'activity_type_id' => $activityTypeID, | |
328 | 'source_contact_id' => $params['creatorID'], | |
329 | 'is_auto' => FALSE, | |
330 | 'is_current_revision' => 1, | |
331 | 'subject' => CRM_Utils_Array::value('subject', $params) ? $params['subject'] : $activityTypeName, | |
332 | 'status_id' => CRM_Core_OptionGroup::getValue('activity_status', | |
333 | $statusName, | |
334 | 'name' | |
335 | ), | |
336 | 'target_contact_id' => $client, | |
337 | 'medium_id' => CRM_Utils_Array::value('medium_id', $params), | |
338 | 'location' => CRM_Utils_Array::value('location', $params), | |
339 | 'details' => CRM_Utils_Array::value('details', $params), | |
340 | 'duration' => CRM_Utils_Array::value('duration', $params), | |
341 | 'weight' => $orderVal, | |
342 | ); | |
343 | } | |
344 | else { | |
345 | $activityParams = array( | |
346 | 'activity_type_id' => $activityTypeID, | |
347 | 'source_contact_id' => $params['creatorID'], | |
348 | 'is_auto' => TRUE, | |
349 | 'is_current_revision' => 1, | |
350 | 'status_id' => CRM_Core_OptionGroup::getValue('activity_status', | |
351 | $statusName, | |
352 | 'name' | |
353 | ), | |
354 | 'target_contact_id' => $client, | |
355 | 'weight' => $orderVal, | |
356 | ); | |
357 | } | |
358 | ||
359 | //parsing date to default preference format | |
360 | $params['activity_date_time'] = CRM_Utils_Date::processDate($params['activity_date_time']); | |
361 | ||
362 | if ($activityTypeName == 'Open Case') { | |
363 | // we don't set activity_date_time for auto generated | |
364 | // activities, but we want it to be set for open case. | |
365 | $activityParams['activity_date_time'] = $params['activity_date_time']; | |
366 | if (array_key_exists('custom', $params) && is_array($params['custom'])) { | |
367 | $activityParams['custom'] = $params['custom']; | |
368 | } | |
369 | ||
370 | // Add parameters for attachments | |
371 | ||
372 | $numAttachments = CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME, 'max_attachments'); | |
373 | for ( $i = 1; $i <= $numAttachments; $i++ ) { | |
374 | $attachName = "attachFile_$i"; | |
375 | if ( isset( $params[$attachName] ) && !empty( $params[$attachName] ) ) { | |
376 | $activityParams[$attachName] = $params[$attachName]; | |
377 | } | |
378 | } | |
379 | } | |
380 | else { | |
381 | $activityDate = NULL; | |
382 | //get date of reference activity if set. | |
383 | if ($referenceActivityName = (string) $activityTypeXML->reference_activity) { | |
384 | ||
385 | //we skip open case as reference activity.CRM-4374. | |
386 | if (CRM_Utils_Array::value('resetTimeline', $params) && $referenceActivityName == 'Open Case') { | |
387 | $activityDate = $params['activity_date_time']; | |
388 | } | |
389 | else { | |
390 | $referenceActivityInfo = CRM_Utils_Array::value($referenceActivityName, $activityTypes); | |
391 | if ($referenceActivityInfo['id']) { | |
392 | $caseActivityParams = array('activity_type_id' => $referenceActivityInfo['id']); | |
393 | ||
394 | //if reference_select is set take according activity. | |
395 | if ($referenceSelect = (string) $activityTypeXML->reference_select) { | |
396 | $caseActivityParams[$referenceSelect] = 1; | |
397 | } | |
398 | ||
399 | $referenceActivity = CRM_Case_BAO_Case::getCaseActivityDates($params['caseID'], $caseActivityParams, TRUE); | |
400 | ||
401 | if (is_array($referenceActivity)) { | |
402 | foreach ($referenceActivity as $aId => $details) { | |
403 | $activityDate = CRM_Utils_Array::value('activity_date', $details); | |
404 | break; | |
405 | } | |
406 | } | |
407 | } | |
408 | } | |
409 | } | |
410 | if (!$activityDate) { | |
411 | $activityDate = $params['activity_date_time']; | |
412 | } | |
413 | list($activity_date, $activity_time) = CRM_Utils_Date::setDateDefaults($activityDate); | |
414 | $activityDateTime = CRM_Utils_Date::processDate($activity_date, $activity_time); | |
415 | //add reference offset to date. | |
416 | if ((int) $activityTypeXML->reference_offset) { | |
417 | $activityDateTime = CRM_Utils_Date::intervalAdd('day', (int) $activityTypeXML->reference_offset, | |
418 | $activityDateTime | |
419 | ); | |
420 | } | |
421 | ||
422 | $activityParams['activity_date_time'] = CRM_Utils_Date::format($activityDateTime); | |
423 | } | |
424 | ||
425 | // if same activity is already there, skip and dont touch | |
426 | $params['activityTypeID'] = $activityTypeID; | |
427 | $params['activityTypeName'] = $activityTypeName; | |
428 | if ($this->isActivityPresent($params)) { | |
429 | return TRUE; | |
430 | } | |
431 | $activityParams['case_id'] = $params['caseID']; | |
432 | if (CRM_Utils_Array::value('is_auto', $activityParams)) { | |
433 | $activityParams['skipRecentView'] = TRUE; | |
434 | } | |
435 | ||
436 | $activity = CRM_Activity_BAO_Activity::create($activityParams); | |
437 | ||
438 | if (!$activity) { | |
439 | CRM_Core_Error::fatal(); | |
440 | return FALSE; | |
441 | } | |
442 | ||
443 | // create case activity record | |
444 | $caseParams = array( | |
445 | 'activity_id' => $activity->id, | |
446 | 'case_id' => $params['caseID'], | |
447 | ); | |
448 | CRM_Case_BAO_Case::processCaseActivity($caseParams); | |
449 | return TRUE; | |
450 | } | |
451 | ||
452 | function activitySets($activitySetsXML) { | |
453 | $result = array(); | |
454 | foreach ($activitySetsXML as $activitySetXML) { | |
455 | foreach ($activitySetXML as $recordXML) { | |
456 | $activitySetName = (string ) $recordXML->name; | |
457 | $activitySetLabel = (string ) $recordXML->label; | |
458 | $result[$activitySetName] = $activitySetLabel; | |
459 | } | |
460 | } | |
461 | ||
462 | return $result; | |
463 | } | |
464 | ||
465 | function getMaxInstance($caseType, $activityTypeName = NULL) { | |
466 | $xml = $this->retrieve($caseType); | |
467 | ||
468 | if ($xml === FALSE) { | |
469 | CRM_Core_Error::fatal(); | |
470 | return FALSE; | |
471 | } | |
472 | ||
473 | $activityInstances = $this->activityTypes($xml->ActivityTypes, TRUE); | |
474 | return $activityTypeName ? CRM_Utils_Array::value($activityTypeName, $activityInstances) : $activityInstances; | |
475 | } | |
476 | ||
477 | function getCaseManagerRoleId($caseType) { | |
478 | $xml = $this->retrieve($caseType); | |
479 | return $this->caseRoles($xml->CaseRoles, TRUE); | |
480 | } | |
481 | ||
482 | function getRedactActivityEmail() { | |
483 | $xml = $this->retrieve("Settings"); | |
484 | return ( string ) $xml->RedactActivityEmail ? 1 : 0; | |
485 | } | |
486 | ||
487 | /** | |
488 | * Retrieves AllowMultipleCaseClients setting | |
489 | * | |
490 | * @return string 1 if allowed, 0 if not | |
491 | */ | |
492 | function getAllowMultipleCaseClients() { | |
493 | $xml = $this->retrieve("Settings"); | |
494 | if ($xml) { | |
495 | return ( string ) $xml->AllowMultipleCaseClients ? 1 : 0; | |
496 | } | |
497 | return 0; | |
498 | } | |
499 | ||
500 | /** | |
501 | * Retrieves NaturalActivityTypeSort setting | |
502 | * | |
503 | * @return string 1 if natural, 0 if alphabetic | |
504 | */ | |
505 | function getNaturalActivityTypeSort() { | |
506 | $xml = $this->retrieve("Settings"); | |
507 | return ( string ) $xml->NaturalActivityTypeSort ? 1 : 0; | |
508 | } | |
509 | } | |
510 |