Later I expect to add more parameters & deal with situation when log_date is not passed
return array($titles, $values);
}
+ /**
+ * Get all changes made in the connection.
+ *
+ * @param array $tables
+ * Array of tables to inspect.
+ *
+ * @return array
+ */
+ public function getAllChangesForConnection($tables) {
+ $params = array(1 => array($this->log_conn_id, 'String'));
+ foreach ($tables as $table) {
+ if (empty($sql)) {
+ $sql = " SELECT '{$table}' as table_name, id FROM {$this->db}.log_{$table} WHERE log_conn_id = %1";
+ }
+ else {
+ $sql .= " UNION SELECT '{$table}' as table_name, id FROM {$this->db}.log_{$table} WHERE log_conn_id = %1";
+ }
+ }
+ $diffs = array();
+ $dao = CRM_Core_DAO::executeQuery($sql, $params);
+ while ($dao->fetch()) {
+ if (empty($this->log_date)) {
+ $this->log_date = CRM_Core_DAO::singleValueQuery("SELECT log_date FROM {$this->db}.log_{$table} WHERE log_conn_id = %1 LIMIT 1", $params);
+ }
+ $diffs = array_merge($diffs, $this->diffsInTableForId($dao->table_name, $dao->id));
+ }
+ return $diffs;
+ }
+
}
*/
protected function revert() {
$reverter = new CRM_Logging_Reverter($this->log_conn_id, $this->log_date);
- $reverter->revert($this->tables);
+ $reverter->calculateDiffsFromLogConnAndDate($this->tables);
+ $reverter->revert();
CRM_Core_Session::setStatus(ts('The changes have been reverted.'), ts('Reverted'), 'success');
if ($this->cid) {
CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/contact/view', "reset=1&selectedChild=log&cid={$this->cid}", FALSE, NULL, FALSE));
private $log_conn_id;
private $log_date;
+ /**
+ * The diffs to be reverted.
+ *
+ * @var array
+ */
+ private $diffs = array();
+
/**
* Class constructor.
*
}
/**
- * Revert changes in the array of diffs in $this->diffs.
*
- * @param $tables
+ * Calculate a set of diffs based on the connection_id and changes at a close time.
+ *
+ * @param array $tables
+ */
+ public function calculateDiffsFromLogConnAndDate($tables) {
+ $differ = new CRM_Logging_Differ($this->log_conn_id, $this->log_date);
+ $this->diffs = $differ->diffsInTables($tables);
+ }
+
+ public function setDiffs($diffs) {
+ $this->diffs = $diffs;
+ }
+
+ /**
+ * Revert changes in the array of diffs in $this->diffs.
*/
- public function revert($tables) {
+ public function revert() {
// get custom data tables, columns and types
$ctypes = array();
$ctypes[$dao->table_name][$dao->column_name] = $dao->data_type;
}
- $differ = new CRM_Logging_Differ($this->log_conn_id, $this->log_date);
- $diffs = $differ->diffsInTables($tables);
-
+ $diffs = $this->diffs;
$deletes = array();
$reverts = array();
foreach ($diffs as $table => $changes) {
}
}
+ /**
+ * Get all the log tables that reference civicrm_contact.
+ *
+ * Note that it might make sense to wrap this in a getLogTablesForEntity
+ * but this is the only entity currently available...
+ */
+ public function getLogTablesForContact() {
+ $tables = array_keys(CRM_Dedupe_Merger::cidRefs());
+ return array_intersect($tables, $this->tables);
+ }
+
}
--- /dev/null
+<?php
+/*
+ +--------------------------------------------------------------------+
+ | CiviCRM version 4.7 |
+ +--------------------------------------------------------------------+
+ | Copyright CiviCRM LLC (c) 2004-2015 |
+ +--------------------------------------------------------------------+
+ | 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 |
+ +--------------------------------------------------------------------+
+ */
+
+/**
+ * This api exposes functionality for interacting with the logging functionality.
+ *
+ * @package CiviCRM_APIv3
+ */
+
+/**
+ * Revert a log change.
+ *
+ * @param array $params
+ *
+ * @return array
+ * API Success Array
+ * @throws \API_Exception
+ * @throws \Civi\API\Exception\UnauthorizedException
+ */
+function civicrm_api3_logging_revert($params) {
+ $schema = new CRM_Logging_Schema();
+ $reverter = new CRM_Logging_Reverter($params['log_conn_id'], $params['log_date']);
+ $reverter->calculateDiffsFromLogConnAndDate($schema->getLogTablesForContact());
+ $reverter->revert();
+ return civicrm_api3_create_success(1);
+}
--- /dev/null
+<?php
+/**
+ * Test Generated example demonstrating the Logging.revert API.
+ *
+ * @return array
+ * API result array
+ */
+function logging_revert_example() {
+ $params = array(
+ 'log_conn_id' => 'woot',
+ 'log_date' => '2016-04-05 23:52:59',
+ );
+
+ try{
+ $result = civicrm_api3('Logging', 'revert', $params);
+ }
+ catch (CiviCRM_API3_Exception $e) {
+ // Handle error here.
+ $errorMessage = $e->getMessage();
+ $errorCode = $e->getErrorCode();
+ $errorData = $e->getExtraParams();
+ return array(
+ 'error' => $errorMessage,
+ 'error_code' => $errorCode,
+ 'error_data' => $errorData,
+ );
+ }
+
+ return $result;
+}
+
+/**
+ * Function returns array of result expected from previous function.
+ *
+ * @return array
+ * API result array
+ */
+function logging_revert_expectedresult() {
+
+ $expectedResult = array(
+ 'is_error' => 0,
+ 'version' => 3,
+ 'count' => 1,
+ 'values' => 1,
+ );
+
+ return $expectedResult;
+}
+
+/*
+* This example has been generated from the API test suite.
+* The test that created it is called "/Users/emcnaughton/buildkit/build/dmaster/sites/all/modules/civicrm/tests/phpunit/api/v3/LoggingTest.php"
+* and can be found at:
+* https://github.com/civicrm/civicrm-core/blob/master/tests/phpunit/api/v3/Revert
+*
+* You can see the outcome of the API tests at
+* https://test.civicrm.org/job/CiviCRM-master-git/
+*
+* To Learn about the API read
+* http://wiki.civicrm.org/confluence/display/CRMDOC/Using+the+API
+*
+* Browse the api on your own site with the api explorer
+* http://MYSITE.ORG/path/to/civicrm/api
+*
+* Read more about testing here
+* http://wiki.civicrm.org/confluence/display/CRM/Testing
+*
+* API Standards documentation:
+* http://wiki.civicrm.org/confluence/display/CRM/API+Architecture+Standards
+*/
$smarty->assign('result', $result);
$smarty->assign('action', $action);
- if (file_exists('../tests/templates/documentFunction.tpl')) {
- if (!is_dir("../api/v3/examples/$entity")) {
- mkdir("../api/v3/examples/$entity");
+ global $civicrm_root;
+ if (file_exists($civicrm_root . '/tests/templates/documentFunction.tpl')) {
+ if (!is_dir($civicrm_root . '/api/v3/examples/$entity')) {
+ mkdir($civicrm_root . '/api/v3/examples/$entity');
}
- $f = fopen("../api/v3/examples/$entity/$exampleName.php", "w+b");
- fwrite($f, $smarty->fetch('../tests/templates/documentFunction.tpl'));
+ $f = fopen($civicrm_root . "/api/v3/examples/$entity/$exampleName.php", "w+b");
+ fwrite($f, $smarty->fetch($civicrm_root . '/tests/templates/documentFunction.tpl'));
fclose($f);
}
}
");
}
+ /**
+ * Test changes can be reverted.
+ */
+ public function testRevert() {
+ $contactId = $this->individualCreate();
+ $this->callAPISuccess('Setting', 'create', array('logging' => TRUE));
+ CRM_Core_DAO::executeQuery("SET @uniqueID = 'woot'");
+ $timeStamp = date('Y-m-d H:i:s');
+ $this->callAPISuccess('Contact', 'create', array(
+ 'id' => $contactId,
+ 'first_name' => 'Dopey',
+ 'api.email.create' => array('email' => 'dopey@mail.com'))
+ );
+ $email = $this->callAPISuccessGetSingle('email', array('email' => 'dopey@mail.com'));
+ $this->callAPIAndDocument('Logging', 'revert', array('log_conn_id' => 'woot', 'log_date' => $timeStamp), __FILE__, 'Revert');
+ $this->assertEquals('Anthony', $this->callAPISuccessGetValue('contact', array('id' => $contactId, 'return' => 'first_name')));
+ $this->callAPISuccessGetCount('Email', array('id' => $email['id']), 0);
+ }
+
}
'System',
'Setting',
'Payment',
+ 'Logging',
);
$this->toBeImplemented['create'] = array(
'Cxn',
'Payment',
'Order',
'SavedSearch', //work fine in local
+ 'Logging',
);
$this->toBeImplemented['delete'] = array(
'Cxn',
'CustomValue',
'Setting',
'User',
+ 'Logging',
);
if ($sequential === TRUE) {
return $entitiesWithout;
'Extension',
'ReportTemplate',
'System',
+ 'Logging',
);
if ($sequential === TRUE) {
return $entitiesWithoutGet;
'MailingContact',
'SystemLog',
//skip this because it doesn't make sense to update logs,
+ 'Logging',
);
if ($sequential === TRUE) {
return $entitiesWithout;