From fdc67a75b2f20aea9f0961683bd8a59c78755d5f Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Fri, 15 Apr 2022 19:04:06 -0700 Subject: [PATCH] hook_managed - Accept option module filter --- CRM/Core/ManagedEntities.php | 5 +---- CRM/Utils/Hook.php | 32 +++++++++++++++++++++++++++++--- ext/afform/core/afform.php | 5 ++++- mixin/mgd-php@1/mixin.php | 4 ++++ 4 files changed, 38 insertions(+), 8 deletions(-) diff --git a/CRM/Core/ManagedEntities.php b/CRM/Core/ManagedEntities.php index 1e249fe76d..9b94ff6e09 100644 --- a/CRM/Core/ManagedEntities.php +++ b/CRM/Core/ManagedEntities.php @@ -547,10 +547,7 @@ class CRM_Core_ManagedEntities { $declarations = array_merge($declarations, $component->getManagedEntities()); } } - // Ideally, given a $moduleName like 'org.foo.demo' we'd just call the function `demo_civicrm_managed()` - // But alas, that only works with old-style hooks and not the event dispatcher. - // So here we go loading declarations from every module whether we need them or not. - CRM_Utils_Hook::managed($declarations); + CRM_Utils_Hook::managed($declarations, $modules); $this->validate($declarations); $this->setDeclarations($declarations); } diff --git a/CRM/Utils/Hook.php b/CRM/Utils/Hook.php index a9679480a0..bb8b464bee 100644 --- a/CRM/Utils/Hook.php +++ b/CRM/Utils/Hook.php @@ -702,6 +702,21 @@ abstract class CRM_Utils_Hook { /** * This hook is called for declaring managed entities via API. * + * @code + * // Example: Optimal skeleton for backward/forward compatibility + * function example_civicrm_managed(&$entities, ?array $modules = NULL) { + * if ($modules !== NULL && !in_array(E::LONG_NAME, $modules, TRUE)) { + * return; + * } + * $entities[] = [ + * 'module' => E::LONG_NAME, + * 'name' => 'my_option_value', + * 'entity' => 'OptionValue', + * 'params' => [...], + * ]; + * } + * @endCode + * * @param array $entities * List of pending entities. Each entity is an array with keys: * + 'module': string; for module-extensions, this is the fully-qualifed name (e.g. "com.example.mymodule"); for CMS modules, the name is prefixed by the CMS (e.g. "drupal.mymodule") @@ -715,15 +730,26 @@ abstract class CRM_Utils_Hook { * - 'always' (default): always delete orphaned records * - 'never': never delete orphaned records * - 'unused': only delete orphaned records if there are no other references to it in the DB. (This is determined by calling the API's "getrefcount" action.) + * @param array|NULL $modules + * (Added circa v5.50) If given, only report entities related to $modules. NULL is a wildcard ("all modules"). * + * This parameter is _advisory_ and is not supplied on older versions. + * Listeners SHOULD self-censor (only report entities which match the filter). + * However, all pre-existing listeners were unaware of this option, and they WILL over-report. + * Over-reported data will be discarded. * @return null * the return value is ignored */ - public static function managed(&$entities) { - return self::singleton()->invoke(['entities'], $entities, - self::$_nullObject, self::$_nullObject, self::$_nullObject, self::$_nullObject, self::$_nullObject, + public static function managed(&$entities, ?array $modules = NULL) { + self::singleton()->invoke(['entities', 'modules'], $entities, $modules, + self::$_nullObject, self::$_nullObject, self::$_nullObject, self::$_nullObject, 'civicrm_managed' ); + if ($modules) { + $entities = array_filter($entities, function($decl) use ($modules) { + return in_array($decl['module'], $modules, TRUE); + }); + } } /** diff --git a/ext/afform/core/afform.php b/ext/afform/core/afform.php index aa7834d2ec..1fdb6bd9ff 100644 --- a/ext/afform/core/afform.php +++ b/ext/afform/core/afform.php @@ -125,7 +125,10 @@ function afform_civicrm_upgrade($op, CRM_Queue_Queue $queue = NULL) { * * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_managed */ -function afform_civicrm_managed(&$entities) { +function afform_civicrm_managed(&$entities, $modules) { + if ($modules && !in_array(E::LONG_NAME, $modules, TRUE)) { + return; + } /** @var \CRM_Afform_AfformScanner $scanner */ if (\Civi::container()->has('afform_scanner')) { $scanner = \Civi::service('afform_scanner'); diff --git a/mixin/mgd-php@1/mixin.php b/mixin/mgd-php@1/mixin.php index 39d45b14ab..676860848e 100644 --- a/mixin/mgd-php@1/mixin.php +++ b/mixin/mgd-php@1/mixin.php @@ -23,6 +23,10 @@ return function ($mixInfo, $bootCache) { return; } + if (is_array($event->modules) && !in_array($mixInfo->longName, $event->modules, TRUE)) { + return; + } + $mgdFiles = CRM_Utils_File::findFiles($mixInfo->getPath(), '*.mgd.php'); sort($mgdFiles); foreach ($mgdFiles as $file) { -- 2.25.1