Completed
Push — master ( 23e787...2652bc )
by Andreas
33:54 queued 13:51
created

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