5 * Class CiviEventInspector
7 * The event inspector is a development tool which provides metadata about events.
8 * It can be used for code-generators and documentation-generators.
11 * $i = new CiviEventInspector();
12 * print_r(CRM_Utils_Array::collect('name', $i->getAll()));
15 * Note: The inspector is only designed for use in developer workflows, such
16 * as code-generation and inspection. It should be not called by regular
19 class CiviEventInspector
{
22 * Register the default hooks defined by 'CRM_Utils_Hook'.
24 * @param \Civi\Core\Event\GenericHookEvent $e
25 * @see \CRM_Utils_Hook::hooks()
27 public static function findBuiltInEvents(\Civi\Core\Event\GenericHookEvent
$e) {
28 $skipList = array('singleton');
29 $e->inspector
->addStaticStubs('CRM_Utils_Hook', 'hook_civicrm_',
30 function ($eventDef, $method) use ($skipList) {
31 return in_array($method->name
, $skipList) ?
NULL : $eventDef;
37 * Array(string $name => array $eventDef).
39 * Ex: $eventDefs['hook_civicrm_foo']['description_html'] = 'Hello world';
44 * Perform a scan to identify/describe all events.
47 * @return CiviEventInspector
49 public function build($force = FALSE) {
50 if ($force ||
$this->eventDefs
=== NULL) {
51 $this->eventDefs
= array();
52 \CRM_Utils_Hook
::hooks($this);
53 ksort($this->eventDefs
);
59 * Get a list of all events.
62 * Array(string $name => array $eventDef).
63 * Ex: $result['hook_civicrm_foo']['description_html'] = 'Hello world';
65 public function getAll() {
67 return $this->eventDefs
;
71 * Find any events that match a pattern.
73 * @param string $regex
75 * Array(string $name => array $eventDef).
76 * Ex: $result['hook_civicrm_foo']['description_html'] = 'Hello world';
78 public function find($regex) {
80 return array_filter($this->eventDefs
, function($e) use ($regex) {
81 return preg_match($regex, $e['name']);
86 * Get the definition of one event.
89 * Ex: 'hook_civicrm_alterSettingsMetaData'.
91 * Ex: $result['description_html'] = 'Hello world';
93 public function get($name) {
95 return $this->eventDefs
[$name];
103 public function validate($eventDef) {
106 && !empty($eventDef['name'])
107 && isset($eventDef['signature'])
108 && is_array($eventDef['fields']);
112 * Add a new event definition.
114 * @param array $eventDef
115 * @return CiviEventInspector
117 public function add($eventDef) {
118 $name = isset($eventDef['name']) ?
$eventDef['name'] : NULL;
120 if (!isset($eventDef['is_hook'])) {
121 $eventDef['is_hook'] = (bool) preg_match('/^hook_/', $eventDef['name']);
124 if (empty($eventDef['signature'])) {
125 $eventDef['signature'] = implode(', ', array_map(
127 $sigil = $field['ref'] ?
'&$' : '$';
128 return $sigil . $field['name'];
134 if (TRUE !== $this->validate($eventDef)) {
135 throw new \
CRM_Core_Exception("Failed to register event ($name). Invalid definition.");
138 $this->eventDefs
[$name] = $eventDef;
143 * Scan a class for hook stubs, and add all of them.
145 * @param string $className
146 * The name of a class which contains static stub functions.
147 * Ex: 'CRM_Utils_Hook'.
148 * @param string $prefix
149 * A prefix to apply to all hook names.
150 * Ex: 'hook_civicrm_'.
151 * @param null|callable $filter
152 * An optional function to filter/rewrite the metadata for each hook.
153 * @return CiviEventInspector
155 public function addStaticStubs($className, $prefix, $filter = NULL) {
156 $class = new \
ReflectionClass($className);
158 foreach ($class->getMethods(\ReflectionMethod
::IS_STATIC
) as $method) {
159 if (!isset($method->name
)) {
164 'name' => $prefix . $method->name
,
165 'description_html' => $method->getDocComment() ? \CRM_Admin_Page_APIExplorer
::formatDocBlock($method->getDocComment()) : '',
167 'class' => 'Civi\Core\Event\GenericHookEvent',
170 foreach ($method->getParameters() as $parameter) {
171 $eventDef['fields'][$parameter->getName()] = array(
172 'name' => $parameter->getName(),
173 'ref' => (bool) $parameter->isPassedByReference(),
174 // WISHLIST: 'type' => 'mixed',
178 if ($filter !== NULL) {
179 $eventDef = $filter($eventDef, $method);
180 if ($eventDef === NULL) {
185 $this->add($eventDef);