PHP code example of padosoft / laravel-routines

1. Go to this page and download the library: Download padosoft/laravel-routines library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

padosoft / laravel-routines example snippets


use Padosoft\Routines\Contracts\Target\{RoutineTarget, TargetDescriptor, TargetResult, ValidationResult};
use Padosoft\Routines\Contracts\Execution\RoutineExecution;

final class SendDigestTarget implements RoutineTarget
{
    public function type(): string { return 'digest'; }

    public function descriptor(): TargetDescriptor
    {
        return new TargetDescriptor(
            label: 'Digest by email',
            summary: 'Sends the period summary to an address.',
            fields: ['email' => ['label' => 'Recipient', 'type' => 'email', 's retries:
        // it is what stops the second email from going out after a timeout.
        Mail::to($execution->payload('email'))->send(
            new Digest($execution->scheduledFor, $execution->timezone, $execution->idempotencyKey)
        );

        return TargetResult::succeeded('Digest sent.', cost: 0.001);
    }
}

$this->app->make(TargetRegistry::class)->register(new SendDigestTarget);

$routine = app(RoutineManager::class)->create([
    'owner'          => 'user:'.$user->id,
    'name'           => 'Morning digest',
    'target_type'    => 'digest',
    'target_payload' => ['email' => $user->email],
    'trigger_kind'   => 'cron',
    'cron'           => '0 6 * * 1-5',
    'timezone'       => 'Europe/Rome',   // THEIR 6am, not 6am UTC
    'budget_per_run' => 0.50,
    'max_attempts'   => 3,
]);

app(RoutineManager::class)->preview($routine, 5);
// ["2026-09-01 06:00", "2026-09-02 06:00", …] — in the owner's timezone

// From your EventServiceProvider
Event::listen(OrderPlaced::class, function (OrderPlaced $event): void {
    app(EventTrigger::class)->handle('order.placed', $event);
});

$secret = app(RoutineManager::class)->rotateWebhookSecret($routine);
// Returned in clear ONCE: from here on it only exists encrypted in its column.

'budget_per_run'    => 0.50,
'budget_per_period' => 20.00,
'budget_period'     => 'month',   // day | week | month

// config/routines.php
'lock_seconds'       => 900,   // longer than the slowest fire you expect
'catch_up_cap'       => 25,    // a downtime must not become a swarm
'retry_base_seconds' => 60,    // exponential backoff: 1', 2', 4', 8'…

'targets' => [
    'job' => [
        'enabled' => true,
        // Empty by default, and deliberately so.
        'allowed' => [App\Jobs\SendDailyDigest::class],
    ],
],

use Padosoft\Routines\Testing\TargetContract;

final class InvoiceReminderTargetTest extends TestCase
{
    public function test_it_respects_the_routine_target_contract(): void
    {
        TargetContract::assertAll(
            new InvoiceReminderTarget(...),
            validPayload: ['template' => 'reminder'],
            invalidPayload: ['template' => ''],
            // The "outside the mandate" case is expressed either as fire input or as
            // configuration, because real targets decide in both ways:
            outOfMandatePayload: ['template' => 'reminder', 'write_off_days' => 365],
        );
    }
}
bash
composer vendor:publish --tag=routines-migrations
php artisan migrate