[!!!][TASK] TCA: Remove wizard _HIDDENFIELD and hideParent
[Packages/TYPO3.CMS.git] / typo3 / sysext / backend / Classes / Form / Element / TextElement.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\Authentication\BackendUserAuthentication;
21 use TYPO3\CMS\Backend\Form\NodeFactory;
22
23 /**
24 * Generation of TCEform elements of the type "text"
25 */
26 class TextElement extends AbstractFormElement {
27
28 /**
29 * The number of chars expected per row when the height of a text area field is
30 * automatically calculated based on the number of characters found in the field content.
31 *
32 * @var int
33 */
34 protected $charactersPerRow = 40;
35
36 /**
37 * This will render a <textarea>
38 *
39 * @return array As defined in initializeResultArray() of AbstractNode
40 */
41 public function render() {
42 $languageService = $this->getLanguageService();
43
44 $table = $this->globalOptions['table'];
45 $fieldName = $this->globalOptions['fieldName'];
46 $row = $this->globalOptions['databaseRow'];
47 $parameterArray = $this->globalOptions['parameterArray'];
48 $resultArray = $this->initializeResultArray();
49 $backendUser = $this->getBackendUserAuthentication();
50
51 $config = $parameterArray['fieldConf']['config'];
52
53 // Setting columns number
54 $cols = MathUtility::forceIntegerInRange($config['cols'] ?: $this->defaultInputWidth, $this->minimumInputWidth, $this->maxInputWidth);
55
56 // Setting number of rows
57 $rows = MathUtility::forceIntegerInRange($config['rows'] ?: 5, 1, 20);
58 $originalRows = $rows;
59
60 $itemFormElementValueLength = strlen($parameterArray['itemFormElValue']);
61 if ($itemFormElementValueLength > $this->charactersPerRow * 2) {
62 $cols = $this->maxInputWidth;
63 $rows = MathUtility::forceIntegerInRange(
64 round($itemFormElementValueLength / $this->charactersPerRow),
65 count(explode(LF, $parameterArray['itemFormElValue'])),
66 20
67 );
68 if ($rows < $originalRows) {
69 $rows = $originalRows;
70 }
71 }
72
73 // must be called after the cols and rows calculation, so the parameters are applied
74 // to read-only fields as well.
75 // @todo: Same as in InputElement ...
76 if ($this->isGlobalReadonly() || $config['readOnly']) {
77 $config['cols'] = $cols;
78 $config['rows'] = $rows;
79 $options = $this->globalOptions;
80 $options['parameterArray'] = array(
81 'fieldConf' => array(
82 'config' => $config,
83 ),
84 'itemFormElValue' => $parameterArray['itemFormElValue'],
85 );
86 $options['renderType'] = 'none';
87 /** @var NodeFactory $nodeFactory */
88 $nodeFactory = $this->globalOptions['nodeFactory'];
89 return $nodeFactory->create($options)->render();
90 }
91
92 $evalList = GeneralUtility::trimExplode(',', $config['eval'], TRUE);
93 // "Extra" configuration; Returns configuration for the field based on settings found in the "types" fieldlist. Traditionally, this is where RTE configuration has been found.
94 $specialConfiguration = BackendUtility::getSpecConfParts($parameterArray['fieldConf']['defaultExtras']);
95 $html = '';
96
97 // Show message, if no RTE (field can only be edited with RTE!)
98 if ($specialConfiguration['rte_only']) {
99 $html = '<p><em>' . htmlspecialchars($this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:labels.noRTEfound')) . '</em></p>';
100 } else {
101 $attributes = array();
102 // validation
103 foreach ($evalList as $func) {
104 if ($func === 'required') {
105 $attributes['data-formengine-validation-rules'] = $this->getValidationDataAsJsonString(array('required' => TRUE));
106 } else {
107 // @todo: This is ugly: The code should find out on it's own whether a eval definition is a
108 // @todo: keyword like "date", or a class reference. The global registration could be dropped then
109 // Pair hook to the one in \TYPO3\CMS\Core\DataHandling\DataHandler::checkValue_input_Eval()
110 // There is a similar hook for "evaluateFieldValue" in DataHandler and InputElement
111 if (isset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tce']['formevals'][$func])) {
112 if (class_exists($func)) {
113 $evalObj = GeneralUtility::makeInstance($func);
114 if (method_exists($evalObj, 'deevaluateFieldValue')) {
115 $_params = array(
116 'value' => $parameterArray['itemFormElValue']
117 );
118 $parameterArray['itemFormElValue'] = $evalObj->deevaluateFieldValue($_params);
119 }
120 }
121 }
122 }
123 }
124
125 // calculate classes
126 $classes = array();
127 $classes[] = 'form-control';
128 $classes[] = 't3js-formengine-textarea';
129 if ($specialConfiguration['fixed-font']) {
130 $classes[] = 'text-monospace';
131 }
132 if ($specialConfiguration['enable-tab']) {
133 $classes[] = 't3js-enable-tab';
134 }
135
136 // calculate styles
137 $styles = array();
138 // add the max-height from the users' preference to it
139 $maximumHeight = (int)$backendUser->uc['resizeTextareas_MaxHeight'];
140 if ($maximumHeight > 0) {
141 $styles[] = 'max-height: ' . $maximumHeight . 'px';
142 }
143
144 // calculate attributes
145 $attributes['id'] = str_replace('.', '', uniqid('formengine-textarea-', TRUE));
146 $attributes['name'] = $parameterArray['itemFormElName'];
147 if (!empty($styles)) {
148 $attributes['style'] = implode(' ', $styles);
149 }
150 if (!empty($classes)) {
151 $attributes['class'] = implode(' ', $classes);
152 }
153 $attributes['rows'] = $rows;
154 $attributes['wrap'] = $specialConfiguration['nowrap'] ? 'off' : ($config['wrap'] ?: 'virtual');
155 $attributes['onChange'] = implode('', $parameterArray['fieldChangeFunc']);
156 if (isset($config['max']) && (int)$config['max'] > 0) {
157 $attributes['maxlength'] = (int)$config['max'];
158 }
159 $attributeString = '';
160 foreach ($attributes as $attributeName => $attributeValue) {
161 $attributeString .= ' '. $attributeName . '="' . htmlspecialchars($attributeValue) . '"';
162 }
163
164 // Build the textarea
165 $placeholderValue = $this->getPlaceholderValue($table, $config, $row);
166 $placeholderAttribute = '';
167 if (!empty($placeholderValue)) {
168 $placeholderAttribute = ' placeholder="' . htmlspecialchars(trim($languageService->sL($placeholderValue))) . '" ';
169 }
170
171 $html .= '<textarea'
172 . $attributeString
173 . $placeholderAttribute
174 . $parameterArray['onFocus']
175 . '>' . htmlspecialchars($parameterArray['itemFormElValue']) . '</textarea>';
176
177 // Wrap a wizard around the item?
178 $html = $this->renderWizards(
179 array($html),
180 $config['wizards'],
181 $table,
182 $row,
183 $fieldName,
184 $parameterArray,
185 $parameterArray['itemFormElName'],
186 $specialConfiguration,
187 FALSE
188 );
189
190 $maximumWidth = (int)$this->formMaxWidth($cols);
191 $html = '<div class="form-control-wrap"' . ($maximumWidth ? ' style="max-width: ' . $maximumWidth . 'px"' : '') . '>' . $html . '</div>';
192 }
193
194 $resultArray['html'] = $html;
195 return $resultArray;
196 }
197
198 /**
199 * @return BackendUserAuthentication
200 */
201 protected function getBackendUserAuthentication() {
202 return $GLOBALS['BE_USER'];
203 }
204
205 }