Merge pull request #3179 from webpartners/master
[civicrm-core.git] / Civi / CCase / Events.php
index f1556c490f82ee1f8303bc81e5801e3c291c2ea1..472ac9f6471312a7616dcd6dcb7b2fb3f1e85463 100644 (file)
 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.
    *
@@ -37,7 +44,7 @@ class Events {
     $caseId = NULL;
     switch ($event->entity) {
       case 'Activity':
-        if ($event->object->case_id) {
+        if (!empty($event->object->case_id)) {
           $caseId = $event->object->case_id;
         }
         break;
@@ -49,8 +56,25 @@ class Events {
     }
 
     if ($caseId) {
+      if (!isset(self::$isActive[$caseId])) {
+        \CRM_Core_Transaction::addCallback(
+          \CRM_Core_Transaction::PHASE_POST_COMMIT,
+          array(__CLASS__, 'fireCaseChangeForRealz'),
+          array($caseId),
+          "Civi_CCase_Events::fire::{$caseId}"
+        );
+      }
+    }
+  }
+
+  public static function fireCaseChangeForRealz($caseId) {
+    if (!isset(self::$isActive[$caseId])) {
+      $tx = new \CRM_Core_Transaction();
+      self::$isActive[$caseId] = 1;
       $analyzer = new \Civi\CCase\Analyzer($caseId);
       \CRM_Utils_Hook::caseChange($analyzer);
+      unset(self::$isActive[$caseId]);
+      unset($tx);
     }
   }