TYPO3 CMS  TYPO3_7-6
GroupElement.php
Go to the documentation of this file.
1 <?php
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 
26 
31 {
39  public function render()
40  {
41  $table = $this->data['tableName'];
42  $fieldName = $this->data['fieldName'];
43  $row = $this->data['databaseRow'];
44  $parameterArray = $this->data['parameterArray'];
45  $config = $parameterArray['fieldConf']['config'];
46  $show_thumbs = $config['show_thumbs'];
47  $resultArray = $this->initializeResultArray();
48 
49  $size = isset($config['size']) ? (int)$config['size'] : $this->minimumInputWidth;
50  $maxitems = MathUtility::forceIntegerInRange($config['maxitems'], 0);
51  if (!$maxitems) {
52  $maxitems = 100000;
53  }
54  $minitems = MathUtility::forceIntegerInRange($config['minitems'], 0);
55  $thumbnails = [];
56  $allowed = GeneralUtility::trimExplode(',', $config['allowed'], true);
57  $disallowed = GeneralUtility::trimExplode(',', $config['disallowed'], true);
58  $disabled = $config['readOnly'];
59  $info = [];
60  $parameterArray['itemFormElID_file'] = $parameterArray['itemFormElID'] . '_files';
61 
62  // whether the list and delete controls should be disabled
63  $noList = isset($config['disable_controls']) && GeneralUtility::inList($config['disable_controls'], 'list');
64  $noDelete = isset($config['disable_controls']) && GeneralUtility::inList($config['disable_controls'], 'delete');
65 
66  // "Extra" configuration; Returns configuration for the field based on settings found in the "types" fieldlist.
67  $specConf = BackendUtility::getSpecConfParts($parameterArray['fieldConf']['defaultExtras']);
68 
69  // Register properties in required elements / validation
70  $attributes['data-formengine-validation-rules'] = htmlspecialchars(
72  [
73  'minitems' => $minitems,
74  'maxitems' => $maxitems
75  ]
76  )
77  );
78 
79  // If maxitems==1 then automatically replace the current item (in list and file selector)
80  if ($maxitems === 1) {
81  $resultArray['additionalJavaScriptPost'][] =
82  'TBE_EDITOR.clearBeforeSettingFormValueFromBrowseWin[' . GeneralUtility::quoteJSvalue($parameterArray['itemFormElName']) . '] = {
83  itemFormElID_file: ' . GeneralUtility::quoteJSvalue($parameterArray['itemFormElID_file']) . '
84  }';
85  $parameterArray['fieldChangeFunc']['TBE_EDITOR_fieldChanged'] = 'setFormValueManipulate(' . GeneralUtility::quoteJSvalue($parameterArray['itemFormElName'])
86  . ', \'Remove\'); ' . $parameterArray['fieldChangeFunc']['TBE_EDITOR_fieldChanged'];
87  } elseif ($noList) {
88  // If the list controls have been removed and the maximum number is reached, remove the first entry to avoid "write once" field
89  $parameterArray['fieldChangeFunc']['TBE_EDITOR_fieldChanged'] = 'setFormValueManipulate(' . GeneralUtility::quoteJSvalue($parameterArray['itemFormElName'])
90  . ', \'RemoveFirstIfFull\', ' . GeneralUtility::quoteJSvalue($maxitems) . '); ' . $parameterArray['fieldChangeFunc']['TBE_EDITOR_fieldChanged'];
91  }
92 
93  $html = '<input type="hidden" class="t3js-group-hidden-field" data-formengine-input-name="' . htmlspecialchars($parameterArray['itemFormElName']) . '" value="' . ($config['multiple'] ? 1 : 0) . '"' . $disabled . ' />';
94 
95  // Define parameters for all types below
96  $commonParameters = [
97  'size' => $size,
98  'dontShowMoveIcons' => isset($config['hideMoveIcons']) || $maxitems <= 1,
99  'autoSizeMax' => MathUtility::forceIntegerInRange($config['autoSizeMax'], 0),
100  'maxitems' => $maxitems,
101  'style' => isset($config['selectedListStyle'])
102  ? ' style="' . htmlspecialchars($config['selectedListStyle']) . '"'
103  : '',
104  'readOnly' => $disabled,
105  'noBrowser' => $noList || isset($config['disable_controls']) && GeneralUtility::inList($config['disable_controls'], 'browser'),
106  'noList' => $noList,
107  ];
108 
109  // Acting according to either "file" or "db" type:
110  switch ((string)$config['internal_type']) {
111  case 'file_reference':
112  $config['uploadfolder'] = '';
113  // Fall through
114  case 'file':
115  // Creating string showing allowed types:
116  if (empty($allowed)) {
117  $allowed = ['*'];
118  }
119  // Making the array of file items:
120  $itemArray = GeneralUtility::trimExplode(',', $parameterArray['itemFormElValue'], true);
121  $fileFactory = ResourceFactory::getInstance();
122  // Correct the filename for the FAL items
123  foreach ($itemArray as &$fileItem) {
124  list($fileUid, $fileLabel) = explode('|', $fileItem);
126  $fileObject = $fileFactory->getFileObject($fileUid);
127  $fileLabel = $fileObject->getName();
128  }
129  $fileItem = $fileUid . '|' . $fileLabel;
130  }
131  // Showing thumbnails:
132  if ($show_thumbs) {
133  foreach ($itemArray as $imgRead) {
134  $imgP = explode('|', $imgRead);
135  $imgPath = rawurldecode($imgP[0]);
136  // FAL icon production
138  $fileObject = $fileFactory->getFileObject($imgP[0]);
139  if ($fileObject->isMissing()) {
140  $thumbnails[] = [
141  'message' => '<span class="label label-danger">'
142  . htmlspecialchars(static::getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:warning.file_missing'))
143  . '</span>&nbsp;' . htmlspecialchars($fileObject->getName()) . '<br />'
144  ];
145  } elseif (GeneralUtility::inList($GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'], $fileObject->getExtension())) {
146  $thumbnails[] = [
147  'name' => htmlspecialchars($fileObject->getName()),
148  'image' => $fileObject->process(ProcessedFile::CONTEXT_IMAGEPREVIEW, [])->getPublicUrl(true)
149  ];
150  } else {
151  $name = htmlspecialchars($fileObject->getName());
152  // Icon
153  $thumbnails[] = [
154  'name' => $name,
155  'image' => '<span title="' . $name . '">' . $this->iconFactory->getIconForResource($fileObject, Icon::SIZE_SMALL) . '</span>'
156  ];
157  }
158  } else {
159  $rowCopy = [];
160  $rowCopy[$fieldName] = $imgPath;
161  try {
162  $thumbnails[] = [
163  'name' => $imgPath,
164  'image' => BackendUtility::thumbCode(
165  $rowCopy,
166  $table,
167  $fieldName,
168  '',
169  '',
170  $config['uploadfolder'],
171  0,
172  ' align="middle"'
173  )
174  ];
175  } catch (\Exception $exception) {
177  $message = $exception->getMessage();
178  $flashMessage = GeneralUtility::makeInstance(
179  FlashMessage::class,
180  $message, '', FlashMessage::ERROR, true
181  );
183  $flashMessageService = GeneralUtility::makeInstance(FlashMessageService::class);
184  $defaultFlashMessageQueue = $flashMessageService->getMessageQueueByIdentifier();
185  $defaultFlashMessageQueue->enqueue($flashMessage);
186  $logMessage = $message . ' (' . $table . ':' . $row['uid'] . ')';
187  GeneralUtility::sysLog($logMessage, 'core', GeneralUtility::SYSLOG_SEVERITY_WARNING);
188  }
189  }
190  }
191  }
192  // Creating the element:
193  $params = array_merge($commonParameters, [
194  'allowed' => $allowed,
195  'disallowed' => $disallowed,
196  'thumbnails' => $thumbnails,
197  'noDelete' => $noDelete
198  ]);
199  $html .= $this->dbFileIcons(
200  $parameterArray['itemFormElName'],
201  'file',
202  implode(',', $allowed),
203  $itemArray,
204  '',
205  $params,
206  $parameterArray['onFocus'],
207  '',
208  '',
209  '',
210  $config);
211  if (!$disabled && !(isset($config['disable_controls']) && GeneralUtility::inList($config['disable_controls'], 'upload'))) {
212  // Adding the upload field:
213  $isDirectFileUploadEnabled = (bool)$this->getBackendUserAuthentication()->uc['edit_docModuleUpload'];
214  if ($isDirectFileUploadEnabled && $config['uploadfolder']) {
215  // Insert the multiple attribute to enable HTML5 multiple file upload
216  $multipleAttribute = '';
217  $multipleFilenameSuffix = '';
218  if (isset($config['maxitems']) && $config['maxitems'] > 1) {
219  $multipleAttribute = ' multiple="multiple"';
220  $multipleFilenameSuffix = '[]';
221  }
222  $html .= '
223  <div id="' . $parameterArray['itemFormElID_file'] . '">
224  <input type="file"' . $multipleAttribute . '
225  name="data_files' . $this->data['elementBaseName'] . $multipleFilenameSuffix . '"
226  size="35" onchange="' . implode('', $parameterArray['fieldChangeFunc']) . '"
227  />
228  </div>';
229  }
230  }
231  break;
232  case 'folder':
233  // If the element is of the internal type "folder":
234  // Array of folder items:
235  $itemArray = GeneralUtility::trimExplode(',', $parameterArray['itemFormElValue'], true);
236  // Creating the element:
237  $params = $commonParameters;
238  $html .= $this->dbFileIcons(
239  $parameterArray['itemFormElName'],
240  'folder',
241  '',
242  $itemArray,
243  '',
244  $params,
245  $parameterArray['onFocus']
246  );
247  break;
248  case 'db':
249  // If the element is of the internal type "db":
250  // Creating string showing allowed types:
251  $languageService = $this->getLanguageService();
252 
253  $allowedTables = [];
254  if ($allowed[0] === '*') {
255  $allowedTables = [
256  'name' => htmlspecialchars($languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.allTables'))
257  ];
258  } elseif ($allowed) {
259  foreach ($allowed as $allowedTable) {
260  $allowedTables[] = [
261  // @todo: access to globals!
262  'name' => htmlspecialchars($languageService->sL($GLOBALS['TCA'][$allowedTable]['ctrl']['title'])),
263  'icon' => $this->iconFactory->getIconForRecord($allowedTable, [], Icon::SIZE_SMALL)->render(),
264  'onClick' => 'setFormValueOpenBrowser(\'db\', ' . GeneralUtility::quoteJSvalue($parameterArray['itemFormElName'] . '|||' . $allowedTable) . '); return false;'
265  ];
266  }
267  }
268  $perms_clause = $this->getBackendUserAuthentication()->getPagePermsClause(1);
269  $itemArray = [];
270 
271  // Thumbnails:
272  // @todo: this is data processing - must be extracted
273  $temp_itemArray = GeneralUtility::trimExplode(',', $parameterArray['itemFormElValue'], true);
274  foreach ($temp_itemArray as $dbRead) {
275  $recordParts = explode('|', $dbRead);
276  list($this_table, $this_uid) = BackendUtility::splitTable_Uid($recordParts[0]);
277 
278  $itemArray[] = ['table' => $this_table, 'id' => $this_uid];
279  if (!$disabled && $show_thumbs) {
280  if (empty($this_table)) {
281  throw new \RuntimeException(
282  'Table name could not been determined for field "' . $fieldName . '" in table "' . $table . '". ' .
283  'This should never happen since the table name should have been already prepared in the DataProvider TcaGroup. ' .
284  'Maybe the prepared values have been set to an invalid value by a user defined data provider.',
285  1468149217
286  );
287  }
288  $rr = BackendUtility::getRecordWSOL($this_table, $this_uid);
289  $thumbnails[] = [
290  'name' => BackendUtility::getRecordTitle($this_table, $rr, true),
291  'image' => $this->iconFactory->getIconForRecord($this_table, $rr, Icon::SIZE_SMALL)->render(),
292  'path' => BackendUtility::getRecordPath($rr['pid'], $perms_clause, 15),
293  'uid' => $rr['uid'],
294  'table' => $this_table
295  ];
296  }
297  }
298  // Creating the element:
299  $params = array_merge($commonParameters, [
300  'info' => $info,
301  'allowedTables' => $allowedTables,
302  'thumbnails' => $thumbnails,
303  ]);
304  $html .= $this->dbFileIcons(
305  $parameterArray['itemFormElName'],
306  'db',
307  implode(',', $allowed),
308  $itemArray,
309  '',
310  $params,
311  $parameterArray['onFocus'],
312  $table,
313  $fieldName,
314  $row['uid'],
315  $config
316  );
317  break;
318  }
319  // Wizards:
320  if (!$disabled) {
321  $html = $this->renderWizards(
322  [$html],
323  $config['wizards'],
324  $table,
325  $row,
326  $fieldName,
327  $parameterArray,
328  $parameterArray['itemFormElName'],
329  $specConf
330  );
331  }
332  $resultArray['html'] = $html;
333  return $resultArray;
334  }
335 
339  protected function getBackendUserAuthentication()
340  {
341  return $GLOBALS['BE_USER'];
342  }
343 }
static forceIntegerInRange($theInt, $min, $max=2000000000, $defaultValue=0)
Definition: MathUtility.php:31
static trimExplode($delim, $string, $removeEmptyValues=false, $limit=0)
static getRecordTitle($table, $row, $prep=false, $forceResult=true)
static getRecordPath($uid, $clause, $titleLimit, $fullTitleLimit=0)
static getSpecConfParts($defaultExtrasString, $_='')
if(TYPO3_MODE==='BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']
static getRecordWSOL($table, $uid, $fields=' *', $where='', $useDeleteClause=true, $unsetMovePointers=false)