Passed
Push — master ( bc0996...c35245 )
by Bruno
05:47
created

Model::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
namespace Formularium;
4
5
use Formularium\Exception\Exception;
6
7
class Model
8
{
9
    /**
10
     * @var string
11
     */
12
    protected $name;
13
14
    /**
15
     * @var Field[]
16
     */
17
    protected $fields;
18
19
    /**
20
     *
21
     * @param string $name
22
     * @throws Exception
23
     */
24 4
    protected function __construct(string $name = '')
25
    {
26 4
        $this->name = $name;
27 4
    }
28
29
    /**
30
     * Loads model from JSON file.
31
     *
32
     * @param array $struct
33
     * @return Model
34
     */
35
    public static function fromStruct(array $struct): Model
36
    {
37
        $m = new self('');
38
        $m->parseStruct($struct);
39
        return $m;
40
    }
41
42
    /**
43
     * Loads model from JSON file.
44
     *
45
     * @param string $name The JSON filename.
46
     * @return Model
47
     */
48
    public static function fromJSONFile(string $name): Model
49
    {
50
        $json = file_get_contents($name); // TODO: path
51
        if ($json === false) {
52
            throw new Exception('File not found');
53
        }
54
        return static::fromJSON($json);
55
    }
56
57
    /**
58
     * Loads model from JSON string
59
     *
60
     * @param string $json The JSON string.
61
     * @return Model
62
     */
63 5
    public static function fromJSON(string $json): Model
64
    {
65 5
        $data = \json_decode($json, true);
66 5
        if ($data === null) {
67 1
            throw new Exception('Invalid JSON format');
68
        }
69 4
        $m = new self('');
70 4
        $m->parseStruct($data);
71 1
        return $m;
72
    }
73
74 1
    public function getName(): string
75
    {
76 1
        return $this->name;
77
    }
78
79 1
    public function getFields(): array
80
    {
81 1
        return $this->fields;
82
    }
83
84
    /**
85
     * Validates a set of data against this model.
86
     *
87
     * @param array $data A field name => data array.
88
     * @return array
89
     */
90
    public function validate(array $data): array
91
    {
92
        $validate = [];
93
        $errors = [];
94
        foreach ($data as $name => $d) {
95
            if (!array_key_exists($name, $this->fields)) {
96
                $errors[$name] = "Field $name does not exist in this model";
97
                continue;
98
            }
99
            $field = $this->fields[$name];
100
            try {
101
                $validate[$name] = $field->getDatatype()->validate($d, $field);
102
            } catch (Exception $e) {
103
                $errors[$name] = $e->getMessage();
104
            }
105
        }
106
        foreach ($this->fields as $name => $field) {
107
            if (($field->getValidators()[Datatype::REQUIRED] ?? false) && !array_key_exists($name, $validate)) {
108
                $errors[$name] = "Field $name is missing";
109
            }
110
        }
111
        return ['validated' => $validate, 'errors' => $errors];
112
    }
113
114
    /**
115
     * Renders a readonly view of the model with given data.
116
     *
117
     * @param array $modelData
118
     * @return string
119
     */
120
    public function viewable(array $modelData): string
121
    {
122
        return FrameworkComposer::viewable($this, $modelData);
123
    }
124
125
    /**
126 4
     * Renders a form view of the model with given data.
127
     *
128 4
     * @param array $modelData
129 1
     * @return string
130
     */
131 3
    public function editable(array $modelData = []): string
132 1
    {
133
        return FrameworkComposer::editable($this, $modelData);
134 2
    }
135 2
136 2
    /**
137
     * Parses struct
138 1
     *
139
     * @param array $data
140
     * @throws Exception
141
     * @return void
142
     */
143
    protected function parseStruct(array $data)
144
    {
145
        if (!array_key_exists('name', $data)) {
146
            throw new Exception('Missing name in model');
147
        }
148
        if (!array_key_exists('fields', $data)) {
149
            throw new Exception('Missing fields in model');
150
        }
151
        $this->name = $data['name'];
152
        foreach ($data['fields'] as $fieldName => $fieldData) {
153
            $this->fields[$fieldName] = Field::getFromData($fieldName, $fieldData);
154
        }
155
    }
156
}
157