From: Tim Otten Date: Tue, 27 May 2014 19:55:59 +0000 (-0700) Subject: CRM-14727 - Move $isActive from SequenceListener to Events X-Git-Url: https://vcs.fsf.org/?a=commitdiff_plain;h=874dae9d263b369e2613134bafbe96f4e4f012fd;p=civicrm-core.git CRM-14727 - Move $isActive from SequenceListener to Events When a case-change listener makes another change to a case, we don't want to refire all the case-change listeners. $isActive helps avoid that (infinite) recursion. This commit has two important qualities: 1. The code is simpler. There's a single set() and single unset(). 2. Developers of new case-change listeners don't need to worry about recursion problems -- it's handled centrally. --- diff --git a/Civi/CCase/Events.php b/Civi/CCase/Events.php index f1556c490f..9c5c10c588 100644 --- a/Civi/CCase/Events.php +++ b/Civi/CCase/Events.php @@ -27,6 +27,13 @@ namespace Civi\CCase; class Events { + /** + * @var array (int $caseId => bool $active) list of cases for which we are actively firing case-change event + * + * We do not want to fire case-change events recursively. + */ + static $isActive = array(); + /** * Following a change to an activity or case, fire the case-change event. * @@ -48,9 +55,11 @@ class Events { throw new \CRM_Core_Exception("CRM_Case_Listener does not support entity {$event->entity}"); } - if ($caseId) { + if ($caseId && !isset(self::$isActive[$caseId])) { + self::$isActive[$caseId] = 1; $analyzer = new \Civi\CCase\Analyzer($caseId); \CRM_Utils_Hook::caseChange($analyzer); + unset(self::$isActive[$caseId]); } } diff --git a/Civi/CCase/SequenceListener.php b/Civi/CCase/SequenceListener.php index 5eaa32d0ca..1472b8afc8 100644 --- a/Civi/CCase/SequenceListener.php +++ b/Civi/CCase/SequenceListener.php @@ -28,17 +28,10 @@ class SequenceListener implements CaseChangeListener { self::singleton()->onCaseChange($event); } - private $isActive = array(); - public function onCaseChange(\Civi\CCase\Event\CaseChangeEvent $event) { /** @var \Civi\CCase\Analyzer $analyzer */ $analyzer = $event->analyzer; - if (isset($this->isActive[$analyzer->getCaseId()])) { - return; - } - $this->isActive[$analyzer->getCaseId()] = 1; - $activitySetXML = $this->getSequenceXml($analyzer->getXml()); if (!$activitySetXML) { return; @@ -54,12 +47,10 @@ class SequenceListener implements CaseChangeListener { if (empty($actIndex[$actTypeId])) { // Haven't tried this step yet! $this->createActivity($analyzer, $actTypeXML); - unset($this->isActive[$analyzer->getCaseId()]); return; } elseif (empty($actIndex[$actTypeId][$actStatuses['Completed']])) { // Haven't gotten past this step yet! - unset($this->isActive[$analyzer->getCaseId()]); return; } } @@ -70,9 +61,6 @@ class SequenceListener implements CaseChangeListener { 'status_id' => 'Closed', )); $analyzer->flush(); - - // Wrap-up - unset($this->isActive[$analyzer->getCaseId()]); } /**