lorisleiva/lody
Lody loads files or PHP classes from one or more paths as a Laravel LazyCollection. Discover classes via PSR-4 resolution, then filter (e.g., non-abstract, instance of) and iterate to register or process them. Configurable path and classname resolving.
Plugin/Extension Ecosystem: Enable a marketplace-like architecture where third-party or internal developers drop classes into directories (e.g., app/Plugins/) and Lody auto-discovers and registers them based on traits/interfaces. This accelerates SaaS platform development, CMS plugins, or internal tooling (e.g., custom integrations for finance teams).
PaymentGateway in plugins/payments/.Reduced Technical Debt: Eliminate repetitive register() calls in service providers for classes like EventListeners, Policies, or Rules. Aligns with Laravel’s conventions while supporting custom discovery logic (e.g., hasTrait('Serializable')).
AppServiceProvider, improving onboarding and reducing merge conflicts.Dynamic Feature Flags: Combine Lody with environment checks to conditionally load classes (e.g., hasTrait('BetaFeature')->when(fn() => config('features.beta'))). Enables gradual rollouts, A/B testing, or tenant-specific configurations without refactoring.
Test Automation: Scan for classes with methods like generateTestData() or mock() to automate test setup. Reduces flaky tests and improves CI/CD efficiency by ensuring consistent test data pipelines.
CLI Tooling: Dynamically register Artisan commands implementing traits (e.g., QueuedCommand) to build self-documenting CLI tools. Supports scalable admin panels or developer tools without manual updates.
ExportCommand classes in app/Commands/Exports/.Legacy Modernization: Bridge legacy systems by scanning for classes with specific signatures (e.g., hasMethod('legacyProcess')) and wrapping them in modern interfaces. Lowers migration risk by incrementally adopting new patterns.
Domain-Driven Design (DDD): Discover and instantiate domain-specific classes (e.g., app/Domain/Users/Commands/) to enforce consistent patterns across repositories, services, and use cases.
Roadmap Priorities:
plugins/ directories.Configurable to support runtime overrides (e.g., config('services.'.classname)).PaymentGateway).vendor/ for custom interfaces).resolveClassnameUsing, but expect additional maintenance.SplFileInfo, ReflectionClass, or get_declared_classes().class_alias() or get_declared_classes().setBasePath().spl_file_info listeners.*"Lody is a developer productivity multiplier for Laravel projects. It automates the discovery and registration of classes—like plugins, workflow nodes, or event listeners—so teams can build modular, extensible systems without manual configuration.
Key Benefits:
Use Cases:
ROI: Teams can ship 20% more features with the same resources by eliminating repetitive class registration. Let’s pilot this in [Project X] to auto-discover [specific use case] and measure the impact."*
*"Lody lets you scan directories for classes and filter them dynamically—no more manually registering every EventListener or Policy. Here’s how to leverage it:
Core Features:
app/Workflow/Nodes for classes implementing Node and filter by traits/methods:
Lody::classes('app/Workflow/Nodes')
->isInstanceOf(Node::class)
->hasMethod('execute')
->each(fn($class) => $this->register($class));
config() or feature flags:
Lody::classes('app/Features')
->hasTrait('BetaFeature')
->when(fn() => config('features.beta.enabled'))
->each(...);
plugins/payments/:
Lody::classes('plugins/payments')
->isInstanceOf(PaymentGateway::class)
->each(fn($class) => PaymentGateway::extend($class::name(), $class));
Lody::classes('tests/Data')
->hasMethod('generate')
->each(fn($class) => $this->addTestData(new $class()));
Why It’s Better Than DIY:
Next Steps:
register() calls in AppServiceProvider.Docs: GitHub | Example: [Plugin Auto-Discovery PRD]."*
*"Lody addresses modularity and discoverability in Laravel applications by providing a declarative, lazy-loaded class discovery layer. Here’s how it fits into system design:
Architectural Benefits:
new PaymentGateway() → Lody::classes('gateways')->first()).AuthProvider based on tenant config).How can I help you explore Laravel packages today?