Completed
Pull Request — master (#7)
by Igor
04:25
created

denormalizeBatchResponses()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 5
c 0
b 0
f 0
dl 0
loc 10
rs 10
cc 2
nc 2
nop 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\Response\ResponseObject;
14
use Strider2038\JsonRpcClient\Response\ResponseObjectInterface;
15
use Symfony\Component\Serializer\Exception\LogicException;
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 DelegatingResponseDenormalizer implements DenormalizerInterface, DenormalizerAwareInterface, CacheableSupportsMethodInterface
26
{
27
    use DenormalizerAwareTrait;
28
29
    public function hasCacheableSupportsMethod(): bool
30
    {
31
        return true;
32
    }
33
34
    public function supportsDenormalization($data, $type, $format = null): bool
35
    {
36
        return ResponseObjectInterface::class === $type;
37
    }
38
39
    public function denormalize($data, $type, $format = null, array $context = [])
40
    {
41
        if (!is_array($data)) {
42
            throw new UnexpectedValueException('Denormalization data is expected to be an array');
43
        }
44
45
        $response = null;
46
47
        if (array_key_exists('jsonrpc', $data)) {
48
            $response = $this->denormalizer->denormalize($data, ResponseObject::class, $format, $context);
49
        } else {
50
            $response = $this->denormalizeBatchResponses($data, $format, $context);
51
        }
52
53
        return $response;
54
    }
55
56
    private function denormalizeBatchResponses($data, $format, array $context): array
57
    {
58
        $responses = [];
59
60
        foreach ($data as $singleResponse) {
61
            $singleContext = $this->createResponseContext($singleResponse, $context);
62
            $responses[] = $this->denormalizer->denormalize($singleResponse, ResponseObject::class, $format, $singleContext);
63
        }
64
65
        return $responses;
66
    }
67
68
    private function createResponseContext(array $response, array $context): array
69
    {
70
        if (!array_key_exists('id', $response)) {
71
            throw new LogicException('Response has no id');
72
        }
73
74
        $id = $response['id'];
75
76
        if (!array_key_exists($id, $context['json_rpc']['requests'])) {
77
            throw new LogicException(sprintf('Response id "%s" is not matching any request id', $id));
78
        }
79
80
        $singleContext = $context;
81
        $singleContext['json_rpc'] = [
82
            'request' => $context['json_rpc']['requests'][$id],
83
        ];
84
85
        return $singleContext;
86
    }
87
}
88