[ 'renderType' => 'tcaDescription', ], ]; /** * Default field controls for this element. * * @var array */ protected $defaultFieldControl = [ 'elementBrowser' => [ 'renderType' => 'elementBrowser', ], 'insertClipboard' => [ 'renderType' => 'insertClipboard', 'after' => [ 'elementBrowser' ], ], 'editPopup' => [ 'renderType' => 'editPopup', 'disabled' => true, 'after' => [ 'insertClipboard' ], ], 'addRecord' => [ 'renderType' => 'addRecord', 'disabled' => true, 'after' => [ 'editPopup' ], ], 'listModule' => [ 'renderType' => 'listModule', 'disabled' => true, 'after' => [ 'addRecord' ], ], ]; /** * Default field wizards for this element * * @var array */ protected $defaultFieldWizard = [ 'tableList' => [ 'renderType' => 'tableList', ], 'recordsOverview' => [ 'renderType' => 'recordsOverview', 'after' => [ 'tableList' ], ], 'localizationStateSelector' => [ 'renderType' => 'localizationStateSelector', 'after' => [ 'recordsOverview' ], ], 'otherLanguageContent' => [ 'renderType' => 'otherLanguageContent', 'after' => [ 'localizationStateSelector' ], ], 'defaultLanguageDifferences' => [ 'renderType' => 'defaultLanguageDifferences', 'after' => [ 'otherLanguageContent' ], ], ]; /** * This will render a selector box into which elements from either * the file system or database can be inserted. Relations. * * @return array As defined in initializeResultArray() of AbstractNode * @throws \RuntimeException */ public function render() { $languageService = $this->getLanguageService(); $backendUser = $this->getBackendUserAuthentication(); $resultArray = $this->initializeResultArray(); $table = $this->data['tableName']; $fieldName = $this->data['fieldName']; $row = $this->data['databaseRow']; $parameterArray = $this->data['parameterArray']; $config = $parameterArray['fieldConf']['config']; $elementName = $parameterArray['itemFormElName']; $selectedItems = $parameterArray['itemFormElValue']; $selectedItemsCount = count($selectedItems); $maxItems = $config['maxitems']; $autoSizeMax = MathUtility::forceIntegerInRange($config['autoSizeMax'], 0); $size = 5; if (isset($config['size'])) { $size = (int)$config['size']; } if ($autoSizeMax >= 1) { $size = MathUtility::forceIntegerInRange($selectedItemsCount + 1, MathUtility::forceIntegerInRange($size, 1), $autoSizeMax); } $internalType = (string)$config['internal_type']; $maxTitleLength = $backendUser->uc['titleLen']; $listOfSelectedValues = []; $selectorOptionsHtml = []; if ($internalType === 'folder') { foreach ($selectedItems as $selectedItem) { $folder = $selectedItem['folder']; $listOfSelectedValues[] = $folder; $selectorOptionsHtml[] = ''; } } elseif ($internalType === 'db') { foreach ($selectedItems as $selectedItem) { $tableWithUid = $selectedItem['table'] . '_' . $selectedItem['uid']; $listOfSelectedValues[] = $tableWithUid; $title = $selectedItem['title']; if (empty($title)) { $title = '[' . $languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.no_title') . ']'; } $shortenedTitle = GeneralUtility::fixed_lgd_cs($title, $maxTitleLength); $selectorOptionsHtml[] = ''; } } else { throw new \RuntimeException( 'internal_type missing on type="group" field', 1485007097 ); } $fieldInformationResult = $this->renderFieldInformation(); $fieldInformationHtml = $fieldInformationResult['html']; $resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $fieldInformationResult, false); if (isset($config['readOnly']) && $config['readOnly']) { // Return early if element is read only $html = []; $html[] = '
'; $html[] = $fieldInformationHtml; $html[] = '
'; $html[] = '
'; $html[] = 'data['processedTca']['columns'][$fieldName]['config']['type'] === 'flex') { $flexFormConfig = $this->data['processedTca']['columns'][$fieldName]; $dataStructureIdentifier = $flexFormConfig['config']['dataStructureIdentifier']; if (!isset($flexFormConfig['config']['dataStructureIdentifier'])) { throw new \RuntimeException( 'A data structure identifier must be set in [\'config\'] part of a flex form.' . ' This is usually added by TcaFlexPrepare data processor', 1485206970 ); } if (isset($this->data['flexFormSheetName'])) { $flexFormSheetName = $this->data['flexFormSheetName']; } if (isset($this->data['flexFormFieldName'])) { $flexFormFieldName = $this->data['flexFormFieldName']; } if (isset($this->data['flexFormContainerName'])) { $flexFormContainerName = $this->data['flexFormContainerName']; } if (isset($this->data['flexFormContainerFieldName'])) { $flexFormContainerFieldName = $this->data['flexFormContainerFieldName']; } } // Get minimum characters for suggest from TCA and override by TsConfig $suggestMinimumCharacters = 0; if (isset($config['suggestOptions']['default']['minimumCharacters'])) { $suggestMinimumCharacters = (int)$config['suggestOptions']['default']['minimumCharacters']; } if (isset($parameterArray['fieldTSConfig']['suggest.']['default.']['minimumCharacters'])) { $suggestMinimumCharacters = (int)$parameterArray['fieldTSConfig']['suggest.']['default.']['minimumCharacters']; } $suggestMinimumCharacters = $suggestMinimumCharacters > 0 ? $suggestMinimumCharacters : 2; $itemCanBeSelectedMoreThanOnce = !empty($config['multiple']); $showMoveIcons = true; if (isset($config['hideMoveIcons']) && $config['hideMoveIcons']) { $showMoveIcons = false; } $showDeleteControl = true; if (isset($config['hideDeleteIcon']) && $config['hideDeleteIcon']) { $showDeleteControl = false; } $fieldId = StringUtility::getUniqueId('tceforms-multiselect-'); $selectorAttributes = [ 'id' => $fieldId, 'data-formengine-input-name' => htmlspecialchars($elementName), 'data-formengine-validation-rules' => $this->getValidationDataAsJsonString($config), 'data-maxitems' => (string)$maxItems, 'size' => (string)$size, ]; $selectorAttributes['class'] = 'form-select'; if ($maxItems !== 1 && $size !== 1) { $selectorAttributes['multiple'] = 'multiple'; } $fieldControlResult = $this->renderFieldControl(); $fieldControlHtml = $fieldControlResult['html']; $resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $fieldControlResult, false); $fieldWizardResult = $this->renderFieldWizard(); $fieldWizardHtml = $fieldWizardResult['html']; $resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $fieldWizardResult, false); $html = []; $html[] = '
'; $html[] = $fieldInformationHtml; $html[] = '
'; if ($internalType === 'db' && (!isset($config['hideSuggest']) || (bool)$config['hideSuggest'] !== true)) { $html[] = '
'; $html[] = '
'; $html[] = '
'; $html[] = ''; $html[] = $this->iconFactory->getIcon('actions-search', Icon::SIZE_SMALL)->render(); $html[] = ''; $html[] = 'sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.findRecord') . '"'; $html[] = ' data-fieldname="' . htmlspecialchars($fieldName) . '"'; $html[] = ' data-tablename="' . htmlspecialchars($table) . '"'; $html[] = ' data-field="' . htmlspecialchars($elementName) . '"'; $html[] = ' data-uid="' . htmlspecialchars($this->data['databaseRow']['uid']) . '"'; $html[] = ' data-pid="' . htmlspecialchars($this->data['parentPageRow']['uid'] ?? 0) . '"'; $html[] = ' data-fieldtype="' . htmlspecialchars($config['type']) . '"'; $html[] = ' data-minchars="' . htmlspecialchars((string)$suggestMinimumCharacters) . '"'; $html[] = ' data-datastructureidentifier="' . htmlspecialchars($dataStructureIdentifier) . '"'; $html[] = ' data-flexformsheetname="' . htmlspecialchars($flexFormSheetName) . '"'; $html[] = ' data-flexformfieldname="' . htmlspecialchars($flexFormFieldName) . '"'; $html[] = ' data-flexformcontainername="' . htmlspecialchars($flexFormContainerName) . '"'; $html[] = ' data-flexformcontainerfieldname="' . htmlspecialchars($flexFormContainerFieldName) . '"'; $html[] = '/>'; $html[] = '
'; $html[] = '
'; $html[] = '
'; } $html[] = '
'; $html[] = ''; $html[] = ''; $html[] = '
'; $html[] = ''; $html[] = '
'; $html[] = '
'; $html[] = $fieldControlHtml; $html[] = '
'; $html[] = '
'; if (!empty($fieldWizardHtml)) { $html[] = '
'; $html[] = $fieldWizardHtml; $html[] = '
'; } $html[] = '
'; $html[] = ''; $html[] = '
'; $resultArray['requireJsModules'][] = ['TYPO3/CMS/Backend/FormEngine/Element/GroupElement' => ' function(GroupElement) { new GroupElement(' . GeneralUtility::quoteJSvalue($fieldId) . '); }' ]; $resultArray['html'] = implode(LF, $html); return $resultArray; } /** * @return BackendUserAuthentication */ protected function getBackendUserAuthentication() { return $GLOBALS['BE_USER']; } /** * @return LanguageService */ protected function getLanguageService() { return $GLOBALS['LANG']; } }