Test Failed
Pull Request — master (#1)
by Yo
10:49 queued 05:04
created

RawRequestSerializer::deserialize()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Yoanm\JsonRpcServer\Infra\Serialization;
4
5
use Yoanm\JsonRpcServer\App\Serialization\RequestDenormalizer;
6
use Yoanm\JsonRpcServer\Domain\Exception\JsonRpcInvalidRequestException;
7
use Yoanm\JsonRpcServer\Domain\Exception\JsonRpcParseErrorException;
8
use Yoanm\JsonRpcServer\Infra\RawObject\JsonRpcRawRequest;
9
10
/**
11
 * Class RawRequestSerializer
12
 */
13
class RawRequestSerializer
14
{
15
    /** @var RequestDenormalizer */
16
    private $requestDenormalizer;
17
18
    const KEY_JSON_RPC = 'json-rpc';
19
    const KEY_ID = 'id';
20
    const KEY_METHOD = 'method';
21
    const KEY_PARAM_LIST = 'params';
22
23
    /**
24
     * @param RequestDenormalizer $requestDenormalizer
25
     */
26
    public function __construct(RequestDenormalizer $requestDenormalizer)
27
    {
28
        $this->requestDenormalizer = $requestDenormalizer;
29
    }
30
31
    /**
32
     * @param string $content
33
     *
34
     * @return JsonRpcRawRequest
35
     */
36
    public function deserialize(string $content) : JsonRpcRawRequest
37
    {
38
        return $this->denormalize(
39
            $this->decode($content)
40
        );
41
    }
42
43
    /**
44
     * @param string $requestContent
45
     *
46
     * @return array Decoded content
47
     *
48
     * @throws JsonRpcParseErrorException
49
     */
50
    public function decode(string $requestContent) : array
51
    {
52
        $decodedContent = json_decode($requestContent, true);
53
54
        // Check if parsing is ok => Parse error
55
        if (JSON_ERROR_NONE !== json_last_error()) {
56
            throw new JsonRpcParseErrorException(
57
                $requestContent,
58
                json_last_error(),
59
                json_last_error_msg()
60
            );
61
        }
62
63
        // Content must be either an array (normal request) or an array of array (batch request)
64
        //  => so must be an array
65
        if (!is_array($decodedContent)) {
66
            throw new JsonRpcInvalidRequestException($requestContent);
67
        }
68
69
        return $decodedContent;
70
    }
71
72
    /**
73
     * @param array $decodedContent
74
     *
75
     * @return JsonRpcRawRequest
76
     */
77
    public function denormalize(array $decodedContent) : JsonRpcRawRequest
78
    {
79
        $isBatch = true;
80
        // Loop over each items
81
        // -> In case it's a valid batch request -> all keys will have numeric type -> iterations = Number of requests
82
        // -> In case it's a valid normal request -> all keys will have string type -> iterations = 1 (stopped on #1)
83
        // => Better performance for normal request (Probably most of requests)
84
        foreach ($decodedContent as $item) {
85
            // At least a key is a string (that do not contain an int)
86
            if (!is_int($item)) {
87
                $isBatch = false;
88
                break;
89
            }
90
        }
91
92
        $rawRequest = new JsonRpcRawRequest($isBatch);
93
94
        // convert to array in any cases for simpler use
95
        $itemList = $isBatch ? $decodedContent : [$decodedContent];
96
        foreach ($itemList as $item) {
97
            // Safely denormalize items
98
            try {
99
                $denormalizedItem = $this->requestDenormalizer->denormalize($item);
100
            } catch (\Exception $exception) {
101
                $denormalizedItem = $exception;
102
            }
103
104
            $rawRequest->addItem($denormalizedItem);
105
        }
106
107
        return $rawRequest;
108
    }
109
}
110