Rename hook_civicrm_hooks to hook_civicrm_eventDefs
[civicrm-core.git] / Civi / Core / CiviEventInspector.php
index bee94cae775fb46339ea50be168357cce090307a..d5d3678607239cddd59dad6fe195526241317bba 100644 (file)
@@ -4,12 +4,12 @@ namespace Civi\Core;
 /**
  * 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
@@ -22,101 +22,147 @@ class CiviEventInspector {
    * 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;
   }
 
@@ -133,7 +179,7 @@ class CiviEventInspector {
    *   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) {
@@ -141,7 +187,7 @@ class CiviEventInspector {
         continue;
       }
 
-      $hook = array(
+      $eventDef = array(
         'name' => $prefix . $method->name,
         'description_html' => $method->getDocComment() ? \CRM_Admin_Page_APIExplorer::formatDocBlock($method->getDocComment()) : '',
         'fields' => array(),
@@ -149,7 +195,7 @@ class CiviEventInspector {
       );
 
       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',
@@ -157,13 +203,13 @@ class CiviEventInspector {
       }
 
       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;