Attributes
#[StateId]
Link your event to its state(s) with the StateId
attribute
1class YourEvent extends Event2{3 #[StateId(GameState::class)]4 public int $game_id;5 6 #[StateId(PlayerState::class)]7 public int $player_id;8}
The StateId
attribute takes a state_type
, an optional alias
string, and by default can automatically generate(autofill
) a snowflake_id
for you.
#[AppliesToState]
Another way to link states and events; like StateId
, but using the attributes above the class instead of on each individual id.
1#[AppliesToState(GameState::class)] 2#[AppliesToState(PlayerState::class)] 3class RolledDice extends Event 4{ 5 use PlayerAction; 6 7 public function __construct( 8 public int $game_id, 9 public int $player_id,10 public array $dice,11 )12}
AppliesToState
has the same params as StateId
, with an additional optional id
param (after state_type
) if you want to specify which prop belongs to which state.
1#[AppliesToState(state_type: GameState::class, id: foo_id)] 2#[AppliesToState(state_type: PlayerState::class, id: bar_id)] 3class RolledDice extends Event 4{ 5 use PlayerAction; 6 7 public function __construct( 8 public int $foo_id, 9 public int $bar_id,10 public array $dice,11 )12}
Otherwise, with AppliesToState
, Verbs will find the id
for you based on your State's prefix (i.e. ExampleState
would be example
, meaning example_id
or example_ids
would be associated automatically).
#[AppliesToSingletonState]
Use the AppliesToSingletonState
attribute on an event class to tell Verbs that it should always be applied to a single state (e.g. CountState
) across the entire application (as opposed to having different counts for different states).
Because we're using a singleton state, there is no need for the event to have a $count_id
.
1#[AppliesToSingletonState(CountState::class)]2class IncrementCount extends Event3{4 public function apply(CountState $state)5 {6 $state->count++;7 }8}
In addition to your state_type
param, you may also set an optional alias
string.
#[AppliesToChildState]
Use the AppliesToChildState
attribute on an event class to allow Verbs to access a nested state.
For our example, let's make sure our ParentState
has a child_id
property pointing to a ChildState
by firing a ChildAddedToParent
event:
1ChildAddedToParent::fire(parent_id: 1, child_id: 2); 2 3// ChildAddedToParent.php 4#[AppliesToState(state_type: ParentState::class, id: 'parent_id')] 5#[AppliesToState(state_type: ChildState::class, id: 'child_id')] 6class ChildAddedToParent extends Event 7{ 8 public int $parent_id; 9 10 public int $child_id;11 12 public function applyToParentState(ParentState $state)13 {14 $state->child_id = $this->child_id;15 }16}
1class ParentState extends State2{3 public int $child_id;4}
1class ChildState extends State2{3 public int $count = 0;4}
Now that ParentState
has a record of our ChildState
, we can load the child through the parent with AppliesToChildState
.
Let's show this by firing a NestedStateAccessed
event with our new attribute:
1NestedStateAccessed::fire(parent_id: 1); 2 3// NestedStateAccessed.php 4#[AppliesToChildState( 5 state_type: ChildState::class, 6 parent_type: ParentState::class, 7 id: 'child_id' 8)] 9class NestedStateAccessed extends Event10{11 #[StateId(ParentState::class)]12 public int $parent_id;13 14 public function apply(ChildState $state)15 {16 $state->count++; // 117 }18}
AppliesToChildState
takes a state_type
(your child state), parent_type
, id
(your child state id), and an optional alias
string.
When you use AppliesToChildState
, don't forget to also use StateId
or AppliesToState
to identify the parent_id
.
#[Once]
Use above any handle()
method that you do not want replayed.
1class YourEvent extends Event2{3 #[Once(YourState::class)]4 public function handle()5 {6 //7 }8}
(You may also use Verbs::unlessReplaying
, mentioned in one-time effects)