ResponseObjectDenormalizer::denormalize()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 17
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 9
c 1
b 0
f 0
dl 0
loc 17
ccs 10
cts 10
cp 1
rs 9.9666
cc 3
nc 3
nop 4
crap 3
1
<?php
2
/*
3
 * This file is part of JSON RPC Client.
4
 *
5
 * (c) Igor Lazarev <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace Strider2038\JsonRpcClient\Bridge\Symfony\Serialization;
12
13
use Strider2038\JsonRpcClient\Request\RequestObject;
14
use Strider2038\JsonRpcClient\Response\ErrorObject;
15
use Strider2038\JsonRpcClient\Response\ResponseObject;
16
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
17
use Symfony\Component\Serializer\Normalizer\CacheableSupportsMethodInterface;
18
use Symfony\Component\Serializer\Normalizer\DenormalizerAwareInterface;
19
use Symfony\Component\Serializer\Normalizer\DenormalizerAwareTrait;
20
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
21
22
/**
23
 * @author Igor Lazarev <[email protected]>
24
 */
25
class ResponseObjectDenormalizer implements DenormalizerInterface, DenormalizerAwareInterface, CacheableSupportsMethodInterface
26
{
27
    use DenormalizerAwareTrait;
28
29 5
    public function hasCacheableSupportsMethod(): bool
30
    {
31 5
        return true;
32
    }
33
34 5
    public function supportsDenormalization($data, $type, $format = null): bool
35
    {
36 5
        return ResponseObject::class === $type;
37
    }
38
39 11
    public function denormalize($data, $type, $format = null, array $context = []): ResponseObject
40
    {
41 11
        if (!is_array($data)) {
42 1
            throw new UnexpectedValueException('Denormalization data is expected to be an array');
43
        }
44
45 10
        $response = new ResponseObject(
46 10
            $data['jsonrpc'] ?? '',
47 10
            $this->denormalizeResult($data, $format, $context),
48 10
            $data['id'] ?? null
49
        );
50
51 10
        if (array_key_exists('error', $data)) {
52 6
            $response->setError($this->denormalizeError($data, $format, $context));
53
        }
54
55 10
        return $response;
56
    }
57
58 10
    private function denormalizeResult($data, $format, array $context)
59
    {
60 10
        $result = $data['result'] ?? null;
61
62 10
        $request = $context['json_rpc']['request'] ?? null;
63
64 10
        if ($request instanceof RequestObject) {
65 6
            $method = $request->getMethod();
66
67 6
            $resultTypesByMethods = $context['json_rpc']['result_types_by_methods'] ?? [];
68
69 6
            if (null !== $result && array_key_exists($method, $resultTypesByMethods)) {
70 3
                $resultType = $resultTypesByMethods[$method];
71
72 3
                $result = $this->denormalizer->denormalize($result, $resultType, $format, $context);
73
            }
74
        }
75
76 10
        return $result;
77
    }
78
79 6
    private function denormalizeError($data, $format, array $context): ErrorObject
80
    {
81 6
        return new ErrorObject(
82 6
            $data['error']['code'] ?? 0,
83 6
            $data['error']['message'] ?? 'unknown error',
84 6
            $this->denormalizeErrorData($data['error']['data'] ?? null, $format, $context)
85
        );
86
    }
87
88 6
    private function denormalizeErrorData($errorData, $format, array $context)
89
    {
90 6
        $errorType = $this->detectErrorType($context);
91
92 6
        if (null !== $errorData && null !== $errorType) {
93 4
            $errorData = $this->denormalizer->denormalize($errorData, $errorType, $format, $context);
94
        }
95
96 6
        return $errorData;
97
    }
98
99 6
    private function detectErrorType(array $context): ?string
100
    {
101 6
        $errorType = $context['json_rpc']['default_error_type'] ?? null;
102
103 6
        $request = $context['json_rpc']['request'] ?? null;
104 6
        if ($request instanceof RequestObject) {
105 3
            $errorType = $context['json_rpc']['error_types_by_methods'][$request->getMethod()] ?? $errorType;
106
        }
107
108 6
        return $errorType;
109
    }
110
}
111