Passed
Push — master ( 2ee0d1...1e8995 )
by Tomasz
03:21
created

Board::__construct()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 7
nc 2
nop 4
dl 0
loc 10
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types = 1);
4
5
namespace Aggrego\Domain\Model\ProgressiveBoard;
6
7
use Aggrego\Domain\Api\Application\Event\Aggregate;
8
use Aggrego\Domain\Api\Application\Profile\BoardConstruction\Builder;
9
use Aggrego\Domain\Api\Application\Profile\BoardTransformation\Transformation;
10
use Aggrego\Domain\Model\ProgressiveBoard\Events\BoardCreatedEvent;
11
use Aggrego\Domain\Model\ProgressiveBoard\Events\BoardDeletedEvent;
12
use Aggrego\Domain\Model\ProgressiveBoard\Events\ShardAddedEvent;
13
use Aggrego\Domain\Model\ProgressiveBoard\Events\ShardUpdatedEvent;
14
use Aggrego\Domain\Model\ProgressiveBoard\Events\UpdatedLastStepsShardEvent;
15
use Aggrego\Domain\Model\ProgressiveBoard\Exception\UnfinishedStepPassedForTransformationException;
16
use Aggrego\Domain\Model\ProgressiveBoard\Shard\Collection;
17
use Aggrego\Domain\Model\ProgressiveBoard\Shard\FinalItem;
18
use Aggrego\Domain\Model\ProgressiveBoard\Shard\InitialItem;
19
use Aggrego\Domain\Model\ProgressiveBoard\Step\State;
20
use Aggrego\Domain\Model\ProgressiveBoard\Step\Step;
21
use Aggrego\Domain\Profile\Profile;
22
use Aggrego\Domain\Shared\Event\Model\TraitAggregate;
23
use Aggrego\Domain\Shared\ValueObject\Data;
24
use Aggrego\Domain\Shared\ValueObject\Key;
25
use Aggrego\Domain\Shared\ValueObject\Uuid;
26
27
class Board implements Aggregate
28
{
29
    use TraitAggregate;
30
31
    /** @var Uuid */
32
    private $uuid;
33
34
    /** @var Key */
35
    private $key;
36
37
    /** @var Profile */
38
    private $profile;
39
40
    /** @var Step */
41
    private $step;
42
43
    /** @var bool */
44
    private $isDeleted;
45
46
    private function __construct(Uuid $uuid, Key $key, Profile $profile, Step $step)
47
    {
48
        $this->uuid = $uuid;
49
        $this->key = $key;
50
        $this->profile = $profile;
51
        $this->step = $step;
52
53
        $this->pushEvent(new BoardCreatedEvent($this));
54
        foreach ($step->getShards() as $shard) {
55
            $this->pushEvent(new ShardAddedEvent($shard));
56
        }
57
    }
58
59
    public static function factory(Key $key, Builder $factory): self
60
    {
61
        $initialBoard = $factory->build($key);
62
63
        $shardsList = [];
64
        /** @var InitialItem $item */
65
        foreach ($initialBoard->getShards() as $item) {
66
            $shardsList[] = new InitialItem(
67
                $item->getUuid(),
68
                $item->getProfile(),
69
                $item->getKey()
70
            );
71
        }
72
73
        return new self(
74
            $initialBoard->getUuid(),
75
            $initialBoard->getKey(),
76
            $initialBoard->getProfile(),
77
            new Step(State::createInitial(), new Collection($shardsList))
78
        );
79
    }
80
81
    public function getUuid(): Uuid
82
    {
83
        return $this->uuid;
84
    }
85
86
    public function getKey(): Key
87
    {
88
        return $this->key;
89
    }
90
91
    public function getProfile(): Profile
92
    {
93
        return $this->profile;
94
    }
95
96
    public function getStep(): Step
97
    {
98
        return $this->step;
99
    }
100
101
    public function updateShard(Uuid $shardUuid, Profile $profile, Data $data): void
102
    {
103
        $shard = new FinalItem($shardUuid, $profile, $data);
104
        $this->step->replace($shard);
105
        $this->pushEvent(new ShardUpdatedEvent($shard));
106
        if ($this->isStepReadyForNextTransformation()) {
107
            $this->pushEvent(new UpdatedLastStepsShardEvent());
108
        }
109
    }
110
111
    public function markAsDeleted(): void
112
    {
113
        $this->isDeleted = true;
114
        $this->pushEvent(new BoardDeletedEvent());
115
    }
116
117
    public function isStepReadyForNextTransformation(): bool
118
    {
119
        return $this->step->isAllShardsFinishedProgress();
120
    }
121
122
    public function transformStep(Transformation $transformation): void
123
    {
124
        if (!$this->isStepReadyForNextTransformation()) {
125
            throw new UnfinishedStepPassedForTransformationException();
126
        }
127
128
        $this->step = $transformation->process($this->step);
129
    }
130
}
131