Completed
Push — master ( 211db0...4df7a0 )
by
unknown
21s queued 17s
created

getDescriptionTranslatedClassName()

Size

Total Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 1
c 0
b 0
f 0
nc 1
1
<?php
2
3
namespace CultuurNet\UDB3\Offer\ReadModel\History;
4
5
use Broadway\Domain\DateTime;
6
use Broadway\Domain\DomainMessage;
7
use Broadway\Domain\Metadata;
8
use CultuurNet\UDB3\Event\ReadModel\DocumentRepositoryInterface;
9
use CultuurNet\UDB3\Event\ReadModel\History\Log;
10
use CultuurNet\UDB3\EventHandling\DelegateEventHandlingToSpecificMethodTrait;
11
use CultuurNet\UDB3\Offer\Events\AbstractDescriptionTranslated;
12
use CultuurNet\UDB3\Offer\Events\AbstractLabelAdded;
13
use CultuurNet\UDB3\Offer\Events\AbstractLabelRemoved;
14
use CultuurNet\UDB3\Offer\Events\AbstractTitleTranslated;
15
use CultuurNet\UDB3\ReadModel\JsonDocument;
16
use ValueObjects\StringLiteral\StringLiteral;
17
18
abstract class OfferHistoryProjector
19
{
20
    use DelegateEventHandlingToSpecificMethodTrait {
21
        DelegateEventHandlingToSpecificMethodTrait::handle as handleUnknownEvents;
22
    }
23
24
    /**
25
     * @var DocumentRepositoryInterface
26
     */
27
    private $documentRepository;
28
29
    public function __construct(DocumentRepositoryInterface $documentRepository)
30
    {
31
        $this->documentRepository = $documentRepository;
32
    }
33
34
    /**
35
     * {@inheritdoc}
36
     */
37
    public function handle(DomainMessage $domainMessage)
38
    {
39
        $event = $domainMessage->getPayload();
40
41
        $eventName = get_class($event);
42
        $eventHandlers = $this->getEventHandlers();
43
44
        if (isset($eventHandlers[$eventName])) {
45
            $handler = $eventHandlers[$eventName];
46
            call_user_func(array($this, $handler), $event, $domainMessage);
47
        } else {
48
            $this->handleUnknownEvents($domainMessage);
49
        }
50
    }
51
52
    /**
53
     * @return string[]
54
     *   An associative array of commands and their handler methods.
55
     */
56
    protected function getEventHandlers()
57
    {
58
        $events = [];
59
60
        foreach (get_class_methods($this) as $method) {
61
            $matches = [];
62
63
            if (preg_match('/^apply(.+)$/', $method, $matches)) {
64
                $event = $matches[1];
65
                $classNameMethod = 'get' . $event . 'ClassName';
66
67
                if (method_exists($this, $classNameMethod)) {
68
                    $eventFullClassName = call_user_func(array($this, $classNameMethod));
69
                    $events[$eventFullClassName] = $method;
70
                }
71
            }
72
        }
73
74
        return $events;
75
    }
76
77
    /**
78
     * @return string
79
     */
80
    abstract protected function getLabelAddedClassName();
81
82
    /**
83
     * @return string
84
     */
85
    abstract protected function getLabelRemovedClassName();
86
87
    /**
88
     * @return string
89
     */
90
    abstract protected function getTitleTranslatedClassName();
91
92
    /**
93
     * @return string
94
     */
95
    abstract protected function getDescriptionTranslatedClassName();
96
97
    /**
98
     * @param AbstractLabelAdded $labelAdded
99
     * @param DomainMessage $domainMessage
100
     */
101
    protected function applyLabelAdded(
102
        AbstractLabelAdded $labelAdded,
103
        DomainMessage $domainMessage
104
    ) {
105
        $this->writeHistory(
106
            $labelAdded->getItemId(),
107
            new Log(
108
                $this->domainMessageDateToNativeDate($domainMessage->getRecordedOn()),
109
                new StringLiteral("Label '{$labelAdded->getLabel()}' toegepast"),
110
                $this->getAuthorFromMetadata($domainMessage->getMetadata()),
111
                $this->getApiKeyFromMetadata($domainMessage->getMetadata()),
112
                $this->getApiFromMetadata($domainMessage->getMetadata())
113
            )
114
        );
115
    }
116
117
    /**
118
     * @param AbstractLabelRemoved $labelRemoved
119
     * @param DomainMessage $domainMessage
120
     */
121
    protected function applyLabelRemoved(
122
        AbstractLabelRemoved $labelRemoved,
123
        DomainMessage $domainMessage
124
    ) {
125
        $this->writeHistory(
126
            $labelRemoved->getItemId(),
127
            new Log(
128
                $this->domainMessageDateToNativeDate($domainMessage->getRecordedOn()),
129
                new StringLiteral("Label '{$labelRemoved->getLabel()}' verwijderd"),
130
                $this->getAuthorFromMetadata($domainMessage->getMetadata()),
131
                $this->getApiKeyFromMetadata($domainMessage->getMetadata()),
132
                $this->getApiFromMetadata($domainMessage->getMetadata())
133
            )
134
        );
135
    }
136
137
    protected function applyTitleTranslated(
138
        AbstractTitleTranslated $titleTranslated,
139
        DomainMessage $domainMessage
140
    ) {
141
        $this->writeHistory(
142
            $titleTranslated->getItemId(),
143
            new Log(
144
                $this->domainMessageDateToNativeDate($domainMessage->getRecordedOn()),
145
                new StringLiteral("Titel vertaald ({$titleTranslated->getLanguage()})"),
146
                $this->getAuthorFromMetadata($domainMessage->getMetadata()),
147
                $this->getApiKeyFromMetadata($domainMessage->getMetadata()),
148
                $this->getApiFromMetadata($domainMessage->getMetadata())
149
            )
150
        );
151
    }
152
153
    protected function applyDescriptionTranslated(
154
        AbstractDescriptionTranslated $descriptionTranslated,
155
        DomainMessage $domainMessage
156
    ) {
157
        $this->writeHistory(
158
            $descriptionTranslated->getItemId(),
159
            new Log(
160
                $this->domainMessageDateToNativeDate($domainMessage->getRecordedOn()),
161
                new StringLiteral("Beschrijving vertaald ({$descriptionTranslated->getLanguage()})"),
162
                $this->getAuthorFromMetadata($domainMessage->getMetadata()),
163
                $this->getApiKeyFromMetadata($domainMessage->getMetadata()),
164
                $this->getApiFromMetadata($domainMessage->getMetadata())
165
            )
166
        );
167
    }
168
169
    /**
170
     * @param DateTime $date
171
     * @return \DateTime
172
     */
173
    protected function domainMessageDateToNativeDate(DateTime $date)
174
    {
175
        $dateString = $date->toString();
176
        return \DateTime::createFromFormat(
0 ignored issues
show
Comprehensibility Best Practice introduced by
The expression \DateTime::createFromFor...T_STRING, $dateString); of type DateTime|false adds false to the return on line 176 which is incompatible with the return type documented by CultuurNet\UDB3\Offer\Re...MessageDateToNativeDate of type DateTime. It seems like you forgot to handle an error condition.
Loading history...
177
            DateTime::FORMAT_STRING,
178
            $dateString
179
        );
180
    }
181
182
    /**
183
     * @param $dateString
184
     * @return \DateTime
185
     */
186
    protected function dateFromUdb2DateString($dateString)
187
    {
188
        return \DateTime::createFromFormat(
0 ignored issues
show
Comprehensibility Best Practice introduced by
The expression \DateTime::createFromFor...ne('Europe/Brussels')); of type DateTime|false adds false to the return on line 188 which is incompatible with the return type documented by CultuurNet\UDB3\Offer\Re...:dateFromUdb2DateString of type DateTime. It seems like you forgot to handle an error condition.
Loading history...
189
            'Y-m-d?H:i:s',
190
            $dateString,
191
            new \DateTimeZone('Europe/Brussels')
192
        );
193
    }
194
195
    /**
196
     * @param Metadata $metadata
197
     * @return String|null
198
     */
199
    protected function getAuthorFromMetadata(Metadata $metadata)
200
    {
201
        $properties = $metadata->serialize();
202
203
        if (isset($properties['user_nick'])) {
204
            return new StringLiteral($properties['user_nick']);
205
        }
206
    }
207
208
    /**
209
     * @param Metadata $metadata
210
     * @return String|null
211
     */
212
    protected function getConsumerFromMetadata(Metadata $metadata)
213
    {
214
        $properties = $metadata->serialize();
215
216
        if (isset($properties['consumer']['name'])) {
217
            return new StringLiteral($properties['consumer']['name']);
218
        }
219
    }
220
221
    /**
222
     * @param string $eventId
223
     * @return JsonDocument
224
     */
225
    protected function loadDocumentFromRepositoryByEventId($eventId)
226
    {
227
        $historyDocument = $this->documentRepository->get($eventId);
228
229
        if (!$historyDocument) {
230
            $historyDocument = new JsonDocument($eventId, '[]');
231
        }
232
233
        return $historyDocument;
234
    }
235
236
    /**
237
     * @param string $eventId
238
     * @param Log[]|Log $logs
239
     */
240
    protected function writeHistory($eventId, $logs)
241
    {
242
        $historyDocument = $this->loadDocumentFromRepositoryByEventId($eventId);
243
244
        $history = $historyDocument->getBody();
245
246
        if (!is_array($logs)) {
247
            $logs = [$logs];
248
        }
249
250
        // Append most recent one to the top.
251
        foreach ($logs as $log) {
252
            array_unshift($history, $log);
253
        }
254
255
        $this->documentRepository->save(
256
            $historyDocument->withBody($history)
257
        );
258
    }
259
260
    protected function getApiKeyFromMetadata(Metadata $metadata): ?string
261
    {
262
        $properties = $metadata->serialize();
263
264
        if (isset($properties['auth_api_key'])) {
265
            return $properties['auth_api_key'];
266
        }
267
268
        return null;
269
    }
270
271
    protected function getApiFromMetadata(Metadata $metadata): ?string
272
    {
273
        $properties = $metadata->serialize();
274
275
        if (isset($properties['api'])) {
276
            return $properties['api'];
277
        }
278
279
        return null;
280
    }
281
}
282