PHP code example of maestrodimateo / laravel-workflow
1. Go to this page and download the library: Download maestrodimateo/laravel-workflow 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/ */
maestrodimateo / laravel-workflow example snippets
use Illuminate\Database\Eloquent\Concerns\HasUuids;
use Illuminate\Database\Eloquent\Model;
use Maestrodimateo\Workflow\Traits\Workflowable;
class Invoice extends Model
{
use HasUuids, Workflowable;
}
use Maestrodimateo\Workflow\Facades\Workflow;
// Get current status
$basket = Workflow::for($invoice)->currentStatus();
echo $basket->name; // "Brouillon"
echo $basket->status; // "DRAFT"
// See available next steps
$options = Workflow::for($invoice)->nextBaskets();
// Transition
Workflow::for($invoice)->transition(
$nextBasket->id,
'Approved by manager', // optional comment
);
// Circuits accessible to a role
Workflow::circuitsForRole('manager');
Workflow::circuitsForRoles(['admin', 'manager']);
// Baskets accessible to a role (optionally scoped to a circuit)
Workflow::basketsForRole('validator');
Workflow::basketsForRole('validator', $circuitId);
Workflow::basketsForRoles(['admin', 'operator'], $circuitId);
use Maestrodimateo\Workflow\Models\Circuit;
use Maestrodimateo\Workflow\Models\Basket;
Circuit::forRole('admin')->get();
Basket::forRoles(['admin', 'manager'])->get();
$basket->hasRole('validator'); // true/false
$circuit->hasRole('admin'); // true/false
$history = Workflow::for($invoice)->history();
foreach ($history as $entry) {
echo $entry->previous_status; // "DRAFT"
echo $entry->next_status; // "REVIEW"
echo $entry->duration_seconds; // 3600
echo $entry->duration_human; // "1h"
echo $entry->done_by; // User ID
echo $entry->comment; // "Sent for review"
}
// Total time
$seconds = Workflow::for($invoice)->totalDuration();
// Time in a specific step
$reviewTime = Workflow::for($invoice)->durationInStatus('REVIEW');
// Scope to a specific circuit
Workflow::for($invoice)->in($approvalCircuit)->currentStatus();
Workflow::for($invoice)->in($complianceCircuit)->transition($basketId);
Workflow::for($invoice)->in('circuit-uuid')->history();
// See status in ALL circuits at once
$statuses = Workflow::for($invoice)->allStatuses();
// [
// 'circuit-a-id' => ['circuit' => Circuit, 'basket' => Basket],
// 'circuit-b-id' => ['circuit' => Circuit, 'basket' => Basket],
// ]
// List circuits the model belongs to
$circuits = Workflow::for($invoice)->circuits();
// Lock the model (default: 30 minutes)
Workflow::for($invoice)->lock();
Workflow::for($invoice)->lock(60); // 1 hour
// Check lock status
Workflow::for($invoice)->isLocked(); // true
Workflow::for($invoice)->isLockedByMe(); // true
Workflow::for($invoice)->lockedBy(); // "user-uuid"
Workflow::for($invoice)->lockExpiration(); // Carbon instance
// Transition (auto-checks the lock)
Workflow::for($invoice)->transition($basketId);
// → OK if you hold the lock (lock is released after transition)
// → ModelLockedException if locked by someone else
// Release manually
Workflow::for($invoice)->unlock();
// Admin force unlock
Workflow::for($invoice)->unlock(force: true);
// Available models (not locked or lock expired)
Invoice::fromBasket($reviewBasket)->unlocked()->get();
// Models I'm working on
Invoice::lockedBy(auth()->id())->get();
use Maestrodimateo\Workflow\Exceptions\ModelLockedException;
try {
Workflow::for($invoice)->transition($basketId);
} catch (ModelLockedException $e) {
return back()->withErrors([
'lock' => $e->getMessage(),
// "Ce dossier est verrouillé par [user] jusqu'à [14:30]."
]);
}
use Maestrodimateo\Workflow\Contracts\TransitionAction;
class GeneratePdfAction implements TransitionAction
{
public static function key(): string { return 'generate_pdf'; }
public static function label(): string { return 'Generate Pdf'; }
public function execute(Model $model, Basket $from, Basket $to, array $config = []): void
{
// Your logic here
}
}
use Maestrodimateo\Workflow\Facades\Workflow;
// In a seeder
Workflow::importFromJson(database_path('seeders/workflow-invoices.json'));
// Or via the manager directly
app(\Maestrodimateo\Workflow\WorkflowManager::class)::importFromJson($path);
$invoice->baskets; // Collection<Basket> — all baskets the model is/has been in
$invoice->histories; // Collection<History> — all transition history entries
$invoice->workflowLock; // WorkflowLock|null — the active lock on this model
// Current status (last basket attached)
$invoice->currentStatus(); // ?Basket — across all circuits
$invoice->currentStatus($circuit); // ?Basket — in a specific circuit
$invoice->currentStatus('circuit-uuid'); // same with a string ID
// Inspect the current basket
$invoice->currentStatus()->status; // "REVIEW"
$invoice->currentStatus()->name; // "Under Review"
$invoice->currentStatus()->color; // "#2563eb"
$invoice->currentStatus()->roles; // ["manager", "validator"]
$invoice->currentStatus()->hasRole('manager'); // true
// Access the circuit
$invoice->currentStatus()->circuit->name; // "Invoice Approval"
// Navigate the workflow graph
$invoice->currentStatus()->next; // Collection<Basket> — possible next steps
$invoice->currentStatus()->previous; // Collection<Basket> — where it came from
// History with duration tracking
$invoice->histories->each(function ($h) {
$h->previous_status; // "DRAFT"
$h->next_status; // "REVIEW"
$h->comment; // "Sent for review"
$h->done_by; // "user-uuid"
$h->duration_seconds; // 3600
$h->duration_human; // "1h"
$h->created_at; // Carbon
});
// Lock info
$invoice->workflowLock?->locked_by; // "user-uuid" or null
$invoice->workflowLock?->expires_at; // Carbon or null
$invoice->workflowLock?->isActive(); // true if not expired
// Models currently in a specific basket
Invoice::fromBasket($reviewBasket)->get();
// Available models (not locked or lock expired)
Invoice::unlocked()->get();
// Models locked by a specific user
Invoice::lockedBy(auth()->id())->get();
// Combine scopes
Invoice::fromBasket($reviewBasket)->unlocked()->get();
$invoice = Invoice::create(['number' => 'INV-001']);
$invoice->currentStatus()->status; // "DRAFT" — automatic
$invoice->baskets->count(); // 1 (or more if multiple circuits)