Completed
Push — master ( a0580c...57df1c )
by Tomasz
01:44
created

Board   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 108
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 51
dl 0
loc 108
rs 10
c 0
b 0
f 0
wmc 15

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 9 1
A factory() 0 19 2
A setStep() 0 5 2
A isStepReadyForNextTransformation() 0 6 2
A getProfile() 0 3 1
A updateShard() 0 10 3
A transformStep() 0 22 4
1
<?php
2
3
declare(strict_types = 1);
4
5
namespace Aggrego\Domain\ProgressiveBoard;
6
7
use Aggrego\Domain\Api\Application\Event\Aggregate;
8
use Aggrego\Domain\Profile\BoardConstruction\Builder;
9
use Aggrego\Domain\Profile\BoardTransformation\Transformation;
10
use Aggrego\Domain\Profile\Profile;
11
use Aggrego\Domain\ProgressiveBoard\Events\BoardCreatedEvent;
12
use Aggrego\Domain\ProgressiveBoard\Events\BoardDeletedEvent;
13
use Aggrego\Domain\ProgressiveBoard\Events\BoardTransformedEvent;
14
use Aggrego\Domain\ProgressiveBoard\Events\FinalBoardTransformedEvent;
15
use Aggrego\Domain\ProgressiveBoard\Events\ShardAddedEvent;
16
use Aggrego\Domain\ProgressiveBoard\Events\ShardUpdatedEvent;
17
use Aggrego\Domain\ProgressiveBoard\Events\UpdatedLastStepsShardEvent;
18
use Aggrego\Domain\ProgressiveBoard\Exception\UnfinishedStepPassedForTransformationException;
19
use Aggrego\Domain\ProgressiveBoard\Exception\UnprocessableBoardException;
20
use Aggrego\Domain\ProgressiveBoard\Shard\Collection;
21
use Aggrego\Domain\ProgressiveBoard\Shard\FinalItem;
22
use Aggrego\Domain\ProgressiveBoard\Shard\InitialItem;
23
use Aggrego\Domain\ProgressiveBoard\Step\State;
24
use Aggrego\Domain\ProgressiveBoard\Step\Step;
25
use Aggrego\Domain\ProgressiveBoard\Step\Steps\FinalStep;
26
use Aggrego\Domain\ProgressiveBoard\Step\Steps\ProgressStep;
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($uuid, $key, $profile));
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 getProfile(): Profile
85
    {
86
        return $this->profile;
87
    }
88
89
    public function updateShard(Uuid $shardUuid, Profile $profile, Data $data): void
90
    {
91
        if ($this->isDeleted) {
92
            throw new UnprocessableBoardException();
93
        }
94
        $shard = new FinalItem($shardUuid, $profile, $data);
95
        $this->step->replace($shard);
0 ignored issues
show
Bug introduced by
The method replace() does not exist on Aggrego\Domain\ProgressiveBoard\Step\Step. It seems like you code against a sub-type of Aggrego\Domain\ProgressiveBoard\Step\Step such as Aggrego\Domain\Progressi...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

95
        $this->step->/** @scrutinizer ignore-call */ 
96
                     replace($shard);
Loading history...
96
        $this->pushEvent(new ShardUpdatedEvent($this->uuid, $shard));
97
        if ($this->isStepReadyForNextTransformation()) {
98
            $this->pushEvent(new UpdatedLastStepsShardEvent($this->uuid));
99
        }
100
    }
101
102
    public function isStepReadyForNextTransformation(): bool
103
    {
104
        if ($this->isDeleted) {
105
            return false;
106
        }
107
        return $this->step->isReadyForTransformation();
0 ignored issues
show
Bug introduced by
The method isReadyForTransformation() does not exist on Aggrego\Domain\ProgressiveBoard\Step\Step. It seems like you code against a sub-type of Aggrego\Domain\ProgressiveBoard\Step\Step such as Aggrego\Domain\Progressi...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

107
        return $this->step->/** @scrutinizer ignore-call */ isReadyForTransformation();
Loading history...
108
    }
109
110
    public function transformStep(Transformation $transformation): void
111
    {
112
        if ($this->isDeleted) {
113
            throw new UnprocessableBoardException();
114
        }
115
116
        if (!$this->isStepReadyForNextTransformation()) {
117
            throw new UnfinishedStepPassedForTransformationException();
118
        }
119
120
        $step = $transformation->process($this->step);
121
122
        if ($step->getState()->isFinal()) {
123
            /** @var FinalStep $step */
124
            $this->pushEvent(new FinalBoardTransformedEvent($this->uuid, $step));
125
126
            $this->isDeleted = true;
127
            $this->pushEvent(new BoardDeletedEvent($this->uuid));
128
        } else {
129
            /** @var ProgressStep $step */
130
            $this->pushEvent(new BoardTransformedEvent($this->uuid, $step));
131
            $this->setStep($step);
132
        }
133
    }
134
135
    private function setStep(ProgressStep $step): void
136
    {
137
        $this->step = $step;
138
        foreach ($step->getShards() as $shard) {
139
            $this->pushEvent(new ShardAddedEvent($this->uuid, $shard));
140
        }
141
    }
142
}
143