lorisleiva/lody
Lody loads files or PHP classes from one or more paths as a Laravel LazyCollection. Discover classes via PSR-4, filter by traits/interfaces/abstract status, and iterate to auto-register services, nodes, handlers, etc.
base_path(), app_path(), and Finder integration, reducing friction in existing projects. The LazyCollection pattern aligns with Laravel’s fluent query builder style (e.g., Eloquent, Collections).resolvePathUsing, resolveClassnameUsing) allow adaptation to non-standard projects (e.g., custom autoload paths or namespace structures).composer require with optional service provider setup.base_path, broadening applicability to non-Laravel PHP projects (though Laravel-specific features like app()->getNamespace() are lost).hasMethod('test') for test data generators).| Risk Area | Mitigation Strategy |
|---|---|
| Performance Overhead | Lazy collections defer execution until iteration, avoiding upfront scans. Benchmark critical paths (e.g., large directories) to validate memory/CPU impact. |
| Classname Resolution | Default PSR-4 resolver may fail for custom autoload setups. Test edge cases (e.g., namespaces with slashes, vendor classes) and override resolveClassnameUsing if needed. |
| Laravel Version Lock | Package supports LTS Laravel versions (11–13). Monitor deprecations in Str:: helpers or Finder usage. |
| False Positives | classExists() filtering is required for Lody::files()->getClassnames() to avoid invalid classes. Document this in usage examples. |
| Windows Path Handling | Test cross-platform path resolution (e.g., app/Workflow/Nodes vs. app\Workflow\Nodes). Package claims Windows support, but validate in CI. |
| Custom Logic Complexity | Overriding resolvers or chaining filters (e.g., hasTrait()->hasMethod()) can become unwieldy. Document patterns for complex queries (e.g., "filter classes with trait X and method Y"). |
.internal) that should be excluded/included by default?classExists() filters them out.)hasMethod('generateTestData')).config('plugins')) or service discovery tools (e.g., Laravel’s AppServiceProvider bindings)?base_path(), Finder, and Str helpers. Leverages Laravel’s service container for namespace resolution (e.g., app()->getNamespace()).Lody::files(path: '...', recursive: false)) and type hints (SplFileInfo, string).vendor/composer/autoload_psr4.php for classname resolution, ensuring consistency with Laravel’s autoloading.LazyCollection (or a compatible alternative), enabling memory-efficient iteration.| Step | Action |
|---|---|
| 1. Assessment | Audit existing class discovery logic (e.g., glob(), ReflectionClass, manual arrays). Identify pain points (e.g., boilerplate, performance, maintainability). |
| 2. Proof of Concept | Replace one manual registration (e.g., workflow nodes) with Lody. Example: |
| ```php | |
| // Before: Manual registration in ServiceProvider | |
| $this->register(Node::class); | |
| $this->register(ApprovalNode::class); | |
| // After: Dynamic discovery | |
| Lody::classes('app/Workflow/Nodes') | |
| ->isNotAbstract() | |
| ->isInstanceOf(Node::class) | |
| ->each(fn ($class) => $this->register($class)); | |
| ``` | |
| 3. Configuration | Add optional service provider setup if custom resolvers are needed: |
| ```php | |
| // app/Providers/AppServiceProvider.php | |
| public function boot(): void | |
| { | |
| Lody::resolvePathUsing(fn(string $path) => Str::startsWith($path, '/') ? $path : base_path($path)); | |
| Lody::resolveClassnameUsing(fn(SplFileInfo $file) => ...); | |
| } | |
| ``` | |
| 4. Testing | Write tests for discovery logic, focusing on: |
| - Correct classname resolution (PSR-4 compliance). | |
- Filtering (e.g., isInstanceOf(), hasTrait()). |
|
| - Edge cases (e.g., abstract classes, missing files, vendor classes). | |
| 5. Rollout | Phase integration by module (e.g., workflows → events → CLI). Monitor memory usage and performance. |
| 6. Documentation | Update internal docs with Lody patterns (e.g., "To register all *Command classes: Lody::classes('app/Console/Commands')->hasSuffix('Command')"). |
| Component | Compatibility Notes |
|---|---|
| Laravel | Tested on 11–13. Laravel 10 support dropped in v0.7.0. |
| PHP | Requires 8.1+. Uses attributes (e.g., #[ReturnTypeWillChange]), so PHP 8.0 may need polyfills. |
| Composer | Relies on autoload_psr4.php. Custom autoload setups may need resolver overrides. |
| Filesystems | Uses SplFileInfo and Finder. Works with local filesystems; cloud storage (e.g., S3) requires custom path resolution. |
| Windows | Officially supported (tested in v0.3.0). Validate path separators (/ vs. \) in CI. |
| Non-Laravel PHP | Standalone mode works but loses Laravel helpers (e.g., app()->getNamespace()). |
['Node', 'ApprovalNode']) with dynamic discovery.isInstanceOf(), hasTrait()) for precise targeting.Serializable workflow nodes.How can I help you explore Laravel packages today?