Passed
Pull Request — master (#190)
by Dmitriy
04:22 queued 01:36
created

JsonMessageSerializer::serialize()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 5
c 1
b 0
f 0
nc 2
nop 1
dl 0
loc 9
ccs 7
cts 7
cp 1
crap 2
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Queue\Message;
6
7
use InvalidArgumentException;
8
use JsonException;
9
10
final class JsonMessageSerializer implements MessageSerializerInterface
11
{
12
    /**
13
     * @throws JsonException
14
     */
15 11
    public function serialize(MessageInterface $message): string
16
    {
17 11
        $payload = [
18 11
            'data' => $message->getData(),
19 11
            'meta' => $message->getMetadata(),
20 11
            'class' => $message instanceof EnvelopeInterface ? $message->getMessage()::class : $message::class,
21 11
        ];
22
23 11
        return json_encode($payload, JSON_THROW_ON_ERROR);
24
    }
25
26
    /**
27
     * @throws JsonException
28
     * @throws InvalidArgumentException
29
     */
30 17
    public function unserialize(string $value): MessageInterface
31
    {
32 17
        $payload = json_decode($value, true, 512, JSON_THROW_ON_ERROR);
33 17
        if (!is_array($payload)) {
34 4
            throw new InvalidArgumentException('Payload must be array. Got ' . get_debug_type($payload) . '.');
35
        }
36
37 13
        $meta = $payload['meta'] ?? [];
38 13
        if (!is_array($meta)) {
39 3
            throw new InvalidArgumentException('Metadata must be array. Got ' . get_debug_type($meta) . '.');
40
        }
41 10
        $class = $payload['class'] ?? Message::class;
42
43 10
        if (!is_subclass_of($class, MessageInterface::class)) {
44
            throw new InvalidArgumentException(sprintf(
45
                'Class "%s" must implement "%s" interface.',
46
                $class,
47
                MessageInterface::class,
48
            ));
49
        }
50
51
        /**
52
         * @var MessageInterface $message
53
         */
54 10
        $message = new $class($payload['data'] ?? null, $meta);
55
56 10
        if (isset($meta[EnvelopeInterface::ENVELOPE_STACK_KEY]) && is_array($meta[EnvelopeInterface::ENVELOPE_STACK_KEY])) {
57 8
            $message = $message->withMetadata(
58 8
                array_merge(
59 8
                    $message->getMetadata(),
60 8
                    $meta,
61 8
                    [EnvelopeInterface::ENVELOPE_STACK_KEY => []],
62 8
                ),
63 8
            );
64 8
            foreach ($meta[EnvelopeInterface::ENVELOPE_STACK_KEY] as $envelope) {
65 8
                if (is_string($envelope) && class_exists($envelope) && is_subclass_of($envelope, EnvelopeInterface::class)) {
66 8
                    $message = $envelope::fromMessage($message);
67
                }
68
            }
69
        }
70
71 10
        return $message;
72
    }
73
}
74