PHP code example of soap / eloquent-workflow

1. Go to this page and download the library: Download soap/eloquent-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/ */

    

soap / eloquent-workflow example snippets


return [
];

class ArticleWorkflow extends \Soap\EloquentWorkflow\WorkflowBlueprint
{
    public function states(): array
    {
        return [
            'new',
            'review',
            'published',
            'correction',
        ];
    }
    
    public function transitions(): array
    {
        return [
            ['new', 'review'],
            ['review', 'published'],
            ['review', 'correction'],
            ['correction', 'review']
        ];
    }
}

use \Soap\EloquentWorkflow\Example\Enum;
use \Soap\EloquentWorkflow\Example\ArticleWorkflow;
use \Soap\EloquentWorkflow\StateMachineEngine;

class Article extends Model
{
    use \Soap\EloquentWorkflow\Traits\HasWorkflow;
    
    public function state(): StateMachineEngine
    {
        return $this->workflow(ArticleWorkflow::class, 'state');
    }
}

use \Soap\EloquentWorkflow\Example\Enum;

// creating: will set proper initial state
$article = new \Soap\EloquentWorkflow\Example\Article();
$article->save();
assert($article->state == 'new');

// updating: will examine state machine consistency
$article->state = 'review';
$article->save();
// No exceptions thrown
assert($article->state == 'review');

use \Soap\EloquentWorkflow\State;
use \Soap\EloquentWorkflow\Transition;

class ArticleWorkflow extends \Soap\EloquentWorkflow\WorkflowBlueprint
{
    public function states(): array
    {
        return [
            State::make('new'),
            State::make('review'),
            State::make('published'),
            State::make('correction'),
        ];
    }
    
    public function transitions(): array
    {
        return [
            Transition::make('new', 'review'),
            Transition::make('review', 'published'),
            Transition::make('review', 'correction'),
            Transition::make('correction', 'review'),
        ];
    }
}

use \Soap\EloquentWorkflow\Transition;

Transition::make('new', 'review')
    ->authorizedBy('transit');

use \Soap\EloquentWorkflow\Transition;
use \Illuminate\Support\Facades\Gate;

Transition::make('new', 'review')
    ->authorizedBy(fn(Article $article) => Gate::allows('transit', $article));

$article = new \Soap\EloquentWorkflow\Example\Article();

$transitions = $article->state()
    // Get transitions from model's current state.
    ->transitions()
    // Filter only authorized transitions. 
    ->onlyAuthorized();

public function update(Request $request, \Soap\EloquentWorkflow\Example\Article $article)
{
    $this->authorize('update', $article);
    
    if ($state = $request->input('state')) {
        // Check if user allowed to make this transition
        $article->state()->authorize($state);
    }
    
    $article->fill($request->validated());
    
    $article->save();
}

use \Soap\EloquentWorkflow\Transition;
use \Soap\EloquentWorkflow\Exceptions\TransitionRecoverableException;

Transition::make('new', 'review')
    ->before(function(Article $model) {
        if (strlen($model->body) < 1000) {
            throw new TransitionRecoverableException(
                'Your article should contain at least 1000 symbols. Then you may send it to review.'
            );
        }
    })
    ->before(function(Article $model) {
        if ($model->images->count() == 0) {
            throw new TransitionRecoverableException(
                'Your article should contain at least 1 image. Then you may send it to review.'
            );
        }
    });

use \Soap\EloquentWorkflow\Transition;
use \Soap\EloquentWorkflow\Exceptions\TransitionFatalException;

Transition::make('new', 'to-local-manager')
    ->before(function(Order $model) {
        if ($model->amount >= 1000000) {
            throw new TransitionFatalException("Order amount is too big for this transition.");
        }
    }); 

Transition::make('new', 'to-region-manager')
    ->before(function(Order $model) {
        if ($model->amount < 1000000) {
            throw new TransitionFatalException("Order amount is too small for this transition.");
        }
    }); 

use \Soap\EloquentWorkflow\Transition;

Transition::make('review', 'reject')
    ->rules([
        'reason' => '

use Illuminate\Http\Request;

public function update(Request $request, \Soap\EloquentWorkflow\Example\Article $article)
{
    $this->authorize('update', $article);
    
    if ($state = $request->input('state')) {
        $article->state()
            // Authorize transition
            ->authorize($state)
            // Transit to the new state, passing additional context
            ->transit($state, $request->all())
            // Now save model
            ->save();        
    }
}

use \Soap\EloquentWorkflow\State;
use \Soap\EloquentWorkflow\Transition;
use \Soap\EloquentWorkflow\WorkflowBlueprint;

class ArticleWorkflow extends WorkflowBlueprint
{
    protected function states(): array
    {
        return [
            State::make('new')->as(__('Draft')),
            State::make('published')->as(__('Published'))
        ];
    }
    protected function transitions(): array
    {
        return [
            Transition::make('new', 'published')->as(__('Publish'))
        ];
    }
}

use \Soap\EloquentWorkflow\State;
use \Soap\EloquentWorkflow\Transition;
use \Soap\EloquentWorkflow\WorkflowBlueprint;

class ArticleWorkflow extends WorkflowBlueprint
{
    protected function states(): array
    {
        return [
            State::make('new'),
            State::make('review')     ->set('level', 'warning'),
            State::make('published')  ->set('level', 'success'),
            State::make('correction') ->set('level', 'danger')
        ];
    }
    protected function transitions(): array
    {
        return [
            Transition::make('new', 'review')         ->set('level', 'warning'),
            Transition::make('review', 'published')   ->set('level', 'success'),
            Transition::make('review', 'correction')  ->set('level', 'danger'),
            Transition::make('correction', 'review')  ->set('level', 'warning')
        ];
    }
}

use Illuminate\Http\Request;

public function state(\App\Models\Article $article)
{    
    return $article->state()->toArray();
}

use \Soap\EloquentWorkflow\State;

State::make('correcting')
    ->after(function(Article $article, ?State $previous, array $context) {
        $article->author->notify(
            new ArticleHasProblemNotification(
                $article, $context['reason']
            )
        );
    }); 

use \Soap\EloquentWorkflow\State;
use \Soap\EloquentWorkflow\Transition;

Transition::make('review', 'correcting')
    ->rules([
        'reason' => 'Notification(
                $article, $context['reason']
            )
        );
    }); 

use \Soap\EloquentWorkflow\Events\ModelTransited;

class ModelTransitedListener
{
    public function handle(ModelTransited $event)
    {
        if ($event->model instanceof Article) {
            $article = $event->model;

            if ($event->transition->target()->is('correction')) {
                // Article was send to correction, the reason described in context
                $article->author->notify(
                    new ArticleHasProblemNotification(
                        $article, $event->transition->context('reason')
                    )
                );
            }
        }
    }
}

    'workflow' => [
        'logging' => true
    ]
bash
php artisan vendor:publish --tag="eloquent-workflow-migrations"
php artisan migrate
bash
php artisan vendor:publish --tag="eloquent-workflow-config"
bash
php artisan vendor:publish --tag="eloquent-workflow-views"