From 77927d7049125ad80a9c24c7897766bfe76ef472 Mon Sep 17 00:00:00 2001
From: Jaap Jansma <jaap.jansma@civicoop.org>
Date: Tue, 12 May 2020 12:11:53 +0200
Subject: [PATCH] Improved Contact Summary Tab output so it includes a count.

---
 CHANGELOG.md                                  |  1 +
 .../DataProcessorContactSummaryTab.php        | 62 +++++++++++++++++++
 .../Form/DataProcessorContactSummaryTab.php   | 25 +-------
 3 files changed, 65 insertions(+), 23 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index dfd18087..cc4bf089 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,7 @@
 * Refactored API Output to an Abstract Class so that it is easy for extension developers to develop their own implementation.
 * Added Markup/Html Field Value output field handler.
 * Improved In Memory Dataflow so that joins and filters would work.
+* Improved Contact Summary Tab output so it includes a count.
 
 # Version 1.6.0
 
diff --git a/CRM/Contact/DataProcessorContactSummaryTab.php b/CRM/Contact/DataProcessorContactSummaryTab.php
index f0b5a5e2..c8d609c3 100644
--- a/CRM/Contact/DataProcessorContactSummaryTab.php
+++ b/CRM/Contact/DataProcessorContactSummaryTab.php
@@ -6,6 +6,11 @@
 
 use CRM_Dataprocessor_ExtensionUtil as E;
 use Civi\DataProcessor\Output\UIFormOutputInterface;
+use Civi\DataProcessor\ProcessorType\AbstractProcessorType;
+use Civi\DataProcessor\DataFlow\InMemoryDataFlow\SimpleFilter;
+use Civi\DataProcessor\DataFlow\InMemoryDataFlow;
+use Civi\DataProcessor\DataFlow\SqlDataFlow;
+use Civi\DataProcessor\DataFlow\SqlDataFlow\SimpleWhereClause;
 
 class CRM_Contact_DataProcessorContactSummaryTab implements UIFormOutputInterface {
 
@@ -24,6 +29,7 @@ class CRM_Contact_DataProcessorContactSummaryTab implements UIFormOutputInterfac
     if ($tabsetName != 'civicrm/contact/view') {
       return;
     }
+    $contactId = $context['contact_id'];
 
     $factory = dataprocessor_get_factory();
     // Check whether the factory exists. Usually just after
@@ -61,6 +67,7 @@ class CRM_Contact_DataProcessorContactSummaryTab implements UIFormOutputInterfac
         'id' => 'dataprocessor_' . $dataprocessor['name'],
         'title' => $outputClass->getTitleForUiLink($output, $dataprocessor),
         'icon' => $outputClass->getIconForUiLink($output, $dataprocessor),
+        'count' => $outputClass->getCount($contactId, $output, $dataprocessor),
         'url' => CRM_Utils_System::url('civicrm/dataprocessor/page/contactsummary', array('contact_id' => $context['contact_id'], 'data_processor' => $dataprocessor['name'], 'reset' => 1, 'force' => 1)),
         'class' => '',
       ];
@@ -263,5 +270,60 @@ class CRM_Contact_DataProcessorContactSummaryTab implements UIFormOutputInterfac
     ));
   }
 
+  public function getCount($contact_id, $output, $dataProcessor) {
+    $dataProcessorClass = $this->loadDataProcessor($contact_id, $output, $dataProcessor);
+    return $dataProcessorClass->getDataFlow()->recordCount();
+  }
+
+  /**
+   * @param $contact_id
+   * @param $dataProcessor
+   *
+   * @return \Civi\DataProcessor\ProcessorType\AbstractProcessorType
+   * @throws \Exception
+   */
+  protected function loadDataProcessor($contact_id, $output, $dataProcessor) {
+    $dataProcessorClass = \CRM_Dataprocessor_BAO_DataProcessor::dataProcessorToClass($dataProcessor);
+    return self::alterDataProcessor($contact_id, $output, $dataProcessorClass);
+  }
+
+  /**
+   * @param $contact_id
+   * @param $output
+   * @param AbstractProcessorType $dataProcessorClass
+   *
+   * @return AbstractProcessorType
+   * @throws \Civi\DataProcessor\Exception\DataSourceNotFoundException
+   * @throws \Civi\DataProcessor\Exception\FieldNotFoundException
+   */
+  public static function alterDataProcessor($contact_id, $output, AbstractProcessorType $dataProcessorClass) {
+    list($datasource_name, $field_name) = explode('::', $output['configuration']['contact_id_field'], 2);
+    $dataSource = $dataProcessorClass->getDataSourceByName($datasource_name);
+    if (!$dataSource) {
+      throw new \Civi\DataProcessor\Exception\DataSourceNotFoundException(E::ts("Requires data source '%1' which could not be found. Did you rename or deleted the data source?", array(1=>$datasource_name)));
+    }
+    $fieldSpecification  =  $dataSource->getAvailableFilterFields()->getFieldSpecificationByAlias($field_name);
+    if (!$fieldSpecification) {
+      $fieldSpecification  =  $dataSource->getAvailableFilterFields()->getFieldSpecificationByName($field_name);
+    }
+    if (!$fieldSpecification) {
+      throw new \Civi\DataProcessor\Exception\FieldNotFoundException(E::ts("Requires a field with the name '%1' in the data source '%2'. Did you change the data source type?", array(
+        1 => $field_name,
+        2 => $datasource_name
+      )));
+    }
+
+    $fieldSpecification = clone $fieldSpecification;
+    $fieldSpecification->alias = 'contact_summary_tab_contact_id';
+    $dataFlow = $dataSource->ensureField($fieldSpecification);
+    if ($dataFlow && $dataFlow instanceof SqlDataFlow) {
+      $whereClause = new SimpleWhereClause($dataFlow->getName(), $fieldSpecification->name, '=', $contact_id, $fieldSpecification->type);
+      $dataFlow->addWhereClause($whereClause);
+    } elseif ($dataFlow && $dataFlow instanceof InMemoryDataFlow) {
+      $filterClass = new SimpleFilter($fieldSpecification->name, '=', $contact_id);
+      $dataFlow->addFilter($filterClass);
+    }
+    return $dataProcessorClass;
+  }
 
 }
diff --git a/CRM/Contact/Form/DataProcessorContactSummaryTab.php b/CRM/Contact/Form/DataProcessorContactSummaryTab.php
index 9d666344..ad3df041 100644
--- a/CRM/Contact/Form/DataProcessorContactSummaryTab.php
+++ b/CRM/Contact/Form/DataProcessorContactSummaryTab.php
@@ -5,6 +5,7 @@
  */
 
 use Civi\DataProcessor\DataFlow\SqlDataFlow;
+use Civi\DataProcessor\DataFlow\InMemoryDataFlow;
 use Civi\DataProcessor\DataFlow\SqlDataFlow\SimpleWhereClause;
 use Civi\DataProcessor\Exception\DataSourceNotFoundException;
 use Civi\DataProcessor\Exception\FieldNotFoundException;
@@ -118,28 +119,6 @@ class CRM_Contact_Form_DataProcessorContactSummaryTab extends CRM_DataprocessorS
    */
   protected function alterDataProcessor(AbstractProcessorType $dataProcessorClass) {
     $cid = CRM_Utils_Request::retrieve('contact_id', 'Integer', $this, true);
-    list($datasource_name, $field_name) = explode('::', $this->dataProcessorOutput['configuration']['contact_id_field'], 2);
-    $dataSource = $dataProcessorClass->getDataSourceByName($datasource_name);
-    if (!$dataSource) {
-      throw new DataSourceNotFoundException(E::ts("Requires data source '%1' which could not be found. Did you rename or deleted the data source?", array(1=>$datasource_name)));
-    }
-    $fieldSpecification  =  $dataSource->getAvailableFilterFields()->getFieldSpecificationByAlias($field_name);
-    if (!$fieldSpecification) {
-      $fieldSpecification  =  $dataSource->getAvailableFilterFields()->getFieldSpecificationByName($field_name);
-    }
-    if (!$fieldSpecification) {
-      throw new FieldNotFoundException(E::ts("Requires a field with the name '%1' in the data source '%2'. Did you change the data source type?", array(
-        1 => $field_name,
-        2 => $datasource_name
-      )));
-    }
-
-    $fieldSpecification = clone $fieldSpecification;
-    $fieldSpecification->alias = 'contact_summary_tab_contact_id';
-    $dataFlow = $dataSource->ensureField($fieldSpecification);
-    if ($dataFlow && $dataFlow instanceof SqlDataFlow) {
-      $whereClause = new SimpleWhereClause($dataFlow->getName(), $fieldSpecification->name, '=', $cid, $fieldSpecification->type);
-      $dataFlow->addWhereClause($whereClause);
-    }
+    CRM_Contact_DataProcessorContactSummaryTab::alterDataProcessor($cid, $this->dataProcessorOutput, $dataProcessorClass);
   }
 }
-- 
GitLab