Failed Conditions
Pull Request — release/3.0.0-dev (#32)
by Yo
01:59
created

JsonRpcCallDenormalizer::guessBatchOrNot()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 16
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
cc 3
eloc 6
nc 3
nop 1
dl 0
loc 16
ccs 0
cts 7
cp 0
crap 12
rs 9.4285
c 0
b 0
f 0
1
<?php
2
namespace Yoanm\JsonRpcServer\App\Serialization;
3
4
use Yoanm\JsonRpcServer\Domain\Model\JsonRpcCall;
5
6
/**
7
 * Class JsonRpcCallDenormalizer
8
 */
9
class JsonRpcCallDenormalizer
10
{
11
    /** @var JsonRpcRequestDenormalizer */
12
    private $requestDenormalizer;
13
14
    /**
15
     * @param JsonRpcRequestDenormalizer $requestDenormalizer
16
     */
17
    public function __construct(JsonRpcRequestDenormalizer $requestDenormalizer)
18
    {
19
        $this->requestDenormalizer = $requestDenormalizer;
20
    }
21
22
    /**
23
     * @param array $decodedContent
24
     *
25
     * @return JsonRpcCall
26
     *
27
     * @throws \Exception
28
     */
29
    public function denormalize(array $decodedContent) : JsonRpcCall
30
    {
31
        $jsonRpcCall = new JsonRpcCall(
32
            $this->guessBatchOrNot($decodedContent)
33
        );
34
35
        $this->populateItem($jsonRpcCall, $decodedContent);
36
37
        return $jsonRpcCall;
38
    }
39
40
    /**
41
     * @param array $decodedContent
42
     *
43
     * @return bool
44
     */
45
    private function guessBatchOrNot(array $decodedContent) : bool
46
    {
47
        $isBatch = (0 !== count($decodedContent));
48
        // Loop over each items
49
        // -> In case it's a valid batch request -> all keys will have numeric type -> iterations = Number of requests
50
        // -> In case it's a valid normal request -> all keys will have string type -> iterations = 1 (stopped on #1)
51
        // => Better performance for normal request (Probably most of requests)
52
        foreach ($decodedContent as $key => $item) {
53
            // At least a key is a string (that do not contain an int)
54
            if (!is_int($key)) {
55
                $isBatch = false;
56
                break;
57
            }
58
        }
59
60
        return $isBatch;
61
    }
62
63
    /**
64
     * @param JsonRpcCall $jsonRpcCall
65
     * @param array       $decodedContent
66
     *
67
     * @throws \Exception
68
     */
69
    private function populateItem(JsonRpcCall $jsonRpcCall, array $decodedContent)
70
    {
71
        // convert to array in any cases for simpler use
72
        $itemList = $jsonRpcCall->isBatch() ? $decodedContent : [$decodedContent];
73
        foreach ($itemList as $itemPosition => $item) {
74
            // Safely denormalize items
75
            try {
76
                $item = $this->requestDenormalizer->denormalize($item);
77
78
                $jsonRpcCall->addRequestItem($item);
79
            } catch (\Exception $exception) {
80
                if (false === $jsonRpcCall->isBatch()) {
81
                    // If it's not a batch call, throw the exception
82
                    throw $exception;
83
                }
84
                // Else populate the item (exception will be managed later
85
                $jsonRpcCall->addExceptionItem($exception);
86
            }
87
        }
88
    }
89
}
90