Completed
Push — master ( b10a48...29cde4 )
by Ori
05:27
created

Schema::validate()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 13
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 13
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 9
nc 3
nop 1
1
<?php
2
namespace frictionlessdata\tableschema;
3
4
/**
5
 *  Table Schema representation.
6
 *  Loads and validates a Table Schema descriptor from a descriptor / path to file / url containing the descriptor
7
 */
8
class Schema
9
{
10
    /**
11
     * Schema constructor.
12
     * @param mixed $descriptor
13
     * @throws Exceptions\SchemaLoadException
14
     * @throws Exceptions\SchemaValidationFailedException
15
     */
16
    public function __construct($descriptor)
17
    {
18
        if (Utils::isJsonString($descriptor)) {
19
            // it's a json encoded string
20
            try {
21
                $this->descriptor = json_decode($descriptor);
22
            } catch (\Exception $e) {
23
                throw new Exceptions\SchemaLoadException($descriptor, null, $e->getMessage());
24
            }
25
        } elseif (is_string($descriptor)) {
26
            // it's a url or file path
27
            $descriptorSource = $descriptor;
28
            try {
29
                $descriptor = file_get_contents($descriptorSource);
30
            } catch (\Exception $e) {
31
                throw new Exceptions\SchemaLoadException(null, $descriptorSource, $e->getMessage());
32
            }
33
            try {
34
                $this->descriptor = json_decode($descriptor);
35
            } catch (\Exception $e) {
36
                throw new Exceptions\SchemaLoadException($descriptor, $descriptorSource, $e->getMessage());
37
            }
38
        } else {
39
            $this->descriptor = $descriptor;
40
        }
41
        if (!is_object($this->descriptor())) {
42
            throw new Exceptions\SchemaLoadException($descriptor, null, "descriptor must be an object");
43
        }
44
        $validationErrors = SchemaValidator::validate($this->descriptor());
45
        if (count($validationErrors) > 0) {
46
            throw new Exceptions\SchemaValidationFailedException($validationErrors);
47
        };
48
    }
49
50
    /**
51
     * loads and validates the given descriptor source (php object / string / path to file / url)
52
     * returns an array of validation error objects
53
     * @param mixed $descriptor
54
     * @return array
55
     */
56
    public static function validate($descriptor)
57
    {
58
        try {
59
            new static($descriptor);
60
            return [];
61
        } catch (Exceptions\SchemaLoadException $e) {
62
            return [
63
                new SchemaValidationError(SchemaValidationError::LOAD_FAILED, $e->getMessage())
64
            ];
65
        } catch (Exceptions\SchemaValidationFailedException $e) {
66
            return $e->validationErrors;
67
        }
68
    }
69
70
    /**
71
     * @return object
72
     */
73
    public function descriptor()
74
    {
75
        return $this->descriptor;
76
    }
77
78
    public function fields()
79
    {
80
        $fields = [];
81
        foreach ($this->descriptor()->fields as $fieldDescriptor) {
82
            $field = Fields\FieldsFactory::field($fieldDescriptor);
83
            $fields[$field->name()] = $field;
84
        }
85
        return $fields;
86
    }
87
88
    /**
89
     * @param mixed[] $row
90
     * @return mixed[]
91
     * @throws Exceptions\FieldValidationException
92
     */
93
    public function castRow($row)
94
    {
95
        $outRow = [];
96
        $validationErrors = [];
97
        foreach ($this->fields() as $fieldName => $field) {
98
            $value = array_key_exists($fieldName, $row) ? $row[$fieldName] : null;
99
            try {
100
                $outRow[$fieldName] = $field->castValue($value);
101
            } catch (Exceptions\FieldValidationException $e) {
102
                $validationErrors = array_merge($validationErrors, $e->validationErrors);
103
            }
104
        }
105
        if (count($validationErrors) > 0) {
106
            throw new Exceptions\FieldValidationException($validationErrors);
107
        }
108
        return $outRow;
109
    }
110
111
    /**
112
     * @param array $row
113
     * @return SchemaValidationError[]
114
     */
115
    public function validateRow($row)
116
    {
117
        try {
118
            $this->castRow($row);
119
            return [];
120
        } catch (Exceptions\FieldValidationException $e) {
121
            return $e->validationErrors;
122
        }
123
    }
124
125
    protected $descriptor;
126
}