jooservices/state-machine

A PHP 8.5+ configuration-driven finite state machine for any PHP object

Maintainers

Package info

github.com/jooservices/state-machine

pkg:composer/jooservices/state-machine

Transparency log

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

dev-master 2026-07-21 01:53 UTC

This package is auto-updated.

Last update: 2026-07-22 02:29:59 UTC


README

CI OpenSSF Scorecard PHP Version License: MIT Packagist Version

The JOOservices State Machine is a PHP 8.5+ configuration-driven finite state machine for any PHP object — DTOs, POPOs, or framework models. Zero framework coupling. State is a string property on the subject.

Package name: jooservices/state-machine

Latest stable release: v1.0.0

Install

composer require jooservices/state-machine

Quick example

use JOOservices\StateMachine\StateMachineFactory;

final class Order
{
    public function __construct(
        public string $status = 'pending',
    ) {}
}

$config = [
    'property' => 'status',
    'states' => ['pending', 'confirmed', 'shipped', 'cancelled'],
    'initial_state' => 'pending',
    'transitions' => [
        'confirm' => ['from' => ['pending'], 'to' => 'confirmed'],
        'ship' => ['from' => ['confirmed'], 'to' => 'shipped'],
        'cancel' => ['from' => ['pending', 'confirmed'], 'to' => 'cancelled'],
    ],
];

$order = new Order();
$machine = (new StateMachineFactory())->create($order, 'order', $config);

if ($machine->can('confirm')) {
    $machine->apply('confirm');
}

echo $machine->getState(); // confirmed

What is supported today

  • configuration-driven graphs validated at construction time
  • can() / apply() / getAvailableTransitions()
  • pluggable state accessors (property reflection or getter/setter)
  • guards and before/after callbacks as class strings
  • optional PSR-14 lifecycle events
  • multiple independent graphs per subject (separate machine instances)
  • pure PHP 8.5+ with no Laravel/Symfony runtime requirement

Important current limitations

  • guards and callbacks are constructed with new $class() (no container resolution)
  • event dispatcher is optional; consumers bring their own PSR-14 implementation
  • no built-in persistence, Eloquent casts, or service providers
  • missing properties/methods are handled conservatively by accessors (null / no-op)

Documentation

Start with:

AI Support

This repository includes an AI skill pack for agents working in Cursor, Claude Code, VS Code, JetBrains, and Antigravity.

Start with:

The canonical skill source lives in .github/skills/, with adapter layers for each supported AI environment.

Development

composer lint
composer lint:all
composer test
composer test:coverage
composer check
composer ci

Contributor workflow details live in:

Approved Git flow summary:

  • normal feature and fix work branches from develop and PRs back into develop
  • release preparation uses release/<version> from develop, then PRs into master
  • releases are tagged from master
  • master merges back into develop after release or hotfix completion

Community

GitHub Actions and Services

Current GitHub Actions coverage:

  • CI: security checks, linting, tests, 95% minimum statement coverage, coverage upload, and optional SonarQube Cloud analysis when SONAR_TOKEN is configured
  • Release: validate tags, create GitHub releases, trigger Packagist update
  • PR Labeler: apply labels to pull requests
  • Semantic PR Title: enforce pull request title format
  • OpenSSF Scorecard: publish scorecard results as SARIF
  • Secret Scanning: workflow file exists, but the gitleaks job may be disabled depending on repository settings

External services currently used by workflows:

License

This project is licensed under the MIT License.