First commit
This commit is contained in:
commit
c6e2478c40
13918 changed files with 2303184 additions and 0 deletions
365
sites/all/modules/civicrm/CRM/Logging/ReportDetail.php
Normal file
365
sites/all/modules/civicrm/CRM/Logging/ReportDetail.php
Normal file
|
@ -0,0 +1,365 @@
|
|||
<?php
|
||||
/*
|
||||
+--------------------------------------------------------------------+
|
||||
| CiviCRM version 4.7 |
|
||||
+--------------------------------------------------------------------+
|
||||
| Copyright CiviCRM LLC (c) 2004-2017 |
|
||||
+--------------------------------------------------------------------+
|
||||
| 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 |
|
||||
+--------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @package CRM
|
||||
* @copyright CiviCRM LLC (c) 2004-2017
|
||||
*/
|
||||
class CRM_Logging_ReportDetail extends CRM_Report_Form {
|
||||
protected $cid;
|
||||
|
||||
/**
|
||||
* Other contact ID.
|
||||
*
|
||||
* This would be set if we are viewing a merge of 2 contacts.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $oid;
|
||||
protected $db;
|
||||
protected $log_conn_id;
|
||||
protected $log_date;
|
||||
protected $raw;
|
||||
protected $tables = array();
|
||||
protected $interval = '10 SECOND';
|
||||
|
||||
protected $altered_name;
|
||||
protected $altered_by;
|
||||
protected $altered_by_id;
|
||||
|
||||
// detail/summary report ids
|
||||
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.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $_add2groupSupported = FALSE;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
|
||||
$this->storeDB();
|
||||
|
||||
$this->parsePropertiesFromUrl();
|
||||
|
||||
parent::__construct();
|
||||
|
||||
CRM_Utils_System::resetBreadCrumb();
|
||||
$breadcrumb = array(
|
||||
array(
|
||||
'title' => ts('Home'),
|
||||
'url' => CRM_Utils_System::url(),
|
||||
),
|
||||
array(
|
||||
'title' => ts('CiviCRM'),
|
||||
'url' => CRM_Utils_System::url('civicrm', 'reset=1'),
|
||||
),
|
||||
array(
|
||||
'title' => ts('View Contact'),
|
||||
'url' => CRM_Utils_System::url('civicrm/contact/view', "reset=1&cid={$this->cid}"),
|
||||
),
|
||||
array(
|
||||
'title' => ts('Search Results'),
|
||||
'url' => CRM_Utils_System::url('civicrm/contact/search', "force=1"),
|
||||
),
|
||||
);
|
||||
CRM_Utils_System::appendBreadCrumb($breadcrumb);
|
||||
|
||||
if (CRM_Utils_Request::retrieve('revert', 'Boolean')) {
|
||||
$this->revert();
|
||||
}
|
||||
|
||||
$this->_columnHeaders = array(
|
||||
'field' => array('title' => ts('Field')),
|
||||
'from' => array('title' => ts('Changed From')),
|
||||
'to' => array('title' => ts('Changed To')),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Build rows from query.
|
||||
*
|
||||
* @param string $sql
|
||||
* @param array $rows
|
||||
*/
|
||||
public function buildRows($sql, &$rows) {
|
||||
// safeguard for when there aren’t any log entries yet
|
||||
if (!$this->log_conn_id && !$this->log_date) {
|
||||
return;
|
||||
}
|
||||
$this->getDiffs();
|
||||
$rows = $this->convertDiffsToRows();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $table
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function diffsInTable($table) {
|
||||
$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($this->diffs)) {
|
||||
return array();
|
||||
}
|
||||
|
||||
// populate $rows with only the differences between $changed and $original (skipping certain columns and NULL ↔ empty changes unless raw requested)
|
||||
$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, $diff['log_date']);
|
||||
}
|
||||
$values = CRM_Utils_Array::value('values', $metadata[$diff['table']], array());
|
||||
$titles = $metadata[$diff['table']]['titles'];
|
||||
$field = $diff['field'];
|
||||
$from = $diff['from'];
|
||||
$to = $diff['to'];
|
||||
|
||||
if ($this->raw) {
|
||||
$field = "$table.$field";
|
||||
}
|
||||
else {
|
||||
if (in_array($field, $skipped)) {
|
||||
continue;
|
||||
}
|
||||
// $differ filters out === values; for presentation hide changes like 42 → '42'
|
||||
if ($from == $to) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// special-case for multiple values. Also works for CRM-7251: preferred_communication_method
|
||||
if ((substr($from, 0, 1) == CRM_Core_DAO::VALUE_SEPARATOR &&
|
||||
substr($from, -1, 1) == CRM_Core_DAO::VALUE_SEPARATOR) ||
|
||||
(substr($to, 0, 1) == CRM_Core_DAO::VALUE_SEPARATOR &&
|
||||
substr($to, -1, 1) == CRM_Core_DAO::VALUE_SEPARATOR)
|
||||
) {
|
||||
$froms = $tos = array();
|
||||
foreach (explode(CRM_Core_DAO::VALUE_SEPARATOR, trim($from, CRM_Core_DAO::VALUE_SEPARATOR)) as $val) {
|
||||
$froms[] = CRM_Utils_Array::value($val, $values[$field]);
|
||||
}
|
||||
foreach (explode(CRM_Core_DAO::VALUE_SEPARATOR, trim($to, CRM_Core_DAO::VALUE_SEPARATOR)) as $val) {
|
||||
$tos[] = CRM_Utils_Array::value($val, $values[$field]);
|
||||
}
|
||||
$from = implode(', ', array_filter($froms));
|
||||
$to = implode(', ', array_filter($tos));
|
||||
}
|
||||
|
||||
if (isset($values[$field][$from])) {
|
||||
$from = $values[$field][$from];
|
||||
}
|
||||
if (isset($values[$field][$to])) {
|
||||
$to = $values[$field][$to];
|
||||
}
|
||||
if (isset($titles[$field])) {
|
||||
$field = $titles[$field];
|
||||
}
|
||||
if ($diff['action'] == 'Insert') {
|
||||
$from = '';
|
||||
}
|
||||
if ($diff['action'] == 'Delete') {
|
||||
$to = '';
|
||||
}
|
||||
}
|
||||
|
||||
$rows[] = array('field' => $field . " (id: {$diff['id']})", 'from' => $from, 'to' => $to);
|
||||
}
|
||||
|
||||
return $rows;
|
||||
}
|
||||
|
||||
public function buildQuickForm() {
|
||||
parent::buildQuickForm();
|
||||
|
||||
$this->assign('whom_url', CRM_Utils_System::url('civicrm/contact/view', "reset=1&cid={$this->cid}"));
|
||||
$this->assign('who_url', CRM_Utils_System::url('civicrm/contact/view', "reset=1&cid={$this->altered_by_id}"));
|
||||
$this->assign('whom_name', $this->altered_name);
|
||||
$this->assign('who_name', $this->altered_by);
|
||||
|
||||
$this->assign('log_date', CRM_Utils_Date::mysqlToIso($this->log_date));
|
||||
|
||||
$q = "reset=1&log_conn_id={$this->log_conn_id}&log_date={$this->log_date}";
|
||||
if ($this->oid) {
|
||||
$q .= '&oid=' . $this->oid;
|
||||
}
|
||||
$this->assign('revertURL', CRM_Report_Utils_Report::getNextUrl($this->detail, "$q&revert=1", FALSE, TRUE));
|
||||
$this->assign('revertConfirm', ts('Are you sure you want to revert all changes?'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the dsn for the logging database in $this->db.
|
||||
*/
|
||||
protected function storeDB() {
|
||||
$dsn = defined('CIVICRM_LOGGING_DSN') ? DB::parseDSN(CIVICRM_LOGGING_DSN) : DB::parseDSN(CIVICRM_DSN);
|
||||
$this->db = $dsn['database'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate all the contact related diffs for the change.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
protected function revert() {
|
||||
$reverter = new CRM_Logging_Reverter($this->log_conn_id, $this->log_date);
|
||||
$reverter->calculateDiffsFromLogConnAndDate($this->tables);
|
||||
$reverter->revert();
|
||||
CRM_Core_Session::setStatus(ts('The changes have been reverted.'), ts('Reverted'), 'success');
|
||||
if ($this->cid) {
|
||||
if ($this->oid) {
|
||||
CRM_Utils_System::redirect(CRM_Utils_System::url(
|
||||
'civicrm/contact/merge',
|
||||
"reset=1&cid={$this->cid}&oid={$this->oid}",
|
||||
FALSE,
|
||||
NULL,
|
||||
FALSE)
|
||||
);
|
||||
}
|
||||
else {
|
||||
CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/contact/view', "reset=1&selectedChild=log&cid={$this->cid}", FALSE, NULL, FALSE));
|
||||
}
|
||||
}
|
||||
else {
|
||||
CRM_Utils_System::redirect(CRM_Report_Utils_Report::getNextUrl($this->summary, 'reset=1', FALSE, TRUE));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the properties that might be in the URL.
|
||||
*/
|
||||
protected function parsePropertiesFromUrl() {
|
||||
$this->log_conn_id = CRM_Utils_Request::retrieve('log_conn_id', 'String');
|
||||
$this->log_date = CRM_Utils_Request::retrieve('log_date', 'String');
|
||||
$this->cid = CRM_Utils_Request::retrieve('cid', 'Integer');
|
||||
$this->raw = CRM_Utils_Request::retrieve('raw', 'Boolean');
|
||||
|
||||
$this->altered_name = CRM_Utils_Request::retrieve('alteredName', 'String');
|
||||
$this->altered_by = CRM_Utils_Request::retrieve('alteredBy', 'String');
|
||||
$this->altered_by_id = CRM_Utils_Request::retrieve('alteredById', 'Integer');
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue