Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
100.00% |
40 / 40 |
|
100.00% |
11 / 11 |
CRAP | |
100.00% |
1 / 1 |
PublicationSchemaValidator | |
100.00% |
40 / 40 |
|
100.00% |
11 / 11 |
14 | |
100.00% |
1 / 1 |
call | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
__construct | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
__invoke | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
1 | |||
validate | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
errors | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
1 | |||
makePropertyValidator | |
100.00% |
12 / 12 |
|
100.00% |
1 / 1 |
1 | |||
makeFieldsValidators | |
100.00% |
8 / 8 |
|
100.00% |
1 / 1 |
3 | |||
evaluateFieldValidators | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
1 | |||
validateFields | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
2 | |||
makeValidator | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
mapRulesInput | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
1 |
1 | <?php |
2 | |
3 | declare(strict_types=1); |
4 | |
5 | namespace Hyde\Publications\Actions; |
6 | |
7 | use stdClass; |
8 | use Hyde\Facades\Filesystem; |
9 | use Illuminate\Contracts\Validation\Validator; |
10 | |
11 | use function collect; |
12 | use function is_array; |
13 | use function validator; |
14 | use function json_decode; |
15 | |
16 | /** |
17 | * @see \Hyde\Publications\Testing\Feature\PublicationSchemaValidatorTest |
18 | */ |
19 | class PublicationSchemaValidator |
20 | { |
21 | protected stdClass $schema; |
22 | |
23 | protected Validator $schemaValidator; |
24 | protected array $fieldValidators = []; |
25 | |
26 | public static function call(string $publicationTypeName): static |
27 | { |
28 | return (new self($publicationTypeName))->__invoke(); |
29 | } |
30 | |
31 | public function __construct(string $publicationTypeName) |
32 | { |
33 | $this->schema = json_decode(Filesystem::getContents("$publicationTypeName/schema.json")); |
34 | } |
35 | |
36 | /** @return $this */ |
37 | public function __invoke(): static |
38 | { |
39 | $this->makePropertyValidator(); |
40 | $this->makeFieldsValidators(); |
41 | |
42 | return $this; |
43 | } |
44 | |
45 | /** @throws \Illuminate\Validation\ValidationException */ |
46 | public function validate(): void |
47 | { |
48 | $this->schemaValidator->validate(); |
49 | $this->validateFields(); |
50 | } |
51 | |
52 | /** @return array<string, Validator|array */ |
53 | public function errors(): array |
54 | { |
55 | return [ |
56 | 'schema' => $this->schemaValidator->errors()->all(), |
57 | 'fields' => $this->evaluateFieldValidators(), |
58 | ]; |
59 | } |
60 | |
61 | protected function makePropertyValidator(): void |
62 | { |
63 | $rules = [ |
64 | 'name' => 'required|string', |
65 | 'canonicalField' => 'nullable|string', |
66 | 'detailTemplate' => 'nullable|string', |
67 | 'listTemplate' => 'nullable|string', |
68 | 'sortField' => 'nullable|string', |
69 | 'sortAscending' => 'nullable|boolean', |
70 | 'pageSize' => 'nullable|integer', |
71 | 'fields' => 'nullable|array', |
72 | 'directory' => 'nullable|prohibited', |
73 | ]; |
74 | |
75 | $this->schemaValidator = $this->makeValidator($rules, $this->schema); |
76 | } |
77 | |
78 | protected function makeFieldsValidators(): void |
79 | { |
80 | $rules = [ |
81 | 'type' => 'required|string', |
82 | 'name' => 'required|string', |
83 | 'rules' => 'nullable|array', |
84 | ]; |
85 | |
86 | if (is_array($this->schema->fields)) { |
87 | foreach ($this->schema->fields as $field) { |
88 | $this->fieldValidators[] = $this->makeValidator($rules, $field); |
89 | } |
90 | } |
91 | } |
92 | |
93 | /** @return array<array-key, array<array-key, string>> */ |
94 | protected function evaluateFieldValidators(): array |
95 | { |
96 | return collect($this->fieldValidators)->map(function (Validator $validator): array { |
97 | return $validator->errors()->all(); |
98 | })->all(); |
99 | } |
100 | |
101 | protected function validateFields(): void |
102 | { |
103 | foreach ($this->fieldValidators as $validator) { |
104 | $validator->validate(); |
105 | } |
106 | } |
107 | |
108 | protected function makeValidator(array $rules, stdClass $input): Validator |
109 | { |
110 | return validator($this->mapRulesInput($rules, $input), $rules); |
111 | } |
112 | |
113 | protected function mapRulesInput(array $rules, stdClass $input): array |
114 | { |
115 | return collect($rules)->mapWithKeys(function (string $rule, string $key) use ($input): array { |
116 | return [$key => $input->{$key} ?? null]; |
117 | })->all(); |
118 | } |
119 | } |