Passed
Push — master ( dc3f28...9cb9a1 )
by Andreas
16:51
created

form   F

Complexity

Total Complexity 129

Size/Duplication

Total Lines 635
Duplicated Lines 0 %

Test Coverage

Coverage 80.47%

Importance

Changes 9
Bugs 0 Features 1
Metric Value
wmc 129
eloc 353
c 9
b 0
f 1
dl 0
loc 635
ccs 309
cts 384
cp 0.8047
rs 2

42 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A get_view_renderer() 0 3 1
B form_rows() 0 26 7
A form_end() 0 8 3
A form_row() 0 18 3
A form_errors() 0 15 4
A form_start() 0 15 2
A subform_widget() 0 14 3
A button_widget() 0 8 2
A submit_widget() 0 4 1
A color_widget() 0 3 1
A markdown_widget() 0 11 1
A jsdate_widget() 0 22 4
A choice_widget_options() 0 21 5
A image_row() 0 14 3
A email_widget() 0 3 1
A radio_widget() 0 8 2
A collect_choices() 0 9 4
A password_widget() 0 3 1
C image_widget() 0 55 12
A hidden_widget() 0 3 1
B form_widget_simple() 0 31 10
A choice_widget_expanded() 0 8 2
A delete_widget() 0 4 1
A autocomplete_widget() 0 18 2
A privilegeselection_widget() 0 8 1
A privilege_widget() 0 12 3
A form_label() 0 19 6
A other_widget() 0 6 1
A checkbox_widget() 0 12 3
A url_widget() 0 3 1
A codemirror_widget() 0 13 2
A tinymce_widget() 0 16 2
A textarea_widget() 0 10 2
A captcha_widget() 0 10 1
A prepare_widget_attributes() 0 8 3
D choice_widget_collapsed() 0 51 18
A button_row() 0 5 1
A repeated_row() 0 8 2
A hidden_row() 0 3 1
A toolbar_row() 0 8 2
A attachment_row() 0 28 3

How to fix   Complexity   

Complex Class

Complex classes like form often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use form, and based on these observations, apply Extract Interface, too.

1
<?php
2
namespace midcom\datamanager\template;
3
4
use Symfony\Component\Form\FormView;
5
use Symfony\Component\Form\ChoiceList\View\ChoiceGroupView;
6
use midcom\datamanager\renderer;
7
use midcom;
8
use midcom\datamanager\helper\autocomplete;
9
10
class form extends base
11
{
12 103
    public function __construct(renderer $renderer)
13
    {
14 103
        parent::__construct($renderer);
15 103
        midcom::get()->head->prepend_stylesheet(MIDCOM_STATIC_URL . '/midcom.datamanager/default.css');
16
    }
17
18 5
    protected function get_view_renderer() : view
19
    {
20 5
        return new view($this->renderer);
21
    }
22
23 103
    public function form_start(FormView $view, array $data)
24
    {
25 103
        $attributes = array_replace([
26 103
            'id' => $data['name'],
27 103
            'name' => $data['name'],
28 103
            'method' => strtolower($data['method']),
29 103
            'action' => $data['action'],
30 103
            'class' => 'datamanager2'
31 103
        ], $data['attr']);
32
33 103
        if ($data['multipart']) {
34 16
            $attributes['enctype'] = 'multipart/form-data';
35
        }
36
37 103
        return '<form ' . $this->attributes($attributes) . '>';
38
    }
39
40 102
    public function form_errors(FormView $view, array $data)
41
    {
42 102
        $errors = [];
43 102
        foreach ($data['errors'] as $error) {
44
            $params = $error->getMessageParameters();
45
            $message = $error->getMessage();
46
            foreach ($params as $param) {
47
                if (str_contains($message, (string) $param)) {
48
                    $message = str_replace($param, $this->renderer->humanize($param), $message);
49
                }
50
            }
51
            $errors[] = '<div class="field_error">' . $this->renderer->humanize($message) . '</div>';
52
        }
53
54 102
        return implode('', $errors);
55
    }
56
57 102
    public function form_rows(FormView $view, array $data)
58
    {
59 102
        $string = '';
60 102
        foreach ($view as $child) {
61 102
            if (!empty($child->vars['hidden'])) {
62 19
                $child->setRendered();
63 19
                continue;
64
            }
65 102
            if ($child->vars['start_fieldset'] !== null) {
66 40
                if (!empty($child->vars['start_fieldset']['css_group'])) {
67 31
                    $class = $child->vars['start_fieldset']['css_group'];
68
                } else {
69 9
                    $class = $child->vars['name'];
70
                }
71 40
                $string .= '<fieldset class="fieldset ' . $class . '">';
72 40
                if (!empty($child->vars['start_fieldset']['title'])) {
73 40
                    $string .= '<legend>' . $this->renderer->humanize($child->vars['start_fieldset']['title']) . '</legend>';
74
                }
75
            }
76 102
            $string .= $this->renderer->row($child);
77 102
            if ($child->vars['end_fieldset'] !== null) {
78 43
                $end_fieldsets = max(1, (int) $child->vars['end_fieldset']);
79 43
                $string .= str_repeat('</fieldset>', $end_fieldsets);
80
            }
81
        }
82 102
        return $string;
83
    }
84
85 103
    public function form_end(FormView $view, array $data)
86
    {
87 103
        $string = '';
88 103
        if (   !isset($data['render_rest'])
89 103
            || $data['render_rest']) {
90 103
            $string .= $this->renderer->rest($view);
91
        }
92 103
        return $string . '</form>';
93
    }
94
95 101
    public function form_row(FormView $view, array $data)
96
    {
97 101
        $class = 'element element_' . $view->vars['block_prefixes'][count($view->vars['block_prefixes']) - 2];
98
99 101
        if ($view->vars['required']) {
100 72
            $class .= ' required';
101
        }
102
103 101
        if ($view->vars['errors']->count() > 0) {
104
            $class .= ' error';
105
        }
106
107 101
        $string = '<div class="' . $class . '">';
108 101
        $string .= $this->renderer->label($view);
109 101
        $string .= '<div class="input">';
110 101
        $string .= $this->renderer->errors($view);
111 101
        $string .= $this->renderer->widget($view);
112 101
        return $string . '</div></div>';
113
    }
114
115
    public function button_row(FormView $view, array $data)
116
    {
117
        $string = '<div>';
118
        $string .= $this->renderer->widget($view);
119
        return $string . '</div>';
120
    }
121
122 30
    public function hidden_row(FormView $view, array $data)
123
    {
124 30
        return $this->renderer->widget($view);
125
    }
126
127 103
    public function toolbar_row(FormView $view, array $data)
128
    {
129 103
        $string = '<div class="form_toolbar">';
130 103
        foreach ($view as $key => $child) {
131 103
            $label = $this->renderer->humanize($view->vars['button-labels'][$key]);
132 103
            $string .= $this->renderer->widget($child, ['label' => $label]);
133
        }
134 103
        return $string . '</div>';
135
    }
136
137 2
    public function repeated_row(FormView $view, array $data)
138
    {
139 2
        $view->children['second']->vars['label'] = $this->renderer->humanize($view->children['first']->vars['label']) . ' ' . $this->renderer->humanize($view->children['second']->vars['label']);
140 2
        $string = '';
141 2
        foreach ($view->children as $child) {
142 2
            $string .= $this->form_row($child, $data);
143
        }
144 2
        return $string;
145
    }
146
147 7
    public function attachment_row(FormView $view, array $data)
148
    {
149 7
        midcom::get()->head->add_stylesheet(MIDCOM_STATIC_URL . "/stock-icons/font-awesome-4.7.0/css/font-awesome.min.css");
150 7
        midcom::get()->head->add_jsfile(MIDCOM_STATIC_URL . '/midcom.datamanager/attachment.js');
151
152 7
        $string = '<fieldset ' . $this->renderer->block($view, 'widget_container_attributes') . '>';
153 7
        $string .= '<legend>';
154 7
        $string .= $data['value']['filename'] ?? $this->renderer->humanize('add new file');
155 7
        $string .= '</legend>';
156
157 7
        $string .= '<div class="attachment-container">';
158 7
        $string .= '<div class="attachment-preview">';
159 7
        if (!empty($data['value']['filename'])) {
160
            $ext = pathinfo($data['value']['filename'], PATHINFO_EXTENSION);
161
            $string .= '<a href="' . $data['value']['url'] . '" target="_blank" class="icon" title="' . $data['value']['filename'] . '">';
162
            $string .= '<i class="fa fa-file-o"></i><span class="extension">' . $ext . '</span></a>';
0 ignored issues
show
Bug introduced by
Are you sure $ext of type array|string can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

162
            $string .= '<i class="fa fa-file-o"></i><span class="extension">' . /** @scrutinizer ignore-type */ $ext . '</span></a>';
Loading history...
163
        } else {
164 7
            $string .= '<span class="icon no-file"><i class="fa fa-file-o"></i></span>';
165
        }
166
167 7
        $string .= '</div><div class="attachment-input">';
168 7
        foreach ($view->children as $child) {
169 7
            $string .= $this->renderer->row($child);
170
        }
171
172 7
        $string .= '</div></div>';
173 7
        $string .= $this->jsinit('dm_attachment_init("' . $data['form']['file']->vars['id'] . '")');
174 7
        return $string . '</fieldset>';
175
    }
176
177 5
    public function image_row(FormView $view, array $data)
178
    {
179 5
        if (!in_array('subform', $view->parent->vars['block_prefixes'])) {
180 4
            return $this->form_row($view, $data);
181
        }
182
183 1
        $string = '<fieldset ' . $this->renderer->block($view, 'widget_container_attributes') . '>';
184 1
        $string .= '<legend>';
185 1
        $string .= (!empty($data['value']['objects']['main']['filename'])) ? preg_replace('/^.+?-/', '', $data['value']['objects']['main']['filename']) : $this->renderer->humanize('add new file');
186 1
        $string .= '</legend>';
187
188 1
        $string .= $this->renderer->widget($view);
189
190 1
        return $string . '</fieldset>';
191
    }
192
193 96
    public function form_widget_simple(FormView $view, array $data)
194
    {
195 96
        $type = $data['type'] ?? 'text';
196 96
        if ($view->vars['readonly'] && $type !== 'hidden') {
197 4
            $vr = $this->get_view_renderer();
198 4
            if ($type == 'text' && ($data['attr']['inputmode'] ?? null) == 'url') {
199
                // see https://github.com/symfony/symfony/issues/29690
200
                $method = 'url_widget';
201
            } else {
202 4
                $method = $type . '_widget';
203
            }
204 4
            if (method_exists($vr, $method)) {
205 4
                $value = $vr->$method($view, $data);
206
            } else {
207
                $value = $data['value'];
208
            }
209
210 4
            $data['type'] = 'hidden';
211 4
            return $value . $this->renderer->block($view, 'form_widget_simple', $data);
212
        }
213
214 96
        if (empty($data['attr']['class']) && in_array($type, ['text', 'password', 'email', 'url'])) {
215 96
            $data['attr']['class'] = 'shorttext';
216
        }
217
218 96
        if (   !empty($data['value'])
219 96
            || is_numeric($data['value'])) {
220 82
            $data['attr']['value'] = $data['value'];
221
        }
222 96
        $data['attr']['type'] = $type;
223 96
        return '<input ' . $this->renderer->block($view, 'widget_attributes', $data) . ' />';
224
    }
225
226 103
    public function button_widget(FormView $view, array $data)
227
    {
228 103
        $type = $data['type'] ?? 'button';
229 103
        if (!$data['label']) {
230
            $data['label'] = $data['name'];
231
        }
232
233 103
        return '<button type="' . $type . '" ' . $this->renderer->block($view, 'button_attributes', $data) . '>' . $this->renderer->humanize($data['label']) . '</button>';
234
    }
235
236 74
    public function hidden_widget(FormView $view, array $data)
237
    {
238 74
        return $this->renderer->block($view, 'form_widget_simple', ['type' => $data['type'] ?? "hidden"]);
239
    }
240
241 18
    public function email_widget(FormView $view, array $data)
242
    {
243 18
        return $this->renderer->block($view, 'form_widget_simple', ['type' => $data['type'] ?? "email"]);
244
    }
245
246
    public function color_widget(FormView $view, array $data)
247
    {
248
        return $this->renderer->block($view, 'form_widget_simple', ['type' => $data['type'] ?? "color"]);
249
    }
250
251 4
    public function password_widget(FormView $view, array $data)
252
    {
253 4
        return $this->renderer->block($view, 'form_widget_simple', ['type' => $data['type'] ?? "password"]);
254
    }
255
256 8
    public function url_widget(FormView $view, array $data)
257
    {
258 8
        return $this->renderer->block($view, 'form_widget_simple', ['type' => $data['type'] ?? "url"]);
259
    }
260
261 61
    public function autocomplete_widget(FormView $view, array $data)
262
    {
263 61
        if ($view->vars['readonly']) {
264 2
            $string = $this->get_view_renderer()->autocomplete_widget($view, $data);
265 2
            return $string .  $this->renderer->widget($view['selection']);
266
        }
267
268 61
        autocomplete::add_head_elements($data['handler_options']['creation_mode_enabled'], $data['handler_options']['sortable']);
269
270 61
        $element_id = $view->vars['id'];
271 61
        $jsinit = 'window.' . $element_id . '_handler_options = ' . json_encode($data['handler_options']) . ";\n";
272 61
        $jsinit .= "midcom_helper_datamanager2_autocomplete.create_dm2_widget('{$element_id}_search_input', {$data['min_chars']});\n";
273
274 61
        $string = '<fieldset ' . $this->renderer->block($view, 'widget_container_attributes') . '>';
275 61
        $string .=  $this->renderer->widget($view['selection']);
276 61
        $string .= ' ' . $this->renderer->widget($view['search_input']);
277 61
        $string .= '</fieldset>';
278 61
        return $string . $this->jsinit($jsinit);
279
    }
280
281 57
    protected function prepare_widget_attributes(string $type, array &$data)
282
    {
283 57
        $data['attr']['type'] = $type;
284 57
        if (isset($data['value'])) {
285 57
            $data['attr']['value'] = $data['value'];
286
        }
287 57
        if ($data['checked']) {
288 34
            $data['attr']['checked'] = 'checked';
289
        }
290
    }
291
292 31
    public function radio_widget(FormView $view, array $data)
293
    {
294 31
        $this->prepare_widget_attributes('radio', $data);
295 31
        if ($view->vars['readonly']) {
296
            $data['attr']['disabled'] = true;
297
        }
298
299 31
        return '<input ' . $this->renderer->block($view, 'widget_attributes', $data) . ' />';
300
    }
301
302 36
    public function checkbox_widget(FormView $view, array $data)
303
    {
304 36
        if ($view->vars['readonly']) {
305
            $string = $this->get_view_renderer()->checkbox_widget($view, $data);
306
            if ($data['checked']) {
307
                $string .= $this->renderer->block($view, 'form_widget_simple', ['type' => "hidden"]);
308
            }
309
            return $string;
310
        }
311 36
        $this->prepare_widget_attributes('checkbox', $data);
312
313 36
        return '<input ' . $this->renderer->block($view, 'widget_attributes', $data) . ' />';
314
    }
315
316 46
    private function collect_choices(array $input, array &$choices)
317
    {
318 46
        foreach ($input as $choice) {
319 44
            if ($choice instanceof ChoiceGroupView) {
320
                $this->collect_choices($choice->getIterator()->getArrayCopy(), $choices);
321 44
            } elseif (is_array($choice)) {
322
                $this->collect_choices($choice, $choices);
323
            } else {
324 44
                $choices[] = $choice->value;
325
            }
326
        }
327
    }
328
329 46
    public function choice_widget_collapsed(FormView $view, array $data)
330
    {
331 46
        if ($view->vars['readonly'] && empty($view->vars['multiple'])) {
332
            $string = $this->get_view_renderer()->choice_widget_collapsed($view, $data);
333
            return $string . $this->renderer->block($view, 'form_widget_simple', ['type' => "hidden"]);
334
        }
335
336 46
        $string = '<select ';
337 46
        if (   $data['required']
338 46
            && null === $data['placeholder']
339 46
            && $data['placeholder_in_choices'] === false
340 46
            && $data['multiple'] === false) {
341 3
            $data['required'] = false;
342
        }
343
344 46
        if ($data['multiple']) {
345 4
            $data['attr']['multiple'] = 'multiple';
346
        }
347
348 46
        $string .= $this->renderer->block($view, 'widget_attributes', $data) . '>';
349 46
        if (null !== $data['placeholder']) {
350
            $string .= '<option value=""';
351
            if (   $data['required']
352
                && empty($data['value'])
353
                && "0" !== $data['value']) {
354
                $string .= ' selected="selected"';
355
            }
356
            $string .= '>' . $this->renderer->humanize($data['placeholder']) . '</option>';
357
        }
358 46
        $available_values = [];
359 46
        if (count($data['preferred_choices']) > 0) {
360
            $this->collect_choices($data['preferred_choices'], $available_values);
361
            $string .= $this->renderer->block($view, 'choice_widget_options', ['choices' => $data['preferred_choices']]);
362
            if (count($data['choices']) > 0 && null !== $data['separator']) {
363
                $string .= '<option disabled="disabled">' . $data['separator'] . '</option>';
364
            }
365
        }
366
367 46
        $string .= $this->renderer->block($view, 'choice_widget_options', ['choices' => $data['choices']]);
368
369 46
        $this->collect_choices($data['choices'], $available_values);
370
371 46
        if ($data['value']) {
372 15
            foreach ((array) $data['value'] as $selected) {
373 15
                if (!in_array($selected, $available_values)) {
374 1
                    $string .= '<option ' . $this->attributes(['value' => $selected, 'selected' => 'selected']) . '>' . $selected . '</option>';
375
                }
376
            }
377
        }
378
379 46
        return $string . '</select>';
380
    }
381
382 4
    public function privilege_widget(FormView $view, array $data)
383
    {
384 4
        if (isset($view->vars['effective_value'])) {
385 4
            if ($view->vars['effective_value']) {
386 2
                $label = $this->renderer->humanize('widget privilege: allow');
387
            } else {
388 3
                $label = $this->renderer->humanize('widget privilege: deny');
389
            }
390 4
            $new_label = sprintf($this->renderer->humanize('widget privilege: inherit %s'), $label);
391 4
            $view->children[2]->vars['label'] = $new_label;
392
        }
393 4
        return $this->choice_widget_expanded($view, $data);
394
    }
395
396 1
    public function privilegeselection_widget(FormView $view, array $data)
397
    {
398 1
        midcom::get()->head->enable_jquery();
399 1
        midcom::get()->head->add_stylesheet(MIDCOM_STATIC_URL . '/midcom.datamanager/privilege/jquery.privilege.css');
400 1
        midcom::get()->head->add_jsfile(MIDCOM_STATIC_URL . '/midcom.datamanager/privilege/jquery.privilege.js');
401
402 1
        $string = '<div class="holder">' . $this->choice_widget_collapsed($view, $data) . '</div>';
403 1
        return $string . $this->jsinit($view->vars['jsinit']);
404
    }
405
406 31
    public function choice_widget_expanded(FormView $view, array $data)
407
    {
408 31
        $string = '<fieldset ' . $this->renderer->block($view, 'widget_container_attributes') . '>';
409 31
        foreach ($view as $child) {
410 31
            $string .= $this->renderer->widget($child);
411 31
            $string .= '<label for="' . $child->vars['id'] . '">' . $this->renderer->humanize($child->vars['label']) . '</label>';
412
        }
413 31
        return $string . '</fieldset>';
414
    }
415
416 46
    public function choice_widget_options(FormView $view, array $data)
417
    {
418 46
        $string = '';
419 46
        foreach ($data['choices'] as $index => $choice) {
420 44
            if (is_array($choice) || $choice instanceof ChoiceGroupView) {
421
                $string .= '<optgroup ' . $this->attributes(['label' => $this->renderer->humanize($index)]) . '>';
422
                $string .= $this->renderer->block($view, 'choice_widget_options', ['choices' => $choice]);
423
                $string .= '</optgroup>';
424
            } else {
425 44
                $choice->attr['value'] = $choice->value;
426 44
                if ($data['is_selected']($choice->value, $data['value'])) {
427 24
                    $choice->attr['selected'] = 'selected';
428
                } else {
429 44
                    unset($choice->attr['selected']);
430
                }
431
432 44
                $string .= '<option ' . $this->attributes($choice->attr);
433 44
                $string .= '>' . $this->escape($this->renderer->humanize($choice->label)) . '</option>';
434
            }
435
        }
436 46
        return $string;
437
    }
438
439 2
    public function other_widget(FormView $view, array $data)
440
    {
441 2
        $string = '<fieldset ' . $this->renderer->block($view, 'widget_container_attributes') . '>';
442 2
        $string .= $this->renderer->widget($view->children['select']);
443 2
        $string .= $this->renderer->humanize($view->children['other']->vars['label']) . ': ' . $this->renderer->widget($view->children['other'], ['attr' => ['class' => 'other']]);
444 2
        return $string . '</fieldset>';
445
    }
446
447
    public function captcha_widget(FormView $view, array $data)
448
    {
449
        $alt = $this->renderer->humanize('captcha image alt text');
450
        $string = '<fieldset class="captcha">';
451
        $string .= "<img src='{$view->vars['captcha_url']}' alt='{$alt}' title='{$alt}' class='captcha'><br>";
452
        $string .= $this->renderer->humanize('captcha message');
453
        $data['attr']['class'] = 'captcha';
454
        $data['value'] = '';
455
        $string .= $this->form_widget_simple($view, $data);
456
        return $string . '</fieldset>';
457
    }
458
459 1
    public function codemirror_widget(FormView $view, array $data)
460
    {
461
        // we set required to false, because codemirror doesn't play well with html5 validation..
462 1
        $data['required'] = false;
463 1
        $string = '<textarea ' . $this->renderer->block($view, 'widget_attributes', $data) . '>';
464 1
        $string .= $data['value'] . '</textarea>';
465 1
        if (!empty($data['codemirror_snippet'])) {
466 1
            $this->add_head_elements_for_codemirror($data['modes']);
467 1
            $snippet = str_replace('{$id}', $data['id'], $data['codemirror_snippet']);
468 1
            $snippet = str_replace('{$read_only}', 'false', $snippet);
469 1
            $string .= $this->jsinit($snippet);
470
        }
471 1
        return $string;
472
    }
473
474 29
    public function jsdate_widget(FormView $view, array $data)
475
    {
476 29
        $string = '<fieldset ' . $this->renderer->block($view, 'widget_container_attributes') . '>';
477
478 29
        if ($view->vars['readonly']) {
479 2
            $string .= $this->get_view_renderer()->jsdate_widget($view, $data);
480 2
            $string .= $this->renderer->widget($view['date'], ['type' => 'hidden']);
481 2
            if (isset($view['time'])) {
482 2
                $string .= $this->renderer->widget($view['time'], ['type' => 'hidden']);
483
            }
484
        } else {
485 29
            midcom::get()->head->enable_jquery_ui(['datepicker']);
486 29
            midcom::get()->head->add_jsfile(MIDCOM_STATIC_URL . '/midcom.datamanager/datepicker.js');
487
488 29
            $string .= $this->renderer->widget($view['date'], ['type' => 'hidden']);
489 29
            $string .= $this->renderer->widget($view['input'], ['attr' => ['class' => 'jsdate']]);
490 29
            if (isset($view['time'])) {
491 7
                $string .= ' ' . $this->renderer->widget($view['time']);
492
            }
493 29
            $string .= $data['jsinit'];
494
        }
495 29
        return $string . '</fieldset>';
496
    }
497
498 5
    public function image_widget(FormView $view, array $data)
499
    {
500 5
        midcom::get()->head->add_stylesheet(MIDCOM_STATIC_URL . '/midcom.datamanager/image.css');
501 5
        midcom::get()->head->enable_jquery();
502 5
        midcom::get()->head->add_jsfile(MIDCOM_STATIC_URL . '/midcom.datamanager/image.js');
503
504 5
        $string = '<div ' . $this->renderer->block($view, 'widget_container_attributes') . '>';
505 5
        $string .= '<table class="midcom_datamanager_table_photo"><tr><td>';
506 5
        $preview = null;
507 5
        $objects = $data['value']['objects'] ?? [];
508 5
        foreach ($objects as $identifier => $info) {
509
            $preview = $info;
510
            if ($identifier == 'thumbnail') {
511
                break;
512
            }
513
        }
514 5
        if (!empty($preview)) {
515
            if ($preview['id'] === 0) {
516
                $preview['url'] = \midcom_connection::get_url('self') . 'midcom-exec-midcom.datamanager/preview-tmpfile.php?identifier=' . substr($preview['identifier'], strlen('tmpfile-'));
517
            }
518
519
            $string .= '<img src="' . $preview['url'] . '" class="preview-image">';
520
        }
521 5
        $string .= '</td><td>';
522
523 5
        if (!empty($objects)) {
524
            $string .= '<label class="midcom_datamanager_photo_label">' . $this->renderer->humanize('delete photo') . ' ' . $this->renderer->widget($data['form']['delete']) . '</label>';
525
            $string .= '<ul>';
526
            foreach ($objects as $info) {
527
                if (   $info['size_x']
528
                    && $info['size_y']) {
529
                    $size = "{$info['size_x']}&times;{$info['size_y']}";
530
                } else {
531
                    $size = 'unknown';
532
                }
533
                $string .= "<li title=\"{$info['guid']}\">{$size}: <a href='{$info['url']}' target='_new'>{$info['formattedsize']}</a></li>";
534
            }
535
            $string .= '</ul>';
536
        }
537 5
        $string .= $this->renderer->errors($data['form']['file']);
538 5
        $string .= $this->renderer->widget($data['form']['file']);
539
540 5
        if (array_key_exists('title', $view->children)) {
541 1
            $string .= $this->renderer->widget($view->children['title'], ['attr' => ['placeholder' => $this->renderer->humanize('title')]]);
542
        }
543 5
        if (array_key_exists('description', $view->children)) {
544
            $string .= $this->renderer->widget($view->children['description'], ['attr' => ['placeholder' => $this->renderer->humanize('description')]]);
545
        }
546 5
        if (array_key_exists('score', $view->children)) {
547
            $string .= $this->renderer->widget($view->children['score']);
548
        }
549 5
        $string .= '</td></tr></table></div>';
550 5
        $string .= $this->renderer->row($data['form']['identifier']);
551
552 5
        return $string . $this->jsinit('init_image_widget("' . $view->vars['id'] .'");');
553
    }
554
555 7
    public function subform_widget(FormView $view, array $data)
556
    {
557 7
        $head = midcom::get()->head;
558 7
        $head->enable_jquery();
559 7
        if ($view->vars['sortable'] == 'true') {
560
            $head->enable_jquery_ui(['mouse', 'sortable']);
561
        }
562 7
        $head->add_jsfile(MIDCOM_STATIC_URL . '/midcom.datamanager/subform.js');
563 7
        if (array_key_exists('prototype', $view->vars)) {
564 7
            $data['attr']['data-prototype'] = $this->escape($this->renderer->row($view->vars['prototype']));
565
        }
566 7
        $data['attr']['data-max-count'] = $view->vars['max_count'];
567 7
        $string = $this->renderer->widget($data['form'], $data);
568 7
        return $string . $this->jsinit('init_subform("' . $view->vars['id'] . '", ' . $view->vars['sortable'] . ', ' . $view->vars['allow_add'] . ', ' . $view->vars['allow_delete'] . ');');
569
    }
570
571 103
    public function submit_widget(FormView $view, array $data)
572
    {
573 103
        $data['type'] ??= 'submit';
574 103
        return $this->renderer->block($view, 'button_widget', $data);
575
    }
576
577
    public function delete_widget(FormView $view, array $data)
578
    {
579
        $data['type'] ??= 'delete';
580
        return $this->renderer->block($view, 'button_widget', $data);
581
    }
582
583 30
    public function textarea_widget(FormView $view, array $data)
584
    {
585 30
        if ($view->vars['readonly']) {
586 1
            $view->vars['output_mode'] = 'nl2br';
587 1
            $string = $this->get_view_renderer()->text_widget($view, $data);
588 1
            return $string . $this->renderer->block($view, 'form_widget_simple', ['type' => "hidden"]);
589
        }
590 29
        $data['attr']['class'] = 'longtext';
591 29
        $data['attr']['cols'] = 50;
592 29
        return '<textarea ' . $this->renderer->block($view, 'widget_attributes', $data) . '>' . $data['value'] . '</textarea>';
593
    }
594
595 33
    public function markdown_widget(FormView $view, array $data)
596
    {
597 33
        $head = midcom::get()->head;
598 33
        $head->add_stylesheet(MIDCOM_STATIC_URL . '/stock-icons/font-awesome-4.7.0/css/font-awesome.min.css');
599 33
        $head->add_stylesheet(MIDCOM_STATIC_URL . '/midcom.datamanager/easymde-2.16.1/easymde.min.css');
600 33
        $head->enable_jquery();
601 33
        $head->add_jsfile(MIDCOM_STATIC_URL . '/midcom.datamanager/easymde-2.16.1/easymde.min.js');
602
603 33
        $data['required'] = false;
604 33
        $string = '<textarea ' . $this->renderer->block($view, 'widget_attributes', $data) . '>' . $data['value'] . '</textarea>';
605 33
        return $string . $this->jsinit('var easymde = new EasyMDE({ element: document.getElementById("' . $view->vars['id'] . '"), status: false });');
606
    }
607
608 5
    public function tinymce_widget(FormView $view, array $data)
609
    {
610 5
        if ($view->vars['readonly']) {
611
            $string = $this->get_view_renderer()->text_widget($view, $data);
612
            $data['type'] = 'hidden';
613
            return $string . $this->renderer->block($view, 'form_widget_simple', $data);
614
        }
615
616 5
        midcom::get()->head->enable_jquery();
617 5
        midcom::get()->head->add_jsfile($data['tinymce_url']);
618 5
        midcom::get()->head->add_jsfile(MIDCOM_STATIC_URL . '/midcom.datamanager/tinymce.custom.js');
619
620
        // we set required to false, because tinymce doesn't play well with html5 validation..
621 5
        $data['required'] = false;
622 5
        $string = '<textarea ' . $this->renderer->block($view, 'widget_attributes', $data) . '>' . $data['value'] . '</textarea>';
623 5
        return $string . $this->jsinit($data['tinymce_snippet']);
624
    }
625
626 102
    public function form_label(FormView $view, array $data)
627
    {
628 102
        if ($data['label'] === false) {
629
            return '';
630
        }
631 102
        if (!$data['label']) {
632 9
            $data['label'] = $data['name'];
633
        }
634 102
        $data['label'] = $this->renderer->humanize($data['label']);
635
636 102
        $label_attr = $data['label_attr'];
637 102
        if ($data['required'] && !$view->vars['readonly']) {
638 72
            $label_attr['class'] = trim(($label_attr['class'] ?? '') . ' required');
639 72
            $data['label'] .= ' <span class="field_required_start">*</span>';
640
        }
641 102
        if (!$data['compound']) {
642 97
            $label_attr['for'] = $data['id'];
643
        }
644 102
        return '<label ' . $this->attributes($label_attr) . '><span class="field_text">' . $data['label'] . '</span></label>';
645
    }
646
}
647