*/ private array $registered = array(); /** * Register an action callback. * * Forwards to WordPress's add_action() when it is available (the * normal runtime path) and records the registration for introspection. * When add_action() is not available (pure-unit test context without * WordPress loaded), the registration is still recorded so tests can * assert against it; no error is raised. * * @param string $hook Action hook name. * @param callable $callback Callback to invoke. * @param int $priority Hook priority. Default 10. * @param int $accepted_args Number of arguments the callback accepts. Default 1. */ public function addAction( string $hook, callable $callback, int $priority = 10, int $accepted_args = 1 ): void { $this->record( 'action', $hook, $callback, $priority, $accepted_args ); if ( function_exists( 'add_action' ) ) { add_action( $hook, $callback, $priority, $accepted_args ); } } /** * Register a filter callback. * * See {@see HookRegistrar::addAction()} for semantics; the only * difference is that this delegates to add_filter(). * * @param string $hook Filter hook name. * @param callable $callback Callback to invoke. * @param int $priority Hook priority. Default 10. * @param int $accepted_args Number of arguments the callback accepts. Default 1. */ public function addFilter( string $hook, callable $callback, int $priority = 10, int $accepted_args = 1 ): void { $this->record( 'filter', $hook, $callback, $priority, $accepted_args ); if ( function_exists( 'add_filter' ) ) { add_filter( $hook, $callback, $priority, $accepted_args ); } } /** * Return every hook registration made through this registrar, in order. * * @return list */ public function registered(): array { return $this->registered; } /** * Return only the registrations for the given hook name. * * Useful for targeted assertions in tests (e.g. "the plugin must * register exactly one callback on plugins_loaded") without having * to scan the full list. * * @param string $hook Hook name to filter by. * * @return list */ public function registeredFor( string $hook ): array { return array_values( array_filter( $this->registered, static fn ( array $record ): bool => $record['hook'] === $hook ) ); } /** * Report whether any registration has been made for the given hook. * * @param string $hook Hook name to check. */ public function hasHook( string $hook ): bool { foreach ( $this->registered as $record ) { if ( $record['hook'] === $hook ) { return true; } } return false; } /** * Total number of registrations made through this registrar. */ public function count(): int { return count( $this->registered ); } /** * Record a single hook registration in the internal log. * * @param 'action'|'filter' $type Hook type. * @param string $hook Hook name. * @param callable $callback Callback. * @param int $priority Priority. * @param int $accepted_args Accepted argument count. */ private function record( string $type, string $hook, callable $callback, int $priority, int $accepted_args ): void { $this->registered[] = array( 'type' => $type, 'hook' => $hook, 'callback' => $callback, 'priority' => $priority, 'accepted_args' => $accepted_args, ); } }