(REF) dev/core#1460 - CRM_Utils_Hook::invoke() - Use DispatchPolicy. Simplify. Add...
authorTim Otten <totten@civicrm.org>
Mon, 20 Apr 2020 22:05:10 +0000 (15:05 -0700)
committerTim Otten <totten@civicrm.org>
Tue, 21 Apr 2020 05:58:38 +0000 (22:58 -0700)
commitecb0ae5d0d607a53da2037f7fc618c38e23b81db
treec89852f5f453728337e70935bd9286b609213a91
parent1c3c339421bc886e1fdd54d66f658f4fdfc2998b
(REF) dev/core#1460 - CRM_Utils_Hook::invoke() - Use DispatchPolicy. Simplify. Add test.

Overview
--------

Broadly speaking, this patch aims to allow the list of supported hooks to
change *during* the upgrade process.  To wit:

* While executing low-level DB updates, do not fire many hooks.
* Ater executing low-level DB updates, fire whatever hooks are needed for the
  system to flush its caches.

Before
------

When running upgrades, all phases of the upgrade must use the same list of
permitted hooks.  The list of ugprade hooks is encoded inside of
`CRM_Utils_Hook::invoke` (and `::pre`/`::post`).

The hook whitelist is stored inside of `CRM_Utils_Hook::invoke` as `$upgradeFriendlyHooks`.

After
-----

When running upgrades, the main phase (incremental updates) and the final
phase (doFinish/rebuild) can each use a different list of permitted hooks.

The hook whitelist is stored inside of `CRM_Upgrade_DispatchPolicy`.

Technical Details
-----------------

The updates for `invoke()` have a couple of incidental changes. These
simplify the conditionals/code-paths and also ensure that the
dispatch policy is consistently enforced.

* The hidden option `CIVICRM_FORCE_LEGACY_HOOK` is no longer supported.
  We've been using this invocation style now for years - I haven't heard
  of anyone needing `CIVICRM_FORCE_LEGACY_HOOK` in that, and Google doesn't
  find anyone discussing it.

* Circa `civicrm-core@4.7.x`, the first param changed from `int $count` to
  `string[] $names` to provide compatibility with Symfony-style listeners.
  However, the `int` approach was still supported for backward compatibility
  with extensions.  This patch still provides backward-compatibility, but it
  subtly changes the behavior for legacy callers.  Before, legacy callers
  would bypass the Symfony dispatcher completely. Now, they go through the Symfony
  dispatcher, but they use placeholder names (`arg1`, `arg2`, etc).
    * The support for both canonical `string[] $names` and deprecated `int $count`
      is now covered by a unit-test.
CRM/Upgrade/Form.php
CRM/Utils/Hook.php
Civi/Core/Container.php
tests/phpunit/E2E/Core/HookTest.php [new file with mode: 0644]