Installation Add the package via Composer:
composer require respect/fluentgen
Register the service provider in config/app.php:
'providers' => [
Respect\FluentGen\FluentGenServiceProvider::class,
],
First Use Case
Generate a fluent interface for a model (e.g., App\Models\User):
php artisan fluentgen:generate App\Models\User
This creates a UserFluentInterface.php in app/FluentInterfaces/ with methods like name(), email(), etc.
Where to Look First
php artisan fluentgen:generate (help: php artisan fluentgen:generate --help)app/FluentInterfaces/ for auto-generated files.config/fluentgen.php (if provided) for customization.Model Integration Use the generated fluent interface in controllers or services:
use App\FluentInterfaces\UserFluentInterface;
class UserController {
public function show(UserFluentInterface $user) {
return $user->name()->toUpperCase(); // Hypothetical fluent method
}
}
Dynamic Method Generation Leverage the fluent interface for dynamic queries or method chaining:
$user = new UserFluentInterface($userModel);
$result = $user->email()->contains('@')->get();
Service Layer Abstraction Wrap Eloquent models in fluent interfaces to enforce consistency:
class UserService {
public function __construct(private UserFluentInterface $user) {}
public function getActiveUsers() {
return $this->user->isActive()->get();
}
}
Generate + Use Cycle
php artisan fluentgen:generate App\Models
Testing Mock fluent interfaces in tests:
$mockUser = $this->createMock(UserFluentInterface::class);
$mockUser->method('name')->willReturn(new NameFluent($user));
IDE Support Enable IDE autocompletion by referencing generated interfaces in PHPDoc blocks:
/** @var UserFluentInterface */
$user = resolve(UserFluentInterface::class);
$this->app->bind(UserFluentInterface::class, function ($app) {
return new UserFluentInterface(new User());
});
return new UserResource($user->name()->toUpperCase()->value());
public function rules() {
return [
'email' => ['required', function ($attribute, $value, $fail) {
$user = new UserFluentInterface(new User());
if (!$user->email()->isValid($value)) {
$fail('Invalid email format.');
}
}]
];
}
Namespace Conflicts
app/Fluent/).Dynamic Method Overhead
IDE Autocompletion
@method PHPDoc annotations:
/**
* @method NameFluent name()
*/
State Management
// Bad: Mutates state
$user->name('John')->get(); // Avoid if `name()` modifies $user
// Good: Immutable
$user->name()->set('John')->get();
Testing Edge Cases
$this->expectException(MethodNotAllowedException::class);
$user->nonExistentMethod()->get();
Generated Code Inspection
Check app/FluentInterfaces/ for errors in auto-generated methods. Manually edit if logic is incorrect.
Artisan Verbosity
Use --verbose for debugging:
php artisan fluentgen:generate App\Models --verbose
Reflection Errors If methods aren’t generated, verify:
Custom Directories
Override the output directory in config/fluentgen.php (if configurable):
'output_directory' => app_path('Fluent'),
Excluded Classes Skip specific classes via config or Artisan flags (if supported):
php artisan fluentgen:generate App\Models --exclude=App\Models\Admin
Custom Method Generators Extend the package by creating a custom generator:
use Respect\FluentGen\Generators\MethodGeneratorInterface;
class CustomMethodGenerator implements MethodGeneratorInterface {
public function generateMethods(array $methods) {
// Add custom logic (e.g., filter methods)
return array_filter($methods, fn($method) => str_starts_with($method, 'get'));
}
}
Post-Generation Hooks
Use Laravel’s generated:fluent event (if supported) to modify interfaces:
Event::listen('generated:fluent', function ($interface) {
$interface->addMethod('customMethod', 'Returns a custom value.');
});
Integration with Laravel Mixins
Combine with laravel-mixins for runtime method injection:
Mixin::make('App\Mixins\UserMixin')->for(UserFluentInterface::class);
How can I help you explore Laravel packages today?