CRM-18366 Fix contact logging detail to show all related changes & revert all related...
authoreileen <emcnaughton@wikimedia.org>
Wed, 6 Apr 2016 07:51:37 +0000 (19:51 +1200)
committerEileen <eileen@fuzion.co.nz>
Sat, 23 Apr 2016 03:51:13 +0000 (03:51 +0000)
This report switches from a hard-coded list of contact related tables to considering all tables with an FK to civicrm_contact, including entity_tag
group_subscription, batch, financial_item etc. The revert makes the same switch.

Note that with this change a full subset may still not be retrieved - in order to get that you need to enable the changes from CRM-18193 & apply all patches related to that issue (one will build on this)

CRM/Logging/Differ.php
CRM/Logging/ReportDetail.php
CRM/Report/Form/Contact/LoggingDetail.php

index e09eb40532a7fa072768b7d3df35452e1bf55e0c..923629a809c6f8f1d0dcea2640fda14d94329e33 100644 (file)
@@ -169,6 +169,7 @@ WHERE lt.log_conn_id = %1
    * @param int $id
    *
    * @return array
+   * @throws \CRM_Core_Exception
    */
   private function diffsInTableForId($table, $id) {
     $diffs = array();
index 1f4f3c2f3a943598c63c657997f685e69db8fe1f..b30d7065f032b78fd30ca5e7642562f3312bb020 100644 (file)
@@ -47,6 +47,20 @@ class CRM_Logging_ReportDetail extends CRM_Report_Form {
   protected $detail;
   protected $summary;
 
+  /**
+   * Instance of Differ.
+   *
+   * @var CRM_Logging_Differ
+   */
+  protected $differ;
+
+  /**
+   * Array of changes made.
+   *
+   * @var array
+   */
+  protected $diffs = array();
+
   /**
    * Don't display the Add these contacts to Group button.
    *
@@ -98,6 +112,10 @@ class CRM_Logging_ReportDetail extends CRM_Report_Form {
   }
 
   /**
+   * Build query for report.
+   *
+   * We override this to be empty & calculate the rows in the buildRows function.
+   *
    * @param bool $applyLimit
    */
   public function buildQuery($applyLimit = TRUE) {
@@ -112,16 +130,25 @@ class CRM_Logging_ReportDetail extends CRM_Report_Form {
     if (!$this->log_conn_id or !$this->log_date) {
       return;
     }
+    $this->getDiffs();
+    $rows = $this->convertDiffsToRows();
+  }
 
-    if (empty($rows)) {
-
-      $rows = array();
-
-    }
-
-    foreach ($this->tables as $table) {
-      $rows = array_merge($rows, $this->diffsInTable($table));
+  /**
+   * Get the diffs for the report, calculating them if not already done.
+   *
+   * Note that contact details report now uses a more comprehensive method but
+   * the contribution logging details report still uses this.
+   *
+   * @return array
+   */
+  protected function getDiffs() {
+    if (empty($this->diffs)) {
+      foreach ($this->tables as $table) {
+        $this->diffs = array_merge($this->diffs, $this->diffsInTable($table));
+      }
     }
+    return $this->diffs;
   }
 
   /**
@@ -130,21 +157,30 @@ class CRM_Logging_ReportDetail extends CRM_Report_Form {
    * @return array
    */
   protected function diffsInTable($table) {
-    $rows = array();
-
-    $differ = new CRM_Logging_Differ($this->log_conn_id, $this->log_date, $this->interval);
-    $diffs = $differ->diffsInTable($table, $this->cid);
+    $this->setDiffer();
+    return $this->differ->diffsInTable($table, $this->cid);
+  }
 
+  /**
+   * Convert the diffs to row format.
+   *
+   * @return array
+   */
+  protected function convertDiffsToRows() {
     // return early if nothing found
-    if (empty($diffs)) {
-      return $rows;
+    if (empty($this->diffs)) {
+      return array();
     }
 
-    list($titles, $values) = $differ->titlesAndValuesForTable($table);
-
     // populate $rows with only the differences between $changed and $original (skipping certain columns and NULL ↔ empty changes unless raw requested)
-    $skipped = array('contact_id', 'entity_id', 'id');
-    foreach ($diffs as $diff) {
+    $skipped = array('id');
+    foreach ($this->diffs as $diff) {
+      $table = $diff['table'];
+      if (empty($metadata[$table])) {
+        list($metadata[$table]['titles'], $metadata[$table]['values']) = $this->differ->titlesAndValuesForTable($table);
+      }
+      $values = CRM_Utils_Array::value('values', $metadata[$diff['table']], array());
+      $titles = $metadata[$diff['table']]['titles'];
       $field = $diff['field'];
       $from = $diff['from'];
       $to = $diff['to'];
@@ -224,6 +260,55 @@ class CRM_Logging_ReportDetail extends CRM_Report_Form {
     $this->db = $dsn['database'];
   }
 
+  /**
+   * Calculate all the contact related diffs for the change.
+   *
+   * @return array
+   */
+  protected function calculateContactDiffs(){
+    $this->diffs = $this->getAllContactChangesForConnection();
+  }
+
+
+  /**
+   * Get an array of changes made in the mysql connection.
+   *
+   * @return mixed
+   */
+  public function getAllContactChangesForConnection() {
+    if (empty($this->log_conn_id)) {
+      return array();
+    }
+    $this->setDiffer();
+    try {
+      return $this->differ->getAllChangesForConnection($this->tables);
+    }
+    catch (CRM_Core_Exception $e) {
+      CRM_Core_Error::statusBounce(ts($e->getMessage()));
+    }
+  }
+
+  /**
+   * Make sure the differ is defined.
+   */
+  protected function setDiffer() {
+    if (empty($this->differ)) {
+      $this->differ = new CRM_Logging_Differ($this->log_conn_id, $this->log_date, $this->interval);
+    }
+  }
+
+  /**
+   * Set this tables to reflect tables changed in a merge.
+   */
+  protected function setTablesToContactRelatedTables() {
+    $schema = new CRM_Logging_Schema();
+    $this->tables = $schema->getLogTablesForContact();
+    // allow tables to be extended by report hook query objects.
+    // This is a report specific hook. It's unclear how it interacts to / overlaps the main one.
+    // It probably precedes the main one and was never reconciled with it....
+    CRM_Report_BAO_Hook::singleton()->alterLogTables($this, $this->tables);
+  }
+
   /**
    * Revert the changes defined by the parameters.
    */
index aa31272d0b884102c20bdc521b71b1df5bc1fbd8..ebdd08c0747fb8be2943d1a227e49bb2b5db5c86 100644 (file)
@@ -36,23 +36,10 @@ class CRM_Report_Form_Contact_LoggingDetail extends CRM_Logging_ReportDetail {
   /**
    */
   public function __construct() {
-    $logging = new CRM_Logging_Schema();
-    $this->tables[] = 'civicrm_contact';
-    $this->tables = array_merge($this->tables, array_keys($logging->customDataLogTables()));
-    $this->tables[] = 'civicrm_email';
-    $this->tables[] = 'civicrm_phone';
-    $this->tables[] = 'civicrm_im';
-    $this->tables[] = 'civicrm_openid';
-    $this->tables[] = 'civicrm_website';
-    $this->tables[] = 'civicrm_address';
-    $this->tables[] = 'civicrm_note';
-    $this->tables[] = 'civicrm_relationship';
-    $this->tables[] = 'civicrm_activity';
-    $this->tables[] = 'civicrm_case';
-
-    // allow tables to be extended by report hook query objects
-    CRM_Report_BAO_Hook::singleton()->alterLogTables($this, $this->tables);
-
+    $this->log_conn_id = CRM_Utils_Request::retrieve('log_conn_id', 'String');
+    $this->log_date = CRM_Utils_Request::retrieve('log_date', 'String');
+    $this->setTablesToContactRelatedTables();
+    $this->calculateContactDiffs();
     $this->detail = 'logging/contact/detail';
     $this->summary = 'logging/contact/summary';