Passed
Push — master ( 0d7615...e53071 )
by Csaba
38s
created

SchemaValidator::setDefault()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 14
ccs 8
cts 8
cp 1
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 8
nc 2
nop 2
crap 2
1
<?php
2
namespace Fathomminds\Rest\Schema;
3
4
use Fathomminds\Rest\Schema\TypeValidators\ValidatorFactory;
5
use Fathomminds\Rest\Exceptions\RestException;
6
7
class SchemaValidator
8
{
9
    protected $fields = [];
10
11 6
    public function validate($resource)
12
    {
13 6
        $this->expectObject($resource);
14 6
        $errors = array_merge(
15 6
            $this->validateRequiredFields($resource),
16 6
            $this->validateExtraneousFields($resource),
17 6
            $this->validateFieldTypes($resource)
18
        );
19 6
        if (!empty($errors)) {
20 5
            throw new RestException(
21 5
                'Invalid structure',
22
                [
23 5
                    'schema' => get_class($resource),
24 5
                    'errors' => $errors,
25
                ]
26
            );
27
        }
28 1
    }
29
30 7
    private function expectObject($resource)
31
    {
32 7
        if (gettype($resource) !== 'object') {
33 1
            throw new RestException(
34 1
                'Object expected',
35
                [
36 1
                    'schema' => static::class,
37 1
                    'type' => gettype($resource),
38
                ]
39
            );
40
        }
41 6
    }
42
43 6
    private function validateRequiredFields($resource)
44
    {
45 6
        $errors = [];
46 6
        $requiredFields = $this->getRequiredFields($resource);
47 6
        foreach ($requiredFields as $fieldName) {
48 6
            if (!property_exists($resource, $fieldName)) {
49 6
                $errors[$fieldName] = 'Missing required field';
50
            }
51
        }
52 6
        return $errors;
53
    }
54
55 6
    private function validateExtraneousFields($resource)
56
    {
57 6
        $errors = [];
58 6
        foreach (array_keys(get_object_vars($resource)) as $fieldName) {
59 4
            if (!isset($resource->schema()[$fieldName])) {
60 4
                $errors[$fieldName] = 'Extraneous field';
61
            }
62
        }
63 6
        return $errors;
64
    }
65
66 6
    private function validateFieldTypes($resource)
67
    {
68 6
        $validatorFactory = new ValidatorFactory;
69 6
        $errors = [];
70 6
        foreach ($resource->schema() as $fieldName => $rules) {
71 6
            if (property_exists($resource, $fieldName)) {
72
                try {
73 4
                    $validatorFactory->create($rules)->validate($resource->{$fieldName});
74 1
                } catch (RestException $ex) {
75 1
                    $errors[$fieldName]['error'] = $ex->getMessage();
76 6
                    $errors[$fieldName]['details'] = $ex->getDetails();
77
                }
78
            }
79
        }
80 6
        return $errors;
81
    }
82
83 15
    private function filterFields($resource, $paramKey, $paramValue)
84
    {
85 15
        $fields = [];
86 15
        foreach ($resource->schema() as $fieldName => $params) {
87 15
            if (isset($params[$paramKey]) && $params[$paramKey] == $paramValue) {
88 15
                $fields[] = $fieldName;
89
            }
90
        }
91 15
        return $fields;
92
    }
93
94 2
    public function getFields($resource)
95
    {
96 2
        return $resource->schema();
97
    }
98
99 6
    public function getRequiredFields($resource)
100
    {
101 6
        return $this->filterFields($resource, 'required', true);
102
    }
103
104 9
    public function getUniqueFields($resource)
105
    {
106 9
        return $this->filterFields($resource, 'unique', true);
107
    }
108
}
109