kphoen / doctrine-state-machine-bundle
将 DoctrineStateMachineBehavior 集成到 Symfony2 中。
Requires
- doctrine/doctrine-bundle: ~1.2
- kphoen/doctrine-state-machine: ~1.0
- symfony/framework-bundle: ~2.3|~3.0
Requires (Dev)
- symfony/console: ~2.3|~3.0
- symfony/twig-bundle: ~2.3|~3.0
Suggests
- alom/graphviz: To generate Graphviz views of state machines
- symfony/console: To execute the command to generate Graphviz views of state machines
- symfony/twig-bundle: To integrate with Twig
This package is auto-updated.
Last update: 2022-02-01 12:27:45 UTC
README
为实体添加有限状态机的 Doctrine2 行为。
使用的状态机实现是 Finite。
状态
此项目已 弃用,不应使用。
如果有人出现并希望维护此项目,我将乐意提供对仓库的访问权限。
配置
在您的 app/config/config.yml
文件中,定义您的状态机
k_phoen_doctrine_state_machine: auto_injection: true # should we automatically inject state machines into hydrated objects? auto_validation: true # should we validate any status change before the persistence happens? state_machines: article_state_machine: class: \Acme\FooBundle\Entity\Article property: state states: new: {type: initial} reviewed: ~ accepted: ~ published: {type: final, properties: {printable: true}} rejected: {type: final} transitions: review: {from: [new], to: reviewed} accept: {from: [reviewed], to: accepted} publish: {from: [accepted], to: published} reject: {from: [new, reviewed, accepted, published], to: rejected}
状态机配置非常简单。除了状态和转换,您还需要定义实体类和用于存储状态的列。
重要:实体必须 实现 Stateful
接口。
为了简化实现,您可以使用行为附带的自定义 StatefulTrait
。
使用
Stateful
实体可以访问它们自己的状态机。有关详细信息,请参阅 Finite 的文档。
以下 Article
实体已准备好作为 Stateful
实体使用。
<?php namespace Acme\FooBundle\Entity; use KPhoen\DoctrineStateMachineBehavior\Entity\Stateful; use KPhoen\DoctrineStateMachineBehavior\Entity\StatefulTrait; class Article implements Stateful { use StatefulTrait; /** * define your fields here */ /** * @var string */ protected $state = 'new'; /** * Set state * * @param string $state * @return Article */ public function setState($state) { $this->state = $state; return $this; } /** * Get state * * @return string */ public function getState() { return $this->state; } /** * Sets the object state. * Used by the StateMachine behavior * * @return string */ public function getFiniteState() { return $this->getState(); } /** * Sets the object state. * Used by the StateMachine behavior * * @param string $state */ public function setFiniteState($state) { return $this->setState($state); } }
使用 StatefulTrait
的实体将看到实现了的 setStateMachine()
和 getStateMachine()
方法,并获得以下方法的访问权限
can($transition)
:表示是否允许给定的转换;- 以及一些基于状态机允许的转换的魔法方法
{TransitionName}()
:应用转换{TransitionName}
(例如:accept()
、reject()
等);can{TransitionName}()
:测试转换{TransitionName}
是否可以应用(例如:canAccept()
、canReject()
等)。is{StateName}()
:测试当前状态是否为{StateName}
(例如:isAccepted()
、isRejected()
等)。
<?php $article = new Article(); $article->canAccept(); $article->canReject(); $article->can('accept'); $article->accept(); $article->publish(); $article->isAccepted(); $article->isRejected();
生命周期回调
如果您使用的是具有事件感知状态机的扩展(这是此包默认使用的),则扩展提供了为具有状态的实体实现“生命周期回调”的监听器。
对于每个可用的转换,可以执行三个方法
pre{TransitionName}()
:在应用转换{TransitionName}
之前调用;post{TransitionName}()
:在应用转换{TransitionName}
之后调用;can{TransitionName}()
:当状态机测试转换{TransitionName}
是否可以应用时调用。
<?php namespace Acme\FooBundle\Entity; use KPhoen\DoctrineStateMachineBehavior\Entity\Stateful; use KPhoen\DoctrineStateMachineBehavior\Entity\StatefulTrait; class Article implements Stateful { // previous code public function preAccept() { // your logic here } public function postAccept() { // your logic here } public function onCanAccept() { // your logic here } }
使用服务
您可以使用 Finite 事件上的监听器将状态逻辑放在实体之外。此扩展提供具有与“生命周期回调”监听器相同方法的抽象事件订阅者。
您需要声明一个服务和扩展 AbstractSubscriber。
services: article_workflow_subscriber: class: Acme\FooBundle\Workflow\ArticleSubscriber tags: - { name: kernel.event_subscriber }
<?php namespace Acme\FooBundle\Workflow; use KPhoen\DoctrineStateMachineBundle\Listener\AbstractSubscriber; class ArticleSubscriber extends AbstractSubscriber { public function supportsObject($object) { return $object instanceof \Acme\FooBundle\Entity\Article; } public function preAccept() { // your logic here } public function postAccept() { // your logic here } public function canAccept() { // your logic here } }
Twig
该捆绑包还公开了一些Twig助手
{# your template ... #} {% if article|can('reject') %} <a class="btn btn-danger" href="{{ path('article_delete', article) }}"> <i class="icon-trash"></i> {{ 'link_reject'|trans }} </a> {% endif %} {# this is strictly equivalent #} {% if can(article, 'reject') %} <a class="btn btn-danger" href="{{ path('article_delete', article) }}"> <i class="icon-trash"></i> {{ 'link_reject'|trans }} </a> {% endif %} {% if current_state(article).isFinal %} blabla {% endif %} {% if article|is_status('rejected') %} blabla {% endif %} {# this is strictly equivalent #} {% if is_status(article, 'rejected') %} blabla {% endif %} {% if article|has_property('printable') %} {{ article|property('printable') ? 'I can print' : 'I CANNOT print' }} {% endif %} {# this is strictly equivalent #} {% if has_property(article, 'printable') %} {{ property(article, 'printable') ? 'I can print' : 'I CANNOT print' }} {% endif %}
安装
安装行为,将kphoen/doctrine-state-machine-bundle
添加到您的composer.json或从CLI安装
composer require kphoen/doctrine-state-machine-bundle
然后在您的app/AppKernel.php
文件中注册该捆绑包
// app/AppKernel.php public function registerBundles() { $bundles = array( // ... new KPhoen\DoctrineStateMachineBundle\KPhoenDoctrineStateMachineBundle(), // ... ); }
许可证
此捆绑包在MIT许可证下发布。