burriko/cake-state-machine

CakePHP 2.x 的有限状态机行为

dev-master / 2.0.x-dev 2015-02-09 16:23 UTC

This package is not auto-updated.

Last update: 2024-09-28 14:17:32 UTC


README

CakePHP 2.x 的基本有限状态机行为。 CakePHP 1.x 的版本可以在 cakephp1 分支中找到。

描述模型的状态以及导致状态之间转换的事件,然后触发这些事件来更改模型的状态。

安装

如果你使用 composer,只需将以下内容添加到你的 require 块中。

	"burriko/cake-state-machine": "2.0.*@dev"

如果你不使用 composer,则将此目录的内容克隆/复制到 app/Plugins/CakeStateMachine。

配置

  1. 将以下行添加到你的 app/Config/bootstrap.php。

     CakePlugin::load('CakeStateMachine');
    
  2. 在你的模型中添加以下内容:

     public $actsAs = array('CakeStateMachine.StateMachine');
    
  3. 使用以下模式创建一个新的数据库表来存储状态,调整表名和外键以匹配你的模型。例如,如果你正在向名为 Placement 的模型添加状态,你会使用以下内容。

     CREATE TABLE `placement_states` (
       `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
       `placement_id` int(11) unsigned NOT NULL,
       `state` varchar(50) NOT NULL DEFAULT '',
       `created` datetime NOT NULL,
       PRIMARY KEY (`id`)
     ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
  4. 在你的模型表中添加一个新的 varchar 字段,名称为 'state'。

     ALTER TABLE `placements` ADD `state` VARCHAR(50);
    

使用方法

  1. 在你的模型中描述所需的状态和转换,如下所示。

     public $states = array('state' => array('event' => 'new_state'));
    

    以下是一个示例。

     public $states = array(
       'advertised' => array(
         'select_appropriate_applicants' => 'shortlisted',
         'no_appropriate_applicants' => 'unplaced'
       ),
       'shortlisted' => array(
         'select_for_interview' => 'interviews',
         'no_appropriate_applicants' => 'unplaced'
       ),
       'interviews' => array(
         'select_successful_candidate' => 'placed',
         'no_appropriate_applicants' => 'unplaced'
       ),
       'placed' => array(
         'placement_complete' => 'complete',
         'problem_with_placement' => 'unplaced'
       ),
       'unplaced' => array(
         'readvertise' => 'advertised'
       ),
       'complete'
     );
    
  2. 当由该模型创建新记录时,它将被分配列表中的第一个状态作为其初始状态。

  3. 要转换到新状态,请调用 transition() 方法并传递事件的名称。

     $this->Model->transition('event');
    

    在这个示例中,如果 Placement 模型处于 'interviews' 状态,它将转换到 'placed' 状态。

     $this->Placement->transition('select_successful_candidate');
    
  4. 每次状态更改都会记录在数据库中。每个使用 StateMachine 行为的模型都将有一个名为 ModelnameState 的适当状态模型。该模型与该模型通过 hasMany 关系相关联。因此,你可以使用此模型以任何方式查找状态更改。

     $this->Placement->PlacementState->findByPlacementId($placement_id);
    

    您也可以从 getCurrentState() 方法中获取模型的当前状态。

     // set model id if not already set
     $this->Placement->id = $placement_id;
     $this->Placement->getCurrentState(); // returns 'placed'
    

备注

  • 记录的当前状态也存储在模型的 'state' 列中。这是为了在按状态查询模型时简化操作。

  • 支持状态更改的回调方法。此方法应命名为 _onState(). 例如,要在一个模型的状态更改为名为 'placed' 的状态时运行一个方法,请向你的模型添加以下方法。

      public function _onStatePlaced() {}
    
  • 您可以通过调用 is() 来检查当前是否设置了状态。例如,要检查 Placement 记录当前是否设置为 shortlisted,请调用以下方法。

      $this->Placement->isShortlisted();