CommandBusEventDispatcher::extractCommands()   A
last analyzed

Complexity

Conditions 4
Paths 4

Size

Total Lines 13
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 13
rs 9.2
cc 4
eloc 8
nc 4
nop 1
1
<?php
2
namespace PhpDDD\Command\Bus;
3
4
use PhpDDD\Command\CommandInterface;
5
use PhpDDD\Command\Handler\CommandHandlerInterface;
6
use PhpDDD\Domain\AbstractAggregateRoot;
7
use PhpDDD\Domain\Event\Bus\EventBusInterface;
8
use PhpDDD\Domain\Event\EventInterface;
9
use PhpDDD\Domain\Event\Listener\EventListenerCollection;
10
11
/**
12
 * Class that act as a CommandBus and dispatch events
13
 *
14
 * @see php-ddd/event project
15
 */
16
class CommandBusEventDispatcher implements CommandBusInterface, EventBusInterface
17
{
18
19
    /**
20
     * @var CommandBusInterface
21
     */
22
    private $commandBus;
23
24
    /**
25
     * @var EventBusInterface
26
     */
27
    private $eventBus;
28
29
    /**
30
     * @param CommandBusInterface $commandBus
31
     * @param EventBusInterface   $eventBus
32
     */
33
    public function __construct(CommandBusInterface $commandBus, EventBusInterface $eventBus)
34
    {
35
        $this->commandBus = $commandBus;
36
        $this->eventBus   = $eventBus;
37
    }
38
39
    /**
40
     * @param CommandInterface $command
41
     *
42
     * @return AbstractAggregateRoot[]
43
     */
44
    public function dispatch(CommandInterface $command)
45
    {
46
        $aggregateRoots = $this->commandBus->dispatch($command);
47
48
        $this->dispatchEvents($aggregateRoots);
49
50
        return $aggregateRoots;
51
    }
52
53
    /**
54
     * @return CommandHandlerInterface[]
55
     */
56
    public function getRegisteredCommandHandlers()
57
    {
58
        return $this->commandBus->getRegisteredCommandHandlers();
59
    }
60
61
    /**
62
     * Publishes the event $event to every EventListener that wants to.
63
     *
64
     * @param EventInterface $event
65
     *
66
     * @return string[]|null data returned by each EventListener
67
     */
68
    public function publish(EventInterface $event)
69
    {
70
        $commandsToDispatch = $this->eventBus->publish($event);
71
72
        $commands = $this->extractCommands($commandsToDispatch);
73
        foreach ($commands as $command) {
74
            $this->dispatch($command);
75
        }
76
    }
77
78
    /**
79
     * Get the list of every EventListener defined in the EventBus.
80
     * This might be useful for debug
81
     *
82
     * @return EventListenerCollection[]
83
     */
84
    public function getRegisteredEventListeners()
85
    {
86
        return $this->eventBus->getRegisteredEventListeners();
87
    }
88
89
    /**
90
     * @param array $elements
91
     */
92
    private function dispatchEvents(array $elements)
93
    {
94
        foreach ($elements as $element) {
95
            if (is_array($element)) {
96
                $this->dispatchEvents($element);
97
98
                return;
99
            }
100
            if ($element instanceof AbstractAggregateRoot) {
101
                $this->dispatchEventsForAggregateRoot($element);
102
            }
103
        }
104
    }
105
106
    /**
107
     * @param AbstractAggregateRoot $aggregateRoot
108
     */
109
    private function dispatchEventsForAggregateRoot(AbstractAggregateRoot $aggregateRoot)
110
    {
111
        $events = $aggregateRoot->pullEvents();
112
113
        foreach ($events as $event) {
114
            $this->publish($event);
115
        }
116
    }
117
118
    /**
119
     * @param array $commandsToDispatch
120
     *
121
     * @return CommandInterface[]
122
     */
123
    private function extractCommands(array $commandsToDispatch)
124
    {
125
        $commands = array();
126
        foreach ($commandsToDispatch as $command) {
127
            if (is_array($command)) {
128
                $commands = array_merge($commands, $this->extractCommands($command));
129
            } elseif ($command instanceof CommandInterface) {
130
                $commands[] = $command;
131
            }
132
        }
133
134
        return $commands;
135
    }
136
}
137