Merge pull request #15982 from civicrm/5.20
[civicrm-core.git] / Civi / CCase / Events.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 Events
15 *
16 * @package Civi\CCase
17 */
18 class Events {
19 /**
20 * @var array (int $caseId => bool $active) list of cases for which we are actively firing case-change event
21 *
22 * We do not want to fire case-change events recursively.
23 */
24 public static $isActive = [];
25
26 /**
27 * Following a change to an activity or case, fire the case-change event.
28 *
29 * @param \Civi\Core\Event\PostEvent $event
30 * @throws \CRM_Core_Exception
31 */
32 public static function fireCaseChange(\Civi\Core\Event\PostEvent $event) {
33 // Activities can be linked to multiple cases, so $caseIds might be an array or an int
34 $caseIds = NULL;
35 switch ($event->entity) {
36 case 'Activity':
37 if (!empty($event->object->case_id)) {
38 $caseIds = $event->object->case_id;
39 }
40 break;
41
42 case 'Case':
43 // by the time we get the post-delete event, the record is gone, so
44 // there's nothing to analyze
45 if ($event->action != 'delete') {
46 $caseIds = $event->id;
47 }
48 break;
49
50 default:
51 throw new \CRM_Core_Exception("CRM_Case_Listener does not support entity {$event->entity}");
52 }
53
54 if ($caseIds) {
55 foreach ((array) $caseIds as $caseId) {
56 if (!isset(self::$isActive[$caseId])) {
57 $tx = new \CRM_Core_Transaction();
58 \CRM_Core_Transaction::addCallback(
59 \CRM_Core_Transaction::PHASE_POST_COMMIT,
60 [__CLASS__, 'fireCaseChangeForRealz'],
61 [$caseId],
62 "Civi_CCase_Events::fire::{$caseId}"
63 );
64 }
65 }
66 }
67 }
68
69 /**
70 * Fire case change hook
71 *
72 * @param int|array $caseIds
73 */
74 public static function fireCaseChangeForRealz($caseIds) {
75 foreach ((array) $caseIds as $caseId) {
76 if (!isset(self::$isActive[$caseId])) {
77 $tx = new \CRM_Core_Transaction();
78 self::$isActive[$caseId] = 1;
79 $analyzer = new \Civi\CCase\Analyzer($caseId);
80 \CRM_Utils_Hook::caseChange($analyzer);
81 unset(self::$isActive[$caseId]);
82 unset($tx);
83 }
84 }
85 }
86
87 /**
88 * Find any extra listeners declared in XML and pass the event along to them.
89 *
90 * @param \Civi\CCase\Event\CaseChangeEvent $event
91 */
92 public static function delegateToXmlListeners(\Civi\CCase\Event\CaseChangeEvent $event) {
93 $p = new \CRM_Case_XMLProcessor_Process();
94 $listeners = $p->getListeners($event->analyzer->getCaseType());
95 foreach ($listeners as $listener) {
96 /** @var $listener \Civi\CCase\CaseChangeListener */
97 $listener->onCaseChange($event);
98 }
99 }
100
101 }