Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Hooks Laravel Package

artisanpack-ui/hooks

WordPress-style actions and filters for Laravel. Register callbacks on named hooks and filter values with helper functions, Facades, and Blade directives. Predictable priority order, auto-discovery, and support for removing specific or all callbacks.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require artisanpack-ui/hooks
    

    No manual configuration needed—Laravel’s package discovery handles registration.

  2. First Use Case: Trigger an action in a controller:

    use function doAction;
    
    // Dispatch an action with payload
    doAction('user.created', $user);
    
  3. Where to Look First:

    • Quick Start Guide in the README.
    • Blade directives section for template integration.

Implementation Patterns

Core Workflows

  1. Modular Extensibility:

    • Package Development: Register hooks in service providers to expose extension points:
      // In a package's service provider
      addAction('app.package.initialized', fn () => $this->boot());
      
    • Plugin Architecture: Use filters to modify core behavior:
      addFilter('auth.login.message', fn ($message) => "Welcome, {$message}");
      
  2. Priority-Based Execution:

    • Assign priorities to control callback order (lower numbers run first):
      addAction('order.processed', fn () => logger('Early step'), 5);
      addAction('order.processed', fn () => logger('Default step'), 10);
      
  3. Blade Integration:

    • Trigger actions or apply filters directly in views:
      @action('view.rendered', $post)
      @filter('title.display', $post->title)
      
  4. Dynamic Hook Management:

    • Remove callbacks conditionally (e.g., for feature flags):
      if (config('features.email_notifications')) {
          addAction('order.placed', fn ($order) => sendEmail($order));
      } else {
          removeAllActions('order.placed');
      }
      

Integration Tips

  • Service Providers: Register hooks in boot() for lazy loading:
    public function boot(): void
    {
        Action::add('app.started', [$this, 'handleAppStarted']);
    }
    
  • Middleware: Dispatch actions for cross-cutting concerns:
    public function handle($request, Closure $next)
    {
        doAction('middleware.executed', $request);
        return $next($request);
    }
    
  • Testing: Mock hooks using removeAllActions()/removeAllFilters():
    removeAllActions('test.hook');
    Action::add('test.hook', fn () => $this->assertTrue(true));
    

Gotchas and Tips

Pitfalls

  1. Callback Reference Equality:

    • removeAction()/removeFilter() require exact callable references (closures must be identical):
      $callback = fn () => logger('test');
      addAction('hook', $callback);
      removeAction('hook', $callback); // Works
      removeAction('hook', fn () => logger('test')); // Fails (new closure)
      
    • Workaround: Use named functions or class methods for stable references.
  2. Priority Collisions:

    • Callbacks with the same priority execute in registration order (FIFO). Use unique priorities for deterministic behavior.
  3. Blade Directive Scope:

    • @action/@filter directives only work in Blade templates. Avoid using them in non-Blade contexts (e.g., API responses).
  4. Memory Leaks:

    • Unregistered callbacks (e.g., from removed packages) persist until manually cleared:
      removeAllActions('hook.name'); // Cleanup
      

Debugging

  • Inspect Hooks: Use Action::getCallbacks('hook.name') or Filter::getCallbacks('hook.name') to debug registered callbacks (requires extending the package or using reflection).
  • Priority Debugging: Log priorities during registration to visualize execution order:
    addAction('hook', fn () => logger('Priority: ' . debug_backtrace()[0]['args'][2]));
    

Extension Points

  1. Custom Hook Storage: Override the default storage (e.g., for persistence):
    // Extend the Action class
    class CustomAction extends Action {
        protected static function storage(): array { return cache()->rememberForever('hooks', fn () => []); }
    }
    
  2. Blade Directives: Extend with custom directives by publishing the BladeDirectiveServiceProvider:
    php artisan vendor:publish --provider="ArtisanPackUI\Hooks\BladeDirectiveServiceProvider"
    
  3. Facade Bindings: Replace facades with custom implementations:
    $this->app->bind('Action', fn () => new CustomAction());
    

Config Quirks

  • No Config File: The package uses zero-configuration. All behavior is code-driven.
  • Facade Aliases: Automatically registered as Action and Filter. Override in config/app.php if needed:
    'aliases' => [
        'Action' => ArtisanPackUI\Hooks\Facades\Action::class,
    ],
    

Performance

  • Avoid Heavy Callbacks: Hooks add minimal overhead, but complex callbacks (e.g., DB queries) in actions can slow down critical paths.
  • Filter Chaining: Each filter callback processes the value sequentially. For performance-critical paths, minimize filter chains or use removeAllFilters() to disable them.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor