Passed
Push — master ( 1e8995...e0bd2f )
by Tomasz
02:02
created

Board::factory()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 19
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 12
nc 2
nop 2
dl 0
loc 19
rs 9.8666
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\BoardTransformedEvent;
13
use Aggrego\Domain\Model\ProgressiveBoard\Events\FinalBoardTransformedEvent;
14
use Aggrego\Domain\Model\ProgressiveBoard\Events\ShardAddedEvent;
15
use Aggrego\Domain\Model\ProgressiveBoard\Events\ShardUpdatedEvent;
16
use Aggrego\Domain\Model\ProgressiveBoard\Events\UpdatedLastStepsShardEvent;
17
use Aggrego\Domain\Model\ProgressiveBoard\Exception\UnfinishedStepPassedForTransformationException;
18
use Aggrego\Domain\Model\ProgressiveBoard\Exception\UnprocessableBoardException;
19
use Aggrego\Domain\Model\ProgressiveBoard\Shard\Collection;
20
use Aggrego\Domain\Model\ProgressiveBoard\Shard\FinalItem;
21
use Aggrego\Domain\Model\ProgressiveBoard\Shard\InitialItem;
22
use Aggrego\Domain\Model\ProgressiveBoard\Step\State;
23
use Aggrego\Domain\Model\ProgressiveBoard\Step\Step;
24
use Aggrego\Domain\Model\ProgressiveBoard\Step\Steps\FinalStep;
25
use Aggrego\Domain\Model\ProgressiveBoard\Step\Steps\ProgressStep;
26
use Aggrego\Domain\Profile\Profile;
27
use Aggrego\Domain\Shared\Event\Model\TraitAggregate;
28
use Aggrego\Domain\Shared\ValueObject\Data;
29
use Aggrego\Domain\Shared\ValueObject\Key;
30
use Aggrego\Domain\Shared\ValueObject\Uuid;
31
32
class Board implements Aggregate
33
{
34
    use TraitAggregate;
35
36
    /** @var Uuid */
37
    private $uuid;
38
39
    /** @var Key */
40
    private $key;
41
42
    /** @var Profile */
43
    private $profile;
44
45
    /** @var Step */
46
    private $step;
47
48
    /** @var bool */
49
    private $isDeleted;
50
51
    private function __construct(Uuid $uuid, Key $key, Profile $profile, ProgressStep $step)
52
    {
53
        $this->uuid = $uuid;
54
        $this->key = $key;
55
        $this->profile = $profile;
56
        $this->step = $step;
57
58
        $this->pushEvent(new BoardCreatedEvent($this));
59
        $this->setStep($step);
60
    }
61
62
    public static function factory(Key $key, Builder $factory): self
63
    {
64
        $initialBoard = $factory->build($key);
65
66
        $shardsList = [];
67
        /** @var InitialItem $item */
68
        foreach ($initialBoard->getShards() as $item) {
69
            $shardsList[] = new InitialItem(
70
                $item->getUuid(),
71
                $item->getProfile(),
72
                $item->getKey()
73
            );
74
        }
75
76
        return new self(
77
            $initialBoard->getUuid(),
78
            $initialBoard->getKey(),
79
            $initialBoard->getProfile(),
80
            new ProgressStep(State::createInitial(), new Collection($shardsList))
81
        );
82
    }
83
84
    public function getUuid(): Uuid
85
    {
86
        return $this->uuid;
87
    }
88
89
    public function getKey(): Key
90
    {
91
        return $this->key;
92
    }
93
94
    public function getProfile(): Profile
95
    {
96
        return $this->profile;
97
    }
98
99
    public function updateShard(Uuid $shardUuid, Profile $profile, Data $data): void
100
    {
101
        if ($this->isDeleted) {
102
            throw new UnprocessableBoardException();
103
        }
104
        $shard = new FinalItem($shardUuid, $profile, $data);
105
        $this->step->replace($shard);
0 ignored issues
show
Bug introduced by
The method replace() does not exist on Aggrego\Domain\Model\ProgressiveBoard\Step\Step. It seems like you code against a sub-type of Aggrego\Domain\Model\ProgressiveBoard\Step\Step such as Aggrego\Domain\Model\Pro...Step\Steps\ProgressStep. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

105
        $this->step->/** @scrutinizer ignore-call */ 
106
                     replace($shard);
Loading history...
106
        $this->pushEvent(new ShardUpdatedEvent($shard));
107
        if ($this->isStepReadyForNextTransformation()) {
108
            $this->pushEvent(new UpdatedLastStepsShardEvent());
109
        }
110
    }
111
112
    public function isStepReadyForNextTransformation(): bool
113
    {
114
        if ($this->isDeleted) {
115
            return false;
116
        }
117
        return $this->step->isReadyForTransformation();
0 ignored issues
show
Bug introduced by
The method isReadyForTransformation() does not exist on Aggrego\Domain\Model\ProgressiveBoard\Step\Step. It seems like you code against a sub-type of Aggrego\Domain\Model\ProgressiveBoard\Step\Step such as Aggrego\Domain\Model\Pro...Step\Steps\ProgressStep. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

117
        return $this->step->/** @scrutinizer ignore-call */ isReadyForTransformation();
Loading history...
118
    }
119
120
    public function transformStep(Transformation $transformation): void
121
    {
122
        if ($this->isDeleted) {
123
            throw new UnprocessableBoardException();
124
        }
125
126
        if (!$this->isStepReadyForNextTransformation()) {
127
            throw new UnfinishedStepPassedForTransformationException();
128
        }
129
130
        $step = $transformation->process($this->step);
131
132
        if ($step->getState()->isFinal()) {
133
            /** @var FinalStep $step */
134
            $this->pushEvent(new FinalBoardTransformedEvent($step));
135
136
            $this->isDeleted = true;
137
            $this->pushEvent(new BoardDeletedEvent());
138
        } else {
139
            /** @var ProgressStep $step */
140
            $this->pushEvent(new BoardTransformedEvent($step));
141
            $this->setStep($step);
142
        }
143
    }
144
145
    private function setStep(ProgressStep $step): void
146
    {
147
        $this->step = $step;
148
        foreach ($step->getShards() as $shard) {
149
            $this->pushEvent(new ShardAddedEvent($shard));
150
        }
151
    }
152
}
153