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