Completed
Pull Request — master (#441)
by
unknown
03:16
created

OfferHistoryProjector::getApiFromMetadata()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 10
rs 9.9332
c 0
b 0
f 0
cc 2
nc 2
nop 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
154
    protected function applyDescriptionTranslated(
155
        AbstractDescriptionTranslated $descriptionTranslated,
156
        DomainMessage $domainMessage
157
    ) {
158
        $this->writeHistory(
159
            $descriptionTranslated->getItemId(),
160
            new Log(
161
                $this->domainMessageDateToNativeDate($domainMessage->getRecordedOn()),
162
                new StringLiteral("Beschrijving vertaald ({$descriptionTranslated->getLanguage()})"),
163
                $this->getAuthorFromMetadata($domainMessage->getMetadata()),
164
                $this->getApiKeyFromMetadata($domainMessage->getMetadata()),
165
                $this->getApiFromMetadata($domainMessage->getMetadata())
166
            )
167
        );
168
    }
169
170
    /**
171
     * @param DateTime $date
172
     * @return \DateTime
173
     */
174
    protected function domainMessageDateToNativeDate(DateTime $date)
175
    {
176
        $dateString = $date->toString();
177
        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 177 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...
178
            DateTime::FORMAT_STRING,
179
            $dateString
180
        );
181
    }
182
183
    /**
184
     * @param $dateString
185
     * @return \DateTime
186
     */
187
    protected function dateFromUdb2DateString($dateString)
188
    {
189
        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 189 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...
190
            'Y-m-d?H:i:s',
191
            $dateString,
192
            new \DateTimeZone('Europe/Brussels')
193
        );
194
    }
195
196
    /**
197
     * @param Metadata $metadata
198
     * @return String|null
199
     */
200
    protected function getAuthorFromMetadata(Metadata $metadata)
201
    {
202
        $properties = $metadata->serialize();
203
204
        if (isset($properties['user_nick'])) {
205
            return new StringLiteral($properties['user_nick']);
206
        }
207
    }
208
209
    /**
210
     * @param Metadata $metadata
211
     * @return String|null
212
     */
213
    protected function getConsumerFromMetadata(Metadata $metadata)
214
    {
215
        $properties = $metadata->serialize();
216
217
        if (isset($properties['consumer']['name'])) {
218
            return new StringLiteral($properties['consumer']['name']);
219
        }
220
    }
221
222
    /**
223
     * @param string $eventId
224
     * @return JsonDocument
225
     */
226
    protected function loadDocumentFromRepositoryByEventId($eventId)
227
    {
228
        $historyDocument = $this->documentRepository->get($eventId);
229
230
        if (!$historyDocument) {
231
            $historyDocument = new JsonDocument($eventId, '[]');
232
        }
233
234
        return $historyDocument;
235
    }
236
237
    /**
238
     * @param string $eventId
239
     * @param Log[]|Log $logs
240
     */
241
    protected function writeHistory($eventId, $logs)
242
    {
243
        $historyDocument = $this->loadDocumentFromRepositoryByEventId($eventId);
244
245
        $history = $historyDocument->getBody();
246
247
        if (!is_array($logs)) {
248
            $logs = [$logs];
249
        }
250
251
        // Append most recent one to the top.
252
        foreach ($logs as $log) {
253
            array_unshift($history, $log);
254
        }
255
256
        $this->documentRepository->save(
257
            $historyDocument->withBody($history)
258
        );
259
    }
260
261
    protected function getApiKeyFromMetadata(Metadata $metadata): ?string
262
    {
263
        $properties = $metadata->serialize();
264
265
        if (isset($properties['auth_api_key'])) {
266
            return $properties['auth_api_key'];
267
           }
268
269
        return null;
270
    }
271
272
    protected function getApiFromMetadata(Metadata $metadata): ?string
273
    {
274
        $properties = $metadata->serialize();
275
276
        if (isset($properties['api'])) {
277
            return $properties['api'];
278
        }
279
280
        return null;
281
    }
282
}
283