therour / laravel-actionable
Single Class Action Handler for Laravel Framework
Installs: 180
Dependents: 0
Suggesters: 0
Security: 0
Stars: 1
Watchers: 1
Forks: 0
Open Issues: 0
pkg:composer/therour/laravel-actionable
Requires
- php: ^7.1.3
- illuminate/container: ~5.4
- illuminate/contracts: ~5.4
- illuminate/http: ~5.4
- illuminate/routing: ~5.4
- illuminate/support: ~5.4
Requires (Dev)
- orchestra/testbench: ^3.5
- orchestra/testbench-browser-kit: ^3.5
- phpunit/phpunit: ^7.0
README
Laravel Actionable is used to create single action class and made routing simple to them.
Installation
Composer
Install by composer command
composer require therour/laravel-actionable
Service Provider
Version >= Laravel 5.5 attached automatically, no need action
Version < Laravel 5.5
In your config/app.php add Therour\Actionable\Providers\ServiceProvider::class to the packages of provider array
'providers' => [ ... /* * Package Service Providers... */ ... Therour\Actionable\Providers\ServiceProvider::class, ... ],
Configuration
Publish
php artisan vendor:publish --provider "Therour\Actionable\Providers\ServiceProvider::class"
Edit (optional)
- If you create a custom controller to handle Actionable class, you may define the controller class in key
controllerat config file. - If you want to load action routes, define the php file or directory path to your routes file, because
web.phpandapi.phphas default controller namespace, so we cannot load our default action controller that has different namespace
Usage
Routes
create a routes file, by default routes/actions.php and add the action route.
or you may edit route_path in your config/actionable.php configuration
<?php Route::action('GET', '/users/{id}', App\User\Actions\GetUser::class); // If you need to define your FormRequest class Route::action('POST', '/users', App\user\Actions\CreateUser::class);
Create an Action
Create a class implementing Therour\Actionable\Contracts\Actionable interface
nb: you may inject your dependency at __construct() method
the route parameter {id} will be passed to variable $id at the run method of actionable class.
use Therour\Actionable\Contracts\Actionable; use App\User\Models\User; class GetUser implements Actionable { /** * @var mixed */ protected $result; /** * @var \App\User\Models\User */ protected $model; /** * Initiate a single action class */ public function __construct(User $model) { $this->model = $model; } /** * Start running the action * * @var array $data * @return mixed */ public function run($id) { return $this->result = $this->model->find($id); } }
Create Param to Filter and Validate parameters
You may define Param class to filter and validate parameters, by typehint Param class in run method of Actionable Class all request data will be passed to Param class.
By defining rules static method, our default controller will validate it before running the action.
use Therour\Actionable\Params\AbstractParam; class CreateUserParam extends AbstractParam { private $name; private $email; public function getName() { return $this->name; } public function getEmail() { return strtolower($this->email); } public static function rules() { return [ 'name' => 'required|string|max:255', 'email' => 'required|email|unique:users' ]; } }
Param Usage
... public function run(CreateUserParam $param) { // load all filtered parameters. with `getParameters()` // $this->model->create($param->getParameters()) $this->model->create([ 'user' => $param->getName(), 'email' => $param->getEmail() ]); } ...
Or you may run the action without action route.
public function blabla(Request $request, CreateUser $action, CreateUserParam $param) { $param->create($request->all()) ->validate(); $user = $action->run($param); return $user; }
Modify as Http Response
You can use the Responsable interface of Laravel by implemented it, and add method toResponse($request) inside the action class.
... use Illuminate\Http\JsonResponse; class GetUser implements Actionable, Responsable { ... /** * Create an HTTP response that represents the object. * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\Response */ public function toResponse($request) { // accessing the result of `run` method by assigned `result` attribute return new JsonResponse(['data' => $this->result]); } }