{"id":36397276,"url":"https://github.com/jeyroik/extas-m","last_synced_at":"2026-01-11T16:00:00.484Z","repository":{"id":56998483,"uuid":"137048868","full_name":"jeyroik/extas-m","owner":"jeyroik","description":"EXTendable State Machine","archived":false,"fork":false,"pushed_at":"2023-06-08T19:03:15.000Z","size":201,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-12-31T05:40:23.015Z","etag":null,"topics":["extas","php","state-machine"],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jeyroik.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-06-12T09:28:57.000Z","updated_at":"2020-03-26T10:48:11.000Z","dependencies_parsed_at":"2022-08-21T14:10:23.834Z","dependency_job_id":null,"html_url":"https://github.com/jeyroik/extas-m","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/jeyroik/extas-m","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeyroik%2Fextas-m","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeyroik%2Fextas-m/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeyroik%2Fextas-m/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeyroik%2Fextas-m/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jeyroik","download_url":"https://codeload.github.com/jeyroik/extas-m/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeyroik%2Fextas-m/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28312027,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-11T14:58:17.114Z","status":"ssl_error","status_checked_at":"2026-01-11T14:55:53.580Z","response_time":60,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["extas","php","state-machine"],"created_at":"2026-01-11T16:00:00.352Z","updated_at":"2026-01-11T16:00:00.477Z","avatar_url":"https://github.com/jeyroik.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# extas-m\n\nПакет машины состояния для Extas'a.\n\n# Установка\n\n```composer require jeyroik/extas-m:*```\n\n# Использование\n\n## Использование демонстрационной машины состояния\n\nСразу же после установки можно запустить демонстрационную машину состояния:\n\n```php\nuse extas\\components\\SystemContainer as Container;\nuse extas\\interfaces\\machines\\IMachineRepository;\nuse extas\\interfaces\\machines\\IMachine;\n\n$machineRepo = Container::getItem(IMachineRepository::class);\n$machine = $machineRepo-\u003eone([IMachine::FIELD__NAME =\u003e 'extas.demo']);\n$machine-\u003erun('init', ['anything' =\u003e 'you want']);\n```\n\nВы должны увидеть следующий вывод:\n\n```text\nInitialized demo machine with the context:\n[\n    'anything' =\u003e 'you want'\n]\nSet to context initialized = true\nFinished demo machine with the context: \n[\n    'anything' =\u003e 'you want',\n    'initialized' =\u003e true\n]\n```\n\nКроме того, можно посмотреть цепочку переходов состояний из одного в другое:\n\n```php\necho '\u003cpre\u003e' . print_r($machine-\u003egetDump(), true) . '\u003c/pre\u003e;\n```\n\nВы должны увидеть следующее:\n\n```text\n[\n    [\n        'state_from' =\u003e 'extas.demo.not initialized yet',\n        'state_to' =\u003e 'extas.demo.init',\n        'context' =\u003e [\n            'anything' =\u003e 'you want'\n        ]\n    ],\n    [\n        'state_from' =\u003e 'extas.demo.init',\n        'state_to' =\u003e 'extas.demo.end',\n        'context' =\u003e [\n            'anything' =\u003e 'you want',\n            'initialized' =\u003e true\n        ]    \n    ]\n]\n```\n\n## Создание своей машины состояния\n    \n### Создание конфигурации машины\n\nДля начала необходимо сконфигурировать машину и состояния. Их необходимо указать в extas-совместимой конфигурации.\n\n```json\n{\n  \"machine_states\": [\n    {\n      \"name\": \"init\",\n      \"title\": \"Инициализация\",\n      \"description\": \"Состояние инициализации машины\"\n    },\n    {\n      \"name\": \"hello\",\n      \"title\": \"Привет\",\n      \"description\": \"Приветствие\",\n      \"parameters\": [{\"name\": \"text\"}]\n    },\n    {\n      \"name\": \"space\",\n      \"title\": \"Пробел\",\n      \"description\": \"Состояние пробела\",\n      \"parameters\": [{\"name\": \"text\"}]\n    },\n    {\n      \"name\": \"end\",\n      \"title\": \"Конец\",\n      \"description\": \"завершающее состояние машины\",\n      \"parameters\": [{\"name\": \"text\"}]\n    },\n    {\n      \"name\": \"someone\",\n      \"title\": \"Некто\",\n      \"description\": \"Состояние незнакомца\",\n      \"parameters\": [{\"name\": \"text\"}, {\"name\": \"user\"}]\n    },\n    {\n      \"name\": \"print_html\",\n      \"title\": \"Вывести HTML\",\n      \"description\": \"Вывод HTML\",\n      \"parameters\": [{\"name\": \"data\"}]\n    },\n    {\n      \"name\": \"print_json\",\n      \"title\": \"Вывод JSON\",\n      \"description\": \"Вывод JSON\",\n      \"parameters\": [{\"name\": \"data\"}]\n    }\n  ],\n  \"machines\": [\n    {\n      \"name\": \"hello_world\",\n      \"title\": \"Привет мир\",\n      \"description\": \"Данная машина выводит приветственное сообщение миру\",\n      \"states\": [\n        {\n          \"name\": \"init\",\n          \"on_success\": {\"state\": \"hello\"},\n          \"on_failure\": {\"state\": \"end\"}\n        },\n        {\n          \"name\": \"hello\",\n          \"on_success\": {\"state\": \"space\"},\n          \"on_failure\": {\"state\": \"end\"}\n        },\n        {\n          \"name\": \"space\",\n          \"on_success\": {\"state\": \"world\"},\n          \"on_failure\": {\"state\": \"end\"}\n        },\n        {\n          \"name\": \"world\",\n          \"on_success\": {\"state\": \"end\"},\n          \"on_failure\": {\"state\": \"someone\"}\n        },\n        {\n          \"name\": \"end\",\n          \"on_success\": {\"machine\": \"sub_machine\", \"state\": \"print_html\"}\n        },\n        {\n          \"name\": \"someone\"\n        }\n      ]\n    },\n    {\n      \"name\": \"sub_machine\",\n      \"parameters\": [{\"name\": \"text\"}],\n      \"states\": [\n        {\n          \"name\": \"print_html\",\n          \"on_failure\": {\"state\": \"print_json\"}\n        },\n        {\n          \"name\": \"print_json\"\n        }\n      ]\n    }\n  ]\n}\n```\n\n- `Параметры состояния` - это необходимые для состояния параметры контекста. Если хотя бы один из параметров отсутствует в контексте, то состояние считается не валидным и его запуск будет отменён.\n- `Параметры машины` - это параметры для всех состояний, используемых в данной машине. \n\n### Создание плагинов для состояний\n\nДалее необходимо создать плагины для обработки состояний. \n\n```php\nuse extas\\components\\plugins\\Plugin;\n\nclass PluginStateHello extends Plugin\n{\n    public function __invoke($state, \u0026$context, $machine, \u0026$isSuccess)\n    {\n        $context['text'] = $context['text'] . 'hello';\n        $isSuccess = true;\n    }\n}\n\nclass PluginStateSpace extends Plugin\n{\n    public function __invoke($state, \u0026$context, $machine, \u0026$isSuccess)\n    {\n        $context['text'] = $context['text'] . ' ';\n        $isSuccess = true;\n    }\n}\n\nclass PluginStateWorld extends Plugin\n{\n    public function __invoke($state, \u0026$context, $machine, \u0026$isSuccess)\n    {\n        $context['text'] = $context['text'] . 'world';\n        $isSuccess = true;\n    }\n}\n```\n### Установка машины, состояний и плагинов\n\n`/vendor/bin/extas i`\n\n### Запуск машины состояния\n\n```php\n$machine = $machineRepo-\u003eone([IMachine::FIELD__NAME =\u003e 'hello_world'])\n$machine-\u003erun('hello', ['text' =\u003e '']); // \"hello world\" \n/**\n * [\n *    [\n *      \"state_from\" =\u003e \"hello_world.init\",\n *      \"state_to\" =\u003e \"hello_world.hello\",\n *      \"context\" =\u003e [\n *        \"text\" =\u003e \"\"\n *      ]\n *    ],\n *    [\n *      \"state_from\" =\u003e \"hello_world.hello\",\n *      \"state_to\" =\u003e \"hello_world.hello\",\n *      \"context\" =\u003e [\n *        \"text\" =\u003e \"hello\"\n *      ]\n *    ], \n *    [\n *      \"state_from\" =\u003e \"hello_world.space\",\n *      \"state_to\" =\u003e \"hello_world.hello\",\n *      \"context\" =\u003e [\n *        \"text\" =\u003e \"hello \"\n *      ]\n *    ],\n *    [\n *      \"state_from\" =\u003e \"hello_world.world\",\n *      \"state_to\" =\u003e \"hello_world.end\",\n *      \"context\" =\u003e [\n *        \"text\" =\u003e \"hello world\"\n *      ]\n *    ],\n *    [\n *      \"state_from\" =\u003e \"hello_world.end\",\n *      \"state_to\" =\u003e \"sub_machine.print_html\",\n *      \"context\" =\u003e [\n *        \"text\" =\u003e \"hello world\"\n *      ]\n *    ]\n * ] \n */\n$machine-\u003edump();\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjeyroik%2Fextas-m","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjeyroik%2Fextas-m","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjeyroik%2Fextas-m/lists"}