/**
* Class CiviEventInspector
*
- * The hook inspector is a development tool which provides metadata about hooks.
+ * The event inspector is a development tool which provides metadata about events.
* It can be used for code-generators and documentation-generators.
*
* @code
* $i = new CiviEventInspector();
- * print_r(CRM_Utils_Array::collect('name', $i->getHooks()));
+ * print_r(CRM_Utils_Array::collect('name', $i->getAll()));
* @endCode
*
* Note: The inspector is only designed for use in developer workflows, such
* Register the default hooks defined by 'CRM_Utils_Hook'.
*
* @param \Civi\Core\Event\GenericHookEvent $e
- * @see \CRM_Utils_Hook::hooks()
+ * @see \CRM_Utils_Hook::eventDefs()
*/
- public static function findBuiltInHooks(\Civi\Core\Event\GenericHookEvent $e) {
+ public static function findBuiltInEvents(\Civi\Core\Event\GenericHookEvent $e) {
$skipList = array('singleton');
$e->inspector->addStaticStubs('CRM_Utils_Hook', 'hook_civicrm_',
- function ($hook, $method) use ($skipList) {
- return in_array($method->name, $skipList) ? NULL : $hook;
+ function ($eventDef, $method) use ($skipList) {
+ return in_array($method->name, $skipList) ? NULL : $eventDef;
});
}
/**
* @var array
- * Array(string $name => array $hookDef).
+ * Array(string $name => array $eventDef).
*
- * Ex: $hooks['hook_civicrm_foo']['description_html'] = 'Hello world';
+ * Ex: $eventDefs['hook_civicrm_foo']['description_html'] = 'Hello world';
*/
- protected $hooks;
+ protected $eventDefs;
/**
- * Perform a scan to identify/describe all hooks.
+ * Perform a scan to identify/describe all events.
*
* @param bool $force
* @return CiviEventInspector
*/
public function build($force = FALSE) {
- if ($force || $this->hooks === NULL) {
- $this->hooks = array();
- \CRM_Utils_Hook::hooks($this);
- ksort($this->hooks);
+ if ($force || $this->eventDefs === NULL) {
+ $this->eventDefs = array();
+ \CRM_Utils_Hook::eventDefs($this);
+ ksort($this->eventDefs);
}
return $this;
}
/**
- * Get a list of all hooks.
+ * Get a list of all events.
*
* @return array
- * Array(string $name => array $hookDef).
- * Ex: $hooks['hook_civicrm_foo']['description_html'] = 'Hello world';
+ * Array(string $name => array $eventDef).
+ * Ex: $result['hook_civicrm_foo']['description_html'] = 'Hello world';
*/
public function getAll() {
$this->build();
- return $this->hooks;
+ return $this->eventDefs;
}
/**
- * Get the definition of one hook.
+ * Find any events that match a pattern.
+ *
+ * @param string $regex
+ * @return array
+ * Array(string $name => array $eventDef).
+ * Ex: $result['hook_civicrm_foo']['description_html'] = 'Hello world';
+ */
+ public function find($regex) {
+ $this->build();
+ return array_filter($this->eventDefs, function ($e) use ($regex) {
+ return preg_match($regex, $e['name']);
+ });
+ }
+
+ /**
+ * Get the definition of one event.
*
* @param string $name
* Ex: 'hook_civicrm_alterSettingsMetaData'.
* @return array
- * Ex: $hook['description_html'] = 'Hello world';
+ * Ex: $result['description_html'] = 'Hello world';
*/
public function get($name) {
$this->build();
- return $this->hooks[$name];
+ return $this->eventDefs[$name];
}
/**
- * @param $hook
+ * @param $eventDef
* @return bool
* TRUE if valid.
*/
- public function validate($hook) {
- return
- is_array($hook)
- && !empty($hook['name'])
- && isset($hook['signature'])
- && is_array($hook['fields']);
+ public function validate($eventDef) {
+ if (!is_array($eventDef) || empty($eventDef['name']) || !isset($eventDef['type'])) {
+ return FALSE;
+ }
+
+ if (!in_array($eventDef['type'], array('hook', 'object'))) {
+ return FALSE;
+ }
+
+ if ($eventDef['type'] === 'hook') {
+ if (!isset($eventDef['signature']) || !is_array($eventDef['fields'])) {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
}
/**
- * Add a new hook definition.
+ * Add a new event definition.
*
- * @param array $hook
+ * @param array $eventDef
* @return CiviEventInspector
*/
- public function add($hook) {
- $name = isset($hook['name']) ? $hook['name'] : NULL;
+ public function add($eventDef) {
+ $name = isset($eventDef['name']) ? $eventDef['name'] : NULL;
+
+ if (!isset($eventDef['type'])) {
+ $eventDef['type'] = preg_match('/^hook_/', $eventDef['name']) ? 'hook' : 'object';
+ }
- if (empty($hook['signature'])) {
- $hook['signature'] = implode(', ', array_map(
+ if ($eventDef['type'] === 'hook' && empty($eventDef['signature'])) {
+ $eventDef['signature'] = implode(', ', array_map(
function ($field) {
$sigil = $field['ref'] ? '&$' : '$';
return $sigil . $field['name'];
},
- $hook['fields']
+ $eventDef['fields']
));
}
- if (TRUE !== $this->validate($hook)) {
- throw new \CRM_Core_Exception("Failed to register hook ($name). Invalid definition.");
+ if (TRUE !== $this->validate($eventDef)) {
+ throw new \CRM_Core_Exception("Failed to register event ($name). Invalid definition.");
}
- $this->hooks[$name] = $hook;
+ $this->eventDefs[$name] = $eventDef;
+ return $this;
+ }
+
+ /**
+ * Scan a Symfony event class for metadata, and add it.
+ *
+ * @param string $event
+ * Ex: 'civi.api.authorize'.
+ * @param string $className
+ * Ex: 'Civi\API\Event\AuthorizeEvent'.
+ * @return CiviEventInspector
+ */
+ public function addEventClass($event, $className) {
+ $this->add(array(
+ 'name' => $event,
+ 'class' => $className,
+ ));
return $this;
}
* An optional function to filter/rewrite the metadata for each hook.
* @return CiviEventInspector
*/
- public function addStaticStubs($className, $prefix = 'hook_', $filter = NULL) {
+ public function addStaticStubs($className, $prefix, $filter = NULL) {
$class = new \ReflectionClass($className);
foreach ($class->getMethods(\ReflectionMethod::IS_STATIC) as $method) {
continue;
}
- $hook = array(
+ $eventDef = array(
'name' => $prefix . $method->name,
'description_html' => $method->getDocComment() ? \CRM_Admin_Page_APIExplorer::formatDocBlock($method->getDocComment()) : '',
'fields' => array(),
);
foreach ($method->getParameters() as $parameter) {
- $hook['fields'][$parameter->getName()] = array(
+ $eventDef['fields'][$parameter->getName()] = array(
'name' => $parameter->getName(),
'ref' => (bool) $parameter->isPassedByReference(),
// WISHLIST: 'type' => 'mixed',
}
if ($filter !== NULL) {
- $hook = $filter($hook, $method);
- if ($hook === NULL) {
+ $eventDef = $filter($eventDef, $method);
+ if ($eventDef === NULL) {
continue;
}
}
- $this->add($hook);
+ $this->add($eventDef);
}
return $this;