[!!!][TASK] Improve flex and TCA handling in FormEngine
[Packages/TYPO3.CMS.git] / typo3 / sysext / backend / Classes / Form / Element / InputColorPickerElement.php
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\Utility\BackendUtility;
18 use TYPO3\CMS\Core\Utility\GeneralUtility;
19 use TYPO3\CMS\Core\Utility\MathUtility;
20 use TYPO3\CMS\Core\Utility\StringUtility;
21
22 /**
23 * Class InputColorPickerElement
24 */
25 class InputColorPickerElement extends AbstractFormElement
26 {
27 /**
28 * This will render a single-line input form field, possibly with various control/validation features
29 *
30 * @return array As defined in initializeResultArray() of AbstractNode
31 */
32 public function render()
33 {
34 $table = $this->data['tableName'];
35 $fieldName = $this->data['fieldName'];
36 $row = $this->data['databaseRow'];
37 $parameterArray = $this->data['parameterArray'];
38 $resultArray = $this->initializeResultArray();
39
40 $config = $parameterArray['fieldConf']['config'];
41 $specConf = BackendUtility::getSpecConfParts($parameterArray['fieldConf']['defaultExtras']);
42 $size = MathUtility::forceIntegerInRange($config['size'] ?: $this->defaultInputWidth, $this->minimumInputWidth, $this->maxInputWidth);
43 $evalList = GeneralUtility::trimExplode(',', $config['eval'], true);
44 $classes = [];
45 $attributes = [];
46
47 // readonly
48 if ($config['readOnly']) {
49 $itemFormElValue = $parameterArray['itemFormElValue'];
50 $options = $this->data;
51 $options['parameterArray'] = [
52 'fieldConf' => [
53 'config' => $config,
54 ],
55 'itemFormElValue' => $itemFormElValue,
56 ];
57 $options['renderType'] = 'none';
58 return $this->nodeFactory->create($options)->render();
59 }
60
61 // @todo: The whole eval handling is a mess and needs refactoring
62 foreach ($evalList as $func) {
63 switch ($func) {
64 case 'required':
65 $attributes['data-formengine-validation-rules'] = $this->getValidationDataAsJsonString(['required' => true]);
66 break;
67 default:
68 // @todo: This is ugly: The code should find out on it's own whether a eval definition is a
69 // @todo: keyword like "date", or a class reference. The global registration could be dropped then
70 // Pair hook to the one in \TYPO3\CMS\Core\DataHandling\DataHandler::checkValue_input_Eval()
71 if (isset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tce']['formevals'][$func])) {
72 if (class_exists($func)) {
73 $evalObj = GeneralUtility::makeInstance($func);
74 if (method_exists($evalObj, 'deevaluateFieldValue')) {
75 $_params = [
76 'value' => $parameterArray['itemFormElValue']
77 ];
78 $parameterArray['itemFormElValue'] = $evalObj->deevaluateFieldValue($_params);
79 }
80 }
81 }
82 }
83 }
84
85 $paramsList = [
86 'field' => $parameterArray['itemFormElName'],
87 'evalList' => implode(',', $evalList),
88 'is_in' => trim($config['is_in']),
89 ];
90
91 // set classes
92 $classes[] = 'form-control';
93 $classes[] = 'hasDefaultValue';
94 $classes[] = 't3js-clearable';
95 $classes[] = 't3js-color-picker';
96 $classes[] = 'formengine-colorpickerelement';
97 $attributes['class'] = implode(' ', $classes);
98
99 // Load needed js library
100 $resultArray['requireJsModules'][] = [
101 'TYPO3/CMS/Backend/ColorPicker' => 'function(ColorPicker){ColorPicker.initialize()}'
102 ];
103
104 // calculate attributes
105 $attributes['data-formengine-validation-rules'] = $this->getValidationDataAsJsonString($config);
106 $attributes['data-formengine-input-params'] = json_encode($paramsList);
107 $attributes['data-formengine-input-name'] = $parameterArray['itemFormElName'];
108 $attributes['id'] = StringUtility::getUniqueId('formengine-input-');
109 $attributes['value'] = '';
110 if (isset($config['max']) && (int)$config['max'] > 0) {
111 $attributes['maxlength'] = (int)$config['max'];
112 }
113
114 // This is the EDITABLE form field.
115 if (!empty($config['placeholder'])) {
116 $attributes['placeholder'] = trim($config['placeholder']);
117 }
118
119 if (isset($config['autocomplete'])) {
120 $attributes['autocomplete'] = empty($config['autocomplete']) ? 'new-' . $fieldName : 'on';
121 }
122
123 // Build the attribute string
124 $attributeString = '';
125 foreach ($attributes as $attributeName => $attributeValue) {
126 $attributeString .= ' ' . $attributeName . '="' . htmlspecialchars($attributeValue) . '"';
127 }
128
129 $html = '<input type="text" value="' . htmlspecialchars($parameterArray['itemFormElValue']) . '" ' . $attributeString . ' />';
130
131 // This is the ACTUAL form field - values from the EDITABLE field must be transferred to this field which is the one that is written to the database.
132 $html .= '<input type="hidden" name="' . htmlspecialchars($parameterArray['itemFormElName']) . '" value="' . htmlspecialchars($parameterArray['itemFormElValue']) . '" />';
133
134 // Going through all custom evaluations configured for this field
135 // @todo: Similar to above code!
136 foreach ($evalList as $evalData) {
137 if (isset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tce']['formevals'][$evalData])) {
138 if (class_exists($evalData)) {
139 $evalObj = GeneralUtility::makeInstance($evalData);
140 if (method_exists($evalObj, 'returnFieldJS')) {
141 $resultArray['additionalJavaScriptPost'][] = 'TBE_EDITOR.customEvalFunctions[' . GeneralUtility::quoteJSvalue($evalData) . '] = function(value) {' . $evalObj->returnFieldJS() . '};';
142 }
143 }
144 }
145 }
146
147 // Wrap a wizard around the item?
148 $html = $this->renderWizards(
149 [$html],
150 $config['wizards'],
151 $table,
152 $row,
153 $fieldName,
154 $parameterArray,
155 $parameterArray['itemFormElName'],
156 $specConf
157 );
158
159 // Add a wrapper to remain maximum width
160 $width = (int)$this->formMaxWidth($size);
161 $html = '<div class="form-control-wrap"' . ($width ? ' style="max-width: ' . $width . 'px"' : '') . '>' . $html . '</div>';
162 $resultArray['html'] = $html;
163 return $resultArray;
164 }
165 }