Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
77.05% covered (warning)
77.05%
47 / 61
62.50% covered (warning)
62.50%
5 / 8
CRAP
0.00% covered (danger)
0.00%
0 / 1
Validator
77.05% covered (warning)
77.05%
47 / 61
62.50% covered (warning)
62.50%
5 / 8
26.33
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
1 / 1
2
 loadSchemas
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
2
 isValid
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getErrors
85.71% covered (warning)
85.71%
6 / 7
0.00% covered (danger)
0.00%
0 / 1
3.03
 extractErrors
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
1 / 1
3
 getCustomMessage
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
4
 getOriginPointer
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
6
 getTranslatedPointer
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
20
1<?php
2
3namespace BO\Zmsentities\Schema;
4
5use Opis\JsonSchema\{Validator as OpisValidator, ValidationResult, Schema as OpisSchema};
6use Opis\JsonSchema\Resolvers\FormatResolver;
7use Opis\JsonSchema\Errors\ValidationError as OpisValidationError;
8
9class Validator
10{
11    protected $schemaObject;
12    protected $schemaData;
13    protected $locale;
14    protected $validator;
15    protected $validationResult;
16
17    public function __construct($data, Schema $schemaObject, $locale)
18    {
19        $this->schemaData = $data;
20        $this->schemaObject = $schemaObject;
21        $this->locale = $locale;
22        $this->validator = new OpisValidator();
23
24        $formats = $this->validator->parser()->getFormatResolver();
25        $formats->registerCallable("array", "sameValues", function (array $data): bool {
26            return count($data) === 2 && $data[0] === $data[1];
27        });
28
29        $this->loadSchemas();
30        $schemaJson = json_decode(json_encode($schemaObject->toJsonObject()));
31        $data = json_decode(json_encode($data));
32        $this->validationResult = $this->validator->validate($data, $schemaJson);
33    }
34
35    private function loadSchemas()
36    {
37        $schemaPath = realpath(dirname(__FILE__) . '/../../../schema') . '/';
38        $this->validator->resolver()->registerPrefix('schema://', $schemaPath);
39        $schemaFiles = glob($schemaPath . '*.json');
40
41        foreach ($schemaFiles as $schemaFile) {
42            $schemaContent = file_get_contents($schemaFile);
43            $schemaName = 'schema://' . basename($schemaFile);
44            $this->validator->resolver()->registerRaw($schemaContent, $schemaName);
45        }
46    }
47
48    public function isValid()
49    {
50        return $this->validationResult->isValid();
51    }
52
53    public function getErrors()
54    {
55        if ($this->validationResult->isValid()) {
56            return [];
57        }
58
59        $errorsReducedList = [];
60        $error = $this->validationResult->error();
61
62        if ($error) {
63            $errorsReducedList = $this->extractErrors($error);
64        }
65
66        return $errorsReducedList;
67    }
68
69    private function extractErrors(OpisValidationError $error)
70    {
71        $errors = [];
72
73        $errors[] = new OpisValidationError(
74            $error->keyword(),
75            $error->schema(),
76            $error->data(),
77            $this->getCustomMessage($error),
78            $error->args(),
79            []
80        );
81
82        foreach ($error->subErrors() as $subError) {
83            if ($subError instanceof OpisValidationError) {
84                $errors = array_merge($errors, $this->extractErrors($subError));
85            }
86        }
87
88        return $errors;
89    }
90
91    public function getCustomMessage(OpisValidationError $error)
92    {
93        $schemaData = $error->schema()->info()->data();
94        if (is_object($schemaData)) {
95            $schemaData = (array) $schemaData;
96        }
97        $property = new \BO\Zmsentities\Helper\Property($schemaData);
98
99        if (
100            isset($property['x-locale'][$this->locale]->messages[$error->keyword()])
101            && $property['x-locale'][$this->locale]->messages[$error->keyword()] !== null
102        ) {
103            return $property['x-locale'][$this->locale]->messages[$error->keyword()]->get();
104        }
105
106        return $error->message();
107    }
108
109    public static function getOriginPointer(OpisValidationError $error)
110    {
111        $dataInfo = $error->data();
112
113        if (empty($dataInfo->path())) {
114            return '/';
115        }
116
117        $pointer = '/' . implode('/', array_map('strval', $dataInfo->path()));
118
119        return $pointer;
120    }
121
122    public function getTranslatedPointer(OpisValidationError $error)
123    {
124        $schemaData = $error->schema()->info()->data();
125        if (is_object($schemaData)) {
126            $schemaData = (array) $schemaData;
127        }
128        $property = new \BO\Zmsentities\Helper\Property($schemaData);
129
130        if (
131            isset($property['x-locale'][$this->locale]->pointer)
132            && $property['x-locale'][$this->locale]->pointer !== null
133        ) {
134            return $property['x-locale'][$this->locale]->pointer->get(self::getOriginPointer($error));
135        }
136
137        return self::getOriginPointer($error);
138    }
139}