Passed
Branch master (6c65a4)
by Christian
27:15 queued 11:09
created

SelectSingleElement::render()   F

Complexity

Conditions 30
Paths > 20000

Size

Total Lines 189
Code Lines 127

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 30
eloc 127
nc 179200
nop 0
dl 0
loc 189
rs 2
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
namespace TYPO3\CMS\Backend\Form\Element;
3
4
/*
5
 * This file is part of the TYPO3 CMS project.
6
 *
7
 * It is free software; you can redistribute it and/or modify it under
8
 * the terms of the GNU General Public License, either version 2
9
 * of the License, or any later version.
10
 *
11
 * For the full copyright and license information, please read the
12
 * LICENSE.txt file that was distributed with this source code.
13
 *
14
 * The TYPO3 project - inspiring people to share!
15
 */
16
17
use TYPO3\CMS\Backend\Form\InlineStackProcessor;
18
use TYPO3\CMS\Backend\Form\Utility\FormEngineUtility;
19
use TYPO3\CMS\Core\Utility\GeneralUtility;
20
use TYPO3\CMS\Core\Utility\StringUtility;
21
22
/**
23
 * Creates a widget where only one item can be selected.
24
 * This is either a select drop-down if no size config is given or set to 1, or a select box.
25
 *
26
 * This is rendered for type=select, renderType=selectSingle
27
 */
28
class SelectSingleElement extends AbstractFormElement
29
{
30
    /**
31
     * Default field wizards enabled for this element.
32
     *
33
     * @var array
34
     */
35
    protected $defaultFieldWizard = [
36
        'selectIcons' => [
37
            'renderType' => 'selectIcons',
38
            'disabled' => true,
39
        ],
40
        'localizationStateSelector' => [
41
            'renderType' => 'localizationStateSelector',
42
            'after' => [
43
                'selectIcons',
44
            ],
45
        ],
46
        'otherLanguageContent' => [
47
            'renderType' => 'otherLanguageContent',
48
            'after' => [ 'localizationStateSelector' ],
49
        ],
50
        'defaultLanguageDifferences' => [
51
            'renderType' => 'defaultLanguageDifferences',
52
            'after' => [ 'otherLanguageContent' ],
53
        ],
54
    ];
55
56
    /**
57
     * Render single element
58
     *
59
     * @return array As defined in initializeResultArray() of AbstractNode
60
     */
61
    public function render()
62
    {
63
        $resultArray = $this->initializeResultArray();
64
65
        $table = $this->data['tableName'];
66
        $field = $this->data['fieldName'];
67
        $row = $this->data['databaseRow'];
68
        $parameterArray = $this->data['parameterArray'];
69
        $config = $parameterArray['fieldConf']['config'];
70
71
        $selectItems = $parameterArray['fieldConf']['config']['items'];
72
73
        // Check against inline uniqueness
74
        /** @var InlineStackProcessor $inlineStackProcessor */
75
        $inlineStackProcessor = GeneralUtility::makeInstance(InlineStackProcessor::class);
76
        $inlineStackProcessor->initializeByGivenStructure($this->data['inlineStructure']);
77
        $uniqueIds = null;
78
        if ($this->data['isInlineChild'] && $this->data['inlineParentUid']) {
79
            $inlineObjectName = $inlineStackProcessor->getCurrentStructureDomObjectIdPrefix($this->data['inlineFirstPid']);
80
            $inlineFormName = $inlineStackProcessor->getCurrentStructureFormPrefix();
81
            if ($this->data['inlineParentConfig']['foreign_table'] === $table
82
                && $this->data['inlineParentConfig']['foreign_unique'] === $field
83
            ) {
84
                $uniqueIds = $this->data['inlineData']['unique'][$inlineObjectName . '-' . $table]['used'];
85
                $parameterArray['fieldChangeFunc']['inlineUnique'] = 'inline.updateUnique(this,'
86
                    . GeneralUtility::quoteJSvalue($inlineObjectName . '-' . $table) . ','
87
                    . GeneralUtility::quoteJSvalue($inlineFormName) . ','
88
                    . GeneralUtility::quoteJSvalue($row['uid']) . ');';
89
            }
90
            // hide uid of parent record for symmetric relations
91
            if ($this->data['inlineParentConfig']['foreign_table'] === $table
92
                && (
93
                    $this->data['inlineParentConfig']['foreign_field'] === $field
94
                    || $this->data['inlineParentConfig']['symmetric_field'] === $field
95
                )
96
            ) {
97
                $uniqueIds[] = $this->data['inlineParentUid'];
98
            }
99
        }
100
101
        // Initialization:
102
        $selectId = StringUtility::getUniqueId('tceforms-select-');
103
        $selectedIcon = '';
104
        $size = (int)$config['size'];
105
106
        // Style set on <select/>
107
        $options = '';
108
        $disabled = false;
109
        if (!empty($config['readOnly'])) {
110
            $disabled = true;
111
        }
112
113
        // Prepare groups
114
        $selectItemCounter = 0;
115
        $selectItemGroupCount = 0;
116
        $selectItemGroups = [];
117
        $selectedValue = '';
118
        $hasIcons = false;
119
120
        if (!empty($parameterArray['itemFormElValue'])) {
121
            $selectedValue = (string)$parameterArray['itemFormElValue'][0];
122
        }
123
124
        foreach ($selectItems as $item) {
125
            if ($item[1] === '--div--') {
126
                // IS OPTGROUP
127
                if ($selectItemCounter !== 0) {
128
                    $selectItemGroupCount++;
129
                }
130
                $selectItemGroups[$selectItemGroupCount]['header'] = [
131
                    'title' => $item[0],
132
                ];
133
            } else {
134
                // IS ITEM
135
                $icon = !empty($item[2]) ? FormEngineUtility::getIconHtml($item[2], $item[0], $item[0]) : '';
136
                $selected = $selectedValue === (string)$item[1];
137
138
                if ($selected) {
139
                    $selectedIcon = $icon;
140
                }
141
142
                $selectItemGroups[$selectItemGroupCount]['items'][] = [
143
                    'title' => $item[0],
144
                    'value' => $item[1],
145
                    'icon' => $icon,
146
                    'selected' => $selected,
147
                ];
148
                $selectItemCounter++;
149
            }
150
        }
151
152
        // Fallback icon
153
        // @todo: assign a special icon for non matching values?
154
        if (!$selectedIcon && $selectItemGroups[0]['items'][0]['icon']) {
155
            $selectedIcon = $selectItemGroups[0]['items'][0]['icon'];
156
        }
157
158
        // Process groups
159
        foreach ($selectItemGroups as $selectItemGroup) {
160
            // suppress groups without items
161
            if (empty($selectItemGroup['items'])) {
162
                continue;
163
            }
164
165
            $optionGroup = is_array($selectItemGroup['header']);
166
            $options .= ($optionGroup ? '<optgroup label="' . htmlspecialchars($selectItemGroup['header']['title'], ENT_COMPAT, 'UTF-8', false) . '">' : '');
167
168
            if (is_array($selectItemGroup['items'])) {
169
                foreach ($selectItemGroup['items'] as $item) {
170
                    $options .= '<option value="' . htmlspecialchars($item['value']) . '" data-icon="' .
171
                        htmlspecialchars($item['icon']) . '"'
172
                        . ($item['selected'] ? ' selected="selected"' : '') . '>' . htmlspecialchars($item['title'], ENT_COMPAT, 'UTF-8', false) . '</option>';
173
                }
174
                $hasIcons = !empty($item['icon']);
175
            }
176
177
            $options .= ($optionGroup ? '</optgroup>' : '');
178
        }
179
180
        $selectAttributes = [
181
            'id' => $selectId,
182
            'name' => $parameterArray['itemFormElName'],
183
            'data-formengine-validation-rules' => $this->getValidationDataAsJsonString($config),
184
            'class' => 'form-control form-control-adapt',
185
        ];
186
        if ($size) {
187
            $selectAttributes['size'] = $size;
188
        }
189
        if ($disabled) {
190
            $selectAttributes['disabled'] = 'disabled';
191
        }
192
193
        $fieldInformationResult = $this->renderFieldInformation();
194
        $fieldInformationHtml = $fieldInformationResult['html'];
195
        $resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $fieldInformationResult, false);
196
197
        $fieldWizardResult = $this->renderFieldWizard();
198
        $fieldWizardHtml = $fieldWizardResult['html'];
199
        $resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $fieldWizardResult, false);
200
201
        $html = [];
202
        $html[] = '<div class="formengine-field-item t3js-formengine-field-item">';
203
        if (!$disabled) {
204
            $html[] = $fieldInformationHtml;
205
        }
206
        $html[] =   '<div class="form-control-wrap">';
207
        $html[] =       '<div class="form-wizards-wrap">';
208
        $html[] =           '<div class="form-wizards-element">';
209
        if ($hasIcons) {
210
            $html[] =           '<div class="input-group">';
211
            $html[] =               '<span class="input-group-addon input-group-icon">';
212
            $html[] =                   $selectedIcon;
213
            $html[] =               '</span>';
214
        }
215
        $html[] =                   '<select ' . GeneralUtility::implodeAttributes($selectAttributes, true) . '>';
216
        $html[] =                       $options;
217
        $html[] =                   '</select>';
218
        if ($hasIcons) {
219
            $html[] =           '</div>';
220
        }
221
        $html[] =           '</div>';
222
        if (!$disabled) {
223
            $html[] =       '<div class="form-wizards-items-bottom">';
224
            $html[] =           $fieldWizardHtml;
225
            $html[] =       '</div>';
226
        }
227
        $html[] =       '</div>';
228
        $html[] =   '</div>';
229
        $html[] = '</div>';
230
231
        $resultArray['requireJsModules'][] = ['TYPO3/CMS/Backend/FormEngine/Element/SelectSingleElement' => implode(LF, [
232
            'function(SelectSingleElement) {',
233
                'require([\'jquery\'], function($) {',
234
                    '$(function() {',
235
                        'SelectSingleElement.initialize(',
236
                            GeneralUtility::quoteJSvalue('#' . $selectId) . ',',
237
                            '{',
238
                                'onChange: function() {',
239
                                    implode('', $parameterArray['fieldChangeFunc']),
240
                                '}',
241
                            '}',
242
                        ');',
243
                    '});',
244
                '});',
245
            '}',
246
        ])];
247
248
        $resultArray['html'] = implode(LF, $html);
249
        return $resultArray;
250
    }
251
}
252