'none', 'select' => 'select', 'modify' => 'modify', ]; public function __construct( private readonly IconFactory $iconFactory, ) {} public function render(): array { $resultArray = $this->initializeResultArray(); $parameterArray = $this->data['parameterArray']; $config = $parameterArray['fieldConf']['config']; $elementFieldName = $parameterArray['itemFormElName']; $currentValue = ['modify' => [], 'select' => []]; if (is_array($parameterArray['itemFormElValue']['modify'] ?? false) && is_array($parameterArray['itemFormElValue']['select'] ?? false) ) { $currentValue = $parameterArray['itemFormElValue']; } $readOnly = (bool)($config['readOnly'] ?? false); $availableTables = $config['items'] ?? []; if (empty($availableTables)) { // Early return in case the field does not contain any items return $resultArray; } $tablesConfiguration = []; $lang = $this->getLanguageService(); $itemArrayModify = array_flip($currentValue['modify']); $itemArraySelect = array_flip($currentValue['select']); $elementId = StringUtility::getUniqueId('formengine-table-permission-'); foreach ($availableTables as $table) { $permissions = []; foreach (self::Permissions as $permission) { $permissions[$permission] = [ 'label' => $lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:be_groups.tables_modify.permissions.' . $permission), 'attributes' => [ 'type' => 'radio', 'class' => 'form-check-input t3js-table-permissions-item t3js-multi-record-selection-check', 'value' => $permission, 'name' => $elementId . '[' . $table['value'] . ']', 'id' => $elementId . '[' . $table['value'] . '][' . $permission . ']', 'data-table' => $table['value'], ], ]; } if (isset($itemArrayModify[$table['value']])) { $permissions[self::Permissions['modify']]['attributes']['checked'] = 'checked'; } elseif (isset($itemArraySelect[$table['value']])) { $permissions[self::Permissions['select']]['attributes']['checked'] = 'checked'; } else { $permissions[self::Permissions['none']]['attributes']['checked'] = 'checked'; } if ($readOnly) { foreach (self::Permissions as $permission) { $permissions[$permission]['attributes']['disabled'] = 'disabled'; } } $tablesConfiguration[] = [ 'permissions' => $permissions, 'label' => [ 'id' => $elementId . '-' . $table['value'] . '-label', 'icon' => $this->getIconForTable(!empty($table['icon']) ? $table['icon'] : 'empty-empty'), 'title' => $lang->sL($table['label']), 'value' => $table['value'], ], ]; } $modifyStateFieldName = htmlspecialchars($elementFieldName); $selectStateFieldName = htmlspecialchars(str_replace($this->data['fieldName'], $config['selectFieldName'], $elementFieldName)); $fieldInformationResult = $this->renderFieldInformation(); $fieldInformationHtml = $fieldInformationResult['html']; $resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $fieldInformationResult, false); $html[] = ''; $html[] = '
'; $html[] = $fieldInformationHtml; if (!$readOnly) { $html[] = ''; $html[] = ''; } $tableRows = []; foreach ($tablesConfiguration as $tableConfiguration) { $tableRows[] = ''; foreach ($tableConfiguration['permissions'] as $key => $permission) { $tableRows[] = ''; $tableRows[] = '
'; $tableRows[] = ''; $tableRows[] = ''; $tableRows[] = '
'; $tableRows[] = ''; } $tableRows[] = ''; $tableRows[] = ''; $tableRows[] = ''; $tableRows[] = ''; } $html[] = '
'; $html[] = '
'; $html[] = ''; $html[] = ''; $html[] = ''; foreach (self::Permissions as $permission) { $html[] = ''; } $html[] = ''; $html[] = ''; $html[] = ''; $html[] = '' . implode(LF, $tableRows) . ''; $html[] = '
'; $html[] = $this->getRecordSelectionCheckActions($permission === self::Permissions['none'] ? ['all'] : ['all', 'none', 'toggle'], $readOnly); $html[] = '' . htmlspecialchars($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.th.name')) . '
'; $html[] = '
'; $html[] = '
'; $html[] = '
'; if (!$readOnly) { $resultArray['javaScriptModules'][] = JavaScriptModuleInstruction::create('@typo3/backend/form-engine/element/table-permission-element.js'); $resultArray['javaScriptModules'][] = JavaScriptModuleInstruction::create('@typo3/backend/multi-record-selection.js'); } $html[] = '
'; $resultArray['html'] = $this->wrapWithFieldsetAndLegend(implode(LF, $html)); return $resultArray; } protected function wrapWithFieldsetAndLegend(string $innerHTML): string { $legend = htmlspecialchars($this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:be_groups.tables_modify')); if ($this->getBackendUser()->shallDisplayDebugInformation()) { $legend .= ' [' . ($this->data['parameterArray']['fieldConf']['config']['selectFieldName'] ?? '') . ', ' . $this->data['fieldName'] . ']'; } $html = []; $html[] = '
'; $html[] = '' . $legend . ''; $html[] = $innerHTML; $html[] = '
'; return implode(LF, $html); } private function getIconForTable(string $icon): string { return FormEngineUtility::getIconHtml($icon); } private function getRecordSelectionCheckActions(array $optionsToShow, bool $readOnly): string { $checkboxOptions = [ 'all' => '
  • ', 'none' => '
  • ', 'toggle' => '
  • ', ]; $checkboxOptions = array_filter($checkboxOptions, static fn($checkboxOption) => in_array($checkboxOption, $optionsToShow, true), ARRAY_FILTER_USE_KEY); if ($checkboxOptions === []) { return ''; } return ' '; } }