From 8a475c3df95092b5c2c5f0cb2b954a1109acefb3 Mon Sep 17 00:00:00 2001 From: Eileen McNaughton Date: Wed, 21 Jul 2021 18:54:45 +1200 Subject: [PATCH] dev/core#2709 Enable logging for custom data tables with non-standard names --- CRM/Logging/Schema.php | 9 +++++ tests/phpunit/CRM/Logging/LoggingTest.php | 38 +++++++++++++++++-- .../CRMTraits/Custom/CustomDataTrait.php | 5 +-- tests/phpunit/CiviTest/CiviUnitTestCase.php | 28 +++++++++----- 4 files changed, 64 insertions(+), 16 deletions(-) diff --git a/CRM/Logging/Schema.php b/CRM/Logging/Schema.php index 85bd657a6207..ad09e3a32c20 100644 --- a/CRM/Logging/Schema.php +++ b/CRM/Logging/Schema.php @@ -131,6 +131,15 @@ public function __construct() { while ($dao->fetch()) { $this->tables[] = $dao->TABLE_NAME; } + // Get any non standard table names used for custom groups. + // include these BEFORE the hook is called. + $customFieldDAO = CRM_Core_DAO::executeQuery(" + SELECT DISTINCT table_name as TABLE_NAME FROM civicrm_custom_group + where table_name NOT LIKE 'civicrm_%'; + "); + while ($customFieldDAO->fetch()) { + $this->tables[] = $customFieldDAO->TABLE_NAME; + } // do not log temp import, cache, menu and log tables $this->tables = preg_grep('/^civicrm_import_job_/', $this->tables, PREG_GREP_INVERT); diff --git a/tests/phpunit/CRM/Logging/LoggingTest.php b/tests/phpunit/CRM/Logging/LoggingTest.php index 2a92319f5586..050fce542a3d 100644 --- a/tests/phpunit/CRM/Logging/LoggingTest.php +++ b/tests/phpunit/CRM/Logging/LoggingTest.php @@ -6,19 +6,43 @@ */ class CRM_Logging_LoggingTest extends CiviUnitTestCase { + use CRMTraits_Custom_CustomDataTrait; + + /** + * Has the db been set to multilingual. + * + * @var bool + */ + protected $isDBMultilingual = FALSE; + public function tearDown(): void { Civi::settings()->set('logging', FALSE); - CRM_Core_I18n_Schema::makeSinglelingual('en_US'); + if ($this->isDBMultilingual) { + CRM_Core_I18n_Schema::makeSinglelingual('en_US'); + } $logging = new CRM_Logging_Schema(); $logging->dropAllLogTables(); + $this->cleanupCustomGroups(); parent::tearDown(); } + /** + * Check that log tables are created even for non standard custom fields + * tables. + * + * @throws \API_Exception + */ + public function testLoggingNonStandardCustomTableName(): void { + $this->createCustomGroupWithFieldOfType(['table_name' => 'abcd']); + Civi::settings()->set('logging', TRUE); + $this->assertNotEmpty(CRM_Core_DAO::singleValueQuery("SHOW tables LIKE 'log_abcd'")); + } + /** * Test creating logging schema when database is in multilingual mode. */ public function testMultilingualLogging(): void { - CRM_Core_I18n_Schema::makeMultilingual('en_US'); + $this->makeMultilingual(); Civi::settings()->set('logging', TRUE); $value = CRM_Core_DAO::singleValueQuery('SELECT id FROM log_civicrm_contact LIMIT 1', [], FALSE, FALSE); $this->assertNotNull($value, 'Logging not enabled successfully'); @@ -29,7 +53,7 @@ public function testMultilingualLogging(): void { * Also test altering a multilingual table. */ public function testMultilingualAlterSchemaLogging(): void { - CRM_Core_I18n_Schema::makeMultilingual('en_US'); + $this->makeMultilingual(); Civi::settings()->set('logging', TRUE); $logging = new CRM_Logging_Schema(); $value = CRM_Core_DAO::singleValueQuery('SELECT id FROM log_civicrm_contact LIMIT 1', [], FALSE, FALSE); @@ -67,4 +91,12 @@ public function testMultilingualAlterSchemaLogging(): void { ); } + /** + * Convert the database to multilingual mode. + */ + protected function makeMultilingual(): void { + CRM_Core_I18n_Schema::makeMultilingual('en_US'); + $this->isDBMultilingual = TRUE; + } + } diff --git a/tests/phpunit/CRMTraits/Custom/CustomDataTrait.php b/tests/phpunit/CRMTraits/Custom/CustomDataTrait.php index ef904881c664..5811015977b1 100644 --- a/tests/phpunit/CRMTraits/Custom/CustomDataTrait.php +++ b/tests/phpunit/CRMTraits/Custom/CustomDataTrait.php @@ -91,12 +91,11 @@ protected function getCustomFieldColumnName($key) { * @param array $fieldParams * * @throws \API_Exception - * @throws \CRM_Core_Exception */ - public function createCustomGroupWithFieldOfType($groupParams = [], $customFieldType = 'text', $identifier = NULL, $fieldParams = []): void { + public function createCustomGroupWithFieldOfType(array $groupParams = [], string $customFieldType = 'text', ?string $identifier = NULL, array $fieldParams = []): void { $supported = ['text', 'select', 'date', 'checkbox', 'int', 'contact_reference', 'radio', 'multi_country']; if (!in_array($customFieldType, $supported, TRUE)) { - throw new CRM_Core_Exception('we have not yet extracted other custom field types from createCustomFieldsOfAllTypes, Use consistent syntax when you do'); + $this->fail('we have not yet extracted other custom field types from createCustomFieldsOfAllTypes, Use consistent syntax when you do'); } $groupParams['title'] = empty($groupParams['title']) ? $identifier . 'Group with field ' . $customFieldType : $groupParams['title']; $groupParams['name'] = $identifier ?? 'Custom Group'; diff --git a/tests/phpunit/CiviTest/CiviUnitTestCase.php b/tests/phpunit/CiviTest/CiviUnitTestCase.php index 5c46e94887fd..598af30de889 100644 --- a/tests/phpunit/CiviTest/CiviUnitTestCase.php +++ b/tests/phpunit/CiviTest/CiviUnitTestCase.php @@ -1870,16 +1870,7 @@ public function quickCleanup($tablesToTruncate, $dropCustomValueTables = FALSE) throw new \CRM_Core_Exception("CiviUnitTestCase: quickCleanup() is not compatible with useTransaction()"); } if ($dropCustomValueTables) { - - CustomField::get(FALSE)->setSelect(['option_group_id', 'custom_group_id']) - ->addChain('delete_options', OptionGroup::delete() - ->addWhere('id', '=', '$option_group_id') - ) - ->addChain('delete_fields', CustomField::delete() - ->addWhere('id', '=', '$id') - )->execute(); - - CustomGroup::delete(FALSE)->addWhere('id', '>', 0)->execute(); + $this->cleanupCustomGroups(); // Reset autoincrement too. $tablesToTruncate[] = 'civicrm_custom_group'; $tablesToTruncate[] = 'civicrm_custom_field'; @@ -3878,4 +3869,21 @@ protected function deleteNonDefaultRelationshipTypes(): void { ])->execute(); } + /** + * Delete any existing custom data groups. + * + * @throws \API_Exception + */ + protected function cleanupCustomGroups(): void { + CustomField::get(FALSE)->setSelect(['option_group_id', 'custom_group_id']) + ->addChain('delete_options', OptionGroup::delete() + ->addWhere('id', '=', '$option_group_id') + ) + ->addChain('delete_fields', CustomField::delete() + ->addWhere('id', '=', '$id') + )->execute(); + + CustomGroup::delete(FALSE)->addWhere('id', '>', 0)->execute(); + } + }