[NFC] Fix tests in prepartion for phpunit7
[civicrm-core.git] / Civi / CCase / SequenceListener.php
CommitLineData
b019b130
TO
1<?php
2namespace Civi\CCase;
3
4/**
5 * The sequence-listener looks for CiviCase XML tags with "<sequence>". If
6 * a change is made to any record in case-type which uses "<sequence>", then
7 * it attempts to add the next step in the sequence.
8 */
9class SequenceListener implements CaseChangeListener {
10
11 /**
12 * @var SequenceListener
13 */
14 private static $singleton;
15
16 /**
04855556
TO
17 * @param bool $reset
18 * Whether to forcibly rebuild the entire container.
45322593 19 * @return SequenceListener
b019b130
TO
20 */
21 public static function singleton($reset = FALSE) {
22 if ($reset || self::$singleton === NULL) {
23 self::$singleton = new SequenceListener();
24 }
25 return self::$singleton;
26 }
27
7fe37828
EM
28 /**
29 * @param \Civi\CCase\Event\CaseChangeEvent $event
30 */
b019b130
TO
31 public static function onCaseChange_static(\Civi\CCase\Event\CaseChangeEvent $event) {
32 self::singleton()->onCaseChange($event);
33 }
34
7fe37828 35 /**
5f7f8810
JP
36 * Triggers next case activity in sequence if current activity status is updated
37 * to type=COMPLETED(See CRM-21598). The adjoining activity is created according
38 * to the sequence configured in case type.
39 *
7fe37828
EM
40 * @param \Civi\CCase\Event\CaseChangeEvent $event
41 *
42 * @throws \CiviCRM_API3_Exception
45322593 43 * @return void
7fe37828 44 */
b019b130
TO
45 public function onCaseChange(\Civi\CCase\Event\CaseChangeEvent $event) {
46 /** @var \Civi\CCase\Analyzer $analyzer */
47 $analyzer = $event->analyzer;
48
b019b130
TO
49 $activitySetXML = $this->getSequenceXml($analyzer->getXml());
50 if (!$activitySetXML) {
51 return;
52 }
53
b864360d 54 $actTypes = array_flip(\CRM_Activity_BAO_Activity::buildOptions('activity_type_id', 'validate'));
de33391d 55 $actStatuses = array_flip(\CRM_Activity_BAO_Activity::getStatusesByType(\CRM_Activity_BAO_Activity::COMPLETED));
b019b130 56
c64f69d9 57 $actIndex = $analyzer->getActivityIndex(['activity_type_id', 'status_id']);
b019b130
TO
58
59 foreach ($activitySetXML->ActivityTypes->ActivityType as $actTypeXML) {
60 $actTypeId = $actTypes[(string) $actTypeXML->name];
61 if (empty($actIndex[$actTypeId])) {
62 // Haven't tried this step yet!
63 $this->createActivity($analyzer, $actTypeXML);
b019b130
TO
64 return;
65 }
de33391d 66 elseif (!in_array(key($actIndex[$actTypeId]), $actStatuses)) {
b019b130 67 // Haven't gotten past this step yet!
b019b130
TO
68 return;
69 }
70 }
71
674829bf
DA
72 //CRM-17452 - Close the case only if all the activities are complete
73 $activities = $analyzer->getActivities();
74 foreach ($activities as $activity) {
de33391d 75 if (!in_array($activity['status_id'], $actStatuses)) {
674829bf
DA
76 return;
77 }
78 }
79
80 // OK, the all activities have completed
c64f69d9 81 civicrm_api3('Case', 'create', [
46bcf597 82 'id' => $analyzer->getCaseId(),
b019b130 83 'status_id' => 'Closed',
c64f69d9 84 ]);
b019b130 85 $analyzer->flush();
b019b130
TO
86 }
87
88 /**
89 * Find the ActivitySet which defines the pipeline.
90 *
91 * @param \SimpleXMLElement $xml
92 * @return \SimpleXMLElement|NULL
93 */
94 public function getSequenceXml($xml) {
95 if ($xml->ActivitySets && $xml->ActivitySets->ActivitySet) {
96 foreach ($xml->ActivitySets->ActivitySet as $activitySetXML) {
97 $seq = (string) $activitySetXML->sequence;
98 if ($seq && strtolower($seq) == 'true') {
99 if ($activitySetXML->ActivityTypes && $activitySetXML->ActivityTypes->ActivityType) {
100 return $activitySetXML;
101 }
102 else {
103 return NULL;
104 }
105 }
106 }
107 }
108 return NULL;
109 }
110
111 /**
04855556
TO
112 * @param Analyzer $analyzer
113 * The case being analyzed -- to which we want to add an activity.
b019b130
TO
114 * @param \SimpleXMLElement $actXML the <ActivityType> tag which describes the new activity
115 */
116 public function createActivity(Analyzer $analyzer, \SimpleXMLElement $actXML) {
c64f69d9 117 $params = [
b019b130
TO
118 'activity_type_id' => (string) $actXML->name,
119 'status_id' => 'Scheduled',
120 'activity_date_time' => \CRM_Utils_Time::getTime('YmdHis'),
121 'case_id' => $analyzer->getCaseId(),
c64f69d9 122 ];
c90ec5ab
MWMC
123 $case = $analyzer->getCase();
124 if (!empty($case['contact_id'])) {
125 $params['target_id'] = \CRM_Utils_Array::first($case['contact_id']);
126 }
127
128 civicrm_api3('Activity', 'create', $params);
b019b130
TO
129 $analyzer->flush();
130 }
96025800 131
ef10e0b5 132}