From: Coleman Watts Date: Mon, 18 Oct 2021 14:54:03 +0000 (-0400) Subject: AllCoreTables - Allow virtual entities to share a DAO class X-Git-Url: https://vcs.fsf.org/?a=commitdiff_plain;h=40ac12d386dd1a9acd934ad397b8c31b5e457f01;p=civicrm-core.git AllCoreTables - Allow virtual entities to share a DAO class Indexes entities by brief name instead of class name, which allows one class to be shared by multiple entities. --- diff --git a/CRM/Core/BAO/EntityTag.php b/CRM/Core/BAO/EntityTag.php index 580729a87c..daa8568faa 100644 --- a/CRM/Core/BAO/EntityTag.php +++ b/CRM/Core/BAO/EntityTag.php @@ -486,13 +486,13 @@ class CRM_Core_BAO_EntityTag extends CRM_Core_DAO_EntityTag { // This is probably fairly mild in terms of helping performance - a case could be made to check if tags // exist before deleting (further down) as delete is a locking action. $entity = CRM_Core_DAO_AllCoreTables::getBriefName(get_class($event->object)); - if (!isset(Civi::$statics[__CLASS__]['tagged_entities'][$entity])) { + if ($entity && !isset(Civi::$statics[__CLASS__]['tagged_entities'][$entity])) { $tableName = CRM_Core_DAO_AllCoreTables::getTableForEntityName($entity); $used_for = CRM_Core_OptionGroup::values('tag_used_for'); Civi::$statics[__CLASS__]['tagged_entities'][$entity] = !empty($used_for[$tableName]) ? $tableName : FALSE; } - if (Civi::$statics[__CLASS__]['tagged_entities'][$entity]) { + if (!empty(Civi::$statics[__CLASS__]['tagged_entities'][$entity])) { CRM_Core_DAO::executeQuery('DELETE FROM civicrm_entity_tag WHERE entity_table = %1 AND entity_id = %2', [1 => [Civi::$statics[__CLASS__]['tagged_entities'][$entity], 'String'], 2 => [$event->object->id, 'Integer']] ); diff --git a/CRM/Core/DAO/AllCoreTables.php b/CRM/Core/DAO/AllCoreTables.php index 6a274847fc..febcb374a8 100644 --- a/CRM/Core/DAO/AllCoreTables.php +++ b/CRM/Core/DAO/AllCoreTables.php @@ -56,17 +56,17 @@ class CRM_Core_DAO_AllCoreTables { /** * (Quasi-Private) Do not call externally (except for unit-testing) * - * @param string $daoName + * @param string $briefName * @param string $className * @param string $tableName * @param string $fields_callback * @param string $links_callback */ - public static function registerEntityType($daoName, $className, $tableName, $fields_callback = NULL, $links_callback = NULL) { - self::$daoToClass[$daoName] = $className; + public static function registerEntityType($briefName, $className, $tableName, $fields_callback = NULL, $links_callback = NULL) { + self::$daoToClass[$briefName] = $className; self::$tables[$tableName] = $className; - self::$entityTypes[$className] = [ - 'name' => $daoName, + self::$entityTypes[$briefName] = [ + 'name' => $briefName, 'class' => $className, 'table' => $tableName, 'fields_callback' => $fields_callback, @@ -76,7 +76,7 @@ class CRM_Core_DAO_AllCoreTables { /** * @return array - * Ex: $result['CRM_Contact_DAO_Contact']['table'] == 'civicrm_contact'; + * Ex: $result['Contact']['table'] == 'civicrm_contact'; */ public static function get() { self::init(); @@ -317,7 +317,8 @@ class CRM_Core_DAO_AllCoreTables { * Ex: 'CRM_Contact_DAO_Contact'. */ public static function getFullName($briefName) { - return self::daoToClass()[$briefName] ?? NULL; + self::init(); + return self::$entityTypes[$briefName]['class'] ?? NULL; } /** @@ -345,12 +346,13 @@ class CRM_Core_DAO_AllCoreTables { /** * Convert the entity name into a table name. * - * @param string $entityBriefName + * @param string $briefName * * @return FALSE|string */ - public static function getTableForEntityName($entityBriefName) { - return self::getTableForClass(self::getFullName($entityBriefName)); + public static function getTableForEntityName($briefName) { + self::init(); + return self::$entityTypes[$briefName]['table']; } /** @@ -361,7 +363,9 @@ class CRM_Core_DAO_AllCoreTables { * @return FALSE|string */ public static function getEntityNameForTable(string $tableName) { - return self::getBriefName(self::getClassForTable($tableName)); + self::init(); + $matches = CRM_Utils_Array::findAll(self::$entityTypes, ['table' => $tableName]); + return $matches ? $matches[0]['name'] : NULL; } /** @@ -456,14 +460,18 @@ class CRM_Core_DAO_AllCoreTables { * * Apply any third-party alterations to the `fields()`. * + * TODO: This function should probably take briefName as the key instead of className + * because the latter is not always unique (e.g. virtual entities) + * * @param string $className * @param string $event * @param mixed $values */ public static function invoke($className, $event, &$values) { self::init(); - if (isset(self::$entityTypes[$className][$event])) { - foreach (self::$entityTypes[$className][$event] as $filter) { + $briefName = self::getBriefName($className); + if (isset(self::$entityTypes[$briefName][$event])) { + foreach (self::$entityTypes[$briefName][$event] as $filter) { $args = [$className, &$values]; \Civi\Core\Resolver::singleton()->call($filter, $args); } diff --git a/Civi/Api4/Service/Schema/SchemaMapBuilder.php b/Civi/Api4/Service/Schema/SchemaMapBuilder.php index 87c2816ab6..d9baef14cd 100644 --- a/Civi/Api4/Service/Schema/SchemaMapBuilder.php +++ b/Civi/Api4/Service/Schema/SchemaMapBuilder.php @@ -58,9 +58,9 @@ class SchemaMapBuilder { */ private function loadTables(SchemaMap $map) { /** @var \CRM_Core_DAO $daoName */ - foreach (AllCoreTables::get() as $daoName => $data) { + foreach (AllCoreTables::get() as $data) { $table = new Table($data['table']); - foreach ($daoName::fields() as $fieldData) { + foreach ($data['class']::fields() as $fieldData) { $this->addJoins($table, $fieldData['name'], $fieldData); } $map->addTable($table); diff --git a/tests/phpunit/CRM/Core/DAO/AllCoreTablesTest.php b/tests/phpunit/CRM/Core/DAO/AllCoreTablesTest.php index 6457a85fb1..612b2c3cf7 100644 --- a/tests/phpunit/CRM/Core/DAO/AllCoreTablesTest.php +++ b/tests/phpunit/CRM/Core/DAO/AllCoreTablesTest.php @@ -216,6 +216,18 @@ class CRM_Core_DAO_AllCoreTablesTest extends CiviUnitTestCase { public function testGetBriefName() { $this->assertEquals('Contact', CRM_Core_DAO_AllCoreTables::getBriefName('CRM_Contact_BAO_Contact')); $this->assertEquals('Contact', CRM_Core_DAO_AllCoreTables::getBriefName('CRM_Contact_DAO_Contact')); + $this->assertNull(CRM_Core_DAO_AllCoreTables::getBriefName('CRM_Core_DAO_XqZy')); + } + + public function testGetFullName() { + $this->assertEquals('CRM_Contact_DAO_Contact', CRM_Core_DAO_AllCoreTables::getFullName('Contact')); + $this->assertNull(CRM_Core_DAO_AllCoreTables::getFullName('XqZy')); + } + + public function testGetEntityNameForTable() { + $this->assertEquals('Contact', CRM_Core_DAO_AllCoreTables::getEntityNameForTable('civicrm_contact')); + $this->assertEquals('RelationshipCache', CRM_Core_DAO_AllCoreTables::getEntityNameForTable('civicrm_relationship_cache')); + $this->assertNull(CRM_Core_DAO_AllCoreTables::getEntityNameForTable('civicrm_invalid_table')); } }