From 2ddaad96338ff0b738d2c396d30eb25be8be71ea Mon Sep 17 00:00:00 2001 From: Coleman Watts Date: Thu, 24 Jun 2021 16:09:33 -0400 Subject: [PATCH] APIv4 - Store entity info in metadata cache Note that this caches the info returned by the generic function in `AbstractEntity::getInfo()` and some entities override that function. However the overrides generally call the parent and do not perform any expensive computations of their own, so this seems like the best spot to add caching. --- Civi/Api4/Generic/AbstractEntity.php | 62 +++++++++++++++------------- 1 file changed, 34 insertions(+), 28 deletions(-) diff --git a/Civi/Api4/Generic/AbstractEntity.php b/Civi/Api4/Generic/AbstractEntity.php index 5dec8467b8..1e17d1337f 100644 --- a/Civi/Api4/Generic/AbstractEntity.php +++ b/Civi/Api4/Generic/AbstractEntity.php @@ -132,35 +132,41 @@ abstract class AbstractEntity { * @return array */ public static function getInfo() { - $info = [ - 'name' => static::getEntityName(), - 'title' => static::getEntityTitle(), - 'title_plural' => static::getEntityTitle(TRUE), - 'type' => [self::stripNamespace(get_parent_class(static::class))], - 'paths' => static::getEntityPaths(), - 'class' => static::class, - 'id_field' => 'id', - // Entities without a @searchable annotation will default to secondary, - // which makes them visible in SearchKit but not at the top of the list. - 'searchable' => 'secondary', - ]; - // Add info for entities with a corresponding DAO - $dao = \CRM_Core_DAO_AllCoreTables::getFullName($info['name']); - if ($dao) { - $info['paths'] = $dao::getEntityPaths(); - $info['icon'] = $dao::$_icon; - $info['label_field'] = $dao::$_labelField; - $info['dao'] = $dao; - } - foreach (ReflectionUtils::getTraits(static::class) as $trait) { - $info['type'][] = self::stripNamespace($trait); - } - $reflection = new \ReflectionClass(static::class); - $info = array_merge($info, ReflectionUtils::getCodeDocs($reflection, NULL, ['entity' => $info['name']])); - if ($dao) { - $info['description'] = $dao::getEntityDescription() ?? $info['description'] ?? NULL; + $cache = \Civi::cache('metadata'); + $entityName = static::getEntityName(); + $info = $cache->get("api4.$entityName.info"); + if (!$info) { + $info = [ + 'name' => $entityName, + 'title' => static::getEntityTitle(), + 'title_plural' => static::getEntityTitle(TRUE), + 'type' => [self::stripNamespace(get_parent_class(static::class))], + 'paths' => static::getEntityPaths(), + 'class' => static::class, + 'id_field' => 'id', + // Entities without a @searchable annotation will default to secondary, + // which makes them visible in SearchKit but not at the top of the list. + 'searchable' => 'secondary', + ]; + // Add info for entities with a corresponding DAO + $dao = \CRM_Core_DAO_AllCoreTables::getFullName($info['name']); + if ($dao) { + $info['paths'] = $dao::getEntityPaths(); + $info['icon'] = $dao::$_icon; + $info['label_field'] = $dao::$_labelField; + $info['dao'] = $dao; + } + foreach (ReflectionUtils::getTraits(static::class) as $trait) { + $info['type'][] = self::stripNamespace($trait); + } + $reflection = new \ReflectionClass(static::class); + $info = array_merge($info, ReflectionUtils::getCodeDocs($reflection, NULL, ['entity' => $info['name']])); + if ($dao) { + $info['description'] = $dao::getEntityDescription() ?? $info['description'] ?? NULL; + } + unset($info['package'], $info['method']); + $cache->set("api4.$entityName.info", $info); } - unset($info['package'], $info['method']); return $info; } -- 2.25.1