Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
33 / 33
100.00% covered (success)
100.00%
9 / 9
CRAP
100.00% covered (success)
100.00%
1 / 1
PublicationPageValidator
100.00% covered (success)
100.00%
33 / 33
100.00% covered (success)
100.00%
9 / 9
15
100.00% covered (success)
100.00%
1 / 1
 call
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 __construct
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 __invoke
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
2
 validate
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 errors
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 warnings
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
3
 validatedFields
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getResults
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
4
 getValidationRules
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3declare(strict_types=1);
4
5namespace Hyde\Publications\Actions;
6
7use Hyde\Markdown\Models\MarkdownDocument;
8use Hyde\Publications\Models\PublicationFieldDefinition;
9use Hyde\Publications\Models\PublicationType;
10use Illuminate\Contracts\Validation\Validator;
11use Illuminate\Support\Str;
12
13use function array_flip;
14use function array_merge;
15use function collect;
16use function implode;
17use function in_array;
18use function lcfirst;
19use function sprintf;
20use function validator;
21
22/**
23 * @see \Hyde\Publications\Testing\Feature\PublicationPageValidatorTest
24 */
25class PublicationPageValidator
26{
27    protected PublicationType $publicationType;
28    protected array $matter;
29
30    protected Validator $validator;
31
32    public static function call(PublicationType $publicationType, string $pageIdentifier): static
33    {
34        return (new self($publicationType, $pageIdentifier))->__invoke();
35    }
36
37    public function __construct(PublicationType $publicationType, string $pageIdentifier)
38    {
39        $this->publicationType = $publicationType;
40        $this->matter = MarkdownDocument::parse("{$publicationType->getDirectory()}/$pageIdentifier.md")->matter()->toArray();
41        unset($this->matter['__createdAt']);
42    }
43
44    /** @return $this */
45    public function __invoke(): static
46    {
47        $rules = [];
48        $input = [];
49
50        foreach ($this->publicationType->getFields() as $field) {
51            $rules[$field->name] = $this->getValidationRules($field);
52            $input[$field->name] = $this->matter[$field->name] ?? null;
53        }
54
55        $this->validator = validator($input, $rules);
56
57        return $this;
58    }
59
60    /** @throws \Illuminate\Validation\ValidationException */
61    public function validate(): void
62    {
63        $this->validator->validate();
64    }
65
66    /** @return array<int, string> */
67    public function errors(): array
68    {
69        return collect($this->validator->errors())->map(function (array $message): string {
70            return implode(', ', $message);
71        })->toArray();
72    }
73
74    public function warnings(): array
75    {
76        $warnings = [];
77
78        $fields = $this->publicationType->getFields()->pluck('name')->toArray();
79        foreach ($this->matter as $key => $value) {
80            if (! in_array($key, $fields)) {
81                $warnings[$key] = sprintf('The %s field is not defined in the publication type.', lcfirst(Str::title($key)));
82            }
83        }
84
85        return $warnings;
86    }
87
88    public function validatedFields(): array
89    {
90        return array_merge($this->matter, array_flip($this->publicationType->getFields()->pluck('name')->toArray()));
91    }
92
93    /** @return array<string, string> */
94    public function getResults(): array
95    {
96        $results = [];
97        $warnings = $this->warnings();
98        $errors = $this->errors();
99
100        foreach ($this->validatedFields() as $key => $value) {
101            if (isset($warnings[$key])) {
102                $results[$key] = "Warning: $warnings[$key]";
103            } elseif (isset($errors[$key])) {
104                $results[$key] = "Error: $errors[$key]";
105            } else {
106                $results[$key] = "Field $key passed.";
107            }
108        }
109
110        return $results;
111    }
112
113    protected function getValidationRules(PublicationFieldDefinition $field): array
114    {
115        return (new PublicationFieldValidator($this->publicationType, $field))->getValidationRules();
116    }
117}