Merge pull request #15307 from seamuslee001/dev_core_1249
[civicrm-core.git] / Civi / CCase / Analyzer.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
5 | |
6 | This work is published under the GNU AGPLv3 license with some |
7 | permitted exceptions and without any warranty. For full license |
8 | and copyright information, see https://civicrm.org/licensing |
9 +--------------------------------------------------------------------+
10 */
11 namespace Civi\CCase;
12
13 /**
14 * Class Analyzer
15 *
16 * @package Civi\CCase
17 */
18 class Analyzer {
19 /**
20 * @var int
21 */
22 private $caseId;
23
24 /**
25 * @var array per APIv3
26 */
27 private $case;
28
29 /**
30 * @var string
31 */
32 private $caseType;
33
34 /**
35 * @var array per APIv3
36 */
37 private $activities;
38
39 /**
40 * @var \SimpleXMLElement
41 */
42 private $xml;
43
44 /**
45 * @var array<string,array>
46 */
47 private $indices;
48
49 /**
50 * @param $caseId
51 */
52 public function __construct($caseId) {
53 $this->caseId = $caseId;
54 $this->flush();
55 }
56
57 /**
58 * Determine if case includes an activity of given type/status
59 *
60 * @param string $type
61 * Eg "Phone Call", "Interview Prospect", "Background Check".
62 * @param string $status
63 * Eg "Scheduled", "Completed".
64 * @return bool
65 */
66 public function hasActivity($type, $status = NULL) {
67 $idx = $this->getActivityIndex(['activity_type_id', 'status_id']);
68 $activityTypeGroup = civicrm_api3('option_group', 'get', ['name' => 'activity_type']);
69 $activityType = [
70 'name' => $type,
71 'option_group_id' => $activityTypeGroup['id'],
72 ];
73 $activityTypeID = civicrm_api3('option_value', 'get', $activityType);
74 $activityTypeID = $activityTypeID['values'][$activityTypeID['id']]['value'];
75 if ($status) {
76 $activityStatusGroup = civicrm_api3('option_group', 'get', ['name' => 'activity_status']);
77 $activityStatus = [
78 'name' => $status,
79 'option_group_id' => $activityStatusGroup['id'],
80 ];
81 $activityStatusID = civicrm_api3('option_value', 'get', $activityStatus);
82 $activityStatusID = $activityStatusID['values'][$activityStatusID['id']]['value'];
83 }
84 if ($status === NULL) {
85 return !empty($idx[$activityTypeID]);
86 }
87 else {
88 return !empty($idx[$activityTypeID][$activityStatusID]);
89 }
90 }
91
92 /**
93 * Get a list of all activities in the case.
94 *
95 * @return array
96 * list of activity records (api/v3 format)
97 */
98 public function getActivities() {
99 if ($this->activities === NULL) {
100 // TODO find batch-oriented API for getting all activities in a case
101 $case = $this->getCase();
102 $activities = [];
103 if (isset($case['activities'])) {
104 foreach ($case['activities'] as $actId) {
105 $result = civicrm_api3('Activity', 'get', [
106 'id' => $actId,
107 'is_current_revision' => 1,
108 ]);
109 $activities = array_merge($activities, $result['values']);
110 }
111 }
112 $this->activities = $activities;
113 }
114 return $this->activities;
115 }
116
117 /**
118 * Get a single activity record by type.
119 * This function is only used by SequenceListenerTest
120 *
121 * @param string $type
122 * @throws \Civi\CCase\Exception\MultipleActivityException
123 * @return array|NULL, activity record (api/v3)
124 */
125 public function getSingleActivity($type) {
126 $idx = $this->getActivityIndex(['activity_type_id', 'id']);
127 $actTypes = array_flip(\CRM_Activity_BAO_Activity::buildOptions('activity_type_id', 'validate'));
128 $typeId = $actTypes[$type];
129 $count = isset($idx[$typeId]) ? count($idx[$typeId]) : 0;
130
131 if ($count === 0) {
132 return NULL;
133 }
134 elseif ($count === 1) {
135 foreach ($idx[$typeId] as $item) {
136 return $item;
137 }
138 }
139 else {
140 throw new \Civi\CCase\Exception\MultipleActivityException("Wrong quantity of [$type] records. Expected 1 but found " . $count);
141 }
142 }
143
144 /**
145 * @return int
146 */
147 public function getCaseId() {
148 return $this->caseId;
149 }
150
151 /**
152 * @return array, Case record (api/v3 format)
153 */
154 public function getCase() {
155 if ($this->case === NULL) {
156 $this->case = civicrm_api3('case', 'getsingle', ['id' => $this->caseId]);
157 }
158 return $this->case;
159 }
160
161 /**
162 * @return string
163 * @throws \CRM_Core_Exception
164 */
165 public function getCaseType() {
166 if ($this->caseType === NULL) {
167 $case = $this->getCase();
168 $caseTypes = \CRM_Case_XMLRepository::singleton()->getAllCaseTypes();
169 if (!isset($caseTypes[$case['case_type_id']])) {
170 throw new \CRM_Core_Exception("Case does not have a recognized case-type!");
171 }
172 $this->caseType = $caseTypes[$case['case_type_id']];
173 }
174 return $this->caseType;
175 }
176
177 /**
178 * Get a list of all activities in the case (indexed by some property/properties)
179 *
180 * @param array $keys
181 * List of properties by which to index activities.
182 * @return array
183 * list of activity records (api/v3 format), indexed by $keys
184 */
185 public function getActivityIndex($keys) {
186 $key = implode(";", $keys);
187 if (!isset($this->indices[$key])) {
188 $this->indices[$key] = \CRM_Utils_Array::index($keys, $this->getActivities());
189 }
190 return $this->indices[$key];
191 }
192
193 /**
194 * @return \SimpleXMLElement|NULL
195 */
196 public function getXml() {
197 if ($this->xml === NULL) {
198 $this->xml = \CRM_Case_XMLRepository::singleton()->retrieve($this->getCaseType());
199 }
200 return $this->xml;
201 }
202
203 /**
204 * Flush any cached information.
205 */
206 public function flush() {
207 $this->case = NULL;
208 $this->caseType = NULL;
209 $this->activities = NULL;
210 $this->indices = [];
211 }
212
213 }