magdicom/laravel-hooks
A lightweight Laravel hooks package for registering and running actions and filters, making it easy to extend app behavior without editing core code. Useful for modular customization and package integration.
This is a thin Laravel wrapper around the magdicom/hooks core package, so treat the core docs as the source of truth and the Laravel layer as an access-path adapter. The v2 line is a deliberate break from v1 — plan a migration, not an upgrade.
Install both packages pinned to the beta channel. The wrapper is useless without the matching core, and the constraint is explicit:
composer require magdicom/laravel-hooks:"^2.0@beta" magdicom/hooks:"^2.0@beta"
You need minimum-stability to permit beta (or per-package @beta flags as above). Both packages must move together — the wrapper requires ^2.0.0-beta.2 of the core and expects the core's Magdicom\Processors namespace.
Read the Hooks documentation site first, then the wrapper's own README for the Laravel-specific surface. The wrapper intentionally adds no API of its own, so anything you can't find in the wrapper docs almost certainly exists in the core docs.
Check what the service provider registers. With an optional facade and a singleton lifecycle, the container bindings are the map of the package. Confirm whether discovery is automatic or you must add the provider/facade alias to config/app.php.
First use case: a single one-off call. Before wiring anything into application structure, prove the install with a one-off processWith() through the helper:
$result = hooks()->processWith(MyHook::class, $payload);
Then repeat it through the facade to confirm both paths are live:
use Magdicom\LaravelHooks\Facades\Hooks;
Hooks::processWith(MyHook::class, $payload);
Second use case: rendering. renderWith() is the parallel entry point for output-producing hooks — exercise it once with a trivial processor before adopting it in views or mail templates.
Constructor injection is the preferred production path. The release notes call it out as a documented first-class option, and it is the only approach that plays well with Laravel's container, test doubles, and static analysis. Inject the hook manager/processor contract into controllers, jobs, and listeners rather than reaching for the helper.
Helper vs. facade vs. injection. All three reach the same underlying singleton. Use the hooks() helper for terse, local, one-off calls (artisan commands, closures, quick scripts); use the Hooks facade when you want an explicit import and IDE discoverability in application code; use injection wherever the class is already container-resolved. Do not mix styles within a single class — pick one and stay consistent.
Wrap processor calls behind your own application service. Because the wrapper adds no abstraction over the core, core beta churn leaks straight into call sites. Put processWith() / renderWith() behind a small app-level service or action class so a future core beta bump touches one file.
Processor classes live under Magdicom\Processors. When referencing core processor types (exceptions, base classes, contracts) in use statements, that is the namespace to expect in v2. Anything you carried over from v1 referencing the old namespace needs updating.
One-off calls are the integration seam. processWith() and renderWith() are the natural fit for a single processor invocation with an explicit payload — form submission handling, a webhook handler, a queued job body. For multi-step pipelines, compose several one-off calls in your own orchestration rather than looking for a pipeline API in the wrapper; the wrapper doesn't provide one.
Respect the singleton lifecycle. The manager is registered as a singleton, so anything you register onto it at runtime persists for the whole request and, under Octane or in long-running queue workers, across requests. Register processors in a service provider's register()/boot() — never lazily inside a controller or job — and ensure registration is idempotent.
Testing. Bind a fake or mock of the injected contract in the container for unit tests; assert on the payload passed to processWith() rather than on the returned value of a real processor. For feature tests, the facade supports the usual Hooks::shouldReceive(...) mocking, which is a good reason to prefer the facade over the helper in code you intend to feature-test.
composer.lock, and do not let CI float ^2.0@beta on a shared branch — a beta.3 → beta.4 bump can change behaviour without a major version signal you'd recognize.Magdicom\Processors. Grep the codebase before you start; this is a mechanical but wide-reaching change.laravel-hooks and hooks is the most likely install failure. If you see a constraint conflict, align both to the same beta minor rather than loosening one.@beta per-package is safer than lowering global minimum-stability. Watch for transitive dependencies that also resolve to betas once the flag is set.app()->runningInConsole() checks or a once-style flag, and consider resetting the manager in a terminating callback if you register per-request.Hooks:: calls fail with a container binding error that reads like a missing class. Verify the provider is loaded (php artisan about or package:discover) before debugging your own code.magdicom/hooks. Read the core source in vendor/magdicom/hooks/src — the Processors directory is where the actual work happens — and check the core's issue tracker before assuming the Laravel layer is at fault.magdicom/hooks. Write against the core contracts so you keep working when the wrapper's container wiring changes between betas.2.0.0 stable lands, re-run the full test suite against the release candidate; treat the beta as a spike branch, not a production dependency, unless you can absorb a breaking change mid-sprint.How can I help you explore Laravel packages today?