步骤19:根据工作流程做出决定

5.2版本
维护 没有维护的
5.0

根据工作流程做出决策

为模型拥有一个状态是很常见的。注释状态仅由垃圾邮件检查器确定。如果我们增加更多的决策因素呢?

我们可能想让网站管理员在垃圾邮件检查后调整所有评论。这个过程应该是这样的:

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

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

1
$ ob娱乐下载symfony composer请求工作流

描述工作流

注释工作流可以在配置/包/ 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控制台工作流:转储注释|工作流程。png
. . / _images / workflow.png

请注意

命令是Graphviz实用程序。

使用一个工作流

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

patch_file
1 2 3 4 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 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美元;美元+私人公交;+私人美元工作流;+私人美元记录器;-公共函数__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->bus = $bus;+ $this->工作流= $commentStateMachine;+ $this->logger = $logger;} public function __invoke(CommentMessage $message)@@类CommentMessageHandler实现了messagehandler接口返回;}- if (2 === $this->spamChecker->getSpamScore($comment, $message->getContext()))){/ /获取消息——评论- >设置状态(“垃圾邮件”);-} else {——评论- >设置状态(“发表”);- - - - - -}- $ this - > entityManager - >冲洗();+ if ($this->workflow->can($comment, 'accept')){/ /处理流程$this- comment = $this- comment = $this- comment = $this- comment = $this- comment = $this- comment = $this- comment = $this- comment = $this- comment = $this- comment = $this- comment = $this+ $transition = '接受';+ if (2 === $score) {+ $transition = 'reject_spam';+} elseif (1 === $score) {+ $transition = 'might_be_spam';+}+ $ this - >工作流- >应用(评论,美元过渡);+ $ this - > entityManager - >冲洗();++ $ this - >总线- >调度($消息);+} elseif ($this->logger) {+ $this->logger->debug(' drop comment message', ['comment' => $comment->getId(), 'state' => $comment->getState()]);+}}}

新的逻辑如下:

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

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

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

patch_file
12 3 4 5 6 7 8 9 10 11 12
——MessageHandler / src / / CommentMessageHandler.php+ + + MessageHandler b / src / / CommentMessageHandler.php@@类CommentMessageHandler实现MessageHandlerInterface$ this - > entityManager >冲洗();$ this - >总线- >调度($消息);+} elseif ($this->workflow->can($comment, 'publish_ham')) {$this->workflow->can($comment, 'publish_ham')) {+ $this->workflow->apply($comment, $this->workflow->) ?“发布”:“publish_ham”);+ $ this - > entityManager - >冲洗();} else ($this->logger) {$this->logger->debug(' drop comment message', ['comment' => $comment->getId(), 'state' => $comment->getState()]);}

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

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

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

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

当我们注入泛型的任何实例时WorkflowInterface接口在构造器中,Symfony如何猜测使用哪个工作流实现?ob娱乐下载ob娱乐下载Symfony使用了一个基于参数名的约定:commentStateMachine美元指的是评论配置中的工作流(类型是state_machine)。尝试任何其他参数名称都会失败。

如果你不记得惯例,用调试:容器命令。搜索所有包含“工作流”的服务:

12 3 4 5 6 7 8 9 10 11 12 13 14
选择ob娱乐下载以下服务之一来显示它的信息:(0]console.command.workflow_dump(1]workflow.abstract(2]workflow.marking_store.method(3.]workflow.registry(4]workflow.security.expression_language(5]workflow.twig_extension(6]monolog.logger.workflow(7]ob娱乐下载\ Component\ WorkflowR \egistry(8]ob娱乐下载\ Component\ Workflow\ WorkflowInterfacecommentStateMachine美元(9]PsrL \L \oggerInterfaceworkflowLogger美元>

注意选择8,ob娱乐下载Symfony \组件\ \ WorkflowInterface工作流commentStateMachine美元这说明了使用commentStateMachine美元作为参数名有特殊的含义。

请注意

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

1
$ ob娱乐下载symfony控制台调试:自动装配工作流

该工作,包括代码示例,根据anc - sa知识共享4.0许可证。