iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 24
0
Modern Web

PHP框架-Symfony4 + api platform 系列 第 24

Day#24 Workflow 流程引擎 ~

  • 分享至 

  • xImage
  •  

Workflow 流程引擎要拿來幹嘛的?

我們可以透過流程引擎來控管我們一系列的流程,讓狀態可以跟著我們的設定所變動,
且可以透過權限,來判斷我們是否可以執行下一步的流程


首先 先來安裝workflow

composer require symfony/workflow

安裝完以後,我們會在目錄config下的子目錄packages下看到一個workflow.yaml ,
裡面就是我們要設定流程的地方,一開始預設的workflow 會像以下這樣 ,是null

framework:
    workflows: null

workflows裡可以同時存在很多個引擎,
如果要建立一個新的引擎,我們需要給引擎的名稱,還有一些設定,
例如類型,要拿來當流程狀態的欄位,支援哪個實體類,初始的值,總共有幾個階段及各個階段如何轉換等等....

那我們就來自己建立一個流程引擎吧!


首先 先給引擎一個名稱,並給予基本設定

framework:
    workflows:
        test_workflow:
            type: 'state_machine'
            audit_trail:
                enabled: true
            marking_store:
                type: 'method'
                property: 'status'
            supports:
                - App\Entity\Test
            initial_marking: "1"
  • test_workflow 是引擎的名稱
  • type 可以使用 'state_machine' 或 'workflow'
  • marking_store 裡面的property為流程狀態的欄位
  • supports 是 對應的實體類
  • initial_marking 是流程狀態的初始值

接著要來設定引擎的各種狀態

framework:
    workflows:
        test_workflow:
            type: 'state_machine'
            audit_trail:
                enabled: true
            marking_store:
                type: 'method'
                property: 'status'
            supports:
                - App\Entity\Test
            initial_marking: "1"
            places:
                "1":
                    metadata:
                        description: 申請中
                "3":
                    metadata:
                        description: 待審核
                "4":
                    metadata:
                        description: 確認
                "5":
                    metadata:
                        description: 退回
  • places 是流程狀態 "" << 裡的是值 ,description是描述

最後我們要來做轉換的設定

framework:
    workflows:
        test_workflow:
            type: 'state_machine'
            audit_trail:
                enabled: true
            marking_store:
                type: 'method'
                property: 'status'
            supports:
                - App\Entity\Test
            initial_marking: "1"
            places:
                "1":
                    metadata:
                        description: 申請中
                "3":
                    metadata:
                        description: 待審核
                "4":
                    metadata:
                        description: 確認
                "5":
                    metadata:
                        description: 退回
            transitions:
                start:
                    guard: ' user.getName() =="小叮噹" '
                    from:  ['1']
                    to:    '3'
                    metadata:
                        label: start 申請
                reject:
                    from: ['5']
                    to:   '3'
                    metadata:
                        label: reject 退回
  • transitions是設定狀態轉換的地方,可以設置多個
  • start和reject 是名稱
  • guard 可以檢查執行這個轉換的條件
  • from 是從狀態幾 , to 是到狀態幾

以上是簡單workflow的設定,那在程式裡面,我們通常會怎麼運用呢?


在Action裡使用workflow ,我們要先 依賴注入Registry 這個class

    private $workflows;

    public function __construct(Registry $workflows)
    {
   
        $this->workflows = $workflows;
    
    }

接著,在form submit後,透過get 拿取 workflow裡的引擎,
看要使用哪一個,並且將接到的資料丟進去,
最後透過try catch 去幫我們判斷是否可以執行這個workflow

if ($form->isSubmitted() && $form->isValid()){
           
                $stateMachine = $this->workflows->get($data,'test_workflow');

                try {
                    $stateMachine->apply($data,$data->getWorkflow());
                } catch (LogicException $exception) {
                    throw new AccessDeniedException('非授權流程動作');
                }
           

            $this->em->persist($data);

            try {
                $this->em->flush();
            } catch (Exception $e) {
            }
        }

  • $data->getWorkflow() 是從,前面送過來的,來決定我們要執行哪一個轉換 ,我們也可以直接用轉換的那個名稱做替代

    if ($form->isSubmitted() && $form->isValid()){
    
                    $stateMachine = $this->workflows->get($data,'test_workflow');
    
                    try {
                        $stateMachine->apply($data,'start');
                    } catch (LogicException $exception) {
                        throw new AccessDeniedException('非授權流程動作');
                    }
    
    
                $this->em->persist($data);
    
                try {
                    $this->em->flush();
                } catch (Exception $e) {
                }
            }
    

在twig裡 ,我們也可以判斷是否可以執行這個workflow

    {% if workflow_can($test,'start') %}
                            
         <button class="btn btn-primary" id="save" type="button">
           申請
         </button>
    {% endif %}

  • workflow_can 第一個參數是,實體類的資料 , 第二個參數是轉換的名稱

直接透過workflow.yaml 來看流程 是不是感覺眼花 ...

沒關係 workflow很貼心,它可以幫我們的流程轉成圖檔

詳情請參考官網

https://symfony.com/doc/4.4/workflow/dumping-workflows.html


上一篇
Day#23 用參數取得路徑,版本4.3↑及4.3↓權限控管用法,實體類型別問題~真的是各種雷阿...(((゚Д゚;)))
下一篇
Day#25 被匯出匯入跟編碼搞到快崩潰的小菜鳥(`д´)-切割字串與計算字元長度
系列文
PHP框架-Symfony4 + api platform 30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言