winzou/state-machine-bundle

轻量级但功能强大的PHP状态机的Bundle

安装量: 8,510,529

依赖项: 11

建议者: 0

安全: 0

星标: 337

关注者: 9

分支: 43

开放性问题: 7

类型:symfony-bundle

v0.6.2 2024-04-22 15:58 UTC

README

定义你的状态、转换和回调:我们来做其余的事情。硬编码状态的年代已经过去了!

Build

安装

安装(通过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服务的能力。