Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/php.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ name: Php state machine

on:
push:
branches: [ master ]
branches: [ master, release/* ]
pull_request:
branches: [ master ]
branches: [ master, release/* ]

jobs:
phpunit:
Expand Down
16 changes: 16 additions & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
# Release notes

# 3.3.0

This release is a deprecation release. Deprecation warning will be issued when using a changed feature.

* Introduction of a `StateContext` to replace the context that could be mixed.

Before 3.3.0, a context could be `"post"` or an object that was converted to a FQCN.

Starting with 4.0, we'll only accept implementation of `StateContext`. You will need your context to
implement the interface, or use the adapters [StringAdapterContext](src/Context/StringAdapterContext.php) or
[ObjectAdapterContext](src/Context/ObjectAdapterContext.php) if you don't want to add new custom code.

# 3.2.0

[3.2.0](https://github.com/yvoyer/php-state/releases/tag/3.2.0)

# 3.1.0

* [#30](https://github.com/yvoyer/php-state/pull/30)
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
}
},
"require": {
"php": ">=7.4",
"php": ">=7.4|^8.0",
"webmozart/assert": "^1.0",
"symfony/event-dispatcher": "^4.0|^5.0|^6.0|^7.0"
},
Expand Down
12 changes: 9 additions & 3 deletions examples/CallbackStateTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use Star\Component\State\Callbacks\TransitionCallback;
use Star\Component\State\InvalidStateTransitionException;
use Star\Component\State\RegistryBuilder;
use Star\Component\State\StateContext;
use Star\Component\State\StateMachine;
use Star\Component\State\StateMetadata;
use Star\Component\State\StateTransition;
Expand Down Expand Up @@ -58,7 +59,7 @@ public function test_workflow(): void
}
}

final class TurnStill
final class TurnStill implements StateContext
{
/**
* @var TurnStillState|StateMetadata
Expand All @@ -75,6 +76,11 @@ public function __construct()
$this->state = new TurnStillState('locked');
}

public function toStateContextIdentifier(): string
{
return 'turn-still';
}

public function pay(int $coin): void
{
$this->state = $this->state->transit(
Expand All @@ -94,7 +100,7 @@ public function pass(): void
{
$this->state = $this->state->transit(
'pass',
'turn-still',
$this,
new CallClosureOnFailure(
function () {
return $this->state->transit('alarm', $this)->getCurrent();
Expand All @@ -105,7 +111,7 @@ function () {

public function reset(): void
{
$this->state = $this->state->transit('reset', 'turn-still');
$this->state = $this->state->transit('reset', $this);
}

public function isLocked(): bool
Expand Down
24 changes: 12 additions & 12 deletions examples/ContextUsingBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use PHPUnit\Framework\TestCase;
use Star\Component\State\Builder\StateBuilder;
use Star\Component\State\InvalidStateTransitionException;
use Star\Component\State\StateContext;
use Star\Component\State\StateMachine;

final class ContextUsingBuilderTest extends TestCase
Expand Down Expand Up @@ -192,7 +193,7 @@ public function test_it_should_allow_to_define_attributes_on_state(): void
/**
* Example of usage when using self contained workflow creation.
*/
final class Post
final class Post implements StateContext
{
const ALIAS = 'post';

Expand All @@ -207,16 +208,18 @@ final class Post
const ATTRIBUTE_ACTIVE = 'active';
const ATTRIBUTE_CLOSED = 'closed';

/**
* @var string
*/
private $state;
private string $state;

private function __construct(string $state)
{
$this->state = $state;
}

public function toStateContextIdentifier(): string
{
return self::ALIAS;
}

public function isDraft(): bool
{
return $this->workflow()->isInState(self::STATE_DRAFT);
Expand Down Expand Up @@ -244,23 +247,20 @@ public function isClosed(): bool

public function moveToDraft(): void
{
$this->state = $this->workflow()->transit(self::TRANSITION_TO_DRAFT, 'post');
$this->state = $this->workflow()->transit(self::TRANSITION_TO_DRAFT, $this);
}

public function publish(): void
{
$this->state = $this->workflow()->transit(self::TRANSITION_PUBLISH, 'post');
$this->state = $this->workflow()->transit(self::TRANSITION_PUBLISH, $this);
}

public function archive(): void
{
$this->state = $this->workflow()->transit(self::TRANSITION_ARCHIVE, 'post');
$this->state = $this->workflow()->transit(self::TRANSITION_ARCHIVE, $this);
}

/**
* @return Post
*/
public static function drafted()
public static function drafted(): self
{
return new self(self::STATE_DRAFT);
}
Expand Down
13 changes: 8 additions & 5 deletions examples/ContextUsingCustomMetadataTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use PHPUnit\Framework\TestCase;
use Star\Component\State\Builder\StateBuilder;
use Star\Component\State\RegistryBuilder;
use Star\Component\State\StateContext;
use Star\Component\State\StateMetadata;
use Star\Component\State\StateTransition;

Expand Down Expand Up @@ -215,18 +216,20 @@ public function getDestinationState(): string
}
}

final class ContextStub
final class ContextStub implements StateContext
{
/**
* @var MyStateWorkflow|StateMetadata
*/
public $state;
public MyStateWorkflow $state;

public function __construct()
{
$this->state = new MyStateWorkflow();
}

public function toStateContextIdentifier(): string
{
return 'ContextStub';
}

public function publish(): void
{
$this->state = $this->state->transit('publish', $this);
Expand Down
8 changes: 7 additions & 1 deletion examples/DoctrineMappedContextTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use PHPUnit\Framework\AssertionFailedError;
use PHPUnit\Framework\TestCase;
use Star\Component\State\Builder\StateBuilder;
use Star\Component\State\StateContext;
use Star\Component\State\StateMetadata;

final class DoctrineMappedContextTest extends TestCase
Expand Down Expand Up @@ -85,7 +86,7 @@ private function save(MyEntity $entity): MyEntity
/**
* @Entity()
*/
class MyEntity
class MyEntity implements StateContext
{
/**
* @var int
Expand All @@ -106,6 +107,11 @@ public function __construct()
$this->state = new MyState();
}

public function toStateContextIdentifier(): string
{
throw new \RuntimeException(__METHOD__ . ' is not implemented yet.');
}

public function isLocked(): bool
{
return $this->state->isInState('locked');
Expand Down
26 changes: 19 additions & 7 deletions src/Builder/StateBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,19 @@ final class StateBuilder
private TransitionRegistry $registry;
private EventRegistry $listeners;

public function __construct()
{
$this->registry = new TransitionRegistry();
$this->listeners = new EventDispatcherAdapter();
public function __construct(
?TransitionRegistry $registry = null,
?EventRegistry $listeners = null
) {
if (!$registry) {
$registry = new TransitionRegistry();
}
$this->registry = $registry;

if (!$listeners) {
$listeners = new EventDispatcherAdapter();
}
$this->listeners = $listeners;
}

/**
Expand Down Expand Up @@ -73,8 +82,11 @@ public function create(string $currentState): StateMachine
return new StateMachine($currentState, $this->registry, $this->listeners);
}

public static function build(): StateBuilder
{
return new static();
public static function build(
?TransitionRegistry $registry = null,
?EventRegistry $listeners = null
): StateBuilder {
// todo deprecate explict class in favor of interface
return new self($registry, $listeners);
}
}
28 changes: 16 additions & 12 deletions src/Callbacks/AlwaysReturnStateOnFailure.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Star\Component\State\Callbacks;

use Star\Component\State\InvalidStateTransitionException;
use Star\Component\State\StateContext;
use Star\Component\State\StateMachine;

final class AlwaysReturnStateOnFailure implements TransitionCallback
Expand All @@ -14,31 +15,34 @@ public function __construct(string $to)
$this->to = $to;
}

/**
* @param mixed $context
* @param StateMachine $machine
*/
public function beforeStateChange($context, StateMachine $machine): void
{
public function beforeStateChange(
/* StateContext in 4.0 */ $context,
StateMachine $machine
): void {
}

/**
* @param mixed $context
* @param string|object|StateContext $context
* @param StateMachine $machine
*/
public function afterStateChange($context, StateMachine $machine): void
{
public function afterStateChange(
/* StateContext in 4.0 */ $context,
StateMachine $machine
): void {
}

/**
* @param InvalidStateTransitionException $exception
* @param mixed $context
* @param string|object|StateContext $context
* @param StateMachine $machine
*
* @return string
*/
public function onFailure(InvalidStateTransitionException $exception, $context, StateMachine $machine): string
{
public function onFailure(
InvalidStateTransitionException $exception,
/* StateContext in 4.0 */ $context,
StateMachine $machine
): string {
return $this->to;
}
}
19 changes: 13 additions & 6 deletions src/Callbacks/AlwaysThrowExceptionOnFailure.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,20 @@ final class AlwaysThrowExceptionOnFailure implements TransitionCallback
* @param mixed $context
* @param StateMachine $machine
*/
public function beforeStateChange($context, StateMachine $machine): void
{
public function beforeStateChange(
/* StateContext in 4.0 */ $context,
StateMachine $machine
): void {
}

/**
* @param mixed $context
* @param StateMachine $machine
*/
public function afterStateChange($context, StateMachine $machine): void
{
public function afterStateChange(
/* StateContext in 4.0 */ $context,
StateMachine $machine
): void {
}

/**
Expand All @@ -31,8 +35,11 @@ public function afterStateChange($context, StateMachine $machine): void
* @return string
* @throws InvalidStateTransitionException
*/
public function onFailure(InvalidStateTransitionException $exception, $context, StateMachine $machine): string
{
public function onFailure(
InvalidStateTransitionException $exception,
/* StateContext in 4.0 */ $context,
StateMachine $machine
): string {
throw $exception;
}
}
Loading