frontier / action
Laravel Frontier Actions Package
Installs: 28
Dependents: 1
Suggesters: 1
Security: 0
Stars: 0
Watchers: 1
Forks: 0
Open Issues: 0
pkg:composer/frontier/action
Requires
- php: >=8.2
- illuminate/console: ^10.0|^11.0|^12.0
- illuminate/contracts: ^10.0|^11.0|^12.0
- illuminate/database: ^10.0|^11.0|^12.0
- illuminate/support: ^10.0|^11.0|^12.0
- laravel/prompts: ^0.1|^0.2|^0.3
Requires (Dev)
- laravel/pint: ^1.22
- orchestra/testbench: ^9.0|^10.0
- pestphp/pest: ^3.0
- pestphp/pest-plugin-laravel: ^3.0
- rector/rector: ^2.0
Suggests
- frontier/module: Required for --module option support
README
Frontier Action
Elegant, Reusable Action Classes for Laravel
Installation • Quick Start • Eloquent Actions • Commands • Testing
Features
- ✅ Single Responsibility — Encapsulate business logic into dedicated classes
- ✅ Static Execution — Clean
Action::exec($args)syntax - ✅ Dependency Injection — Fully supported in constructors
- ✅ Eloquent Ready — Pre-built CRUD actions for models
- ✅ Module Support — Works seamlessly with internachi/modular
- ✅ Strict Types — Built with modern PHP standards
Installation
composer require frontier/action
Quick Start
1. Generate an Action
php artisan frontier:action CreateUser
2. Implement Logic
<?php declare(strict_types=1); namespace App\Actions; use App\Models\User; use Frontier\Actions\BaseAction; use Illuminate\Support\Facades\Hash; use App\Services\NotificationService; class CreateUser extends BaseAction { public function __construct( protected NotificationService $notifications ) {} public function handle(array $data): User { $user = User::create([ 'name' => $data['name'], 'email' => $data['email'], 'password' => Hash::make($data['password']), ]); $this->notifications->sendWelcome($user); return $user; } }
3. Execute
Use the static exec() helper for automatic dependency resolution:
// In Controller, Job, or Command $user = CreateUser::exec($request->validated());
Eloquent Actions
The package includes a set of abstract actions optimized for Eloquent operations. Extend Frontier\Actions\EloquentAction or specific implementations to save time.
Available Actions
| Class | Returns | Description |
|---|---|---|
Frontier\Actions\Eloquent\CreateAction |
Model |
Create a new record |
Frontier\Actions\Eloquent\UpdateAction |
int |
Update matching records |
Frontier\Actions\Eloquent\DeleteAction |
int |
Delete matching records |
Frontier\Actions\Eloquent\FindAction |
?Model |
Find a single record |
Frontier\Actions\Eloquent\FindOrFailAction |
Model |
Find or throw exception |
Frontier\Actions\Eloquent\RetrieveAction |
Collection|Paginator |
Get all or paginate |
Frontier\Actions\Eloquent\CountAction |
int |
Count records |
Frontier\Actions\Eloquent\ExistsAction |
bool |
Check existence |
Frontier\Actions\Eloquent\UpdateOrCreateAction |
Model |
Upsert record |
Usage Example
namespace App\Actions\Posts; use App\Models\Post; use Frontier\Actions\Eloquent\CreateAction; class CreatePost extends CreateAction { public function __construct() { // Simply set the model $this->model = new Post(); } }
// Usage $post = CreatePost::exec(['title' => 'Hello World']);
Artisan Commands
Generate Action
php artisan frontier:action [Name]
Modular Generation
If you are using internachi/modular:
# Interactive selection php artisan frontier:action CreateUser --module # Direct module target php artisan frontier:action CreateUser --module=blog
Architecture
The BaseAction
All actions extend Frontier\Actions\BaseAction.
exec(...$args): Static entry point. Resolves class from container (injecting constructor dependencies) and callsexecute.execute(...$args): Instance method. Callshandle.handle(...$args): Your logic goes here.
Why Actions?
- Refactoring: Move complex logic out of Controllers.
- Reusability: Call the same action from a Controller, an API endpoint, and a CLI command.
- Testing: Test business logic in isolation without HTTP layer overhead.
Testing
Action classes are easy to test because they are just simple PHP classes.
use App\Actions\CreateUser; use App\Models\User; it('creates a user', function () { // Arrange $data = ['name' => 'Test', 'email' => 'test@example.com', 'password' => '123456']; // Act $user = CreateUser::exec($data); // Assert expect($user)->toBeInstanceOf(User::class); $this->assertDatabaseHas('users', ['email' => 'test@example.com']); });
Because BaseAction resolves via the container, you can mock injected dependencies easily using Laravel's mock() or spy() before calling exec().
Development
composer test # Run tests composer lint # Fix code style composer rector # Apply refactorings
Related Packages
| Package | Description |
|---|---|
| frontier/frontier | Laravel Starter Kit |
| frontier/repository | Repository Pattern |
| frontier/module | Modular Architecture |
🤝 Contributing
- Follow PSR-12 coding standards
- Use Laravel Pint for code styling
- Write tests using Pest
- Add strict types to all PHP files
📄 License
MIT License - see LICENSE for details.
👤 Author
Mohamed Khedr — 0xkhdr@gmail.com
Made with ❤️ for the Laravel community