Commit | Line | Data |
---|---|---|
2aa3d7ab TO |
1 | <?php |
2 | /* | |
3 | +--------------------------------------------------------------------+ | |
bc77d7c0 | 4 | | Copyright CiviCRM LLC. All rights reserved. | |
2aa3d7ab | 5 | | | |
bc77d7c0 TO |
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 | | |
2aa3d7ab | 9 | +--------------------------------------------------------------------+ |
d25dd0ee | 10 | */ |
2aa3d7ab TO |
11 | |
12 | /** | |
13 | * | |
14 | * @package CRM | |
ca5cec67 | 15 | * @copyright CiviCRM LLC https://civicrm.org/licensing |
2aa3d7ab | 16 | */ |
3a0d0bbd | 17 | class CRM_Utils_Check_Component_Case extends CRM_Utils_Check_Component { |
2aa3d7ab | 18 | |
c7006a4b TO |
19 | const DOCTOR_WHEN = 'https://github.com/civicrm/org.civicrm.doctorwhen'; |
20 | ||
2aa3d7ab TO |
21 | /** |
22 | * @var CRM_Case_XMLRepository | |
23 | */ | |
24 | protected $xmlRepo; | |
25 | ||
26 | /** | |
51dda21e | 27 | * @var string[] |
2aa3d7ab TO |
28 | */ |
29 | protected $caseTypeNames; | |
30 | ||
31 | /** | |
d631cdc8 | 32 | * Class constructor. |
2aa3d7ab | 33 | */ |
3a0d0bbd CW |
34 | public function __construct() { |
35 | $this->caseTypeNames = CRM_Case_PseudoConstant::caseType('name'); | |
36 | $this->xmlRepo = CRM_Case_XMLRepository::singleton(); | |
2aa3d7ab TO |
37 | } |
38 | ||
39 | /** | |
3a0d0bbd | 40 | * @inheritDoc |
2aa3d7ab | 41 | */ |
3a0d0bbd CW |
42 | public function isEnabled() { |
43 | return CRM_Case_BAO_Case::enabled(); | |
2aa3d7ab TO |
44 | } |
45 | ||
46 | /** | |
47 | * Check that the case-type names don't rely on double-munging. | |
48 | * | |
02b3ba91 | 49 | * @return CRM_Utils_Check_Message[] |
3a0d0bbd | 50 | * An empty array, or a list of warnings |
2aa3d7ab TO |
51 | */ |
52 | public function checkCaseTypeNameConsistency() { | |
be2fb01f | 53 | $messages = []; |
2aa3d7ab TO |
54 | |
55 | foreach ($this->caseTypeNames as $caseTypeName) { | |
56 | $normalFile = $this->xmlRepo->findXmlFile($caseTypeName); | |
57 | $mungedFile = $this->xmlRepo->findXmlFile(CRM_Case_XMLProcessor::mungeCaseType($caseTypeName)); | |
58 | ||
59 | if ($normalFile && $mungedFile && $normalFile == $mungedFile) { | |
60 | // ok | |
61 | } | |
62 | elseif ($normalFile && $mungedFile) { | |
63 | $messages[] = new CRM_Utils_Check_Message( | |
3a0d0bbd | 64 | __FUNCTION__ . $caseTypeName, |
be2fb01f | 65 | ts('Case type "%1" has duplicate XML files ("%2" and "%3")', [ |
165aab59 CW |
66 | 1 => $caseTypeName, |
67 | 2 => $normalFile, | |
68 | 3 => $mungedFile, | |
be2fb01f | 69 | ]) . |
165aab59 CW |
70 | '<br /><a href="' . CRM_Utils_System::getWikiBaseURL() . __FUNCTION__ . '">' . |
71 | ts('Read more about this warning') . | |
72 | '</a>', | |
73 | ts('CiviCase'), | |
74 | \Psr\Log\LogLevel::WARNING, | |
75 | 'fa-puzzle-piece' | |
2aa3d7ab TO |
76 | ); |
77 | } | |
78 | elseif ($normalFile && !$mungedFile) { | |
79 | // ok | |
80 | } | |
81 | elseif (!$normalFile && $mungedFile) { | |
82 | $messages[] = new CRM_Utils_Check_Message( | |
3a0d0bbd | 83 | __FUNCTION__ . $caseTypeName, |
be2fb01f | 84 | ts('Case type "%1" corresponds to XML file ("%2") The XML file should be named "%3".', [ |
165aab59 CW |
85 | 1 => $caseTypeName, |
86 | 2 => $mungedFile, | |
87 | 3 => "{$caseTypeName}.xml", | |
be2fb01f | 88 | ]) . |
165aab59 CW |
89 | '<br /><a href="' . CRM_Utils_System::getWikiBaseURL() . __FUNCTION__ . '">' . |
90 | ts('Read more about this warning') . | |
91 | '</a>', | |
92 | ts('CiviCase'), | |
93 | \Psr\Log\LogLevel::WARNING, | |
94 | 'fa-puzzle-piece' | |
2aa3d7ab TO |
95 | ); |
96 | } | |
97 | elseif (!$normalFile && !$mungedFile) { | |
98 | // ok -- probably a new or DB-based CaseType | |
99 | } | |
100 | } | |
101 | ||
102 | return $messages; | |
103 | } | |
96025800 | 104 | |
c7006a4b TO |
105 | /** |
106 | * Check that the timestamp columns are populated. (CRM-20958) | |
107 | * | |
02b3ba91 | 108 | * @return CRM_Utils_Check_Message[] |
c7006a4b TO |
109 | * An empty array, or a list of warnings |
110 | */ | |
111 | public function checkNullTimestamps() { | |
be2fb01f | 112 | $messages = []; |
c7006a4b TO |
113 | |
114 | $nullCount = 0; | |
115 | $nullCount += CRM_Utils_SQL_Select::from('civicrm_activity') | |
116 | ->where('created_date IS NULL OR modified_date IS NULL') | |
117 | ->select('COUNT(*)') | |
118 | ->execute() | |
119 | ->fetchValue(); | |
120 | $nullCount += CRM_Utils_SQL_Select::from('civicrm_case') | |
121 | ->where('created_date IS NULL OR modified_date IS NULL') | |
122 | ->select('COUNT(*)') | |
123 | ->execute() | |
124 | ->fetchValue(); | |
125 | ||
126 | if ($nullCount > 0) { | |
127 | $messages[] = new CRM_Utils_Check_Message( | |
128 | __FUNCTION__, | |
129 | '<p>' . | |
be2fb01f | 130 | ts('The tables "<em>civicrm_activity</em>" and "<em>civicrm_case</em>" were updated to support two new fields, "<em>created_date</em>" and "<em>modified_date</em>". For historical data, these fields may appear blank. (%1 records have NULL timestamps.)', [ |
c7006a4b | 131 | 1 => $nullCount, |
be2fb01f | 132 | ]) . |
c7006a4b TO |
133 | '</p><p>' . |
134 | ts('At time of writing, this is not a problem. However, future extensions and improvements could rely on these fields, so it may be useful to back-fill them.') . | |
135 | '</p><p>' . | |
be2fb01f | 136 | ts('For further discussion, please visit %1', [ |
c7006a4b | 137 | 1 => sprintf('<a href="%s" target="_blank">%s</a>', self::DOCTOR_WHEN, self::DOCTOR_WHEN), |
be2fb01f | 138 | ]) . |
c7006a4b TO |
139 | '</p>', |
140 | ts('Timestamps for Activities and Cases'), | |
141 | \Psr\Log\LogLevel::NOTICE, | |
142 | 'fa-clock-o' | |
143 | ); | |
144 | } | |
145 | ||
146 | return $messages; | |
147 | } | |
148 | ||
2058bf54 D |
149 | /** |
150 | * Check that the relationship types aren't going to cause problems. | |
151 | * | |
02b3ba91 | 152 | * @return CRM_Utils_Check_Message[] |
2058bf54 D |
153 | * An empty array, or a list of warnings |
154 | */ | |
155 | public function checkRelationshipTypeProblems() { | |
156 | $messages = []; | |
157 | ||
158 | /** | |
159 | * There's no use-case to have two different relationship types | |
160 | * with the same machine name, and it will cause problems because the | |
161 | * system might match up the wrong type when comparing to xml. | |
162 | * A single bi-directional one CAN and probably does have the same | |
163 | * name_a_b and name_b_a and that's ok. | |
164 | */ | |
165 | ||
166 | $dao = CRM_Core_DAO::executeQuery("SELECT rt1.*, rt2.id AS id2, rt2.name_a_b AS nameab2, rt2.name_b_a AS nameba2 FROM civicrm_relationship_type rt1 INNER JOIN civicrm_relationship_type rt2 ON (rt1.name_a_b = rt2.name_a_b OR rt1.name_a_b = rt2.name_b_a) WHERE rt1.id <> rt2.id"); | |
167 | while ($dao->fetch()) { | |
168 | $messages[] = new CRM_Utils_Check_Message( | |
169 | __FUNCTION__ . $dao->id . "dupe1", | |
170 | ts("Relationship type <em>%1</em> has the same internal machine name as another type. | |
171 | <table> | |
172 | <tr><th>ID</th><th>name_a_b</th><th>name_b_a</th></tr> | |
173 | <tr><td>%2</td><td>%3</td><td>%4</td></tr> | |
174 | <tr><td>%5</td><td>%6</td><td>%7</td></tr> | |
175 | </table>", [ | |
176 | 1 => htmlspecialchars($dao->label_a_b), | |
177 | 2 => $dao->id, | |
178 | 3 => htmlspecialchars($dao->name_a_b), | |
179 | 4 => htmlspecialchars($dao->name_b_a), | |
180 | 5 => $dao->id2, | |
181 | 6 => htmlspecialchars($dao->nameab2), | |
182 | 7 => htmlspecialchars($dao->nameba2), | |
183 | ]) . | |
184 | '<br /><a href="' . CRM_Utils_System::docURL2('user/case-management/what-you-need-to-know#relationship-type-internal-name-duplicates', TRUE) . '">' . | |
185 | ts('Read more about this warning') . | |
186 | '</a>', | |
187 | ts('Relationship Type Internal Name Duplicates'), | |
188 | \Psr\Log\LogLevel::ERROR, | |
189 | 'fa-exchange' | |
190 | ); | |
191 | } | |
192 | ||
193 | // Ditto for labels | |
194 | $dao = CRM_Core_DAO::executeQuery("SELECT rt1.*, rt2.id AS id2, rt2.label_a_b AS labelab2, rt2.label_b_a AS labelba2 FROM civicrm_relationship_type rt1 INNER JOIN civicrm_relationship_type rt2 ON (rt1.label_a_b = rt2.label_a_b OR rt1.label_a_b = rt2.label_b_a) WHERE rt1.id <> rt2.id"); | |
195 | while ($dao->fetch()) { | |
196 | $messages[] = new CRM_Utils_Check_Message( | |
197 | __FUNCTION__ . $dao->id . "dupe2", | |
198 | ts("Relationship type <em>%1</em> has the same display label as another type. | |
199 | <table> | |
200 | <tr><th>ID</th><th>label_a_b</th><th>label_b_a</th></tr> | |
201 | <tr><td>%2</td><td>%3</td><td>%4</td></tr> | |
202 | <tr><td>%5</td><td>%6</td><td>%7</td></tr> | |
203 | </table>", [ | |
204 | 1 => htmlspecialchars($dao->label_a_b), | |
205 | 2 => $dao->id, | |
206 | 3 => htmlspecialchars($dao->label_a_b), | |
207 | 4 => htmlspecialchars($dao->label_b_a), | |
208 | 5 => $dao->id2, | |
209 | 6 => htmlspecialchars($dao->labelab2), | |
210 | 7 => htmlspecialchars($dao->labelba2), | |
211 | ]) . | |
212 | '<br /><a href="' . CRM_Utils_System::docURL2('user/case-management/what-you-need-to-know#relationship-type-display-label-duplicates', TRUE) . '">' . | |
213 | ts('Read more about this warning') . | |
214 | '</a>', | |
215 | ts('Relationship Type Display Label Duplicates'), | |
216 | \Psr\Log\LogLevel::ERROR, | |
217 | 'fa-exchange' | |
218 | ); | |
219 | } | |
220 | ||
221 | /** | |
222 | * If the name of one type matches the label of another type, there may | |
223 | * also be problems. This can happen if for example you initially set | |
224 | * it up and then keep changing your mind adding and deleting and renaming | |
225 | * a couple times in a certain order. | |
226 | */ | |
227 | $dao = CRM_Core_DAO::executeQuery("SELECT rt1.*, rt2.id AS id2, rt2.name_a_b AS nameab2, rt2.name_b_a AS nameba2, rt2.label_a_b AS labelab2, rt2.label_b_a AS labelba2 FROM civicrm_relationship_type rt1 INNER JOIN civicrm_relationship_type rt2 ON (rt1.name_a_b = rt2.label_a_b OR rt1.name_b_a = rt2.label_a_b OR rt1.name_a_b = rt2.label_b_a OR rt1.name_b_a = rt2.label_b_a) WHERE rt1.id <> rt2.id"); | |
228 | // No point displaying the same matching id twice, which can happen with | |
229 | // the query. | |
230 | $ids = []; | |
231 | while ($dao->fetch()) { | |
232 | if (isset($ids[$dao->id2])) { | |
233 | continue; | |
234 | } | |
235 | $ids[$dao->id] = $dao->id; | |
236 | $messages[] = new CRM_Utils_Check_Message( | |
237 | __FUNCTION__ . $dao->id . "dupe3", | |
238 | ts("Relationship type <em>%1</em> has an internal machine name that is the same as the display label as another type. | |
239 | <table> | |
240 | <tr><th>ID</th><th>name_a_b</th><th>name_b_a</th><th>label_a_b</th><th>label_b_a</th></tr> | |
241 | <tr><td>%2</td><td>%3</td><td>%4</td><td>%5</td><td>%6</td></tr> | |
242 | <tr><td>%7</td><td>%8</td><td>%9</td><td>%10</td><td>%11</td></tr> | |
243 | </table>", [ | |
244 | 1 => htmlspecialchars($dao->label_a_b), | |
245 | 2 => $dao->id, | |
246 | 3 => htmlspecialchars($dao->name_a_b), | |
247 | 4 => htmlspecialchars($dao->name_b_a), | |
248 | 5 => htmlspecialchars($dao->label_a_b), | |
249 | 6 => htmlspecialchars($dao->label_b_a), | |
250 | 7 => $dao->id2, | |
251 | 8 => htmlspecialchars($dao->nameab2), | |
252 | 9 => htmlspecialchars($dao->nameab2), | |
253 | 10 => htmlspecialchars($dao->labelab2), | |
254 | 11 => htmlspecialchars($dao->labelba2), | |
255 | ]) . | |
256 | '<br /><a href="' . CRM_Utils_System::docURL2('user/case-management/what-you-need-to-know#relationship-type-cross-duplication', TRUE) . '">' . | |
257 | ts('Read more about this warning') . | |
258 | '</a>', | |
259 | ts('Relationship Type Cross-Duplication'), | |
260 | \Psr\Log\LogLevel::WARNING, | |
261 | 'fa-exchange' | |
262 | ); | |
263 | } | |
264 | ||
265 | /** | |
266 | * Check that ones that appear to be unidirectional don't have the same | |
267 | * machine name for both a_b and b_a. This can happen for example if you | |
268 | * forget to fill in the b_a label when creating, then go back and edit. | |
269 | */ | |
270 | $dao = CRM_Core_DAO::executeQuery("SELECT rt1.* FROM civicrm_relationship_type rt1 WHERE rt1.name_a_b = rt1.name_b_a AND rt1.label_a_b <> rt1.label_b_a"); | |
271 | while ($dao->fetch()) { | |
272 | $messages[] = new CRM_Utils_Check_Message( | |
273 | __FUNCTION__ . $dao->id . "ambiguousname", | |
274 | ts("Relationship type <em>%1</em> appears to be unidirectional, but has the same internal machine name for both sides. | |
275 | <table> | |
276 | <tr><th>ID</th><th>name_a_b</th><th>name_b_a</th><th>label_a_b</th><th>label_b_a</th></tr> | |
277 | <tr><td>%2</td><td>%3</td><td>%4</td><td>%5</td><td>%6</td></tr> | |
278 | </table>", [ | |
279 | 1 => htmlspecialchars($dao->label_a_b), | |
280 | 2 => $dao->id, | |
281 | 3 => htmlspecialchars($dao->name_a_b), | |
282 | 4 => htmlspecialchars($dao->name_b_a), | |
283 | 5 => htmlspecialchars($dao->label_a_b), | |
284 | 6 => htmlspecialchars($dao->label_b_a), | |
285 | ]) . | |
286 | '<br /><a href="' . CRM_Utils_System::docURL2('user/case-management/what-you-need-to-know#relationship-type-ambiguity', TRUE) . '">' . | |
287 | ts('Read more about this warning') . | |
288 | '</a>', | |
289 | ts('Relationship Type Ambiguity'), | |
290 | \Psr\Log\LogLevel::WARNING, | |
291 | 'fa-exchange' | |
292 | ); | |
293 | } | |
294 | ||
295 | /** | |
296 | * Check that ones that appear to be unidirectional don't have the same | |
297 | * label for both a_b and b_a. This can happen for example if you | |
298 | * created it as unidirectional, then edited it later trying to make it | |
299 | * bidirectional. | |
300 | */ | |
301 | $dao = CRM_Core_DAO::executeQuery("SELECT rt1.* FROM civicrm_relationship_type rt1 WHERE rt1.label_a_b = rt1.label_b_a AND rt1.name_a_b <> rt1.name_b_a"); | |
302 | while ($dao->fetch()) { | |
303 | $messages[] = new CRM_Utils_Check_Message( | |
304 | __FUNCTION__ . $dao->id . "ambiguouslabel", | |
305 | ts("Relationship type <em>%1</em> appears to be unidirectional internally, but has the same display label for both sides. Possibly you created it initially as unidirectional and then made it bidirectional later. | |
306 | <table> | |
307 | <tr><th>ID</th><th>name_a_b</th><th>name_b_a</th><th>label_a_b</th><th>label_b_a</th></tr> | |
308 | <tr><td>%2</td><td>%3</td><td>%4</td><td>%5</td><td>%6</td></tr> | |
309 | </table>", [ | |
310 | 1 => htmlspecialchars($dao->label_a_b), | |
311 | 2 => $dao->id, | |
312 | 3 => htmlspecialchars($dao->name_a_b), | |
313 | 4 => htmlspecialchars($dao->name_b_a), | |
314 | 5 => htmlspecialchars($dao->label_a_b), | |
315 | 6 => htmlspecialchars($dao->label_b_a), | |
316 | ]) . | |
317 | '<br /><a href="' . CRM_Utils_System::docURL2('user/case-management/what-you-need-to-know#relationship-type-ambiguity', TRUE) . '">' . | |
318 | ts('Read more about this warning') . | |
319 | '</a>', | |
320 | ts('Relationship Type Ambiguity'), | |
321 | \Psr\Log\LogLevel::WARNING, | |
322 | 'fa-exchange' | |
323 | ); | |
324 | } | |
325 | ||
326 | /** | |
327 | * Check for missing roles listed in the xml but not defined as | |
328 | * relationship types. | |
329 | */ | |
330 | ||
331 | // Don't use database since might be in xml files. | |
332 | $caseTypes = civicrm_api3('CaseType', 'get', [ | |
333 | 'options' => ['limit' => 0], | |
334 | ])['values']; | |
335 | // Don't use pseudoconstant since want all and also name and label. | |
336 | $relationshipTypes = civicrm_api3('RelationshipType', 'get', [ | |
337 | 'options' => ['limit' => 0], | |
338 | ])['values']; | |
339 | $allConfigured = array_column($relationshipTypes, 'id', 'name_a_b') | |
340 | + array_column($relationshipTypes, 'id', 'name_b_a') | |
341 | + array_column($relationshipTypes, 'id', 'label_a_b') | |
342 | + array_column($relationshipTypes, 'id', 'label_b_a'); | |
343 | $missing = []; | |
344 | foreach ($caseTypes as $caseType) { | |
35d5bbae | 345 | foreach ($caseType['definition']['caseRoles'] ?? [] as $role) { |
2058bf54 D |
346 | if (!isset($allConfigured[$role['name']])) { |
347 | $missing[$role['name']] = $role['name']; | |
348 | } | |
349 | } | |
350 | } | |
351 | if (!empty($missing)) { | |
352 | $tableRows = []; | |
353 | foreach ($relationshipTypes as $relationshipType) { | |
354 | $tableRows[] = ts('<tr><td>%1</td><td>%2</td><td>%3</td><td>%4</td><td>%5</td></tr>', [ | |
355 | 1 => $relationshipType['id'], | |
356 | 2 => htmlspecialchars($relationshipType['name_a_b']), | |
357 | 3 => htmlspecialchars($relationshipType['name_b_a']), | |
358 | 4 => htmlspecialchars($relationshipType['label_a_b']), | |
359 | 5 => htmlspecialchars($relationshipType['label_b_a']), | |
360 | ]); | |
361 | } | |
362 | $messages[] = new CRM_Utils_Check_Message( | |
363 | __FUNCTION__ . "missingroles", | |
364 | ts("<p>The following roles listed in your case type definitions do not match any relationship type defined in the system: <em>%1</em>.</p>" | |
365 | . "<p>This might be because of a mismatch if you are using external xml files to manage case types. If using xml files, then use either the name_a_b or name_b_a value from the following table. (Out of the box you would use name_b_a, which lists them on the case from the client perspective.) If you are not using xml files, you can edit your case types at Administer - CiviCase - Case Types.</p>" | |
366 | . "<table> | |
367 | <tr><th>ID</th><th>name_a_b</th><th>name_b_a</th><th>label_a_b</th><th>label_b_a</th></tr>" | |
368 | . implode("\n", $tableRows) | |
369 | . "</table>", [ | |
370 | 1 => htmlspecialchars(implode(', ', $missing)), | |
371 | ]) . | |
372 | '<br /><a href="' . CRM_Utils_System::docURL2('user/case-management/what-you-need-to-know#missing-roles', TRUE) . '">' . | |
373 | ts('Read more about this warning') . | |
374 | '</a>', | |
375 | ts('Missing Roles'), | |
376 | \Psr\Log\LogLevel::ERROR, | |
377 | 'fa-exclamation' | |
378 | ); | |
379 | } | |
380 | ||
381 | return $messages; | |
382 | } | |
383 | ||
ef618a14 D |
384 | /** |
385 | * Check any xml definitions stored as external files to see if they | |
386 | * have label as the role and where the label is different from the name. | |
387 | * We don't have to think about edge cases because there are already | |
388 | * status checks above for those. | |
389 | * | |
02b3ba91 | 390 | * @return CRM_Utils_Check_Message[] |
ef618a14 D |
391 | * An empty array, or a list of warnings |
392 | */ | |
393 | public function checkExternalXmlFileRoleNames() { | |
394 | $messages = []; | |
395 | ||
396 | // Get config for relationship types | |
397 | $relationship_types = civicrm_api3('RelationshipType', 'get', [ | |
398 | 'options' => ['limit' => 0], | |
399 | ])['values']; | |
400 | // keyed on name, with id as the value, e.g. 'Case Coordinator is' => 10 | |
401 | $names_a_b = array_column($relationship_types, 'id', 'name_a_b'); | |
402 | $names_b_a = array_column($relationship_types, 'id', 'name_b_a'); | |
403 | $labels_a_b = array_column($relationship_types, 'id', 'label_a_b'); | |
404 | $labels_b_a = array_column($relationship_types, 'id', 'label_b_a'); | |
405 | ||
406 | $dao = CRM_Core_DAO::executeQuery("SELECT id FROM civicrm_case_type WHERE definition IS NULL OR definition=''"); | |
407 | while ($dao->fetch()) { | |
408 | $case_type = civicrm_api3('CaseType', 'get', [ | |
409 | 'id' => $dao->id, | |
410 | ])['values'][$dao->id]; | |
411 | if (empty($case_type['definition'])) { | |
412 | $messages[] = new CRM_Utils_Check_Message( | |
413 | __FUNCTION__ . "missingcasetypedefinition", | |
414 | '<p>' . ts('Unable to locate xml file for Case Type "<em>%1</em>".', | |
415 | [ | |
416 | 1 => htmlspecialchars(empty($case_type['title']) ? $dao->id : $case_type['title']), | |
417 | ]) . '</p>', | |
418 | ts('Missing Case Type Definition'), | |
419 | \Psr\Log\LogLevel::ERROR, | |
420 | 'fa-exclamation' | |
421 | ); | |
422 | continue; | |
423 | } | |
424 | ||
425 | if (empty($case_type['definition']['caseRoles'])) { | |
426 | $messages[] = new CRM_Utils_Check_Message( | |
427 | __FUNCTION__ . "missingcaseroles", | |
428 | '<p>' . ts('CaseRoles seems to be missing in the xml file for Case Type "<em>%1</em>".', | |
429 | [ | |
430 | 1 => htmlspecialchars(empty($case_type['title']) ? $dao->id : $case_type['title']), | |
431 | ]) . '</p>', | |
432 | ts('Missing Case Roles'), | |
433 | \Psr\Log\LogLevel::ERROR, | |
434 | 'fa-exclamation' | |
435 | ); | |
436 | continue; | |
437 | } | |
438 | ||
439 | // Loop thru each role in the xml. | |
440 | foreach ($case_type['definition']['caseRoles'] as $role) { | |
441 | $name_to_suggest = NULL; | |
442 | $xml_name = $role['name']; | |
443 | if (isset($names_a_b[$xml_name]) || isset($names_b_a[$xml_name])) { | |
444 | // It matches a name, so either name and label are the same or it's | |
445 | // an edge case already dealt with by core status checks, so do | |
446 | // nothing. | |
447 | continue; | |
448 | } | |
449 | elseif (isset($labels_b_a[$xml_name])) { | |
450 | // $labels_b_a[$xml_name] gives us the id, so then look up name_b_a | |
451 | // from the original relationship_types array which is keyed on id. | |
452 | // We do b_a first because it's the more standard one, although it | |
453 | // will only make a difference in edge cases which we leave to the | |
454 | // other checks. | |
455 | $name_to_suggest = $relationship_types[$labels_b_a[$xml_name]]['name_b_a']; | |
456 | } | |
457 | elseif (isset($labels_a_b[$xml_name])) { | |
458 | $name_to_suggest = $relationship_types[$labels_a_b[$xml_name]]['name_a_b']; | |
459 | } | |
460 | ||
461 | // If it didn't match any name or label then that's weird. | |
462 | if (empty($name_to_suggest)) { | |
463 | $messages[] = new CRM_Utils_Check_Message( | |
464 | __FUNCTION__ . "invalidcaserole", | |
465 | '<p>' . ts('CaseRole "<em>%1</em>" in the xml file for Case Type "<em>%2</em>" doesn\'t seem to match any existing relationship type.', | |
466 | [ | |
467 | 1 => htmlspecialchars($xml_name), | |
468 | 2 => htmlspecialchars(empty($case_type['title']) ? $dao->id : $case_type['title']), | |
469 | ]) . '</p>', | |
470 | ts('Invalid Case Role'), | |
471 | \Psr\Log\LogLevel::ERROR, | |
472 | 'fa-exclamation' | |
473 | ); | |
474 | } | |
475 | else { | |
476 | $messages[] = new CRM_Utils_Check_Message( | |
477 | __FUNCTION__ . "suggestedchange", | |
478 | '<p>' . ts('Please edit the XML file for case type "<em>%2</em>" so that the case role label "<em>%1</em>" is changed to its corresponding name "<em>%3</em>". Using label is deprecated as of version 5.20.', | |
479 | [ | |
480 | 1 => htmlspecialchars($xml_name), | |
481 | 2 => htmlspecialchars(empty($case_type['title']) ? $dao->id : $case_type['title']), | |
482 | 3 => htmlspecialchars($name_to_suggest), | |
483 | ]) . '</p>', | |
484 | ts('Case Role using display label instead of internal machine name'), | |
485 | \Psr\Log\LogLevel::WARNING, | |
486 | 'fa-code' | |
487 | ); | |
488 | } | |
489 | } | |
490 | } | |
491 | return $messages; | |
492 | } | |
493 | ||
ef10e0b5 | 494 | } |