Completed
Push — master ( 0ed9d0...0089ee )
by Adam
01:40
created

RequestBuilder::assembleJsonSchemaValidator()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 8
ccs 4
cts 4
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 4
nc 1
nop 1
crap 1
1
<?php
2
3
namespace PhpJsonRpc\Server\Request;
4
5
use PhpJsonRpc\Server\Error\ParseError;
6
use PhpJsonRpc\Server\Error\InvalidRequest;
7
use JsonSchema\Validator as JsonSchemaValidator;
8
9
class RequestBuilder
10
{
11
    const JSON_SCHEMA_PATH = '/../../jsonschemas/request.json';
12
13
    /**
14
     * @var mixed should be object or array
15
     */
16
    protected $decodedJson;
17
18
    /**
19
     * @param string $jsonRpcMessage
20
     *
21
     * @throws InvalidRequest
22
     * @throws ParseError
23
     */
24 33
    public function __construct($jsonRpcMessage)
25
    {
26 33
        $this->decodedJson  = json_decode($jsonRpcMessage);
27 33
        $jsonLastError      = json_last_error();
28
29 33
        if ($jsonLastError !== JSON_ERROR_NONE) {
30 3
            throw new ParseError($this->buildJsonErrorMessage($jsonLastError));
31
        }
32
33 30
        if ($this->isBatchRequest() && !$this->decodedJson()) {
34 3
            throw new InvalidRequest;
35
        }
36 27
    }
37
38
    /**
39
     * @return bool
40
     */
41 30
    public function isBatchRequest()
42 3
    {
43 30
        return is_array($this->decodedJson);
44
    }
45
46
    /**
47
     * @return mixed should be object or array
48
     */
49 30
    public function decodedJson()
50
    {
51 30
        return $this->decodedJson;
52
    }
53
54
    /**
55
     * @param object $jsonObject
56
     *
57
     * @return AbstractRequest NotificationRequest|Request
58
     *
59
     * @throws InvalidRequest
60
     */
61 27
    public function buildRequest($jsonObject)
62
    {
63 27
        $jsonSchemaValidator = $this->assembleJsonSchemaValidator($jsonObject);
64
65 27
        if ($jsonSchemaValidator->isValid() === false) {
66 9
            throw new InvalidRequest($jsonSchemaValidator->getErrors());
67
        }
68
69 21
        if (property_exists($jsonObject, 'id')) {
70 15
            return new Request($jsonObject);
71
        }
72
73 9
        return new NotificationRequest($jsonObject);
74
    }
75
76
    /**
77
     * @param mixed $jsonDecodedMessage
78
     *
79
     * @return JsonSchemaValidator
80
     */
81 27
    protected function assembleJsonSchemaValidator($jsonDecodedMessage)
82
    {
83 27
        $validator = new JsonSchemaValidator;
84
85 27
        $validator->check($jsonDecodedMessage, (object)['$ref' => 'file://' . __DIR__ . self::JSON_SCHEMA_PATH]);
86
87 27
        return $validator;
88
    }
89
90
    /**
91
     * @param int $jsonLastError
92
     *
93
     * @return string
94
     */
95 3
    protected function buildJsonErrorMessage($jsonLastError)
96
    {
97 3
        $message = 'Unknown error';
98
99
        switch ($jsonLastError) {
100 3
            case JSON_ERROR_NONE:
101
                $message = 'No errors';
102
                break;
103 3
            case JSON_ERROR_DEPTH:
104
                $message = 'Maximum stack depth exceeded';
105
                break;
106 3
            case JSON_ERROR_STATE_MISMATCH:
107
                $message = 'Underflow or the modes mismatch';
108
                break;
109 3
            case JSON_ERROR_CTRL_CHAR:
110
                $message = 'Unexpected control character found';
111
                break;
112 3
            case JSON_ERROR_SYNTAX:
113 3
                $message = 'Syntax error, malformed JSON';
114 3
                break;
115
            case JSON_ERROR_UTF8:
116
                $message = 'Malformed UTF-8 characters, possibly incorrectly encoded';
117
                break;
118
        }
119
120 3
        return $message;
121
    }
122
}
123