safelyPopulateEventsWithAggregateId()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 8
rs 9.4285
cc 3
eloc 4
nc 3
nop 0
1
<?php
2
3
namespace PhpDDD\Domain;
4
5
use BadMethodCallException;
6
use PhpDDD\Domain\Event\EventInterface;
7
use PhpDDD\Domain\Event\Utils\EventName;
8
9
/**
10
 * An AggregateRoot is the starting point of an Aggregate.
11
 * It's the only class from an Aggregate that should be known by the outside world.
12
 */
13
abstract class AbstractAggregateRoot
14
{
15
    /**
16
     * @var int
17
     */
18
    protected $id;
19
20
    /**
21
     * List of events that occurred.
22
     *
23
     * @var EventInterface[]
24
     */
25
    private $events = array();
26
27
    /**
28
     * @return int
29
     */
30
    public function getId()
31
    {
32
        return $this->id;
33
    }
34
35
    /**
36
     * This allows you to get every events raised by the aggregate and clear the stack.
37
     * It's helpful when you do event sourcing because once an event is raised you may need to do some actions in other
38
     * bounded contexts. So the events is fired once.
39
     *
40
     * @return EventInterface[]
41
     */
42
    public function pullEvents()
43
    {
44
        $this->safelyPopulateEventsWithAggregateId();
45
        $events       = $this->events;
46
        $this->events = array();
47
48
        return $events;
49
    }
50
51
    /**
52
     * Used when somebody is trying to modify an Aggregate.
53
     * You should check that the input is good then create an event and call this method.
54
     *
55
     * @param EventInterface $event
56
     */
57
    protected function apply(EventInterface $event)
58
    {
59
        $this->executeEvent($event);
60
        $this->events[] = $event;
61
    }
62
63
    /**
64
     * @param EventInterface $event
65
     *
66
     * @throws BadMethodCallException
67
     */
68
    private function executeEvent(EventInterface $event)
69
    {
70
        $eventName = new EventName($event);
71
        $method    = sprintf('apply%s', (string) $eventName);
72
73
        if (!method_exists($this, $method)) {
74
            throw new BadMethodCallException(
75
                sprintf(
76
                    'You must define the %s::%s method(%s $event) in order to apply event named "%s". ',
77
                    get_class($this),
78
                    $method,
79
                    get_class($event),
80
                    $eventName
81
                )
82
            );
83
        }
84
85
        $this->$method($event);
86
    }
87
88
    /**
89
     *
90
     */
91
    private function safelyPopulateEventsWithAggregateId()
92
    {
93
        foreach ($this->events as $event) {
94
            if (null === $event->getAggregateRootId()) {
95
                $event->setAggregateRootId($this->id);
96
            }
97
        }
98
    }
99
}
100