JsonSchemaValidator::init()   C
last analyzed

Complexity

Conditions 8
Paths 96

Size

Total Lines 32
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 22
CRAP Score 8

Importance

Changes 2
Bugs 0 Features 2
Metric Value
c 2
b 0
f 2
dl 0
loc 32
ccs 22
cts 22
cp 1
rs 5.3846
cc 8
eloc 16
nc 96
nop 0
crap 8
1
<?php
2
namespace dstotijn\yii2jsv;
3
4
use JsonSchema\Uri\UriRetriever;
5
use JsonSchema\Validator as JSValidator;
6
use Yii;
7
use yii\base\InvalidConfigException;
8
use yii\validators\Validator;
9
10
/**
11
 * JsonSchemaValidator validates a value against a JSON Schema file.
12
 *
13
 * The URI of the schema file must be defined via the [[schema]] property.
14
 *
15
 * @author David Stotijn <[email protected]>
16
 */
17
class JsonSchemaValidator extends Validator
18
{
19
    /**
20
     * @var string The URI of the JSON schema file.
21
     */
22
    public $schema;
23
24
    /**
25
     * @var string User-defined error message used when the schema is missing.
26
     */
27
    public $schemaEmpty;
28
29
    /**
30
     * @var string User-defined error message used when the schema isn't a string.
31
     */
32
    public $schemaNotString;
33
34
    /**
35
     * @var string User-defined error message used when the value is not a string.
36
     */
37
    public $notString;
38
39
    /**
40
     * @var string User-defined error message used when the value is not a valid JSON string.
41
     */
42
    public $notJsonString;
43
44
    /**
45
     * @inheritdoc
46
     */
47 15
    public function init()
48
    {
49 15
        parent::init();
50
51 15
        if ($this->schemaEmpty === null) {
52 15
            $this->schemaEmpty = 'The "schema" property must be set.';
53 15
        }
54
55 15
        if ($this->schemaNotString === null) {
56 15
            $this->schemaNotString = 'The "schema" property must be a a string.';
57 15
        }
58
59 15
        if ($this->message === null) {
60 15
            $this->message = Yii::t('app', '{property}: {message}.');
61 15
        }
62
63 15
        if ($this->notString === null) {
64 15
            $this->notString = Yii::t('app', 'The value must be a string.');
65 15
        }
66
67 15
        if ($this->notJsonString === null) {
68 15
            $this->notJsonString = Yii::t('app', 'The value must be a valid JSON string.');
69 15
        }
70
71 15
        if (empty($this->schema)) {
72 2
            throw new InvalidConfigException($this->schemaEmpty);
73
        }
74
75 13
        if (!is_string($this->schema)) {
76 2
            throw new InvalidConfigException($this->schemaNotString);
77
        }
78 11
    }
79
80
    /**
81
     * @inheritdoc
82
     */
83 6
    public function validateAttribute($model, $attribute)
84
    {
85 6
        if (!is_string($model->$attribute)) {
86 2
            $this->addError($model, $attribute, $this->notString);
87 2
            return;
88
        }
89
90 4
        $value = json_decode($model->$attribute);
91 4
        if (json_last_error()) {
92 1
            $this->addError($model, $attribute, $this->notJsonString);
93 1
        }
94
95 4
        $retriever = new UriRetriever();
96 4
        $schema = $retriever->retrieve($this->schema);
97
98 4
        $validator = new JSValidator();
99 4
        $validator->check($value, $schema);
100
101 4
        if (!$validator->isValid()) {
102 3
            foreach ($validator->getErrors() as $error) {
103 3
                $this->addError(
104 3
                    $model,
105 3
                    $attribute,
106 3
                    $this->message,
107
                    [
108 3
                        'property' => $error['property'],
109 3
                        'message' => ucfirst($error['message']),
110
                    ]
111 3
                );
112 3
            }
113 3
        }
114 4
    }
115
116
    /**
117
     * Validates a value.
118
     *
119
     * @param string $value A JSON encoded string to validate.
120
     * @return array|null An array of error data, or null if the data is valid.
121
     */
122 5
    protected function validateValue($value)
123
    {
124 5
        if (!is_string($value)) {
125 1
            return [$this->notString, []];
126
        }
127
128 4
        $value = json_decode($value);
129 4
        if (json_last_error()) {
130 1
            return [$this->notJsonString, []];
131
        }
132
133 3
        $retriever = new UriRetriever();
134 3
        $schema = $retriever->retrieve($this->schema);
135
136 3
        $validator = new JSValidator();
137 3
        $validator->check($value, $schema);
138
139 3
        if (!$validator->isValid()) {
140 2
            $errors = $validator->getErrors();
141 2
            $error = reset($errors);
142 2
            return [$this->message, ['property' => $error['property'], 'message' => ucfirst($error['message'])]];
143
        }
144
145 1
        return null;
146
    }
147
}
148