1. Go to this page and download the library: Download andydefer/laravel-task 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/ */
andydefer / laravel-task example snippets
use AndyDefer\Directive\DirectiveKernel;
$kernel = DirectiveKernel::init($app);
$kernel->addSource('/path/to/directives');
// Exécution d'une directive
$exitCode = $kernel->run(['directive', 'tasks:process']);
use AndyDefer\Task\Contracts\Services\UniqueTaskServiceInterface;
use AndyDefer\Task\Contracts\Services\RecurringTaskServiceInterface;
use AndyDefer\Task\Records\UniqueTaskConfigRecord;
use AndyDefer\Task\Records\RecurringTaskConfigRecord;
class MyService
{
public function __construct(
private readonly UniqueTaskServiceInterface $uniqueService,
private readonly RecurringTaskServiceInterface $recurringService
) {}
}
namespace App\Tasks;
use AndyDefer\Task\Abstract\AbstractUniqueTask;
use AndyDefer\Task\ValueObjects\DescriptionVO;
use AndyDefer\DomainStructures\Utils\StrictDataObject;
class SendWelcomeEmailTask extends AbstractUniqueTask
{
// ✅ Hook exécuté avant process() - idéal pour la validation
protected function before(StrictDataObject $payload): void
{
if (!$payload->has('email')) {
throw new \InvalidArgumentException('Email is ook exécuté après process() - idéal pour la notification
protected function after(bool $success, ?DescriptionVO $error = null): void
{
if ($success) {
$this->info(new DescriptionVO('Task completed successfully'));
} else {
$this->error(new DescriptionVO("Task failed: {$error->getValue()}"));
// Envoyer une alerte, logger, etc.
}
}
}
namespace App\Http\Controllers;
use AndyDefer\Task\Contracts\Services\UniqueTaskServiceInterface;
use AndyDefer\Task\Records\UniqueTaskConfigRecord;
use AndyDefer\Task\ValueObjects\UniqueTaskFqcnVO;
use AndyDefer\DomainStructures\Utils\StrictDataObject;
use AndyDefer\Task\ValueObjects\Iso8601DateTimeVO;
use AndyDefer\Task\ValueObjects\MaxAttemptsVO;
use AndyDefer\Task\ValueObjects\DurationVO;
class UserController extends Controller
{
public function __construct(
private readonly UniqueTaskServiceInterface $taskService
) {}
public function store(Request $request)
{
// Création de l'utilisateur...
// ✅ Enregistrement de la tâche avec UniqueTaskConfigRecord
$config = UniqueTaskConfigRecord::from([
'scheduled_at' => new Iso8601DateTimeVO(now()->addMinutes(5)),
'max_attempts' => new MaxAttemptsVO(3),
'grace_period' => new DurationVO(3600), // 1h
]);
$payload = StrictDataObject::from([
'email' => $request->email,
'name' => $request->name,
]);
$alias = $this->taskService->register(
new UniqueTaskFqcnVO(SendWelcomeEmailTask::class),
$payload,
$config
);
return response()->json([
'message' => 'Email planifié dans 5 minutes',
'task_alias' => $alias->getValue(),
]);
}
}
namespace App\Tasks;
use AndyDefer\Task\Abstract\AbstractRecurringTask;
use AndyDefer\Task\ValueObjects\DescriptionVO;
class CleanExpiredCacheTask extends AbstractRecurringTask
{
protected function process(): void
{
$this->info(new DescriptionVO('Starting cache cleanup...'));
// ✅ Ici votre code métier exécuté à chaque intervalle
// Cache::cleanExpired();
$this->info(new DescriptionVO('Cache cleaned successfully'));
}
protected function after(bool $success, ?DescriptionVO $error = null): void
{
if (!$success) {
$this->error(new DescriptionVO("Cleanup failed: {$error->getValue()}"));
// ✅ Alerter l'équipe, envoyer un email, etc.
}
}
}
namespace App\Console\Commands;
use AndyDefer\Task\Contracts\Services\RecurringTaskServiceInterface;
use AndyDefer\Task\Records\RecurringTaskConfigRecord;
use AndyDefer\Task\ValueObjects\RecurringTaskFqcnVO;
use AndyDefer\DomainStructures\Utils\StrictDataObject;
use AndyDefer\Task\ValueObjects\DurationVO;
use AndyDefer\Task\ValueObjects\Iso8601DateTimeVO;
use AndyDefer\Task\ValueObjects\MaxFailedAttemptsVO;
class SetupTasksCommand extends Command
{
public function __construct(
private readonly RecurringTaskServiceInterface $taskService
) {
parent::__construct();
}
public function handle()
{
// ✅ Nettoyage toutes les heures, pendant 30 jours
$config = RecurringTaskConfigRecord::from([
'interval_seconds' => new DurationVO(3600), // Toutes les heures
'start_at' => new Iso8601DateTimeVO(now()->toIso8601String()),
'end_at' => new Iso8601DateTimeVO(now()->addDays(30)->toIso8601String()),
'max_attempts' => new MaxFailedAttemptsVO(3),
]);
$alias = $this->taskService->register(
new RecurringTaskFqcnVO(CleanExpiredCacheTask::class),
StrictDataObject::from(['enabled' => true]),
$config
);
$this->info("Task registered: {$alias->getValue()}");
}
}
use AndyDefer\Directive\DirectiveKernel;
use AndyDefer\Directive\Enums\ExitCode;
$kernel = DirectiveKernel::init($app);
// Par signature complète
$exitCode = $kernel->runSignature('tasks:process 50 --unique-only --verbose');
// Par FQCN
$exitCode = $kernel->runDirective(
'AndyDefer\Task\Directives\TasksProcessDirective',
['50', '--unique-only']
);
// Par arguments bruts (comme en ligne de commande)
$exitCode = $kernel->run(['directive', 'tasks:process', '50', '--unique-only']);
$kernel = DirectiveKernel::init($app);
// Définir des données dans le contexte
$context = $kernel->getContext();
$context->put('user_id', 12345);
$context->put('batch_id', 'batch-abc-123');
// Exécuter une directive qui utilise le contexte
$kernel->run(['directive', 'process:user']);
// Récupérer les résultats du contexte
$result = $context->get('process_result');
namespace App\Services;
use AndyDefer\Task\Contracts\Services\UniqueTaskServiceInterface;
use AndyDefer\Task\Contracts\Services\RecurringTaskServiceInterface;
use AndyDefer\Task\ValueObjects\TaskAliasVO;
use AndyDefer\Task\ValueObjects\DurationVO;
use AndyDefer\Task\ValueObjects\DescriptionVO;
use AndyDefer\Task\ValueObjects\Iso8601DateTimeVO;
use AndyDefer\Task\ValueObjects\LimitVO;
class TaskManager
{
public function __construct(
private readonly UniqueTaskServiceInterface $uniqueService,
private readonly RecurringTaskServiceInterface $recurringService
) {}
// === TÂCHES UNIQUES ===
// ✅ Annuler une tâche unique
public function cancelUnique(string $alias): void
{
$this->uniqueService->cancel(
new TaskAliasVO($alias),
new DescriptionVO('Canceled by admin')
);
}
// ✅ Reprogrammer à une autre date
public function reschedule(string $alias, Iso8601DateTimeVO $newDate): void
{
$this->uniqueService->reschedule(
new TaskAliasVO($alias),
$newDate
);
}
// ✅ Prolonger la période de grâce
public function extendGracePeriod(string $alias, DurationVO $extraSeconds): void
{
$this->uniqueService->extendGracePeriod(
new TaskAliasVO($alias),
$extraSeconds
);
}
// ✅ Exécuter une tâche unique manuellement
public function runUnique(string $alias): TaskRunResultRecord
{
return $this->uniqueService->run(new TaskAliasVO($alias));
}
// === TÂCHES RÉCURRENTES ===
// ✅ Mettre en pause
public function pause(string $alias): void
{
$this->recurringService->pause(new TaskAliasVO($alias));
}
// ✅ Reprendre
public function resume(string $alias): void
{
$this->recurringService->resume(new TaskAliasVO($alias));
}
// ✅ Changer l'intervalle
public function changeInterval(string $alias, DurationVO $interval): void
{
$this->recurringService->changeInterval(
new TaskAliasVO($alias),
$interval
);
}
// ✅ Terminer définitivement
public function finish(string $alias): void
{
$this->recurringService->finish(new TaskAliasVO($alias));
}
// ✅ Prolonger la date de fin
public function extendEndAt(string $alias, Iso8601DateTimeVO $newEndAt): void
{
$this->recurringService->extendEndAt(
new TaskAliasVO($alias),
$newEndAt
);
}
// === INSPECTION ===
// ✅ Récupérer une tâche
public function findUnique(string $alias): ?UniqueTaskRecord
{
return $this->uniqueService->find(new TaskAliasVO($alias));
}
public function findRecurring(string $alias): ?RecurringTaskRecord
{
return $this->recurringService->find(new TaskAliasVO($alias));
}
// ✅ Compter les tâches
public function getStats(): array
{
return [
'unique_pending' => $this->uniqueService->countPending()->getValue(),
'unique_completed' => $this->uniqueService->countCompleted()->getValue(),
'unique_failed' => $this->uniqueService->countFailed()->getValue(),
'unique_canceled' => $this->uniqueService->countCanceled()->getValue(),
'recurring_waiting' => $this->recurringService->countWaiting()->getValue(),
'recurring_playing' => $this->recurringService->countPlaying()->getValue(),
'recurring_paused' => $this->recurringService->countPaused()->getValue(),
'recurring_finished' => $this->recurringService->countFinished()->getValue(),
'recurring_canceled' => $this->recurringService->countCanceled()->getValue(),
];
}
}
namespace App\Services;
use AndyDefer\Task\Contracts\Services\UniqueTaskServiceInterface;
use AndyDefer\Task\Records\UniqueTaskConfigRecord;
use AndyDefer\Task\ValueObjects\UniqueTaskFqcnVO;
use AndyDefer\Task\ValueObjects\Iso8601DateTimeVO;
use AndyDefer\Task\ValueObjects\MaxAttemptsVO;
use AndyDefer\Task\ValueObjects\DurationVO;
use AndyDefer\DomainStructures\Utils\StrictDataObject;
class SubscriptionService
{
public function __construct(
private readonly UniqueTaskServiceInterface $taskService
) {}
public function createSubscription(User $user, Plan $plan): void
{
// ✅ Rappel J-1 avant expiration
$this->taskService->register(
new UniqueTaskFqcnVO(RenewalReminderTask::class),
StrictDataObject::from([
'user_id' => $user->id,
'email' => $user->email,
'plan' => $plan->name,
]),
UniqueTaskConfigRecord::from([
'scheduled_at' => new Iso8601DateTimeVO($user->subscription_end_at->subDay()),
'max_attempts' => new MaxAttemptsVO(2),
'grace_period' => new DurationVO(3600),
])
);
// ✅ Désactivation à la date d'expiration
$this->taskService->register(
new UniqueTaskFqcnVO(ExpireSubscriptionTask::class),
StrictDataObject::from([
'user_id' => $user->id,
]),
UniqueTaskConfigRecord::from([
'scheduled_at' => new Iso8601DateTimeVO($user->subscription_end_at),
'max_attempts' => new MaxAttemptsVO(3),
'grace_period' => new DurationVO(7200),
])
);
// ✅ Relance en cas de paiement échoué
$this->taskService->register(
new UniqueTaskFqcnVO(PaymentRetryTask::class),
StrictDataObject::from([
'user_id' => $user->id,
'payment_id' => $payment->id,
]),
UniqueTaskConfigRecord::from([
'scheduled_at' => new Iso8601DateTimeVO(now()->addHours(24)),
'max_attempts' => new MaxAttemptsVO(3),
'grace_period' => new DurationVO(86400),
])
);
}
}
namespace App\Services;
use AndyDefer\Task\Contracts\Services\UniqueTaskServiceInterface;
use AndyDefer\Task\Records\UniqueTaskConfigRecord;
use AndyDefer\Task\ValueObjects\UniqueTaskFqcnVO;
use AndyDefer\Task\ValueObjects\Iso8601DateTimeVO;
use AndyDefer\Task\ValueObjects\MaxAttemptsVO;
use AndyDefer\Task\ValueObjects\DurationVO;
use AndyDefer\DomainStructures\Utils\StrictDataObject;
class AbandonedCartService
{
public function __construct(
private readonly UniqueTaskServiceInterface $uniqueService
) {}
public function handleAbandonedCart(Cart $cart, User $user): void
{
// ✅ Email de relance 30 min après abandon
$this->uniqueService->register(
new UniqueTaskFqcnVO(AbandonedCartReminderTask::class),
StrictDataObject::from([
'cart_id' => $cart->id,
'user_id' => $user->id,
'items' => $cart->items,
]),
UniqueTaskConfigRecord::from([
'scheduled_at' => new Iso8601DateTimeVO(now()->addMinutes(30)),
'max_attempts' => new MaxAttemptsVO(2),
'grace_period' => new DurationVO(3600),
])
);
// ✅ Email de suivi J+3
$this->uniqueService->register(
new UniqueTaskFqcnVO(FollowUpEmailTask::class),
StrictDataObject::from([
'user_id' => $user->id,
'cart_id' => $cart->id,
]),
UniqueTaskConfigRecord::from([
'scheduled_at' => new Iso8601DateTimeVO(now()->addDays(3)),
'max_attempts' => new MaxAttemptsVO(2),
'grace_period' => new DurationVO(3600),
])
);
}
}
namespace App\Services;
use AndyDefer\Task\Contracts\Services\UniqueTaskServiceInterface;
use AndyDefer\Task\Records\UniqueTaskConfigRecord;
use AndyDefer\Task\ValueObjects\UniqueTaskFqcnVO;
use AndyDefer\Task\ValueObjects\Iso8601DateTimeVO;
use AndyDefer\Task\ValueObjects\MaxAttemptsVO;
use AndyDefer\Task\ValueObjects\DurationVO;
class WebhookService
{
public function __construct(
private readonly UniqueTaskServiceInterface $uniqueService
) {}
public function sendWebhook($event, $data): string
{
// ✅ Appel API avec retry automatique
$config = UniqueTaskConfigRecord::from([
'scheduled_at' => new Iso8601DateTimeVO(now()->addSeconds(5)),
'max_attempts' => new MaxAttemptsVO(5),
'grace_period' => new DurationVO(7200), // 2h
]);
$alias = $this->uniqueService->register(
new UniqueTaskFqcnVO(SendWebhookTask::class),
StrictDataObject::from([
'url' => config('webhooks.endpoint'),
'event' => $event,
'data' => $data,
]),
$config
);
return $alias->getValue();
}
}
namespace App\Services;
use AndyDefer\Task\Contracts\Services\RecurringTaskServiceInterface;
use AndyDefer\Task\Contracts\Services\UniqueTaskServiceInterface;
use AndyDefer\Task\Records\RecurringTaskConfigRecord;
use AndyDefer\Task\Records\UniqueTaskConfigRecord;
use AndyDefer\Task\ValueObjects\RecurringTaskFqcnVO;
use AndyDefer\Task\ValueObjects\UniqueTaskFqcnVO;
use AndyDefer\Task\ValueObjects\DurationVO;
use AndyDefer\Task\ValueObjects\Iso8601DateTimeVO;
use AndyDefer\Task\ValueObjects\MaxFailedAttemptsVO;
use AndyDefer\Task\ValueObjects\MaxAttemptsVO;
class MaintenanceService
{
public function __construct(
private readonly RecurringTaskServiceInterface $recurringService,
private readonly UniqueTaskServiceInterface $uniqueService
) {}
public function scheduleMaintenance(): void
{
// ✅ Nettoyage toutes les heures
$this->recurringService->register(
new RecurringTaskFqcnVO(CacheCleanTask::class),
StrictDataObject::from(['enabled' => true]),
RecurringTaskConfigRecord::from([
'interval_seconds' => new DurationVO(3600),
'start_at' => new Iso8601DateTimeVO(now()->toIso8601String()),
'max_attempts' => new MaxFailedAttemptsVO(3),
])
);
// ✅ Backup DB à 2h du matin
$this->uniqueService->register(
new UniqueTaskFqcnVO(BackupDatabaseTask::class),
StrictDataObject::from([
'database' => config('database.connections.mysql.database'),
'backup_path' => storage_path('backups'),
]),
UniqueTaskConfigRecord::from([
'scheduled_at' => new Iso8601DateTimeVO(Carbon::now()->setTime(2, 0)),
'max_attempts' => new MaxAttemptsVO(1),
'grace_period' => new DurationVO(3600),
])
);
}
}
namespace App\Services;
use AndyDefer\Task\Contracts\Services\UniqueTaskServiceInterface;
use AndyDefer\Task\Records\UniqueTaskConfigRecord;
use AndyDefer\Task\ValueObjects\UniqueTaskFqcnVO;
use AndyDefer\Task\ValueObjects\Iso8601DateTimeVO;
use AndyDefer\Task\ValueObjects\MaxAttemptsVO;
use AndyDefer\Task\ValueObjects\DurationVO;
class OrderWorkflowService
{
public function __construct(
private readonly UniqueTaskServiceInterface $uniqueService
) {}
public function processOrder(Order $order): void
{
$payload = StrictDataObject::from([
'order_id' => $order->id,
'user_id' => $order->user_id,
'total' => $order->total,
]);
$steps = [
ValidateOrderTask::class => now()->addSeconds(10),
ProcessPaymentTask::class => now()->addSeconds(30),
GenerateInvoiceTask::class => now()->addMinutes(1),
SendConfirmationTask::class => now()->addMinutes(2),
];
foreach ($steps as $class => $scheduledAt) {
$this->uniqueService->register(
new UniqueTaskFqcnVO($class),
$payload,
UniqueTaskConfigRecord::from([
'scheduled_at' => new Iso8601DateTimeVO($scheduledAt),
'max_attempts' => new MaxAttemptsVO(2),
'grace_period' => new DurationVO(3600),
])
);
}
}
}
namespace App\Services;
use AndyDefer\Task\Contracts\Services\RecurringTaskServiceInterface;
use AndyDefer\Task\Records\RecurringTaskConfigRecord;
use AndyDefer\Task\ValueObjects\RecurringTaskFqcnVO;
use AndyDefer\Task\ValueObjects\DurationVO;
use AndyDefer\Task\ValueObjects\Iso8601DateTimeVO;
use AndyDefer\Task\ValueObjects\MaxFailedAttemptsVO;
class CampaignService
{
public function __construct(
private readonly RecurringTaskServiceInterface $recurringService
) {}
public function startCampaign(Campaign $campaign): void
{
// ✅ Newsletter hebdomadaire sur 4 semaines
$this->recurringService->register(
new RecurringTaskFqcnVO(NewsletterTask::class),
StrictDataObject::from([
'campaign_id' => $campaign->id,
'template' => $campaign->template,
]),
RecurringTaskConfigRecord::from([
'interval_seconds' => new DurationVO(604800), // 7 jours
'start_at' => new Iso8601DateTimeVO(now()->toIso8601String()),
'end_at' => new Iso8601DateTimeVO(now()->addWeeks(4)->toIso8601String()),
'max_attempts' => new MaxFailedAttemptsVO(2),
])
);
}
}
// BON
class UserController
{
public function __construct(
private readonly UniqueTaskServiceInterface $taskService
) {}
}
// BON
new Iso8601DateTimeVO(now()->addMinutes(5))
// ÉVITER
$config['scheduled_at'] = now()->addMinutes(5);