PHPackages                             r4nkt/laravel-dto-action - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. r4nkt/laravel-dto-action

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

r4nkt/laravel-dto-action
========================

A (somewhat opinionated) Laravel package to help make preparing and executing actions using data transfer objects a little easier and more uniform.

v1.0.0(3y ago)1111MITPHPPHP ^8.0

Since Sep 30Pushed 3y ago1 watchersCompare

[ Source](https://github.com/r4nkt/laravel-dto-action)[ Packagist](https://packagist.org/packages/r4nkt/laravel-dto-action)[ Docs](https://github.com/r4nkt/laravel-dto-action)[ RSS](/packages/r4nkt-laravel-dto-action/feed)WikiDiscussions master Synced yesterday

READMEChangelog (5)Dependencies (6)Versions (6)Used By (0)

A (somewhat opinionated) Laravel package that makes working with actions and data transfer objects a little easier.
===================================================================================================================

[](#a-somewhat-opinionated-laravel-package-that-makes-working-with-actions-and-data-transfer-objects-a-little-easier)

[![Latest Version on Packagist](https://camo.githubusercontent.com/f2cf221bc64696df5c86eec94f0a6a03aeabf44a46580871444103b8b20cf451/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f72346e6b742f6c61726176656c2d64746f2d616374696f6e2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/r4nkt/laravel-dto-action)[![Tests](https://github.com/r4nkt/laravel-dto-action/workflows/run%20tests/badge.svg)](https://github.com/r4nkt/laravel-dto-action/actions?query=workflow%3A%22run+tests%22)[![Quality Score](https://camo.githubusercontent.com/dea1588284dcc221b3be2af5770bb4e4e2c3bd47330f629399493ff9c60dfa65/68747470733a2f2f696d672e736869656c64732e696f2f7363727574696e697a65722f672f72346e6b742f6c61726176656c2d64746f2d616374696f6e2e7376673f7374796c653d666c61742d737175617265)](https://scrutinizer-ci.com/g/r4nkt/laravel-dto-action)[![Total Downloads](https://camo.githubusercontent.com/21c79f50dbb5df0fbec15dbe1abd4ce541bca5e42f27a46f3673c4f257169a7f/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f72346e6b742f6c61726176656c2d64746f2d616374696f6e2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/r4nkt/laravel-dto-action)

This package is inspired by a few people. Please check out the following to see where the inspiration came from:

- [Brent](https://twitter.com/brendt_gd)'s articles on [working with data](https://stitcher.io/blog/laravel-beyond-crud-02-working-with-data) and [actions](https://stitcher.io/blog/laravel-beyond-crud-03-actions) in Laravel
- [Freek](https://twitter.com/freekmurze)'s [video](https://freek.dev/1545-how-to-avoid-large-function-signatures-by-using-pending-objects) about pending objects with actions
- and [Mohamed](https://twitter.com/themsaid)'s [video](https://divinglaravel.com/when-does-php-call-__destruct) on using `__destruct()` in similar situations

It should also be noted that it's a variation of [my own](https://twitter.com/traviselkins) [pending actions package](https://github.com/telkins/laravel-pending-action) that I hope will prove to be more useful.

Also important to note is the fact that this package is built around [Spatie's](https://spatie.be) [data transfer object package](https://github.com/spatie/data-transfer-object). In fact, it's required.

Introduction
------------

[](#introduction)

From time to time you may need to perform tasks or actions in your application or different parts of your code where there isn't an out-of-the-box Laravel solution. Most likely, this is or is related to your business logic. An oft-used example is creating an invoice. This is an action that may need to take place in one of your applications. It will likely require parameters, and it will likely be made up of smaller actions.

The goal of this package is to provide a (somewhat opinionated) way to make, define, and use actions along with data transfer objects (DTOs). You can create `Action` classes and then, when you want to execute that action, you "prep" that class: `$myAction = MyAction::dto();`. You get back a pending action object, which you define, that allows you to provide the parameters necessary for your action to be carried out. When ready, you call `execute()`.

Here's an example:

```
$data = [
    'email' => 'me@mydomain.com',
    'list' => $emailList,
    'attributes' => $attributes,
    'confirm' => false,
    'send_welcome_mail' => false,
];

// create the DTO for the CreateSubscriber action and then execute the action
CreateSubscriber::dto($data)->execute();
```

Installation
------------

[](#installation)

You can install the package via composer:

```
composer require r4nkt/laravel-dto-action
```

Usage
-----

[](#usage)

For now, one must manually create your `Action` and `DataTransferObject` classes. A future release will include the ability to create `Action` and `DataTransferObject` classes via `php artisan`.

### Create an Action

[](#create-an-action)

```
use R4nkt\LaravelDtoAction\Action;

class CreateSubscriber extends Action
{
    public function __invoke(CreateSubscriberDto $dto)
    {
        // code to perform action, using $dto as needed...
    }

    // supporting methods, if needed...
}
```

#### DTO Class Naming Conventions

[](#dto-class-naming-conventions)

By default, each `Action` class will look for a DTO class that has the same FQCN with `Dto` appended. So, for our example `CreateSubscriber` class, it will look for `CreateSubscriberDto`.

To override this behavior, you can specify the DTO class name in your `Action` class like so:

```
use R4nkt\LaravelDtoAction\Action;
use My\Custom\Namespace\UnconventionalCreateSubscriberDto;

class CreateSubscriber extends Action
{
    // override default DTO class
    protected static $dtoClass = UnconventionalCreateSubscriberDto::class;

    // ...
}
```

### Create a DTO

[](#create-a-dto)

To create a DTO class, refer to the [documentation](https://github.com/spatie/data-transfer-object). Once created, simply add the `ExecutesDtoActions` trait:

```
use App\EmailList;
use R4nkt\LaravelDtoAction\ExecutesDtoActions;
use Spatie\DataTransferObject\DataTransferObject;

class CreateSubscriberDto extends DataTransferObject
{
    use ExecutesDtoActions;

    public string $email;
    public EmailList $list;
    public array $attributes = [];
    public bool $confirm = true;
    public bool $send_welcome_mail = true;
}
```

### "Prep" Your Action, Carry it Out

[](#prep-your-action-carry-it-out)

Once you have built your action and DTO classes, then you can begin to use them. There are three main steps to preparing your action and executing it:

1. Call the static `dto()` method on your `Action` class. This returns the "action-aware" DTO.
2. Optionally, make any additional changes to your DTO.
3. Finally, call the `execute()` method on the pending action object.

Here is an example of preparing and executing an action all at once:

```
UpdateLeaderboard::dto($data)->execute();
```

Here is an example of using the DTO to provide different parameters to carry out the action for different scenarios:

```
$data = [
    'player' => $peter,
    'score' = $petersScore,
];

$updateLeaderboardDto = UpdateLeaderboard::dto($data);

$updateLeaderboardDto->execute();

$updateLeaderboardDto->player = $paul;
$updateLeaderboardDto->score = $paulsScore;
$updateLeaderboardDto->execute();
```

### Add a Custom Static Contructor

[](#add-a-custom-static-contructor)

You can also take advantage of Spatie's DTO support for custom static constructors. Simply add a custom static constructor to your DTO per the documentation and then call it via the action by prepending `dto` to its name.

Here is an example of how you can do this:

```
class UpdateLeaderboardDto extends DataTransferObject
{
    // ...

    public static function fromRequest(Request $request): self
    {
        return new self([
            'player' => Player::find($request->input('player_id')),
            'score' => $request->input('score'),
        ]);
    }
}
```

You can then use it like so:

```
UpdateLeaderboard::dtoFromRequest($request)->execute();
```

**NOTE: This functionality is not IDE-friendly and the developer will be responsible for passing the right types of arguments.**

Testing
-------

[](#testing)

```
composer test
```

Changelog
---------

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING](CONTRIBUTING.md) for details.

Security
--------

[](#security)

If you discover any security related issues, please use the issue tracker.

Credits
-------

[](#credits)

- [Travis Elkins](https://github.com/telkins)
- [All Contributors](../../contributors)

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

28

—

LowBetter than 54% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity11

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity63

Established project with proven stability

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~157 days

Total

5

Last Release

1422d ago

Major Versions

v0.4.0 → v1.0.02022-06-20

PHP version history (3 changes)v0.1.0PHP ^7.4

v0.2.0PHP ^7.4 || ^8.0

v0.3.0PHP ^8.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/d0099a02e09e4fd03c5aca40dd7cc943391d0333009959c276321e59f6423965?d=identicon)[travis.elkins](/maintainers/travis.elkins)

---

Top Contributors

[![telkins](https://avatars.githubusercontent.com/u/53731?v=4)](https://github.com/telkins "telkins (11 commits)")

---

Tags

hacktoberfestlaraveldataobjectdtoexecutetransferactionr4nktlaravel-dto-action

###  Code Quality

TestsPHPUnit

Code StylePHP CS Fixer

### Embed Badge

![Health badge](/badges/r4nkt-laravel-dto-action/health.svg)

```
[![Health](https://phpackages.com/badges/r4nkt-laravel-dto-action/health.svg)](https://phpackages.com/packages/r4nkt-laravel-dto-action)
```

###  Alternatives

[markwalet/nova-modal-response

A Laravel Nova asset for Modal responses on an action.

14720.0k](/packages/markwalet-nova-modal-response)[iteks/laravel-enum

A comprehensive Laravel package providing enhanced enum functionalities, including attribute handling, select array conversions, and fluent facade interactions for robust enum management in Laravel applications.

2516.7k](/packages/iteks-laravel-enum)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
