用工作流做决定

用工作流做决定

拥有模型的状态是很常见的。评论状态仅由垃圾邮件检查器决定。如果我们加入更多的决定因素呢?

我们可能想让网站管理员在垃圾邮件检查器之后调节所有的评论。这个过程大致如下:

  • 从一个提交当评论是由用户提交时声明;
  • 让垃圾邮件检查器分析评论并将状态切换到任何一种状态potential_spam火腿,或拒绝了
  • 如果没有被拒绝,等待网站管理员通过切换到状态来决定评论是否足够好发表拒绝了

实现这个逻辑并不太复杂,但是您可以想象,添加更多的规则将大大增加复杂性。我们可以使用Symfony工作流组件,而不是自己编写逻辑代码:ob娱乐下载

1
ob娱乐下载Symfony作曲家要求工作流

描述工作流

注释工作流可以在配置/包/ workflow.yaml文件:

配置/包/ workflow.yaml
12 34 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
框架:工作流程:备注:类型:state_machineaudit_trail:启用:“% kernel.debug %”marking_store:类型:“方法”属性:“状态”支持:-应用实体\ \发表评论initial_marking:提交地方:-提交-火腿-potential_spam-垃圾邮件-拒绝了-发表转换:接受:来自:提交:火腿might_be_spam:来自:提交:potential_spamreject_spam:来自:提交:垃圾邮件发布:来自:potential_spam:发表拒绝:来自:potential_spam:拒绝了publish_ham:来自:火腿:发表reject_ham:来自:火腿:拒绝了

为了验证工作流,生成一个可视化表示:

1
ob娱乐下载symfony控制台工作流:dump comment | dot - tng -o workflow.png

请注意

命令的一部分Graphviz实用程序。

使用工作流

用工作流替换消息处理程序中的当前逻辑:

12 34 56 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
——MessageHandler / src / / CommentMessageHandler.php+ + + MessageHandler b / src / / CommentMessageHandler.php@@ -6,19 +6,28 @@使用App\Message\CommentMessage;使用App \ Repository \ CommentRepository;使用App \ SpamChecker;使用原则\ ORM \ EntityManagerInterface;+使用Psr \ Log \ LoggerInterface;使用Syob娱乐下载mfony \信使\ \组件处理程序\ MessageHandlerInterface;+使用Syob娱乐下载mfony \组件\ \ MessageBusInterface使者;+使用Syob娱乐下载mfony \工作流组件\ \ WorkflowInterface;类CommentMessageHandler实现MessageHandlerInterface {private $spamChecker;私人entityManager美元;私人commentRepository美元;+私人$bus;+私人$工作流;+ private $logger;-公共函数__construct(EntityManagerInterface $entityManager, SpamChecker $ SpamChecker, CommentRepository $ CommentRepository)+公共函数__construct(EntityManagerInterface $entityManager, SpamChecker $ SpamChecker, CommentRepository $ CommentRepository, MessageBusInterface $bus, WorkflowInterface $commentStateMachine, LoggerInterface $logger = null){$this->entityManager = $entityManager;$this->spamChecker = $spamChecker;$this->commentRepository = $commentRepository;+ $this->总线= $总线;+ $this->工作流= $commentStateMachine;+ $this->记录器= $记录器;}公共函数__invoke(CommentMessage $message) @@ -28,12 +37,21类CommentMessageHandler实现MessageHandlerInterface返回;}- if (2 === $this->spamChecker->getSpamScore($comment, $message->getContext())) {——评论- >设置状态(“垃圾邮件”);-}其他{——评论- >设置状态(“发表”);- - - - - -}- $ this - > entityManager - >冲洗();+ if ($this->工作流->can($comment, 'accept')) {+ $score = $this->spamChecker->getSpamScore($comment, $message->getContext());+ $transition = 'accept';+ if (2 === $score) {+ $transition = 'reject_spam';+} elseif (1 === $score) {+ $transition = 'might_be_spam';+}+ $this->工作流->应用($注释,$过渡);+ $ this - > entityManager - >冲洗();++ $ this - >总线- >调度($消息);+} elseif ($this->记录器){+ $this->logger->debug('删除评论消息',['comment' => $comment->getId(), 'state' => $comment->getState()]);+}}}

新的逻辑如下:

  • 如果接受过渡是可用的评论在消息,检查垃圾邮件;
  • 根据结果,选择正确的过渡应用;
  • 调用应用()的调用来更新注释设置状态()方法;
  • 调用冲洗()将更改提交到数据库;
  • 重新分派消息以允许工作流再次转换。

由于我们还没有实现管理验证,所以下次使用消息时,将记录“删除评论消息”。

让我们实现一个自动验证,直到下一章:

12 3 4 5 6 7 8 9 10 11 12
——MessageHandler / src / / CommentMessageHandler.php+ + + MessageHandler b / src / / CommentMessageHandler.php@@ -50,6 +50,9 @@类CommentMessageHandler实现MessageHandlerInterface $this->entityManager->flush();$ this - >总线- >调度($消息);+} elseif ($this->workflow->can($comment, 'publish') || $this->workflow->can($comment, 'publish_ham')) {+ $this->工作流->应用($comment, $this->工作流->可以($comment, '发布')?'publish': 'publish_ham');+ $ this - > entityManager - >冲洗();} elseif ($this->logger) {$this->logger->debug('删除评论消息',['comment' => $comment->getId(), 'state' => $comment->getState()]);}

运行ob娱乐下载symfony服务器:日志并在前端添加一个注释,以查看所有转换一个接一个地发生。

从依赖注入容器中查找服务

当使用依赖注入时,我们通过类型从依赖注入容器中获取服务,类型暗示接口,有时是具体的实现类名。但是当一个接口有多个实现时,Symfony无法猜测您需要哪个实现。ob娱乐下载我们需要一种明确的方式。

我们刚刚遇到了一个注入a的例子WorkflowInterface在前一节中。

当注入泛型的任何实例时WorkflowInterface接口在构造函数中,Symfony怎么能猜到使用哪个工作流实现呢?ob娱乐下载ob娱乐下载Symfony使用了一个基于参数名的约定:commentStateMachine美元评论配置中的工作流(哪种类型是state_machine).尝试任何其他参数名称,它将失败。

如果您不记得约定,请使用调试:容器命令。搜索所有包含“workflow”的服务:

12 3 4 5 6 7 8 9 10 11 12 13 14
ob娱乐下载symfony console debug:container workflow选择以下服务之一显示其信息:[0]console.command.workflow_dump [1] workflow。摘要[2]工作流。marking_store。方法[3]工作流。注册表[4]workflow.security。Expression_language[5]工作流。[7] Symfony\Component\Workflow\Registry [8] Symob娱乐下载fony\Component\Workflow\WorkflowInterfacecommentStateMachine[9] Psr \ \ LoggerInterface日志workflowLogger>

注意选择8ob娱乐下载Symfony \工作流组件\ \ WorkflowInterface commentStateMachine美元是谁告诉你使用的commentStateMachine美元作为参数,名称有特殊的含义。

请注意

我们可以用调试:自动装配命令,如前一章所示:

1
ob娱乐下载Symfony控制台调试:自动装配工作流
此工作,包括代码示例,是根据知识共享协议BY-NC-SA 4.0许可证。