schema::has_field()   A
last analyzed

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 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
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 Symfony\Component\OptionsResolver\Options;
10
use Symfony\Component\OptionsResolver\OptionsResolver;
11
use midcom;
12
use midcom_core_context;
13
use midcom_services_i18n_l10n;
14
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
15
16
/**
17
 * Experimental schema class
18
 */
19
class schema
20
{
21
    private array $defaults = [
22
        'operations' => ['save' => '', 'cancel' => ''],
23
        'fields' => [],
24
        'customdata' => [],
25
        'validation' => [],
26
        'action' => ''
27
    ];
28
29
    private array $config = [];
30
31
    private string $name = 'default';
32
33 196
    public function __construct(array $config)
34
    {
35 196
        $this->config = array_merge($this->defaults, [
36 196
            'templates' => \midcom_baseclasses_components_configuration::get('midcom.datamanager', 'config')->get_array('templates')
37 196
        ], $config);
38 196
        $this->complete_fields();
39
    }
40
41 192
    public function set_name(string $name)
42
    {
43 192
        $this->name = $name;
44
    }
45
46 52
    public function get_name() : string
47
    {
48 52
        return $this->name;
49
    }
50
51 185
    public function get(string $key)
52
    {
53 185
        return $this->config[$key];
54
    }
55
56 12
    public function set(string $key, $value)
57
    {
58 12
        $this->config[$key] = $value;
59 12
        if ($key === 'fields') {
60 8
            $this->complete_fields();
61
        }
62
    }
63
64 50
    public function has_field(string $name) : bool
65
    {
66 50
        return array_key_exists($name, $this->config['fields']);
67
    }
68
69
    /**
70
     * Returns reference to field config (for on the fly modification)
71
     */
72 41
    public function & get_field(string $name) : array
73
    {
74 41
        if (!$this->has_field($name)) {
75
            throw new midcom_error('Field ' . $name . ' is not available in this schema');
76
        }
77 41
        return $this->config['fields'][$name];
78
    }
79
80 170
    public function get_defaults() : array
81
    {
82 170
        $defaults = [];
83 170
        foreach ($this->config['fields'] as $name => $config) {
84 167
            if (!empty($config['default'])) {
85 40
                $defaults[$name] = $config['default'];
86
            }
87
        }
88 170
        return $defaults;
89
    }
90
91 148
    public function get_l10n() : midcom_services_i18n_l10n
92
    {
93
        // Populate the l10n_schema member
94 148
        $l10n_name = $this->config['l10n_db'] ?? midcom_core_context::get()->get_key(MIDCOM_CONTEXT_COMPONENT);
95 148
        if (!$l10n_name || !midcom::get()->componentloader->is_installed($l10n_name)) {
96 1
            $l10n_name = 'midcom';
97
        }
98 148
        return midcom::get()->i18n->get_l10n($l10n_name);
99
    }
100
101 196
    private function complete_fields()
102
    {
103 196
        foreach ($this->config['fields'] as $name => &$config) {
104 193
            $config = $this->resolve_field_options($config, $name);
105
        }
106
    }
107
108 193
    private function resolve_field_options(array $config, string $name) : array
109
    {
110 193
        $resolver = new OptionsResolver();
111
112 193
        $resolver->setDefaults(array_merge([
113 193
            'title' => '',
114 193
            'description' => '',
115 193
            'type' => '',
116 193
            'type_config' => [],
117 193
            'widget' => null,
118 193
            'widget_config' => [],
119 193
            'required' => false,
120 193
            'readonly' => false,
121 193
            'hidden' => false,
122 193
            'default' => null,
123 193
            'storage' => '__UNSET__',
124 193
            'index_method' => 'auto',
125 193
            'index_merge_with_content' => true,
126 193
            'start_fieldset' => null,
127 193
            'end_fieldset' => null,
128 193
            'validation' => [],
129 193
            'helptext' => null,
130 193
            'write_privilege' => null,
131 193
            'customdata' => []
132 193
        ], $config));
133
134 193
        $normalize_widget = function (Options $options, $value) {
135 193
            if ($value == 'text') {
136 182
                if (!empty($options['widget_config']['hideinput'])) {
137 1
                    return PasswordType::class;
138
                }
139 182
                if ($options['type'] === 'number') {
140 65
                    return 'number';
141
                }
142 172
                if ($options['type'] === 'urlname') {
143 38
                    return 'urlname';
144
                }
145 172
                if (!empty($options['validation'])) {
146 42
                    foreach ($options['validation'] as $rule) {
147 42
                        if (is_array($rule) && $rule['type'] === 'email') {
148 42
                            return 'email';
149
                        }
150
                    }
151
                }
152
            }
153 193
            if ($value == 'select' && !empty($options['type_config']['allow_other'])) {
154 16
                return 'other';
155
            }
156 193
            return $value;
157 193
        };
158
159 193
        $normalize_storage = function (Options $options, $value) use ($name) {
160 193
            $default = [
161 193
                'location' => 'parameter',
162 193
                'domain' => 'midcom.helper.datamanager2',
163 193
                'name' => $name
164 193
            ];
165 193
            if ($value === '__UNSET__') {
166 54
                return $default;
167
            }
168 193
            if ($options['type'] === 'privilege') {
169 5
                return [
170 5
                    'location' => 'privilege',
171 5
                    'name' => $name
172 5
                ];
173
            }
174 191
            if ($options['type'] === 'tags' || $value === null) {
175 116
                return null;
176
            }
177 184
            if (is_string($value)) {
178 175
                if ($value === 'metadata') {
179 2
                    return ['location' => $value, 'name' => $name];
180
                }
181 173
                if ($value === 'parameter') {
182 34
                    return $default;
183
                }
184 172
                return ['location' => $value];
185
            }
186 41
            if (strtolower($value['location']) === 'parameter') {
187 12
                $value['location'] = strtolower($value['location']);
188 12
                if (!array_key_exists('domain', $value)) {
189
                    $value['domain'] = 'midcom.helper.datamanager2';
190
                }
191
            }
192 41
            if (strtolower($value['location']) === 'configuration') {
193 36
                $value['location'] = 'parameter';
194
            }
195 41
            return $value;
196 193
        };
197
198 193
        $normalize_validation = function (Options $options, $value) {
199 193
            $validation = [];
200
201 193
            foreach ((array) $value as $key => $rule) {
202 42
                if (!is_array($rule)) {
203 42
                    if (is_object($rule)) {
204
                        $validation[] = $rule;
205
                        continue;
206
                    }
207 42
                    $rule = ['type' => $rule];
208 2
                } elseif (!array_key_exists('type', $rule)) {
209
                    throw new midcom_error("Missing validation rule type for rule {$key} on field {$options['name']}, this is a required option.");
210 2
                } elseif (   $rule['type'] == 'compare'
211 2
                          && !array_key_exists('compare_with', $rule)) {
212
                    throw new midcom_error("Missing compare_with option for compare type rule {$key} on field {$options['name']}, this is a required option.");
213
                }
214
215 42
                $defaults = [
216 42
                    'message' => "validation failed: {$rule['type']}",
217 42
                    'format' => ''
218 42
                ];
219
220 42
                $validation[] = array_merge($defaults, $rule);
221
            }
222
223 193
            return $validation;
224 193
        };
225
226 193
        $normalize_type = function(Options $options, $value) {
227 193
            if ($value === 'tags') {
228 54
                return 'net_nemein_tag_datamanager_storage';
229
            }
230 193
            return $value;
231 193
        };
232
233 193
        $resolver->setNormalizer('storage', $normalize_storage);
234 193
        $resolver->setNormalizer('widget', $normalize_widget);
235 193
        $resolver->setNormalizer('validation', $normalize_validation);
236 193
        $resolver->setNormalizer('type', $normalize_type);
237
238 193
        return $resolver->resolve($config);
239
    }
240
}
241