PHPackages                             cheese-driven-development/laravel-tasks - 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. cheese-driven-development/laravel-tasks

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

cheese-driven-development/laravel-tasks
=======================================

Create and manage scheduled tasks in Laravel.

v1.1.1-alpha(3mo ago)0974↓34.9%MITPHPPHP ^8.4|^8.5CI passing

Since Dec 18Pushed 1mo agoCompare

[ Source](https://github.com/cheese-driven-development/laravel-tasks)[ Packagist](https://packagist.org/packages/cheese-driven-development/laravel-tasks)[ RSS](/packages/cheese-driven-development-laravel-tasks/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (10)Dependencies (8)Versions (13)Used By (0)

Laravel Tasks
=============

[](#laravel-tasks)

Create and manage scheduled tasks in Laravel.

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

[](#installation)

```
composer require cheese-driven-development/laravel-tasks
```

### Publish the configuration and migrations

[](#publish-the-configuration-and-migrations)

```
php artisan vendor:publish --provider="CheeseDriven\LaravelTasks\TaskServiceProvider" --tag="laravel-tasks-config"
php artisan vendor:publish --provider="CheeseDriven\LaravelTasks\TaskServiceProvider" --tag="laravel-tasks-migrations"
```

### Run the migrations

[](#run-the-migrations)

```
php artisan migrate
```

Usage
-----

[](#usage)

### Task Types

[](#task-types)

There are two types of tasks:

- Mail Task
- Custom Action Task

### Mail Task

[](#mail-task)

A mail task is a task that sends a Laravel Mailable.

```
use CheeseDriven\LaravelTasks\Task;
use CheeseDriven\LaravelTasks\Enums\TaskType;
use App\Mail\WelcomeMail;

Task::init('Send welcome email')
    ->type(TaskType::Mail)
    ->mailable(new WelcomeMail)
    ->recipients('user@example.com')
    ->scheduleAt(now()->addMinutes(5))
    ->unique()
    ->save();
```

**A note on unique tasks:**

The `unique()` method is used to set the task to be unique by target, action, mailable and name. This will allow you to call the task multiple times without creating duplicate tasks.

Every mail task will be pushed to the queue via the `SendMailJob` and executed via the `SendMailAction`. The `SendMailJob` will always only be dispatched once - even if the task itself is executed multiple times. This will prevent duplicate jobs from being added to the queue. So only one `SendMailAction` will be executed for a given mail task.

### Custom Action Task

[](#custom-action-task)

A custom action task is a task that executes a custom action.

```
use CheeseDriven\LaravelTasks\Task;
use CheeseDriven\LaravelTasks\Enums\TaskType;
use App\Actions\ProcessOrderAction;

Task::init('Process order')
    ->type(TaskType::Custom)
    ->action(new ProcessOrderAction)
    ->scheduleAt(now()->addHour())
    ->unique()
    ->save();
```

### Creating Tasks

[](#creating-tasks)

You can create tasks using the `Task` facade. This is the basic requirement for a task to be executed:

```
use CheeseDriven\LaravelTasks\Task;
use CheeseDriven\LaravelTasks\Enums\TaskType;

Task::init('Mailable Task')
    ->type(TaskType::Mail)
    ->mailable(...)
    ->recipients(...)
    ->save();

Task::init('Custom Action Task')
    ->type(TaskType::Custom)
    ->action(...)
    ->save();
```

The following methods are available for creating tasks:

- `type(TaskType $type)`: Set the type of the task.
- `mailable(Mailable $mailable)`: Set the mailable of the task (only for Mail Tasks).
- `recipients(...$recipients)`: Set the recipients of the task (only for Mail Tasks).
- `action(Action $action)`: Set the action of the task (only for Custom Action Tasks).
- `scheduleAt(Carbon $date)`: Set the scheduled execution time of the task.
- `unique()`: Set the task to be unique. To prevent duplicate tasks from being created.
- `target(Model $target)`: Set the target of the task. To attach a model to the task.
- `save()`: Save the task to the database. This is required for the task to be executed.

### Custom Actions

[](#custom-actions)

Custom actions are used to execute a custom action. You can add a custom action to a task by using the `action(Action $action)` method.

```
use CheeseDriven\LaravelTasks\Task;
use CheeseDriven\LaravelTasks\Enums\TaskType;
use App\Actions\ProcessOrderAction;

Task::init('Process order')
    ->type(TaskType::Custom)
    ->action(new ProcessOrderAction)
    ->save();
```

The action must implement the `Action` interface. The `handle` method should receive the task as a parameter.

```
namespace App\Actions;

use CheeseDriven\LaravelTasks\Contracts\Action;

class ProcessOrderAction implements Action
{
    public function handle(Task $task)
    {
        try {
            // ... your custom action logic here ...

            $task->complete();
        } catch (Exception $e) {
            $task->logFailure($e->getMessage());
            return;
        }
    }
}
```

Do NOT forget to complete the task if it was successful. Otherwise the task will be executed again on the next run.

```
$task->complete();
```

You can also complete the task with a custom log message:

```
$task->complete('Order processed successfully');
```

### Custom Constraints

[](#custom-constraints)

Constraints are used to restrict if a task should be executed. You can add constraints to a task by using the `constraint(Constraint $constraint)` method.

```
use CheeseDriven\LaravelTasks\Task;
use CheeseDriven\LaravelTasks\Enums\TaskType;
use App\Constraints\MyCustomConstraint;

Task::init('Process order')
    ->type(TaskType::Custom)
    ->action(new ProcessOrderAction)
    ->constraint(new MyCustomConstraint)
    ->save();
```

Constraints must implement the `Constraint` interface. The `shouldRun` method should return a boolean value.

```
namespace App\Constraints;

use CheeseDriven\LaravelTasks\Contracts\Constraint;

class MyCustomConstraint implements Constraint
{
    public function shouldRun(Task $task): bool
    {
        return $task->targetable->isActive();
    }

    public function completeOnSkipped(): bool
    {
        return false;
    }
}
```

In the above example, the task will only be executed if the target is active. It will not be marked as completed when the constraint fails. So the task will be triggered again with the next task run.

The `completeOnSkipped` method is used to determine if the task should be marked as completed when the constraint fails. If true, the task will be completed after the task is skipped when the constraint fails.

```
namespace App\Constraints;

use CheeseDriven\LaravelTasks\Contracts\Constraint;

class MyCustomConstraint implements Constraint
{
    public function shouldRun(Task $task): bool
    {
        // ... your custom constraint logic here ...
    }

    public function completeOnSkipped(): bool
    {
        return true;
    }
}
```

For example if a model is deleted, it doesn't make sense to run the task again. So you can mark the task as completed when the constraint fails.

You can add multiple constraints to a task by using the `constraint(Constraint $constraint)` method multiple times.

```
Task::init('Process order')
    ->type(TaskType::Custom)
    ->action(new ProcessOrderAction)
    ->constraint(new MyCustomConstraint)
    ->constraint(new MyOtherCustomConstraint)
    ->save();
```

You can also add constraints to a mailable by implementing the `WithConstraints` interface in the mailable class. Instead of declaring the constraints in the task, you can declare them directly in the mailable class.

```
namespace App\Mail;

use CheeseDriven\LaravelTasks\Contracts\WithConstraints;

class MyCustomMailable implements WithConstraints
{
    public function constraints(): array
    {
        return [
            new MyCustomConstraint,
            new MyOtherCustomConstraint,
        ];
    }
}
```

In this example, the task will only be executed if these custom constraints are met.

### Task Execution

[](#task-execution)

Tasks are executed by the `tasks:run` command. This command should be scheduled in your `app/Console/Kernel.php`:

If a task has no scheduled execution time, it will be executed immediately.

### Seeding Sample Tasks

[](#seeding-sample-tasks)

To see examples of how tasks work, you can seed some sample tasks:

```
php artisan tasks:seed
```

Commands
--------

[](#commands)

The package provides several Artisan commands:

### `tasks:run`

[](#tasksrun)

Runs all tasks that are ready to be executed. This command should be scheduled in your `app/Console/Kernel.php`:

```
use CheeseDriven\LaravelTasks\Commands\RunTasksCommand;

protected function schedule(Schedule $schedule): void
{
    $schedule->command(RunTasksCommand::class)->everyThirtyMinutes();
    // or use smaller intervals like:
    // $schedule->command(RunTasksCommand::class)->everyMinute();
    // $schedule->command(RunTasksCommand::class)->everyFiveMinutes();
}
```

### `tasks:list`

[](#taskslist)

Lists tasks with their status, type, and scheduled execution time. By default, it only lists tasks that have not been executed successfully yet:

```
php artisan tasks:list
```

To include all tasks, including successful runs:

```
php artisan tasks:list --all
```

### `tasks:prune`

[](#tasksprune)

Removes old tasks and their logs. By default, it removes tasks older than 30 days:

```
php artisan tasks:prune
```

You can specify a different number of days:

```
php artisan tasks:prune --days=60
```

This will remove all tasks and their logs older than 60 days.

Scheduler Setup
---------------

[](#scheduler-setup)

**Important:** Make sure to add the `tasks:run` command to your Laravel scheduler in `app/Console/Kernel.php`:

```
use CheeseDriven\LaravelTasks\Commands\RunTasksCommand;

protected function schedule(Schedule $schedule): void
{
    $schedule->command(RunTasksCommand::class)->everyThirtyMinutes();
}
```

For more frequent task execution, you can use smaller intervals:

```
$schedule->command(RunTasksCommand::class)->everyMinute();
// or
$schedule->command(RunTasksCommand::class)->everyFiveMinutes();
```

### Upgrade Guide

[](#upgrade-guide)

#### From v.1.0.7-alpha to v.1.1.0-alpha

[](#from-v107-alpha-to-v110-alpha)

This release eliminates the use of enums for the `latest_status` and `status` columns for wider database support and future compatibility. You should manually migrate the fields to the new data type to avoid breaking changes in the future (if new statuses are added).

To do this, you should create a new migration in your project:

```
php artisan make:migration change_latest_status_and_status_to_string --table=tasks
```

and add the following code to the migration:

```
use CheeseDriven\LaravelTasks\Enums\TaskLogStatus;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::table('tasks', function (Blueprint $table) {
            $table->string('latest_status')->nullable()->change();
        });

        Schema::table('task_logs', function (Blueprint $table) {
            $table->string('status')->default(TaskLogStatus::Pending->value)->change();
        });
    }
};
```

#### From v.1.0.6-alpha to v.1.0.7-alpha

[](#from-v106-alpha-to-v107-alpha)

- Custom constraints need to implement the `completeOnSkipped` method.
- Republish the migrations to add the `skipped` status to the tasks table.

```
php artisan vendor:publish --provider="CheeseDriven\LaravelTasks\TaskServiceProvider" --tag="laravel-tasks-migrations"
```

### Testing

[](#testing)

```
composer test
```

### Security

[](#security)

If you discover any security related issues, please email  instead of using the issue tracker.

### Credits

[](#credits)

This package is heavily inspired by [BinarCode/laravel-mailator](https://github.com/BinarCode/laravel-mailator). Thanks to [Eduard Lupacescu](https://github.com/binaryk) for the original idea and implementation.

###  Health Score

42

—

FairBetter than 90% of packages

Maintenance87

Actively maintained with recent releases

Popularity20

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity45

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 87% 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 ~7 days

Total

9

Last Release

91d ago

PHP version history (2 changes)v1.0.1-alphaPHP ^8.4

v1.0.2-alphaPHP ^8.4|^8.5

### Community

Maintainers

![](https://www.gravatar.com/avatar/ad7972fc2b302ffbfb2743ff7d2ff976f60dbbf92badad4e759d80e85010af74?d=identicon)[frankmichel](/maintainers/frankmichel)

---

Top Contributors

[![frankmichel](https://avatars.githubusercontent.com/u/236225?v=4)](https://github.com/frankmichel "frankmichel (20 commits)")[![eggnaube](https://avatars.githubusercontent.com/u/1303328?v=4)](https://github.com/eggnaube "eggnaube (3 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/cheese-driven-development-laravel-tasks/health.svg)

```
[![Health](https://phpackages.com/badges/cheese-driven-development-laravel-tasks/health.svg)](https://phpackages.com/packages/cheese-driven-development-laravel-tasks)
```

###  Alternatives

[barryvdh/laravel-ide-helper

Laravel IDE Helper, generates correct PHPDocs for all Facade classes, to improve auto-completion.

14.9k123.0M687](/packages/barryvdh-laravel-ide-helper)[orchestra/canvas

Code Generators for Laravel Applications and Packages

20917.2M158](/packages/orchestra-canvas)[kirschbaum-development/commentions

A package to allow you to create comments, tag users and more

12369.2k](/packages/kirschbaum-development-commentions)[aedart/athenaeum

Athenaeum is a mono repository; a collection of various PHP packages

245.2k](/packages/aedart-athenaeum)[glhd/special

1929.4k](/packages/glhd-special)[bjuppa/laravel-blog

Add blog functionality to your Laravel project

483.3k2](/packages/bjuppa-laravel-blog)

PHPackages © 2026

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