From c1bf8a765de607abae4728fced38758298660e77 Mon Sep 17 00:00:00 2001 From: colemanw Date: Fri, 21 Jul 2023 11:13:42 -0400 Subject: [PATCH] DAO - Add 'fillValues' utility function to facilitate looking up fields from an incomplete record. --- CRM/ACL/BAO/ACL.php | 7 ++--- CRM/Core/DAO.php | 42 ++++++++++++++++++++++++++++++ CRM/Core/PseudoConstant.php | 1 + tests/phpunit/CRM/Core/DAOTest.php | 11 ++++++++ 4 files changed, 56 insertions(+), 5 deletions(-) diff --git a/CRM/ACL/BAO/ACL.php b/CRM/ACL/BAO/ACL.php index d8b84cec67..2c8e39a67e 100644 --- a/CRM/ACL/BAO/ACL.php +++ b/CRM/ACL/BAO/ACL.php @@ -541,11 +541,8 @@ SELECT g.* } public static function getObjectIdOptions($context, $params): array { - $tableName = $params['values']['object_table'] ?? NULL; - // Look up object_table if not known - if (!$tableName && !empty($params['values']['id'])) { - $tableName = CRM_Core_DAO::getFieldValue('CRM_ACL_DAO_ACL', $params['values']['id'], 'object_table'); - } + $values = self::fillValues($params['values'], ['object_table']); + $tableName = $values['object_table']; if (!$tableName) { return []; } diff --git a/CRM/Core/DAO.php b/CRM/Core/DAO.php index d39791f0c7..f4ae7c3d8c 100644 --- a/CRM/Core/DAO.php +++ b/CRM/Core/DAO.php @@ -3354,4 +3354,46 @@ SELECT contact_id return !defined("$daoName::COMPONENT") || CRM_Core_Component::isEnabled($daoName::COMPONENT); } + /** + * Given an incomplete record, attempt to fill missing field values from the database + */ + public static function fillValues(array $existingValues, $fieldsToRetrieve): array { + $idField = static::$_primaryKey[0]; + // Ensure primary key is set + $existingValues += [$idField => NULL]; + // It's hard to look things up without an ID! Check for another unique field to use: + if (!$existingValues[$idField] && is_callable([static::class, 'indices'])) { + foreach (static::indices(FALSE) as $index) { + if (!empty($index['unique']) && count($index['field']) === 1 && !empty($existingValues[$index['field'][0]])) { + $idField = $index['field'][0]; + } + } + } + $idValue = $existingValues[$idField] ?? NULL; + foreach ($fieldsToRetrieve as $fieldName) { + if (!array_key_exists($fieldName, $existingValues)) { + $fieldMeta = static::getSupportedFields()[$fieldName] ?? ['type' => NULL]; + $existingValues[$fieldName] = NULL; + if ($idValue) { + $existingValues[$fieldName] = self::getFieldValue(static::class, $idValue, $fieldName, $idField); + } + if (isset($existingValues[$fieldName])) { + if (!empty($fieldMeta['serialize'])) { + self::unSerializeField($existingValues[$fieldName], $fieldMeta['serialize']); + } + elseif ($fieldMeta['type'] === CRM_Utils_Type::T_BOOLEAN) { + $existingValues[$fieldName] = (bool) $existingValues[$fieldName]; + } + elseif ($fieldMeta['type'] === CRM_Utils_Type::T_INT) { + $existingValues[$fieldName] = (int) $existingValues[$fieldName]; + } + elseif ($fieldMeta['type'] === CRM_Utils_Type::T_FLOAT) { + $existingValues[$fieldName] = (float) $existingValues[$fieldName]; + } + } + } + } + return $existingValues; + } + } diff --git a/CRM/Core/PseudoConstant.php b/CRM/Core/PseudoConstant.php index ce077fb601..46073b964a 100644 --- a/CRM/Core/PseudoConstant.php +++ b/CRM/Core/PseudoConstant.php @@ -193,6 +193,7 @@ class CRM_Core_PseudoConstant { 'fresh' => FALSE, 'context' => $context, 'condition' => [], + 'values' => [], ]; $entity = CRM_Core_DAO_AllCoreTables::getBriefName($daoName); diff --git a/tests/phpunit/CRM/Core/DAOTest.php b/tests/phpunit/CRM/Core/DAOTest.php index a3d9969699..ea4c58285d 100644 --- a/tests/phpunit/CRM/Core/DAOTest.php +++ b/tests/phpunit/CRM/Core/DAOTest.php @@ -602,4 +602,15 @@ class CRM_Core_DAOTest extends CiviUnitTestCase { $this->assertNull($dao->expired_date); } + public function testFillValues() { + $label = uniqid(); + $saved = CRM_Contact_BAO_SavedSearch::writeRecord([ + 'label' => $label, + ]); + $onlyId = ['id' => $saved->id]; + $onlyName = ['name' => $saved->name]; + $this->assertEquals($label, CRM_Contact_BAO_SavedSearch::fillValues($onlyId, ['label'])['label']); + $this->assertEquals($label, CRM_Contact_BAO_SavedSearch::fillValues($onlyName, ['label'])['label']); + } + } -- 2.25.1