Completed
Pull Request — master (#70)
by Yo
02:40
created

JsonRpcRequestDenormalizer::denormalize()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 17
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 9
nc 1
nop 1
dl 0
loc 17
ccs 10
cts 10
cp 1
crap 1
rs 9.9666
c 0
b 0
f 0
1
<?php
2
namespace Yoanm\JsonRpcServer\App\Serialization;
3
4
use Yoanm\JsonRpcServer\Domain\Exception\JsonRpcInvalidRequestException;
5
use Yoanm\JsonRpcServer\Domain\Model\JsonRpcRequest;
6
7
/**
8
 * Class JsonRpcRequestDenormalizer
9
 */
10
class JsonRpcRequestDenormalizer
11
{
12
    const KEY_JSON_RPC = 'jsonrpc';
13
    const KEY_ID = 'id';
14
    const KEY_METHOD = 'method';
15
    const KEY_PARAM_LIST = 'params';
16
17
    /**
18
     * @param mixed $item Should be an array
19
     *
20
     * @return JsonRpcRequest
21
     *
22
     * @throws JsonRpcInvalidRequestException
23
     */
24 9
    public function denormalize($item) : JsonRpcRequest
25
    {
26 9
        $this->validateArray($item, 'Item must be an array');
27
28
        // Validate json-rpc and method keys
29 9
        $this->validateRequiredKey($item, self::KEY_JSON_RPC);
30 8
        $this->validateRequiredKey($item, self::KEY_METHOD);
31
32 7
        $request = new JsonRpcRequest(
33 7
            $item[self::KEY_JSON_RPC],
34 7
            $item[self::KEY_METHOD]
35
        );
36
37 7
        $this->bindIdIfProvided($request, $item);
38 7
        $this->bindParamListIfProvided($request, $item);
39
40 4
        return $request;
41
    }
42
43
    /**
44
     * @param JsonRpcRequest $request
45
     * @param array $item
46
     *
47
     * @return void
48
     */
49 7
    protected function bindIdIfProvided(JsonRpcRequest $request, array $item) : void
50
    {
51
        /** If no id defined => request is a notification */
52 7
        if (isset($item[self::KEY_ID])) {
53 6
            $request->setId(
54 6
                $item[self::KEY_ID] == (string)((int)$item[self::KEY_ID])
55 2
                    ? (int)$item[self::KEY_ID] // Convert it in case it's a string containing an int
56 6
                    : (string)$item[self::KEY_ID] // Convert to string in all other cases
57
            );
58
        }
59 7
    }
60
61
    /**
62
     * @param JsonRpcRequest $request
63
     * @param array          $item
64
     *
65
     * @return void
66
     *
67
     * @throws JsonRpcInvalidRequestException
68
     */
69 7
    protected function bindParamListIfProvided(JsonRpcRequest $request, array $item) : void
70
    {
71 7
        if (isset($item[self::KEY_PARAM_LIST])) {
72 4
            $this->validateArray($item[self::KEY_PARAM_LIST], 'Parameter list must be an array');
73 1
            $request->setParamList($item[self::KEY_PARAM_LIST]);
74
        }
75 4
    }
76
77
    /**
78
     * @param mixed  $value
79
     * @param string $errorDescription
80
     *
81
     * @return void
82
     *
83
     * @throws JsonRpcInvalidRequestException
84
     */
85 9
    private function validateArray($value, string $errorDescription) : void
86
    {
87 9
        if (!is_array($value)) {
88 3
            throw new JsonRpcInvalidRequestException($value, $errorDescription);
89
        }
90 9
    }
91
92
    /**
93
     * @param array  $item
94
     * @param string $key
95
     *
96
     * @return void
97
     *
98
     * @throws JsonRpcInvalidRequestException
99
     */
100 9
    private function validateRequiredKey(array $item, string $key) : void
101
    {
102 9
        if (!isset($item[$key])) {
103 2
            throw new JsonRpcInvalidRequestException(
104 2
                $item,
105 2
                sprintf('"%s" is a required key', $key)
106
            );
107
        }
108 8
    }
109
}
110