return $this->caseRoles($xml->CaseRoles, TRUE);
}
+ /**
+ * @param string $caseType
+ * @return array<\Civi\CCase\CaseChangeListener>
+ */
+ function getListeners($caseType) {
+ $xml = $this->retrieve($caseType);
+ $listeners = array();
+ if ($xml->Listeners && $xml->Listeners->Listener) {
+ foreach ($xml->Listeners->Listener as $listenerXML) {
+ $class = (string) $listenerXML;
+ $listeners[] = new $class();
+ }
+ }
+ return $listeners;
+ }
+
/**
* @return int
*/
}
/**
- * @return array<string> symbolic names of case-types
+ * @return array<int,string> symbolic names of case-types
*/
public function getAllCaseTypes() {
if ($this->allCaseTypes === NULL) {
);
}
+ /**
+ * This hook fires whenever a record in a case changes.
+ *
+ * @param \Civi\CCase\Analyzer $analyzer
+ */
+ static function caseChange(\Civi\CCase\Analyzer $analyzer) {
+ $event = new \Civi\CCase\Event\CaseChangeEvent($analyzer);
+ \Civi\Core\Container::singleton()->get('dispatcher')->dispatch("hook_civicrm_caseChange", $event);
+
+ return self::singleton()->invoke(1, $angularModules,
+ self::$_nullObject, self::$_nullObject, self::$_nullObject, self::$_nullObject, self::$_nullObject,
+ 'civicrm_caseChange'
+ );
+ }
}
--- /dev/null
+<?php
+/*
+ +--------------------------------------------------------------------+
+ | CiviCRM version 4.5 |
+ +--------------------------------------------------------------------+
+ | Copyright CiviCRM LLC (c) 2004-2014 |
+ +--------------------------------------------------------------------+
+ | This file is a part of CiviCRM. |
+ | |
+ | CiviCRM is free software; you can copy, modify, and distribute it |
+ | under the terms of the GNU Affero General Public License |
+ | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
+ | |
+ | CiviCRM is distributed in the hope that it will be useful, but |
+ | WITHOUT ANY WARRANTY; without even the implied warranty of |
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
+ | See the GNU Affero General Public License for more details. |
+ | |
+ | You should have received a copy of the GNU Affero General Public |
+ | License and the CiviCRM Licensing Exception along |
+ | with this program; if not, contact CiviCRM LLC |
+ | at info[AT]civicrm[DOT]org. If you have questions about the |
+ | GNU Affero General Public License or the licensing of CiviCRM, |
+ | see the CiviCRM license FAQ at http://civicrm.org/licensing |
+ +--------------------------------------------------------------------+
+*/
+namespace Civi\CCase;
+
+class Analyzer {
+ /**
+ * @var int
+ */
+ private $caseId;
+
+ /**
+ * @var array per APIv3
+ */
+ private $case;
+
+ /**
+ * @var string
+ */
+ private $caseType;
+
+ /**
+ * @var array per APIv3
+ */
+ private $activities;
+
+ /**
+ * @var \SimpleXMLElement
+ */
+ private $xml;
+
+ /**
+ * @var array<string,array>
+ */
+ private $indices;
+
+ public function __construct($caseId) {
+ $this->caseId = $caseId;
+ $this->flush();
+ }
+
+ /**
+ * Determine if case includes an activity of given type/status
+ *
+ * @param string $type eg "Phone Call", "Interview Prospect", "Background Check"
+ * @param string $status eg "Scheduled", "Completed"
+ * @return bool
+ */
+ public function hasActivity($type, $status = NULL) {
+ $idx = $this->getActivityIndex(array('activity_type_id', 'status_id'));
+ $activityTypeGroup = civicrm_api3('option_group', 'get', array('name' => 'activity_type'));
+ $activityType = array(
+ 'name' => $type,
+ 'option_group_id' => $activityTypeGroup['id'],
+ );
+ $activityTypeID = civicrm_api3('option_value', 'get', $activityType);
+ $activityTypeID = $activityTypeID['values'][$activityTypeID['id']]['value'];
+ if ($status) {
+ $activityStatusGroup = civicrm_api3('option_group', 'get', array('name' => 'activity_status'));
+ $activityStatus = array(
+ 'name' => $status,
+ 'option_group_id' => $activityStatusGroup['id']
+ );
+ $activityStatusID = civicrm_api3('option_value', 'get', $activityStatus);
+ $activityStatusID = $activityStatusID['values'][$activityStatusID['id']]['value'];
+ }
+ if ($status === NULL) {
+ return !empty($idx[$activityTypeID]);
+ }
+ else {
+ return !empty($idx[$activityTypeID][$activityStatusID]);
+ }
+ }
+
+ /**
+ * Get a list of all activities in the case
+ *
+ * @return array list of activity records (api/v3 format)
+ */
+ public function getActivities() {
+ if ($this->activities === NULL) {
+ $result = civicrm_api3('Activity', 'get', array('case_id' => $this->caseId));
+ $this->activities = $result['values'];
+ }
+ return $this->activities;
+ }
+
+ /**
+ * Get a single activity record by type
+ *
+ * @param string $type
+ * @throws \Civi\CCase\Exception\MultipleActivityException
+ * @return array|NULL, activity record (api/v3)
+ */
+ public function getSingleActivity($type) {
+ $idx = $this->getActivityIndex(array('activity_type_id', 'id'));
+ $actTypes = array_flip(\CRM_Core_PseudoConstant::activityType(TRUE, TRUE, FALSE, 'name'));
+ $typeId = $actTypes[$type];
+ $count = isset($idx[$typeId]) ? count($idx[$typeId]) : 0;
+
+ if ($count === 0) {
+ return NULL;
+ }
+ elseif ($count === 1) {
+ foreach ($idx[$typeId] as $item) {
+ return $item;
+ }
+ }
+ else {
+ throw new \Civi\CCase\Exception\MultipleActivityException("Wrong quantity of [$type] records. Expected 1 but found " . $count);
+ }
+ }
+
+ /**
+ * @return int
+ */
+ public function getCaseId() {
+ return $this->caseId;
+ }
+
+ /**
+ * @return array, Case record (api/v3 format)
+ */
+ public function getCase() {
+ if ($this->case === NULL) {
+ $this->case = civicrm_api3('case', 'getsingle', array('id' => $this->caseId));
+ }
+ return $this->case;
+ }
+
+ /**
+ * @return string
+ */
+ public function getCaseType() {
+ if ($this->caseType === NULL) {
+ $case = $this->getCase();
+ $caseTypes = \CRM_Case_XMLRepository::singleton()->getAllCaseTypes();
+ if (!isset($caseTypes[$case['case_type_id']])) {
+ throw new \CRM_Core_Exception("Case does not have a recognized case-type!");
+ }
+ $this->caseType = $caseTypes[$case['case_type_id']];
+ }
+ return $this->caseType;
+ }
+
+ /**
+ * Get a list of all activities in the case (indexed by some property/properties)
+ *
+ * @param array $keys list of properties by which to index activities
+ * @return array list of activity records (api/v3 format), indexed by $keys
+ */
+ public function getActivityIndex($keys) {
+ $key = implode(";", $keys);
+ if (!isset($this->indices[$key])) {
+ $this->indices[$key] = \CRM_Utils_Array::index($keys, $this->getActivities());
+ }
+ return $this->indices[$key];
+ }
+
+ /**
+ * @return SimpleXMLElement|NULL
+ */
+ public function getXml() {
+ if ($this->xml === NULL) {
+ $this->xml = \CRM_Case_XMLRepository::singleton()->retrieve($this->getCaseType());
+ }
+ return $this->xml;
+ }
+
+ /**
+ * Flush any cached information
+ *
+ * @return void
+ */
+ public function flush() {
+ $this->case = NULL;
+ $this->caseType = NULL;
+ $this->activities = NULL;
+ $this->indices = array();
+ }
+}
\ No newline at end of file
--- /dev/null
+<?php
+/*
+ +--------------------------------------------------------------------+
+ | CiviCRM version 4.5 |
+ +--------------------------------------------------------------------+
+ | Copyright CiviCRM LLC (c) 2004-2014 |
+ +--------------------------------------------------------------------+
+ | This file is a part of CiviCRM. |
+ | |
+ | CiviCRM is free software; you can copy, modify, and distribute it |
+ | under the terms of the GNU Affero General Public License |
+ | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
+ | |
+ | CiviCRM is distributed in the hope that it will be useful, but |
+ | WITHOUT ANY WARRANTY; without even the implied warranty of |
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
+ | See the GNU Affero General Public License for more details. |
+ | |
+ | You should have received a copy of the GNU Affero General Public |
+ | License and the CiviCRM Licensing Exception along |
+ | with this program; if not, contact CiviCRM LLC |
+ | at info[AT]civicrm[DOT]org. If you have questions about the |
+ | GNU Affero General Public License or the licensing of CiviCRM, |
+ | see the CiviCRM license FAQ at http://civicrm.org/licensing |
+ +--------------------------------------------------------------------+
+*/
+namespace Civi\CCase;
+
+interface CaseChangeListener {
+ function onCaseChange(\Civi\CCase\Event\CaseChangeEvent $event);
+}
\ No newline at end of file
--- /dev/null
+<?php
+/*
+ +--------------------------------------------------------------------+
+ | CiviCRM version 4.5 |
+ +--------------------------------------------------------------------+
+ | Copyright CiviCRM LLC (c) 2004-2014 |
+ +--------------------------------------------------------------------+
+ | This file is a part of CiviCRM. |
+ | |
+ | CiviCRM is free software; you can copy, modify, and distribute it |
+ | under the terms of the GNU Affero General Public License |
+ | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
+ | |
+ | CiviCRM is distributed in the hope that it will be useful, but |
+ | WITHOUT ANY WARRANTY; without even the implied warranty of |
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
+ | See the GNU Affero General Public License for more details. |
+ | |
+ | You should have received a copy of the GNU Affero General Public |
+ | License and the CiviCRM Licensing Exception along |
+ | with this program; if not, contact CiviCRM LLC |
+ | at info[AT]civicrm[DOT]org. If you have questions about the |
+ | GNU Affero General Public License or the licensing of CiviCRM, |
+ | see the CiviCRM license FAQ at http://civicrm.org/licensing |
+ +--------------------------------------------------------------------+
+*/
+
+namespace Civi\CCase\Event;
+
+/**
+ * Class CaseChangeEvent
+ * @package Civi\API\Event
+ */
+class CaseChangeEvent extends \Symfony\Component\EventDispatcher\Event {
+ /**
+ * @var \Civi\CCase\Analyzer
+ */
+ public $analyzer;
+
+ function __construct($analyzer) {
+ $this->analyzer = $analyzer;
+ }
+}
--- /dev/null
+<?php
+/*
+ +--------------------------------------------------------------------+
+ | CiviCRM version 4.5 |
+ +--------------------------------------------------------------------+
+ | Copyright CiviCRM LLC (c) 2004-2014 |
+ +--------------------------------------------------------------------+
+ | This file is a part of CiviCRM. |
+ | |
+ | CiviCRM is free software; you can copy, modify, and distribute it |
+ | under the terms of the GNU Affero General Public License |
+ | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
+ | |
+ | CiviCRM is distributed in the hope that it will be useful, but |
+ | WITHOUT ANY WARRANTY; without even the implied warranty of |
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
+ | See the GNU Affero General Public License for more details. |
+ | |
+ | You should have received a copy of the GNU Affero General Public |
+ | License and the CiviCRM Licensing Exception along |
+ | with this program; if not, contact CiviCRM LLC |
+ | at info[AT]civicrm[DOT]org. If you have questions about the |
+ | GNU Affero General Public License or the licensing of CiviCRM, |
+ | see the CiviCRM license FAQ at http://civicrm.org/licensing |
+ +--------------------------------------------------------------------+
+*/
+namespace Civi\CCase;
+
+class Events {
+ /**
+ * Following a change to an activity or case, fire the case-change event.
+ *
+ * @param \Civi\Core\Event\PostEvent $event
+ * @throws \CRM_Core_Exception
+ */
+ public static function fireCaseChange(\Civi\Core\Event\PostEvent $event) {
+ $caseId = NULL;
+ switch ($event->entity) {
+ case 'Activity':
+ if ($event->object->case_id) {
+ $caseId = $event->object->case_id;
+ }
+ break;
+ case 'Case':
+ $caseId = $event->id;
+ break;
+ default:
+ throw new \CRM_Core_Exception("CRM_Case_Listener does not support entity {$event->entity}");
+ }
+
+ if ($caseId) {
+ $analyzer = new \Civi\CCase\Analyzer($caseId);
+ \CRM_Utils_Hook::caseChange($analyzer);
+ }
+ }
+
+ /**
+ * Find any extra listeners declared in XML and pass the event along to them
+ *
+ * @param Event\CaseChangeEvent $event
+ */
+ public static function delegateToXmlListeners(\Civi\CCase\Event\CaseChangeEvent $event) {
+ $p = new \CRM_Case_XMLProcessor_Process();
+ $listeners = $p->getListeners($event->analyzer->getCaseType());
+ foreach ($listeners as $listener) {
+ /** @var $listener \Civi\CCase\CaseChangeListener */
+ $listener->onCaseChange($event);
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+<?php
+namespace Civi\CCase\Exception;
+
+class MultipleActivityException extends \CRM_Core_Exception {
+
+}
\ No newline at end of file
*/
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_caseChange', array('\Civi\CCase\Events', 'delegateToXmlListeners'));
return $dispatcher;
}