### Install IDE Helper for Autocomplete Source: https://www.laravelactions.com/2.x/installation.html For PHP versions 8.0 and above, install the `wulfheart/laravel-actions-ide-helper` package to enable IDE autocompletion for your actions. ```bash composer require --dev wulfheart/laravel-actions-ide-helper ``` -------------------------------- ### Create a Basic Action Class Source: https://www.laravelactions.com/2.x/basic-usage.html Define a PHP class for your task. This example shows a class to update a user's password. ```php namespace App\Authentication\Actions; class UpdateUserPassword { public function handle(User $user, string $newPassword): void { $user->password = Hash::make($newPassword); $user->save(); } } ``` -------------------------------- ### Cherry-picking Traits for an Action Source: https://www.laravelactions.com/2.x/granular-traits.html Example of an action that explicitly uses only the `AsObject` and `AsController` traits. ```php class MyAction { use AsObject; use AsController; // ... } ``` -------------------------------- ### Example Folder Structure for Actions Source: https://www.laravelactions.com/2.x/one-class-one-task.html Organize actions within an `app/Actions` folder, grouping them by topic or module. This convention helps maintain a clear and exhaustive dictionary of your application's functionalities. ```text app/ ├── Actions/ │ ├── Authentication/ │ │ ├── LoginUser.php │ │ ├── RegisterUser.php │ │ ├── ResetUserPassword.php │ │ └── SendResetPasswordEmail.php │ ├── Leads/ │ │ ├── BulkRemoveLead.php │ │ ├── CreateNewLead.php │ │ ├── GetLeadDetails.php │ │ ├── MarkLeadAsCustomer.php │ │ ├── MarkLeadAsLost.php │ │ ├── RemoveLead.php │ │ ├── SearchLeadsForUser.php │ │ └── UpdateLeadDetails.php │ └── Settings/ │ ├── GetUserSettings.php │ ├── UpdateUserAvatar.php │ ├── UpdateUserDetails.php │ ├── UpdateUserPassword.php │ └── DeleteUserAccount.php ├── Models/ └── ... ``` ```text app/ ├── Authentication/ │ ├── Actions/ │ ├── Models/ │ └── ... ├── Leads/ │ ├── Actions/ │ ├── Models/ │ └── ... └── Settings/ ├── Actions/ └── ... ``` -------------------------------- ### Implement asCommand with Arguments Source: https://www.laravelactions.com/2.x/execute-as-commands.html Implement the `asCommand` method to parse command arguments and options, then call the action's `handle` method. This example uses direct argument retrieval. ```php use Illuminate\Console\Command; class UpdateUserRole { use AsAction; public string $commandSignature = 'users:update-role {user_id} {role}'; public function handle(User $user, string $newRole): void { $user->update(['role' => $newRole]); } public function asCommand(Command $command): void { $this->handle( User::findOrFail($command->argument('user_id')), $command->argument('role') ); $command->info('Done!'); } } ``` -------------------------------- ### Authorize using user can method or Gate facade Source: https://www.laravelactions.com/2.x/add-validation-to-controllers.html Examples of using the user's can method or the Gate facade for authorization checks within the authorize method. ```php use Illuminate\Support\Facades\Gate; public function authorize(ActionRequest $request): bool { // Using the `can` method. return $request->user()->can('update', $request->route('article')); // Using the `Gate` facade (this allows for nullable users). return Gate::check('update', $request->route('article')); } ``` -------------------------------- ### Install Laravel Actions Package Source: https://www.laravelactions.com/2.x/installation.html Add the Laravel Actions package to your project's Composer dependencies to begin using it. ```bash composer require lorisleiva/laravel-actions ``` -------------------------------- ### Executing Demote Team Command Source: https://www.laravelactions.com/2.x/examples/demote-team-membership.html Example of how to manually demote a team with a specific ID using the Artisan command-line interface. ```bash php artisan teams:demote 42 ``` -------------------------------- ### Manage Attributes with WithAttributes Methods Source: https://www.laravelactions.com/2.x/use-unified-attributes.html Utilize methods like `setRawAttributes`, `fill`, `all`, `only`, `except`, `has`, and `get` to manage action attributes. ```php $action->setRawAttributes(['key' => 'value']); // Replace all attributes. $action->fill(['key' => 'value']); // Merge the given attributes with the existing attributes. $action->fillFromRequest($request); // Merge the request data and route parameters with the existing attributes. $action->all(); // Retrieve all attributes. $action->only('title', 'body'); // Retrieve only the attributes provided. $action->except('body'); // Retrieve all attributes excepts the one provided. $action->has('title'); // Whether the action has the provided attribute. $action->get('title'); // Get an attribute. $action->get('title', 'Untitled'); // Get an attribute with default value. $action->set('title', 'My blog post'); // Set an attribute. $action->title; // Get an attribute. $action->title = 'My blog post'; // Set an attribute. ``` -------------------------------- ### Implement asListener Method in Laravel Action Source: https://www.laravelactions.com/2.x/as-listener.html Use the `asListener` method to define how an action should respond when executed as an event listener. If `asListener` is not defined, the `handle` method is used directly. This example shows a `SendOfferToNearbyDrivers` action implementing `asListener`. ```php class SendOfferToNearbyDrivers { use AsAction; public function handle(Address $source, Address $destination): void { // ... } public function asListener(TaxiRequested $event): void { $this->handle($event->source, $event->destination); } } ``` -------------------------------- ### Unified Input/Output Handling (v1 vs v2) Source: https://www.laravelactions.com/2.x/upgrade.html v1 required separate methods for pre- and post-handle logic. v2 unifies this into a single entry point per pattern (e.g., `asCommand`), handling both input parsing and output formatting. ```php // v1 class CreateNewArticle extends Action { public function getAttributesFromCommand(Command $command): array { $this->actingAs(User::findOrFail($command->argument('user_id'))); return [ 'title' => $command->argument('title'), 'body' => $command->argument('body'), ]; } public function handle(): Article { return $this->user()->articles()->create([ 'title' => $this->title, 'body' => $this->body, ]); } public function consoleOutput($article, Command $command): void { $command->info("Article \"{$article->title}\" created."); } } ``` ```php // v2 class CreateNewArticle { use AsAction; public function handle(User $author, string $title, string $body): Article { return $author->articles()->create([ 'title' => $title, 'body' => $body, ]); } public function asCommand(Command $command): void { $article = $this->handle( User::findOrFail($command->argument('user_id')), $command->argument('title')), $command->argument('body')), ); $command->info("Article \"{$article->title}\" created."); } } ``` -------------------------------- ### Using DemoteTeamMembership as an Object Source: https://www.laravelactions.com/2.x/examples/demote-team-membership.html Demonstrates how to directly instantiate and run the DemoteTeamMembership action. ```php DemoteTeamMembership::run($team); ``` -------------------------------- ### Run Action Source: https://www.laravelactions.com/2.x/as-object.html Use `run` to resolve and execute an action with provided arguments. This is a shortcut for resolving the action and then calling its `handle` method. ```php MyAction::run($someArguments); // Equivalent to: MyAction::make()->handle($someArguments); ``` -------------------------------- ### Get Attribute Value Source: https://www.laravelactions.com/2.x/with-attributes.html Retrieves the value of an attribute by its key. An optional default value can be provided if the attribute does not exist. ```php $action->get('title'); $action->get('title', 'Untitled'); ``` -------------------------------- ### Generate IDE Helper Actions File Source: https://www.laravelactions.com/2.x/installation.html Run this Artisan command to generate the `_ide_helper_actions.php` file, which your IDE will use for autocompletion. ```bash php artisan ide-helper:actions ``` -------------------------------- ### Define Command Help using Method Source: https://www.laravelactions.com/2.x/as-command.html Provides additional help text for the console command, displayed when the `--help` option is used. This method is an alternative to using the `$commandHelp` property. ```php public function getCommandHelp(): string { return 'My help message.'; } ``` -------------------------------- ### Define Command Help using Property Source: https://www.laravelactions.com/2.x/as-command.html Sets the command help text directly as a public property. This is a convenient way to define the help message for console commands. ```php public string $commandHelp = 'My help message.'; ``` -------------------------------- ### Conditional JSON and HTML Responses Source: https://www.laravelactions.com/2.x/register-as-controller.html Handle requests expecting JSON or HTML separately. This example shows a basic conditional response structure. ```php if ($request->expectsJson()) { return new ArticleResource($article); } else { return redirect()->route('articles.show', [$article]); } ``` -------------------------------- ### Implement Action as Command Source: https://www.laravelactions.com/2.x/basic-usage.html Implement the `asCommand` method to handle command-line arguments and options. Define the command signature and description using `$commandSignature` and `$commandDescription` properties. ```php class UpdateUserPassword { use AsAction; public string $commandSignature = 'user:update-password {user_id} {password}'; public string $commandDescription = 'Updates the password a user.'; public function asCommand(Command $command): void { $user = User::findOrFail($command->argument('user_id')); $this->handle($user, $command->argument('password')); $command->line(sprintf('Password updated for %s.', $user->name)); } // ... } ``` -------------------------------- ### Preparing Request Data for Validation Source: https://www.laravelactions.com/2.x/as-controller.html The `prepareForValidation` method is executed just before authorization and validation are resolved. It allows you to modify the request data, for example, by merging additional fields. ```php public function prepareForValidation(ActionRequest $request): void { $request->merge(['some' => 'additional data']); } ``` -------------------------------- ### Update User Password Action (v1) Source: https://www.laravelactions.com/2.x/upgrade.html Example of updating a user's password using Laravel Actions v1, which extends an Action class and uses attributes for data. ```php // v1 class UpdateUserPassword extends Action { public function handle(): void { $this->user()->update([ 'password' => Hash::make($this->password), ]); } } ``` -------------------------------- ### Implement asCommand with Prompts Source: https://www.laravelactions.com/2.x/execute-as-commands.html Implement the `asCommand` method to interactively prompt the user for input using methods like `ask` and `choice`, then call the action's `handle` method. ```php class UpdateUserRole { use AsAction; public string $commandSignature = 'users:update-role'; public function handle(User $user, string $newRole): void { $user->update(['role' => $newRole]); } public function asCommand(Command $command): void { $userId = $command->ask('What is the ID of the user?'); if (! $user = User::find($userId)) { return $command->error('This user does not exists.'); } $role = $command->choice('What new role should we assign this user?', [ 'reader', 'author', 'moderator', 'admin', ]); $this->handle($user, $role); $command->info('Done!'); } } ``` -------------------------------- ### Define Command Description using Method Source: https://www.laravelactions.com/2.x/as-command.html Provides a description for the console command. This method is an alternative to using the `$commandDescription` property. ```php public function getCommandDescription(): string { return 'Updates the role of a given user.'; } ``` -------------------------------- ### Update User Password Action (v2) Source: https://www.laravelactions.com/2.x/upgrade.html Example of updating a user's password using Laravel Actions v2, which uses traits like AsAction and does not require extending a base class. ```php // v2 class UpdateUserPassword { use AsAction; public function handle(User $user, string $newPassword): void { $user->update([ 'password' => $newPassword, ]); } } ``` -------------------------------- ### Define Command Metadata Methods Source: https://www.laravelactions.com/2.x/execute-as-commands.html Alternatively, define command signature, description, help, and hidden status using dedicated methods for more dynamic control. ```php class UpdateUserRole { use AsAction; public function getCommandSignature(): string { return 'users:update-role {user_id} {role}'; } public function getCommandDescription(): string { return 'Updates the role of a given user.'; } public function getCommandHelp(): string { return 'Additional message displayed when using the --help option.'; } public function isCommandHidden(): bool { return true; // Hides the command from the artisan list. } // ... } ``` -------------------------------- ### Register Action Routes with Facade Source: https://www.laravelactions.com/2.x/register-as-controller.html Use the `Actions` Facade to register routes from your actions. Specify the folder(s) containing your actions to enable route discovery. ```php use Lorisleiva\Actions\Facades\Actions; // Register routes from actions in "app/Actions" (default). Actions::registerRoutes(); // Register routes from actions in "app/MyCustomActionsFolder". Actions::registerRoutes('app/MyCustomActionsFolder'); // Register routes from actions in multiple folders. Actions::registerRoutes([ 'app/Authentication', 'app/Billing', 'app/TeamManagement', ]); ``` -------------------------------- ### Define Command Metadata Properties Source: https://www.laravelactions.com/2.x/execute-as-commands.html Set the command description, help text, and hidden status using `$commandDescription`, `$commandHelp`, and `$commandHidden` properties. ```php class UpdateUserRole { use AsAction; public string $commandSignature = 'users:update-role {user_id} {role}'; public string $commandDescription = 'Updates the role of a given user.'; public string $commandHelp = 'Additional message displayed when using the --help option.'; public bool $commandHidden = true; // Hides the command from the artisan list. // ... } ``` -------------------------------- ### Define Command Description using Property Source: https://www.laravelactions.com/2.x/as-command.html Sets the command description directly as a public property. This is a convenient way to define the description for console commands. ```php public string $commandDescription = 'Updates the role of a given user.'; ``` -------------------------------- ### Implement Action as Command Source: https://www.laravelactions.com/2.x/as-command.html Defines an action that can be executed as a console command. It uses the `handle` method directly if `asCommand` is not defined. ```php use Illuminate\Console\Command; class UpdateUserRole { use AsAction; public string $commandSignature = 'users:update-role {user_id} {role}'; public function handle(User $user, string $newRole): void { $user->update(['role' => $newRole]); } public function asCommand(Command $command): void { $this->handle( User::findOrFail($command->argument('user_id')), $command->argument('role') ); $command->info('Done!'); } } ``` -------------------------------- ### Run Action as an Object Source: https://www.laravelactions.com/2.x/basic-usage.html Execute your action class as an object using helper methods like `make()` and `run()`, or by resolving it from the container. ```php // Equivalent to "app(UpdateUserPassword::class)". UpdateUserPassword::make(); // Equivalent to "UpdateUserPassword::make()->handle($user, 'secret')". UpdateUserPassword::run($user, 'secret'); ``` ```php class MySecurityService { protected UpdateUserPassword $updatePassword; public function __construct(UpdateUserPassword $updatePassword): void { $this->updatePassword = $updatePassword; } } ``` -------------------------------- ### Dispatch job using dispatch helper (with makeJob) Source: https://www.laravelactions.com/2.x/dispatch-jobs.html Use the `dispatch` helper method with `makeJob` to dispatch an action when the `dispatch` helper is required. This method correctly instantiates the job with the action's arguments. ```php dispatch(SendTeamReportEmail::makeJob($team)); ``` -------------------------------- ### Expecting an Action to Run Source: https://www.laravelactions.com/2.x/as-fake.html Helper method adding an expectation that the `handle` method will be called. ```APIDOC ## POST /api/users ### Description Helper method adding an expectation on the `handle` method. ### Method POST ### Endpoint /api/users ### Request Example ```json { "example": "FetchContactsFromGoogle::shouldRun();" } ``` ### Response #### Success Response (200) - **message** (string) - Indicates the expectation has been set. #### Response Example ```json { "message": "Expectation set for handle method." } ``` ``` -------------------------------- ### Dispatching a Job with Configuration Source: https://www.laravelactions.com/2.x/dispatch-jobs.html Chain job configuration options when dispatching a job using the PendingDispatch instance. ```php SendTeamReportEmail::dispatch($team) ->onConnection('my_connection') ->onQueue('my_queue') ->through(['my_middleware']) ->chain(['my_chain']) ->delay(60); ``` -------------------------------- ### Register Command in Kernel Source: https://www.laravelactions.com/2.x/basic-usage.html Register your action as a console command by adding its class to the `$commands` array in your `app/Console/Kernel.php` file. ```php namespace App\Console; class Kernel extends ConsoleKernel { protected $commands = [ UpdateUserPassword::class, ]; // ... } ``` -------------------------------- ### Configuring Tries, MaxExceptions, and Timeout via configureJob Source: https://www.laravelactions.com/2.x/dispatch-jobs.html Use the `configureJob` method to set specific values for tries, max exceptions, and timeout. ```php public function configureJob(JobDecorator $job): void { $job->setTries(10) ->setMaxExceptions(3) ->setTimeout(60 * 30); } ``` -------------------------------- ### Mock an Action Source: https://www.laravelactions.com/2.x/mock-and-test.html Use the `mock` static method to replace an action with a mock. This is useful for setting up expectations on the action's methods. ```php FetchContactsFromGoogle::mock(); ``` -------------------------------- ### Publish Action Stub Source: https://www.laravelactions.com/2.x/installation.html Publish the stub file used by the `make:action` command if you need to customize the default action template. ```bash php artisan vendor:publish --tag=stubs --provider="Lorisleiva\Actions\ActionServiceProvider" ``` -------------------------------- ### Registering Job Middleware Source: https://www.laravelactions.com/2.x/dispatch-jobs.html Attach job middleware to actions by returning them from the `getJobMiddleware` method. ```php public function getJobMiddleware(): array { return [new RateLimited('reports')]; } ``` -------------------------------- ### Command Help Configuration Source: https://www.laravelactions.com/2.x/as-command.html Provides additional help text for the Artisan command, displayed when the `--help` option is used. This can be set using the `$commandHelp` property or the `getCommandHelp` method. ```APIDOC ## DELETE /api/users/{id} ### Description Deletes a user identified by their unique ID. ### Method DELETE ### Endpoint /api/users/{id} ### Parameters #### Path Parameters - **id** (integer) - Required - The unique identifier of the user to delete. ### Response #### Success Response (200) - **message** (string) - A confirmation message indicating the user was deleted. #### Response Example { "message": "User with ID 1 deleted successfully." } ``` -------------------------------- ### Assert Action Should Run Source: https://www.laravelactions.com/2.x/as-fake.html A helper method to add an expectation that the 'handle' method of the action will be called. ```php FetchContactsFromGoogle::shouldRun(); // Equivalent to: FetchContactsFromGoogle::mock()->shouldReceive('handle'); ``` -------------------------------- ### Register Event Listener using Event Facade Source: https://www.laravelactions.com/2.x/listen-for-events.html Alternatively, use the listen method on the Event facade to register listeners dynamically. This method supports both class-based and string-based events. ```php Event::listen(MyEvent::class, MyAction::class); // Note that it also works with string events. Event::listen('my_string_events.*', MyAction::class); ``` -------------------------------- ### Validation and Authorization Source: https://www.laravelactions.com/2.x/as-controller.html Explains how to implement validation preparation, authorization, and custom validation logic. ```APIDOC ## `prepareForValidation` Method ### Description Called right before authorization and validation are resolved. Allows merging additional data into the request. ### Method `prepareForValidation` ### Parameters - **request** (ActionRequest) - Required - The action request object. ### Request Example ```php public function prepareForValidation(ActionRequest $request): void { $request->merge(['some' => 'additional data']); } ``` ``` ```APIDOC ## `authorize` Method ### Description Defines the authorization logic for the controller action. Can return a boolean or a gate response. ### Method `authorize` ### Parameters - **request** (ActionRequest) - Required - The action request object. ### Response #### Success Response (200) `bool` or `Illuminate\Auth\Access\Response` - `true` if authorized, `false` or a `Response::deny` if not. ### Request Example (Boolean) ```php public function authorize(ActionRequest $request): bool { return $request->user()->role === 'author'; } ``` ### Request Example (Gate Response) ```php use Illuminate\Auth\Access\Response; public function authorize(ActionRequest $request): Response { if ($request->user()->role !== 'author') { return Response::deny('You must be an author to create a new article.'); } return Response::allow(); } ``` ``` ```APIDOC ## `rules` Method ### Description Provides the validation rules for the controller action. ### Method `rules` ### Response #### Success Response (200) `array` - An associative array defining validation rules. ### Request Example ```php public function rules(): array { return [ 'title' => ['required', 'min:8'], 'body' => ['required', IsValidMarkdown::class], ]; } ``` ``` ```APIDOC ## `withValidator` Method ### Description Adds custom validation logic to the existing validator after initial rules are applied. ### Method `withValidator` ### Parameters - **validator** (Validator) - Required - The validation validator instance. - **request** (ActionRequest) - Required - The action request object. ### Request Example ```php use Illuminate\Validation\Validator; public function withValidator(Validator $validator, ActionRequest $request): void { $validator->after(function (Validator $validator) use ($request) { if (! Hash::check($request->get('current_password'), $request->user()->password)) { $validator->errors()->add('current_password', 'Wrong password.'); } }); } ``` ``` -------------------------------- ### Use Helper for Handle Method Mocking Source: https://www.laravelactions.com/2.x/mock-and-test.html The `shouldRun` helper method simplifies setting expectations on the `handle` method, making the code more readable. ```php FetchContactsFromGoogle::shouldRun() ->with(42) ->andReturn(['Loris', 'Will', 'Barney']); ``` -------------------------------- ### Chain multiple jobs together Source: https://www.laravelactions.com/2.x/dispatch-jobs.html Chain multiple jobs together using the `withChain` method, ensuring each job is instantiated with `makeJob`. This allows for sequential execution of related tasks. ```php $chain = [ OptimizeTeamReport::makeJob($team), SendTeamReportEmail::makeJob($team), ]; CreateNewTeamReport::withChain($chain)->dispatch($team); ``` -------------------------------- ### Run Action Conditionally (Unless) Source: https://www.laravelactions.com/2.x/as-object.html Use `runUnless` to resolve and execute an action only if the provided condition evaluates to false. Arguments are passed to the action's `handle` method. ```php MyAction::runUnless(false, $someArguments); ``` -------------------------------- ### Define Command Signature using Method Source: https://www.laravelactions.com/2.x/as-command.html Provides the command signature for registering an action in the console Kernel. This method is an alternative to using the `$commandSignature` property. ```php public function getCommandSignature(): string { return 'users:update-role {user_id} {role}'; } ``` -------------------------------- ### Register Command in Console Kernel Source: https://www.laravelactions.com/2.x/execute-as-commands.html Register your action as a command by adding its class to the `$commands` array in your `app/Console/Kernel.php` file. ```php namespace App\Console; class Kernel extends ConsoleKernel { protected $commands = [ UpdateUserRole::class, ]; // ... } ``` -------------------------------- ### Dynamically Configuring Job Backoff and Retry Until Source: https://www.laravelactions.com/2.x/dispatch-jobs.html Define dynamic backoff strategies and retry until times using dedicated methods. ```php class SendTeamReportEmail { use AsAction; public function getJobBackoff(): array { return [30, 60, 120]; } public function getJobRetryUntil(): DateTime { return now()->addMinutes(30); } // ... } ``` -------------------------------- ### Registering DemoteTeamMembership as a Console Command Source: https://www.laravelactions.com/2.x/examples/demote-team-membership.html Illustrates how to register the DemoteTeamMembership action as a console command in the application's Console Kernel, making it available via Artisan. ```php namespace App\Console; class Kernel extends ConsoleKernel { protected $commands = [ DemoteTeamMembership::class, ]; // ... } ``` -------------------------------- ### Instantiate and Run Actions Source: https://www.laravelactions.com/2.x/one-class-one-task.html Laravel Actions provides static helper methods `make` to instantiate an action and `run` to instantiate and execute it with arguments. These methods ensure actions are resolved from the container, facilitating dependency injection and testing. ```php // Equivalent to "app(MyFirstAction::class)". MyFirstAction::make(); // Equivalent to "MyFirstAction::make()->handle($myArguments)". MyFirstAction::run($myArguments); ``` -------------------------------- ### Partial Mock Action Fetch Source: https://www.laravelactions.com/2.x/as-fake.html Swaps the action with a partial mock, allowing specific methods like 'fetch' to be mocked with expectations. ```php FetchContactsFromGoogle::partialMock() ->shouldReceive('fetch') ->with('some_google_identifier') ->andReturn(['Loris', 'Will', 'Barney']); ``` -------------------------------- ### Configuring Job Defaults in Action Source: https://www.laravelactions.com/2.x/dispatch-jobs.html Set default job configurations within the action itself using the `configureJob` method. ```php use Lorisleiva\Actions\Decorators\JobDecorator; public function configureJob(JobDecorator $job): void { $job->onConnection('my_connection') ->onQueue('my_queue') ->through(['my_middleware']) ->chain(['my_chain']) ->delay(60); } ``` -------------------------------- ### Mock Action Handle Source: https://www.laravelactions.com/2.x/as-fake.html Swaps the action with a mock and sets an expectation for the 'handle' method with specific arguments. ```php FetchContactsFromGoogle::mock() ->shouldReceive('handle') ->with(42) ->andReturn(['Loris', 'Will', 'Barney']); ``` -------------------------------- ### Chain jobs using the Bus facade Source: https://www.laravelactions.com/2.x/dispatch-jobs.html Achieve job chaining by using the `chain` method on the `Bus` facade. This provides an alternative way to define and dispatch sequential jobs. ```php use Illuminate\Support\Facades\Bus; Bus::chain([ CreateNewTeamReport::makeJob($team), OptimizeTeamReport::makeJob($team), SendTeamReportEmail::makeJob($team), ])->dispatch(); ``` -------------------------------- ### Implement asController Method Source: https://www.laravelactions.com/2.x/basic-usage.html Implement the `asController` method to translate request data into arguments for your action's `handle` method. ```php class UpdateUserPassword { use AsAction; public function handle(User $user, string $newPassword): void { $user->password = Hash::make($newPassword); $user->save(); } public function asController(Request $request): Response { $this->handle( $request->user(), $request->get('password') ); return redirect()->back(); } } ``` -------------------------------- ### Action Resolution and Execution Source: https://www.laravelactions.com/2.x/as-object.html This section covers the core methods for interacting with actions: resolving them from the container, running them directly, or running them conditionally. ```APIDOC ## Action Methods ### `make` Resolves the action from the container. ```php MyAction::make(); // Equivalent to: app(MyAction::class); ``` ### `run` Resolves and executes the action. ```php MyAction::run($someArguments); // Equivalent to: MyAction::make()->handle($someArguments); ``` ### `runIf` Resolves and executes the action if the condition is met. ```php MyAction::runIf(true, $someArguments); ``` ### `runUnless` Resolves and executes the action if some condition is not met. ```php MyAction::runUnless(false, $someArguments); ``` ``` -------------------------------- ### Spying on an Action Source: https://www.laravelactions.com/2.x/mock-and-test.html Use the `spy` method to create a spy instance of an action. This allows you to record method calls and assert them after execution. ```php $spy = FetchContactsFromGoogle::spy(); $spy->allows('handle')->andReturn(['Loris', 'Will', 'Barney']); // ... $spy->shouldHaveReceived('handle')->with(42); ``` -------------------------------- ### Auto-register Commands from Folders Source: https://www.laravelactions.com/2.x/execute-as-commands.html Automatically register commands by calling `Actions::registerCommands()` in a service provider, optionally specifying custom folders. ```php use Lorisleiva\Actions\Facades\Actions; // Register commands from actions in "app/Actions" (default). Actions::registerCommands(); // Register commands from actions in "app/MyCustomActionsFolder". Actions::registerCommands('app/MyCustomActionsFolder'); // Register commands from actions in multiple folders. Actions::registerCommands([ 'app/Authentication', 'app/Billing', 'app/TeamManagement', ]); ``` -------------------------------- ### Define Command Signature using Property Source: https://www.laravelactions.com/2.x/as-command.html Sets the command signature directly as a public property. This is a convenient way to define the signature for console commands. ```php public string $commandSignature = 'users:update-role {user_id} {role}'; ``` -------------------------------- ### Use Helper for Spying on Handle Method Source: https://www.laravelactions.com/2.x/mock-and-test.html The `allowToRun` helper method simplifies setting up expectations for the `handle` method when using spies. ```php FetchContactsFromGoogle::allowToRun() ->andReturn(['Loris', 'Will', 'Barney']); // ... FetchContactsFromGoogle::spy() ->shouldHaveReceived('handle')->with(42); ``` -------------------------------- ### Accessing Batch Instance in Action (asJob) Source: https://www.laravelactions.com/2.x/dispatch-jobs.html Inject the `?Batch` instance into the `asJob` method to access batch information when jobs are dispatched in a batch. ```php use Illuminate\Bus\Batch; public function asJob(?Batch $batch, Team $team): void { if ($batch && $batch->cancelled()) { return; } $this->handle($team, true); } ``` -------------------------------- ### Setting Job Properties via Class Properties Source: https://www.laravelactions.com/2.x/dispatch-jobs.html Configure job retry logic and other properties by defining class properties. ```php class SendTeamReportEmail { use AsAction; public string $jobConnection = 'my_connection'; public string $jobQueue = 'my_queue'; public int $jobTries = 10; public int $jobMaxExceptions = 3; public int $jobBackoff = 60 * 5; public int $jobTimeout = 60 * 30; public int $jobRetryUntil = 3600 * 2; // ... } ``` -------------------------------- ### Allow Action Handle to Run with Spy Source: https://www.laravelactions.com/2.x/as-fake.html A helper method to allow the 'handle' method to run on a spy, often used with specific return values. ```php $spy = FetchContactsFromGoogle::allowToRun() ->andReturn(['Loris', 'Will', 'Barney']); // ... $spy->shouldHaveReceived('handle')->with(42); ``` -------------------------------- ### Translate Request to Action Handle Method Source: https://www.laravelactions.com/2.x/register-as-controller.html Use the `asController` method to translate the incoming request into parameters for your action's `handle` method. Route model binding is automatically applied. ```php class CreateNewArticle { use AsAction; public function handle(User $user, string $title, string $body): Article { return $user->articles()->create(compact('title', 'body')); } public function asController(User $user, Request $request): Response { $article = $this->handle( $user, $request->get('title'), $request->get('body') ); return redirect()->route('articles.show', [$article]); } } ``` -------------------------------- ### Mocking GenerateReservationCode for Testing Source: https://www.laravelactions.com/2.x/examples/generate-reservation-code.html This test demonstrates how to mock the `GenerateReservationCode` action using `shouldRun()->andReturn()` to control the generated code during reservation creation. ```PHP /** @test */ public function it_generates_a_unique_code_when_creating_a_new_reservation() { // Given an existing user and concert. $user = User::factory()->create(); $concert = Concert::factory()->create(); // And given we mock the code generator. GenerateReservationCode::shouldRun()->andReturn('ABCD234'); // When we create a new reservation for that user and that concert. $reservation = CreateNewReservation::run($user, $concert); // Then we saved the expected reservation code. $this->assertSame('ABCD234', $reservation->code); } ``` -------------------------------- ### Command Description Configuration Source: https://www.laravelactions.com/2.x/as-command.html Provides a description for the Artisan command. This can be set using the `$commandDescription` property or the `getCommandDescription` method. ```APIDOC ## PUT /api/users/{id} ### Description Updates an existing user identified by their unique ID. ### Method PUT ### Endpoint /api/users/{id} ### Parameters #### Path Parameters - **id** (integer) - Required - The unique identifier of the user to update. #### Request Body - **name** (string) - Optional - The updated name of the user. - **email** (string) - Optional - The updated email address of the user. ### Request Example { "name": "Jane Doe", "email": "jane.doe@example.com" } ### Response #### Success Response (200) - **id** (integer) - The unique identifier for the updated user. - **name** (string) - The updated name of the user. - **email** (string) - The updated email address of the user. #### Response Example { "id": 1, "name": "Jane Doe", "email": "jane.doe@example.com" } ``` -------------------------------- ### Use CreateNewArticle as an Object Source: https://www.laravelactions.com/2.x/examples/create-new-article.html Demonstrates using the CreateNewArticle action as a standalone object, allowing for custom publication dates. ```php CreateNewArticle::run($author, [ 'title' => 'My article', 'body' => '# My article', 'published_at' => now()->addWeek(), ]) ``` -------------------------------- ### Create New Article Action (v1 vs v2) Source: https://www.laravelactions.com/2.x/upgrade.html Compares the implementation of creating a new article in Laravel Actions v1 (attribute-based) and v2 (trait-based, direct arguments). ```php // v1 class CreateNewArticle extends Action { public function handle(): Article { return $this->user()->articles()->create([ 'title' => $this->title, 'body' => $this->body, ]); } } // v2 class CreateNewArticle { use AsAction; public function handle(User $author, string $title, string $body): Article { return $author->articles()->create([ 'title' => $title, 'body' => $body, ]); } } ``` -------------------------------- ### Job Middleware Configuration Source: https://www.laravelactions.com/2.x/as-job.html Adds job middleware directly in the action. The parameters are passed in but note that they are in an array. ```APIDOC ## `getJobMiddleware` ### Description Adds job middleware directly in the action. The parameters are passed in but note that they are in an array. ### Method `getJobMiddleware` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```php public function getJobMiddleware(array $parameters): array { return [new RateLimited('reports')]; } ``` ### Response #### Success Response (200) - `array` - An array of middleware instances. #### Response Example ```json [ "RateLimited('reports')" ] ``` ``` -------------------------------- ### Prepare Action for Validation Source: https://www.laravelactions.com/2.x/add-validation-to-controllers.html Use the `prepareForValidation` method to add custom logic before authorization and validation. It allows merging additional data into the request. ```php public function prepareForValidation(ActionRequest $request): void { $request->merge(['some' => 'additional data']); } ``` -------------------------------- ### Implement asJob method for custom job logic Source: https://www.laravelactions.com/2.x/dispatch-jobs.html Implement the `asJob` method when the logic for dispatching a job differs from the `handle` method. This allows for custom preparation or argument modification specifically for job execution. ```php class SendTeamReportEmail { use AsAction; public function handle(Team $team, bool $fullReport = false): void { // Prepare report and send it to all $team->users. } public function asJob(Team $team): void { $this->handle($team, true); } } ``` -------------------------------- ### Configure Job Settings for ExportUserData Source: https://www.laravelactions.com/2.x/examples/export-user-data.html Configures job settings such as connection, queue, middleware, chain, and delay directly within the action class using the `configureJob` method. ```php use Lorisleiva\Actions\Decorators\JobDecorator; class ExportUserData { use AsAction; public function configureJob(JobDecorator $job): void { $job->onConnection('my_connection') ->onQueue('my_queue') ->through(['my_middleware']) ->chain(['my_chain']) ->delay(60); } // ... } ``` -------------------------------- ### Batching Jobs with Laravel Actions Source: https://www.laravelactions.com/2.x/dispatch-jobs.html Create and dispatch jobs within a batch using `Bus::batch` and `makeJob`. ```php $batch = Bus::batch([ SendTeamReportEmail::makeJob($firstTeam), SendTeamReportEmail::makeJob($secondTeam), SendTeamReportEmail::makeJob($thirdTeam), ])->then(function (Batch $batch) { // All jobs completed successfully... })->catch(function (Batch $batch, Throwable $e) { // First batch job failure detected... })->finally(function (Batch $batch) { // The batch has finished executing... })->dispatch(); ``` -------------------------------- ### Resolve Action Instance Source: https://www.laravelactions.com/2.x/as-object.html Use `make` to resolve an action instance from the container. This is equivalent to using Laravel's `app()` helper. ```php MyAction::make(); // Equivalent to: app(MyAction::class); ``` -------------------------------- ### Run Action Conditionally (If) Source: https://www.laravelactions.com/2.x/as-object.html Use `runIf` to resolve and execute an action only if the provided condition evaluates to true. Arguments are passed to the action's `handle` method. ```php MyAction::runIf(true, $someArguments); ``` -------------------------------- ### Handle String Events with Parameters in asListener Source: https://www.laravelactions.com/2.x/listen-for-events.html When listening to string events with parameters, the asListener method receives all dispatched parameters as arguments. This allows flexible handling of events dispatched with multiple values. ```php // When we dispatch that string event with some parameters. Event::dispatch('taxi.requested', [$source, $destination]); // Then the `asListener` method receives them as arguments. public function asListener(Source $source, Destination $destination): void { $this->handle($source, $destination); } ``` -------------------------------- ### Implement handle method for job dispatching Source: https://www.laravelactions.com/2.x/dispatch-jobs.html Implement the `handle` method to define the action's logic when dispatched as a job. This method is used when the arguments for running an action as an object and dispatching it as a job are the same. ```php class SendTeamReportEmail { use AsAction; public function handle(Team $team): void { // Prepare report and send it to all $team->users. } } ``` -------------------------------- ### AsCommand Method Source: https://www.laravelactions.com/2.x/as-command.html The `asCommand` method is invoked when the action is executed as a command. If this method is not defined, the `handle` method is used directly. It allows for custom logic to parse command arguments and options before calling the main action logic. ```APIDOC ## POST /api/users ### Description This endpoint allows for the creation of new user resources. ### Method POST ### Endpoint /api/users ### Parameters #### Request Body - **name** (string) - Required - The name of the user. - **email** (string) - Required - The email address of the user. ### Request Example { "name": "John Doe", "email": "john.doe@example.com" } ### Response #### Success Response (200) - **id** (integer) - The unique identifier for the newly created user. - **name** (string) - The name of the user. - **email** (string) - The email address of the user. #### Response Example { "id": 1, "name": "John Doe", "email": "john.doe@example.com" } ``` -------------------------------- ### Add Custom Tags and Display Name to Action Source: https://www.laravelactions.com/2.x/dispatch-jobs.html Enhance job monitoring in Horizon by implementing `getJobTags` to provide custom tags and `getJobDisplayName` to set a custom display name for the action. Job arguments are available within these methods. ```php class SendTeamReportEmail { use AsAction; public function getJobTags(Team $team): array { return ['report', 'team:'.$team->id]; } public function getJobDisplayName(): string { return 'Send team report email'; } // ... } ``` -------------------------------- ### Register Action as a Controller Route Source: https://www.laravelactions.com/2.x/basic-usage.html Register your action class in the routes file like an invokable controller to use it as a controller. ```php Route::put('auth/password', UpdateUserPassword::class)->middleware('auth'); ``` -------------------------------- ### Mocking an Action Source: https://www.laravelactions.com/2.x/as-fake.html Swaps the action with a mock. This allows you to define specific return values for methods called on the action. ```APIDOC ## POST /api/users ### Description Swaps the action with a mock. ### Method POST ### Endpoint /api/users ### Request Example ```json { "example": "FetchContactsFromGoogle::mock()\n ->shouldReceive('handle')\n ->with(42)\n ->andReturn(['Loris', 'Will', 'Barney']);" } ``` ### Response #### Success Response (200) - **example** (string) - Mocked response from the action. #### Response Example ```json { "example": "['Loris', 'Will', 'Barney']" } ``` ``` -------------------------------- ### Custom Job Handling with `asJob` Source: https://www.laravelactions.com/2.x/as-job.html Define an `asJob` method within your action class to customize how it's handled when dispatched as a job. If `asJob` is not present, the `handle` method is used directly. ```php class SendTeamReportEmail { use AsAction; public function handle(Team $team, bool $fullReport = false): void { // Prepare report and send it to all $team->users. } public function asJob(Team $team): void { $this->handle($team, true); } } ``` -------------------------------- ### Retrieve All Attributes Source: https://www.laravelactions.com/2.x/with-attributes.html Returns all attributes currently set on the action. ```php $action->all(); ``` -------------------------------- ### Middleware and Route Definition Source: https://www.laravelactions.com/2.x/as-controller.html Covers defining controller middleware and routes directly within the action class. ```APIDOC ## `getControllerMiddleware` Method ### Description Adds controller middleware directly in the action class. ### Method `getControllerMiddleware` ### Response #### Success Response (200) `array` - An array of middleware names. ### Request Example ```php public function getControllerMiddleware(): array { return ['auth', MyCustomMiddleware::class]; } ``` ``` ```APIDOC ## `routes` Method ### Description Defines routes directly in your action class. These routes need to be registered using `Actions::registerRoutes`. ### Method `routes` ### Parameters - **router** (Router) - Required - The router instance provided by Laravel. ### Request Example ```php use Illuminate outing outer; public static function routes(Router $router) { $router->get('author/{author}/articles', static::class); } ``` ### Route Registration To register routes defined in actions, use the `Actions::registerRoutes` facade method in a service provider: ```php use Lorisleiva\Actions\Facades\Actions; // Register routes from default actions folder Actions::registerRoutes(); // Register routes from a custom folder Actions::registerRoutes('app/MyCustomActionsFolder'); // Register routes from multiple folders Actions::registerRoutes([ 'app/Authentication', 'app/Billing', 'app/TeamManagement', ]); ``` ``` -------------------------------- ### Registering DemoteTeamMembership as a Listener Source: https://www.laravelactions.com/2.x/examples/demote-team-membership.html Shows how to register the DemoteTeamMembership action as a listener for the PaymentFailed event in the application's EventServiceProvider. ```php namespace App\Providers; class EventServiceProvider extends ServiceProvider { protected $listen = [ PaymentFailed::class => [ DemoteTeamMembership::class, ], ]; // ... } ``` -------------------------------- ### Create New Reservation Action Source: https://www.laravelactions.com/2.x/examples/generate-reservation-code.html This action creates a new reservation, nesting the `GenerateReservationCode` action to obtain a unique code for the reservation. ```PHP class CreateNewReservation { use AsAction; public function handle(User $user, Concert $concert, int $tickets = 1): Reservation { return $user->reservations()->create([ 'concert_id' => $concert->id, 'price' => $concert->getTicketPrice() * $tickets, 'code' => GenerateReservationCode::run(), ]); } } ``` -------------------------------- ### Job Decorator Creation Source: https://www.laravelactions.com/2.x/as-job.html Methods for creating job decorators to wrap actions. ```APIDOC ## POST /makeJob ### Description Creates a new `JobDecorator` that wraps the action. This can be used to dispatch a job using `dispatch` helper method or when creating a chain of jobs from actions. ### Method POST ### Endpoint /makeJob ### Request Example ```json { "action": "SendTeamReportEmail", "arguments": [{"team": {"id": 1}}] } ``` ### Response #### Success Response (200) Returns the created `JobDecorator` instance. #### Response Example ```json { "job_decorator": "SendTeamReportEmailJobDecorator" } ``` ``` ```APIDOC ## POST /makeUniqueJob ### Description Creates a new `UniqueJobDecorator` that wraps the action. By default, `makeJob` will automatically return a `UniqueJobDecorator` if your action implements the `ShouldBeUnique` trait. However, you may use this method directly to force a `UniqueJobDecorator` to be created. ### Method POST ### Endpoint /makeUniqueJob ### Request Example ```json { "action": "SendTeamReportEmail", "arguments": [{"team": {"id": 1}}] } ``` ### Response #### Success Response (200) Returns the created `UniqueJobDecorator` instance. #### Response Example ```json { "unique_job_decorator": "SendTeamReportEmailUniqueJobDecorator" } ``` ``` -------------------------------- ### Dispatch Job Synchronously (Alias) Source: https://www.laravelactions.com/2.x/as-job.html Use `dispatchNow` as an alias for `dispatchSync` to execute a job immediately on the current process. ```php SendTeamReportEmail::dispatchNow($team); ```