State Machine Transitions

For an actual example being used in Drupal Commerce, check out the state machine transition event subscriber being used in commerce_order to set an order's placed timestamp: * commerce_order.services.yml * TimestampEventSubscriber.php

Finding Transitions

Transition information can be found in a {module}.workflows.yml.

Example from commerce_order:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
# commerce_order.services.yml
order_default:
  id: order_default
  group: commerce_order
  label: 'Default'
  states:
    draft:
      label: Draft
    completed:
      label: Completed
    canceled:
      label: Canceled
  transitions:
    place:
      label: 'Place order'
      from: [draft]
      to: completed
    cancel:
      label: 'Cancel order'
      from: [draft]
      to:   canceled

Reacting to Transitions

Example - reacting to the order 'place' transition.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
// mymodule/src/EventSubscriber/MyModuleEventSubscriber.php
namespace Drupal\my_module\EventSubscriber;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Drupal\state_machine\Event\WorkflowTransitionEvent;

class MyModuleEventSubscriber implements EventSubscriberInterface {

  public static function getSubscribedEvents() {
    // The format for adding a state machine event to subscribe to is:
    // {group}.{transition key}.pre_transition or {group}.{transition key}.post_transition
    // depending on when you want to react.
    $events = ['commerce_order.place.post_transition' => 'onOrderPlace'];
    return $events;
  }

  public function onOrderPlace(WorkflowTransitionEvent $event) {
    // @todo Write code that will run when the subscribed event fires.
  }
}

Telling Drupal About Your Event Subscriber

Your event subscriber should be added to {module}.services.yml in the base directory of your module.

The following would register the event subscriber in the previous section:

1
2
3
4
5
6
# mymodule.services.yml
services:
  my_module_event_subscriber:
    class: '\Drupal\my_module\EventSubscriber\MyModuleEventSubscriber'
    tags:
      - { name: 'event_subscriber' }