Passed
Push — master ( 05b645...e6fae1 )
by Andreas
10:21
created

schemadb   A

Complexity

Total Complexity 28

Size/Duplication

Total Lines 130
Duplicated Lines 0 %

Test Coverage

Coverage 44.44%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 58
dl 0
loc 130
ccs 28
cts 63
cp 0.4444
rs 10
c 1
b 0
f 0
wmc 28

9 Methods

Rating   Name   Duplication   Size   Complexity  
A from_path() 0 3 1
A add() 0 4 1
A all() 0 3 1
A get() 0 6 2
C check_inheritance() 0 68 16
A has() 0 3 1
A load_from_path() 0 7 2
A get_first() 0 6 2
A __construct() 0 5 2
1
<?php
2
/**
3
 * @copyright CONTENT CONTROL GmbH, http://www.contentcontrol-berlin.de
4
 */
5
6
namespace midcom\datamanager;
7
8
use midcom_error;
9
use midcom_helper_misc;
10
11
/**
12
 * Experimental schemadb class
13
 */
14
class schemadb
15
{
16
    private array $schemas = [];
17
18 170
    public static function from_path(string $path) : self
19
    {
20 170
        return new static(static::load_from_path($path));
21
    }
22
23 170
    private static function load_from_path(string $path) : array
24
    {
25 170
        if (str_ends_with($path, '.php')) {
26 3
            return include midcom_helper_misc::resolve_path($path);
27
        }
28 167
        $data = midcom_helper_misc::get_snippet_content($path);
29 167
        return midcom_helper_misc::parse_config($data, $path);
30
    }
31
32 192
    public function __construct(array $data = [])
33
    {
34 192
        $this->check_inheritance($data);
35 192
        foreach ($data as $name => $config) {
36 189
            $this->add($name, new schema($config));
37
        }
38
    }
39
40 192
    private function check_inheritance(array &$data)
41
    {
42 192
        foreach ($data as $schema_name => $schema) {
43 189
            if (!isset($schema['extends'])) {
44 189
                continue;
45
            }
46
47
            // Default extended schema is with the same name
48
            $extended_schema_name = $schema_name;
49
            $path = '';
50
51
            if (is_array($schema['extends'])) {
52
                if (isset($schema['extends']['path'])) {
53
                    $path = $schema['extends']['path'];
54
                }
55
56
                // Override schema name
57
                if (isset($schema['extends']['name'])) {
58
                    $extended_schema_name = $schema['extends']['name'];
59
                }
60
            } elseif (isset($data[$schema['extends']])) {
61
                $schema['extends'] = [
62
                    'name' => $schema['extends'],
63
                ];
64
            } else {
65
                $path = $schema['extends'];
66
            }
67
68
            if ($path === '') {
69
                // Infinite loop, set an UI message and stop executing
70
                if (   !isset($schema['extends']['name'])
71
                    || $schema['extends']['name'] === $schema_name) {
72
                    throw new midcom_error('schema ' . $schema_name . ' extends itself');
73
                }
74
                $extended_schema_name = $schema['extends']['name'];
75
                $extended_schemadb = [$extended_schema_name => $data[$extended_schema_name]];
76
            } else {
77
                $extended_schemadb = static::load_from_path($path);
78
                if (!isset($extended_schemadb[$extended_schema_name])) {
79
                    throw new midcom_error('extended schema ' . $path . ':' . $schema_name . ' was not found');
80
                }
81
            }
82
83
            // Override the extended schema with fields from the new schema
84
            foreach ($schema as $key => $value) {
85
                if ($key === 'extends') {
86
                    continue;
87
                }
88
89
                // This is probably either fields or operations
90
                if (is_array($value)) {
91
                    $extended_schemadb[$extended_schema_name][$key] ??= [];
92
93
                    foreach ($value as $name => $field) {
94
                        if (!$field) {
95
                            unset($extended_schemadb[$extended_schema_name][$key][$name]);
96
                            continue;
97
                        }
98
99
                        $extended_schemadb[$extended_schema_name][$key][$name] = $field;
100
                    }
101
                } else {
102
                    $extended_schemadb[$extended_schema_name][$key] = $value;
103
                }
104
            }
105
106
            // Replace the new schema with extended schema
107
            $data[$schema_name] = $extended_schemadb[$extended_schema_name];
108
        }
109
    }
110
111 192
    public function add(string $name, schema $schema)
112
    {
113 192
        $this->schemas[$name] = $schema;
114 192
        $schema->set_name($name);
115
    }
116
117
    /**
118
     * @return schema[]
119
     */
120 34
    public function all() : array
121
    {
122 34
        return $this->schemas;
123
    }
124
125 118
    public function get_first() : schema
126
    {
127 118
        if (empty($this->schemas)) {
128
            throw new midcom_error('Schema DB is empty');
129
        }
130 118
        return reset($this->schemas);
131
    }
132
133 59
    public function has(string $name) : bool
134
    {
135 59
        return array_key_exists($name, $this->schemas);
136
    }
137
138 78
    public function get(string $name) : schema
139
    {
140 78
        if (!array_key_exists($name, $this->schemas)) {
141
            throw new midcom_error('Schema ' . $name . ' not found in schemadb');
142
        }
143 78
        return $this->schemas[$name];
144
    }
145
}
146