Passed
Push — master ( cdf522...20c244 )
by Joachim
02:03
created

Dispatcher   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 88
Duplicated Lines 0 %

Test Coverage

Coverage 17.14%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 11
eloc 34
c 1
b 0
f 0
dl 0
loc 88
ccs 6
cts 35
cp 0.1714
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 10 1
A dispatch() 0 20 4
A getObjectManager() 0 19 4
A getWorkflow() 0 8 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Setono\MessageSchedulerBundle\Dispatcher;
6
7
use Doctrine\Persistence\ManagerRegistry;
8
use Doctrine\Persistence\ObjectManager;
9
use LogicException;
10
use RuntimeException;
11
use function Safe\sprintf;
12
use Setono\MessageSchedulerBundle\Message\Command\DispatchMessage;
13
use Setono\MessageSchedulerBundle\Repository\ScheduledMessageRepositoryInterface;
14
use Setono\MessageSchedulerBundle\Workflow\ScheduledMessageWorkflow;
15
use Symfony\Component\Messenger\MessageBusInterface;
16
use Symfony\Component\Workflow\Registry;
17
use Symfony\Component\Workflow\Workflow;
18
19
final class Dispatcher implements DispatcherInterface
20
{
21
    private ?ObjectManager $objectManager = null;
22
23
    private MessageBusInterface $commandBus;
24
25
    private ScheduledMessageRepositoryInterface $scheduledMessageRepository;
26
27
    private Registry $workflowRegistry;
28
29
    private ManagerRegistry $managerRegistry;
30
31 1
    public function __construct(
32
        MessageBusInterface $commandBus,
33
        ScheduledMessageRepositoryInterface $scheduledMessageRepository,
34
        Registry $workflowRegistry,
35
        ManagerRegistry $managerRegistry
36
    ) {
37 1
        $this->commandBus = $commandBus;
38 1
        $this->scheduledMessageRepository = $scheduledMessageRepository;
39 1
        $this->workflowRegistry = $workflowRegistry;
40 1
        $this->managerRegistry = $managerRegistry;
41 1
    }
42
43
    public function dispatch(): void
44
    {
45
        $messages = $this->scheduledMessageRepository->findDispatchable();
46
47
        if (count($messages) === 0) {
48
            return;
49
        }
50
51
        $workflow = $this->getWorkflow($messages);
52
        $objectManager = $this->getObjectManager($messages);
53
54
        foreach ($messages as $message) {
55
            if (!$workflow->can($message, ScheduledMessageWorkflow::TRANSITION_DISPATCH)) {
56
                continue;
57
            }
58
59
            $workflow->apply($message, ScheduledMessageWorkflow::TRANSITION_DISPATCH);
60
            $objectManager->flush();
61
62
            $this->commandBus->dispatch(new DispatchMessage($message));
63
        }
64
    }
65
66
    /**
67
     * This method presumes that all the objects are of the same class
68
     * therefore it returns the workflow for the first object
69
     *
70
     * @param object[] $objects
71
     */
72
    private function getWorkflow(array $objects): Workflow
73
    {
74
        $obj = current($objects);
75
        if (false === $obj) {
76
            throw new LogicException('An empty array of objects were passed to this method');
77
        }
78
79
        return $this->workflowRegistry->get($obj, ScheduledMessageWorkflow::NAME);
80
    }
81
82
    /**
83
     * This method presumes that all the objects are of the same class
84
     * therefore it returns the object manager for the first object's class
85
     *
86
     * @param object[] $objects
87
     */
88
    private function getObjectManager(array $objects): ObjectManager
89
    {
90
        if (null === $this->objectManager) {
91
            $obj = current($objects);
92
            if (false === $obj) {
93
                throw new LogicException('An empty array of objects were passed to this method');
94
            }
95
96
            $class = get_class($obj);
97
            $manager = $this->managerRegistry->getManagerForClass($class);
98
99
            if (null === $manager) {
100
                throw new RuntimeException(sprintf('No object manager associated with the class, %s', $class));
101
            }
102
103
            $this->objectManager = $manager;
104
        }
105
106
        return $this->objectManager;
107
    }
108
}
109