Completed
Pull Request — develop (#305)
by Wachter
15:11
created

Article::whenChangeTranslationStructure()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 9
rs 9.6666
c 0
b 0
f 0
cc 1
eloc 7
nc 1
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Sulu\Bundle\ArticleBundle\Prooph\Model;
6
7
use Prooph\EventSourcing\AggregateChanged;
8
use Prooph\EventSourcing\AggregateRoot;
9
use Sulu\Bundle\ArticleBundle\Prooph\Model\Event\ChangeTranslationStructure;
10
use Sulu\Bundle\ArticleBundle\Prooph\Model\Event\CreateArticle;
11
use Sulu\Bundle\ArticleBundle\Prooph\Model\Event\CreateTranslation;
12
use Sulu\Bundle\ArticleBundle\Prooph\Model\Event\ModifyTranslationStructure;
13
use Sulu\Bundle\ArticleBundle\Prooph\Model\Event\PublishTranslation;
14
use Sulu\Bundle\ArticleBundle\Prooph\Model\Event\RemoveArticle;
15
use Sulu\Bundle\ArticleBundle\Prooph\Model\Event\UnpublishTranslation;
16
use Sulu\Component\Content\Document\WorkflowStage;
17
18
class Article extends AggregateRoot
19
{
20
    /**
21
     * @var string
22
     */
23
    private $id;
24
25
    /**
26
     * @var int
27
     */
28
    private $createdBy;
29
30
    /**
31
     * @var \DateTimeImmutable
32
     */
33
    private $createdAt;
34
35
    /**
36
     * @var int
37
     */
38
    private $modifiedBy;
39
40
    /**
41
     * @var \DateTimeImmutable
42
     */
43
    private $modifiedAt;
44
45
    /**
46
     * @var int
47
     */
48
    private $removedBy;
49
50
    /**
51
     * @var \DateTimeImmutable
52
     */
53
    private $removedAt;
54
55
    /**
56
     * @var ArticleTranslation[]
57
     */
58
    private $translations = [];
59
60
    static public function create(string $id, int $userId)
0 ignored issues
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
61
    {
62
        $article = new self();
63
        $article->recordThat(CreateArticle::occur($id, ['createdBy' => $userId]));
64
65
        return $article;
66
    }
67
68
    public function modifyTranslationStructure(
69
        string $locale,
70
        string $structureType,
71
        array $structureData,
72
        int $userId,
73
        array $requestData
74
    ) {
75
        $translation = $this->findTranslation($locale);
76
        if (!$translation) {
77
            $this->recordThat(
78
                CreateTranslation::occur(
79
                    $this->id,
80
                    [
81
                        'locale' => $locale,
82
                        'createdBy' => $userId,
83
                        'structureType' => $structureType,
84
                        'requestData' => $requestData,
85
                    ]
86
                )
87
            );
88
89
            $translation = new ArticleTranslation();
90
        } elseif ($structureType !== $translation->structureType) {
91
            $this->recordThat(
92
                ChangeTranslationStructure::occur(
93
                    $this->id,
94
                    [
95
                        'locale' => $locale,
96
                        'structureType' => $structureType,
97
                        'createdBy' => $userId,
98
                    ]
99
                )
100
            );
101
        }
102
103
        $this->recordThat(
104
            ModifyTranslationStructure::occur(
105
                $this->id,
106
                [
107
                    'locale' => $locale,
108
                    'structureData' => array_diff($structureData, $translation->structureData),
109
                    'createdBy' => $userId,
110
                    'requestData' => $requestData,
111
                ]
112
            )
113
        );
114
115
        return $this;
116
    }
117
118
    public function publishTranslation(string $locale, int $userId)
119
    {
120
        $this->recordThat(
121
            PublishTranslation::occur(
122
                $this->id,
123
                [
124
                    'locale' => $locale,
125
                    'createdBy' => $userId,
126
                ]
127
            )
128
        );
129
130
        return $this;
131
    }
132
133
    public function unpublishTranslation(string $locale, int $userId)
134
    {
135
        $this->recordThat(
136
            UnpublishTranslation::occur(
137
                $this->id,
138
                [
139
                    'locale' => $locale,
140
                    'createdBy' => $userId,
141
                ]
142
            )
143
        );
144
145
        return $this;
146
    }
147
148
    public function remove(int $userId)
149
    {
150
        $this->recordThat(RemoveArticle::occur($this->id, ['createdBy' => $userId]));
151
152
        return $this;
153
    }
154
155
    protected function aggregateId(): string
156
    {
157
        return $this->id;
158
    }
159
160
    public function findTranslation(string $locale): ?ArticleTranslation
161
    {
162
        if (!array_key_exists($locale, $this->translations)) {
163
            return null;
164
        }
165
166
        return $this->translations[$locale];
167
    }
168
169
    public function whenCreateArticle(CreateArticle $event): void
170
    {
171
        $this->id = $event->aggregateId();
172
        $this->createdAt = $event->createdAt();
173
        $this->createdBy = $event->createdBy();
174
    }
175
176
    public function whenCreateTranslation(CreateTranslation $event): void
177
    {
178
        $this->translations[$event->locale()] = $translation = new ArticleTranslation();
179
        $translation->locale = $event->locale();
180
        $translation->structureType = $event->structureType();
181
        $translation->createdAt = $event->createdAt();
182
        $translation->createdBy = $event->createdBy();
183
    }
184
185
    public function whenChangeTranslationStructure(ChangeTranslationStructure $event)
186
    {
187
        $translation = $this->findTranslation($event->locale());
188
        $translation->structureType = $event->structureType();
189
        $translation->modifiedAt = $event->createdAt();
190
        $translation->modifiedBy = $event->createdBy();
191
        $this->modifiedAt = $event->createdAt();
192
        $this->modifiedBy = $event->createdBy();
193
    }
194
195
    public function whenModifyTranslationStructure(ModifyTranslationStructure $event)
196
    {
197
        $translation = $this->findTranslation($event->locale());
198
        $translation->structureData = array_merge($translation->structureData, $event->structureData());
199
        $translation->modifiedAt = $event->createdAt();
200
        $translation->modifiedBy = $event->createdBy();
201
        $this->modifiedAt = $event->createdAt();
202
        $this->modifiedBy = $event->createdBy();
203
    }
204
205
    public function whenPublishTranslation(PublishTranslation $event)
206
    {
207
        $translation = $this->findTranslation($event->locale());
208
        $translation->workflowStage = WorkflowStage::PUBLISHED;
209
        $translation->publishedAt = $event->createdAt();
210
        $translation->publishedBy = $event->createdBy();
211
        $translation->modifiedAt = $event->createdAt();
212
        $translation->modifiedBy = $event->createdBy();
213
        $this->modifiedAt = $event->createdAt();
214
        $this->modifiedBy = $event->createdBy();
215
    }
216
217
    public function whenUnpublishTranslation(UnpublishTranslation $event)
218
    {
219
        $translation = $this->findTranslation($event->locale());
220
        $translation->workflowStage = WorkflowStage::TEST;
221
        $translation->modifiedAt = $event->createdAt();
222
        $translation->modifiedBy = $event->createdBy();
223
        $this->modifiedAt = $event->createdAt();
224
        $this->modifiedBy = $event->createdBy();
225
    }
226
227
    public function whenRemoveArticle(RemoveArticle $event)
228
    {
229
        $this->translations = [];
230
        $this->removedAt = $event->createdAt();
231
        $this->removedBy = $event->createdBy();
232
        $this->modifiedAt = $event->createdAt();
233
        $this->modifiedBy = $event->createdBy();
234
    }
235
236
    protected function apply(AggregateChanged $event): void
237
    {
238
        $handler = $this->determineEventHandlerMethodFor($event);
239
        if (!method_exists($this, $handler)) {
240
            throw new \RuntimeException(
241
                sprintf(
242
                    'Missing event handler method %s for aggregate root %s',
243
                    $handler,
244
                    get_class($this)
245
                )
246
            );
247
        }
248
        $this->{$handler}($event);
249
    }
250
251
    protected function determineEventHandlerMethodFor(AggregateChanged $e): string
252
    {
253
        return 'when' . implode(array_slice(explode('\\', get_class($e)), -1));
254
    }
255
}
256