CRM-14727 - SequenceListener fixes
authorTim Otten <totten@civicrm.org>
Tue, 3 Jun 2014 06:03:23 +0000 (23:03 -0700)
committerTim Otten <totten@civicrm.org>
Tue, 3 Jun 2014 06:19:19 +0000 (23:19 -0700)
1. Fire the case-change event outside the main transaction. When case-change
listeners query the DB, they'll more understandable results.

2. Determine list of case-activities using $case['activities'] rather than
trying to call Activity.get(case_id=X).  Activity.get does not support
filtering on case_id.

CRM/Core/Transaction.php
Civi/CCase/Analyzer.php
Civi/CCase/Events.php
Civi/Core/Container.php

index 63493f151eb579544577a7382439d1681b1aa47a..17f7e9a88d6efbf19b1c59617fded9141534d12d 100644 (file)
@@ -198,11 +198,18 @@ class CRM_Core_Transaction {
    * @param mixed $params Optional values to pass to callback.
    *          See php manual call_user_func_array for details.
    */
-  static public function addCallback($phase, $callback, $params = null) {
-    self::$_callbacks[$phase][] = array(
-      'callback' => $callback,
-      'parameters' => (is_array($params) ? $params : array($params))
-    );
+  static public function addCallback($phase, $callback, $params = null, $id = NULL) {
+    if ($id) {
+      self::$_callbacks[$phase][$id] = array(
+        'callback' => $callback,
+        'parameters' => (is_array($params) ? $params : array($params))
+      );
+    } else {
+      self::$_callbacks[$phase][] = array(
+        'callback' => $callback,
+        'parameters' => (is_array($params) ? $params : array($params))
+      );
+    }
   }
 
   /**
index b16cedcd9f27072707dd4bf5425bfe9ba5140b80..2d94873126b6486c4406b293e40a143da992bd62 100644 (file)
@@ -102,8 +102,19 @@ class Analyzer {
    */
   public function getActivities() {
     if ($this->activities === NULL) {
-      $result = civicrm_api3('Activity', 'get', array('case_id' => $this->caseId));
-      $this->activities = $result['values'];
+      // TODO find batch-oriented API for getting all activities in a case
+      $case = $this->getCase();
+      $activities = array();
+      if (isset($case['activities'])) {
+        foreach ($case['activities'] as $actId) {
+          $result = civicrm_api3('Activity', 'get', array(
+            'id' => $actId,
+            'is_current_revision' => 1,
+          ));
+          $activities = array_merge($activities, $result['values']);
+        }
+      }
+      $this->activities = $activities;
     }
     return $this->activities;
   }
index 85b633682048d3f337e1540079b776632ad720a4..472ac9f6471312a7616dcd6dcb7b2fb3f1e85463 100644 (file)
@@ -55,11 +55,26 @@ class Events {
         throw new \CRM_Core_Exception("CRM_Case_Listener does not support entity {$event->entity}");
     }
 
-    if ($caseId && !isset(self::$isActive[$caseId])) {
+    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);
     }
   }
 
index faecd4b407eb47456bd03f09e4f2a08ab8ffb276..d1a0578c37923c2fb37a1c6fd9f6b3b75165e308 100644 (file)
@@ -90,7 +90,7 @@ class Container {
   public function createEventDispatcher() {
     $dispatcher = new \Symfony\Component\EventDispatcher\EventDispatcher();
     $dispatcher->addListener('hook_civicrm_post::Activity', array('\Civi\CCase\Events', 'fireCaseChange'));
-    $dispatcher->addListener('hook_civicrm_post::Case', array('\Civi\CCase\Events', 'fireCaseChange'));
+    //$dispatcher->addListener('hook_civicrm_post::Case', array('\Civi\CCase\Events', 'fireCaseChange'));
     $dispatcher->addListener('hook_civicrm_caseChange', array('\Civi\CCase\Events', 'delegateToXmlListeners'));
     $dispatcher->addListener('hook_civicrm_caseChange', array('\Civi\CCase\SequenceListener', 'onCaseChange_static'));
     return $dispatcher;