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"
接著要來設定引擎的各種狀態
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: 退回
最後我們要來做轉換的設定
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 退回
以上是簡單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.yaml 來看流程 是不是感覺眼花 ...
沒關係 workflow很貼心,它可以幫我們的流程轉成圖檔
詳情請參考官網
https://symfony.com/doc/4.4/workflow/dumping-workflows.html