Skip to content

Commit

Permalink
Merge pull request #6 from norotaro/support-history
Browse files Browse the repository at this point in the history
The feature of transitioning out of the state machine has been improved.
  • Loading branch information
norotaro committed Aug 18, 2023
2 parents 5811927 + 31b3c82 commit 0a81187
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 13 deletions.
8 changes: 3 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ State Machines for Eloquent models using Enums.
- [Register the State Definition file](#register-the-state-definition-file)
- [The State Machine](#the-state-machine)
- [Using the State Machine](#using-the-state-machine)
- [Transitioning](#transitioning)
- [Checking available transitions](#checking-available-transitions)
- [Transitioning](#transitioning-1)
- [Checking available transitions](#checking-available-transitions)
- [Events](#events)
- [Listening to events using `$dispatchesEvents`](#listening-to-events-using-dispatchesEvents)
- [Listening to events using `$dispatchesEvents`](#listening-to-events-using-dispatchesevents)
- [Listening to events using Closures](#listening-to-events-using-closures)
- [Testing](#testing)
- [Inspiration](#inspiration)
Expand Down Expand Up @@ -347,8 +347,6 @@ The `transitioning($field, $callback)` and `transitioned($field, $callback)` met
> Note that the first parameter must be the name of the field we want to listen to.
```php
use App\Events\TransitionedOrderFulfillment;
use App\Events\TransitioningOrderStatus;
use Norotaro\Enumata\Traits\HasStateMachines;

class Order extends Model
Expand Down
23 changes: 17 additions & 6 deletions src/StateMachine.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

class StateMachine implements Contracts\StateMachine
{
protected bool $isTransitioning = false;

public function __construct(
protected Model $model,
protected string $field
Expand Down Expand Up @@ -52,32 +54,41 @@ public function canBe(DefineStates&UnitEnum $state): bool
* @throws InvalidArgumentException
* @throws InvalidCastException
*/
public function transitionTo(DefineStates&UnitEnum $state, bool $force = false): void
public function transitionTo(DefineStates&UnitEnum $to, bool $force = false): void
{
if ($state === $this->currentState()) {
if ($to === $this->currentState()) {
return;
}

/** TODO: unify the validation logic of transitions */
if (!$force && !$this->canBe($state)) {
if (!$force && !$this->canBe($to)) {
throw new TransitionNotAllowedException(
$this->currentState(),
$state,
$to,
$this->model
);
}

$this->model->{$this->field} = $state;
$this->isTransitioning = true;

$this->model->{$this->field} = $to;

$this->model->fireTransitioningEvent($this->field);

$this->model->save();

$this->model->fireTransitionedEvent($this->field);
$this->model->fireTransitionedEvent($this->field, $to);

$this->isTransitioning = false;
}

public function getField(): string
{
return $this->field;
}

public function isTransitioning(): bool
{
return $this->isTransitioning;
}
}
6 changes: 4 additions & 2 deletions src/Traits/HasStateMachines.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,12 @@ public static function bootHasStateMachines()
}

MacroableModels::addMacro(static::class, 'fireTransitioningEvent', function ($field) {
// fire Eloquent event
$this->fireModelEvent("transitioning:$field", false);
});

MacroableModels::addMacro(static::class, 'fireTransitionedEvent', function ($field) {
MacroableModels::addMacro(static::class, 'fireTransitionedEvent', function ($field, $from) {
// fire Eloquent event
$this->fireModelEvent("transitioned:$field", false);
});

Expand All @@ -89,7 +91,7 @@ public static function bootHasStateMachines()
foreach ($model->getStateMachines() as $stateMachine) {
$field = $stateMachine->getField();

if ($model->isDirty($field)) {
if ($model->isDirty($field) && !$stateMachine->isTransitioning()) {
$from = $model->getOriginal($field);
$to = $model->{$field};

Expand Down
8 changes: 8 additions & 0 deletions tests/Traits/HasStateMachinesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,15 @@
expect(MacroableModels::modelHasMacro($this->model::class, 'finish'))->toBe(true);
});

it('change status with transition methods', function () {
$this->model->save();
$this->model->pay();

expect($this->model->status)->toBe(OrderStatus::Pending);
});

it('creates transition methods that allows forced transitions', function () {
$this->model->save();
$this->model->end(force: true);

expect($this->model->status)->toBe(OrderStatus::Finished);
Expand Down

0 comments on commit 0a81187

Please sign in to comment.