PHP code example of jodeveloper / approval-flow

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;
}

use jodeveloper\ApprovalFlow\ApprovalFlowManager;

$manager = app(ApprovalFlowManager::class);

// Bulk approve multiple documents
$documents = Document::where('status_id', $pendingStatusId)->get();
$results = $manager->bulkApprove($documents, 'Batch approval');

// Results contain success and failed arrays
echo "Approved: " . count($results['success']);
echo "Failed: " . count($results['failed']);

$manager = app(ApprovalFlowManager::class);
$stats = $manager->getApprovalStats($document);

/*
Array output:
[
    'total_approvals' => 2,
    'total_rejections' => 1,
    'current_status' => 'MANAGER_REVIEW',
    'is_completed' => false,
    'can_approve' => true,
    'can_reject' => true,
    'next_step' => 'Manager'
]
*/

// 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);
    }
}

// config/approval-flow.php
return [
    'models' => [
        'approval_log' => \App\Models\CustomApprovalLog::class,
    ],
    // ...
];

// In your .env file
APPROVAL_FLOW_LOG_ENABLED=false

// Or in config/approval-flow.php
'log_approvals' => false,
bash
php artisan vendor:publish --tag="approval-flow-migrations"
php artisan migrate
bash
php artisan vendor:publish --tag="approval-flow-config"
bash
php artisan make:approval-flow Document

src/
├── ApprovalFlowServiceProvider.php
├── ApprovalFlowManager.php
├── Commands/
│   └── MakeApprovalFlowCommand.php
├── Contracts/
│   └── ApprovalStatusInterface.php
├── DataTransferObjects/
│   └── ApprovalFlowStep.php
├── Events/
│   ├── ModelApproved.php
│   └── ModelRejected.php
├── Exceptions/
│   └── ApprovalFlowException.php
├── Listeners/
│   └── LogApprovalActivity.php
├── Models/
│   └── ApprovalLog.php
└── Traits/
    └── HasApprovalFlow.php