winzou / state-machine-bundle
轻量级但功能强大的PHP状态机的Bundle
v0.6.2
2024-04-22 15:58 UTC
Requires
- php: ^7.4|^8.0|^8.1
- symfony/framework-bundle: ^4.4|^5.4|^6.0|^7.0
- winzou/state-machine: ~0.4
Requires (Dev)
- phpspec/phpspec: ^5.0|^6.0|^7.0
README
定义你的状态、转换和回调:我们来做其余的事情。硬编码状态的年代已经过去了!
安装
安装(通过composer)
composer require winzou/state-machine-bundle
注册Bundle
// app/AppKernel.php public function registerBundles() { return array( // ... new winzou\Bundle\StateMachineBundle\winzouStateMachineBundle(), ); }
使用
配置状态机图
为了使用这个Bundle的状态机,你首先需要定义一个图。一个图是对状态、转换和可选回调的定义,这些定义都附加在你的领域对象上。可以将多个图附加到同一个对象上。
让我们为我们的Article
对象定义一个名为simple的图
# app/config/config.yml winzou_state_machine: my_bundle_article: class: My\Bundle\Entity\Article # class of your domain object property_path: state # property of your object holding the actual state (default is "state") graph: simple # name of the graph (default is "default") # list of all possible states: states: - new - pending_review - awaiting_changes - accepted - published - rejected # list of all possible transitions: transitions: create: from: [new] to: pending_review ask_for_changes: from: [pending_review, accepted] to: awaiting_changes submit_changes: from: [awaiting_changes] to: pending_review approve: from: [pending_review, rejected] to: accepted publish: from: [accepted] to: published # list of all callbacks callbacks: # will be called when testing a transition guard: guard_on_submitting: on: 'submit_changes' # call the callback on a specific transition do: ['@my.awesome.service', 'isSubmittable'] # will call the method of this Symfony service args: ['object'] # arguments for the callback # will be called before applying a transition before: update_reviewer: on: 'create' do: ['@my.awesome.service', 'update'] args: ['object'] # will be called after applying a transition after: email_on_publish: on: 'publish' do: ['@my.awesome.service', 'sendEmail'] args: ['object', '"Email title"']
因此,在上面的例子中,对象Article
有6个可能的状态,可以通过应用一些转换到实体来实现这些状态。例如,当你创建一个新的Article
时,你会应用'create'转换到实体,之后它的状态就会变成pending_review。
现在让我们假设,经过彻底的审查后,有人决定Article
不够好,所以他们想让你做一些更改。因此,他们会应用ask_for_changes转换,现在状态就会变成awaiting_changes。
使用状态机
定义
状态机是实际操作你的对象的那个对象。通过使用状态机,你可以测试是否可以应用转换,实际应用转换,检索当前状态等。一个状态机是针对一对对象 + 图的。这意味着,如果你想操作另一个对象,或者同一个对象使用另一个图,你需要另一个状态机。
工厂帮助你获取这些对象 + 图的状态机。你给它一个对象和一个图名,它会返回这对的状态机。工厂是一个名为SM\Factory\Factory
的服务。
使用
public function myAwesomeAction($id, \SM\Factory\Factory $factory) { // Get your domain object $article = $this->getRepository('MyAwesomeBundle:Article')->find($id); // Get the state machine for this object, and graph called "simple" $articleSM = $factory->get($article, 'simple'); }
现在,$articleSM
有一系列方法,这将允许你检查是否可以应用期望的转换,给定我们传递给它的对象的状态(在我们的例子中是$article
)。例如,我们可以
// Check if a transition can be applied: returns true or false $articleSM->can('a_transition_name'); // Apply a transition $articleSM->apply('a_transition_name'); // Get the actual state of the object $articleSM->getState(); // Get all available transitions $articleSM->getPossibleTransitions();
回调
回调用于保护转换或在应用转换之前或之后执行一些代码。这个Bundle增加了在回调中使用Symfony2服务的能力。