}
}
- // CRM-7353: if nothing altered civicrm_contact, touch it; this will
- // make sure there’s an entry in log_civicrm_contact for this revert
- if (empty($diffs['civicrm_contact'])) {
- $query = "
- SELECT id FROM `{$this->db}`.log_civicrm_contact
- WHERE log_conn_id = %1 AND log_date BETWEEN DATE_SUB(%2, INTERVAL 10 SECOND) AND DATE_ADD(%2, INTERVAL 10 SECOND)
- ORDER BY log_date DESC LIMIT 1
- ";
- $params = array(
- 1 => array($this->log_conn_id, 'String'),
- 2 => array($this->log_date, 'String'),
- );
- $cid = CRM_Core_DAO::singleValueQuery($query, $params);
- if (!$cid) {
- return;
- }
-
- $dao = new CRM_Contact_DAO_Contact();
- $dao->id = $cid;
- if ($dao->find(TRUE)) {
- // CRM-8102: MySQL can’t parse its own dates
- $dao->birth_date = CRM_Utils_Date::isoToMysql($dao->birth_date);
- $dao->deceased_date = CRM_Utils_Date::isoToMysql($dao->deceased_date);
- $dao->save();
- }
- }
}
}
function civicrm_api3_logging_revert($params) {
$schema = new CRM_Logging_Schema();
$reverter = new CRM_Logging_Reverter($params['log_conn_id'], CRM_Utils_Array::value('log_date', $params));
- $reverter->calculateDiffsFromLogConnAndDate($schema->getLogTablesForContact());
+ $tables = !empty($params['tables']) ? (array) $params['tables'] : $schema->getLogTablesForContact();
+ $reverter->calculateDiffsFromLogConnAndDate($tables);
$reverter->revert();
return civicrm_api3_create_success(1);
}
'api.default' => '10 SECOND',
'description' => ts('Used when log_date is passed in'),
);
+
+ $params['tables'] = array(
+ 'title' => ts('Tables to revert'),
+ 'type' => CRM_Utils_Type::T_STRING,
+ 'description' => ts('Tables to revert, if not set all contact-referring entities will be reverted'),
+ );
}
/**
$schema = new CRM_Logging_Schema();
$interval = (empty($params['log_date'])) ? NULL : $params['interval'];
$differ = new CRM_Logging_Differ($params['log_conn_id'], CRM_Utils_Array::value('log_date', $params), $interval);
- return civicrm_api3_create_success($differ->getAllChangesForConnection($schema->getLogTablesForContact()));
+ $tables = !empty($params['tables']) ? (array) $params['tables'] : $schema->getLogTablesForContact();
+ return civicrm_api3_create_success($differ->getAllChangesForConnection($tables));
}
/**
'api.default' => '10 SECOND',
'description' => ts('Used when log_date is passed in'),
);
+ $params['tables'] = array(
+ 'title' => ts('Tables to query'),
+ 'type' => CRM_Utils_Type::T_STRING,
+ 'description' => ts('Tables to query, if not set all contact-referring entities will be queried'),
+ );
}
* Clean up log tables.
*/
protected function tearDown() {
- $this->quickCleanup(array('civicrm_email'));
+ $this->quickCleanup(array('civicrm_email', 'civicrm_address'));
parent::tearDown();
$this->callAPISuccess('Setting', 'create', array('logging' => FALSE));
$schema = new CRM_Logging_Schema();
/**
* Check the triggers were created and look OK.
+ *
+ * @param bool $unique
+ * Is the site configured for unique logging connection IDs per CRM-18193?
*/
protected function checkTriggersCreated($unique) {
$dao = CRM_Core_DAO::executeQuery("SHOW TRIGGERS LIKE 'civicrm_contact'");
$this->callAPISuccessGetCount('Email', array('id' => $email['id']), 0);
}
+ /**
+ * Ensure that a limited list of tables can be reverted.
+ *
+ * In this case ONLY civicrm_address is reverted and we check that email, contact and contribution
+ * entities have not been.
+ *
+ * @throws \Exception
+ */
+ public function testRevertRestrictedTables() {
+
+ CRM_Core_DAO::executeQuery("SET @uniqueID = 'temp name'");
+ $this->callAPISuccessGetValue('Setting', array('name' => 'logging_all_tables_uniquid'), TRUE);
+ $this->callAPISuccess('Setting', 'create', array('logging' => TRUE));
+
+ $contactId = $this->individualCreate(array('address' => array(array('street_address' => '27 Cool way', 'location_type_id' => 1))));
+ $contact = $this->callAPISuccessGetSingle('contact', array('id' => $contactId));
+ $this->assertEquals('Anthony', $contact['first_name']);
+ $this->assertEquals('anthony_anderson@civicrm.org', $contact['email']);
+ $this->assertEquals('27 Cool way', $contact['street_address']);
+
+ CRM_Core_DAO::executeQuery("SET @uniqueID = 'bitty bot bot'");
+ $this->callAPISuccess('Contact', 'create', array(
+ 'id' => $contactId,
+ 'first_name' => 'Dopey',
+ 'address' => array(array('street_address' => '25 Dorky way', 'location_type_id' => 1)),
+ 'email' => array('email' => array('email' => 'dopey@mail.com', 'location_type_id' => 1)),
+ 'api.contribution.create' => array('financial_type_id' => 'Donation', 'receive_date' => 'now', 'total_amount' => 10),
+ )
+ );
+ $contact = $this->callAPISuccessGetSingle('contact', array('id' => $contactId, 'return' => array('first_name', 'email', 'modified_date', 'street_address')));
+ $this->assertEquals('Dopey', $contact['first_name']);
+ $this->assertEquals('dopey@mail.com', $contact['email']);
+ $this->assertEquals('25 Dorky way', $contact['street_address']);
+ $modifiedDate = $contact['modified_date'];
+ // To protect against the modified date not changing due to the updates being too close together.
+ sleep(1);
+ $loggings = $this->callAPISuccess('Logging', 'get', array('log_conn_id' => 'bitty bot bot', 'tables' => array('civicrm_address')));
+ $this->assertEquals('civicrm_address', $loggings['values'][0]['table'], CRM_Core_DAO::executeQuery('SELECT * FROM log_civicrm_address')->toArray());
+ $this->assertEquals(1, $loggings['count'], CRM_Core_DAO::executeQuery('SELECT * FROM log_civicrm_address')->toArray());
+ $this->assertEquals('27 Cool way', $loggings['values'][0]['from']);
+ $this->assertEquals('25 Dorky way', $loggings['values'][0]['to']);
+ $this->callAPISuccess('Logging', 'revert', array('log_conn_id' => 'bitty bot bot', 'tables' => array('civicrm_address')));
+
+ $contact = $this->callAPISuccessGetSingle('contact', array('id' => $contactId, 'return' => array('first_name', 'email', 'modified_date', 'street_address')));
+ $this->assertEquals('Dopey', $contact['first_name']);
+ $this->assertEquals('dopey@mail.com', $contact['email']);
+ $this->assertEquals('27 Cool way', $contact['street_address']);
+ $this->callAPISuccessGetCount('Contribution', array('contact_id' => $contactId), 1);
+ $this->assertTrue(strtotime($modifiedDate) < strtotime($contact['modified_date']));
+ }
+
/**
* Test changes can be reverted.
*/
* @param string $table
* @param string $column
*
- * @return \CRM_Core_DAO|object
+ * @return bool
*/
protected function checkColumnExistsInTable($table, $column) {
$dao = CRM_Core_DAO::executeQuery("SHOW columns FROM {$table} WHERE Field = '{$column}'");