5 * The sequence-listener looks for CiviCase XML tags with "<sequence>". If
6 * a change is made to any record in case-type which uses "<sequence>", then
7 * it attempts to add the next step in the sequence.
9 class SequenceListener
implements CaseChangeListener
{
12 * @var SequenceListener
14 private static $singleton;
18 * Whether to forcibly rebuild the entire container.
19 * @return \Symfony\Component\DependencyInjection\TaggedContainerInterface
21 public static function singleton($reset = FALSE) {
22 if ($reset || self
::$singleton === NULL) {
23 self
::$singleton = new SequenceListener();
25 return self
::$singleton;
29 * @param \Civi\CCase\Event\CaseChangeEvent $event
31 public static function onCaseChange_static(\Civi\CCase\Event\CaseChangeEvent
$event) {
32 self
::singleton()->onCaseChange($event);
36 * @param \Civi\CCase\Event\CaseChangeEvent $event
38 * @throws \CiviCRM_API3_Exception
40 public function onCaseChange(\Civi\CCase\Event\CaseChangeEvent
$event) {
41 /** @var \Civi\CCase\Analyzer $analyzer */
42 $analyzer = $event->analyzer
;
44 $activitySetXML = $this->getSequenceXml($analyzer->getXml());
45 if (!$activitySetXML) {
49 $actTypes = array_flip(\CRM_Core_PseudoConstant
::activityType(TRUE, TRUE, FALSE, 'name'));
50 $actStatuses = array_flip(\CRM_Core_PseudoConstant
::activityStatus('name'));
52 $actIndex = $analyzer->getActivityIndex(array('activity_type_id', 'status_id'));
54 foreach ($activitySetXML->ActivityTypes
->ActivityType
as $actTypeXML) {
55 $actTypeId = $actTypes[(string) $actTypeXML->name
];
56 if (empty($actIndex[$actTypeId])) {
57 // Haven't tried this step yet!
58 $this->createActivity($analyzer, $actTypeXML);
61 elseif (empty($actIndex[$actTypeId][$actStatuses['Completed']])) {
62 // Haven't gotten past this step yet!
67 //CRM-17452 - Close the case only if all the activities are complete
68 $activities = $analyzer->getActivities();
69 foreach ($activities as $activity) {
70 if ($activity['status_id'] != $actStatuses['Completed']) {
75 // OK, the all activities have completed
76 civicrm_api3('Case', 'create', array(
77 'id' => $analyzer->getCaseId(),
78 'status_id' => 'Closed',
84 * Find the ActivitySet which defines the pipeline.
86 * @param \SimpleXMLElement $xml
87 * @return \SimpleXMLElement|NULL
89 public function getSequenceXml($xml) {
90 if ($xml->ActivitySets
&& $xml->ActivitySets
->ActivitySet
) {
91 foreach ($xml->ActivitySets
->ActivitySet
as $activitySetXML) {
92 $seq = (string) $activitySetXML->sequence
;
93 if ($seq && strtolower($seq) == 'true') {
94 if ($activitySetXML->ActivityTypes
&& $activitySetXML->ActivityTypes
->ActivityType
) {
95 return $activitySetXML;
107 * @param Analyzer $analyzer
108 * The case being analyzed -- to which we want to add an activity.
109 * @param \SimpleXMLElement $actXML the <ActivityType> tag which describes the new activity
111 public function createActivity(Analyzer
$analyzer, \SimpleXMLElement
$actXML) {
113 'activity_type_id' => (string) $actXML->name
,
114 'status_id' => 'Scheduled',
115 'activity_date_time' => \CRM_Utils_Time
::getTime('YmdHis'),
116 'case_id' => $analyzer->getCaseId(),
118 $r = civicrm_api3('Activity', 'create', $params);