From: Eileen McNaughton Date: Sat, 1 Jul 2023 04:21:01 +0000 (-0700) Subject: Fix apiv4 bug on custom fields with spaces in name X-Git-Url: https://vcs.fsf.org/?a=commitdiff_plain;h=66f087187f0e2c94d1cf60a5f25cb67401953bf6;p=civicrm-core.git Fix apiv4 bug on custom fields with spaces in name --- diff --git a/Civi/Api4/Query/Api4Query.php b/Civi/Api4/Query/Api4Query.php index 65fc736945..15f7050cf3 100644 --- a/Civi/Api4/Query/Api4Query.php +++ b/Civi/Api4/Query/Api4Query.php @@ -93,7 +93,7 @@ abstract class Api4Query { $result = []; foreach ($this->selectAliases as $alias => $expr) { $returnName = $alias; - $alias = str_replace('.', '_', $alias); + $alias = str_replace(['.', ' '], '_', $alias); $result[$returnName] = property_exists($query, $alias) ? $query->$alias : NULL; } $results[] = $result; diff --git a/Civi/Api4/Query/Api4SelectQuery.php b/Civi/Api4/Query/Api4SelectQuery.php index 9002d6b44c..26d09e1897 100644 --- a/Civi/Api4/Query/Api4SelectQuery.php +++ b/Civi/Api4/Query/Api4SelectQuery.php @@ -159,7 +159,7 @@ class Api4SelectQuery extends Api4Query { ], ['custom_group' => 'custom_group']); $customSelect = []; foreach ($customGroups as $groupName) { - $customSelect[] = "$groupName.*"; + $customSelect[] = str_replace([' '], '_', $groupName) . '.*'; } array_splice($select, $customStar, 1, $customSelect); } diff --git a/tests/phpunit/api/v4/Custom/ContactCustomJoinTest.php b/tests/phpunit/api/v4/Custom/ContactCustomJoinTest.php index 99f20fbf34..850fd8473f 100644 --- a/tests/phpunit/api/v4/Custom/ContactCustomJoinTest.php +++ b/tests/phpunit/api/v4/Custom/ContactCustomJoinTest.php @@ -32,22 +32,56 @@ class ContactCustomJoinTest extends CustomTestBase { /** * Add test to ensure that in the very unusual and not really supported situation where there is a space in the * custom group machine name. This is not supported but has been seen in the wild and as such we have this test to lock in the fix for dev/mail#103 + * + * @throws \CRM_Core_Exception */ - public function testContactCustomJoin() { + public function testContactCustomJoin(): void { $customGroup = CustomGroup::create()->setValues([ 'name' => 'D - Identification_20', 'table_name' => 'civicrm_value_demographics', 'title' => 'D - Identification', 'extends' => 'Individual', ])->execute(); + CustomGroup::create()->setValues([ + 'name' => 'other', + 'title' => 'other', + 'extends' => 'Individual', + ])->execute(); \CRM_Core_DAO::executeQuery("UPDATE civicrm_custom_group SET name = 'D - Identification_20' WHERE id = %1", [1 => [$customGroup[0]['id'], 'Integer']]); $customField = CustomField::create()->setValues([ 'label' => 'Test field', + 'name' => 'test field', 'custom_group_id' => $customGroup[0]['id'], 'html_type' => 'Text', 'data_type' => 'String', ])->execute(); - Contact::get()->addSelect('*')->addSelect('custom.*')->execute(); + \CRM_Core_DAO::executeQuery("UPDATE civicrm_custom_field SET name = 'D - Identification_20' WHERE id = %1", [1 => [$customField[0]['id'], 'Integer']]); + CustomField::create()->setValues([ + 'label' => 'other', + 'name' => 'other', + 'custom_group_id:name' => 'other', + 'html_type' => 'Text', + 'data_type' => 'String', + ])->execute(); + $contactID = Contact::create()->setValues([ + 'contact_type' => 'Individual', + 'first_name' => 'Ben', + 'other.other' => 'other', + 'D - Identification_20.D - Identification_20' => 10, + ])->execute()->first()['id']; + $this->assertEquals(10, Contact::get()->addSelect('*') + ->addSelect('D - Identification_20.D - Identification_20') + ->addWhere('id', '=', $contactID) + ->execute()->first()['D - Identification_20.D - Identification_20']); + + // Test that calling a get with custom.* does not fatal. + // Ideally we would also check it returns our field - but so far I haven't + // figured out how to make it do that - so this maintains the prior level of cover. + Contact::get() + ->addSelect('*') + ->addSelect('custom.*') + ->addWhere('id', '=', $contactID) + ->execute()->first(); } /**