CRM-19813 - GenericHookEvent - Bridge between Symfony Events and hooks
authorTim Otten <totten@civicrm.org>
Fri, 3 Mar 2017 20:15:09 +0000 (12:15 -0800)
committerTim Otten <totten@civicrm.org>
Thu, 30 Mar 2017 22:39:52 +0000 (15:39 -0700)
commit762dc04dcf9b61d964d24b7177289c79e104922c
tree9f7584943fe99aafb14e7cfd3226a1d4fac940f9
parent9897fb1ed76bcbc2a69a776b4d5652f108dbf7bc
CRM-19813 - GenericHookEvent - Bridge between Symfony Events and hooks

The GenericHookEvent is used to expose all traditional hooks to the Symfony
EventDispatcher.

The traditional notation for a hook is based on a function signature:

  function hook_civicrm_foo($bar, &$whiz, &$bang);

Symfony Events are based on a class with properties and methods.  This
requires some kind of mapping.

Symfony Events has two conventions which might be used to support that
mapping.  One might implement event classes for every hook, or one might use
the `GenericEvent`.  This design-decision comes with a basic trade-off
between size (total #files, #classes, #SLOC) and IDE assistance
(docs/autocomplete):

 * `GenericEvent` has smaller size and less boiler-plate, but it also
   provides little IDE assistance.
 * Custom event classes provide more IDE assistance, but they also
   inflate the size (with lots of boilerplate).

This patch implements `GenericHookEvent`, which is conceptually similar to
`GenericEvent`, but it has a few modifications:

 * The `__get()` function returns references, which makes it easier to
   alter data.
 * The `getHookValues()` function returns an ordered list of hook arguments.

The approach of `GenericEvent` / `GenericHookEvent` seems like a reasonable
balance -- it starts out with little boilerplate, but we can incrementally
introduce subclasses.  The subclasses can:

 * Use docblocks for IDE support
 * Use declared properties for IDE support (though you may need to customize
   the constructor, etal).
 * Add semantic/businessy functions.
 * Override the `__get()` / `__set()` functions to be provide
   different getter/setter behavior.
Civi/Core/CiviEventDispatcher.php [new file with mode: 0644]
Civi/Core/Container.php
Civi/Core/Event/GenericHookEvent.php [new file with mode: 0644]
tests/phpunit/Civi/Core/Event/GenericHookEventTest.php [new file with mode: 0644]