From bb85f9b8e3a9fa36584c80077a9021410e006a34 Mon Sep 17 00:00:00 2001 From: colemanw Date: Sun, 10 Sep 2023 18:51:58 -0400 Subject: [PATCH] Scan core `civicrm/managed` directory for entity declarations Switch to a more complete module option list using CRM_Core_Module::getAll() --- CRM/Core/BAO/Managed.php | 39 +++++++++++++++++++ CRM/Utils/Hook.php | 2 +- .../Provider/ManagedEntitySpecProvider.php | 2 +- distmaker/dists/common.sh | 2 +- ext/afform/core/Civi/Api4/Afform.php | 2 +- ext/search_kit/Civi/Search/Admin.php | 5 +-- mixin/mgd-php@1/mixin.php | 2 +- 7 files changed, 45 insertions(+), 9 deletions(-) diff --git a/CRM/Core/BAO/Managed.php b/CRM/Core/BAO/Managed.php index 124eabfdad..4204350105 100644 --- a/CRM/Core/BAO/Managed.php +++ b/CRM/Core/BAO/Managed.php @@ -20,6 +20,31 @@ */ class CRM_Core_BAO_Managed extends CRM_Core_DAO_Managed implements Civi\Core\HookInterface { + /** + * Scan core `civicrm/managed` directory for entity declarations. + * + * Note: This is similar to the `mgd-php` mixin for extensions, but slightly stricter: + * - It doesn't scan any directory outside `managed/` + * - It doesn't allow omitting `$params['version']` + * TODO: Consider making a 2.0 version of the extension mixin using this code, for consistent strictness. + * + * @param \Civi\Core\Event\GenericHookEvent $e + * @implements CRM_Utils_Hook::managed + */ + public static function on_hook_civicrm_managed(\Civi\Core\Event\GenericHookEvent $e) { + if ($e->modules && !in_array('civicrm', $e->modules, TRUE)) { + return; + } + $mgdFiles = CRM_Utils_File::findFiles(Civi::paths()->getPath('[civicrm.root]/managed'), '*.mgd.php'); + sort($mgdFiles); + foreach ($mgdFiles as $file) { + $declarations = include $file; + foreach ($declarations as $declaration) { + $e->entities[] = $declaration + ['module' => 'civicrm']; + } + } + } + /** * Callback for hook_civicrm_post(). * @param \Civi\Core\Event\PostEvent $event @@ -54,4 +79,18 @@ class CRM_Core_BAO_Managed extends CRM_Core_DAO_Managed implements Civi\Core\Hoo return $type && in_array('ManagedEntity', $type, TRUE); } + /** + * Options callback for `base_module`. + * @return array + */ + public static function getBaseModules(): array { + $modules = []; + foreach (CRM_Core_Module::getAll() as $module) { + if ($module->is_active) { + $modules[$module->name] = $module->label; + } + } + return $modules; + } + } diff --git a/CRM/Utils/Hook.php b/CRM/Utils/Hook.php index ec44995af8..71d75c3fc2 100644 --- a/CRM/Utils/Hook.php +++ b/CRM/Utils/Hook.php @@ -771,7 +771,7 @@ abstract class CRM_Utils_Hook { * @return null * the return value is ignored */ - public static function managed(&$entities, ?array $modules = NULL) { + public static function managed(array &$entities, ?array $modules = NULL) { $null = NULL; self::singleton()->invoke(['entities', 'modules'], $entities, $modules, $null, $null, $null, $null, diff --git a/Civi/Api4/Service/Spec/Provider/ManagedEntitySpecProvider.php b/Civi/Api4/Service/Spec/Provider/ManagedEntitySpecProvider.php index 5a247952e9..28c149d9b3 100644 --- a/Civi/Api4/Service/Spec/Provider/ManagedEntitySpecProvider.php +++ b/Civi/Api4/Service/Spec/Provider/ManagedEntitySpecProvider.php @@ -52,7 +52,7 @@ class ManagedEntitySpecProvider extends \Civi\Core\Service\AutoService implement ->setDescription(ts('Name of extension which provides this package')) ->setType('Extra') ->setReadonly(TRUE) - ->setOptionsCallback(['CRM_Core_PseudoConstant', 'getExtensions']) + ->setOptionsCallback(['CRM_Core_BAO_Managed', 'getBaseModules']) ->setSqlRenderer([__CLASS__, 'renderBaseModule']); $spec->addFieldSpec($field); diff --git a/distmaker/dists/common.sh b/distmaker/dists/common.sh index a1cc56bea3..51b83b9565 100644 --- a/distmaker/dists/common.sh +++ b/distmaker/dists/common.sh @@ -82,7 +82,7 @@ function dm_install_core() { local repo="$1" local to="$2" - for dir in ang css i js PEAR templates bin CRM api extern Reports install mixin settings Civi partials release-notes xml setup sql/civicrm_data ; do + for dir in ang css i js PEAR templates bin CRM api extern Reports install managed mixin settings Civi partials release-notes xml setup sql/civicrm_data ; do [ -d "$repo/$dir" ] && dm_install_dir "$repo/$dir" "$to/$dir" done diff --git a/ext/afform/core/Civi/Api4/Afform.php b/ext/afform/core/Civi/Api4/Afform.php index 353a5b5969..dc5bacd606 100644 --- a/ext/afform/core/Civi/Api4/Afform.php +++ b/ext/afform/core/Civi/Api4/Afform.php @@ -306,7 +306,7 @@ class Afform extends Generic\AbstractEntity { 'data_type' => 'String', 'description' => 'Name of extension which provides this form', 'readonly' => TRUE, - 'pseudoconstant' => ['callback' => ['CRM_Core_PseudoConstant', 'getExtensions']], + 'pseudoconstant' => ['callback' => ['CRM_Core_BAO_Managed', 'getBaseModules']], ]; $fields[] = [ 'name' => 'search_displays', diff --git a/ext/search_kit/Civi/Search/Admin.php b/ext/search_kit/Civi/Search/Admin.php index 6c224e1630..066c31cb91 100644 --- a/ext/search_kit/Civi/Search/Admin.php +++ b/ext/search_kit/Civi/Search/Admin.php @@ -13,7 +13,6 @@ namespace Civi\Search; use Civi\Api4\Action\SearchDisplay\AbstractRunAction; use Civi\Api4\Entity; -use Civi\Api4\Extension; use Civi\Api4\Query\SqlEquation; use Civi\Api4\Query\SqlFunction; use Civi\Api4\SearchDisplay; @@ -35,8 +34,6 @@ class Admin { */ public static function getAdminSettings():array { $schema = self::getSchema(); - $extensions = Extension::get(FALSE)->addWhere('status', '=', 'installed') - ->execute()->indexBy('key')->column('label'); $data = [ 'schema' => self::addImplicitFKFields($schema), 'joins' => self::getJoins($schema), @@ -48,7 +45,7 @@ class Admin { 'styles' => \CRM_Utils_Array::makeNonAssociative(self::getStyles()), 'defaultPagerSize' => (int) \Civi::settings()->get('default_pager_size'), 'defaultDisplay' => SearchDisplay::getDefault(FALSE)->setSavedSearch(['id' => NULL])->execute()->first(), - 'modules' => $extensions, + 'modules' => \CRM_Core_BAO_Managed::getBaseModules(), 'defaultContactType' => \CRM_Contact_BAO_ContactType::basicTypeInfo()['Individual']['name'] ?? NULL, 'defaultDistanceUnit' => \CRM_Utils_Address::getDefaultDistanceUnit(), 'jobFrequency' => \Civi\Api4\Job::getFields() diff --git a/mixin/mgd-php@1/mixin.php b/mixin/mgd-php@1/mixin.php index 990ed89061..064d82dbae 100644 --- a/mixin/mgd-php@1/mixin.php +++ b/mixin/mgd-php@1/mixin.php @@ -26,7 +26,7 @@ return function ($mixInfo, $bootCache) { // Optimization: if managed entities were requested for specific module(s), // check name and return early if not applicable. - if (is_array($event->modules) && !in_array($mixInfo->longName, $event->modules, TRUE)) { + if ($event->modules && !in_array($mixInfo->longName, $event->modules, TRUE)) { return; } -- 2.25.1