} */ abstract protected static function stateMachineConfig(): array; public function getStateField(): string { return static::stateMachineConfig()['field']; } public function getCurrentState(): string { $field = $this->getStateField(); return $this->{$field}; } public function canTransitionTo(string $newState): bool { $config = static::stateMachineConfig(); $currentState = $this->getCurrentState(); $transitions = $config['transitions'] ?? []; if (!isset($transitions[$currentState])) { return false; } return in_array($newState, $transitions[$currentState], true); } public function transitionTo(string $newState): static { if (!$this->canTransitionTo($newState)) { $currentState = $this->getCurrentState(); $field = $this->getStateField(); throw new InvalidArgumentException( "Cannot transition '{$field}' from '{$currentState}' to '{$newState}'." ); } $field = $this->getStateField(); $oldState = $this->getCurrentState(); $this->{$field} = $newState; $this->save(); // Fire an event for the transition $modelName = class_basename(static::class); event("{$modelName}StateChanged", [ 'model' => $this, 'field' => $field, 'from' => $oldState, 'to' => $newState, ]); return $this; } public function getAllowedTransitions(): array { $config = static::stateMachineConfig(); $currentState = $this->getCurrentState(); return $config['transitions'][$currentState] ?? []; } }