Completed
Push — master ( c7ef41...d37901 )
by Andreas
19:38
created

schema::set()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

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