1. Go to this page and download the library: Download jodeveloper/approval-flow 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/ */
jodeveloper / approval-flow example snippets
namespace App\Enums;
use jodeveloper\ApprovalFlow\Contracts\ApprovalStatusInterface;
use jodeveloper\ApprovalFlow\DataTransferObjects\ApprovalFlowStep;
enum DocumentStatuses: string implements ApprovalStatusInterface
{
case DRAFT = 'DRAFT';
case MANAGER_REVIEW = 'MANAGER_REVIEW';
case DIRECTOR_REVIEW = 'DIRECTOR_REVIEW';
case APPROVED = 'APPROVED';
case REJECTED = 'REJECTED';
public static function getApprovalFlow(): array
{
return [
self::DRAFT->name => new ApprovalFlowStep(
permission: null, // No permission elf::DIRECTOR_REVIEW->value => self::REJECTED->value,
];
}
public static function getCompletedStatus(): string
{
return self::APPROVED->value;
}
/**
* Define simple status transitions that bypass the approval workflow.
* Use this for automatic transitions that don't
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use jodeveloper\ApprovalFlow\Traits\HasApprovalFlow;
class Document extends Model
{
use HasApprovalFlow;
protected $fillable = [
'title',
'content',
'status_id',
'approval_comment',
'rejection_note',
];
public function status()
{
return $this->belongsTo(Status::class);
}
public static function getStatusEnum(): string
{
return DocumentStatuses::class;
}
public static function getStatus(string $code)
{
return Status::where('code', $code)->first();
}
}
namespace App\Http\Controllers;
use App\Models\Document;
use Illuminate\Http\Request;
class DocumentApprovalController extends Controller
{
public function approve(Request $request, Document $document)
{
if (!$document->canApprove()) {
return response()->json(['error' => 'Unauthorized'], 403);
}
if ($document->approve($request->comment)) {
return response()->json([
'message' => 'Document approved successfully',
'status' => $document->fresh()->status->name
]);
}
return response()->json(['error' => 'Could not approve document'], 400);
}
public function reject(Request $request, Document $document)
{
$request->validate(['note' => '
$document = Document::find(1);
// Check permissions
if ($document->canApprove()) {
$document->approve('Looks good!');
}
if ($document->canReject()) {
$document->reject('Please revise section 3');
}
// Check status
if ($document->isCompleted()) {
// Document is fully approved
}
if ($document->isInApprovalProcess()) {
$step = $document->getCurrentApprovalStep();
echo "Waiting for: " . $step->role;
}
// In your EventServiceProvider
use jodeveloper\ApprovalFlow\Events\ModelApproved;
use jodeveloper\ApprovalFlow\Events\ModelRejected;
protected $listen = [
ModelApproved::class => [
SendApprovalNotification::class,
],
ModelRejected::class => [
SendRejectionNotification::class,
],
];
namespace App\Listeners;
use jodeveloper\ApprovalFlow\Events\ModelApproved;
use Illuminate\Support\Facades\Mail;
class SendApprovalNotification
{
public function handle(ModelApproved $event): void
{
// Send notification to next approver or completion notification
$model = $event->model;
$nextStep = $model->getCurrentApprovalStep();
if ($nextStep) {
// Notify next approver
Mail::to($nextStep->role)->send(new ApprovalNeeded($model));
} else {
// Notify completion
Mail::to($model->user)->send(new ApprovalCompleted($model));
}
}
}
// Get approval history for a model
$history = $document->approvalHistory;
foreach ($history as $log) {
echo "{$log->user->name} {$log->action} on {$log->created_at}";
if ($log->comment) {
echo " - Comment: {$log->comment}";
}
}
enum DocumentStatuses: string implements ApprovalStatusInterface
{
case DRAFT = 'DRAFT';
case ON_HOLD = 'ON_HOLD';
case ARCHIVED = 'ARCHIVED';
case AUTO_APPROVED = 'AUTO_APPROVED';
case EXPIRED = 'EXPIRED';
// ... other cases
public static function getStatusTransitions(): array
{
return [
// Simple transitions without permissions
self::DRAFT->name => self::ON_HOLD->name,
self::ON_HOLD->name => self::DRAFT->name,
// Automatic system transitions
self::AUTO_APPROVED->name => self::APPROVED->name,
self::EXPIRED->name => self::ARCHIVED->name,
];
}
// ... other methods
}
namespace App\Models;
use jodeveloper\ApprovalFlow\Models\ApprovalLog as BaseApprovalLog;
class CustomApprovalLog extends BaseApprovalLog
{
protected $fillable = [
...parent::$fillable,
'department',
'priority',
];
// Add custom relationships or methods
public function department()
{
return $this->belongsTo(Department::class);
}
}