Installation:
composer require teofanis/hook-press
Add to composer.json under extra:
"hook-press": {
"enabled": true,
"cache-path": "bootstrap/cache/hookpress",
"discover": ["app/Contracts/*", "app/Traits/*"]
}
Run composer dump-autoload to trigger the Composer hook.
First Use Case:
Use the HookPress facade to fetch cached classes:
use Teofanis\HookPress\Facades\HookPress;
$contracts = HookPress::get('App\\Contracts\\*');
$traits = HookPress::get('App\\Traits\\*');
config/hookpress.php (auto-generated after first run).bootstrap/cache/hookpress/ (pre-built class maps).HookPress::get($pattern) for runtime lookups.Class Discovery:
composer.json under hook-press.discover.Service classes:
"hook-press": {
"discover": ["app/Services/*"]
}
$services = HookPress::get('App\\Services\\*');
Dynamic Filtering:
HookPress::filter() to narrow results at runtime:
$activeServices = HookPress::filter($services, fn($class) => class_exists($class));
Integration with Service Providers:
public function register()
{
$classes = HookPress::get('App\\Contracts\\*');
foreach ($classes as $class) {
$this->app->bind($class, fn($app) => new $class());
}
}
Caching Strategies:
Teofanis\HookPress\Cache\CacheManager to clear cache on config changes.HookPress::refresh() after adding new classes.Trait/Interface Enforcement:
Use HookPress::validate() to ensure discovered classes implement traits/interfaces:
$validClasses = HookPress::validate($classes, 'App\\Contracts\\Validatable');
Lazy Loading: Defer class instantiation until needed:
$classNames = HookPress::get('App\\Lazy\\*');
$instances = collect($classNames)->map(fn($class) => new $class());
Testing:
Mock HookPress in tests:
HookPress::shouldReceive('get')->andReturn(['Mock\\Class']);
Cache Staleness:
composer dump-autoload or manually call HookPress::refresh().Pattern Mismatches:
HookPress::get() returns empty results.composer.json patterns match actual class paths (e.g., App\Contracts\* vs. app/Contracts/*).Composer Hook Conflicts:
hook-press runs last in post-autoload-dump:
"scripts": {
"post-autoload-dump": [
"@hook-press",
"other-scripts"
]
}
Namespace Collisions:
App\\Services\\*) or filter results:
HookPress::filter($classes, fn($class) => str_starts_with($class, 'App\\Services\\'));
ls -la bootstrap/cache/hookpress/
cat bootstrap/cache/hookpress/classes.json
HOOKPRESS_DEBUG=1 in .env to log discovery steps.Custom Cache Drivers:
Extend Teofanis\HookPress\Cache\CacheInterface for Redis/Memcached:
HookPress::setCacheDriver(new RedisCache());
Pre/Post-Processors:
Add logic before/after discovery via hook-press.processors in composer.json:
"hook-press": {
"processors": ["App\\HookPress\\Processors\\ValidateTrait"]
}
Dynamic Patterns:
Override HookPress::getPatterns() to fetch patterns from a config file:
public function getPatterns(): array
{
return config('hookpress.patterns');
}
app/Contracts/* instead of app/*).How can I help you explore Laravel packages today?