{"id":494689,"date":"2026-09-15T08:00:09","date_gmt":"2026-09-15T08:00:09","guid":{"rendered":"https:\/\/savepearlharbor.com\/?p=494689"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=494689","title":{"rendered":"Symfony Workflow: \u043a\u0430\u043a \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u043b\u043e\u0436\u043d\u0443\u044e \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0443 \u0447\u0435\u0440\u0435\u0437 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u044b"},"content":{"rendered":"<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width \"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/6ed\/391\/1e2\/6ed3911e2c4696f67d3aac8ab8aec910.png\" width=\"780\" height=\"440\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/6ed\/391\/1e2\/6ed3911e2c4696f67d3aac8ab8aec910.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/6ed\/391\/1e2\/6ed3911e2c4696f67d3aac8ab8aec910.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u0417\u0430\u043a\u0430\u0437 \u0432 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442-\u043c\u0430\u0433\u0430\u0437\u0438\u043d\u0435 \u0440\u0435\u0434\u043a\u043e \u0436\u0438\u0432\u0451\u0442 \u043f\u043e \u0438\u0434\u0435\u0430\u043b\u044c\u043d\u043e\u0439 \u0441\u0445\u0435\u043c\u0435 \u00ab\u0441\u043e\u0437\u0434\u0430\u043d \u2192 \u043e\u043f\u043b\u0430\u0447\u0435\u043d \u2192 \u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u00bb. \u0412 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0436\u0438\u0437\u043d\u0435\u043d\u043d\u044b\u0439 \u0446\u0438\u043a\u043b \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u043d\u0435\u043b\u0438\u043d\u0435\u0439\u043d\u044b\u0439: \u043a\u043b\u0438\u0435\u043d\u0442 \u043e\u0444\u043e\u0440\u043c\u043b\u044f\u0435\u0442 \u0437\u0430\u043a\u0430\u0437, \u043d\u043e \u043c\u043e\u0436\u0435\u0442 \u043f\u0435\u0440\u0435\u0434\u0443\u043c\u0430\u0442\u044c \u0438 \u043e\u0442\u043c\u0435\u043d\u0438\u0442\u044c \u0435\u0433\u043e; \u0442\u043e\u0432\u0430\u0440 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442 \u0441 \u0431\u0440\u0430\u043a\u043e\u043c \u0438 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0442; \u0447\u0430\u0441\u0442\u044c \u043f\u043e\u0437\u0438\u0446\u0438\u0439 \u043d\u0435 \u0443\u0441\u043f\u0435\u043b\u0430 \u043f\u0440\u0438\u0439\u0442\u0438 \u0438 \u043d\u0443\u0436\u043d\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0438\u0445 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e. \u041f\u043e\u043f\u044b\u0442\u043a\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u0430\u043a\u0438\u0435 \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0435 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0438, \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043f\u0440\u0430\u0432 \u0438 \u0441\u043e\u043f\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u00ab\u0432 \u043b\u043e\u0431\u00bb \u0431\u044b\u0441\u0442\u0440\u043e \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0443 \u0432 \u0445\u0430\u043e\u0441 \u0438\u0437 \u0440\u0430\u0437\u0440\u043e\u0437\u043d\u0435\u043d\u043d\u044b\u0445 if\/else, \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a \u0441\u0442\u0430\u0442\u0443\u0441\u043e\u0432 \u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u043f\u043e \u0432\u0441\u0435\u043c\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0443.<\/p>\n<p>\u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u0440\u0430\u0437\u0431\u0435\u0440\u0451\u043c, \u043a\u0430\u043a \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 Symfony Workflow \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0441\u043b\u043e\u0436\u043d\u044b\u0435 \u0431\u0438\u0437\u043d\u0435\u0441-\u043f\u0440\u043e\u0446\u0435\u0441\u0441\u044b \u0432 \u0432\u0438\u0434\u0435 \u044f\u0432\u043d\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439 \u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043e\u0432. \u041d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a \u0437\u0430\u0434\u0430\u0432\u0430\u0442\u044c \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0435 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u044b, \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u0431\u0438\u0437\u043d\u0435\u0441-\u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438, \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0438 \u043e\u0442\u0434\u0435\u043b\u044f\u0442\u044c \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430 \u043e\u0442 \u043a\u043e\u0434\u0430, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0449\u0435\u0433\u043e \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f. \u0412 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u0442\u0430\u0442\u0443\u0441\u0430\u043c\u0438, \u0430 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u0435\u043b\u0430\u0435\u0442 \u0441\u043b\u043e\u0436\u043d\u0443\u044e \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0443 \u043f\u043e\u043d\u044f\u0442\u043d\u043e\u0439, \u043f\u0440\u0435\u0434\u0441\u043a\u0430\u0437\u0443\u0435\u043c\u043e\u0439 \u0438 \u0443\u0434\u043e\u0431\u043d\u043e\u0439 \u0434\u043b\u044f \u0441\u043e\u043f\u0440\u043e\u0432\u043e\u0436\u0434\u0435\u043d\u0438\u044f.<\/p>\n<p><strong>\u041f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043f\u0440\u0438\u043c\u0435\u0440:<\/strong> \u0421\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u0434\u043b\u044f \u0441\u0442\u0430\u0442\u044c\u0438 \u043c\u044b \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u043b\u0438 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u043d\u0430 GitHub \u2014 <a href=\"https:\/\/github.com\/alexdontsov\/symfony_workflow_lesson\">symfony_workflow_lesson<\/a>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u043d\u043e \u0441\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u0440\u0430\u0437\u0431\u043e\u0440\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u043a\u043e\u0434\u0430.<\/p>\n<blockquote>\n<p>\u041f\u043e\u043b\u044c\u0437\u0443\u044f\u0441\u044c \u0441\u043b\u0443\u0447\u0430\u0435\u043c, \u043a\u043e\u043c\u0430\u043d\u0434\u0430 FirstVDS \u0433\u043e\u0440\u044f\u0447\u043e \u043f\u043e\u0437\u0434\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0441 \u043f\u0440\u043e\u0448\u0435\u0434\u0448\u0438\u043c \u0414\u043d\u0451\u043c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442\u0430 \u0432\u0441\u0435\u0445 IT-\u0433\u0435\u0440\u043e\u0435\u0432! \u0412 \u0447\u0435\u0441\u0442\u044c \u044d\u0442\u043e\u0433\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0434\u0430\u0440\u0438\u043c \u043f\u0440\u043e\u043c\u043e\u043a\u043e\u0434 \u0441\u043e\u00a0\u0441\u043a\u0438\u0434\u043a\u043e\u0439 25%\u00a0\u043d\u0430 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0439 \u043f\u0435\u0440\u0438\u043e\u0434 \u0437\u0430\u043a\u0430\u0437\u0430 (1, 3, 6, 12 \u043c\u0435\u0441\u044f\u0446\u0435\u0432) \u043d\u043e\u0432\u044b\u0445 VDS \u0432 \u0420\u043e\u0441\u0441\u0438\u0438, \u041d\u0438\u0434\u0435\u0440\u043b\u0430\u043d\u0434\u0430\u0445 \u0438\u043b\u0438 \u041a\u0430\u0437\u0430\u0445\u0441\u0442\u0430\u043d\u0435. \u0423\u0441\u043f\u0435\u0439\u0442\u0435 <a href=\"https:\/\/firstvds.ru\/actions\/dev_day_2026\">\u0430\u043a\u0442\u0438\u0432\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u043a\u0438\u0434\u043a\u0443<\/a>! <\/p>\n<\/blockquote>\n<h3>\u041a\u0430\u043a\u0443\u044e \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 \u0440\u0435\u0448\u0430\u0435\u0442 Workflow<\/h3>\n<p>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0443\u043f\u0440\u043e\u0449\u0451\u043d\u043d\u0443\u044e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0441\u043c\u0435\u043d\u044b \u0441\u0442\u0430\u0442\u0443\u0441\u0430 \u0437\u0430\u043a\u0430\u0437\u0430 \u0431\u0435\u0437 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432:<\/p>\n<pre><code class=\"php\">public function pay(Order $order): void{    if ($order-&gt;getStatus() !== OrderStatus::PendingPayment) {        throw new \\DomainException('Order is not awaiting payment');    }    $order-&gt;setStatus(OrderStatus::Paid);}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:87px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041d\u0430 \u043f\u0435\u0440\u0432\u044b\u0439 \u0432\u0437\u0433\u043b\u044f\u0434 \u0432\u0441\u0451 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e: \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0438 \u043c\u0435\u043d\u044f\u0435\u043c \u0435\u0433\u043e \u043d\u0430 \u043d\u043e\u0432\u043e\u0435. \u041e\u0434\u043d\u0430\u043a\u043e \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u0436\u0438\u0437\u043d\u0435\u043d\u043d\u044b\u0439 \u0446\u0438\u043a\u043b \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0440\u0435\u0434\u043a\u043e \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0434\u0432\u0443\u043c\u044f-\u0442\u0440\u0435\u043c\u044f \u0441\u0442\u0430\u0442\u0443\u0441\u0430\u043c\u0438. \u041f\u043e\u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043e\u0442\u043c\u0435\u043d\u0430 \u0437\u0430\u043a\u0430\u0437\u0430, \u0432\u043e\u0437\u0432\u0440\u0430\u0442 \u0441\u0440\u0435\u0434\u0441\u0442\u0432, \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u0430\u044f \u043e\u043f\u043b\u0430\u0442\u0430, \u0447\u0430\u0441\u0442\u0438\u0447\u043d\u0430\u044f \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0430, \u0440\u0430\u0437\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u0440\u043e\u043b\u0435\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0441\u043e\u043f\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043f\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u043c \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0435: \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0439, \u0440\u0435\u0437\u0435\u0440\u0432\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438\u043b\u0438 \u0441\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0442\u043e\u0432\u0430\u0440\u0430, \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u044f \u0441\u043e\u0431\u044b\u0442\u0438\u0439, \u0437\u0430\u043f\u0438\u0441\u044c \u0432 \u0436\u0443\u0440\u043d\u0430\u043b \u0430\u0443\u0434\u0438\u0442\u0430.<\/p>\n<p>\u0412 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u043a\u0430\u0436\u0434\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u043e\u0431\u0440\u0430\u0441\u0442\u0430\u0442\u044c \u0434\u0443\u0431\u043b\u0438\u0440\u0443\u044e\u0449\u0438\u043c\u0438\u0441\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430\u043c\u0438 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f, \u0443\u0441\u043b\u043e\u0432\u0438\u0439 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u0438 \u043f\u0440\u0430\u0432 \u0434\u043e\u0441\u0442\u0443\u043f\u0430. \u0421\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0435\u043c \u0431\u0438\u0437\u043d\u0435\u0441-\u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u043e\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u044b \u043f\u043e \u0434\u0435\u0441\u044f\u0442\u043a\u0430\u043c \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432, \u0430 \u043f\u043e\u043d\u044f\u0442\u044c, \u043a\u0430\u043a\u0438\u0435 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u044b \u0432\u043e\u043e\u0431\u0449\u0435 \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b, \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u0432\u0441\u0451 \u0441\u043b\u043e\u0436\u043d\u0435\u0435. \u041b\u044e\u0431\u043e\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u043f\u043e\u0438\u0441\u043a\u0430 \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0439 \u043b\u043e\u0433\u0438\u043a\u0438 \u043f\u043e \u0432\u0441\u0435\u043c\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0443, \u0438\u0437-\u0437\u0430 \u0447\u0435\u0433\u043e \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u043e\u0441\u0442\u044c \u043e\u0448\u0438\u0431\u043a\u0438 \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u0440\u0430\u0441\u0442\u0451\u0442. \u0418\u043c\u0435\u043d\u043d\u043e \u044d\u0442\u0443 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 \u0440\u0435\u0448\u0430\u0435\u0442 Symfony Workflow. \u041a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0432\u044b\u043d\u0435\u0441\u0442\u0438 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043e\u0432 \u0432 \u0435\u0434\u0438\u043d\u043e\u0435 \u0446\u0435\u043d\u0442\u0440\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435, \u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044e \u043e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u043b\u0438\u0448\u044c \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043d\u0430 \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0435\u0433\u043e:<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td data-colwidth=\"370\" width=\"370\">\n<p align=\"left\"><strong>\u0411\u0435\u0437 Workflow\u00a0<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u0421 Workflow<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"370\" width=\"370\">\n<p align=\"left\">\u041f\u0440\u0430\u0432\u0438\u043b\u0430 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043e\u0432 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u044b \u043f\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u043c \u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430\u043c\u00a0<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0412\u0441\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u044b \u043e\u043f\u0438\u0441\u0430\u043d\u044b \u0432 \u043e\u0434\u043d\u043e\u043c \u043c\u0435\u0441\u0442\u0435<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"370\" width=\"370\">\n<p align=\"left\">\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043f\u0438\u0441\u0430\u0442\u044c \u0432\u0440\u0443\u0447\u043d\u0443\u044e<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041d\u0435\u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0435 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u044b \u0431\u043b\u043e\u043a\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"370\" width=\"370\">\n<p align=\"left\">\u041b\u0435\u0433\u043a\u043e \u0437\u0430\u0431\u044b\u0442\u044c \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u0432 \u043d\u043e\u0432\u043e\u043c \u043a\u043e\u0434\u0435<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0412\u0441\u0435 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u044b \u043f\u0440\u043e\u0445\u043e\u0434\u044f\u0442 \u0447\u0435\u0440\u0435\u0437 \u0435\u0434\u0438\u043d\u044b\u0439 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"370\" width=\"370\">\n<p align=\"left\">\u0421\u043b\u043e\u0436\u043d\u043e \u043f\u043e\u043d\u044f\u0442\u044c \u0436\u0438\u0437\u043d\u0435\u043d\u043d\u044b\u0439 \u0446\u0438\u043a\u043b \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u00a0<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u0440\u043e\u0446\u0435\u0441\u0441 \u043c\u043e\u0436\u043d\u043e \u0432\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432 \u0432\u0438\u0434\u0435 \u0441\u0445\u0435\u043c\u044b<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"370\" width=\"370\">\n<p align=\"left\">\u0411\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0430 \u0441\u043c\u0435\u0448\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0441 \u043f\u0440\u0438\u043a\u043b\u0430\u0434\u043d\u044b\u043c \u043a\u043e\u0434\u043e\u043c<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u0440\u0430\u0432\u0438\u043b\u0430 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430 \u043e\u0442\u0434\u0435\u043b\u0435\u043d\u044b \u043e\u0442 \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u0412 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 Workflow \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u043c \u0441\u043c\u0435\u043d\u044b \u0441\u0442\u0430\u0442\u0443\u0441\u043e\u0432, \u0430 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u043e\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u0443\u0435\u0442 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0441\u0442\u044c \u0436\u0438\u0437\u043d\u0435\u043d\u043d\u043e\u0433\u043e \u0446\u0438\u043a\u043b\u0430 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0438 \u0434\u0435\u043b\u0430\u0435\u0442 \u0431\u0438\u0437\u043d\u0435\u0441-\u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u044f\u0432\u043d\u044b\u043c \u043a\u0430\u043a \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432, \u0442\u0430\u043a \u0438 \u0434\u043b\u044f \u0441\u0430\u043c\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b.<\/p>\n<h3>\u0427\u0442\u043e \u0442\u0430\u043a\u043e\u0435 Symfony Workflow, \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043f\u043e\u043d\u044f\u0442\u0438\u044f<\/h3>\n<p>\u041f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u0442\u044c \u043a \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430, \u0440\u0430\u0437\u0431\u0435\u0440\u0451\u043c\u0441\u044f \u0441 \u0435\u0433\u043e \u0442\u0435\u0440\u043c\u0438\u043d\u043e\u043b\u043e\u0433\u0438\u0435\u0439. \u0412\u0441\u0435 \u043f\u043e\u043d\u044f\u0442\u0438\u044f \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u043f\u0440\u0438\u0432\u044b\u0447\u043d\u044b\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u043c \u0431\u0438\u0437\u043d\u0435\u0441-\u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430:<\/p>\n<ol>\n<li>\n<p><strong>Place (\u043c\u0435\u0441\u0442\u043e\/\u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435)<\/strong> \u2014 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043e\u0431\u044a\u0435\u043a\u0442. \u0412 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0435\u043c\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0437\u0430\u043a\u0430\u0437\u0430 \u0442\u0430\u043a\u0438\u043c\u0438 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f\u043c\u0438 \u0432\u044b\u0441\u0442\u0443\u043f\u0430\u044e\u0442 <code>new, pending_payment, paid<\/code> \u0438 \u0442. \u0434. \u0412 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432 \u043e\u043d\u0438 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0432 \u0432\u0438\u0434\u0435 Enum \u0438\u043b\u0438 \u0441\u0442\u0440\u043e\u043a\u043e\u0432\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0432 \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<\/li>\n<li>\n<p><strong>Transition (\u043f\u0435\u0440\u0435\u0445\u043e\u0434)<\/strong> \u2014 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435, \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u044f\u0449\u0435\u0435 \u043e\u0431\u044a\u0435\u043a\u0442 \u0438\u0437 \u043e\u0434\u043d\u043e\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0432 \u0434\u0440\u0443\u0433\u043e\u0435 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <code>submit<\/code> \u2014 \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u0438\u0437 <code>new<\/code> \u0432 <code>pending_payment<\/code>). \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435: \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u0438\u043c\u0435\u0435\u0442 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435 \u0438\u043c\u044f. \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435 \u0433\u043e\u0432\u043e\u0440\u044f\u0442 \u043d\u0435 \u00ab\u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0441\u0442\u0430\u0442\u0443\u0441 \u043d\u0430 <code>paid<\/code>\u00bb, \u0430 \u00ab\u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043f\u0435\u0440\u0435\u0445\u043e\u0434 <code>pay<\/code>\u00bb. \u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u044d\u0442\u043e\u043c\u0443 \u043a\u043e\u0434 \u043e\u0442\u0440\u0430\u0436\u0430\u0435\u0442 \u0431\u0438\u0437\u043d\u0435\u0441-\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f, \u0430 \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u0435\u0442 \u043d\u043e\u0432\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u044e.<\/p>\n<\/li>\n<li>\n<p><strong>Marking (\u043c\u0435\u0442\u043a\u0430)<\/strong> \u2014 \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 (\u0438\u043b\u0438 \u043d\u0430\u0431\u043e\u0440 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439). \u0412 \u0441\u043b\u0443\u0447\u0430\u0435 <code>state_machine<\/code> \u043c\u0435\u0442\u043a\u0430 \u0440\u043e\u0432\u043d\u043e \u043e\u0434\u043d\u0430 \u0438 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0442\u0435\u043a\u0443\u0449\u0435\u043c\u0443 \u0441\u0442\u0430\u0442\u0443\u0441\u0443 \u0437\u0430\u043a\u0430\u0437\u0430.<\/p>\n<\/li>\n<\/ol>\n<p>\u041e\u0431\u044b\u0447\u043d\u043e \u043c\u0435\u0442\u043a\u0430 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0432 \u043e\u0434\u043d\u043e\u043c \u0438\u0437 \u043f\u043e\u043b\u0435\u0439 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438:<\/p>\n<pre><code>class Order {    private string $status = 'new';}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0418\u043c\u0435\u043d\u043d\u043e \u044d\u0442\u043e \u043f\u043e\u043b\u0435 Symfony Workflow \u0431\u0443\u0434\u0435\u0442 \u0447\u0438\u0442\u0430\u0442\u044c \u0438 \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u043f\u0440\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043e\u0432.<\/p>\n<h4>Workflow vs State Machine<\/h4>\n<p>Symfony \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0434\u0432\u0430 \u0440\u0435\u0436\u0438\u043c\u0430 \u0440\u0430\u0431\u043e\u0442\u044b: <strong>Workflow<\/strong> \u0438 <strong>State Machine<\/strong>. \u0413\u043b\u0430\u0432\u043d\u043e\u0435 \u0440\u0430\u0437\u043b\u0438\u0447\u0438\u0435 \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0435 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0445 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439:<\/p>\n<ol>\n<li>\n<p><strong>State Machine<\/strong> \u0434\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e <em>\u043e\u0434\u043d\u043e<\/em> \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0432 \u043a\u0430\u0436\u0434\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0432\u0440\u0435\u043c\u0435\u043d\u0438. \u0414\u043b\u044f \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0430 \u0431\u0438\u0437\u043d\u0435\u0441-\u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439 \u2014 \u0437\u0430\u043a\u0430\u0437\u0430, \u0441\u0447\u0451\u0442\u0430, \u0437\u0430\u044f\u0432\u043a\u0438, \u0434\u043e\u0433\u043e\u0432\u043e\u0440\u0430 \u2014 \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442 \u0438\u043c\u0435\u043d\u043d\u043e \u044d\u0442\u043e\u0442 \u0440\u0435\u0436\u0438\u043c. \u0417\u0430\u043a\u0430\u0437 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u0431\u044b\u0442\u044c \u00ab\u043e\u043f\u043b\u0430\u0447\u0435\u043d\u00bb \u0438 \u00ab\u043e\u0442\u043c\u0435\u043d\u0451\u043d\u00bb.<\/p>\n<\/li>\n<li>\n<p><strong>Workflow<\/strong> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043e\u0431\u044a\u0435\u043a\u0442\u0443 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u0441\u0440\u0430\u0437\u0443 \u0432 <em>\u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445<\/em> \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f\u0445. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442 \u043c\u043e\u0436\u0435\u0442 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u043d\u0430 \u0441\u043e\u0433\u043b\u0430\u0441\u043e\u0432\u0430\u043d\u0438\u0438 \u0443 \u044e\u0440\u0438\u0434\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u043e\u0442\u0434\u0435\u043b\u0430, \u043d\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0435 \u0441\u043b\u0443\u0436\u0431\u044b \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u0438 \u0438 \u043d\u0430 \u0443\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0438 \u0443 \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044f.<\/p>\n<\/li>\n<\/ol>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <strong>State Machine<\/strong>, \u0442\u0430\u043a \u043a\u0430\u043a \u044d\u0442\u043e\u0442 \u0440\u0435\u0436\u0438\u043c \u0438\u0434\u0435\u0430\u043b\u044c\u043d\u043e \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u043c\u0443 \u0436\u0438\u0437\u043d\u0435\u043d\u043d\u043e\u043c\u0443 \u0446\u0438\u043a\u043b\u0443 \u0437\u0430\u043a\u0430\u0437\u0430 \u0438 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0451\u043d\u043d\u044b\u043c \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0435\u043c.<\/p>\n<h3>\u041e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435<\/h3>\n<p>\u0414\u043b\u044f \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u0438\u0437 \u0441\u0442\u0430\u0442\u044c\u0438 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u044c\u0442\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435. \u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043a\u043b\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0433\u043e\u0442\u043e\u0432\u044b\u0439 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u0441 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u043c \u0438\u043b\u0438 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 Symfony \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0439 \u0441\u0442\u0435\u043a:<\/p>\n<ol>\n<li>\n<p>PHP 8.3+ (\u0438\u043b\u0438 PHP 8.5)<\/p>\n<\/li>\n<li>\n<p>Nginx \/ Web-\u0441\u0435\u0440\u0432\u0435\u0440<\/p>\n<\/li>\n<li>\n<p>PostgreSQL<\/p>\n<\/li>\n<li>\n<p>Docker Compose<\/p>\n<\/li>\n<\/ol>\n<p>\u041f\u043e\u0441\u043b\u0435 \u043a\u043b\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b:<\/p>\n<pre><code class=\"bash\">docker compose up -d<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 Symfony Workflow \u0438 Doctrine ORM:<\/p>\n<pre><code class=\"bash\">docker compose exec php composer require symfony\/workflow doctrine<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 Flex \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0441\u043e\u0437\u0434\u0430\u0441\u0442 \u0431\u0430\u0437\u043e\u0432\u0443\u044e \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<h3>\u041c\u043e\u0434\u0435\u043b\u044c \u0434\u0430\u043d\u043d\u044b\u0445: \u0437\u0430\u043a\u0430\u0437 \u0438 \u0441\u0442\u0430\u0442\u0443\u0441\u044b<\/h3>\n<p>\u0414\u043b\u044f \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0440\u0430\u0431\u043e\u0442\u044b Workflow \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0443\u043f\u0440\u043e\u0449\u0451\u043d\u043d\u0443\u044e \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c \u0437\u0430\u043a\u0430\u0437\u0430. \u041d\u0430\u0441 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u0435\u0442 \u0436\u0438\u0437\u043d\u0435\u043d\u043d\u044b\u0439 \u0446\u0438\u043a\u043b \u043e\u0431\u044a\u0435\u043a\u0442\u0430, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0441\u043e\u0441\u0440\u0435\u0434\u043e\u0442\u043e\u0447\u0438\u043c\u0441\u044f \u043d\u0430 \u043f\u043e\u043b\u0435 <code>$status<\/code>. \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c Enum \u0441\u0442\u0430\u0442\u0443\u0441\u043e\u0432:<\/p>\n<pre><code class=\"php\">\/\/ src\/Enum\/OrderStatus.phpenum OrderStatus: string{    case New = 'new';    case PendingPayment = 'pending_payment';    case Paid = 'paid';    case Processing = 'processing';    case Shipped = 'shipped';    case Delivered = 'delivered';    case Cancelled = 'cancelled';    case Refunded = 'refunded';}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><strong>\u0412\u0430\u0436\u043d\u043e:<\/strong> \u0421\u0442\u0440\u043e\u043a\u043e\u0432\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f Enum (<code>new, pending_payment, paid<\/code> \u0438 \u0442. \u0434.) \u0434\u043e\u043b\u0436\u043d\u044b \u0441\u0442\u0440\u043e\u0433\u043e \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u0442\u044c \u0441 \u0438\u043c\u0435\u043d\u0430\u043c\u0438 places, \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u043c\u0438 \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 Workflow.<\/p>\n<h4>\u0421\u0443\u0449\u043d\u043e\u0441\u0442\u044c Order<\/h4>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0441\u0430\u043c\u0443 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c:<\/p>\n<pre><code class=\"php\">\/\/ src\/Entity\/Order.phpnamespace App\\Entity;use App\\Enum\\OrderStatus;use Doctrine\\ORM\\Mapping as ORM;#[ORM\\Entity]#[ORM\\Table(name: 'orders')]class Order{    #[ORM\\Id]    #[ORM\\GeneratedValue]    #[ORM\\Column(type: 'integer')]    private ?int $id = null;    #[ORM\\Column(enumType: OrderStatus::class)]    private OrderStatus $status = OrderStatus::New;    public function getId(): ?int    {        return $this-&gt;id;    }    public function getStatus(): OrderStatus    {        return $this-&gt;status;    }    public function setStatus(OrderStatus $status): static    {        $this-&gt;status = $status;        return $this;    }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>Symfony Workflow \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f \u043e\u0442 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0445 \u0431\u0430\u0437\u043e\u0432\u044b\u0445 \u043a\u043b\u0430\u0441\u0441\u043e\u0432, \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0442\u0440\u0435\u0439\u0442\u043e\u0432 \u0438\u043b\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u0445 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u043e\u0432. \u0414\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e, \u0445\u0440\u0430\u043d\u044f\u0449\u0435\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 (<code>marking_store.property<\/code>), \u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0431\u0443\u0434\u0435\u0442 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0447\u0438\u0442\u0430\u0442\u044c \u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \u0435\u0433\u043e \u0447\u0435\u0440\u0435\u0437 getter \u0438 setter (<code>getStatus() \/ setStatus()<\/code>).<\/p>\n<h3>\u041a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f Workflow<\/h3>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043e\u043f\u0438\u0448\u0435\u043c \u0436\u0438\u0437\u043d\u0435\u043d\u043d\u044b\u0439 \u0446\u0438\u043a\u043b \u0437\u0430\u043a\u0430\u0437\u0430 \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 Symfony Workflow. \u0412\u0441\u0435 \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u044b \u0431\u0443\u0434\u0443\u0442 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u0432 <code>config\/packages\/workflow.yaml<\/code>:<\/p>\n<pre><code class=\"yaml\">framework:    workflows:        order:            type: state_machine            audit_trail:                enabled: true            marking_store:                type: method                property: status            supports:                - App\\Entity\\Order            initial_marking: new            places:                - new                - pending_payment                - paid                - processing                - shipped                - delivered                - cancelled                - refunded            transitions:                submit:                    from: new                    to: pending_payment                pay:                    from: pending_payment                    to: paid                process:                    from: paid                    to: processing                ship:                    from: processing                    to: shipped                deliver:                    from: shipped                    to: delivered                cancel:                    from: [new, pending_payment, paid, processing]                    to: cancelled                refund:                    from: [paid, processing, shipped, delivered]                    to: refunded<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h4>\u041a\u043b\u044e\u0447\u0435\u0432\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b<\/h4>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p><strong>\u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440<\/strong><\/p>\n<\/th>\n<th>\n<p><strong>\u041d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435<\/strong><\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>type: state_machine<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0440\u0435\u0436\u0438\u043c, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u043d\u043e \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>marking_store.property: status<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0423\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 (<code>status<\/code>), \u0445\u0440\u0430\u043d\u044f\u0449\u0435\u0435 \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>supports<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u043a\u043b\u0430\u0441\u0441\u044b \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0439 Workflow<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>initial_marking: new<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>places<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u043e\u043b\u043d\u044b\u0439 \u0441\u043f\u0438\u0441\u043e\u043a \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0445 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>transitions<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0440\u0430\u0437\u0440\u0435\u0448\u0451\u043d\u043d\u044b\u0445 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043e\u0432 \u043c\u0435\u0436\u0434\u0443 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f\u043c\u0438<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>audit_trail.enabled: true<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0412\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 Workflow (\u0443\u0434\u043e\u0431\u043d\u043e \u043f\u0440\u0438 \u043e\u0442\u043b\u0430\u0434\u043a\u0435)<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043e\u0432:<\/p>\n<pre><code class=\"yaml\">cancel:     from: [new, pending_payment, paid, processing]    to: cancelled<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041e\u0442\u043c\u0435\u043d\u0438\u0442\u044c \u0437\u0430\u043a\u0430\u0437 \u043c\u043e\u0436\u043d\u043e \u0438\u0437 \u0447\u0435\u0442\u044b\u0440\u0451\u0445 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439, \u043d\u043e \u0438\u0442\u043e\u0433\u043e\u0432\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432\u0441\u0435\u0433\u0434\u0430 \u043e\u0434\u0438\u043d \u2014 <code>cancelled<\/code>. \u0415\u0441\u043b\u0438 \u043f\u043e\u043f\u044b\u0442\u0430\u0442\u044c\u0441\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c <code>cancel<\/code> \u0434\u043b\u044f \u0437\u0430\u043a\u0430\u0437\u0430 \u0432 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0438 <code>shipped<\/code>, Workflow \u043d\u0435 \u043d\u0430\u0439\u0434\u0451\u0442 \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0435\u0433\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0438 \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u0443\u0435\u0442 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e.<\/p>\n<h3>\u0421\u0435\u0440\u0432\u0438\u0441\u043d\u044b\u0439 \u0441\u043b\u043e\u0439<\/h3>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 Symfony \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u0442 \u0441\u0435\u0440\u0432\u0438\u0441 State Machine \u0432 DI-\u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0435. \u0414\u043b\u044f \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u0441 \u0438\u043c\u0435\u043d\u0435\u043c <code>order<\/code> \u0438 \u0442\u0438\u043f\u043e\u043c <code>state_machine<\/code> \u0441\u0435\u0440\u0432\u0438\u0441\u0443 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u0441\u0432\u043e\u0435\u043d \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 <code>state_machine.order<\/code>. \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0441\u0435\u0440\u0432\u0438\u0441-\u043e\u0431\u0451\u0440\u0442\u043a\u0443 <code>OrderWorkflowService<\/code> \u0434\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430\u043c\u0438:<\/p>\n<pre><code class=\"php\">\/\/ src\/Service\/OrderWorkflowService.phpnamespace App\\Service;use App\\Entity\\Order;use LogicException;use Symfony\\Component\\Workflow\\WorkflowInterface;final readonly class OrderWorkflowService{    public function __construct(        private WorkflowInterface $orderStateMachine,    ) {}    public function getEnabledTransitions(Order $order): array    {        return array_map(            static fn ($transition) =&gt; $transition-&gt;getName(),            $this-&gt;orderStateMachine-&gt;getEnabledTransitions($order)        );    }    public function apply(Order $order, string $transition): void    {        if (!$this-&gt;orderStateMachine-&gt;can($order, $transition)) {            throw new LogicException(sprintf(                'Transition \"%s\" is not allowed for order #%s in status \"%s\".',                $transition,                $order-&gt;getId() ?? 'new',                $order-&gt;getStatus()-&gt;value            ));        }        $this-&gt;orderStateMachine-&gt;apply($order, $transition);    }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u0432 <code>config\/services.yaml<\/code>:<\/p>\n<pre><code class=\"yaml\">services:    App\\Service\\OrderWorkflowService:        arguments:            $orderStateMachine: '@state_machine.order'<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h4>\u041e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u0440\u0430\u0431\u043e\u0442\u044b \u0441 Workflow<\/h4>\n<ol>\n<li>\n<p><code>can($object, 'transition_name')<\/code> \u2014 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442, \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c \u043b\u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u0438\u0437 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f.<\/p>\n<\/li>\n<li>\n<p><code>getEnabledTransitions($object)<\/code> \u2014 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043c\u0430\u0441\u0441\u0438\u0432 \u0432\u0441\u0435\u0445 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043e\u0432, \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u0434\u043b\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0432 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 (\u0443\u0434\u043e\u0431\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f UI \u0438\u043b\u0438 \u043e\u0442\u0432\u0435\u0442\u043e\u0432 API).<\/p>\n<\/li>\n<li>\n<p><code>apply($object, 'transition_name')<\/code> \u2014 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u0438 \u043c\u0435\u043d\u044f\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0432 \u043f\u0430\u043c\u044f\u0442\u0438.<\/p>\n<\/li>\n<\/ol>\n<p><strong>\u0412\u0430\u0436\u043d\u043e\u0435 \u0437\u0430\u043c\u0435\u0447\u0430\u043d\u0438\u0435:<\/strong> \u041c\u0435\u0442\u043e\u0434 <code>apply()<\/code> \u043c\u0435\u043d\u044f\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0438\u0441\u043a\u043b\u044e\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0432 \u043f\u0430\u043c\u044f\u0442\u0438 PHP. \u0414\u043b\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u0432 \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u044f\u0432\u043d\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434 <code>flush()<\/code> \u0443 EntityManager Doctrine.<\/p>\n<h3>\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0440\u0430\u0431\u043e\u0442\u044b<\/h3>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f Workflow \u0432 REST-\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0435.<\/p>\n<pre><code class=\"php\">\/\/ src\/Controller\/OrderController.phpnamespace App\\Controller;use App\\Entity\\Order;use App\\Service\\OrderWorkflowService;use Doctrine\\ORM\\EntityManagerInterface;use LogicException;use Symfony\\Bundle\\FrameworkBundle\\Controller\\AbstractController;use Symfony\\Component\\HttpFoundation\\JsonResponse;use Symfony\\Component\\HttpFoundation\\Request;use Symfony\\Component\\HttpFoundation\\Response;use Symfony\\Component\\Routing\\Annotation\\Route;#[Route('\/orders')]class OrderController extends AbstractController{    public function __construct(        private EntityManagerInterface $entityManager,        private OrderWorkflowService $orderWorkflow,    ) {}    #[Route('', methods: ['POST'])]    public function create(): JsonResponse    {        $order = new Order();        $this-&gt;entityManager-&gt;persist($order);        $this-&gt;entityManager-&gt;flush();        return $this-&gt;json([            'id' =&gt; $order-&gt;getId(),            'status' =&gt; $order-&gt;getStatus()-&gt;value,        ], Response::HTTP_CREATED);    }    #[Route('\/{id}\/transitions', methods: ['POST'])]    public function applyTransition(int $id, Request $request): JsonResponse    {        $data = json_decode($request-&gt;getContent(), true);        $transition = $data['transition'] ?? '';        $order = $this-&gt;entityManager-&gt;getRepository(Order::class)-&gt;find($id);        if (!$order) {            return $this-&gt;json(['error' =&gt; 'Order not found'], Response::HTTP_NOT_FOUND);        }        try {            $this-&gt;orderWorkflow-&gt;apply($order, $transition);            $this-&gt;entityManager-&gt;flush();        } catch (LogicException $exception) {            return $this-&gt;json([                'error' =&gt; $exception-&gt;getMessage(),                'availableTransitions' =&gt; $this-&gt;orderWorkflow-&gt;getEnabledTransitions($order),            ], Response::HTTP_UNPROCESSABLE_ENTITY);        }        return $this-&gt;json([            'id' =&gt; $order-&gt;getId(),            'status' =&gt; $order-&gt;getStatus()-&gt;value,        ]);    }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h4>\u041f\u0440\u0438\u043c\u0435\u0440 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f<\/h4>\n<ol>\n<li>\n<p><strong>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0437\u0430\u043a\u0430\u0437\u0430:<\/strong> <code>POST \/orders<\/code><br \/>\u041e\u0442\u0432\u0435\u0442: <code>{\"id\": 1, \"status\": \"new\"}<\/code><\/p>\n<\/li>\n<li>\n<p><strong>\u041f\u043e\u043f\u044b\u0442\u043a\u0430 \u043d\u0435\u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430:<\/strong> <code>POST \/orders\/1\/transitions<\/code> \u0441 \u0442\u0435\u043b\u043e\u043c <code>{\"transition\": \"pay\"}<\/code><br \/>\u041e\u0442\u0432\u0435\u0442:<\/p>\n<\/li>\n<\/ol>\n<pre><code class=\"json\">{    \"error\": \"Transition \\\"pay\\\" is not allowed for order #1 in status \\\"new\\\".\",    \"availableTransitions\": [\"submit\", \"cancel\"]}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><strong>\u041f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u0430\u044f \u0446\u0435\u043f\u043e\u0447\u043a\u0430 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043e\u0432:<\/strong><\/p>\n<ol>\n<li>\n<p><code>POST \/orders\/1\/transitions ({\"transition\": \"submit\"})<\/code> -&gt; Status: <code>pending_payment<\/code><\/p>\n<\/li>\n<li>\n<p><code>POST \/orders\/1\/transitions ({\"transition\": \"pay\"}<\/code>) -&gt; Status: <code>paid<\/code><\/p>\n<\/li>\n<\/ol>\n<p>\u041c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043b\u0438 \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u044b \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u0438\u0437 \u043e\u0434\u043d\u043e\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0432 \u0434\u0440\u0443\u0433\u043e\u0435 (submit \u0438 pay). \u0412\u0441\u0435 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u044b (process, ship, deliver, cancel, refund) \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e: \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0435\u0439 \u0438\u043c\u0435\u043d\u0438 \u043d\u0443\u0436\u043d\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u0432 \u043c\u0435\u0442\u043e\u0434 apply(). Symfony Workflow \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0441\u0432\u0435\u0440\u0438\u0442 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u0441\u0442\u0430\u0442\u0443\u0441 \u0437\u0430\u043a\u0430\u0437\u0430 \u0441 \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u0439 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0435\u0439 \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442 \u0441\u043c\u0435\u043d\u0443 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f, \u0435\u0441\u043b\u0438 \u0448\u0430\u0433 \u0440\u0430\u0437\u0440\u0435\u0448\u0451\u043d.<\/p>\n<h3>\u041f\u0440\u043e\u0434\u0432\u0438\u043d\u0443\u0442\u044b\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438: \u0441\u043e\u0431\u044b\u0442\u0438\u044f, Guard&#8217;\u044b \u0438 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435<\/h3>\n<h4>1. \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 (Event Subscribers)<\/h4>\n<p>Symfony Workflow \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0446\u0435\u043f\u043e\u0447\u043a\u0443 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u043d\u0430 \u0440\u0430\u0437\u043d\u044b\u0445 \u044d\u0442\u0430\u043f\u0430\u0445 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 (guard, leave, transition, enter, entered, completed).<\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0441\u043b\u0443\u0448\u0430\u0442\u0435\u043b\u044f, \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0449\u0435\u0433\u043e \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0435 \u043f\u043e\u0441\u043b\u0435 \u0443\u0441\u043f\u0435\u0448\u043d\u043e\u0439 \u043e\u043f\u043b\u0430\u0442\u044b:<\/p>\n<pre><code class=\"php\">\/\/ src\/EventListener\/OrderPaidListener.phpnamespace App\\EventListener;use App\\Entity\\Order;use Symfony\\Component\\EventDispatcher\\Attribute\\AsEventListener;use Symfony\\Component\\Workflow\\Event\\CompletedEvent;#[AsEventListener(event: 'workflow.order.completed.pay')]class OrderPaidListener{    public function __invoke(CompletedEvent $event): void    {        \/** @var Order $order *\/        $order = $event-&gt;getSubject();        \/\/ \u041b\u043e\u0433\u0438\u043a\u0430 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u043f\u0438\u0441\u044c\u043c\u0430 \u0438\u043b\u0438 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u044f \u0434\u043e\u043c\u0435\u043d\u043d\u043e\u0433\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u044f    }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h4>2. \u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 (Guard Events)<\/h4>\n<p>\u0415\u0441\u043b\u0438 \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0437\u043d\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043f\u0440\u0430\u0432 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u0438\u043b\u0438 \u0431\u0430\u043b\u0430\u043d\u0441\u0430), \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f Guard-\u0441\u043e\u0431\u044b\u0442\u0438\u044f:<\/p>\n<pre><code class=\"php\">\/\/ src\/EventListener\/OrderCancelGuard.phpnamespace App\\EventListener;use Symfony\\Component\\EventDispatcher\\Attribute\\AsEventListener;use Symfony\\Component\\Workflow\\Event\\GuardEvent;use Symfony\\Bundle\\SecurityBundle\\Security;#[AsEventListener(event: 'workflow.order.guard.cancel')]class OrderCancelGuard{    public function __construct(private Security $security) {}    public function __invoke(GuardEvent $event): void    {        if (!$this-&gt;security-&gt;isGranted('ROLE_ADMIN')) {            $event-&gt;setBlocked(true, '\u041e\u0442\u043c\u0435\u043d\u0438\u0442\u044c \u0437\u0430\u043a\u0430\u0437 \u043c\u043e\u0436\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440.');        }    }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h4>3. \u041c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435 (Metadata)<\/h4>\n<p>\u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u0440\u0438\u0432\u044f\u0437\u044b\u0432\u0430\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e (\u0447\u0435\u043b\u043e\u0432\u0435\u043a\u043e\u0447\u0438\u0442\u0430\u0435\u043c\u044b\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f, \u0446\u0432\u0435\u0442\u0430, \u0438\u043a\u043e\u043d\u043a\u0438) \u043f\u0440\u044f\u043c\u043e \u043a \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f\u043c \u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430\u043c \u0432 YAML-\u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438:<\/p>\n<pre><code class=\"yaml\">places:    paid:        metadata:            label: '\u041e\u043f\u043b\u0430\u0447\u0435\u043d'            badge_color: 'green'transitions:    pay:        from: pending_payment        to: paid        metadata:            label: '\u041e\u043f\u043b\u0430\u0442\u0438\u0442\u044c \u0437\u0430\u043a\u0430\u0437'<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435 \u0432 PHP-\u043a\u043e\u0434\u0435 \u043c\u043e\u0436\u043d\u043e \u0447\u0435\u0440\u0435\u0437 \u043e\u0431\u044a\u0435\u043a\u0442 <code>WorkflowMetadataStore<\/code>:<\/p>\n<pre><code class=\"php\">$title = $workflow-&gt;getMetadataStore()-&gt;getPlaceMetadata('paid')['label'];<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h4>4. \u0412\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0441\u0445\u0435\u043c<\/h4>\n<p>\u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 Workflow \u0432 \u0444\u043e\u0440\u043c\u0430\u0442 Graphviz (DOT) \u0438\u043b\u0438 PlantUML \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043d\u0430\u0433\u043b\u044f\u0434\u043d\u044b\u0445 \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c. \u041a\u043e\u043c\u0430\u043d\u0434\u0430 \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 DOT-\u0444\u0430\u0439\u043b\u0430 \u0447\u0435\u0440\u0435\u0437 \u043a\u043e\u043d\u0441\u043e\u043b\u044c Symfony:<\/p>\n<pre><code class=\"bash\">php bin\/console workflow:dump order | dot -Tpng -o workflow.png<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0421\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0430\u044f \u0441\u0445\u0435\u043c\u0430 \u043d\u0430\u0433\u043b\u044f\u0434\u043d\u043e \u043f\u043e\u043a\u0430\u0436\u0435\u0442 \u0432\u0441\u0435 \u043c\u0435\u0441\u0442\u0430, \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u044b \u0438 \u0432\u0435\u0442\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430, \u0437\u0430\u043c\u0435\u043d\u044f\u044f \u0441\u043e\u0431\u043e\u0439 \u0443\u0441\u0442\u0430\u0440\u0435\u0432\u0430\u044e\u0449\u0443\u044e \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u0443\u044e \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044e.<\/p>\n<h3>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h3>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 <strong>Symfony Workflow<\/strong> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043e\u0442\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u043e\u0442 \u0440\u0430\u0437\u0440\u043e\u0437\u043d\u0435\u043d\u043d\u044b\u0445 \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a \u0438 \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u0442\u044c \u0441\u043c\u0435\u043d\u0443 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439 \u0432 \u0447\u0435\u0442\u043a\u043e \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0438\u0440\u0443\u0435\u043c\u044b\u0439 \u043f\u0440\u043e\u0446\u0435\u0441\u0441. \u0412\u044b \u0432\u044b\u043d\u043e\u0441\u0438\u0442\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0436\u0438\u0437\u043d\u0435\u043d\u043d\u043e\u0433\u043e \u0446\u0438\u043a\u043b\u0430 \u0432 \u0435\u0434\u0438\u043d\u0443\u044e \u0434\u0435\u043a\u043b\u0430\u0440\u0430\u0442\u0438\u0432\u043d\u0443\u044e \u043c\u043e\u0434\u0435\u043b\u044c, \u0434\u0435\u043b\u0430\u044f \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0443 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0447\u0438\u0449\u0435 \u0438 \u043d\u0430\u0434\u0435\u0436\u043d\u0435\u0435.<\/p>\n<p><strong>\u041a\u043b\u044e\u0447\u0435\u0432\u044b\u0435 \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u0430:<\/strong><\/p>\n<ul>\n<li>\n<p><strong>\u041f\u0440\u043e\u0437\u0440\u0430\u0447\u043d\u043e\u0441\u0442\u044c:<\/strong> \u0432\u0441\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u044b \u043e\u043f\u0438\u0441\u0430\u043d\u044b \u0432 \u043e\u0434\u043d\u043e\u043c \u0444\u0430\u0439\u043b\u0435 (<code>workflow.yaml<\/code>), \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043b\u0443\u0436\u0438\u0442 \u043d\u0430\u0433\u043b\u044f\u0434\u043d\u043e\u0439 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0435\u0439 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430.<\/p>\n<\/li>\n<li>\n<p><strong>\u041d\u0430\u0434\u0435\u0436\u043d\u043e\u0441\u0442\u044c:<\/strong> \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u0443\u0435\u0442 \u0446\u0435\u043b\u043e\u0441\u0442\u043d\u043e\u0441\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0431\u043b\u043e\u043a\u0438\u0440\u0443\u0435\u0442 \u043b\u044e\u0431\u044b\u0435 \u043d\u0435\u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0435 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u044b.<\/p>\n<\/li>\n<li>\n<p><strong>\u0420\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0441\u0442\u0438:<\/strong> \u041f\u0435\u0440\u0435\u0445\u043e\u0434 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0437\u0430 \u0441\u043c\u0435\u043d\u0443 \u0441\u0442\u0430\u0442\u0443\u0441\u0430, \u0430 \u043f\u043e\u0431\u043e\u0447\u043d\u044b\u0435 \u044d\u0444\u0444\u0435\u043a\u0442\u044b (\u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f, \u0441\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0431\u0430\u043b\u0430\u043d\u0441\u0430, \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438) \u043b\u0435\u0433\u043a\u043e \u0432\u044b\u043d\u043e\u0441\u044f\u0442\u0441\u044f \u0432 \u0441\u043e\u0431\u044b\u0442\u0438\u0439\u043d\u043e-\u043e\u0440\u0438\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0441\u043b\u0443\u0448\u0430\u0442\u0435\u043b\u0438 (<code>Event Subscribers<\/code>).<\/p>\n<\/li>\n<li>\n<p><strong>\u0413\u0438\u0431\u043a\u043e\u0441\u0442\u044c \u0438 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u0443\u0435\u043c\u043e\u0441\u0442\u044c:<\/strong> \u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u043e\u0432\u044b\u0445 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439, Guard-\u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a \u043f\u0440\u0430\u0432 \u0438\u043b\u0438 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0439 \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u044b\u0432\u0430\u043d\u0438\u044f \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0438.<\/p>\n<\/li>\n<\/ul>\n<p>\u0415\u0441\u043b\u0438 \u0436\u0438\u0437\u043d\u0435\u043d\u043d\u044b\u0439 \u0446\u0438\u043a\u043b \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u0432\u044b\u0445\u043e\u0434\u0438\u0442 \u0437\u0430 \u0440\u0430\u043c\u043a\u0438 \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u0434\u0432\u0443\u0445-\u0442\u0440\u0435\u0445 \u0441\u0442\u0430\u0442\u0443\u0441\u043e\u0432 \u0438 \u043e\u0431\u0440\u0430\u0441\u0442\u0430\u0435\u0442 \u0443\u0441\u043b\u043e\u0432\u0438\u044f\u043c\u0438, \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043d\u044b\u043c\u0438 \u0432\u0435\u0442\u043a\u0430\u043c\u0438 \u0438 \u0440\u043e\u043b\u044f\u043c\u0438 \u2014 <strong>Symfony Workflow<\/strong> \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u0443\u0434\u043e\u0431\u043d\u044b\u043c \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u043d\u044b\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u043c, \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u0443\u044e\u0449\u0438\u043c \u043f\u0440\u0435\u0434\u0441\u043a\u0430\u0437\u0443\u0435\u043c\u043e\u0441\u0442\u044c \u0438 \u043f\u0440\u043e\u0441\u0442\u043e\u0442\u0443 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438 \u0441\u0438\u0441\u0442\u0435\u043c\u044b.<\/p>\n<hr\/>\n<p>\u041d\u041b\u041e \u043f\u0440\u0438\u043b\u0435\u0442\u0435\u043b\u043e \u0438 \u043e\u0441\u0442\u0430\u0432\u0438\u043b\u043e \u0437\u0434\u0435\u0441\u044c \u043f\u0440\u043e\u043c\u043e\u043a\u043e\u0434 \u0434\u043b\u044f \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u0435\u0439 \u043d\u0430\u0448\u0435\u0433\u043e \u0431\u043b\u043e\u0433\u0430:<br \/><a href=\"https:\/\/firstvds.ru\/?utm%5C%5C_source=habr&amp;utm%5C%5C_medium=article&amp;utm%5C%5C_campaign=product&amp;utm%5C%5C_content=vds15exeptprogrev\">-15% \u043d\u0430 \u0437\u0430\u043a\u0430\u0437 \u043d\u043e\u0432\u043e\u0433\u043e VDS<\/a>\u00a0\u2014\u00a0<strong>HABRFIRSTVDS<\/strong>.<\/p>\n<p><a href=\"https:\/\/firstvds.ru\/habr15\">\u041f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043e\u0431 \u0430\u043a\u0446\u0438\u0438<\/a><\/p>\n<\/div>\n<p>\u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/1082284\/\">https:\/\/habr.com\/ru\/articles\/1082284\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u0417\u0430\u043a\u0430\u0437 \u0432 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442-\u043c\u0430\u0433\u0430\u0437\u0438\u043d\u0435 \u0440\u0435\u0434\u043a\u043e \u0436\u0438\u0432\u0451\u0442 \u043f\u043e \u0438\u0434\u0435\u0430\u043b\u044c\u043d\u043e\u0439 \u0441\u0445\u0435\u043c\u0435 \u00ab\u0441\u043e\u0437\u0434\u0430\u043d \u2192 \u043e\u043f\u043b\u0430\u0447\u0435\u043d \u2192 \u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u00bb. \u0412 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0436\u0438\u0437\u043d\u0435\u043d\u043d\u044b\u0439 \u0446\u0438\u043a\u043b \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u043d\u0435\u043b\u0438\u043d\u0435\u0439\u043d\u044b\u0439: \u043a\u043b\u0438\u0435\u043d\u0442 \u043e\u0444\u043e\u0440\u043c\u043b\u044f\u0435\u0442 \u0437\u0430\u043a\u0430\u0437, \u043d\u043e \u043c\u043e\u0436\u0435\u0442 \u043f\u0435\u0440\u0435\u0434\u0443\u043c\u0430\u0442\u044c \u0438 \u043e\u0442\u043c\u0435\u043d\u0438\u0442\u044c \u0435\u0433\u043e; \u0442\u043e\u0432\u0430\u0440 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442 \u0441 \u0431\u0440\u0430\u043a\u043e\u043c \u0438 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0442; \u0447\u0430\u0441\u0442\u044c \u043f\u043e\u0437\u0438\u0446\u0438\u0439 \u043d\u0435 \u0443\u0441\u043f\u0435\u043b\u0430 \u043f\u0440\u0438\u0439\u0442\u0438 \u0438 \u043d\u0443\u0436\u043d\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0438\u0445 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e. \u041f\u043e\u043f\u044b\u0442\u043a\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u0430\u043a\u0438\u0435 \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0435 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0438, \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043f\u0440\u0430\u0432 \u0438 \u0441\u043e\u043f\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u00ab\u0432 \u043b\u043e\u0431\u00bb \u0431\u044b\u0441\u0442\u0440\u043e \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0443 \u0432 \u0445\u0430\u043e\u0441 \u0438\u0437 \u0440\u0430\u0437\u0440\u043e\u0437\u043d\u0435\u043d\u043d\u044b\u0445 if\/else, \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a \u0441\u0442\u0430\u0442\u0443\u0441\u043e\u0432 \u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u043f\u043e \u0432\u0441\u0435\u043c\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0443.\u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u0440\u0430\u0437\u0431\u0435\u0440\u0451\u043c, \u043a\u0430\u043a \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 Symfony Workflow \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0441\u043b\u043e\u0436\u043d\u044b\u0435 \u0431\u0438\u0437\u043d\u0435\u0441-\u043f\u0440\u043e\u0446\u0435\u0441\u0441\u044b \u0432 \u0432\u0438\u0434\u0435 \u044f\u0432\u043d\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439 \u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043e\u0432. \u041d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a \u0437\u0430\u0434\u0430\u0432\u0430\u0442\u044c \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0435 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u044b, \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u0431\u0438\u0437\u043d\u0435\u0441-\u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438, \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0438 \u043e\u0442\u0434\u0435\u043b\u044f\u0442\u044c \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430 \u043e\u0442 \u043a\u043e\u0434\u0430, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0449\u0435\u0433\u043e \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f. \u0412 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u0442\u0430\u0442\u0443\u0441\u0430\u043c\u0438, \u0430 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u0435\u043b\u0430\u0435\u0442 \u0441\u043b\u043e\u0436\u043d\u0443\u044e \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0443 \u043f\u043e\u043d\u044f\u0442\u043d\u043e\u0439, \u043f\u0440\u0435\u0434\u0441\u043a\u0430\u0437\u0443\u0435\u043c\u043e\u0439 \u0438 \u0443\u0434\u043e\u0431\u043d\u043e\u0439 \u0434\u043b\u044f \u0441\u043e\u043f\u0440\u043e\u0432\u043e\u0436\u0434\u0435\u043d\u0438\u044f.\u041f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043f\u0440\u0438\u043c\u0435\u0440: \u0421\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u0434\u043b\u044f \u0441\u0442\u0430\u0442\u044c\u0438 \u043c\u044b \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u043b\u0438 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u043d\u0430 GitHub \u2014 symfony_workflow_lesson, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u043d\u043e \u0441\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u0440\u0430\u0437\u0431\u043e\u0440\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u043a\u043e\u0434\u0430.\u041f\u043e\u043b\u044c\u0437\u0443\u044f\u0441\u044c \u0441\u043b\u0443\u0447\u0430\u0435\u043c, \u043a\u043e\u043c\u0430\u043d\u0434\u0430 FirstVDS \u0433\u043e\u0440\u044f\u0447\u043e \u043f\u043e\u0437\u0434\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0441 \u043f\u0440\u043e\u0448\u0435\u0434\u0448\u0438\u043c \u0414\u043d\u0451\u043c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442\u0430 \u0432\u0441\u0435\u0445 IT-\u0433\u0435\u0440\u043e\u0435\u0432! \u0412 \u0447\u0435\u0441\u0442\u044c \u044d\u0442\u043e\u0433\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0434\u0430\u0440\u0438\u043c \u043f\u0440\u043e\u043c\u043e\u043a\u043e\u0434 \u0441\u043e\u00a0\u0441\u043a\u0438\u0434\u043a\u043e\u0439 25%\u00a0\u043d\u0430 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0439 \u043f\u0435\u0440\u0438\u043e\u0434 \u0437\u0430\u043a\u0430\u0437\u0430 (1, 3, 6, 12 \u043c\u0435\u0441\u044f\u0446\u0435\u0432) \u043d\u043e\u0432\u044b\u0445 VDS \u0432 \u0420\u043e\u0441\u0441\u0438\u0438, \u041d\u0438\u0434\u0435\u0440\u043b\u0430\u043d\u0434\u0430\u0445 \u0438\u043b\u0438 \u041a\u0430\u0437\u0430\u0445\u0441\u0442\u0430\u043d\u0435. \u0423\u0441\u043f\u0435\u0439\u0442\u0435 \u0430\u043a\u0442\u0438\u0432\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u043a\u0438\u0434\u043a\u0443! \u041a\u0430\u043a\u0443\u044e \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 \u0440\u0435\u0448\u0430\u0435\u0442 Workflow\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0443\u043f\u0440\u043e\u0449\u0451\u043d\u043d\u0443\u044e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0441\u043c\u0435\u043d\u044b \u0441\u0442\u0430\u0442\u0443\u0441\u0430 \u0437\u0430\u043a\u0430\u0437\u0430 \u0431\u0435\u0437 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432:public function pay(Order $order): void{    if ($order-&gt;getStatus() !== OrderStatus::PendingPayment) {        throw new \\DomainException(&#8216;Order is not awaiting payment&#8217;);    }    $order-&gt;setStatus(OrderStatus::Paid);}\u041d\u0430 \u043f\u0435\u0440\u0432\u044b\u0439 \u0432\u0437\u0433\u043b\u044f\u0434 \u0432\u0441\u0451 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e: \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0438 \u043c\u0435\u043d\u044f\u0435\u043c \u0435\u0433\u043e \u043d\u0430 \u043d\u043e\u0432\u043e\u0435. \u041e\u0434\u043d\u0430\u043a\u043e \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u0436\u0438\u0437\u043d\u0435\u043d\u043d\u044b\u0439 \u0446\u0438\u043a\u043b \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0440\u0435\u0434\u043a\u043e \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0434\u0432\u0443\u043c\u044f-\u0442\u0440\u0435\u043c\u044f \u0441\u0442\u0430\u0442\u0443\u0441\u0430\u043c\u0438. \u041f\u043e\u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043e\u0442\u043c\u0435\u043d\u0430 \u0437\u0430\u043a\u0430\u0437\u0430, \u0432\u043e\u0437\u0432\u0440\u0430\u0442 \u0441\u0440\u0435\u0434\u0441\u0442\u0432, \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u0430\u044f \u043e\u043f\u043b\u0430\u0442\u0430, \u0447\u0430\u0441\u0442\u0438\u0447\u043d\u0430\u044f \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0430, \u0440\u0430\u0437\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u0440\u043e\u043b\u0435\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0441\u043e\u043f\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043f\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u043c \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0435: \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0439, \u0440\u0435\u0437\u0435\u0440\u0432\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438\u043b\u0438 \u0441\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0442\u043e\u0432\u0430\u0440\u0430, \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u044f \u0441\u043e\u0431\u044b\u0442\u0438\u0439, \u0437\u0430\u043f\u0438\u0441\u044c \u0432 \u0436\u0443\u0440\u043d\u0430\u043b \u0430\u0443\u0434\u0438\u0442\u0430.\u0412 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u043a\u0430\u0436\u0434\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u043e\u0431\u0440\u0430\u0441\u0442\u0430\u0442\u044c \u0434\u0443\u0431\u043b\u0438\u0440\u0443\u044e\u0449\u0438\u043c\u0438\u0441\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430\u043c\u0438 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f, \u0443\u0441\u043b\u043e\u0432\u0438\u0439 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u0438 \u043f\u0440\u0430\u0432 \u0434\u043e\u0441\u0442\u0443\u043f\u0430. \u0421\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0435\u043c \u0431\u0438\u0437\u043d\u0435\u0441-\u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u043e\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u044b \u043f\u043e \u0434\u0435\u0441\u044f\u0442\u043a\u0430\u043c \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432, \u0430 \u043f\u043e\u043d\u044f\u0442\u044c, \u043a\u0430\u043a\u0438\u0435 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u044b \u0432\u043e\u043e\u0431\u0449\u0435 \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b, \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u0432\u0441\u0451 \u0441\u043b\u043e\u0436\u043d\u0435\u0435. \u041b\u044e\u0431\u043e\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u043f\u043e\u0438\u0441\u043a\u0430 \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0439 \u043b\u043e\u0433\u0438\u043a\u0438 \u043f\u043e \u0432\u0441\u0435\u043c\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0443, \u0438\u0437-\u0437\u0430 \u0447\u0435\u0433\u043e \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u043e\u0441\u0442\u044c \u043e\u0448\u0438\u0431\u043a\u0438 \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u0440\u0430\u0441\u0442\u0451\u0442. \u0418\u043c\u0435\u043d\u043d\u043e \u044d\u0442\u0443 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 \u0440\u0435\u0448\u0430\u0435\u0442 Symfony Workflow. \u041a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0432\u044b\u043d\u0435\u0441\u0442\u0438 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043e\u0432 \u0432 \u0435\u0434\u0438\u043d\u043e\u0435 \u0446\u0435\u043d\u0442\u0440\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435, \u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044e \u043e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u043b\u0438\u0448\u044c \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043d\u0430 \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0435\u0433\u043e:\u0411\u0435\u0437 Workflow\u00a0\u0421 Workflow\u041f\u0440\u0430\u0432\u0438\u043b\u0430 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043e\u0432 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u044b \u043f\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u043c \u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430\u043c\u00a0\u0412\u0441\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u044b \u043e\u043f\u0438\u0441\u0430\u043d\u044b \u0432 \u043e\u0434\u043d\u043e\u043c \u043c\u0435\u0441\u0442\u0435\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043f\u0438\u0441\u0430\u0442\u044c \u0432\u0440\u0443\u0447\u043d\u0443\u044e\u041d\u0435\u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0435 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u044b \u0431\u043b\u043e\u043a\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u041b\u0435\u0433\u043a\u043e \u0437\u0430\u0431\u044b\u0442\u044c \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u0432 \u043d\u043e\u0432\u043e\u043c \u043a\u043e\u0434\u0435\u0412\u0441\u0435 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u044b \u043f\u0440\u043e\u0445\u043e\u0434\u044f\u0442 \u0447\u0435\u0440\u0435\u0437 \u0435\u0434\u0438\u043d\u044b\u0439 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u0421\u043b\u043e\u0436\u043d\u043e \u043f\u043e\u043d\u044f\u0442\u044c \u0436\u0438\u0437\u043d\u0435\u043d\u043d\u044b\u0439 \u0446\u0438\u043a\u043b \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u00a0\u041f\u0440\u043e\u0446\u0435\u0441\u0441 \u043c\u043e\u0436\u043d\u043e \u0432\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432 \u0432\u0438\u0434\u0435 \u0441\u0445\u0435\u043c\u044b\u0411\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0430 \u0441\u043c\u0435\u0448\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0441 \u043f\u0440\u0438\u043a\u043b\u0430\u0434\u043d\u044b\u043c \u043a\u043e\u0434\u043e\u043c\u041f\u0440\u0430\u0432\u0438\u043b\u0430 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430 \u043e\u0442\u0434\u0435\u043b\u0435\u043d\u044b \u043e\u0442 \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0412 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 Workflow \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u043c \u0441\u043c\u0435\u043d\u044b \u0441\u0442\u0430\u0442\u0443\u0441\u043e\u0432, \u0430 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u043e\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u0443\u0435\u0442 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0441\u0442\u044c \u0436\u0438\u0437\u043d\u0435\u043d\u043d\u043e\u0433\u043e \u0446\u0438\u043a\u043b\u0430 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0438 \u0434\u0435\u043b\u0430\u0435\u0442 \u0431\u0438\u0437\u043d\u0435\u0441-\u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u044f\u0432\u043d\u044b\u043c \u043a\u0430\u043a \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432, \u0442\u0430\u043a \u0438 \u0434\u043b\u044f \u0441\u0430\u043c\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b.\u0427\u0442\u043e \u0442\u0430\u043a\u043e\u0435 Symfony Workflow, \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043f\u043e\u043d\u044f\u0442\u0438\u044f\u041f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u0442\u044c \u043a \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430, \u0440\u0430\u0437\u0431\u0435\u0440\u0451\u043c\u0441\u044f \u0441 \u0435\u0433\u043e \u0442\u0435\u0440\u043c\u0438\u043d\u043e\u043b\u043e\u0433\u0438\u0435\u0439. \u0412\u0441\u0435 \u043f\u043e\u043d\u044f\u0442\u0438\u044f \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u043f\u0440\u0438\u0432\u044b\u0447\u043d\u044b\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u043c \u0431\u0438\u0437\u043d\u0435\u0441-\u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430:Place (\u043c\u0435\u0441\u0442\u043e\/\u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435) \u2014 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043e\u0431\u044a\u0435\u043a\u0442. \u0412 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0435\u043c\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0437\u0430\u043a\u0430\u0437\u0430 \u0442\u0430\u043a\u0438\u043c\u0438 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f\u043c\u0438 \u0432\u044b\u0441\u0442\u0443\u043f\u0430\u044e\u0442 new, pending_payment, paid \u0438 \u0442. \u0434. \u0412 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432 \u043e\u043d\u0438 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0432 \u0432\u0438\u0434\u0435 Enum \u0438\u043b\u0438 \u0441\u0442\u0440\u043e\u043a\u043e\u0432\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0432 \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445.Transition (\u043f\u0435\u0440\u0435\u0445\u043e\u0434) \u2014 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435, \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u044f\u0449\u0435\u0435 \u043e\u0431\u044a\u0435\u043a\u0442 \u0438\u0437 \u043e\u0434\u043d\u043e\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0432 \u0434\u0440\u0443\u0433\u043e\u0435 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, submit \u2014 \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u0438\u0437 new \u0432 pending_payment). \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435: \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u0438\u043c\u0435\u0435\u0442 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435 \u0438\u043c\u044f. \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435 \u0433\u043e\u0432\u043e\u0440\u044f\u0442 \u043d\u0435 \u00ab\u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0441\u0442\u0430\u0442\u0443\u0441 \u043d\u0430 paid\u00bb, \u0430 \u00ab\u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043f\u0435\u0440\u0435\u0445\u043e\u0434 pay\u00bb. \u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u044d\u0442\u043e\u043c\u0443 \u043a\u043e\u0434 \u043e\u0442\u0440\u0430\u0436\u0430\u0435\u0442 \u0431\u0438\u0437\u043d\u0435\u0441-\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f, \u0430 \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u0435\u0442 \u043d\u043e\u0432\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u044e.Marking (\u043c\u0435\u0442\u043a\u0430) \u2014 \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 (\u0438\u043b\u0438 \u043d\u0430\u0431\u043e\u0440 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439). \u0412 \u0441\u043b\u0443\u0447\u0430\u0435 state_machine \u043c\u0435\u0442\u043a\u0430 \u0440\u043e\u0432\u043d\u043e \u043e\u0434\u043d\u0430 \u0438 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0442\u0435\u043a\u0443\u0449\u0435\u043c\u0443 \u0441\u0442\u0430\u0442\u0443\u0441\u0443 \u0437\u0430\u043a\u0430\u0437\u0430.\u041e\u0431\u044b\u0447\u043d\u043e \u043c\u0435\u0442\u043a\u0430 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0432 \u043e\u0434\u043d\u043e\u043c \u0438\u0437 \u043f\u043e\u043b\u0435\u0439 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438:class Order {    private string $status = &#8216;new&#8217;;}\u0418\u043c\u0435\u043d\u043d\u043e \u044d\u0442\u043e \u043f\u043e\u043b\u0435 Symfony Workflow \u0431\u0443\u0434\u0435\u0442 \u0447\u0438\u0442\u0430\u0442\u044c \u0438 \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u043f\u0440\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043e\u0432.Workflow vs State MachineSymfony \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0434\u0432\u0430 \u0440\u0435\u0436\u0438\u043c\u0430 \u0440\u0430\u0431\u043e\u0442\u044b: Workflow \u0438 State Machine. \u0413\u043b\u0430\u0432\u043d\u043e\u0435 \u0440\u0430\u0437\u043b\u0438\u0447\u0438\u0435 \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0435 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0445 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439:State Machine \u0434\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u043d\u043e \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0432 \u043a\u0430\u0436\u0434\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0432\u0440\u0435\u043c\u0435\u043d\u0438. \u0414\u043b\u044f \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0430 \u0431\u0438\u0437\u043d\u0435\u0441-\u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439 \u2014 \u0437\u0430\u043a\u0430\u0437\u0430, \u0441\u0447\u0451\u0442\u0430, \u0437\u0430\u044f\u0432\u043a\u0438, \u0434\u043e\u0433\u043e\u0432\u043e\u0440\u0430 \u2014 \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442 \u0438\u043c\u0435\u043d\u043d\u043e \u044d\u0442\u043e\u0442 \u0440\u0435\u0436\u0438\u043c. \u0417\u0430\u043a\u0430\u0437 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u0431\u044b\u0442\u044c \u00ab\u043e\u043f\u043b\u0430\u0447\u0435\u043d\u00bb \u0438 \u00ab\u043e\u0442\u043c\u0435\u043d\u0451\u043d\u00bb.Workflow \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043e\u0431\u044a\u0435\u043a\u0442\u0443 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u0441\u0440\u0430\u0437\u0443 \u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f\u0445. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442 \u043c\u043e\u0436\u0435\u0442 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u043d\u0430 \u0441\u043e\u0433\u043b\u0430\u0441\u043e\u0432\u0430\u043d\u0438\u0438 \u0443 \u044e\u0440\u0438\u0434\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u043e\u0442\u0434\u0435\u043b\u0430, \u043d\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0435 \u0441\u043b\u0443\u0436\u0431\u044b \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u0438 \u0438 \u043d\u0430 \u0443\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0438 \u0443 \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044f.\u0414\u0430\u043b\u0435\u0435 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c State Machine, \u0442\u0430\u043a \u043a\u0430\u043a \u044d\u0442\u043e\u0442 \u0440\u0435\u0436\u0438\u043c \u0438\u0434\u0435\u0430\u043b\u044c\u043d\u043e \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u043c\u0443 \u0436\u0438\u0437\u043d\u0435\u043d\u043d\u043e\u043c\u0443 \u0446\u0438\u043a\u043b\u0443 \u0437\u0430\u043a\u0430\u0437\u0430 \u0438 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0451\u043d\u043d\u044b\u043c \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0435\u043c.\u041e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435\u0414\u043b\u044f \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u0438\u0437 \u0441\u0442\u0430\u0442\u044c\u0438 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u044c\u0442\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435. \u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043a\u043b\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0433\u043e\u0442\u043e\u0432\u044b\u0439 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u0441 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u043c \u0438\u043b\u0438 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 Symfony \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0439 \u0441\u0442\u0435\u043a:PHP 8.3+ (\u0438\u043b\u0438 PHP 8.5)Nginx \/ Web-\u0441\u0435\u0440\u0432\u0435\u0440PostgreSQLDocker Compose\u041f\u043e\u0441\u043b\u0435 \u043a\u043b\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b:docker compose up -d\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 Symfony Workflow \u0438 Doctrine ORM:docker compose exec php composer require symfony\/workflow doctrine\u041f\u043e\u0441\u043b\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 Flex \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0441\u043e\u0437\u0434\u0430\u0441\u0442 \u0431\u0430\u0437\u043e\u0432\u0443\u044e \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445.\u041c\u043e\u0434\u0435\u043b\u044c \u0434\u0430\u043d\u043d\u044b\u0445: \u0437\u0430\u043a\u0430\u0437 \u0438 \u0441\u0442\u0430\u0442\u0443\u0441\u044b\u0414\u043b\u044f \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0440\u0430\u0431\u043e\u0442\u044b Workflow \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0443\u043f\u0440\u043e\u0449\u0451\u043d\u043d\u0443\u044e \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c \u0437\u0430\u043a\u0430\u0437\u0430. \u041d\u0430\u0441 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u0435\u0442 \u0436\u0438\u0437\u043d\u0435\u043d\u043d\u044b\u0439 \u0446\u0438\u043a\u043b \u043e\u0431\u044a\u0435\u043a\u0442\u0430, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0441\u043e\u0441\u0440\u0435\u0434\u043e\u0442\u043e\u0447\u0438\u043c\u0441\u044f \u043d\u0430 \u043f\u043e\u043b\u0435 $status. \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c Enum \u0441\u0442\u0430\u0442\u0443\u0441\u043e\u0432:\/\/ src\/Enum\/OrderStatus.phpenum OrderStatus: string{    case New = &#8216;new&#8217;;    case PendingPayment = &#8216;pending_payment&#8217;;    case Paid = &#8216;paid&#8217;;    case Processing = &#8216;processing&#8217;;    case Shipped = &#8216;shipped&#8217;;    case Delivered = &#8216;delivered&#8217;;    case Cancelled = &#8216;cancelled&#8217;;    case Refunded = &#8216;refunded&#8217;;}\u0412\u0430\u0436\u043d\u043e: \u0421\u0442\u0440\u043e\u043a\u043e\u0432\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f Enum (new, pending_payment, paid \u0438 \u0442. \u0434.) \u0434\u043e\u043b\u0436\u043d\u044b \u0441\u0442\u0440\u043e\u0433\u043e \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u0442\u044c \u0441 \u0438\u043c\u0435\u043d\u0430\u043c\u0438 places, \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u043c\u0438 \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 Workflow.\u0421\u0443\u0449\u043d\u043e\u0441\u0442\u044c Order\u0422\u0435\u043f\u0435\u0440\u044c \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0441\u0430\u043c\u0443 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c:\/\/ src\/Entity\/Order.phpnamespace App\\Entity;use App\\Enum\\OrderStatus;use Doctrine\\ORM\\Mapping as ORM;#[ORM\\Entity]#[ORM\\Table(name: &#8216;orders&#8217;)]class Order{    #[ORM\\Id]    #[ORM\\GeneratedValue]    #[ORM\\Column(type: &#8216;integer&#8217;)]    private ?int $id = null;    #[ORM\\Column(enumType: OrderStatus::class)]    private OrderStatus $status = OrderStatus::New;    public function getId(): ?int    {        return $this-&gt;id;    }    public function getStatus(): OrderStatus    {        return $this-&gt;status;    }    public function setStatus(OrderStatus $status): static    {        $this-&gt;status = $status;        return $this;    }}Symfony Workflow \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f \u043e\u0442 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0445 \u0431\u0430\u0437\u043e\u0432\u044b\u0445 \u043a\u043b\u0430\u0441\u0441\u043e\u0432, \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0442\u0440\u0435\u0439\u0442\u043e\u0432 \u0438\u043b\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u0445 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u043e\u0432. \u0414\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e, \u0445\u0440\u0430\u043d\u044f\u0449\u0435\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 (marking_store.property), \u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0431\u0443\u0434\u0435\u0442 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0447\u0438\u0442\u0430\u0442\u044c \u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \u0435\u0433\u043e \u0447\u0435\u0440\u0435\u0437 getter \u0438 setter (getStatus() \/ setStatus()).\u041a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f Workflow\u0422\u0435\u043f\u0435\u0440\u044c \u043e\u043f\u0438\u0448\u0435\u043c \u0436\u0438\u0437\u043d\u0435\u043d\u043d\u044b\u0439 \u0446\u0438\u043a\u043b \u0437\u0430\u043a\u0430\u0437\u0430 \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 Symfony Workflow. \u0412\u0441\u0435 \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u044b \u0431\u0443\u0434\u0443\u0442 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u0432 config\/packages\/workflow.yaml:framework:    workflows:        order:            type: state_machine            audit_trail:                enabled: true            marking_store:                type: method                property: status            supports:                &#8212; App\\Entity\\Order            initial_marking: new            places:                &#8212; new                &#8212; pending_payment                &#8212; paid                &#8212; processing                &#8212; shipped                &#8212; delivered                &#8212; cancelled                &#8212; refunded            transitions:                submit:                    from: new                    to: pending_payment                pay:                    from: pending_payment                    to: paid                process:                    from: paid                    to: processing                ship:                    from: processing                    to: shipped                deliver:                    from: shipped                    to: delivered                cancel:                    from: [new, pending_payment, paid, processing]                    to: cancelled                refund:                    from: [paid, processing, shipped, delivered]                    to: refunded\u041a\u043b\u044e\u0447\u0435\u0432\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b\u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u041d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435type: state_machine\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0440\u0435\u0436\u0438\u043c, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u043d\u043e \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435marking_store.property: status\u0423\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 (status), \u0445\u0440\u0430\u043d\u044f\u0449\u0435\u0435 \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435supports\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u043a\u043b\u0430\u0441\u0441\u044b \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0439 Workflowinitial_marking: new\u041d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438places\u041f\u043e\u043b\u043d\u044b\u0439 \u0441\u043f\u0438\u0441\u043e\u043a \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0445 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439transitions\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0440\u0430\u0437\u0440\u0435\u0448\u0451\u043d\u043d\u044b\u0445 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043e\u0432 \u043c\u0435\u0436\u0434\u0443 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f\u043c\u0438audit_trail.enabled: true\u0412\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 Workflow (\u0443\u0434\u043e\u0431\u043d\u043e \u043f\u0440\u0438 \u043e\u0442\u043b\u0430\u0434\u043a\u0435)\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043e\u0432:cancel:     from: [new, pending_payment, paid, processing]    to: cancelled\u041e\u0442\u043c\u0435\u043d\u0438\u0442\u044c \u0437\u0430\u043a\u0430\u0437 \u043c\u043e\u0436\u043d\u043e \u0438\u0437 \u0447\u0435\u0442\u044b\u0440\u0451\u0445 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439, \u043d\u043e \u0438\u0442\u043e\u0433\u043e\u0432\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432\u0441\u0435\u0433\u0434\u0430 \u043e\u0434\u0438\u043d \u2014 cancelled. \u0415\u0441\u043b\u0438 \u043f\u043e\u043f\u044b\u0442\u0430\u0442\u044c\u0441\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c cancel \u0434\u043b\u044f \u0437\u0430\u043a\u0430\u0437\u0430 \u0432 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0438 shipped, Workflow \u043d\u0435 \u043d\u0430\u0439\u0434\u0451\u0442 \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0435\u0433\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0438&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-494689","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/494689","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=494689"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/494689\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=494689"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=494689"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=494689"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}