From 0b9bbdbc18c5ac81196095dde610aa5986773dff Mon Sep 17 00:00:00 2001 From: Jens Schuppe Date: Fri, 15 Oct 2021 12:00:08 +0200 Subject: [PATCH] Fix possible recursion during Entity::get() Use plain SQL instead of APIv4 in a function that is called by APIv4 Entity.get to avoid an infinite loop. --- CRM/Contact/BAO/ContactType.php | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/CRM/Contact/BAO/ContactType.php b/CRM/Contact/BAO/ContactType.php index fdf38a1816..a495d7e398 100644 --- a/CRM/Contact/BAO/ContactType.php +++ b/CRM/Contact/BAO/ContactType.php @@ -9,8 +9,6 @@ +--------------------------------------------------------------------+ */ -use Civi\Api4\ContactType; - /** * * @package CRM @@ -871,14 +869,21 @@ WHERE ($subtypeClause)"; $cacheKey = 'all_' . $GLOBALS['tsLocale']; $contactTypes = $cache->get($cacheKey); if ($contactTypes === NULL) { - $contactTypes = (array) ContactType::get(FALSE) - ->setSelect(['id', 'name', 'label', 'description', 'is_active', 'is_reserved', 'image_URL', 'parent_id', 'parent_id:name', 'parent_id:label']) - ->execute()->indexBy('name'); - + $query = CRM_Utils_SQL_Select::from('civicrm_contact_type'); + $dao = CRM_Core_DAO::executeQuery($query->toSQL()); + $contactTypes = array_column($dao->fetchAll(), NULL, 'name'); + $name_options = self::buildOptions('parent_id', 'validate'); + $label_options = self::buildOptions('parent_id', 'get'); foreach ($contactTypes as $id => $contactType) { - $contactTypes[$id]['parent'] = $contactType['parent_id:name']; - $contactTypes[$id]['parent_label'] = $contactType['parent_id:label']; - unset($contactTypes[$id]['parent_id:name'], $contactTypes[$id]['parent_id:label']); + $contactTypes[$id]['parent'] = $contactType['parent_id'] ? $name_options[$contactType['parent_id']] : NULL; + $contactTypes[$id]['parent_label'] = $contactType['parent_id'] ? $label_options[$contactType['parent_id']] : NULL; + // Fix types. + $contactTypes[$id]['id'] = (int) $contactType['id']; + $contactTypes[$id]['parent_id'] = $contactType['parent_id'] ? (int) $contactType['parent_id'] : NULL; + $contactTypes[$id]['is_active'] = (bool) $contactType['is_active']; + $contactTypes[$id]['is_reserved'] = (bool) $contactType['is_reserved']; + $contactTypes[$id]['description'] = $contactType['description'] ?: NULL; + $contactTypes[$id]['image_URL'] = $contactType['image_URL'] ?: NULL; } $cache->set($cacheKey, $contactTypes); } -- 2.25.1