PHP code example of codewiser / workflow

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

    

codewiser / workflow example snippets


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

class ArticleWorkflow extends \Codewiser\Workflow\WorkflowBlueprint
{
    public function states(): array
    {
        return Enum::cases();
    }
    
    public function transitions(): array
    {
        return [
            [Enum::new, Enum::review],
            [Enum::review, Enum::published],
            [Enum::review, Enum::correction],
            [Enum::correction, Enum::review]
        ];
    }
}

use \Codewiser\Workflow\Example\Enum;
use \Codewiser\Workflow\Example\ArticleWorkflow;
use \Codewiser\Workflow\StateMachineEngine;

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

use \Codewiser\Workflow\Example\Enum;

// creating: will set proper initial state
$article = new \Codewiser\Workflow\Example\Article();
$article->save();
assert($article->state == Enum::new);

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

use \Codewiser\Workflow\State;
use \Codewiser\Workflow\Transition;

class ArticleWorkflow extends \Codewiser\Workflow\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 \Codewiser\Workflow\Transition;

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

class ArticlePolicy
{
    public function transit(User $user, Article $article, Transition $transition)
    {
        //
    }
}

use \Codewiser\Workflow\Transition;
use \Illuminate\Support\Facades\Gate;

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

$article = new \Codewiser\Workflow\Example\Article();

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

public function update(Request $request, 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 \Codewiser\Workflow\Charge;
use \Codewiser\Workflow\Transition;

Transition::make('review', 'publish')
    ->chargeable(Charge::make(
        progress: function(Article $article) {
            return $article->accepts / 3;
        },
        callback: function (Article $article) {
            $article->accepts++;
            $article->save();
        }
    ));

use \Codewiser\Workflow\Transition;
use \Codewiser\Workflow\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 \Codewiser\Workflow\Transition;
use \Codewiser\Workflow\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 \Codewiser\Workflow\Transition;

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

use Illuminate\Http\Request;

public function store(Request $request)
{
    $this->authorize('create', \Codewiser\Workflow\Example\Article::class);
    
    $article = \Codewiser\Workflow\Example\Article::query()->make(
        $request->all()
    );
    
    $article->state()
        // Init workflow, passing additional context
        ->init($request->all())
        // Now save model
        ->save();
}

use Illuminate\Http\Request;

public function update(Request $request, \Codewiser\Workflow\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 \Codewiser\Workflow\State;
use \Codewiser\Workflow\Transition;
use \Codewiser\Workflow\WorkflowBlueprint;

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

use \Codewiser\Workflow\State;
use \Codewiser\Workflow\Transition;
use \Codewiser\Workflow\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(\Codewiser\Workflow\Example\Article $article)
{    
    return $article->state()->toArray();
}

use \Codewiser\Workflow\Context;
use \Codewiser\Workflow\State;
use \Codewiser\Workflow\Transition;

State::make('correcting')
    ->rules(['reason' => '    $article, $context->data()->get('reason')
            )
        );
    }); 

use \Codewiser\Workflow\Context;
use \Codewiser\Workflow\Transition;

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

use \Codewiser\Workflow\Events\ModelTransited;

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

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

    'workflow' => [
        'history' => true
    ]