Completed
Pull Request — feature/app (#2)
by Yo
01:57
created

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